Mercurial > dropbear
comparison src/misc/pkcs5/pkcs_5_2.c @ 192:9cc34777b479 libtomcrypt
propagate from branch 'au.asn.ucc.matt.ltc-orig' (head 9ba8f01f44320e9cb9f19881105ae84f84a43ea9)
to branch 'au.asn.ucc.matt.dropbear.ltc' (head dbf51c569bc34956ad948e4cc87a0eeb2170b768)
author | Matt Johnston <matt@ucc.asn.au> |
---|---|
date | Sun, 08 May 2005 06:36:47 +0000 |
parents | 1c15b283127b |
children | 39d5d58461d6 |
comparison
equal
deleted
inserted
replaced
164:cd1143579f00 | 192:9cc34777b479 |
---|---|
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, [email protected], http://libtomcrypt.org | |
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 */ | |
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 |