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

1.1.1.9   root        1: /*
1.1.1.11  root        2:  Legal Notice: Some portions of the source code contained in this file were
                      3:  derived from the source code of Encryption for the Masses 2.02a, which is
                      4:  Copyright (c) 1998-2000 Paul Le Roux and which is governed by the 'License
                      5:  Agreement for Encryption for the Masses'. Modifications and additions to
1.1.1.17! root        6:  the original source code (contained in this file) and all other portions
        !             7:  of this file are Copyright (c) 2003-2009 TrueCrypt Developers Association
        !             8:  and are governed by the TrueCrypt License 2.8 the full text of which is
        !             9:  contained in the file License.txt included in TrueCrypt binary and source
        !            10:  code distribution packages. */
1.1       root       11: 
1.1.1.6   root       12: #include "Tcdefs.h"
1.1       root       13: 
                     14: #include <memory.h>
1.1.1.6   root       15: #include "Rmd160.h"
1.1.1.11  root       16: #ifndef TC_WINDOWS_BOOT
                     17: #include "Sha1.h"
                     18: #include "Sha2.h"
1.1.1.6   root       19: #include "Whirlpool.h"
1.1.1.11  root       20: #endif
1.1.1.6   root       21: #include "Pkcs5.h"
                     22: #include "Crypto.h"
1.1       root       23: 
1.1.1.11  root       24: void hmac_truncate
1.1       root       25:   (
                     26:          char *d1,             /* data to be truncated */
                     27:          char *d2,             /* truncated data */
                     28:          int len               /* length in bytes to keep */
                     29: )
                     30: {
                     31:        int i;
                     32:        for (i = 0; i < len; i++)
                     33:                d2[i] = d1[i];
                     34: }
                     35: 
1.1.1.11  root       36: #ifndef TC_WINDOWS_BOOT
                     37: 
                     38: void hmac_sha512
                     39: (
                     40:          char *k,              /* secret key */
                     41:          int lk,               /* length of the key in bytes */
                     42:          char *d,              /* data */
                     43:          int ld,               /* length of data in bytes */
                     44:          char *out,            /* output buffer, at least "t" bytes */
                     45:          int t
                     46: )
                     47: {
                     48:        sha512_ctx ictx, octx;
                     49:        char isha[SHA512_DIGESTSIZE], osha[SHA512_DIGESTSIZE];
                     50:        char key[SHA512_DIGESTSIZE];
                     51:        char buf[SHA512_BLOCKSIZE];
                     52:        int i;
                     53: 
                     54:     /* If the key is longer than the hash algorithm block size,
                     55:           let key = sha512(key), as per HMAC specifications. */
                     56:        if (lk > SHA512_BLOCKSIZE)
                     57:        {
                     58:                sha512_ctx tctx;
                     59: 
                     60:                sha512_begin (&tctx);
                     61:                sha512_hash ((unsigned char *) k, lk, &tctx);
                     62:                sha512_end ((unsigned char *) key, &tctx);
                     63: 
                     64:                k = key;
                     65:                lk = SHA512_DIGESTSIZE;
                     66: 
                     67:                burn (&tctx, sizeof(tctx));             // Prevent leaks
                     68:        }
                     69: 
                     70:        /**** Inner Digest ****/
                     71: 
                     72:        sha512_begin (&ictx);
                     73: 
                     74:        /* Pad the key for inner digest */
                     75:        for (i = 0; i < lk; ++i)
                     76:                buf[i] = (char) (k[i] ^ 0x36);
                     77:        for (i = lk; i < SHA512_BLOCKSIZE; ++i)
                     78:                buf[i] = 0x36;
                     79: 
                     80:        sha512_hash ((unsigned char *) buf, SHA512_BLOCKSIZE, &ictx);
                     81:        sha512_hash ((unsigned char *) d, ld, &ictx);
                     82: 
                     83:        sha512_end ((unsigned char *) isha, &ictx);
                     84: 
                     85:        /**** Outer Digest ****/
                     86: 
                     87:        sha512_begin (&octx);
                     88: 
                     89:        for (i = 0; i < lk; ++i)
                     90:                buf[i] = (char) (k[i] ^ 0x5C);
                     91:        for (i = lk; i < SHA512_BLOCKSIZE; ++i)
                     92:                buf[i] = 0x5C;
                     93: 
                     94:        sha512_hash ((unsigned char *) buf, SHA512_BLOCKSIZE, &octx);
                     95:        sha512_hash ((unsigned char *) isha, SHA512_DIGESTSIZE, &octx);
                     96: 
                     97:        sha512_end ((unsigned char *) osha, &octx);
                     98: 
                     99:        /* truncate and print the results */
                    100:        t = t > SHA512_DIGESTSIZE ? SHA512_DIGESTSIZE : t;
                    101:        hmac_truncate (osha, out, t);
                    102: 
                    103:        /* Prevent leaks */
                    104:        burn (&ictx, sizeof(ictx));
                    105:        burn (&octx, sizeof(octx));
                    106:        burn (isha, sizeof(isha));
                    107:        burn (osha, sizeof(osha));
                    108:        burn (buf, sizeof(buf));
                    109:        burn (key, sizeof(key));
                    110: }
                    111: 
                    112: 
                    113: void derive_u_sha512 (char *pwd, int pwd_len, char *salt, int salt_len, int iterations, char *u, int b)
                    114: {
                    115:        char j[SHA512_DIGESTSIZE], k[SHA512_DIGESTSIZE];
                    116:        char init[128];
                    117:        char counter[4];
                    118:        int c, i;
                    119: 
                    120:        /* iteration 1 */
                    121:        memset (counter, 0, 4);
                    122:        counter[3] = (char) b;
                    123:        memcpy (init, salt, salt_len);  /* salt */
                    124:        memcpy (&init[salt_len], counter, 4);   /* big-endian block number */
                    125:        hmac_sha512 (pwd, pwd_len, init, salt_len + 4, j, SHA512_DIGESTSIZE);
                    126:        memcpy (u, j, SHA512_DIGESTSIZE);
                    127: 
                    128:        /* remaining iterations */
                    129:        for (c = 1; c < iterations; c++)
                    130:        {
                    131:                hmac_sha512 (pwd, pwd_len, j, SHA512_DIGESTSIZE, k, SHA512_DIGESTSIZE);
                    132:                for (i = 0; i < SHA512_DIGESTSIZE; i++)
                    133:                {
                    134:                        u[i] ^= k[i];
                    135:                        j[i] = k[i];
                    136:                }
                    137:        }
                    138: 
                    139:        /* Prevent possible leaks. */
                    140:        burn (j, sizeof(j));
                    141:        burn (k, sizeof(k));
                    142: }
                    143: 
                    144: 
                    145: void derive_key_sha512 (char *pwd, int pwd_len, char *salt, int salt_len, int iterations, char *dk, int dklen)
                    146: {
                    147:        char u[SHA512_DIGESTSIZE];
                    148:        int b, l, r;
                    149: 
                    150:        if (dklen % SHA512_DIGESTSIZE)
                    151:        {
                    152:                l = 1 + dklen / SHA512_DIGESTSIZE;
                    153:        }
                    154:        else
                    155:        {
                    156:                l = dklen / SHA512_DIGESTSIZE;
                    157:        }
                    158: 
                    159:        r = dklen - (l - 1) * SHA512_DIGESTSIZE;
                    160: 
                    161:        /* first l - 1 blocks */
                    162:        for (b = 1; b < l; b++)
                    163:        {
                    164:                derive_u_sha512 (pwd, pwd_len, salt, salt_len, iterations, u, b);
                    165:                memcpy (dk, u, SHA512_DIGESTSIZE);
                    166:                dk += SHA512_DIGESTSIZE;
                    167:        }
                    168: 
                    169:        /* last block */
                    170:        derive_u_sha512 (pwd, pwd_len, salt, salt_len, iterations, u, b);
                    171:        memcpy (dk, u, r);
                    172: 
                    173: 
                    174:        /* Prevent possible leaks. */
                    175:        burn (u, sizeof(u));
                    176: }
                    177: 
                    178: 
                    179: /* Deprecated/legacy */
1.1.1.6   root      180: void hmac_sha1
                    181: (
1.1       root      182:          char *k,              /* secret key */
                    183:          int lk,               /* length of the key in bytes */
                    184:          char *d,              /* data */
                    185:          int ld,               /* length of data in bytes */
                    186:          char *out,            /* output buffer, at least "t" bytes */
                    187:          int t
                    188: )
                    189: {
1.1.1.6   root      190:        sha1_ctx ictx, octx;
                    191:        char isha[SHA1_DIGESTSIZE], osha[SHA1_DIGESTSIZE];
                    192:        char key[SHA1_DIGESTSIZE];
                    193:        char buf[SHA1_BLOCKSIZE];
1.1       root      194:        int i;
                    195: 
1.1.1.6   root      196:     /* If the key is longer than the hash algorithm block size,
                    197:           let key = sha1(key), as per HMAC specifications. */
                    198:        if (lk > SHA1_BLOCKSIZE)
                    199:        {
                    200:                sha1_ctx tctx;
                    201: 
                    202:                sha1_begin (&tctx);
                    203:                sha1_hash ((unsigned char *) k, lk, &tctx);
                    204:                sha1_end ((unsigned char *) key, &tctx);
1.1       root      205: 
                    206:                k = key;
1.1.1.6   root      207:                lk = SHA1_DIGESTSIZE;
                    208: 
1.1.1.11  root      209:                burn (&tctx, sizeof(tctx));             // Prevent leaks
1.1       root      210:        }
                    211: 
                    212:        /**** Inner Digest ****/
                    213: 
1.1.1.6   root      214:        sha1_begin (&ictx);
1.1       root      215: 
                    216:        /* Pad the key for inner digest */
                    217:        for (i = 0; i < lk; ++i)
                    218:                buf[i] = (char) (k[i] ^ 0x36);
1.1.1.6   root      219:        for (i = lk; i < SHA1_BLOCKSIZE; ++i)
1.1       root      220:                buf[i] = 0x36;
                    221: 
1.1.1.6   root      222:        sha1_hash ((unsigned char *) buf, SHA1_BLOCKSIZE, &ictx);
                    223:        sha1_hash ((unsigned char *) d, ld, &ictx);
1.1       root      224: 
1.1.1.6   root      225:        sha1_end ((unsigned char *) isha, &ictx);
1.1       root      226: 
1.1.1.11  root      227:        /**** Outer Digest ****/
1.1       root      228: 
1.1.1.6   root      229:        sha1_begin (&octx);
1.1       root      230: 
                    231:        for (i = 0; i < lk; ++i)
                    232:                buf[i] = (char) (k[i] ^ 0x5C);
1.1.1.6   root      233:        for (i = lk; i < SHA1_BLOCKSIZE; ++i)
1.1       root      234:                buf[i] = 0x5C;
                    235: 
1.1.1.6   root      236:        sha1_hash ((unsigned char *) buf, SHA1_BLOCKSIZE, &octx);
                    237:        sha1_hash ((unsigned char *) isha, SHA1_DIGESTSIZE, &octx);
1.1       root      238: 
1.1.1.6   root      239:        sha1_end ((unsigned char *) osha, &octx);
1.1       root      240: 
                    241:        /* truncate and print the results */
1.1.1.6   root      242:        t = t > SHA1_DIGESTSIZE ? SHA1_DIGESTSIZE : t;
1.1.1.11  root      243:        hmac_truncate (osha, out, t);
1.1.1.6   root      244: 
                    245:        /* Prevent leaks */
1.1.1.11  root      246:        burn (&ictx, sizeof(ictx));
                    247:        burn (&octx, sizeof(octx));
                    248:        burn (isha, sizeof(isha));
                    249:        burn (osha, sizeof(osha));
                    250:        burn (buf, sizeof(buf));
                    251:        burn (key, sizeof(key));
1.1       root      252: }
                    253: 
                    254: 
1.1.1.11  root      255: /* Deprecated/legacy */
1.1.1.6   root      256: void derive_u_sha1 (char *pwd, int pwd_len, char *salt, int salt_len, int iterations, char *u, int b)
1.1       root      257: {
1.1.1.6   root      258:        char j[SHA1_DIGESTSIZE], k[SHA1_DIGESTSIZE];
1.1       root      259:        char init[128];
                    260:        char counter[4];
                    261:        int c, i;
                    262: 
                    263:        /* iteration 1 */
                    264:        memset (counter, 0, 4);
                    265:        counter[3] = (char) b;
                    266:        memcpy (init, salt, salt_len);  /* salt */
                    267:        memcpy (&init[salt_len], counter, 4);   /* big-endian block number */
1.1.1.6   root      268:        hmac_sha1 (pwd, pwd_len, init, salt_len + 4, j, SHA1_DIGESTSIZE);
                    269:        memcpy (u, j, SHA1_DIGESTSIZE);
1.1       root      270: 
                    271:        /* remaining iterations */
                    272:        for (c = 1; c < iterations; c++)
                    273:        {
1.1.1.6   root      274:                hmac_sha1 (pwd, pwd_len, j, SHA1_DIGESTSIZE, k, SHA1_DIGESTSIZE);
                    275:                for (i = 0; i < SHA1_DIGESTSIZE; i++)
1.1       root      276:                {
                    277:                        u[i] ^= k[i];
                    278:                        j[i] = k[i];
                    279:                }
                    280:        }
1.1.1.6   root      281: 
                    282:        /* Prevent possible leaks. */
1.1.1.11  root      283:        burn (j, sizeof(j));
                    284:        burn (k, sizeof(k));
1.1       root      285: }
                    286: 
1.1.1.11  root      287: 
                    288: /* Deprecated/legacy */
1.1.1.6   root      289: void derive_key_sha1 (char *pwd, int pwd_len, char *salt, int salt_len, int iterations, char *dk, int dklen)
1.1       root      290: {
1.1.1.6   root      291:        char u[SHA1_DIGESTSIZE];
1.1       root      292:        int b, l, r;
                    293: 
1.1.1.6   root      294:        if (dklen % SHA1_DIGESTSIZE)
1.1       root      295:        {
1.1.1.6   root      296:                l = 1 + dklen / SHA1_DIGESTSIZE;
1.1       root      297:        }
                    298:        else
                    299:        {
1.1.1.6   root      300:                l = dklen / SHA1_DIGESTSIZE;
1.1       root      301:        }
                    302: 
1.1.1.6   root      303:        r = dklen - (l - 1) * SHA1_DIGESTSIZE;
1.1       root      304: 
                    305:        /* first l - 1 blocks */
                    306:        for (b = 1; b < l; b++)
                    307:        {
1.1.1.6   root      308:                derive_u_sha1 (pwd, pwd_len, salt, salt_len, iterations, u, b);
                    309:                memcpy (dk, u, SHA1_DIGESTSIZE);
                    310:                dk += SHA1_DIGESTSIZE;
1.1       root      311:        }
                    312: 
                    313:        /* last block */
1.1.1.6   root      314:        derive_u_sha1 (pwd, pwd_len, salt, salt_len, iterations, u, b);
1.1       root      315:        memcpy (dk, u, r);
                    316: 
                    317: 
1.1.1.6   root      318:        /* Prevent possible leaks. */
1.1.1.11  root      319:        burn (u, sizeof(u));
1.1.1.6   root      320: }
1.1       root      321: 
1.1.1.11  root      322: #endif // TC_WINDOWS_BOOT
                    323: 
1.1.1.6   root      324: void hmac_ripemd160 (char *key, int keylen, char *input, int len, char *digest)
1.1.1.3   root      325: {
                    326:     RMD160_CTX context;
                    327:     unsigned char k_ipad[65];  /* inner padding - key XORd with ipad */
                    328:     unsigned char k_opad[65];  /* outer padding - key XORd with opad */
1.1.1.6   root      329:     unsigned char tk[RIPEMD160_DIGESTSIZE];
1.1.1.3   root      330:     int i;
                    331: 
1.1.1.6   root      332:     /* If the key is longer than the hash algorithm block size,
                    333:           let key = ripemd160(key), as per HMAC specifications. */
                    334:     if (keylen > RIPEMD160_BLOCKSIZE) 
                    335:        {
1.1.1.3   root      336:         RMD160_CTX      tctx;
                    337: 
                    338:         RMD160Init(&tctx);
1.1.1.14  root      339:         RMD160Update(&tctx, (const unsigned char *) key, keylen);
1.1.1.3   root      340:         RMD160Final(tk, &tctx);
                    341: 
1.1.1.14  root      342:         key = (char *) tk;
1.1.1.6   root      343:         keylen = RIPEMD160_DIGESTSIZE;
                    344: 
1.1.1.11  root      345:                burn (&tctx, sizeof(tctx));     // Prevent leaks
1.1.1.3   root      346:     }
                    347: 
1.1.1.6   root      348:        /*
                    349: 
                    350:        RMD160(K XOR opad, RMD160(K XOR ipad, text))
1.1.1.3   root      351: 
1.1.1.6   root      352:        where K is an n byte key
                    353:        ipad is the byte 0x36 repeated RIPEMD160_BLOCKSIZE times
                    354:        opad is the byte 0x5c repeated RIPEMD160_BLOCKSIZE times
                    355:        and text is the data being protected */
1.1.1.3   root      356: 
                    357: 
1.1.1.6   root      358:        /* start out by storing key in pads */
                    359:        memset(k_ipad, 0x36, sizeof(k_ipad));
1.1.1.3   root      360:     memset(k_opad, 0x5c, sizeof(k_opad));
                    361: 
1.1.1.6   root      362:     /* XOR key with ipad and opad values */
                    363:     for (i=0; i<keylen; i++) 
                    364:        {
1.1.1.3   root      365:         k_ipad[i] ^= key[i];
                    366:         k_opad[i] ^= key[i];
                    367:     }
                    368: 
1.1.1.6   root      369:     /* perform inner RIPEMD-160 */
1.1.1.3   root      370: 
                    371:     RMD160Init(&context);           /* init context for 1st pass */
1.1.1.6   root      372:     RMD160Update(&context, k_ipad, RIPEMD160_BLOCKSIZE);  /* start with inner pad */
1.1.1.14  root      373:     RMD160Update(&context, (const unsigned char *) input, len); /* then text of datagram */
                    374:     RMD160Final((unsigned char *) digest, &context);         /* finish up 1st pass */
1.1.1.3   root      375: 
1.1.1.6   root      376:     /* perform outer RIPEMD-160 */
1.1.1.3   root      377:     RMD160Init(&context);           /* init context for 2nd pass */
1.1.1.6   root      378:     RMD160Update(&context, k_opad, RIPEMD160_BLOCKSIZE);  /* start with outer pad */
                    379:     /* results of 1st hash */
1.1.1.14  root      380:     RMD160Update(&context, (const unsigned char *) digest, RIPEMD160_DIGESTSIZE);
                    381:     RMD160Final((unsigned char *) digest, &context);         /* finish up 2nd pass */
1.1       root      382: 
1.1.1.6   root      383:        /* Prevent possible leaks. */
1.1.1.11  root      384:     burn (k_ipad, sizeof(k_ipad));
                    385:     burn (k_opad, sizeof(k_opad));
                    386:        burn (tk, sizeof(tk));
                    387:        burn (&context, sizeof(context));
1.1       root      388: }
                    389: 
1.1.1.6   root      390: void derive_u_ripemd160 (char *pwd, int pwd_len, char *salt, int salt_len, int iterations, char *u, int b)
1.1       root      391: {
1.1.1.6   root      392:        char j[RIPEMD160_DIGESTSIZE], k[RIPEMD160_DIGESTSIZE];
1.1       root      393:        char init[128];
                    394:        char counter[4];
                    395:        int c, i;
                    396: 
                    397:        /* iteration 1 */
                    398:        memset (counter, 0, 4);
                    399:        counter[3] = (char) b;
                    400:        memcpy (init, salt, salt_len);  /* salt */
                    401:        memcpy (&init[salt_len], counter, 4);   /* big-endian block number */
1.1.1.6   root      402:        hmac_ripemd160 (pwd, pwd_len, init, salt_len + 4, j);
                    403:        memcpy (u, j, RIPEMD160_DIGESTSIZE);
1.1       root      404: 
                    405:        /* remaining iterations */
                    406:        for (c = 1; c < iterations; c++)
                    407:        {
1.1.1.6   root      408:                hmac_ripemd160 (pwd, pwd_len, j, RIPEMD160_DIGESTSIZE, k);
                    409:                for (i = 0; i < RIPEMD160_DIGESTSIZE; i++)
1.1       root      410:                {
                    411:                        u[i] ^= k[i];
                    412:                        j[i] = k[i];
                    413:                }
                    414:        }
1.1.1.6   root      415: 
                    416:        /* Prevent possible leaks. */
1.1.1.11  root      417:        burn (j, sizeof(j));
                    418:        burn (k, sizeof(k));
1.1       root      419: }
                    420: 
1.1.1.6   root      421: void derive_key_ripemd160 (char *pwd, int pwd_len, char *salt, int salt_len, int iterations, char *dk, int dklen)
1.1       root      422: {
1.1.1.6   root      423:        char u[RIPEMD160_DIGESTSIZE];
1.1       root      424:        int b, l, r;
                    425: 
1.1.1.6   root      426:        if (dklen % RIPEMD160_DIGESTSIZE)
1.1       root      427:        {
1.1.1.6   root      428:                l = 1 + dklen / RIPEMD160_DIGESTSIZE;
1.1       root      429:        }
                    430:        else
                    431:        {
1.1.1.6   root      432:                l = dklen / RIPEMD160_DIGESTSIZE;
1.1       root      433:        }
                    434: 
1.1.1.6   root      435:        r = dklen - (l - 1) * RIPEMD160_DIGESTSIZE;
1.1       root      436: 
                    437:        /* first l - 1 blocks */
                    438:        for (b = 1; b < l; b++)
                    439:        {
1.1.1.6   root      440:                derive_u_ripemd160 (pwd, pwd_len, salt, salt_len, iterations, u, b);
                    441:                memcpy (dk, u, RIPEMD160_DIGESTSIZE);
                    442:                dk += RIPEMD160_DIGESTSIZE;
1.1       root      443:        }
                    444: 
                    445:        /* last block */
1.1.1.6   root      446:        derive_u_ripemd160 (pwd, pwd_len, salt, salt_len, iterations, u, b);
1.1       root      447:        memcpy (dk, u, r);
1.1.1.6   root      448: 
                    449: 
                    450:        /* Prevent possible leaks. */
1.1.1.11  root      451:        burn (u, sizeof(u));
1.1       root      452: }
                    453: 
1.1.1.11  root      454: #ifndef TC_WINDOWS_BOOT
                    455: 
1.1.1.6   root      456: void hmac_whirlpool
                    457: (
                    458:          char *k,              /* secret key */
                    459:          int lk,               /* length of the key in bytes */
                    460:          char *d,              /* data */
                    461:          int ld,               /* length of data in bytes */
                    462:          char *out,    /* output buffer, at least "t" bytes */
                    463:          int t
                    464: )
                    465: {
                    466:        WHIRLPOOL_CTX ictx, octx;
                    467:        char iwhi[WHIRLPOOL_DIGESTSIZE], owhi[WHIRLPOOL_DIGESTSIZE];
                    468:        char key[WHIRLPOOL_DIGESTSIZE];
                    469:        char buf[WHIRLPOOL_BLOCKSIZE];
                    470:        int i;
                    471: 
                    472:     /* If the key is longer than the hash algorithm block size,
                    473:           let key = whirlpool(key), as per HMAC specifications. */
                    474:        if (lk > WHIRLPOOL_BLOCKSIZE)
                    475:        {
                    476:                WHIRLPOOL_CTX tctx;
                    477: 
                    478:                WHIRLPOOL_init (&tctx);
                    479:                WHIRLPOOL_add ((unsigned char *) k, lk * 8, &tctx);
                    480:                WHIRLPOOL_finalize (&tctx, (unsigned char *) key);
1.1       root      481: 
1.1.1.6   root      482:                k = key;
                    483:                lk = WHIRLPOOL_DIGESTSIZE;
1.1       root      484: 
1.1.1.11  root      485:                burn (&tctx, sizeof(tctx));             // Prevent leaks
1.1.1.6   root      486:        }
1.1       root      487: 
1.1.1.6   root      488:        /**** Inner Digest ****/
1.1       root      489: 
1.1.1.6   root      490:        WHIRLPOOL_init (&ictx);
1.1       root      491: 
1.1.1.6   root      492:        /* Pad the key for inner digest */
                    493:        for (i = 0; i < lk; ++i)
                    494:                buf[i] = (char) (k[i] ^ 0x36);
                    495:        for (i = lk; i < WHIRLPOOL_BLOCKSIZE; ++i)
                    496:                buf[i] = 0x36;
1.1       root      497: 
1.1.1.6   root      498:        WHIRLPOOL_add ((unsigned char *) buf, WHIRLPOOL_BLOCKSIZE * 8, &ictx);
                    499:        WHIRLPOOL_add ((unsigned char *) d, ld * 8, &ictx);
1.1       root      500: 
1.1.1.6   root      501:        WHIRLPOOL_finalize (&ictx, (unsigned char *) iwhi);
1.1       root      502: 
1.1.1.11  root      503:        /**** Outer Digest ****/
1.1.1.3   root      504: 
1.1.1.6   root      505:        WHIRLPOOL_init (&octx);
1.1.1.3   root      506: 
1.1.1.6   root      507:        for (i = 0; i < lk; ++i)
                    508:                buf[i] = (char) (k[i] ^ 0x5C);
                    509:        for (i = lk; i < WHIRLPOOL_BLOCKSIZE; ++i)
                    510:                buf[i] = 0x5C;
                    511: 
                    512:        WHIRLPOOL_add ((unsigned char *) buf, WHIRLPOOL_BLOCKSIZE * 8, &octx);
                    513:        WHIRLPOOL_add ((unsigned char *) iwhi, WHIRLPOOL_DIGESTSIZE * 8, &octx);
1.1.1.3   root      514: 
1.1.1.6   root      515:        WHIRLPOOL_finalize (&octx, (unsigned char *) owhi);
                    516: 
                    517:        /* truncate and print the results */
                    518:        t = t > WHIRLPOOL_DIGESTSIZE ? WHIRLPOOL_DIGESTSIZE : t;
1.1.1.11  root      519:        hmac_truncate (owhi, out, t);
1.1.1.6   root      520: 
                    521:        /* Prevent possible leaks. */
1.1.1.11  root      522:        burn (&ictx, sizeof(ictx));
                    523:        burn (&octx, sizeof(octx));
                    524:        burn (owhi, sizeof(owhi));
                    525:        burn (iwhi, sizeof(iwhi));
                    526:        burn (buf, sizeof(buf));
                    527:        burn (key, sizeof(key));
1.1.1.6   root      528: }
                    529: 
                    530: void derive_u_whirlpool (char *pwd, int pwd_len, char *salt, int salt_len, int iterations, char *u, int b)
1.1       root      531: {
1.1.1.6   root      532:        char j[WHIRLPOOL_DIGESTSIZE], k[WHIRLPOOL_DIGESTSIZE];
                    533:        char init[128];
                    534:        char counter[4];
                    535:        int c, i;
                    536: 
                    537:        /* iteration 1 */
                    538:        memset (counter, 0, 4);
                    539:        counter[3] = (char) b;
                    540:        memcpy (init, salt, salt_len);  /* salt */
                    541:        memcpy (&init[salt_len], counter, 4);   /* big-endian block number */
                    542:        hmac_whirlpool (pwd, pwd_len, init, salt_len + 4, j, WHIRLPOOL_DIGESTSIZE);
                    543:        memcpy (u, j, WHIRLPOOL_DIGESTSIZE);
1.1       root      544: 
1.1.1.6   root      545:        /* remaining iterations */
                    546:        for (c = 1; c < iterations; c++)
1.1       root      547:        {
1.1.1.6   root      548:                hmac_whirlpool (pwd, pwd_len, j, WHIRLPOOL_DIGESTSIZE, k, WHIRLPOOL_DIGESTSIZE);
                    549:                for (i = 0; i < WHIRLPOOL_DIGESTSIZE; i++)
                    550:                {
                    551:                        u[i] ^= k[i];
                    552:                        j[i] = k[i];
                    553:                }
1.1       root      554:        }
                    555: 
1.1.1.6   root      556:        /* Prevent possible leaks. */
1.1.1.11  root      557:        burn (j, sizeof(j));
                    558:        burn (k, sizeof(k));
1.1       root      559: }
                    560: 
1.1.1.6   root      561: void derive_key_whirlpool (char *pwd, int pwd_len, char *salt, int salt_len, int iterations, char *dk, int dklen)
1.1       root      562: {
1.1.1.6   root      563:        char u[WHIRLPOOL_DIGESTSIZE];
                    564:        int b, l, r;
                    565: 
                    566:        if (dklen % WHIRLPOOL_DIGESTSIZE)
                    567:        {
                    568:                l = 1 + dklen / WHIRLPOOL_DIGESTSIZE;
                    569:        }
                    570:        else
1.1       root      571:        {
1.1.1.6   root      572:                l = dklen / WHIRLPOOL_DIGESTSIZE;
1.1       root      573:        }
                    574: 
1.1.1.6   root      575:        r = dklen - (l - 1) * WHIRLPOOL_DIGESTSIZE;
1.1       root      576: 
1.1.1.6   root      577:        /* first l - 1 blocks */
                    578:        for (b = 1; b < l; b++)
                    579:        {
                    580:                derive_u_whirlpool (pwd, pwd_len, salt, salt_len, iterations, u, b);
                    581:                memcpy (dk, u, WHIRLPOOL_DIGESTSIZE);
                    582:                dk += WHIRLPOOL_DIGESTSIZE;
                    583:        }
1.1       root      584: 
1.1.1.6   root      585:        /* last block */
                    586:        derive_u_whirlpool (pwd, pwd_len, salt, salt_len, iterations, u, b);
                    587:        memcpy (dk, u, r);
1.1       root      588: 
                    589: 
1.1.1.6   root      590:        /* Prevent possible leaks. */
1.1.1.11  root      591:        burn (u, sizeof(u));
1.1.1.6   root      592: }
1.1       root      593: 
                    594: 
1.1.1.11  root      595: char *get_pkcs5_prf_name (int pkcs5_prf_id)
1.1.1.6   root      596: {
                    597:        switch (pkcs5_prf_id)
                    598:        {
1.1.1.11  root      599:        case SHA512:    
                    600:                return "HMAC-SHA-512";
                    601: 
                    602:        case SHA1:      // Deprecated/legacy
                    603:                return "HMAC-SHA-1";
                    604: 
                    605:        case RIPEMD160: 
                    606:                return "HMAC-RIPEMD-160";
                    607: 
                    608:        case WHIRLPOOL: 
                    609:                return "HMAC-Whirlpool";
                    610: 
                    611:        default:                
                    612:                return "(Unknown)";
1.1.1.6   root      613:        }
1.1       root      614: }
                    615: 
1.1.1.11  root      616: #endif //!TC_WINDOWS_BOOT
                    617: 
                    618: 
                    619: int get_pkcs5_iteration_count (int pkcs5_prf_id, BOOL bBoot)
1.1.1.6   root      620: {
                    621:        switch (pkcs5_prf_id)
                    622:        {
1.1.1.11  root      623:        case RIPEMD160: 
                    624:                return (bBoot ? 1000 : 2000);
                    625: 
                    626: #ifndef TC_WINDOWS_BOOT
                    627: 
                    628:        case SHA512:    
                    629:                return 1000;                    
                    630: 
                    631:        case SHA1:              // Deprecated/legacy            
                    632:                return 2000;                    
                    633: 
                    634:        case WHIRLPOOL: 
                    635:                return 1000;
                    636: #endif
                    637: 
                    638:        default:                
                    639:                TC_THROW_FATAL_EXCEPTION;       // Unknown/wrong ID
1.1.1.6   root      640:        }
1.1.1.11  root      641:        return 0;
1.1.1.6   root      642: }

unix.superglobalmegacorp.com

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