|
|
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
1.1.1.14! root 7: this file are Copyright (c) 2003-2009 TrueCrypt Foundation and are governed
1.1.1.13 root 8: by the TrueCrypt License 2.6 the full text of which is contained in the
1.1.1.11 root 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);
1.1.1.14! root 339: RMD160Update(&tctx, (const unsigned char *) key, keylen);
1.1.1.3 root 340: RMD160Final(tk, &tctx);
341:
1.1.1.14! root 342: key = (char *) 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.14! root 373: RMD160Update(&context, (const unsigned char *) input, len); /* then text of datagram */
! 374: RMD160Final((unsigned char *) digest, &context); /* finish up 1st pass */
1.1.1.3 root 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 */
1.1.1.14! root 380: RMD160Update(&context, (const unsigned char *) digest, RIPEMD160_DIGESTSIZE);
! 381: RMD160Final((unsigned char *) 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.