BeRTOS
yarrow.c
Go to the documentation of this file.
00001 
00038 #include "yarrow.h"
00039 #include <sec/hash/sha1.h>
00040 #include <cfg/macros.h>
00041 #include <string.h>
00042 
00043 #define CONFIG_YARROW_GENERATOR_GATE             10
00044 
00045 static void yarrow_generate(PRNG *ctx_, uint8_t *data, size_t len)
00046 {
00047     YarrowContext *ctx = (YarrowContext *)ctx_;
00048     BlockCipher *cipher = 0;
00049 
00050     ASSERT(len != 0);
00051 
00052     do
00053     {
00054         if (ctx->lastidx == sizeof(ctx->last))
00055         {
00056             if (!cipher)
00057             {
00058                 cipher = AES128_stackinit();
00059                 ASSERT(sizeof(ctx->counter) == cipher_block_len(cipher));
00060                 ASSERT(sizeof(ctx->curkey) == cipher_key_len(cipher));
00061 
00062                 cipher_set_key(cipher, ctx->curkey);
00063                 cipher_ctr_begin(cipher, ctx->counter);
00064             }
00065 
00066             cipher_ctr_step(cipher, ctx->last);
00067 
00068             if (ctx->curkey_gencount == CONFIG_YARROW_GENERATOR_GATE)
00069             {
00070                 ASSERT(cipher_block_len(cipher) == cipher_key_len(cipher));
00071                 cipher_set_key(cipher, ctx->last);
00072                 ctx->curkey_gencount = 0;
00073                 continue;
00074             }
00075 
00076             ctx->lastidx = 0;
00077             ctx->curkey_gencount++;
00078         }
00079 
00080         int n = MIN(len, 16U-ctx->lastidx);
00081         memcpy(data, ctx->last+ctx->lastidx, n);
00082         data += n;
00083         len -= n;
00084         ctx->lastidx += n;
00085     } while (len);
00086 }
00087 
00088 static void yarrow_reseed(PRNG *ctx_, const uint8_t *seed)
00089 {
00090     YarrowContext *ctx = (YarrowContext *)ctx_;
00091     Hash *h = SHA1_stackinit();
00092 
00093     hash_begin(h);
00094     hash_update(h, seed, ctx->prng.seed_len);
00095     hash_update(h, ctx->curkey, sizeof(ctx->curkey));
00096     memcpy(ctx->curkey, hash_final(h), sizeof(ctx->curkey));
00097 
00098     // Reset the counter for the sequence
00099     memset(ctx->counter, 0, sizeof(ctx->counter));
00100 }
00101 
00102 
00103 /*********************************************************************/
00104 
00105 void yarrow_init(YarrowContext *ctx)
00106 {
00107     ctx->prng.reseed = yarrow_reseed;
00108     ctx->prng.generate = yarrow_generate;
00109     ctx->prng.seed_len = 16;
00110     ctx->prng.seeded = 0;
00111 
00112     ctx->lastidx = sizeof(ctx->last);
00113     ctx->curkey_gencount = 0;
00114     memset(ctx->curkey, 0, sizeof(ctx->curkey));
00115 
00116     ASSERT(sizeof(ctx->counter) == sizeof(ctx->last));
00117 }