~ubuntu-branches/ubuntu/utopic/dropbear/utopic-proposed

« back to all changes in this revision

Viewing changes to libtomcrypt/src/prngs/yarrow.c

  • Committer: Bazaar Package Importer
  • Author(s): Matt Johnston
  • Date: 2005-12-08 19:20:21 UTC
  • mfrom: (1.2.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20051208192021-nyp9rwnt77nsg6ty
Tags: 0.47-1
* New upstream release.
* SECURITY: Fix incorrect buffer sizing.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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.org
 
10
 */
 
11
#include "tomcrypt.h"
 
12
 
 
13
/**
 
14
  @file yarrow.c
 
15
  Yarrow PRNG, Tom St Denis
 
16
*/  
 
17
 
 
18
#ifdef YARROW
 
19
 
 
20
const struct ltc_prng_descriptor yarrow_desc =
 
21
{
 
22
    "yarrow", 64,
 
23
    &yarrow_start,
 
24
    &yarrow_add_entropy,
 
25
    &yarrow_ready,
 
26
    &yarrow_read,
 
27
    &yarrow_done,
 
28
    &yarrow_export,
 
29
    &yarrow_import,
 
30
    &yarrow_test
 
31
};
 
32
 
 
33
/**
 
34
  Start the PRNG
 
35
  @param prng     [out] The PRNG state to initialize
 
36
  @return CRYPT_OK if successful
 
37
*/  
 
38
int yarrow_start(prng_state *prng)
 
39
{
 
40
   int err;
 
41
   
 
42
   LTC_ARGCHK(prng != NULL);
 
43
 
 
44
   /* these are the default hash/cipher combo used */
 
45
#ifdef RIJNDAEL
 
46
#if    YARROW_AES==0
 
47
   prng->yarrow.cipher = register_cipher(&rijndael_enc_desc);
 
48
#elif  YARROW_AES==1
 
49
   prng->yarrow.cipher = register_cipher(&aes_enc_desc);
 
50
#elif  YARROW_AES==2
 
51
   prng->yarrow.cipher = register_cipher(&rijndael_desc);
 
52
#elif  YARROW_AES==3
 
53
   prng->yarrow.cipher = register_cipher(&aes_desc);
 
54
#endif
 
55
#elif defined(BLOWFISH)
 
56
   prng->yarrow.cipher = register_cipher(&blowfish_desc);
 
57
#elif defined(TWOFISH)
 
58
   prng->yarrow.cipher = register_cipher(&twofish_desc);
 
59
#elif defined(RC6)
 
60
   prng->yarrow.cipher = register_cipher(&rc6_desc);
 
61
#elif defined(RC5)
 
62
   prng->yarrow.cipher = register_cipher(&rc5_desc);
 
63
#elif defined(SAFERP)
 
64
   prng->yarrow.cipher = register_cipher(&saferp_desc);
 
65
#elif defined(RC2)
 
66
   prng->yarrow.cipher = register_cipher(&rc2_desc);
 
67
#elif defined(NOEKEON)   
 
68
   prng->yarrow.cipher = register_cipher(&noekeon_desc);
 
69
#elif defined(CAST5)
 
70
   prng->yarrow.cipher = register_cipher(&cast5_desc);
 
71
#elif defined(XTEA)
 
72
   prng->yarrow.cipher = register_cipher(&xtea_desc);
 
73
#elif defined(SAFER)
 
74
   prng->yarrow.cipher = register_cipher(&safer_sk128_desc);
 
75
#elif defined(DES)
 
76
   prng->yarrow.cipher = register_cipher(&des3_desc);
 
77
#else
 
78
   #error YARROW needs at least one CIPHER
 
79
#endif
 
80
   if ((err = cipher_is_valid(prng->yarrow.cipher)) != CRYPT_OK) {
 
81
      return err;
 
82
   }
 
83
 
 
84
#ifdef SHA256
 
85
   prng->yarrow.hash   = register_hash(&sha256_desc);
 
86
#elif defined(SHA512)
 
87
   prng->yarrow.hash   = register_hash(&sha512_desc);
 
88
#elif defined(TIGER)
 
89
   prng->yarrow.hash   = register_hash(&tiger_desc);
 
90
#elif defined(SHA1)
 
91
   prng->yarrow.hash   = register_hash(&sha1_desc);
 
92
#elif defined(RIPEMD160)
 
93
   prng->yarrow.hash   = register_hash(&rmd160_desc);
 
94
#elif defined(RIPEMD128)
 
95
   prng->yarrow.hash   = register_hash(&rmd128_desc);
 
96
#elif defined(MD5)
 
97
   prng->yarrow.hash   = register_hash(&md5_desc);
 
98
#elif defined(MD4)
 
99
   prng->yarrow.hash   = register_hash(&md4_desc);
 
100
#elif defined(MD2)
 
101
   prng->yarrow.hash   = register_hash(&md2_desc);
 
102
#elif defined(WHIRLPOOL)
 
103
   prng->yarrow.hash   = register_hash(&whirlpool_desc);
 
104
#else
 
105
   #error YARROW needs at least one HASH
 
106
#endif
 
107
   if ((err = hash_is_valid(prng->yarrow.hash)) != CRYPT_OK) {
 
108
      return err;
 
109
   }
 
110
 
 
111
   /* zero the memory used */
 
112
   zeromem(prng->yarrow.pool, sizeof(prng->yarrow.pool));
 
113
 
 
114
   return CRYPT_OK;
 
115
}
 
116
 
 
117
/**
 
118
  Add entropy to the PRNG state
 
119
  @param in       The data to add
 
120
  @param inlen    Length of the data to add
 
121
  @param prng     PRNG state to update
 
122
  @return CRYPT_OK if successful
 
123
*/  
 
124
int yarrow_add_entropy(const unsigned char *in, unsigned long inlen, prng_state *prng)
 
125
{
 
126
   hash_state md;
 
127
   int err;
 
128
 
 
129
   LTC_ARGCHK(in  != NULL);
 
130
   LTC_ARGCHK(prng != NULL);
 
131
 
 
132
   if ((err = hash_is_valid(prng->yarrow.hash)) != CRYPT_OK) {
 
133
      return err;
 
134
   }
 
135
 
 
136
   /* start the hash */
 
137
   if ((err = hash_descriptor[prng->yarrow.hash].init(&md)) != CRYPT_OK) {
 
138
      return err; 
 
139
   }
 
140
 
 
141
   /* hash the current pool */
 
142
   if ((err = hash_descriptor[prng->yarrow.hash].process(&md, prng->yarrow.pool, 
 
143
                                                        hash_descriptor[prng->yarrow.hash].hashsize)) != CRYPT_OK) {
 
144
      return err;
 
145
   }
 
146
 
 
147
   /* add the new entropy */
 
148
   if ((err = hash_descriptor[prng->yarrow.hash].process(&md, in, inlen)) != CRYPT_OK) {
 
149
      return err;
 
150
   }
 
151
 
 
152
   /* store result */
 
153
   if ((err = hash_descriptor[prng->yarrow.hash].done(&md, prng->yarrow.pool)) != CRYPT_OK) {
 
154
      return err;
 
155
   }
 
156
 
 
157
   return CRYPT_OK;
 
158
}
 
159
 
 
160
/**
 
161
  Make the PRNG ready to read from
 
162
  @param prng   The PRNG to make active
 
163
  @return CRYPT_OK if successful
 
164
*/  
 
165
int yarrow_ready(prng_state *prng)
 
166
{
 
167
   int ks, err;
 
168
 
 
169
   LTC_ARGCHK(prng != NULL);
 
170
 
 
171
   if ((err = hash_is_valid(prng->yarrow.hash)) != CRYPT_OK) {
 
172
      return err;
 
173
   }
 
174
   
 
175
   if ((err = cipher_is_valid(prng->yarrow.cipher)) != CRYPT_OK) {
 
176
      return err;
 
177
   }
 
178
 
 
179
   /* setup CTR mode using the "pool" as the key */
 
180
   ks = (int)hash_descriptor[prng->yarrow.hash].hashsize;
 
181
   if ((err = cipher_descriptor[prng->yarrow.cipher].keysize(&ks)) != CRYPT_OK) {
 
182
      return err;
 
183
   }
 
184
 
 
185
   if ((err = ctr_start(prng->yarrow.cipher,     /* what cipher to use */
 
186
                        prng->yarrow.pool,       /* IV */
 
187
                        prng->yarrow.pool, ks,   /* KEY and key size */
 
188
                        0,                       /* number of rounds */
 
189
                        CTR_COUNTER_LITTLE_ENDIAN, /* little endian counter */
 
190
                        &prng->yarrow.ctr)) != CRYPT_OK) {
 
191
      return err;
 
192
   }
 
193
   return CRYPT_OK;
 
194
}
 
195
 
 
196
/**
 
197
  Read from the PRNG
 
198
  @param out      Destination
 
199
  @param outlen   Length of output
 
200
  @param prng     The active PRNG to read from
 
201
  @return Number of octets read
 
202
*/  
 
203
unsigned long yarrow_read(unsigned char *out, unsigned long outlen, prng_state *prng)
 
204
{
 
205
   LTC_ARGCHK(out  != NULL);
 
206
   LTC_ARGCHK(prng != NULL);
 
207
 
 
208
   /* put out in predictable state first */
 
209
   zeromem(out, outlen);
 
210
   
 
211
   /* now randomize it */
 
212
   if (ctr_encrypt(out, out, outlen, &prng->yarrow.ctr) != CRYPT_OK) {
 
213
      return 0;
 
214
   }
 
215
   return outlen;
 
216
}
 
217
 
 
218
/**
 
219
  Terminate the PRNG
 
220
  @param prng   The PRNG to terminate
 
221
  @return CRYPT_OK if successful
 
222
*/  
 
223
int yarrow_done(prng_state *prng)
 
224
{
 
225
   LTC_ARGCHK(prng != NULL);
 
226
 
 
227
   /* call cipher done when we invent one ;-) */
 
228
 
 
229
   /* we invented one */
 
230
   return ctr_done(&prng->yarrow.ctr);
 
231
}
 
232
 
 
233
/**
 
234
  Export the PRNG state
 
235
  @param out       [out] Destination
 
236
  @param outlen    [in/out] Max size and resulting size of the state
 
237
  @param prng      The PRNG to export
 
238
  @return CRYPT_OK if successful
 
239
*/  
 
240
int yarrow_export(unsigned char *out, unsigned long *outlen, prng_state *prng)
 
241
{
 
242
   LTC_ARGCHK(out    != NULL);
 
243
   LTC_ARGCHK(outlen != NULL);
 
244
   LTC_ARGCHK(prng   != NULL);
 
245
 
 
246
   /* we'll write 64 bytes for s&g's */
 
247
   if (*outlen < 64) {
 
248
      return CRYPT_BUFFER_OVERFLOW;
 
249
   }
 
250
 
 
251
   if (yarrow_read(out, 64, prng) != 64) {
 
252
      return CRYPT_ERROR_READPRNG;
 
253
   }
 
254
   *outlen = 64;
 
255
 
 
256
   return CRYPT_OK;
 
257
}
 
258
 
 
259
/**
 
260
  Import a PRNG state
 
261
  @param in       The PRNG state
 
262
  @param inlen    Size of the state
 
263
  @param prng     The PRNG to import
 
264
  @return CRYPT_OK if successful
 
265
*/  
 
266
int yarrow_import(const unsigned char *in, unsigned long inlen, prng_state *prng)
 
267
{
 
268
   int err;
 
269
 
 
270
   LTC_ARGCHK(in   != NULL);
 
271
   LTC_ARGCHK(prng != NULL);
 
272
 
 
273
   if (inlen != 64) {
 
274
      return CRYPT_INVALID_ARG;
 
275
   }
 
276
 
 
277
   if ((err = yarrow_start(prng)) != CRYPT_OK) {
 
278
      return err;
 
279
   }
 
280
   return yarrow_add_entropy(in, 64, prng);
 
281
}
 
282
 
 
283
/**
 
284
  PRNG self-test
 
285
  @return CRYPT_OK if successful, CRYPT_NOP if self-testing has been disabled
 
286
*/  
 
287
int yarrow_test(void)
 
288
{
 
289
#ifndef LTC_TEST
 
290
   return CRYPT_NOP;
 
291
#else
 
292
   int err;
 
293
   prng_state prng;
 
294
 
 
295
   if ((err = yarrow_start(&prng)) != CRYPT_OK) {
 
296
      return err;
 
297
   }
 
298
   
 
299
   /* now let's test the hash/cipher that was chosen */
 
300
   if ((err = cipher_descriptor[prng.yarrow.cipher].test()) != CRYPT_OK) {
 
301
      return err; 
 
302
   }
 
303
   if ((err = hash_descriptor[prng.yarrow.hash].test()) != CRYPT_OK) {
 
304
      return err; 
 
305
   }
 
306
 
 
307
   yarrow_done(&prng);
 
308
   return CRYPT_OK;
 
309
#endif
 
310
}
 
311
 
 
312
#endif
 
313
 
 
314
 
 
315
/* $Source: /cvs/libtom/libtomcrypt/src/prngs/yarrow.c,v $ */
 
316
/* $Revision: 1.5 $ */
 
317
/* $Date: 2005/05/05 14:35:59 $ */