Subversion Repositories planix.SVN

Rev

Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed

#include "os.h"
#include <mp.h>
#include <libsec.h>

typedef struct State{
        QLock           lock;
        int             seeded;
        uvlong          seed;
        DES3state       des3;
} State;
static State x917state;

static void
X917(uchar *rand, int nrand)
{
        int i, m, n8;
        uvlong I, x;

        /* 1. Compute intermediate value I = Ek(time). */
        I = nsec();
        triple_block_cipher(x917state.des3.expanded, (uchar*)&I, 0); /* two-key EDE */

        /* 2. x[i] = Ek(I^seed);  seed = Ek(x[i]^I); */
        m = (nrand+7)/8;
        for(i=0; i<m; i++){
                x = I ^ x917state.seed;
                triple_block_cipher(x917state.des3.expanded, (uchar*)&x, 0);
                n8 = (nrand>8) ? 8 : nrand;
                memcpy(rand, (uchar*)&x, n8);
                rand += 8;
                nrand -= 8;
                x ^= I;
                triple_block_cipher(x917state.des3.expanded, (uchar*)&x, 0);
                x917state.seed = x;
        }
}

static void
X917init(void)
{
        int n;
        uchar mix[128];
        uchar key3[3][8];
        ulong *ulp;

        ulp = (ulong*)key3;
        for(n = 0; n < sizeof(key3)/sizeof(ulong); n++)
                ulp[n] = truerand();
        setupDES3state(&x917state.des3, key3, nil);
        X917(mix, sizeof mix);
        x917state.seeded = 1;
}

void
genrandom(uchar *p, int n)
{
        qlock(&x917state.lock);
        if(x917state.seeded == 0)
                X917init();
        X917(p, n);
        qunlock(&x917state.lock);
}