* \brief ANSI X9.17 PRNG implementation
* \author Giovanni Bajo <rasky@develer.com>
*
+ * notest:avr
*/
#include "x917.h"
{
const size_t blen = cipher_block_len(cipher);
- union
+ struct
{
- uint8_t bytes[blen];
- struct
- {
- time_t t0;
- hptime_t t1;
- } data;
+ time_t t0;
+ hptime_t t1;
+ uint8_t padding[blen - sizeof(time_t) - sizeof(hptime_t)];
} DT;
- ASSERT(sizeof(DT.bytes) >= sizeof(ticks_t) + sizeof(hptime_t));
+ ASSERT(sizeof(DT) == blen);
- DT.data.t0 = timer_clock();
- DT.data.t1 = timer_hw_hpread();
+ memset(&DT, 0, sizeof(DT));
+ DT.t0 = timer_clock();
+ DT.t1 = timer_hw_hpread();
- cipher_ecb_encrypt(cipher, DT.bytes);
+ cipher_ecb_encrypt(cipher, &DT);
- xor_block(out, DT.bytes, ctx->state, blen);
+ xor_block(out, (uint8_t*)&DT, ctx->state, blen);
cipher_ecb_encrypt(cipher, out);
- xor_block(ctx->state, DT.bytes, out, blen);
+ xor_block(ctx->state, (uint8_t*)&DT, out, blen);
cipher_ecb_encrypt(cipher, ctx->state);
- PURGE(DT.bytes);
+ PURGE(DT);
}
// of the seed, and use the result as new seed.
// * Generate and throw away a block to update the state.
X917Context *ctx = (X917Context *)ctx_;
+ const size_t klen = sizeof(ctx->key);
+ const size_t blen = sizeof(ctx->state);
- size_t klen = sizeof(ctx->key);
- size_t blen = sizeof(ctx->state);
-
- uint8_t buf[klen];
- x917_generate(ctx_, buf, klen);
+ if (!ctx->rng.seeded)
+ {
+ memcpy(ctx->key, seed, klen);
+ memcpy(ctx->state, seed+klen, blen);
+ }
+ else
+ {
+ uint8_t buf[klen];
+ x917_generate(ctx_, buf, klen);
- xor_block(ctx->key, buf, seed, klen);
- xor_block(ctx->state, ctx->state, seed+klen, blen);
+ xor_block(ctx->key, buf, seed, klen);
+ xor_block(ctx->state, ctx->state, seed+klen, blen);
- PURGE(buf);
+ PURGE(buf);
+ }
}
/*********************************************************************/
ctx->rng.reseed = x917_reseed;
ctx->rng.generate = x917_generate;
ctx->rng.seed_len = sizeof(ctx->key) + sizeof(ctx->state);
+ ctx->rng.seeded = 0;
}