X-Git-Url: https://git.distorted.org.uk/u/mdw/catacomb/blobdiff_plain/ba044e65f37effe25ed5a6fa86d7c250b8065f60..d34decd2b2b88240cf4ca68a2a5feb7bf36de6e7:/rand.c diff --git a/rand.c b/rand.c index 9aea479..a93bf9b 100644 --- a/rand.c +++ b/rand.c @@ -1,6 +1,6 @@ /* -*-c-*- * - * $Id: rand.c,v 1.2 1999/10/12 21:00:15 mdw Exp $ + * $Id: rand.c,v 1.4 1999/12/13 15:34:28 mdw Exp $ * * Secure random number generator * @@ -30,6 +30,12 @@ /*----- Revision history --------------------------------------------------* * * $Log: rand.c,v $ + * Revision 1.4 1999/12/13 15:34:28 mdw + * Increase the entropy threshhold in rand_getgood. + * + * Revision 1.3 1999/12/10 23:28:07 mdw + * Bug fix: rand_getgood didn't update buffer pointer. + * * Revision 1.2 1999/10/12 21:00:15 mdw * Make pool and buffer sizes more sensible. * @@ -40,10 +46,12 @@ /*----- Header files ------------------------------------------------------*/ +#include #include #include #include +#include #include "blowfish-cbc.h" #include "paranoia.h" @@ -53,13 +61,20 @@ /*----- Static variables --------------------------------------------------*/ -static rand_pool pool; /* Default random pool */ +static const grand_ops gops; + +typedef struct gctx { + grand r; + rand_pool p; +} gctx; + +static gctx pool = { { &gops } }; /* Default random pool */ /*----- Macros ------------------------------------------------------------*/ #define RAND_RESOLVE(r) do { \ if ((r) == RAND_GLOBAL) \ - (r) = &pool; \ + (r) = &pool.p; \ } while (0) #define TIMER(r) do { \ @@ -89,7 +104,7 @@ void rand_init(rand_pool *r) r->ibits = r->obits = 0; r->o = RAND_SECSZ; r->s = 0; - rmd160_hmac(&r->k, 0, 0); + rmd160_hmacinit(&r->k, 0, 0); rand_gate(r); } @@ -131,7 +146,7 @@ void rand_noisesrc(rand_pool *r, const rand_source *s) void rand_key(rand_pool *r, const void *k, size_t sz) { RAND_RESOLVE(r); - rmd160_hmac(&r->k, k, sz); + rmd160_hmacinit(&r->k, k, sz); } /* --- @rand_add@ --- * @@ -218,8 +233,8 @@ void rand_gate(rand_pool *r) rmd160_macctx mc; rmd160_macinit(&mc, &r->k); - rmd160_mac(&mc, r->pool, sizeof(r->pool)); - rmd160_mac(&mc, r->buf, sizeof(r->buf)); + rmd160_machash(&mc, r->pool, sizeof(r->pool)); + rmd160_machash(&mc, r->buf, sizeof(r->buf)); rmd160_macdone(&mc, mac); BURN(mc); } @@ -272,8 +287,8 @@ void rand_stretch(rand_pool *r) rmd160_macctx mc; rmd160_macinit(&mc, &r->k); - rmd160_mac(&mc, r->pool, sizeof(r->pool)); - rmd160_mac(&mc, r->buf, sizeof(r->buf)); + rmd160_machash(&mc, r->pool, sizeof(r->pool)); + rmd160_machash(&mc, r->buf, sizeof(r->buf)); rmd160_macdone(&mc, mac); BURN(mc); } @@ -377,7 +392,7 @@ void rand_getgood(rand_pool *r, void *p, size_t sz) if (chunk * 8 > r->obits) { if (chunk * 8 > r->ibits + r->obits) - do r->s->getnoise(r); while (r->ibits + r->obits < 128); + do r->s->getnoise(r); while (r->ibits + r->obits < 256); rand_gate(r); if (chunk * 8 > r->obits) chunk = r->obits / 8; @@ -387,10 +402,137 @@ void rand_getgood(rand_pool *r, void *p, size_t sz) chunk = RAND_BUFSZ - r->o; memcpy(o, r->buf + r->o, chunk); + r->o += chunk; r->obits -= chunk * 8; o += chunk; sz -= chunk; } } +/*----- Generic random number generator interface -------------------------*/ + +static void gdestroy(grand *r) +{ + gctx *g = (r == &rand_global ? &pool : (gctx *)r); + if (g != &pool) + DESTROY(g); +} + +static int gmisc(grand *r, unsigned op, ...) +{ + gctx *g = (r == &rand_global ? &pool : (gctx *)r); + va_list ap; + int rc = 0; + va_start(ap, op); + + switch (op) { + case GRAND_CHECK: + switch (va_arg(ap, unsigned)) { + case GRAND_CHECK: + case GRAND_SEEDINT: + case GRAND_SEEDUINT32: + case GRAND_SEEDBLOCK: + case GRAND_SEEDRAND: + case RAND_GATE: + case RAND_STRETCH: + case RAND_KEY: + case RAND_NOISESRC: + rc = 1; + break; + default: + rc = 0; + break; + } + break; + case GRAND_SEEDINT: { + unsigned u = va_arg(ap, unsigned); + rand_add(&g->p, &u, sizeof(u), sizeof(u)); + } break; + case GRAND_SEEDUINT32: { + uint32 i = va_arg(ap, uint32); + rand_add(&g->p, &i, sizeof(i), 4); + } break; + case GRAND_SEEDBLOCK: { + const void *p = va_arg(ap, const void *); + size_t sz = va_arg(ap, size_t); + rand_add(&g->p, p, sz, sz); + } break; + case GRAND_SEEDRAND: { + grand *rr = va_arg(ap, grand *); + octet buf[16]; + rr->ops->fill(rr, buf, sizeof(buf)); + rand_add(&g->p, buf, sizeof(buf), 8); + } break; + case RAND_GATE: + rand_gate(&g->p); + break; + case RAND_STRETCH: + rand_stretch(&g->p); + break; + case RAND_KEY: { + const void *k = va_arg(ap, const void *); + size_t sz = va_arg(ap, size_t); + rand_key(&g->p, k, sz); + } break; + case RAND_NOISESRC: + rand_noisesrc(&g->p, va_arg(ap, const rand_source *)); + break; + default: + GRAND_BADOP; + break; + } + + va_end(ap); + return (rc); +} + +static octet gbyte(grand *r) +{ + gctx *g = (r == &rand_global ? &pool : (gctx *)r); + octet o; + rand_getgood(&g->p, &o, 1); + return (o); +} + +static uint32 gword(grand *r) +{ + gctx *g = (r == &rand_global ? &pool : (gctx *)r); + octet b[4]; + rand_getgood(&g->p, &b, sizeof(b)); + return (LOAD32(b)); +} + +static void gfill(grand *r, void *p, size_t sz) +{ + gctx *g = (r == &rand_global ? &pool : (gctx *)r); + rand_getgood(&g->p, p, sz); +} + +static const grand_ops gops = { + "rand", + 0, + gmisc, gdestroy, + gword, gbyte, gword, grand_range, gfill +}; + +grand rand_global = { &gops }; + +/* --- @rand_create@ --- * + * + * Arguments: --- + * + * Returns: Pointer to a generic generator. + * + * Use: Constructs a generic generator interface over a Catacomb + * entropy pool generator. + */ + +grand *rand_create(void) +{ + gctx *g = CREATE(gctx); + g->r.ops = &gops; + rand_init(&g->p); + return (&g->r); +} + /*----- That's all, folks -------------------------------------------------*/