Module Name: src Committed By: martin Date: Fri Aug 15 09:53:48 UTC 2014
Modified Files: src/sys/crypto/cprng_fast [netbsd-7]: cprng_fast.c Log Message: Pull up following revision(s) (requested by riastradh in ticket #16): sys/crypto/cprng_fast/cprng_fast.c: revision 1.7 sys/crypto/cprng_fast/cprng_fast.c: revision 1.8 sys/crypto/cprng_fast/cprng_fast.c: revision 1.9 sys/crypto/cprng_fast/cprng_fast.c: revision 1.10 Access to struct cprng_fast must be consistently at IPL_VM. Use percpu_foreach instead of manual iteration. Move initial entropy bookkeeping out of the fast path. Tweak cprng_fast_buf to use 32-bit unaligned writes if possible. To generate a diff of this commit: cvs rdiff -u -r1.6 -r1.6.2.1 src/sys/crypto/cprng_fast/cprng_fast.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/crypto/cprng_fast/cprng_fast.c diff -u src/sys/crypto/cprng_fast/cprng_fast.c:1.6 src/sys/crypto/cprng_fast/cprng_fast.c:1.6.2.1 --- src/sys/crypto/cprng_fast/cprng_fast.c:1.6 Mon Aug 11 03:50:29 2014 +++ src/sys/crypto/cprng_fast/cprng_fast.c Fri Aug 15 09:53:48 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: cprng_fast.c,v 1.6 2014/08/11 03:50:29 riastradh Exp $ */ +/* $NetBSD: cprng_fast.c,v 1.6.2.1 2014/08/15 09:53:48 martin Exp $ */ /*- * Copyright (c) 2014 The NetBSD Foundation, Inc. @@ -30,7 +30,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: cprng_fast.c,v 1.6 2014/08/11 03:50:29 riastradh Exp $"); +__KERNEL_RCSID(0, "$NetBSD: cprng_fast.c,v 1.6.2.1 2014/08/15 09:53:48 martin Exp $"); #include <sys/types.h> #include <sys/param.h> @@ -203,6 +203,7 @@ struct cprng_fast { __CTASSERT(sizeof ((struct cprng_fast *)0)->key == CPRNG_FAST_SEED_BYTES); +static void cprng_fast_init_cpu(void *, void *, struct cpu_info *); static void cprng_fast_schedule_reseed(struct cprng_fast *); static void cprng_fast_intr(void *); @@ -218,33 +219,39 @@ static void *cprng_fast_softint __read_m void cprng_fast_init(void) { - struct cpu_info *ci; - CPU_INFO_ITERATOR cii; crypto_core_selftest(); cprng_fast_percpu = percpu_alloc(sizeof(struct cprng_fast)); - for (CPU_INFO_FOREACH(cii, ci)) { - struct cprng_fast *cprng; - uint8_t seed[CPRNG_FAST_SEED_BYTES]; - - percpu_traverse_enter(); - cprng = percpu_getptr_remote(cprng_fast_percpu, ci); - cprng_strong(kern_cprng, seed, sizeof(seed), FASYNC); - /* Can't do anything about it if not full entropy. */ - cprng_fast_seed(cprng, seed); - explicit_memset(seed, 0, sizeof(seed)); - percpu_traverse_exit(); - } + percpu_foreach(cprng_fast_percpu, &cprng_fast_init_cpu, NULL); cprng_fast_softint = softint_establish(SOFTINT_SERIAL|SOFTINT_MPSAFE, &cprng_fast_intr, NULL); } +static void +cprng_fast_init_cpu(void *p, void *arg __unused, struct cpu_info *ci __unused) +{ + struct cprng_fast *const cprng = p; + uint8_t seed[CPRNG_FAST_SEED_BYTES]; + + cprng_strong(kern_cprng, seed, sizeof seed, FASYNC); + cprng_fast_seed(cprng, seed); + cprng->have_initial = rnd_initial_entropy; + (void)explicit_memset(seed, 0, sizeof seed); +} + static inline int cprng_fast_get(struct cprng_fast **cprngp) { + struct cprng_fast *cprng; + int s; + + *cprngp = cprng = percpu_getref(cprng_fast_percpu); + s = splvm(); - *cprngp = percpu_getref(cprng_fast_percpu); - return splvm(); + if (__predict_false(!cprng->have_initial)) + cprng_fast_schedule_reseed(cprng); + + return s; } static inline void @@ -256,7 +263,7 @@ cprng_fast_put(struct cprng_fast *cprng, splx(s); percpu_putref(cprng_fast_percpu); } - + static inline void cprng_fast_schedule_reseed(struct cprng_fast *cprng __unused) { @@ -269,11 +276,15 @@ cprng_fast_intr(void *cookie __unused) { struct cprng_fast *cprng; uint8_t seed[CPRNG_FAST_SEED_BYTES]; + int s; cprng_strong(kern_cprng, seed, sizeof(seed), FASYNC); cprng = percpu_getref(cprng_fast_percpu); + s = splvm(); cprng_fast_seed(cprng, seed); + cprng->have_initial = rnd_initial_entropy; + splx(s); percpu_putref(cprng_fast_percpu); explicit_memset(seed, 0, sizeof(seed)); @@ -298,12 +309,6 @@ cprng_fast_seed(struct cprng_fast *cprng (void)memset(cprng->buffer, 0, sizeof cprng->buffer); (void)memcpy(cprng->key, seed, sizeof cprng->key); (void)memset(cprng->nonce, 0, sizeof cprng->nonce); - - if (__predict_true(rnd_initial_entropy)) { - cprng->have_initial = true; - } else { - cprng->have_initial = false; - } } static inline uint32_t @@ -320,12 +325,6 @@ cprng_fast_word(struct cprng_fast *cprng if (__predict_false(++cprng->nonce[0] == 0)) { cprng->nonce[1]++; cprng_fast_schedule_reseed(cprng); - } else { - if (__predict_false(false == cprng->have_initial)) { - if (rnd_initial_entropy) { - cprng_fast_schedule_reseed(cprng); - } - } } v = cprng->buffer[CPRNG_FAST_BUFIDX]; cprng->buffer[CPRNG_FAST_BUFIDX] = CPRNG_FAST_BUFIDX; @@ -339,11 +338,17 @@ cprng_fast_buf(struct cprng_fast *cprng, { uint8_t *p = buf; uint32_t v; - unsigned r; + unsigned w, r; + + w = n / sizeof(uint32_t); + while (w--) { + v = cprng_fast_word(cprng); + (void)memcpy(p, &v, 4); + p += 4; + } - while (n) { - r = MIN(n, 4); - n -= r; + r = n % sizeof(uint32_t); + if (r) { v = cprng_fast_word(cprng); while (r--) { *p++ = (v & 0xff);