Annotation of truecrypt/common/pkcs5.c, revision 1.1.1.8

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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.