|
|
1.1.1.9 root 1: /*
2: Legal Notice: The source code contained in this file has been derived from
3: the source code of Encryption for the Masses 2.02a, which is Copyright (c)
4: Paul Le Roux and which is covered by the 'License Agreement for Encryption
5: for the Masses'. Modifications and additions to that source code contained
6: in this file are Copyright (c) TrueCrypt Foundation and are covered by the
1.1.1.10! root 7: TrueCrypt License 2.3 the full text of which is contained in the file
1.1.1.9 root 8: License.txt included in TrueCrypt binary and source code distribution
9: packages. */
1.1 root 10:
1.1.1.6 root 11: #include "Tcdefs.h"
1.1 root 12:
13: #include <memory.h>
1.1.1.6 root 14: #include "Sha1.h"
15: #include "Rmd160.h"
16: #include "Whirlpool.h"
17: #include "Pkcs5.h"
18: #include "Crypto.h"
1.1 root 19:
20: void truncate
21: (
22: char *d1, /* data to be truncated */
23: char *d2, /* truncated data */
24: int len /* length in bytes to keep */
25: )
26: {
27: int i;
28: for (i = 0; i < len; i++)
29: d2[i] = d1[i];
30: }
31:
1.1.1.6 root 32: void hmac_sha1
33: (
1.1 root 34: char *k, /* secret key */
35: int lk, /* length of the key in bytes */
36: char *d, /* data */
37: int ld, /* length of data in bytes */
38: char *out, /* output buffer, at least "t" bytes */
39: int t
40: )
41: {
1.1.1.6 root 42: sha1_ctx ictx, octx;
43: char isha[SHA1_DIGESTSIZE], osha[SHA1_DIGESTSIZE];
44: char key[SHA1_DIGESTSIZE];
45: char buf[SHA1_BLOCKSIZE];
1.1 root 46: int i;
47:
1.1.1.6 root 48: /* If the key is longer than the hash algorithm block size,
49: let key = sha1(key), as per HMAC specifications. */
50: if (lk > SHA1_BLOCKSIZE)
51: {
52: sha1_ctx tctx;
53:
54: sha1_begin (&tctx);
55: sha1_hash ((unsigned char *) k, lk, &tctx);
56: sha1_end ((unsigned char *) key, &tctx);
1.1 root 57:
58: k = key;
1.1.1.6 root 59: lk = SHA1_DIGESTSIZE;
60:
61: memset (&tctx, 0, sizeof(tctx)); // Prevent leaks
1.1 root 62: }
63:
64: /**** Inner Digest ****/
65:
1.1.1.6 root 66: sha1_begin (&ictx);
1.1 root 67:
68: /* Pad the key for inner digest */
69: for (i = 0; i < lk; ++i)
70: buf[i] = (char) (k[i] ^ 0x36);
1.1.1.6 root 71: for (i = lk; i < SHA1_BLOCKSIZE; ++i)
1.1 root 72: buf[i] = 0x36;
73:
1.1.1.6 root 74: sha1_hash ((unsigned char *) buf, SHA1_BLOCKSIZE, &ictx);
75: sha1_hash ((unsigned char *) d, ld, &ictx);
1.1 root 76:
1.1.1.6 root 77: sha1_end ((unsigned char *) isha, &ictx);
1.1 root 78:
79: /**** Outter Digest ****/
80:
1.1.1.6 root 81: sha1_begin (&octx);
1.1 root 82:
83: for (i = 0; i < lk; ++i)
84: buf[i] = (char) (k[i] ^ 0x5C);
1.1.1.6 root 85: for (i = lk; i < SHA1_BLOCKSIZE; ++i)
1.1 root 86: buf[i] = 0x5C;
87:
1.1.1.6 root 88: sha1_hash ((unsigned char *) buf, SHA1_BLOCKSIZE, &octx);
89: sha1_hash ((unsigned char *) isha, SHA1_DIGESTSIZE, &octx);
1.1 root 90:
1.1.1.6 root 91: sha1_end ((unsigned char *) osha, &octx);
1.1 root 92:
93: /* truncate and print the results */
1.1.1.6 root 94: t = t > SHA1_DIGESTSIZE ? SHA1_DIGESTSIZE : t;
1.1 root 95: truncate (osha, out, t);
1.1.1.6 root 96:
97: /* Prevent leaks */
98: memset (&ictx, 0, sizeof(ictx));
99: memset (&octx, 0, sizeof(octx));
100: memset (isha, 0, sizeof(isha));
101: memset (osha, 0, sizeof(osha));
102: memset (buf, 0, sizeof(buf));
103: memset (key, 0, sizeof(key));
1.1 root 104: }
105:
106:
1.1.1.6 root 107: void derive_u_sha1 (char *pwd, int pwd_len, char *salt, int salt_len, int iterations, char *u, int b)
1.1 root 108: {
1.1.1.6 root 109: char j[SHA1_DIGESTSIZE], k[SHA1_DIGESTSIZE];
1.1 root 110: char init[128];
111: char counter[4];
112: int c, i;
113:
114: /* iteration 1 */
115: memset (counter, 0, 4);
116: counter[3] = (char) b;
117: memcpy (init, salt, salt_len); /* salt */
118: memcpy (&init[salt_len], counter, 4); /* big-endian block number */
1.1.1.6 root 119: hmac_sha1 (pwd, pwd_len, init, salt_len + 4, j, SHA1_DIGESTSIZE);
120: memcpy (u, j, SHA1_DIGESTSIZE);
1.1 root 121:
122: /* remaining iterations */
123: for (c = 1; c < iterations; c++)
124: {
1.1.1.6 root 125: hmac_sha1 (pwd, pwd_len, j, SHA1_DIGESTSIZE, k, SHA1_DIGESTSIZE);
126: for (i = 0; i < SHA1_DIGESTSIZE; i++)
1.1 root 127: {
128: u[i] ^= k[i];
129: j[i] = k[i];
130: }
131: }
1.1.1.6 root 132:
133: /* Prevent possible leaks. */
134: memset (j, 0, sizeof(j));
135: memset (k, 0, sizeof(k));
1.1 root 136: }
137:
1.1.1.6 root 138: void derive_key_sha1 (char *pwd, int pwd_len, char *salt, int salt_len, int iterations, char *dk, int dklen)
1.1 root 139: {
1.1.1.6 root 140: char u[SHA1_DIGESTSIZE];
1.1 root 141: int b, l, r;
142:
1.1.1.6 root 143: if (dklen % SHA1_DIGESTSIZE)
1.1 root 144: {
1.1.1.6 root 145: l = 1 + dklen / SHA1_DIGESTSIZE;
1.1 root 146: }
147: else
148: {
1.1.1.6 root 149: l = dklen / SHA1_DIGESTSIZE;
1.1 root 150: }
151:
1.1.1.6 root 152: r = dklen - (l - 1) * SHA1_DIGESTSIZE;
1.1 root 153:
154: /* first l - 1 blocks */
155: for (b = 1; b < l; b++)
156: {
1.1.1.6 root 157: derive_u_sha1 (pwd, pwd_len, salt, salt_len, iterations, u, b);
158: memcpy (dk, u, SHA1_DIGESTSIZE);
159: dk += SHA1_DIGESTSIZE;
1.1 root 160: }
161:
162: /* last block */
1.1.1.6 root 163: derive_u_sha1 (pwd, pwd_len, salt, salt_len, iterations, u, b);
1.1 root 164: memcpy (dk, u, r);
165:
166:
1.1.1.6 root 167: /* Prevent possible leaks. */
168: memset (u, 0, sizeof(u));
169: }
1.1 root 170:
1.1.1.6 root 171: void hmac_ripemd160 (char *key, int keylen, char *input, int len, char *digest)
1.1.1.3 root 172: {
173: RMD160_CTX context;
174: unsigned char k_ipad[65]; /* inner padding - key XORd with ipad */
175: unsigned char k_opad[65]; /* outer padding - key XORd with opad */
1.1.1.6 root 176: unsigned char tk[RIPEMD160_DIGESTSIZE];
1.1.1.3 root 177: int i;
178:
1.1.1.6 root 179: /* If the key is longer than the hash algorithm block size,
180: let key = ripemd160(key), as per HMAC specifications. */
181: if (keylen > RIPEMD160_BLOCKSIZE)
182: {
1.1.1.3 root 183: RMD160_CTX tctx;
184:
185: RMD160Init(&tctx);
186: RMD160Update(&tctx, key, keylen);
187: RMD160Final(tk, &tctx);
188:
189: key = tk;
1.1.1.6 root 190: keylen = RIPEMD160_DIGESTSIZE;
191:
192: memset (&tctx, 0, sizeof(tctx)); // Prevent leaks
1.1.1.3 root 193: }
194:
1.1.1.6 root 195: /*
196:
197: RMD160(K XOR opad, RMD160(K XOR ipad, text))
1.1.1.3 root 198:
1.1.1.6 root 199: where K is an n byte key
200: ipad is the byte 0x36 repeated RIPEMD160_BLOCKSIZE times
201: opad is the byte 0x5c repeated RIPEMD160_BLOCKSIZE times
202: and text is the data being protected */
1.1.1.3 root 203:
204:
1.1.1.6 root 205: /* start out by storing key in pads */
206: memset(k_ipad, 0x36, sizeof(k_ipad));
1.1.1.3 root 207: memset(k_opad, 0x5c, sizeof(k_opad));
208:
1.1.1.6 root 209: /* XOR key with ipad and opad values */
210: for (i=0; i<keylen; i++)
211: {
1.1.1.3 root 212: k_ipad[i] ^= key[i];
213: k_opad[i] ^= key[i];
214: }
215:
1.1.1.6 root 216: /* perform inner RIPEMD-160 */
1.1.1.3 root 217:
218: RMD160Init(&context); /* init context for 1st pass */
1.1.1.6 root 219: RMD160Update(&context, k_ipad, RIPEMD160_BLOCKSIZE); /* start with inner pad */
1.1.1.3 root 220: RMD160Update(&context, input, len); /* then text of datagram */
221: RMD160Final(digest, &context); /* finish up 1st pass */
222:
1.1.1.6 root 223: /* perform outer RIPEMD-160 */
1.1.1.3 root 224: RMD160Init(&context); /* init context for 2nd pass */
1.1.1.6 root 225: RMD160Update(&context, k_opad, RIPEMD160_BLOCKSIZE); /* start with outer pad */
226: /* results of 1st hash */
227: RMD160Update(&context, digest, RIPEMD160_DIGESTSIZE);
1.1.1.3 root 228: RMD160Final(digest, &context); /* finish up 2nd pass */
1.1 root 229:
1.1.1.6 root 230: /* Prevent possible leaks. */
231: memset(k_ipad, 0, sizeof(k_ipad));
232: memset(k_opad, 0, sizeof(k_opad));
233: memset (tk, 0, sizeof(tk));
234: memset (&context, 0, sizeof(context));
1.1 root 235: }
236:
1.1.1.6 root 237: void derive_u_ripemd160 (char *pwd, int pwd_len, char *salt, int salt_len, int iterations, char *u, int b)
1.1 root 238: {
1.1.1.6 root 239: char j[RIPEMD160_DIGESTSIZE], k[RIPEMD160_DIGESTSIZE];
1.1 root 240: char init[128];
241: char counter[4];
242: int c, i;
243:
244: /* iteration 1 */
245: memset (counter, 0, 4);
246: counter[3] = (char) b;
247: memcpy (init, salt, salt_len); /* salt */
248: memcpy (&init[salt_len], counter, 4); /* big-endian block number */
1.1.1.6 root 249: hmac_ripemd160 (pwd, pwd_len, init, salt_len + 4, j);
250: memcpy (u, j, RIPEMD160_DIGESTSIZE);
1.1 root 251:
252: /* remaining iterations */
253: for (c = 1; c < iterations; c++)
254: {
1.1.1.6 root 255: hmac_ripemd160 (pwd, pwd_len, j, RIPEMD160_DIGESTSIZE, k);
256: for (i = 0; i < RIPEMD160_DIGESTSIZE; i++)
1.1 root 257: {
258: u[i] ^= k[i];
259: j[i] = k[i];
260: }
261: }
1.1.1.6 root 262:
263: /* Prevent possible leaks. */
264: memset (j, 0, sizeof(j));
265: memset (k, 0, sizeof(k));
1.1 root 266: }
267:
1.1.1.6 root 268: void derive_key_ripemd160 (char *pwd, int pwd_len, char *salt, int salt_len, int iterations, char *dk, int dklen)
1.1 root 269: {
1.1.1.6 root 270: char u[RIPEMD160_DIGESTSIZE];
1.1 root 271: int b, l, r;
272:
1.1.1.6 root 273: if (dklen % RIPEMD160_DIGESTSIZE)
1.1 root 274: {
1.1.1.6 root 275: l = 1 + dklen / RIPEMD160_DIGESTSIZE;
1.1 root 276: }
277: else
278: {
1.1.1.6 root 279: l = dklen / RIPEMD160_DIGESTSIZE;
1.1 root 280: }
281:
1.1.1.6 root 282: r = dklen - (l - 1) * RIPEMD160_DIGESTSIZE;
1.1 root 283:
284: /* first l - 1 blocks */
285: for (b = 1; b < l; b++)
286: {
1.1.1.6 root 287: derive_u_ripemd160 (pwd, pwd_len, salt, salt_len, iterations, u, b);
288: memcpy (dk, u, RIPEMD160_DIGESTSIZE);
289: dk += RIPEMD160_DIGESTSIZE;
1.1 root 290: }
291:
292: /* last block */
1.1.1.6 root 293: derive_u_ripemd160 (pwd, pwd_len, salt, salt_len, iterations, u, b);
1.1 root 294: memcpy (dk, u, r);
1.1.1.6 root 295:
296:
297: /* Prevent possible leaks. */
298: memset (u, 0, sizeof(u));
1.1 root 299: }
300:
1.1.1.6 root 301: void hmac_whirlpool
302: (
303: char *k, /* secret key */
304: int lk, /* length of the key in bytes */
305: char *d, /* data */
306: int ld, /* length of data in bytes */
307: char *out, /* output buffer, at least "t" bytes */
308: int t
309: )
310: {
311: WHIRLPOOL_CTX ictx, octx;
312: char iwhi[WHIRLPOOL_DIGESTSIZE], owhi[WHIRLPOOL_DIGESTSIZE];
313: char key[WHIRLPOOL_DIGESTSIZE];
314: char buf[WHIRLPOOL_BLOCKSIZE];
315: int i;
316:
317: /* If the key is longer than the hash algorithm block size,
318: let key = whirlpool(key), as per HMAC specifications. */
319: if (lk > WHIRLPOOL_BLOCKSIZE)
320: {
321: WHIRLPOOL_CTX tctx;
322:
323: WHIRLPOOL_init (&tctx);
324: WHIRLPOOL_add ((unsigned char *) k, lk * 8, &tctx);
325: WHIRLPOOL_finalize (&tctx, (unsigned char *) key);
1.1 root 326:
1.1.1.6 root 327: k = key;
328: lk = WHIRLPOOL_DIGESTSIZE;
1.1 root 329:
1.1.1.6 root 330: memset (&tctx, 0, sizeof(tctx)); // Prevent leaks
331: }
1.1 root 332:
1.1.1.6 root 333: /**** Inner Digest ****/
1.1 root 334:
1.1.1.6 root 335: WHIRLPOOL_init (&ictx);
1.1 root 336:
1.1.1.6 root 337: /* Pad the key for inner digest */
338: for (i = 0; i < lk; ++i)
339: buf[i] = (char) (k[i] ^ 0x36);
340: for (i = lk; i < WHIRLPOOL_BLOCKSIZE; ++i)
341: buf[i] = 0x36;
1.1 root 342:
1.1.1.6 root 343: WHIRLPOOL_add ((unsigned char *) buf, WHIRLPOOL_BLOCKSIZE * 8, &ictx);
344: WHIRLPOOL_add ((unsigned char *) d, ld * 8, &ictx);
1.1 root 345:
1.1.1.6 root 346: WHIRLPOOL_finalize (&ictx, (unsigned char *) iwhi);
1.1 root 347:
1.1.1.6 root 348: /**** Outter Digest ****/
1.1.1.3 root 349:
1.1.1.6 root 350: WHIRLPOOL_init (&octx);
1.1.1.3 root 351:
1.1.1.6 root 352: for (i = 0; i < lk; ++i)
353: buf[i] = (char) (k[i] ^ 0x5C);
354: for (i = lk; i < WHIRLPOOL_BLOCKSIZE; ++i)
355: buf[i] = 0x5C;
356:
357: WHIRLPOOL_add ((unsigned char *) buf, WHIRLPOOL_BLOCKSIZE * 8, &octx);
358: WHIRLPOOL_add ((unsigned char *) iwhi, WHIRLPOOL_DIGESTSIZE * 8, &octx);
1.1.1.3 root 359:
1.1.1.6 root 360: WHIRLPOOL_finalize (&octx, (unsigned char *) owhi);
361:
362: /* truncate and print the results */
363: t = t > WHIRLPOOL_DIGESTSIZE ? WHIRLPOOL_DIGESTSIZE : t;
364: truncate (owhi, out, t);
365:
366: /* Prevent possible leaks. */
367: memset (&ictx, 0, sizeof(ictx));
368: memset (&octx, 0, sizeof(octx));
369: memset (owhi, 0, sizeof(owhi));
370: memset (iwhi, 0, sizeof(iwhi));
371: memset (buf, 0, sizeof(buf));
372: memset (key, 0, sizeof(key));
373: }
374:
375: void derive_u_whirlpool (char *pwd, int pwd_len, char *salt, int salt_len, int iterations, char *u, int b)
1.1 root 376: {
1.1.1.6 root 377: char j[WHIRLPOOL_DIGESTSIZE], k[WHIRLPOOL_DIGESTSIZE];
378: char init[128];
379: char counter[4];
380: int c, i;
381:
382: /* iteration 1 */
383: memset (counter, 0, 4);
384: counter[3] = (char) b;
385: memcpy (init, salt, salt_len); /* salt */
386: memcpy (&init[salt_len], counter, 4); /* big-endian block number */
387: hmac_whirlpool (pwd, pwd_len, init, salt_len + 4, j, WHIRLPOOL_DIGESTSIZE);
388: memcpy (u, j, WHIRLPOOL_DIGESTSIZE);
1.1 root 389:
1.1.1.6 root 390: /* remaining iterations */
391: for (c = 1; c < iterations; c++)
1.1 root 392: {
1.1.1.6 root 393: hmac_whirlpool (pwd, pwd_len, j, WHIRLPOOL_DIGESTSIZE, k, WHIRLPOOL_DIGESTSIZE);
394: for (i = 0; i < WHIRLPOOL_DIGESTSIZE; i++)
395: {
396: u[i] ^= k[i];
397: j[i] = k[i];
398: }
1.1 root 399: }
400:
1.1.1.6 root 401: /* Prevent possible leaks. */
402: memset (j, 0, sizeof(j));
403: memset (k, 0, sizeof(k));
1.1 root 404: }
405:
1.1.1.6 root 406: void derive_key_whirlpool (char *pwd, int pwd_len, char *salt, int salt_len, int iterations, char *dk, int dklen)
1.1 root 407: {
1.1.1.6 root 408: char u[WHIRLPOOL_DIGESTSIZE];
409: int b, l, r;
410:
411: if (dklen % WHIRLPOOL_DIGESTSIZE)
412: {
413: l = 1 + dklen / WHIRLPOOL_DIGESTSIZE;
414: }
415: else
1.1 root 416: {
1.1.1.6 root 417: l = dklen / WHIRLPOOL_DIGESTSIZE;
1.1 root 418: }
419:
1.1.1.6 root 420: r = dklen - (l - 1) * WHIRLPOOL_DIGESTSIZE;
1.1 root 421:
1.1.1.6 root 422: /* first l - 1 blocks */
423: for (b = 1; b < l; b++)
424: {
425: derive_u_whirlpool (pwd, pwd_len, salt, salt_len, iterations, u, b);
426: memcpy (dk, u, WHIRLPOOL_DIGESTSIZE);
427: dk += WHIRLPOOL_DIGESTSIZE;
428: }
1.1 root 429:
1.1.1.6 root 430: /* last block */
431: derive_u_whirlpool (pwd, pwd_len, salt, salt_len, iterations, u, b);
432: memcpy (dk, u, r);
1.1 root 433:
434:
1.1.1.6 root 435: /* Prevent possible leaks. */
436: memset (u, 0, sizeof(u));
437: }
1.1 root 438:
439:
1.1.1.6 root 440: int get_pkcs5_iteration_count (int pkcs5_prf_id)
441: {
442: switch (pkcs5_prf_id)
443: {
444: case SHA1: return 2000;
445: case RIPEMD160: return 2000;
446: case WHIRLPOOL: return 1000;
447: default: return 0;
448: }
1.1 root 449: }
450:
1.1.1.6 root 451: char *get_pkcs5_prf_name (int pkcs5_prf_id)
452: {
453: switch (pkcs5_prf_id)
454: {
455: case SHA1: return "HMAC-SHA-1";
456: case RIPEMD160: return "HMAC-RIPEMD-160";
457: case WHIRLPOOL: return "HMAC-Whirlpool";
458: default: return "Unknown";
459: }
460: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.