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