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 (at) 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 */ 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