1*4190f1a0SAlex Hornung /* 2*4190f1a0SAlex Hornung * Copyright (c) 2011 Alex Hornung <alex@alexhornung.com>. 3*4190f1a0SAlex Hornung * All rights reserved. 4*4190f1a0SAlex Hornung * 5*4190f1a0SAlex Hornung * Redistribution and use in source and binary forms, with or without 6*4190f1a0SAlex Hornung * modification, are permitted provided that the following conditions 7*4190f1a0SAlex Hornung * are met: 8*4190f1a0SAlex Hornung * 9*4190f1a0SAlex Hornung * 1. Redistributions of source code must retain the above copyright 10*4190f1a0SAlex Hornung * notice, this list of conditions and the following disclaimer. 11*4190f1a0SAlex Hornung * 2. Redistributions in binary form must reproduce the above copyright 12*4190f1a0SAlex Hornung * notice, this list of conditions and the following disclaimer in 13*4190f1a0SAlex Hornung * the documentation and/or other materials provided with the 14*4190f1a0SAlex Hornung * distribution. 15*4190f1a0SAlex Hornung * 16*4190f1a0SAlex Hornung * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17*4190f1a0SAlex Hornung * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18*4190f1a0SAlex Hornung * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 19*4190f1a0SAlex Hornung * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 20*4190f1a0SAlex Hornung * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 21*4190f1a0SAlex Hornung * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, 22*4190f1a0SAlex Hornung * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 23*4190f1a0SAlex Hornung * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 24*4190f1a0SAlex Hornung * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 25*4190f1a0SAlex Hornung * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 26*4190f1a0SAlex Hornung * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27*4190f1a0SAlex Hornung * SUCH DAMAGE. 28*4190f1a0SAlex Hornung */ 29*4190f1a0SAlex Hornung #include <sys/param.h> 30*4190f1a0SAlex Hornung #include <sys/systm.h> 31*4190f1a0SAlex Hornung #include <sys/kernel.h> 32*4190f1a0SAlex Hornung #include <sys/module.h> 33*4190f1a0SAlex Hornung #include <sys/malloc.h> 34*4190f1a0SAlex Hornung #include <sys/libkern.h> 35*4190f1a0SAlex Hornung #include <sys/random.h> 36*4190f1a0SAlex Hornung 37*4190f1a0SAlex Hornung #include <dev/crypto/padlock/padlock.h> 38*4190f1a0SAlex Hornung 39*4190f1a0SAlex Hornung static int random_count = 16; 40*4190f1a0SAlex Hornung 41*4190f1a0SAlex Hornung static __inline void 42*4190f1a0SAlex Hornung padlock_rng(int *out, size_t count) 43*4190f1a0SAlex Hornung { 44*4190f1a0SAlex Hornung unsigned int status; 45*4190f1a0SAlex Hornung 46*4190f1a0SAlex Hornung /* 47*4190f1a0SAlex Hornung * xstore-rng: 48*4190f1a0SAlex Hornung * eax: (output) RNG status word 49*4190f1a0SAlex Hornung * ecx: (input) rep. count 50*4190f1a0SAlex Hornung * edx: (input) quality factor (0-3) 51*4190f1a0SAlex Hornung * edi: (input) buffer for random data 52*4190f1a0SAlex Hornung */ 53*4190f1a0SAlex Hornung __asm __volatile( 54*4190f1a0SAlex Hornung "pushf \n\t" 55*4190f1a0SAlex Hornung "popf \n\t" 56*4190f1a0SAlex Hornung "rep \n\t" 57*4190f1a0SAlex Hornung ".byte 0x0f, 0xa7, 0xc0" 58*4190f1a0SAlex Hornung : "=a" (status) 59*4190f1a0SAlex Hornung : "d" (2), "D" (out), "c" (count*sizeof(*out)) 60*4190f1a0SAlex Hornung : "cc", "memory" 61*4190f1a0SAlex Hornung ); 62*4190f1a0SAlex Hornung } 63*4190f1a0SAlex Hornung 64*4190f1a0SAlex Hornung static void 65*4190f1a0SAlex Hornung padlock_rng_harvest(void *arg) 66*4190f1a0SAlex Hornung { 67*4190f1a0SAlex Hornung struct padlock_softc *sc = arg; 68*4190f1a0SAlex Hornung int randomness[128]; 69*4190f1a0SAlex Hornung int *arandomness; /* randomness aligned */ 70*4190f1a0SAlex Hornung int i; 71*4190f1a0SAlex Hornung 72*4190f1a0SAlex Hornung arandomness = PADLOCK_ALIGN(randomness); 73*4190f1a0SAlex Hornung padlock_rng(arandomness, random_count); 74*4190f1a0SAlex Hornung 75*4190f1a0SAlex Hornung for (i = 0; i < random_count; i++) 76*4190f1a0SAlex Hornung add_true_randomness(arandomness[i]); 77*4190f1a0SAlex Hornung 78*4190f1a0SAlex Hornung callout_reset(&sc->sc_rng_co, sc->sc_rng_ticks, 79*4190f1a0SAlex Hornung padlock_rng_harvest, sc); 80*4190f1a0SAlex Hornung } 81*4190f1a0SAlex Hornung 82*4190f1a0SAlex Hornung void 83*4190f1a0SAlex Hornung padlock_rng_init(struct padlock_softc *sc) 84*4190f1a0SAlex Hornung { 85*4190f1a0SAlex Hornung if (hz > 100) 86*4190f1a0SAlex Hornung sc->sc_rng_ticks = hz/100; 87*4190f1a0SAlex Hornung else 88*4190f1a0SAlex Hornung sc->sc_rng_ticks = 1; 89*4190f1a0SAlex Hornung 90*4190f1a0SAlex Hornung callout_init_mp(&sc->sc_rng_co); 91*4190f1a0SAlex Hornung callout_reset(&sc->sc_rng_co, sc->sc_rng_ticks, 92*4190f1a0SAlex Hornung padlock_rng_harvest, sc); 93*4190f1a0SAlex Hornung } 94*4190f1a0SAlex Hornung 95*4190f1a0SAlex Hornung void 96*4190f1a0SAlex Hornung padlock_rng_uninit(struct padlock_softc *sc) 97*4190f1a0SAlex Hornung { 98*4190f1a0SAlex Hornung callout_stop(&sc->sc_rng_co); 99*4190f1a0SAlex Hornung } 100*4190f1a0SAlex Hornung 101