• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
2  *
3  * LibTomCrypt is a library that provides various cryptographic
4  * algorithms in a highly modular and flexible manner.
5  *
6  * The library is free for all purposes without any express
7  * guarantee it works.
8  *
9  * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.com
10  */
11 #include <tomcrypt.h>
12 
13 /**
14    @file pkcs_5_2.c
15    PKCS #5, Algorithm #2, Tom St Denis
16 */
17 #ifdef PKCS_5
18 
19 /**
20    Execute PKCS #5 v2
21    @param password          The input password (or key)
22    @param password_len      The length of the password (octets)
23    @param salt              The salt (or nonce)
24    @param salt_len          The length of the salt (octets)
25    @param iteration_count   # of iterations desired for PKCS #5 v2 [read specs for more]
26    @param hash_idx          The index of the hash desired
27    @param out               [out] The destination for this algorithm
28    @param outlen            [in/out] The max size and resulting size of the algorithm output
29    @return CRYPT_OK if successful
30 */
pkcs_5_alg2(const unsigned char * password,unsigned long password_len,const unsigned char * salt,unsigned long salt_len,int iteration_count,int hash_idx,unsigned char * out,unsigned long * outlen)31 int pkcs_5_alg2(const unsigned char *password, unsigned long password_len,
32                 const unsigned char *salt,     unsigned long salt_len,
33                 int iteration_count,           int hash_idx,
34                 unsigned char *out,            unsigned long *outlen)
35 {
36    int err, itts;
37    ulong32  blkno;
38    unsigned long stored, left, x, y;
39    unsigned char *buf[2];
40    hmac_state    *hmac;
41 
42    LTC_ARGCHK(password != NULL);
43    LTC_ARGCHK(salt     != NULL);
44    LTC_ARGCHK(out      != NULL);
45    LTC_ARGCHK(outlen   != NULL);
46 
47    /* test hash IDX */
48    if ((err = hash_is_valid(hash_idx)) != CRYPT_OK) {
49       return err;
50    }
51 
52    buf[0] = XMALLOC(MAXBLOCKSIZE * 2);
53    hmac   = XMALLOC(sizeof(hmac_state));
54    if (hmac == NULL || buf[0] == NULL) {
55       if (hmac != NULL) {
56          XFREE(hmac);
57       }
58       if (buf[0] != NULL) {
59          XFREE(buf[0]);
60       }
61       return CRYPT_MEM;
62    }
63    /* buf[1] points to the second block of MAXBLOCKSIZE bytes */
64    buf[1] = buf[0] + MAXBLOCKSIZE;
65 
66    left   = *outlen;
67    blkno  = 1;
68    stored = 0;
69    while (left != 0) {
70        /* process block number blkno */
71        zeromem(buf[0], MAXBLOCKSIZE*2);
72 
73        /* store current block number and increment for next pass */
74        STORE32H(blkno, buf[1]);
75        ++blkno;
76 
77        /* get PRF(P, S||int(blkno)) */
78        if ((err = hmac_init(hmac, hash_idx, password, password_len)) != CRYPT_OK) {
79           goto LBL_ERR;
80        }
81        if ((err = hmac_process(hmac, salt, salt_len)) != CRYPT_OK) {
82           goto LBL_ERR;
83        }
84        if ((err = hmac_process(hmac, buf[1], 4)) != CRYPT_OK) {
85           goto LBL_ERR;
86        }
87        x = MAXBLOCKSIZE;
88        if ((err = hmac_done(hmac, buf[0], &x)) != CRYPT_OK) {
89           goto LBL_ERR;
90        }
91 
92        /* now compute repeated and XOR it in buf[1] */
93        XMEMCPY(buf[1], buf[0], x);
94        for (itts = 1; itts < iteration_count; ++itts) {
95            if ((err = hmac_memory(hash_idx, password, password_len, buf[0], x, buf[0], &x)) != CRYPT_OK) {
96               goto LBL_ERR;
97            }
98            for (y = 0; y < x; y++) {
99                buf[1][y] ^= buf[0][y];
100            }
101        }
102 
103        /* now emit upto x bytes of buf[1] to output */
104        for (y = 0; y < x && left != 0; ++y) {
105            out[stored++] = buf[1][y];
106            --left;
107        }
108    }
109    *outlen = stored;
110 
111    err = CRYPT_OK;
112 LBL_ERR:
113 #ifdef LTC_CLEAN_STACK
114    zeromem(buf[0], MAXBLOCKSIZE*2);
115    zeromem(hmac, sizeof(hmac_state));
116 #endif
117 
118    XFREE(hmac);
119    XFREE(buf[0]);
120 
121    return err;
122 }
123 
124 #endif
125 
126 
127 /* $Source: /cvs/libtom/libtomcrypt/src/misc/pkcs5/pkcs_5_2.c,v $ */
128 /* $Revision: 1.5 $ */
129 /* $Date: 2006/03/31 14:15:35 $ */
130