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

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

unix.superglobalmegacorp.com

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