3
|
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 |
|
12 #include "mycrypt.h" |
|
13 |
|
14 #ifdef YARROW |
|
15 |
|
16 const struct _prng_descriptor yarrow_desc = |
|
17 { |
143
|
18 "yarrow", 64, |
3
|
19 &yarrow_start, |
|
20 &yarrow_add_entropy, |
|
21 &yarrow_ready, |
143
|
22 &yarrow_read, |
|
23 &yarrow_done, |
|
24 &yarrow_export, |
|
25 &yarrow_import, |
|
26 &yarrow_test |
3
|
27 }; |
|
28 |
|
29 int yarrow_start(prng_state *prng) |
|
30 { |
|
31 int err; |
|
32 |
|
33 _ARGCHK(prng != NULL); |
|
34 |
|
35 /* these are the default hash/cipher combo used */ |
|
36 #ifdef RIJNDAEL |
15
|
37 #if YARROW_AES==0 |
|
38 prng->yarrow.cipher = register_cipher(&rijndael_enc_desc); |
|
39 #elif YARROW_AES==1 |
|
40 prng->yarrow.cipher = register_cipher(&aes_enc_desc); |
|
41 #elif YARROW_AES==2 |
3
|
42 prng->yarrow.cipher = register_cipher(&rijndael_desc); |
15
|
43 #elif YARROW_AES==3 |
|
44 prng->yarrow.cipher = register_cipher(&aes_desc); |
|
45 #endif |
3
|
46 #elif defined(BLOWFISH) |
|
47 prng->yarrow.cipher = register_cipher(&blowfish_desc); |
|
48 #elif defined(TWOFISH) |
|
49 prng->yarrow.cipher = register_cipher(&twofish_desc); |
|
50 #elif defined(RC6) |
|
51 prng->yarrow.cipher = register_cipher(&rc6_desc); |
|
52 #elif defined(RC5) |
|
53 prng->yarrow.cipher = register_cipher(&rc5_desc); |
|
54 #elif defined(SAFERP) |
|
55 prng->yarrow.cipher = register_cipher(&saferp_desc); |
|
56 #elif defined(RC2) |
|
57 prng->yarrow.cipher = register_cipher(&rc2_desc); |
|
58 #elif defined(NOEKEON) |
|
59 prng->yarrow.cipher = register_cipher(&noekeon_desc); |
|
60 #elif defined(CAST5) |
|
61 prng->yarrow.cipher = register_cipher(&cast5_desc); |
|
62 #elif defined(XTEA) |
|
63 prng->yarrow.cipher = register_cipher(&xtea_desc); |
|
64 #elif defined(SAFER) |
|
65 prng->yarrow.cipher = register_cipher(&safer_sk128_desc); |
|
66 #elif defined(DES) |
|
67 prng->yarrow.cipher = register_cipher(&des3_desc); |
143
|
68 #else |
3
|
69 #error YARROW needs at least one CIPHER |
|
70 #endif |
|
71 if ((err = cipher_is_valid(prng->yarrow.cipher)) != CRYPT_OK) { |
|
72 return err; |
|
73 } |
|
74 |
|
75 #ifdef SHA256 |
|
76 prng->yarrow.hash = register_hash(&sha256_desc); |
|
77 #elif defined(SHA512) |
|
78 prng->yarrow.hash = register_hash(&sha512_desc); |
|
79 #elif defined(TIGER) |
|
80 prng->yarrow.hash = register_hash(&tiger_desc); |
|
81 #elif defined(SHA1) |
|
82 prng->yarrow.hash = register_hash(&sha1_desc); |
|
83 #elif defined(RIPEMD160) |
|
84 prng->yarrow.hash = register_hash(&rmd160_desc); |
|
85 #elif defined(RIPEMD128) |
|
86 prng->yarrow.hash = register_hash(&rmd128_desc); |
|
87 #elif defined(MD5) |
|
88 prng->yarrow.hash = register_hash(&md5_desc); |
|
89 #elif defined(MD4) |
|
90 prng->yarrow.hash = register_hash(&md4_desc); |
|
91 #elif defined(MD2) |
|
92 prng->yarrow.hash = register_hash(&md2_desc); |
15
|
93 #elif defined(WHIRLPOOL) |
|
94 prng->yarrow.hash = register_hash(&whirlpool_desc); |
3
|
95 #else |
|
96 #error YARROW needs at least one HASH |
|
97 #endif |
|
98 if ((err = hash_is_valid(prng->yarrow.hash)) != CRYPT_OK) { |
|
99 return err; |
|
100 } |
|
101 |
|
102 /* zero the memory used */ |
|
103 zeromem(prng->yarrow.pool, sizeof(prng->yarrow.pool)); |
|
104 |
|
105 return CRYPT_OK; |
|
106 } |
|
107 |
|
108 int yarrow_add_entropy(const unsigned char *buf, unsigned long len, prng_state *prng) |
|
109 { |
|
110 hash_state md; |
|
111 int err; |
|
112 |
|
113 _ARGCHK(buf != NULL); |
|
114 _ARGCHK(prng != NULL); |
|
115 |
|
116 if ((err = hash_is_valid(prng->yarrow.hash)) != CRYPT_OK) { |
|
117 return err; |
|
118 } |
|
119 |
|
120 /* start the hash */ |
143
|
121 if ((err = hash_descriptor[prng->yarrow.hash].init(&md)) != CRYPT_OK) { |
|
122 return err; |
|
123 } |
3
|
124 |
|
125 /* hash the current pool */ |
15
|
126 if ((err = hash_descriptor[prng->yarrow.hash].process(&md, prng->yarrow.pool, |
|
127 hash_descriptor[prng->yarrow.hash].hashsize)) != CRYPT_OK) { |
|
128 return err; |
|
129 } |
3
|
130 |
|
131 /* add the new entropy */ |
15
|
132 if ((err = hash_descriptor[prng->yarrow.hash].process(&md, buf, len)) != CRYPT_OK) { |
|
133 return err; |
|
134 } |
3
|
135 |
|
136 /* store result */ |
15
|
137 if ((err = hash_descriptor[prng->yarrow.hash].done(&md, prng->yarrow.pool)) != CRYPT_OK) { |
|
138 return err; |
|
139 } |
3
|
140 |
|
141 return CRYPT_OK; |
|
142 } |
|
143 |
|
144 int yarrow_ready(prng_state *prng) |
|
145 { |
|
146 int ks, err; |
|
147 |
|
148 _ARGCHK(prng != NULL); |
|
149 |
|
150 if ((err = hash_is_valid(prng->yarrow.hash)) != CRYPT_OK) { |
|
151 return err; |
|
152 } |
|
153 |
|
154 if ((err = cipher_is_valid(prng->yarrow.cipher)) != CRYPT_OK) { |
|
155 return err; |
|
156 } |
|
157 |
|
158 /* setup CTR mode using the "pool" as the key */ |
|
159 ks = (int)hash_descriptor[prng->yarrow.hash].hashsize; |
|
160 if ((err = cipher_descriptor[prng->yarrow.cipher].keysize(&ks)) != CRYPT_OK) { |
|
161 return err; |
|
162 } |
|
163 |
|
164 if ((err = ctr_start(prng->yarrow.cipher, /* what cipher to use */ |
|
165 prng->yarrow.pool, /* IV */ |
|
166 prng->yarrow.pool, ks, /* KEY and key size */ |
|
167 0, /* number of rounds */ |
|
168 &prng->yarrow.ctr)) != CRYPT_OK) { |
|
169 return err; |
|
170 } |
|
171 return CRYPT_OK; |
|
172 } |
|
173 |
|
174 unsigned long yarrow_read(unsigned char *buf, unsigned long len, prng_state *prng) |
|
175 { |
|
176 _ARGCHK(buf != NULL); |
|
177 _ARGCHK(prng != NULL); |
|
178 |
|
179 /* put buf in predictable state first */ |
|
180 zeromem(buf, len); |
|
181 |
|
182 /* now randomize it */ |
|
183 if (ctr_encrypt(buf, buf, len, &prng->yarrow.ctr) != CRYPT_OK) { |
|
184 return 0; |
|
185 } |
|
186 return len; |
|
187 } |
|
188 |
143
|
189 int yarrow_done(prng_state *prng) |
|
190 { |
|
191 _ARGCHK(prng != NULL); |
|
192 /* call cipher done when we invent one ;-) */ |
|
193 |
|
194 return CRYPT_OK; |
|
195 } |
|
196 |
|
197 int yarrow_export(unsigned char *out, unsigned long *outlen, prng_state *prng) |
|
198 { |
|
199 _ARGCHK(out != NULL); |
|
200 _ARGCHK(outlen != NULL); |
|
201 _ARGCHK(prng != NULL); |
|
202 |
|
203 /* we'll write 64 bytes for s&g's */ |
|
204 if (*outlen < 64) { |
|
205 return CRYPT_BUFFER_OVERFLOW; |
|
206 } |
|
207 |
|
208 if (yarrow_read(out, 64, prng) != 64) { |
|
209 return CRYPT_ERROR_READPRNG; |
|
210 } |
|
211 *outlen = 64; |
|
212 |
|
213 return CRYPT_OK; |
|
214 } |
|
215 |
|
216 int yarrow_import(const unsigned char *in, unsigned long inlen, prng_state *prng) |
|
217 { |
|
218 int err; |
|
219 |
|
220 _ARGCHK(in != NULL); |
|
221 _ARGCHK(prng != NULL); |
|
222 |
|
223 if (inlen != 64) { |
|
224 return CRYPT_INVALID_ARG; |
|
225 } |
|
226 |
|
227 if ((err = yarrow_start(prng)) != CRYPT_OK) { |
|
228 return err; |
|
229 } |
|
230 return yarrow_add_entropy(in, 64, prng); |
|
231 } |
|
232 |
|
233 int yarrow_test(void) |
|
234 { |
|
235 #ifndef LTC_TEST |
|
236 return CRYPT_NOP; |
|
237 #else |
|
238 int err; |
|
239 prng_state prng; |
|
240 |
|
241 if ((err = yarrow_start(&prng)) != CRYPT_OK) { |
|
242 return err; |
|
243 } |
|
244 |
|
245 /* now let's test the hash/cipher that was chosen */ |
|
246 if ((err = cipher_descriptor[prng.yarrow.cipher].test()) != CRYPT_OK) { |
|
247 return err; |
|
248 } |
|
249 if ((err = hash_descriptor[prng.yarrow.hash].test()) != CRYPT_OK) { |
|
250 return err; |
|
251 } |
|
252 |
|
253 yarrow_done(&prng); |
|
254 return CRYPT_OK; |
|
255 #endif |
|
256 } |
|
257 |
3
|
258 #endif |
|
259 |