|
|
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 ! 7: TrueCrypt License 2.2 the full text of which is contained in the file ! 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.