BeRTOS
|
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 }