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