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 { |
|
18 "yarrow", |
|
19 &yarrow_start, |
|
20 &yarrow_add_entropy, |
|
21 &yarrow_ready, |
|
22 &yarrow_read |
|
23 }; |
|
24 |
|
25 int yarrow_start(prng_state *prng) |
|
26 { |
|
27 int err; |
|
28 |
|
29 _ARGCHK(prng != NULL); |
|
30 |
|
31 /* these are the default hash/cipher combo used */ |
|
32 #ifdef RIJNDAEL |
|
33 prng->yarrow.cipher = register_cipher(&rijndael_desc); |
|
34 #elif defined(BLOWFISH) |
|
35 prng->yarrow.cipher = register_cipher(&blowfish_desc); |
|
36 #elif defined(TWOFISH) |
|
37 prng->yarrow.cipher = register_cipher(&twofish_desc); |
|
38 #elif defined(RC6) |
|
39 prng->yarrow.cipher = register_cipher(&rc6_desc); |
|
40 #elif defined(RC5) |
|
41 prng->yarrow.cipher = register_cipher(&rc5_desc); |
|
42 #elif defined(SAFERP) |
|
43 prng->yarrow.cipher = register_cipher(&saferp_desc); |
|
44 #elif defined(RC2) |
|
45 prng->yarrow.cipher = register_cipher(&rc2_desc); |
|
46 #elif defined(NOEKEON) |
|
47 prng->yarrow.cipher = register_cipher(&noekeon_desc); |
|
48 #elif defined(CAST5) |
|
49 prng->yarrow.cipher = register_cipher(&cast5_desc); |
|
50 #elif defined(XTEA) |
|
51 prng->yarrow.cipher = register_cipher(&xtea_desc); |
|
52 #elif defined(SAFER) |
|
53 prng->yarrow.cipher = register_cipher(&safer_sk128_desc); |
|
54 #elif defined(DES) |
|
55 prng->yarrow.cipher = register_cipher(&des3_desc); |
|
56 #elif |
|
57 #error YARROW needs at least one CIPHER |
|
58 #endif |
|
59 if ((err = cipher_is_valid(prng->yarrow.cipher)) != CRYPT_OK) { |
|
60 return err; |
|
61 } |
|
62 |
|
63 #ifdef SHA256 |
|
64 prng->yarrow.hash = register_hash(&sha256_desc); |
|
65 #elif defined(SHA512) |
|
66 prng->yarrow.hash = register_hash(&sha512_desc); |
|
67 #elif defined(TIGER) |
|
68 prng->yarrow.hash = register_hash(&tiger_desc); |
|
69 #elif defined(SHA1) |
|
70 prng->yarrow.hash = register_hash(&sha1_desc); |
|
71 #elif defined(RIPEMD160) |
|
72 prng->yarrow.hash = register_hash(&rmd160_desc); |
|
73 #elif defined(RIPEMD128) |
|
74 prng->yarrow.hash = register_hash(&rmd128_desc); |
|
75 #elif defined(MD5) |
|
76 prng->yarrow.hash = register_hash(&md5_desc); |
|
77 #elif defined(MD4) |
|
78 prng->yarrow.hash = register_hash(&md4_desc); |
|
79 #elif defined(MD2) |
|
80 prng->yarrow.hash = register_hash(&md2_desc); |
|
81 #else |
|
82 #error YARROW needs at least one HASH |
|
83 #endif |
|
84 if ((err = hash_is_valid(prng->yarrow.hash)) != CRYPT_OK) { |
|
85 return err; |
|
86 } |
|
87 |
|
88 /* zero the memory used */ |
|
89 zeromem(prng->yarrow.pool, sizeof(prng->yarrow.pool)); |
|
90 |
|
91 return CRYPT_OK; |
|
92 } |
|
93 |
|
94 int yarrow_add_entropy(const unsigned char *buf, unsigned long len, prng_state *prng) |
|
95 { |
|
96 hash_state md; |
|
97 int err; |
|
98 |
|
99 _ARGCHK(buf != NULL); |
|
100 _ARGCHK(prng != NULL); |
|
101 |
|
102 if ((err = hash_is_valid(prng->yarrow.hash)) != CRYPT_OK) { |
|
103 return err; |
|
104 } |
|
105 |
|
106 /* start the hash */ |
|
107 hash_descriptor[prng->yarrow.hash].init(&md); |
|
108 |
|
109 /* hash the current pool */ |
|
110 hash_descriptor[prng->yarrow.hash].process(&md, prng->yarrow.pool, hash_descriptor[prng->yarrow.hash].hashsize); |
|
111 |
|
112 /* add the new entropy */ |
|
113 hash_descriptor[prng->yarrow.hash].process(&md, buf, len); |
|
114 |
|
115 /* store result */ |
|
116 hash_descriptor[prng->yarrow.hash].done(&md, prng->yarrow.pool); |
|
117 |
|
118 return CRYPT_OK; |
|
119 } |
|
120 |
|
121 int yarrow_ready(prng_state *prng) |
|
122 { |
|
123 int ks, err; |
|
124 |
|
125 _ARGCHK(prng != NULL); |
|
126 |
|
127 if ((err = hash_is_valid(prng->yarrow.hash)) != CRYPT_OK) { |
|
128 return err; |
|
129 } |
|
130 |
|
131 if ((err = cipher_is_valid(prng->yarrow.cipher)) != CRYPT_OK) { |
|
132 return err; |
|
133 } |
|
134 |
|
135 /* setup CTR mode using the "pool" as the key */ |
|
136 ks = (int)hash_descriptor[prng->yarrow.hash].hashsize; |
|
137 if ((err = cipher_descriptor[prng->yarrow.cipher].keysize(&ks)) != CRYPT_OK) { |
|
138 return err; |
|
139 } |
|
140 |
|
141 if ((err = ctr_start(prng->yarrow.cipher, /* what cipher to use */ |
|
142 prng->yarrow.pool, /* IV */ |
|
143 prng->yarrow.pool, ks, /* KEY and key size */ |
|
144 0, /* number of rounds */ |
|
145 &prng->yarrow.ctr)) != CRYPT_OK) { |
|
146 return err; |
|
147 } |
|
148 return CRYPT_OK; |
|
149 } |
|
150 |
|
151 unsigned long yarrow_read(unsigned char *buf, unsigned long len, prng_state *prng) |
|
152 { |
|
153 _ARGCHK(buf != NULL); |
|
154 _ARGCHK(prng != NULL); |
|
155 |
|
156 /* put buf in predictable state first */ |
|
157 zeromem(buf, len); |
|
158 |
|
159 /* now randomize it */ |
|
160 if (ctr_encrypt(buf, buf, len, &prng->yarrow.ctr) != CRYPT_OK) { |
|
161 return 0; |
|
162 } |
|
163 return len; |
|
164 } |
|
165 |
|
166 #endif |
|
167 |