padlock rng - rework
authorAlex Hornung <ahornung@gmail.com>
Sat, 18 Jun 2011 18:34:23 +0000 (19:34 +0100)
committerAlex Hornung <ahornung@gmail.com>
Sat, 18 Jun 2011 22:22:44 +0000 (23:22 +0100)
 * Rework to use a custom loop so that it doesn't stall when there is no
   more entropy left to harvest.

sys/conf/files
sys/dev/crypto/padlock/Makefile
sys/dev/crypto/padlock/padlock_rng.c
sys/dev/crypto/padlock/rng_harvest.S [copied from sys/dev/crypto/padlock/padlock_rng.c with 50% similarity]

index 59a7eb4..76c7e5a 100644 (file)
@@ -1926,6 +1926,7 @@ dev/crypto/padlock/padlock.c              optional padlock
 dev/crypto/padlock/padlock_cipher.c    optional padlock
 dev/crypto/padlock/padlock_hash.c      optional padlock
 dev/crypto/padlock/padlock_rng.c       optional padlock
+dev/crypto/padlock/rng_harvest.S       optional padlock
 dev/crypto/ubsec/ubsec.c               optional ubsec
 dev/drm/ati_pcigart.c                  optional drm
 dev/drm/drm_agpsupport.c               optional drm
index 9d695a1..b81ecd8 100644 (file)
@@ -1,7 +1,7 @@
 # $FreeBSD: src/sys/modules/padlock/Makefile,v 1.3 2007/03/21 17:37:13 sam Exp $
 
 KMOD=  padlock
-SRCS=  padlock.c padlock_cipher.c padlock_hash.c padlock_rng.c
+SRCS=  padlock.c padlock_cipher.c padlock_hash.c padlock_rng.c rng_harvest.S
 SRCS   += device_if.h bus_if.h opt_bus.h cryptodev_if.h
 
 .include <bsd.kmod.mk>
index 9deca0e..ef4c687 100644 (file)
 
 #include <dev/crypto/padlock/padlock.h>
 
-static int random_count = 16;
+int padlock_rng(uint8_t *out, int limit);
 
-static __inline void
-padlock_rng(int *out, size_t count)
-{
-       unsigned int status;
-
-       /*
-        * xstore-rng:
-        * eax: (output) RNG status word
-        * ecx: (input)  rep. count
-        * edx: (input)  quality factor (0-3)
-        * edi: (input)  buffer for random data
-        */
-       __asm __volatile(
-               "pushf                  \n\t"
-               "popf                   \n\t"
-               "rep                    \n\t"
-               ".byte  0x0f, 0xa7, 0xc0"
-                       : "=a" (status)
-                       : "d" (2), "D" (out), "c" (count*sizeof(*out))
-                       : "cc", "memory"
-       );
-}
+static int random_count = 32;
 
 static void
 padlock_rng_harvest(void *arg)
 {
        struct padlock_softc *sc = arg;
-       int randomness[128];
-       int *arandomness; /* randomness aligned */
-       int i;
+       uint8_t randomness[128];
+       uint8_t *arandomness; /* randomness aligned */
+       int i, cnt;
 
        arandomness = PADLOCK_ALIGN(randomness);
-       padlock_rng(arandomness, random_count);
+       cnt = padlock_rng(arandomness, random_count);
 
-       for (i = 0; i < random_count; i++)
-               add_true_randomness(arandomness[i]);
+       for (i = 0; i < cnt; i++)
+               add_true_randomness((int)arandomness[i]);
 
        callout_reset(&sc->sc_rng_co, sc->sc_rng_ticks,
            padlock_rng_harvest, sc);
similarity index 50%
copy from sys/dev/crypto/padlock/padlock_rng.c
copy to sys/dev/crypto/padlock/rng_harvest.S
index 9deca0e..2405299 100644 (file)
  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  */
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/kernel.h>
-#include <sys/module.h>
-#include <sys/malloc.h>
-#include <sys/libkern.h>
-#include <sys/random.h>
 
-#include <dev/crypto/padlock/padlock.h>
+#include <machine/asmacros.h>
 
-static int random_count = 16;
+       .text
 
-static __inline void
-padlock_rng(int *out, size_t count)
-{
-       unsigned int status;
+/* int padlock_rng(uint8_t *out, int limit) */
+ENTRY(padlock_rng)
+       movl    4(%esp),%edi
+       movl    8(%esp),%ecx
 
+       movl    $3,     %edx
+       xorl    %ebx,   %ebx
+loop:
        /*
-        * xstore-rng:
-        * eax: (output) RNG status word
-        * ecx: (input)  rep. count
-        * edx: (input)  quality factor (0-3)
-        * edi: (input)  buffer for random data
+        * edx: (input)         quality factor of rng entropy
+        * edi: (input)         buffer for random data
+        * eax: (output)        rng status word
         */
-       __asm __volatile(
-               "pushf                  \n\t"
-               "popf                   \n\t"
-               "rep                    \n\t"
-               ".byte  0x0f, 0xa7, 0xc0"
-                       : "=a" (status)
-                       : "d" (2), "D" (out), "c" (count*sizeof(*out))
-                       : "cc", "memory"
-       );
-}
+       .byte   0x0f, 0xa7, 0xc0 /* xstore-rng */
 
-static void
-padlock_rng_harvest(void *arg)
-{
-       struct padlock_softc *sc = arg;
-       int randomness[128];
-       int *arandomness; /* randomness aligned */
-       int i;
 
-       arandomness = PADLOCK_ALIGN(randomness);
-       padlock_rng(arandomness, random_count);
-
-       for (i = 0; i < random_count; i++)
-               add_true_randomness(arandomness[i]);
-
-       callout_reset(&sc->sc_rng_co, sc->sc_rng_ticks,
-           padlock_rng_harvest, sc);
-}
-
-void
-padlock_rng_init(struct padlock_softc *sc)
-{
-       if (hz > 100)
-               sc->sc_rng_ticks = hz/100;
-       else
-               sc->sc_rng_ticks = 1;
+       /*
+        * The lower 5 bits of %eax contain the number of random
+        * bytes stored.
+        * If no bytes were stored, there is no more entropy
+        * available, so we finish up.
+        */
+       andl    $0x1f,  %eax
+       jz      out
 
-       callout_init_mp(&sc->sc_rng_co);
-       callout_reset(&sc->sc_rng_co, sc->sc_rng_ticks,
-           padlock_rng_harvest, sc);
-}
+       /*
+        * Increment the count of stored random bytes as
+        * well as the base buffer pointer.
+        */
+       addl    %eax,   %ebx
+       addl    %eax,   %edi
 
-void
-padlock_rng_uninit(struct padlock_softc *sc)
-{
-       callout_stop(&sc->sc_rng_co);
-}
+       /*
+        * If we haven't already read enough random bytes,
+        * loop again.
+        */
+       cmpl    %ecx,   %ebx
+       jl      loop
+out:
+       /* return the number of stored random bytes. */
+       movl    %ebx,   %eax
+       ret