3
|
1 /* LibTomCrypt, modular cryptographic library -- Tom St Denis |
|
2 * |
|
3 * LibTomCrypt is a library that provides various cryptographic |
|
4 * algorithms in a highly modular and flexible manner. |
|
5 * |
|
6 * The library is free for all purposes without any express |
|
7 * guarantee it works. |
|
8 * |
|
9 * Tom St Denis, [email protected], http://libtomcrypt.org |
|
10 */ |
|
11 /* Submited by Dobes Vandermeer ([email protected]) */ |
|
12 |
|
13 #include "mycrypt.h" |
|
14 |
|
15 /* |
|
16 (1) append zeros to the end of K to create a B byte string |
|
17 (e.g., if K is of length 20 bytes and B=64, then K will be |
|
18 appended with 44 zero bytes 0x00) |
|
19 (2) XOR (bitwise exclusive-OR) the B byte string computed in step |
|
20 (1) with ipad (ipad = the byte 0x36 repeated B times) |
|
21 (3) append the stream of data 'text' to the B byte string resulting |
|
22 from step (2) |
|
23 (4) apply H to the stream generated in step (3) |
|
24 (5) XOR (bitwise exclusive-OR) the B byte string computed in |
|
25 step (1) with opad (opad = the byte 0x5C repeated B times.) |
|
26 (6) append the H result from step (4) to the B byte string |
|
27 resulting from step (5) |
|
28 (7) apply H to the stream generated in step (6) and output |
|
29 the result |
|
30 */ |
|
31 |
|
32 #ifdef HMAC |
|
33 |
|
34 #define HMAC_BLOCKSIZE hash_descriptor[hash].blocksize |
|
35 |
|
36 /* |
|
37 |
|
38 TEST CASES SOURCE: |
|
39 |
|
40 Network Working Group P. Cheng |
|
41 Request for Comments: 2202 IBM |
|
42 Category: Informational R. Glenn |
|
43 NIST |
|
44 September 1997 |
|
45 |
|
46 Test Cases for HMAC-MD5 and HMAC-SHA-1 |
|
47 */ |
|
48 |
|
49 |
|
50 int hmac_test(void) |
|
51 { |
|
52 #ifndef LTC_TEST |
|
53 return CRYPT_NOP; |
|
54 #else |
|
55 unsigned char digest[MAXBLOCKSIZE]; |
|
56 int i; |
|
57 |
|
58 static const struct hmac_test_case { |
|
59 int num; |
|
60 char *algo; |
|
61 unsigned char key[128]; |
|
62 unsigned long keylen; |
|
63 unsigned char data[128]; |
|
64 unsigned long datalen; |
|
65 unsigned char digest[MAXBLOCKSIZE]; |
|
66 } cases[] = { |
|
67 /* |
|
68 3. Test Cases for HMAC-SHA-1 |
|
69 |
|
70 test_case = 1 |
|
71 key = 0x0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b |
|
72 key_len = 20 |
|
73 data = "Hi Ther 20 |
|
74 digest = 0x4c1a03424b55e07fe7f27be1d58bb9324a9a5a04 |
|
75 digest-96 = 0x4c1a03424b55e07fe7f27be1 |
|
76 */ |
|
77 { 5, "sha1", |
|
78 {0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, |
|
79 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, |
|
80 0x0c, 0x0c, 0x0c, 0x0c}, 20, |
|
81 "Test With Truncation", 20, |
|
82 {0x4c, 0x1a, 0x03, 0x42, 0x4b, 0x55, 0xe0, 0x7f, 0xe7, 0xf2, |
|
83 0x7b, 0xe1, 0xd5, 0x8b, 0xb9, 0x32, 0x4a, 0x9a, 0x5a, 0x04} }, |
|
84 |
|
85 /* |
|
86 test_case = 6 |
|
87 key = 0xaa repeated 80 times |
|
88 key_len = 80 |
|
89 data = "Test Using Larger Than Block-Size Key - Hash Key First" |
|
90 data_len = 54 |
|
91 digest = 0xaa4ae5e15272d00e95705637ce8a3b55ed402112 |
|
92 */ |
|
93 { 6, "sha1", |
|
94 {0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, |
|
95 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, |
|
96 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, |
|
97 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, |
|
98 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, |
|
99 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, |
|
100 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, |
|
101 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, |
|
102 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, |
|
103 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa}, 80, |
|
104 "Test Using Larger Than Block-Size Key - Hash Key First", 54, |
|
105 {0xaa, 0x4a, 0xe5, 0xe1, 0x52, 0x72, 0xd0, 0x0e, |
|
106 0x95, 0x70, 0x56, 0x37, 0xce, 0x8a, 0x3b, 0x55, |
|
107 0xed, 0x40, 0x21, 0x12} }, |
|
108 |
|
109 /* |
|
110 test_case = 7 |
|
111 key = 0xaa repeated 80 times |
|
112 key_len = 80 |
|
113 data = "Test Using Larger Than Block-Size Key and Larger |
|
114 Than One Block-Size Data" |
|
115 data_len = 73 |
|
116 digest = 0xe8e99d0f45237d786d6bbaa7965c7808bbff1a91 |
|
117 */ |
|
118 { 7, "sha1", |
|
119 {0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, |
|
120 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, |
|
121 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, |
|
122 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, |
|
123 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, |
|
124 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, |
|
125 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, |
|
126 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, |
|
127 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, |
|
128 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa}, 80, |
|
129 "Test Using Larger Than Block-Size Key and Larger Than One Block-Size Data", 73, |
|
130 {0xe8, 0xe9, 0x9d, 0x0f, 0x45, 0x23, 0x7d, 0x78, 0x6d, |
|
131 0x6b, 0xba, 0xa7, 0x96, 0x5c, 0x78, 0x08, 0xbb, 0xff, 0x1a, 0x91} }, |
|
132 |
|
133 /* |
|
134 2. Test Cases for HMAC-MD5 |
|
135 |
|
136 test_case = 1 |
|
137 key = 0x0b 0b 0b 0b |
|
138 0b 0b 0b 0b |
|
139 0b 0b 0b 0b |
|
140 0b 0b 0b 0b |
|
141 key_len = 16 |
|
142 data = "Hi There" |
|
143 data_len = 8 |
|
144 digest = 0x92 94 72 7a |
|
145 36 38 bb 1c |
|
146 13 f4 8e f8 |
|
147 15 8b fc 9d |
|
148 */ |
|
149 { 1, "md5", |
|
150 {0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, |
|
151 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b}, 16, |
|
152 "Hi There", 8, |
|
153 {0x92, 0x94, 0x72, 0x7a, 0x36, 0x38, 0xbb, 0x1c, |
|
154 0x13, 0xf4, 0x8e, 0xf8, 0x15, 0x8b, 0xfc, 0x9d} }, |
|
155 /* |
|
156 test_case = 2 |
|
157 key = "Jefe" |
|
158 key_len = 4 |
|
159 data = "what do ya want for nothing?" |
|
160 data_len = 28 |
|
161 digest = 0x750c783e6ab0b503eaa86e310a5db738 |
|
162 */ |
|
163 { 2, "md5", |
|
164 "Jefe", 4, |
|
165 "what do ya want for nothing?", 28, |
|
166 {0x75, 0x0c, 0x78, 0x3e, 0x6a, 0xb0, 0xb5, 0x03, |
|
167 0xea, 0xa8, 0x6e, 0x31, 0x0a, 0x5d, 0xb7, 0x38} }, |
|
168 |
|
169 /* |
|
170 test_case = 3 |
|
171 key = 0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa |
|
172 key_len 16 |
|
173 data = 0xdd repeated 50 times |
|
174 data_len = 50 |
|
175 digest = 0x56be34521d144c88dbb8c733f0e8b3f6 |
|
176 */ |
|
177 { 3, "md5", |
|
178 {0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, |
|
179 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa}, 16, |
|
180 {0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, |
|
181 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, |
|
182 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, |
|
183 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, |
|
184 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd}, 50, |
|
185 {0x56, 0xbe, 0x34, 0x52, 0x1d, 0x14, 0x4c, 0x88, |
|
186 0xdb, 0xb8, 0xc7, 0x33, 0xf0, 0xe8, 0xb3, 0xf6} }, |
|
187 /* |
|
188 |
|
189 test_case = 4 |
|
190 key = 0x0102030405060708090a0b0c0d0e0f10111213141516171819 |
|
191 key_len 25 |
|
192 data = 0xcd repeated 50 times |
|
193 data_len = 50 |
|
194 digest = 0x697eaf0aca3a3aea3a75164746ffaa79 |
|
195 */ |
|
196 { 4, "md5", |
|
197 {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, |
|
198 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, |
|
199 0x15, 0x16, 0x17, 0x18, 0x19}, 25, |
|
200 {0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, |
|
201 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, |
|
202 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, |
|
203 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, |
|
204 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd}, 50, |
|
205 {0x69, 0x7e, 0xaf, 0x0a, 0xca, 0x3a, 0x3a, 0xea, |
|
206 0x3a, 0x75, 0x16, 0x47, 0x46, 0xff, 0xaa, 0x79} }, |
|
207 |
|
208 |
|
209 /* |
|
210 |
|
211 test_case = 5 |
|
212 key = 0x0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c |
|
213 key_len = 16 |
|
214 data = "Test With Truncation" |
|
215 data_len = 20 |
|
216 digest = 0x56461ef2342edc00f9bab995690efd4c |
|
217 digest-96 0x56461ef2342edc00f9bab995 |
|
218 */ |
|
219 { 5, "md5", |
|
220 {0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, |
|
221 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c}, 16, |
|
222 "Test With Truncation", 20, |
|
223 {0x56, 0x46, 0x1e, 0xf2, 0x34, 0x2e, 0xdc, 0x00, |
|
224 0xf9, 0xba, 0xb9, 0x95, 0x69, 0x0e, 0xfd, 0x4c} }, |
|
225 |
|
226 /* |
|
227 |
|
228 test_case = 6 |
|
229 key = 0xaa repeated 80 times |
|
230 key_len = 80 |
|
231 data = "Test Using Larger Than Block-Size Key - Hash |
|
232 Key First" |
|
233 data_len = 54 |
|
234 digest = 0x6b1ab7fe4bd7bf8f0b62e6ce61b9d0cd |
|
235 */ |
|
236 { 6, "md5", |
|
237 {0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, |
|
238 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, |
|
239 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, |
|
240 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, |
|
241 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, |
|
242 |
|
243 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, |
|
244 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, |
|
245 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, |
|
246 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, |
|
247 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa}, 80, |
|
248 "Test Using Larger Than Block-Size Key - Hash Key First", 54, |
|
249 {0x6b, 0x1a, 0xb7, 0xfe, 0x4b, 0xd7, 0xbf, 0x8f, |
|
250 0x0b, 0x62, 0xe6, 0xce, 0x61, 0xb9, 0xd0, 0xcd} }, |
|
251 |
|
252 /* |
|
253 |
|
254 test_case = 7 |
|
255 key = 0xaa repeated 80 times |
|
256 key_len = 80 |
|
257 data = "Test Using Larger Than Block-Size Key and Larger |
|
258 Than One Block-Size Data" |
|
259 data_len = 73 |
|
260 digest = 0x6f630fad67cda0ee1fb1f562db3aa53e |
|
261 */ |
|
262 { 7, "md5", |
|
263 {0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, |
|
264 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, |
|
265 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, |
|
266 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, |
|
267 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, |
|
268 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, |
|
269 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, |
|
270 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, |
|
271 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, |
|
272 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa}, 80, |
|
273 "Test Using Larger Than Block-Size Key and Larger Than One Block-Size Data", 73, |
|
274 {0x6f, 0x63, 0x0f, 0xad, 0x67, 0xcd, 0xa0, 0xee, |
|
275 0x1f, 0xb1, 0xf5, 0x62, 0xdb, 0x3a, 0xa5, 0x3e} } |
|
276 }; |
|
277 |
|
278 unsigned long outlen; |
|
279 int err; |
|
280 int tested=0,failed=0; |
|
281 for(i=0; i < (int)(sizeof(cases) / sizeof(cases[0])); i++) { |
|
282 int hash = find_hash(cases[i].algo); |
|
283 if (hash == -1) continue; |
|
284 ++tested; |
|
285 outlen = sizeof(digest); |
|
286 if((err = hmac_memory(hash, cases[i].key, cases[i].keylen, cases[i].data, cases[i].datalen, digest, &outlen)) != CRYPT_OK) { |
|
287 #if 0 |
143
|
288 printf("HMAC-%s test #%d, %s\n", cases[i].algo, cases[i].num, error_to_string(err)); |
3
|
289 #endif |
|
290 return err; |
|
291 } |
|
292 |
|
293 if(memcmp(digest, cases[i].digest, (size_t)hash_descriptor[hash].hashsize) != 0) { |
143
|
294 failed++; |
3
|
295 #if 0 |
|
296 unsigned int j; |
|
297 printf("\nHMAC-%s test #%d:\n", cases[i].algo, cases[i].num); |
|
298 printf( "Result: 0x"); |
|
299 for(j=0; j < hash_descriptor[hash].hashsize; j++) { |
|
300 printf("%2x ", digest[j]); |
|
301 } |
|
302 printf("\nCorrect: 0x"); |
|
303 for(j=0; j < hash_descriptor[hash].hashsize; j++) { |
|
304 printf("%2x ", cases[i].digest[j]); |
|
305 } |
|
306 printf("\n"); |
143
|
307 return CRYPT_ERROR; |
3
|
308 #endif |
|
309 } else { |
|
310 /* printf("HMAC-%s test #%d: Passed\n", cases[i].algo, cases[i].num); */ |
|
311 } |
|
312 } |
|
313 |
|
314 if (failed != 0) { |
|
315 return CRYPT_FAIL_TESTVECTOR; |
|
316 } else if (tested == 0) { |
|
317 return CRYPT_NOP; |
|
318 } else { |
|
319 return CRYPT_OK; |
|
320 } |
|
321 #endif |
|
322 } |
|
323 |
|
324 #endif |
|
325 |