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

1.1.1.3   root        1: /* The source code contained in this file has been derived from the source code
                      2:    of Encryption for the Masses 2.02a by Paul Le Roux. Modifications and
                      3:    additions to that source code contained in this file are Copyright (c) 2004
1.1.1.4 ! root        4:    TrueCrypt Foundation and Copyright (c) 2004 TrueCrypt Team. Unmodified
1.1.1.3   root        5:    parts are Copyright (c) 1998-99 Paul Le Roux. This is a TrueCrypt Foundation
                      6:    release. Please see the file license.txt for full license details. */
1.1       root        7: 
                      8: #include "TCdefs.h"
                      9: 
                     10: #include <memory.h>
                     11: #include "sha1.h"
1.1.1.3   root       12: #include "rmd160.h"
1.1       root       13: #include "pkcs5.h"
                     14: 
                     15: void truncate
                     16:   (
                     17:          char *d1,             /* data to be truncated */
                     18:          char *d2,             /* truncated data */
                     19:          int len               /* length in bytes to keep */
                     20: )
                     21: {
                     22:        int i;
                     23:        for (i = 0; i < len; i++)
                     24:                d2[i] = d1[i];
                     25: }
                     26: 
                     27: 
                     28: /* Function to compute the digest */
                     29: void
                     30:   hmac_sha
                     31:   (
                     32:          char *k,              /* secret key */
                     33:          int lk,               /* length of the key in bytes */
                     34:          char *d,              /* data */
                     35:          int ld,               /* length of data in bytes */
                     36:          char *out,            /* output buffer, at least "t" bytes */
                     37:          int t
                     38: )
                     39: {
                     40:        SHA1_CTX ictx, octx;
                     41:        char isha[SHA_DIGESTSIZE], osha[SHA_DIGESTSIZE];
                     42:        char key[SHA_DIGESTSIZE];
                     43:        char buf[SHA_BLOCKSIZE];
                     44:        int i;
                     45: 
                     46:        if (lk > SHA_BLOCKSIZE)
                     47:        {
                     48: 
                     49:                SHA1_CTX tctx;
                     50: 
                     51:                SHA1Init (&tctx);
                     52:                SHA1Update (&tctx, (unsigned char *) k, lk);
                     53:                SHA1Final ((unsigned char *) key, &tctx);
                     54: 
                     55:                k = key;
                     56:                lk = SHA_DIGESTSIZE;
                     57:        }
                     58: 
                     59:        /**** Inner Digest ****/
                     60: 
                     61:        SHA1Init (&ictx);
                     62: 
                     63:        /* Pad the key for inner digest */
                     64:        for (i = 0; i < lk; ++i)
                     65:                buf[i] = (char) (k[i] ^ 0x36);
                     66:        for (i = lk; i < SHA_BLOCKSIZE; ++i)
                     67:                buf[i] = 0x36;
                     68: 
                     69:        SHA1Update (&ictx, (unsigned char *) buf, SHA_BLOCKSIZE);
                     70:        SHA1Update (&ictx, (unsigned char *) d, ld);
                     71: 
                     72:        SHA1Final ((unsigned char *) isha, &ictx);
                     73: 
                     74:        /**** Outter Digest ****/
                     75: 
                     76:        SHA1Init (&octx);
                     77: 
                     78:        for (i = 0; i < lk; ++i)
                     79:                buf[i] = (char) (k[i] ^ 0x5C);
                     80:        for (i = lk; i < SHA_BLOCKSIZE; ++i)
                     81:                buf[i] = 0x5C;
                     82: 
                     83:        SHA1Update (&octx, (unsigned char *) buf, SHA_BLOCKSIZE);
                     84:        SHA1Update (&octx, (unsigned char *) isha, SHA_DIGESTSIZE);
                     85: 
                     86:        SHA1Final ((unsigned char *) osha, &octx);
                     87: 
                     88:        /* truncate and print the results */
                     89:        t = t > SHA_DIGESTSIZE ? SHA_DIGESTSIZE : t;
                     90:        truncate (osha, out, t);
                     91: }
                     92: 
                     93: 
                     94: void
                     95: derive_u_sha (char *pwd, int pwd_len, char *salt, int salt_len, int iterations, char *u, int b)
                     96: {
                     97:        char j[SHA_DIGESTSIZE], k[SHA_DIGESTSIZE];
                     98:        char init[128];
                     99:        char counter[4];
                    100:        int c, i;
                    101: 
                    102:        /* iteration 1 */
                    103:        memset (counter, 0, 4);
                    104:        counter[3] = (char) b;
                    105:        memcpy (init, salt, salt_len);  /* salt */
                    106:        memcpy (&init[salt_len], counter, 4);   /* big-endian block number */
                    107:        hmac_sha (pwd, pwd_len, init, salt_len + 4, j, SHA_DIGESTSIZE);
                    108:        memcpy (u, j, SHA_DIGESTSIZE);
                    109: 
                    110:        /* remaining iterations */
                    111:        for (c = 1; c < iterations; c++)
                    112:        {
                    113:                hmac_sha (pwd, pwd_len, j, SHA_DIGESTSIZE, k, SHA_DIGESTSIZE);
                    114:                for (i = 0; i < SHA_DIGESTSIZE; i++)
                    115:                {
                    116:                        u[i] ^= k[i];
                    117:                        j[i] = k[i];
                    118:                }
                    119:        }
                    120: }
                    121: 
                    122: void
                    123: derive_sha_key (char *pwd, int pwd_len, char *salt, int salt_len, int iterations, char *dk, int dklen)
                    124: {
                    125:        char u[SHA_DIGESTSIZE];
                    126:        int b, l, r;
                    127: 
                    128:        if (dklen % SHA_DIGESTSIZE)
                    129:        {
                    130:                l = 1 + dklen / SHA_DIGESTSIZE;
                    131:        }
                    132:        else
                    133:        {
                    134:                l = dklen / SHA_DIGESTSIZE;
                    135:        }
                    136: 
                    137:        r = dklen - (l - 1) * SHA_DIGESTSIZE;
                    138: 
                    139:        /* first l - 1 blocks */
                    140:        for (b = 1; b < l; b++)
                    141:        {
                    142:                derive_u_sha (pwd, pwd_len, salt, salt_len, iterations, u, b);
                    143:                memcpy (dk, u, SHA_DIGESTSIZE);
                    144:                dk += SHA_DIGESTSIZE;
                    145:        }
                    146: 
                    147:        /* last block */
                    148:        derive_u_sha (pwd, pwd_len, salt, salt_len, iterations, u, b);
                    149:        memcpy (dk, u, r);
                    150: }
                    151: 
                    152: 
1.1.1.3   root      153: #define RMD160_DIGESTSIZE  20
1.1       root      154: 
1.1.1.3   root      155: void hmac_rmd160 (unsigned char *key, int keylen, unsigned char *input, int len, unsigned char *digest)
                    156: {
                    157:     RMD160_CTX context;
                    158:     unsigned char k_ipad[65];  /* inner padding - key XORd with ipad */
                    159:     unsigned char k_opad[65];  /* outer padding - key XORd with opad */
                    160:     unsigned char tk[RMD160_DIGESTSIZE];
                    161:     int i;
                    162: 
                    163:     /* if key is longer than 64 bytes reset it to key=SHA1(key) */
                    164:     if (keylen > 64) {
                    165:         RMD160_CTX      tctx;
                    166: 
                    167:         RMD160Init(&tctx);
                    168:         RMD160Update(&tctx, key, keylen);
                    169:         RMD160Final(tk, &tctx);
                    170: 
                    171:         key = tk;
                    172:         keylen = RMD160_DIGESTSIZE;
                    173:     }
                    174: 
                    175:         /* The HMAC_SHA1 transform looks like:
                    176: 
                    177:            RMD160(K XOR opad, RMD160(K XOR ipad, text))
                    178: 
                    179:            where K is an n byte key
                    180:            ipad is the byte 0x36 repeated 64 times
                    181:            opad is the byte 0x5c repeated 64 times
                    182:            and text is the data being protected */
                    183: 
                    184:         /* start out by storing key in pads */
                    185:     memset(k_ipad, 0x36, sizeof(k_ipad));
                    186:     memset(k_opad, 0x5c, sizeof(k_opad));
                    187: 
                    188:         /* XOR key with ipad and opad values */
                    189:     for (i=0; i<keylen; i++) {
                    190:         k_ipad[i] ^= key[i];
                    191:         k_opad[i] ^= key[i];
                    192:     }
                    193: 
                    194:         /* perform inner RIPEMD-160 */
                    195: 
                    196:     RMD160Init(&context);           /* init context for 1st pass */
                    197:     RMD160Update(&context, k_ipad, 64);  /* start with inner pad */
                    198:     RMD160Update(&context, input, len); /* then text of datagram */
                    199:     RMD160Final(digest, &context);         /* finish up 1st pass */
                    200: 
                    201:         /* perform outer RIPEMD-160 */
                    202:     RMD160Init(&context);           /* init context for 2nd pass */
                    203:     RMD160Update(&context, k_opad, 64);  /* start with outer pad */
                    204:     /* then results of 1st hash */
                    205:     RMD160Update(&context, digest, RMD160_DIGESTSIZE);
                    206:     RMD160Final(digest, &context);         /* finish up 2nd pass */
1.1       root      207: 
1.1.1.3   root      208:     memset(k_ipad, 0x00, sizeof(k_ipad));
                    209:     memset(k_opad, 0x00, sizeof(k_opad));
1.1       root      210: }
                    211: 
                    212: void
1.1.1.3   root      213: derive_u_rmd160 (char *pwd, int pwd_len, char *salt, int salt_len, int iterations, char *u, int b)
1.1       root      214: {
1.1.1.3   root      215:        char j[RMD160_DIGESTSIZE], k[RMD160_DIGESTSIZE];
1.1       root      216:        char init[128];
                    217:        char counter[4];
                    218:        int c, i;
                    219: 
                    220:        /* iteration 1 */
                    221:        memset (counter, 0, 4);
                    222:        counter[3] = (char) b;
                    223:        memcpy (init, salt, salt_len);  /* salt */
                    224:        memcpy (&init[salt_len], counter, 4);   /* big-endian block number */
1.1.1.3   root      225:        hmac_rmd160 (pwd, pwd_len, init, salt_len + 4, j);
                    226:        memcpy (u, j, RMD160_DIGESTSIZE);
1.1       root      227: 
                    228:        /* remaining iterations */
                    229:        for (c = 1; c < iterations; c++)
                    230:        {
1.1.1.3   root      231:                hmac_rmd160 (pwd, pwd_len, j, RMD160_DIGESTSIZE, k);
                    232:                for (i = 0; i < RMD160_DIGESTSIZE; i++)
1.1       root      233:                {
                    234:                        u[i] ^= k[i];
                    235:                        j[i] = k[i];
                    236:                }
                    237:        }
                    238: }
                    239: 
                    240: void
1.1.1.3   root      241: derive_rmd160_key (char *pwd, int pwd_len, char *salt, int salt_len, int iterations, char *dk, int dklen)
1.1       root      242: {
1.1.1.3   root      243:        char u[RMD160_DIGESTSIZE];
1.1       root      244:        int b, l, r;
                    245: 
1.1.1.3   root      246:        if (dklen % RMD160_DIGESTSIZE)
1.1       root      247:        {
1.1.1.3   root      248:                l = 1 + dklen / RMD160_DIGESTSIZE;
1.1       root      249:        }
                    250:        else
                    251:        {
1.1.1.3   root      252:                l = dklen / RMD160_DIGESTSIZE;
1.1       root      253:        }
                    254: 
1.1.1.3   root      255:        r = dklen - (l - 1) * RMD160_DIGESTSIZE;
1.1       root      256: 
                    257:        /* first l - 1 blocks */
                    258:        for (b = 1; b < l; b++)
                    259:        {
1.1.1.3   root      260:                derive_u_rmd160 (pwd, pwd_len, salt, salt_len, iterations, u, b);
                    261:                memcpy (dk, u, RMD160_DIGESTSIZE);
                    262:                dk += RMD160_DIGESTSIZE;
1.1       root      263:        }
                    264: 
                    265:        /* last block */
1.1.1.3   root      266:        derive_u_rmd160 (pwd, pwd_len, salt, salt_len, iterations, u, b);
1.1       root      267:        memcpy (dk, u, r);
                    268: }
                    269: 
                    270: 
                    271: 
                    272: /* rfc2104 & 2202 */
                    273: 
                    274: char *hmac_test_keys[3] =
                    275: {
                    276:        "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b",
                    277:        "Jefe",
                    278:        "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA"
                    279: };
                    280: 
                    281: 
                    282: char *hmac_test_data[3] =
                    283: {
                    284:        "Hi There",
                    285:        "what do ya want for nothing?",
                    286:        "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
                    287:       "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
                    288:        "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
                    289: };
                    290: 
                    291: 
                    292: char *hmac_sha_test_vectors[3] =
                    293: {
                    294:        "\xb6\x17\x31\x86\x55\x05\x72\x64\xe2\x8b\xc0\xb6\xfb\x37\x8c\x8e\xf1\x46\xbe\x00",
                    295:        "\xef\xfc\xdf\x6a\xe5\xeb\x2f\xa2\xd2\x74\x16\xd5\xf1\x84\xdf\x9c\x25\x9a\x7c\x79",
                    296:        "\x12\x5d\x73\x42\xb9\xac\x11\xcd\x91\xa3\x9a\xf4\x8a\xa1\x7b\x4f\x63\xf1\x75\xd3"
                    297: };
                    298: 
1.1.1.3   root      299: char *hmac_rmd160_test_keys[] =
                    300: {
                    301:        "\x00\x11\x22\x33\x44\x55\x66\x77\x88\x99\xaa\xbb\xcc\xdd\xee\xff\x01\x23\x45\x67",
                    302:        "\x01\x23\x45\x67\x89\xab\xcd\xef\xfe\xdc\xba\x98\x76\x54\x32\x10\x00\x11\x22\x33"
                    303: };
                    304: 
                    305: char *hmac_rmd160_test_data[] =
                    306: {
                    307:        "message digest",
                    308:        "12345678901234567890123456789012345678901234567890123456789012345678901234567890"
                    309: };
                    310: 
                    311: char *hmac_rmd160_test_vectors[] =
                    312: {
                    313:        "\xf8\x36\x62\xcc\x8d\x33\x9c\x22\x7e\x60\x0f\xcd\x63\x6c\x57\xd2\x57\x1b\x1c\x34",
                    314:        "\x85\xf1\x64\x70\x3e\x61\xa6\x31\x31\xbe\x7e\x45\x95\x8e\x07\x94\x12\x39\x04\xf9"
                    315: };
                    316: 
1.1       root      317: BOOL
                    318: test_hmac_sha1 ()
                    319: {
                    320:        BOOL bOK = TRUE;
                    321:        int i;
                    322: 
                    323:        for (i = 0; i < 3; i++)
                    324:        {
                    325:                char digest[SHA_DIGESTSIZE];
                    326:                hmac_sha (hmac_test_keys[i], strlen (hmac_test_keys[i]), hmac_test_data[i], strlen (hmac_test_data[i]), digest, SHA_DIGESTSIZE);
                    327:                if (memcmp (digest, hmac_sha_test_vectors[i], SHA_DIGESTSIZE) != 0)
                    328:                        return FALSE;
                    329:        }
                    330: 
                    331:        return TRUE;
                    332: }
                    333: 
                    334: BOOL
1.1.1.3   root      335: test_hmac_rmd160 ()
1.1       root      336: {
                    337:        int i;
1.1.1.3   root      338:        for (i = 0; i < sizeof (hmac_rmd160_test_data) / sizeof(char *); i++)
1.1       root      339:        {
1.1.1.3   root      340:                char digest[RMD160_DIGESTSIZE];
                    341:                hmac_rmd160 (hmac_rmd160_test_keys[i], 20, hmac_rmd160_test_data[i], strlen (hmac_rmd160_test_data[i]), digest);
                    342:                if (memcmp (digest, hmac_rmd160_test_vectors[i], RMD160_DIGESTSIZE) != 0)
1.1       root      343:                        return FALSE;
                    344:        }
                    345: 
                    346:        return TRUE;
                    347: }
                    348: 
                    349: BOOL
                    350: test_pkcs5 ()
                    351: {
                    352:        char dk[4];
                    353: 
                    354:        /* First make sure the hmacs are ok */
                    355:        if (test_hmac_sha1 ()== FALSE)
                    356:                return FALSE;
1.1.1.3   root      357:        if (test_hmac_rmd160 ()== FALSE)
1.1       root      358:                return FALSE;
                    359: 
                    360:        /* Next check the sha1 with pkcs5 */
                    361:        derive_sha_key ("password", 8, "\x12\x34\x56\x78", 4, 5, dk, 4);
                    362:        if (memcmp (dk, "\x5c\x75\xce\xf0", 4) != 0)
                    363:                return FALSE;
                    364: 
1.1.1.3   root      365:        /* Next check ripemd160 with pkcs5 */
1.1.1.4 ! root      366:        derive_rmd160_key ("password", 8, "\x12\x34\x56\x78", 4, 5, dk, 4);
        !           367:        if (memcmp (dk, "\x7a\x3d\x7c\x03", 4) != 0)
1.1       root      368:                return FALSE;
                    369: 
                    370:        return TRUE;
                    371: 
                    372: }
                    373: 

unix.superglobalmegacorp.com

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