libsec: replace des based X9.17 genrandom() with chacha random number generator
This commit is contained in:
parent
84228515b6
commit
ed9fdc72f5
2 changed files with 29 additions and 49 deletions
|
@ -31,8 +31,6 @@ ulong truerand(void)
|
||||||
.B
|
.B
|
||||||
ulong ntruerand(ulong val)
|
ulong ntruerand(ulong val)
|
||||||
.sp
|
.sp
|
||||||
.B #include <mp.h>
|
|
||||||
.br
|
|
||||||
.B #include <libsec.h>
|
.B #include <libsec.h>
|
||||||
.PP
|
.PP
|
||||||
.B
|
.B
|
||||||
|
@ -117,10 +115,9 @@ returns a uniform random integer
|
||||||
.if n 0≤ x < val ≤ 2^32-1.
|
.if n 0≤ x < val ≤ 2^32-1.
|
||||||
.PP
|
.PP
|
||||||
.I Genrandom
|
.I Genrandom
|
||||||
fills a buffer with bytes from the X9.17 pseudo-random
|
fills a buffer with bytes from the cryptographic pseudo-random
|
||||||
number generator. The X9.17 generator is seeded by 24
|
number generator. The generator is automatically seeded by
|
||||||
truly random bytes read from
|
.IR truerand .
|
||||||
.BR /dev/random .
|
|
||||||
.PP
|
.PP
|
||||||
.I Prng
|
.I Prng
|
||||||
uses the native
|
uses the native
|
||||||
|
|
|
@ -1,61 +1,44 @@
|
||||||
#include "os.h"
|
#include "os.h"
|
||||||
#include <libsec.h>
|
#include <libsec.h>
|
||||||
|
|
||||||
typedef struct State{
|
|
||||||
QLock lock;
|
|
||||||
int seeded;
|
|
||||||
uvlong seed;
|
|
||||||
DES3state des3;
|
|
||||||
} State;
|
|
||||||
static State x917state;
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
X917(uchar *rand, int nrand)
|
init(Chachastate *cs)
|
||||||
{
|
{
|
||||||
int i, m, n8;
|
ulong seed[11];
|
||||||
uvlong I, x;
|
int i;
|
||||||
|
|
||||||
/* 1. Compute intermediate value I = Ek(time). */
|
for(i=0; i<nelem(seed); i++)
|
||||||
I = nsec();
|
seed[i] = truerand();
|
||||||
triple_block_cipher(x917state.des3.expanded, (uchar*)&I, 0); /* two-key EDE */
|
|
||||||
|
|
||||||
/* 2. x[i] = Ek(I^seed); seed = Ek(x[i]^I); */
|
setupChachastate(cs, (uchar*)&seed[0], 32, (uchar*)&seed[8], 12, 20);
|
||||||
m = (nrand+7)/8;
|
memset(seed, 0, sizeof(seed));
|
||||||
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
|
static void
|
||||||
X917init(void)
|
fill(Chachastate *cs, uchar *p, int n)
|
||||||
{
|
{
|
||||||
int n;
|
Chachastate c;
|
||||||
uchar mix[128];
|
|
||||||
uchar key3[3][8];
|
|
||||||
ulong *ulp;
|
|
||||||
|
|
||||||
ulp = (ulong*)key3;
|
c = *cs;
|
||||||
for(n = 0; n < sizeof(key3)/sizeof(ulong); n++)
|
chacha_encrypt((uchar*)&cs->input[4], 32, &c);
|
||||||
ulp[n] = truerand();
|
if(++cs->input[13] == 0)
|
||||||
setupDES3state(&x917state.des3, key3, nil);
|
if(++cs->input[14] == 0)
|
||||||
X917(mix, sizeof mix);
|
++cs->input[15];
|
||||||
x917state.seeded = 1;
|
|
||||||
|
chacha_encrypt(p, n, &c);
|
||||||
|
memset(&c, 0, sizeof(c));
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
genrandom(uchar *p, int n)
|
genrandom(uchar *p, int n)
|
||||||
{
|
{
|
||||||
qlock(&x917state.lock);
|
static QLock lk;
|
||||||
if(x917state.seeded == 0)
|
static Chachastate cs;
|
||||||
X917init();
|
|
||||||
X917(p, n);
|
qlock(&lk);
|
||||||
qunlock(&x917state.lock);
|
if(cs.rounds == 0)
|
||||||
|
init(&cs);
|
||||||
|
cs.input[4] ^= getpid(); /* fork protection */
|
||||||
|
fill(&cs, p, n);
|
||||||
|
qunlock(&lk);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue