From 9f81973580cc5d25d40930f64c74d80480949717 Mon Sep 17 00:00:00 2001 From: rasky Date: Wed, 29 Sep 2010 16:36:14 +0000 Subject: [PATCH] SEC: Add Yarrow PRNG generator. git-svn-id: https://src.develer.com/svnoss/bertos/trunk@4360 38d2e660-2303-0410-9eaa-f027e97ec537 --- bertos/sec/prng/yarrow.c | 119 +++++++++++++++++++++++++++++++++++++++ bertos/sec/prng/yarrow.h | 60 ++++++++++++++++++++ 2 files changed, 179 insertions(+) create mode 100644 bertos/sec/prng/yarrow.c create mode 100644 bertos/sec/prng/yarrow.h diff --git a/bertos/sec/prng/yarrow.c b/bertos/sec/prng/yarrow.c new file mode 100644 index 00000000..8dbaf92f --- /dev/null +++ b/bertos/sec/prng/yarrow.c @@ -0,0 +1,119 @@ +/** + * \file + * + * + * \brief Yarrow implementation + * \author Giovanni Bajo + * + */ + +#include "yarrow.h" +#include +#include +#include + +#define CONFIG_YARROW_GENERATOR_GATE 10 + +static void yarrow_generate(PRNG *ctx_, uint8_t *data, size_t len) +{ + YarrowContext *ctx = (YarrowContext *)ctx_; + BlockCipher *cipher = 0; + + ASSERT(len != 0); + + do + { + if (ctx->lastidx == sizeof(ctx->last)) + { + if (!cipher) + { + cipher = AES128_stackinit(); + ASSERT(sizeof(ctx->counter) == cipher_block_len(cipher)); + ASSERT(sizeof(ctx->curkey) == cipher_key_len(cipher)); + + cipher_set_key(cipher, ctx->curkey); + cipher_ctr_begin(cipher, ctx->counter); + } + + cipher_ctr_step(cipher, ctx->last); + + if (ctx->curkey_gencount == CONFIG_YARROW_GENERATOR_GATE) + { + ASSERT(cipher_block_len(cipher) == cipher_key_len(cipher)); + cipher_set_key(cipher, ctx->last); + ctx->curkey_gencount = 0; + continue; + } + + ctx->lastidx = 0; + ctx->curkey_gencount++; + } + + int n = MIN(len, 16U-ctx->lastidx); + memcpy(data, ctx->last+ctx->lastidx, n); + data += n; + len -= n; + ctx->lastidx += n; + } while (len); +} + +static void yarrow_reseed(PRNG *ctx_, const uint8_t *seed) +{ + YarrowContext *ctx = (YarrowContext *)ctx_; + Hash *h = SHA1_stackinit(); + + hash_begin(h); + hash_update(h, seed, ctx->prng.seed_len); + hash_update(h, ctx->curkey, sizeof(ctx->curkey)); + memcpy(ctx->curkey, hash_final(h), sizeof(ctx->curkey)); + kprintf("Yarrow reseeding:"); + kdump(ctx->curkey, sizeof(ctx->curkey)); + + // Reset the counter for the sequence + memset(ctx->counter, 0, sizeof(ctx->counter)); +} + + +/*********************************************************************/ + +void yarrow_init(YarrowContext *ctx) +{ + ctx->prng.reseed = yarrow_reseed; + ctx->prng.generate = yarrow_generate; + ctx->prng.seed_len = 16; + ctx->prng.seeded = 0; + + ctx->lastidx = sizeof(ctx->last); + ctx->curkey_gencount = 0; + memset(ctx->curkey, 0, sizeof(ctx->curkey)); + + ASSERT(sizeof(ctx->counter) == sizeof(ctx->last)); +} diff --git a/bertos/sec/prng/yarrow.h b/bertos/sec/prng/yarrow.h new file mode 100644 index 00000000..556d573f --- /dev/null +++ b/bertos/sec/prng/yarrow.h @@ -0,0 +1,60 @@ +/** + * \file + * + * + * \brief Yarrow implementation + * \author Giovanni Bajo + * + */ + +#ifndef SEC_PRNG_YARROW_H +#define SEC_PRNG_YARROW_H + +#include +#include + +typedef struct YarrowContext +{ + PRNG prng; + + uint8_t counter[16]; + uint8_t curkey[16]; + uint8_t last[16]; + uint8_t curkey_gencount; + uint8_t lastidx; +} YarrowContext; + +void yarrow_init(YarrowContext *ctx); + +#define yarrow_stackinit(...) \ + ({ YarrowContext *ctx = alloca(sizeof(YarrowContext)); yarrow_init(ctx, ##__VA_ARGS__); &ctx->prng; }) + +#endif /* SEC_PRNG_YARROW_H */ -- 2.25.1