|
|
1.1.1.9 root 1: /* 1.1.1.11! root 2: Legal Notice: Some portions of the source code contained in this file were ! 3: derived from the source code of Encryption for the Masses 2.02a, which is ! 4: Copyright (c) 1998-2000 Paul Le Roux and which is governed by the 'License ! 5: Agreement for Encryption for the Masses'. Modifications and additions to ! 6: the original source code (contained in this file) and all other portions of ! 7: this file are Copyright (c) 2003-2008 TrueCrypt Foundation and are governed ! 8: by the TrueCrypt License 2.4 the full text of which is contained in the ! 9: file License.txt included in TrueCrypt binary and source code distribution 1.1.1.9 root 10: packages. */ 1.1 root 11: 1.1.1.6 root 12: #include "Tcdefs.h" 1.1 root 13: 14: #include <memory.h> 1.1.1.6 root 15: #include "Rmd160.h" 1.1.1.11! root 16: #ifndef TC_WINDOWS_BOOT ! 17: #include "Sha1.h" ! 18: #include "Sha2.h" 1.1.1.6 root 19: #include "Whirlpool.h" 1.1.1.11! root 20: #endif 1.1.1.6 root 21: #include "Pkcs5.h" 22: #include "Crypto.h" 1.1 root 23: 1.1.1.11! root 24: void hmac_truncate 1.1 root 25: ( 26: char *d1, /* data to be truncated */ 27: char *d2, /* truncated data */ 28: int len /* length in bytes to keep */ 29: ) 30: { 31: int i; 32: for (i = 0; i < len; i++) 33: d2[i] = d1[i]; 34: } 35: 1.1.1.11! root 36: #ifndef TC_WINDOWS_BOOT ! 37: ! 38: void hmac_sha512 ! 39: ( ! 40: char *k, /* secret key */ ! 41: int lk, /* length of the key in bytes */ ! 42: char *d, /* data */ ! 43: int ld, /* length of data in bytes */ ! 44: char *out, /* output buffer, at least "t" bytes */ ! 45: int t ! 46: ) ! 47: { ! 48: sha512_ctx ictx, octx; ! 49: char isha[SHA512_DIGESTSIZE], osha[SHA512_DIGESTSIZE]; ! 50: char key[SHA512_DIGESTSIZE]; ! 51: char buf[SHA512_BLOCKSIZE]; ! 52: int i; ! 53: ! 54: /* If the key is longer than the hash algorithm block size, ! 55: let key = sha512(key), as per HMAC specifications. */ ! 56: if (lk > SHA512_BLOCKSIZE) ! 57: { ! 58: sha512_ctx tctx; ! 59: ! 60: sha512_begin (&tctx); ! 61: sha512_hash ((unsigned char *) k, lk, &tctx); ! 62: sha512_end ((unsigned char *) key, &tctx); ! 63: ! 64: k = key; ! 65: lk = SHA512_DIGESTSIZE; ! 66: ! 67: burn (&tctx, sizeof(tctx)); // Prevent leaks ! 68: } ! 69: ! 70: /**** Inner Digest ****/ ! 71: ! 72: sha512_begin (&ictx); ! 73: ! 74: /* Pad the key for inner digest */ ! 75: for (i = 0; i < lk; ++i) ! 76: buf[i] = (char) (k[i] ^ 0x36); ! 77: for (i = lk; i < SHA512_BLOCKSIZE; ++i) ! 78: buf[i] = 0x36; ! 79: ! 80: sha512_hash ((unsigned char *) buf, SHA512_BLOCKSIZE, &ictx); ! 81: sha512_hash ((unsigned char *) d, ld, &ictx); ! 82: ! 83: sha512_end ((unsigned char *) isha, &ictx); ! 84: ! 85: /**** Outer Digest ****/ ! 86: ! 87: sha512_begin (&octx); ! 88: ! 89: for (i = 0; i < lk; ++i) ! 90: buf[i] = (char) (k[i] ^ 0x5C); ! 91: for (i = lk; i < SHA512_BLOCKSIZE; ++i) ! 92: buf[i] = 0x5C; ! 93: ! 94: sha512_hash ((unsigned char *) buf, SHA512_BLOCKSIZE, &octx); ! 95: sha512_hash ((unsigned char *) isha, SHA512_DIGESTSIZE, &octx); ! 96: ! 97: sha512_end ((unsigned char *) osha, &octx); ! 98: ! 99: /* truncate and print the results */ ! 100: t = t > SHA512_DIGESTSIZE ? SHA512_DIGESTSIZE : t; ! 101: hmac_truncate (osha, out, t); ! 102: ! 103: /* Prevent leaks */ ! 104: burn (&ictx, sizeof(ictx)); ! 105: burn (&octx, sizeof(octx)); ! 106: burn (isha, sizeof(isha)); ! 107: burn (osha, sizeof(osha)); ! 108: burn (buf, sizeof(buf)); ! 109: burn (key, sizeof(key)); ! 110: } ! 111: ! 112: ! 113: void derive_u_sha512 (char *pwd, int pwd_len, char *salt, int salt_len, int iterations, char *u, int b) ! 114: { ! 115: char j[SHA512_DIGESTSIZE], k[SHA512_DIGESTSIZE]; ! 116: char init[128]; ! 117: char counter[4]; ! 118: int c, i; ! 119: ! 120: /* iteration 1 */ ! 121: memset (counter, 0, 4); ! 122: counter[3] = (char) b; ! 123: memcpy (init, salt, salt_len); /* salt */ ! 124: memcpy (&init[salt_len], counter, 4); /* big-endian block number */ ! 125: hmac_sha512 (pwd, pwd_len, init, salt_len + 4, j, SHA512_DIGESTSIZE); ! 126: memcpy (u, j, SHA512_DIGESTSIZE); ! 127: ! 128: /* remaining iterations */ ! 129: for (c = 1; c < iterations; c++) ! 130: { ! 131: hmac_sha512 (pwd, pwd_len, j, SHA512_DIGESTSIZE, k, SHA512_DIGESTSIZE); ! 132: for (i = 0; i < SHA512_DIGESTSIZE; i++) ! 133: { ! 134: u[i] ^= k[i]; ! 135: j[i] = k[i]; ! 136: } ! 137: } ! 138: ! 139: /* Prevent possible leaks. */ ! 140: burn (j, sizeof(j)); ! 141: burn (k, sizeof(k)); ! 142: } ! 143: ! 144: ! 145: void derive_key_sha512 (char *pwd, int pwd_len, char *salt, int salt_len, int iterations, char *dk, int dklen) ! 146: { ! 147: char u[SHA512_DIGESTSIZE]; ! 148: int b, l, r; ! 149: ! 150: if (dklen % SHA512_DIGESTSIZE) ! 151: { ! 152: l = 1 + dklen / SHA512_DIGESTSIZE; ! 153: } ! 154: else ! 155: { ! 156: l = dklen / SHA512_DIGESTSIZE; ! 157: } ! 158: ! 159: r = dklen - (l - 1) * SHA512_DIGESTSIZE; ! 160: ! 161: /* first l - 1 blocks */ ! 162: for (b = 1; b < l; b++) ! 163: { ! 164: derive_u_sha512 (pwd, pwd_len, salt, salt_len, iterations, u, b); ! 165: memcpy (dk, u, SHA512_DIGESTSIZE); ! 166: dk += SHA512_DIGESTSIZE; ! 167: } ! 168: ! 169: /* last block */ ! 170: derive_u_sha512 (pwd, pwd_len, salt, salt_len, iterations, u, b); ! 171: memcpy (dk, u, r); ! 172: ! 173: ! 174: /* Prevent possible leaks. */ ! 175: burn (u, sizeof(u)); ! 176: } ! 177: ! 178: ! 179: /* Deprecated/legacy */ 1.1.1.6 root 180: void hmac_sha1 181: ( 1.1 root 182: char *k, /* secret key */ 183: int lk, /* length of the key in bytes */ 184: char *d, /* data */ 185: int ld, /* length of data in bytes */ 186: char *out, /* output buffer, at least "t" bytes */ 187: int t 188: ) 189: { 1.1.1.6 root 190: sha1_ctx ictx, octx; 191: char isha[SHA1_DIGESTSIZE], osha[SHA1_DIGESTSIZE]; 192: char key[SHA1_DIGESTSIZE]; 193: char buf[SHA1_BLOCKSIZE]; 1.1 root 194: int i; 195: 1.1.1.6 root 196: /* If the key is longer than the hash algorithm block size, 197: let key = sha1(key), as per HMAC specifications. */ 198: if (lk > SHA1_BLOCKSIZE) 199: { 200: sha1_ctx tctx; 201: 202: sha1_begin (&tctx); 203: sha1_hash ((unsigned char *) k, lk, &tctx); 204: sha1_end ((unsigned char *) key, &tctx); 1.1 root 205: 206: k = key; 1.1.1.6 root 207: lk = SHA1_DIGESTSIZE; 208: 1.1.1.11! root 209: burn (&tctx, sizeof(tctx)); // Prevent leaks 1.1 root 210: } 211: 212: /**** Inner Digest ****/ 213: 1.1.1.6 root 214: sha1_begin (&ictx); 1.1 root 215: 216: /* Pad the key for inner digest */ 217: for (i = 0; i < lk; ++i) 218: buf[i] = (char) (k[i] ^ 0x36); 1.1.1.6 root 219: for (i = lk; i < SHA1_BLOCKSIZE; ++i) 1.1 root 220: buf[i] = 0x36; 221: 1.1.1.6 root 222: sha1_hash ((unsigned char *) buf, SHA1_BLOCKSIZE, &ictx); 223: sha1_hash ((unsigned char *) d, ld, &ictx); 1.1 root 224: 1.1.1.6 root 225: sha1_end ((unsigned char *) isha, &ictx); 1.1 root 226: 1.1.1.11! root 227: /**** Outer Digest ****/ 1.1 root 228: 1.1.1.6 root 229: sha1_begin (&octx); 1.1 root 230: 231: for (i = 0; i < lk; ++i) 232: buf[i] = (char) (k[i] ^ 0x5C); 1.1.1.6 root 233: for (i = lk; i < SHA1_BLOCKSIZE; ++i) 1.1 root 234: buf[i] = 0x5C; 235: 1.1.1.6 root 236: sha1_hash ((unsigned char *) buf, SHA1_BLOCKSIZE, &octx); 237: sha1_hash ((unsigned char *) isha, SHA1_DIGESTSIZE, &octx); 1.1 root 238: 1.1.1.6 root 239: sha1_end ((unsigned char *) osha, &octx); 1.1 root 240: 241: /* truncate and print the results */ 1.1.1.6 root 242: t = t > SHA1_DIGESTSIZE ? SHA1_DIGESTSIZE : t; 1.1.1.11! root 243: hmac_truncate (osha, out, t); 1.1.1.6 root 244: 245: /* Prevent leaks */ 1.1.1.11! root 246: burn (&ictx, sizeof(ictx)); ! 247: burn (&octx, sizeof(octx)); ! 248: burn (isha, sizeof(isha)); ! 249: burn (osha, sizeof(osha)); ! 250: burn (buf, sizeof(buf)); ! 251: burn (key, sizeof(key)); 1.1 root 252: } 253: 254: 1.1.1.11! root 255: /* Deprecated/legacy */ 1.1.1.6 root 256: void derive_u_sha1 (char *pwd, int pwd_len, char *salt, int salt_len, int iterations, char *u, int b) 1.1 root 257: { 1.1.1.6 root 258: char j[SHA1_DIGESTSIZE], k[SHA1_DIGESTSIZE]; 1.1 root 259: char init[128]; 260: char counter[4]; 261: int c, i; 262: 263: /* iteration 1 */ 264: memset (counter, 0, 4); 265: counter[3] = (char) b; 266: memcpy (init, salt, salt_len); /* salt */ 267: memcpy (&init[salt_len], counter, 4); /* big-endian block number */ 1.1.1.6 root 268: hmac_sha1 (pwd, pwd_len, init, salt_len + 4, j, SHA1_DIGESTSIZE); 269: memcpy (u, j, SHA1_DIGESTSIZE); 1.1 root 270: 271: /* remaining iterations */ 272: for (c = 1; c < iterations; c++) 273: { 1.1.1.6 root 274: hmac_sha1 (pwd, pwd_len, j, SHA1_DIGESTSIZE, k, SHA1_DIGESTSIZE); 275: for (i = 0; i < SHA1_DIGESTSIZE; i++) 1.1 root 276: { 277: u[i] ^= k[i]; 278: j[i] = k[i]; 279: } 280: } 1.1.1.6 root 281: 282: /* Prevent possible leaks. */ 1.1.1.11! root 283: burn (j, sizeof(j)); ! 284: burn (k, sizeof(k)); 1.1 root 285: } 286: 1.1.1.11! root 287: ! 288: /* Deprecated/legacy */ 1.1.1.6 root 289: void derive_key_sha1 (char *pwd, int pwd_len, char *salt, int salt_len, int iterations, char *dk, int dklen) 1.1 root 290: { 1.1.1.6 root 291: char u[SHA1_DIGESTSIZE]; 1.1 root 292: int b, l, r; 293: 1.1.1.6 root 294: if (dklen % SHA1_DIGESTSIZE) 1.1 root 295: { 1.1.1.6 root 296: l = 1 + dklen / SHA1_DIGESTSIZE; 1.1 root 297: } 298: else 299: { 1.1.1.6 root 300: l = dklen / SHA1_DIGESTSIZE; 1.1 root 301: } 302: 1.1.1.6 root 303: r = dklen - (l - 1) * SHA1_DIGESTSIZE; 1.1 root 304: 305: /* first l - 1 blocks */ 306: for (b = 1; b < l; b++) 307: { 1.1.1.6 root 308: derive_u_sha1 (pwd, pwd_len, salt, salt_len, iterations, u, b); 309: memcpy (dk, u, SHA1_DIGESTSIZE); 310: dk += SHA1_DIGESTSIZE; 1.1 root 311: } 312: 313: /* last block */ 1.1.1.6 root 314: derive_u_sha1 (pwd, pwd_len, salt, salt_len, iterations, u, b); 1.1 root 315: memcpy (dk, u, r); 316: 317: 1.1.1.6 root 318: /* Prevent possible leaks. */ 1.1.1.11! root 319: burn (u, sizeof(u)); 1.1.1.6 root 320: } 1.1 root 321: 1.1.1.11! root 322: #endif // TC_WINDOWS_BOOT ! 323: 1.1.1.6 root 324: void hmac_ripemd160 (char *key, int keylen, char *input, int len, char *digest) 1.1.1.3 root 325: { 326: RMD160_CTX context; 327: unsigned char k_ipad[65]; /* inner padding - key XORd with ipad */ 328: unsigned char k_opad[65]; /* outer padding - key XORd with opad */ 1.1.1.6 root 329: unsigned char tk[RIPEMD160_DIGESTSIZE]; 1.1.1.3 root 330: int i; 331: 1.1.1.6 root 332: /* If the key is longer than the hash algorithm block size, 333: let key = ripemd160(key), as per HMAC specifications. */ 334: if (keylen > RIPEMD160_BLOCKSIZE) 335: { 1.1.1.3 root 336: RMD160_CTX tctx; 337: 338: RMD160Init(&tctx); 339: RMD160Update(&tctx, key, keylen); 340: RMD160Final(tk, &tctx); 341: 342: key = tk; 1.1.1.6 root 343: keylen = RIPEMD160_DIGESTSIZE; 344: 1.1.1.11! root 345: burn (&tctx, sizeof(tctx)); // Prevent leaks 1.1.1.3 root 346: } 347: 1.1.1.6 root 348: /* 349: 350: RMD160(K XOR opad, RMD160(K XOR ipad, text)) 1.1.1.3 root 351: 1.1.1.6 root 352: where K is an n byte key 353: ipad is the byte 0x36 repeated RIPEMD160_BLOCKSIZE times 354: opad is the byte 0x5c repeated RIPEMD160_BLOCKSIZE times 355: and text is the data being protected */ 1.1.1.3 root 356: 357: 1.1.1.6 root 358: /* start out by storing key in pads */ 359: memset(k_ipad, 0x36, sizeof(k_ipad)); 1.1.1.3 root 360: memset(k_opad, 0x5c, sizeof(k_opad)); 361: 1.1.1.6 root 362: /* XOR key with ipad and opad values */ 363: for (i=0; i<keylen; i++) 364: { 1.1.1.3 root 365: k_ipad[i] ^= key[i]; 366: k_opad[i] ^= key[i]; 367: } 368: 1.1.1.6 root 369: /* perform inner RIPEMD-160 */ 1.1.1.3 root 370: 371: RMD160Init(&context); /* init context for 1st pass */ 1.1.1.6 root 372: RMD160Update(&context, k_ipad, RIPEMD160_BLOCKSIZE); /* start with inner pad */ 1.1.1.3 root 373: RMD160Update(&context, input, len); /* then text of datagram */ 374: RMD160Final(digest, &context); /* finish up 1st pass */ 375: 1.1.1.6 root 376: /* perform outer RIPEMD-160 */ 1.1.1.3 root 377: RMD160Init(&context); /* init context for 2nd pass */ 1.1.1.6 root 378: RMD160Update(&context, k_opad, RIPEMD160_BLOCKSIZE); /* start with outer pad */ 379: /* results of 1st hash */ 380: RMD160Update(&context, digest, RIPEMD160_DIGESTSIZE); 1.1.1.3 root 381: RMD160Final(digest, &context); /* finish up 2nd pass */ 1.1 root 382: 1.1.1.6 root 383: /* Prevent possible leaks. */ 1.1.1.11! root 384: burn (k_ipad, sizeof(k_ipad)); ! 385: burn (k_opad, sizeof(k_opad)); ! 386: burn (tk, sizeof(tk)); ! 387: burn (&context, sizeof(context)); 1.1 root 388: } 389: 1.1.1.6 root 390: void derive_u_ripemd160 (char *pwd, int pwd_len, char *salt, int salt_len, int iterations, char *u, int b) 1.1 root 391: { 1.1.1.6 root 392: char j[RIPEMD160_DIGESTSIZE], k[RIPEMD160_DIGESTSIZE]; 1.1 root 393: char init[128]; 394: char counter[4]; 395: int c, i; 396: 397: /* iteration 1 */ 398: memset (counter, 0, 4); 399: counter[3] = (char) b; 400: memcpy (init, salt, salt_len); /* salt */ 401: memcpy (&init[salt_len], counter, 4); /* big-endian block number */ 1.1.1.6 root 402: hmac_ripemd160 (pwd, pwd_len, init, salt_len + 4, j); 403: memcpy (u, j, RIPEMD160_DIGESTSIZE); 1.1 root 404: 405: /* remaining iterations */ 406: for (c = 1; c < iterations; c++) 407: { 1.1.1.6 root 408: hmac_ripemd160 (pwd, pwd_len, j, RIPEMD160_DIGESTSIZE, k); 409: for (i = 0; i < RIPEMD160_DIGESTSIZE; i++) 1.1 root 410: { 411: u[i] ^= k[i]; 412: j[i] = k[i]; 413: } 414: } 1.1.1.6 root 415: 416: /* Prevent possible leaks. */ 1.1.1.11! root 417: burn (j, sizeof(j)); ! 418: burn (k, sizeof(k)); 1.1 root 419: } 420: 1.1.1.6 root 421: void derive_key_ripemd160 (char *pwd, int pwd_len, char *salt, int salt_len, int iterations, char *dk, int dklen) 1.1 root 422: { 1.1.1.6 root 423: char u[RIPEMD160_DIGESTSIZE]; 1.1 root 424: int b, l, r; 425: 1.1.1.6 root 426: if (dklen % RIPEMD160_DIGESTSIZE) 1.1 root 427: { 1.1.1.6 root 428: l = 1 + dklen / RIPEMD160_DIGESTSIZE; 1.1 root 429: } 430: else 431: { 1.1.1.6 root 432: l = dklen / RIPEMD160_DIGESTSIZE; 1.1 root 433: } 434: 1.1.1.6 root 435: r = dklen - (l - 1) * RIPEMD160_DIGESTSIZE; 1.1 root 436: 437: /* first l - 1 blocks */ 438: for (b = 1; b < l; b++) 439: { 1.1.1.6 root 440: derive_u_ripemd160 (pwd, pwd_len, salt, salt_len, iterations, u, b); 441: memcpy (dk, u, RIPEMD160_DIGESTSIZE); 442: dk += RIPEMD160_DIGESTSIZE; 1.1 root 443: } 444: 445: /* last block */ 1.1.1.6 root 446: derive_u_ripemd160 (pwd, pwd_len, salt, salt_len, iterations, u, b); 1.1 root 447: memcpy (dk, u, r); 1.1.1.6 root 448: 449: 450: /* Prevent possible leaks. */ 1.1.1.11! root 451: burn (u, sizeof(u)); 1.1 root 452: } 453: 1.1.1.11! root 454: #ifndef TC_WINDOWS_BOOT ! 455: 1.1.1.6 root 456: void hmac_whirlpool 457: ( 458: char *k, /* secret key */ 459: int lk, /* length of the key in bytes */ 460: char *d, /* data */ 461: int ld, /* length of data in bytes */ 462: char *out, /* output buffer, at least "t" bytes */ 463: int t 464: ) 465: { 466: WHIRLPOOL_CTX ictx, octx; 467: char iwhi[WHIRLPOOL_DIGESTSIZE], owhi[WHIRLPOOL_DIGESTSIZE]; 468: char key[WHIRLPOOL_DIGESTSIZE]; 469: char buf[WHIRLPOOL_BLOCKSIZE]; 470: int i; 471: 472: /* If the key is longer than the hash algorithm block size, 473: let key = whirlpool(key), as per HMAC specifications. */ 474: if (lk > WHIRLPOOL_BLOCKSIZE) 475: { 476: WHIRLPOOL_CTX tctx; 477: 478: WHIRLPOOL_init (&tctx); 479: WHIRLPOOL_add ((unsigned char *) k, lk * 8, &tctx); 480: WHIRLPOOL_finalize (&tctx, (unsigned char *) key); 1.1 root 481: 1.1.1.6 root 482: k = key; 483: lk = WHIRLPOOL_DIGESTSIZE; 1.1 root 484: 1.1.1.11! root 485: burn (&tctx, sizeof(tctx)); // Prevent leaks 1.1.1.6 root 486: } 1.1 root 487: 1.1.1.6 root 488: /**** Inner Digest ****/ 1.1 root 489: 1.1.1.6 root 490: WHIRLPOOL_init (&ictx); 1.1 root 491: 1.1.1.6 root 492: /* Pad the key for inner digest */ 493: for (i = 0; i < lk; ++i) 494: buf[i] = (char) (k[i] ^ 0x36); 495: for (i = lk; i < WHIRLPOOL_BLOCKSIZE; ++i) 496: buf[i] = 0x36; 1.1 root 497: 1.1.1.6 root 498: WHIRLPOOL_add ((unsigned char *) buf, WHIRLPOOL_BLOCKSIZE * 8, &ictx); 499: WHIRLPOOL_add ((unsigned char *) d, ld * 8, &ictx); 1.1 root 500: 1.1.1.6 root 501: WHIRLPOOL_finalize (&ictx, (unsigned char *) iwhi); 1.1 root 502: 1.1.1.11! root 503: /**** Outer Digest ****/ 1.1.1.3 root 504: 1.1.1.6 root 505: WHIRLPOOL_init (&octx); 1.1.1.3 root 506: 1.1.1.6 root 507: for (i = 0; i < lk; ++i) 508: buf[i] = (char) (k[i] ^ 0x5C); 509: for (i = lk; i < WHIRLPOOL_BLOCKSIZE; ++i) 510: buf[i] = 0x5C; 511: 512: WHIRLPOOL_add ((unsigned char *) buf, WHIRLPOOL_BLOCKSIZE * 8, &octx); 513: WHIRLPOOL_add ((unsigned char *) iwhi, WHIRLPOOL_DIGESTSIZE * 8, &octx); 1.1.1.3 root 514: 1.1.1.6 root 515: WHIRLPOOL_finalize (&octx, (unsigned char *) owhi); 516: 517: /* truncate and print the results */ 518: t = t > WHIRLPOOL_DIGESTSIZE ? WHIRLPOOL_DIGESTSIZE : t; 1.1.1.11! root 519: hmac_truncate (owhi, out, t); 1.1.1.6 root 520: 521: /* Prevent possible leaks. */ 1.1.1.11! root 522: burn (&ictx, sizeof(ictx)); ! 523: burn (&octx, sizeof(octx)); ! 524: burn (owhi, sizeof(owhi)); ! 525: burn (iwhi, sizeof(iwhi)); ! 526: burn (buf, sizeof(buf)); ! 527: burn (key, sizeof(key)); 1.1.1.6 root 528: } 529: 530: void derive_u_whirlpool (char *pwd, int pwd_len, char *salt, int salt_len, int iterations, char *u, int b) 1.1 root 531: { 1.1.1.6 root 532: char j[WHIRLPOOL_DIGESTSIZE], k[WHIRLPOOL_DIGESTSIZE]; 533: char init[128]; 534: char counter[4]; 535: int c, i; 536: 537: /* iteration 1 */ 538: memset (counter, 0, 4); 539: counter[3] = (char) b; 540: memcpy (init, salt, salt_len); /* salt */ 541: memcpy (&init[salt_len], counter, 4); /* big-endian block number */ 542: hmac_whirlpool (pwd, pwd_len, init, salt_len + 4, j, WHIRLPOOL_DIGESTSIZE); 543: memcpy (u, j, WHIRLPOOL_DIGESTSIZE); 1.1 root 544: 1.1.1.6 root 545: /* remaining iterations */ 546: for (c = 1; c < iterations; c++) 1.1 root 547: { 1.1.1.6 root 548: hmac_whirlpool (pwd, pwd_len, j, WHIRLPOOL_DIGESTSIZE, k, WHIRLPOOL_DIGESTSIZE); 549: for (i = 0; i < WHIRLPOOL_DIGESTSIZE; i++) 550: { 551: u[i] ^= k[i]; 552: j[i] = k[i]; 553: } 1.1 root 554: } 555: 1.1.1.6 root 556: /* Prevent possible leaks. */ 1.1.1.11! root 557: burn (j, sizeof(j)); ! 558: burn (k, sizeof(k)); 1.1 root 559: } 560: 1.1.1.6 root 561: void derive_key_whirlpool (char *pwd, int pwd_len, char *salt, int salt_len, int iterations, char *dk, int dklen) 1.1 root 562: { 1.1.1.6 root 563: char u[WHIRLPOOL_DIGESTSIZE]; 564: int b, l, r; 565: 566: if (dklen % WHIRLPOOL_DIGESTSIZE) 567: { 568: l = 1 + dklen / WHIRLPOOL_DIGESTSIZE; 569: } 570: else 1.1 root 571: { 1.1.1.6 root 572: l = dklen / WHIRLPOOL_DIGESTSIZE; 1.1 root 573: } 574: 1.1.1.6 root 575: r = dklen - (l - 1) * WHIRLPOOL_DIGESTSIZE; 1.1 root 576: 1.1.1.6 root 577: /* first l - 1 blocks */ 578: for (b = 1; b < l; b++) 579: { 580: derive_u_whirlpool (pwd, pwd_len, salt, salt_len, iterations, u, b); 581: memcpy (dk, u, WHIRLPOOL_DIGESTSIZE); 582: dk += WHIRLPOOL_DIGESTSIZE; 583: } 1.1 root 584: 1.1.1.6 root 585: /* last block */ 586: derive_u_whirlpool (pwd, pwd_len, salt, salt_len, iterations, u, b); 587: memcpy (dk, u, r); 1.1 root 588: 589: 1.1.1.6 root 590: /* Prevent possible leaks. */ 1.1.1.11! root 591: burn (u, sizeof(u)); 1.1.1.6 root 592: } 1.1 root 593: 594: 1.1.1.11! root 595: char *get_pkcs5_prf_name (int pkcs5_prf_id) 1.1.1.6 root 596: { 597: switch (pkcs5_prf_id) 598: { 1.1.1.11! root 599: case SHA512: ! 600: return "HMAC-SHA-512"; ! 601: ! 602: case SHA1: // Deprecated/legacy ! 603: return "HMAC-SHA-1"; ! 604: ! 605: case RIPEMD160: ! 606: return "HMAC-RIPEMD-160"; ! 607: ! 608: case WHIRLPOOL: ! 609: return "HMAC-Whirlpool"; ! 610: ! 611: default: ! 612: return "(Unknown)"; 1.1.1.6 root 613: } 1.1 root 614: } 615: 1.1.1.11! root 616: #endif //!TC_WINDOWS_BOOT ! 617: ! 618: ! 619: int get_pkcs5_iteration_count (int pkcs5_prf_id, BOOL bBoot) 1.1.1.6 root 620: { 621: switch (pkcs5_prf_id) 622: { 1.1.1.11! root 623: case RIPEMD160: ! 624: return (bBoot ? 1000 : 2000); ! 625: ! 626: #ifndef TC_WINDOWS_BOOT ! 627: ! 628: case SHA512: ! 629: return 1000; ! 630: ! 631: case SHA1: // Deprecated/legacy ! 632: return 2000; ! 633: ! 634: case WHIRLPOOL: ! 635: return 1000; ! 636: #endif ! 637: ! 638: default: ! 639: TC_THROW_FATAL_EXCEPTION; // Unknown/wrong ID 1.1.1.6 root 640: } 1.1.1.11! root 641: return 0; 1.1.1.6 root 642: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.