1/*
2 * dhcpcd - DHCP client daemon
3 * Copyright (c) 2006-2014 Roy Marples <roy@marples.name>
4 * All rights reserved
5
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 *    notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 *    notice, this list of conditions and the following disclaimer in the
13 *    documentation and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25 * SUCH DAMAGE.
26 */
27
28#include <stdio.h>
29#include <stdint.h>
30
31#include "../crypt/crypt.h"
32#include "test.h"
33
34/* RFC2202 MD5 implementation */
35
36static void
37print_hmac(uint8_t *hmac)
38{
39	int i;
40
41	printf("digest = 0x");
42	for (i = 0; i < 16; i++)
43		printf("%02x", *hmac++);
44	printf("\n");
45}
46
47static void
48hmac_md5_test1(void)
49{
50	uint8_t hmac[16];
51	const uint8_t text[] = "Hi There";
52	uint8_t key[16];
53	int i;
54
55	printf ("HMAC MD5 Test 1:\t\t");
56	for (i = 0; i < 16; i++)
57		key[i] = 0x0b;
58	hmac_md5(text, 8, key, 16, hmac);
59	print_hmac(hmac);
60	printf("\t\texpected result:\t 0x9294727a3638bb1c13f48ef8158bfc9d\n");
61}
62
63static void
64hmac_md5_test2(void)
65{
66	uint8_t hmac[16];
67	const uint8_t text[] = "what do ya want for nothing?";
68	const uint8_t key[] = "Jefe";
69
70	printf("HMAC MD5 Test 2:\t\t");
71	hmac_md5(text, 28, key, 4, hmac);
72	print_hmac(hmac);
73	printf("\t\texpected result:\t 0x750c783e6ab0b503eaa863e10a5db738\n");
74}
75
76static void
77hmac_md5_test3(void)
78{
79	uint8_t hmac[16];
80	uint8_t text[50];
81	uint8_t key[16];
82	int i;
83
84	printf ("HMAC MD5 Test 3:\t\t");
85	for (i = 0; i < 50; i++)
86		text[i] = 0xdd;
87	for (i = 0; i < 16; i++)
88		key[i] = 0xaa;
89	hmac_md5(text, 50, key, 16, hmac);
90	print_hmac(hmac);
91	printf("\t\texpected result:\t 0x56be34521d144c88dbb8c733f0e8b3f6\n");
92}
93
94static void
95hmac_md5_test4(void)
96{
97	uint8_t hmac[16];
98	uint8_t text[50];
99	uint8_t key[25];
100	uint8_t i;
101
102	printf ("HMAC MD5 Test 4:\t\t");
103	for (i = 0; i < 50; i++)
104		text[i] = 0xcd;
105	for (i = 0; i < 25; i++)
106		key[i] = (uint8_t)(i + 1);
107	hmac_md5(text, 50, key, 25, hmac);
108	print_hmac(hmac);
109	printf("\t\texpected result:\t 0x697eaf0aca3a3aea3a75164746ffaa79\n");
110}
111
112static void
113hmac_md5_test5(void)
114{
115	uint8_t hmac[16];
116	const uint8_t text[] = "Test With Truncation";
117	uint8_t key[16];
118	int i;
119
120	printf ("HMAC MD5 Test 5:\t\t");
121	for (i = 0; i < 16; i++)
122		key[i] = 0x0c;
123	hmac_md5(text, 20, key, 16, hmac);
124	print_hmac(hmac);
125	printf("\t\texpected result:\t 0x56461ef2342edc00f9bab995690efd4c\n");
126}
127
128static void
129hmac_md5_test6(void)
130{
131	uint8_t hmac[16];
132	const uint8_t text[] = "Test Using Larger Than Block-Size Key - Hash Key First";
133	uint8_t key[80];
134	int i;
135
136	printf ("HMAC MD5 Test 6:\t\t");
137	for (i = 0; i < 80; i++)
138		key[i] = 0xaa;
139	hmac_md5(text, 54, key, 80, hmac);
140	print_hmac(hmac);
141	printf("\t\texpected result:\t 0x6b1ab7fe4bd7bf8f0b62e6ce61b9d0cd\n");
142}
143
144static void
145hmac_md5_test7(void)
146{
147	uint8_t hmac[16];
148	const uint8_t text[] = "Test Using Larger Than Block-Size Key and Larger Than One Block-Size Data";
149	uint8_t key[80];
150	int i;
151
152	printf ("HMAC MD5 Test 7:\t\t");
153	for (i = 0; i < 80; i++)
154		key[i] = 0xaa;
155	hmac_md5(text, 73, key, 80, hmac);
156	print_hmac(hmac);
157	printf("\t\texpected result:\t 0x6f630fad67cda0ee1fb1f562db3aa53e\n");
158}
159
160int test_hmac_md5(void)
161{
162
163	printf ("Starting HMAC MD5 tests...\n\n");
164	hmac_md5_test1();
165	hmac_md5_test2();
166	hmac_md5_test3();
167	hmac_md5_test4();
168	hmac_md5_test5();
169	hmac_md5_test6();
170	hmac_md5_test7();
171	printf("\nConfirm above results visually against RFC 2202.\n");
172	return 0;
173}
174