ref: b75e3b2cf1e4c6282ab474da4a8a4b0636a75e9b
parent: 9ca0eeaaed1dd8a9ced7e13a560d12fd9e7ac494
author: cinap_lenrek <[email protected]>
date: Tue Dec 27 21:04:30 EST 2016
libsec: replace des based X9.17 genrandom() with chacha random number generator (from 9front)
--- a/libsec/genrandom.c
+++ b/libsec/genrandom.c
@@ -1,61 +1,44 @@
#include "os.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)
+init(Chachastate *cs)
{
- int i, m, n8;
- uvlong I, x;
+ ulong seed[11];
+ int i;
- /* 1. Compute intermediate value I = Ek(time). */
- I = nsec();
- triple_block_cipher(x917state.des3.expanded, (uchar*)&I, 0); /* two-key EDE */
+ for(i=0; i<nelem(seed); i++)
+ seed[i] = truerand();
- /* 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;
- }
+ setupChachastate(cs, (uchar*)&seed[0], 32, (uchar*)&seed[8], 12, 20);
+ memset(seed, 0, sizeof(seed));
}
static void
-X917init(void)
+fill(Chachastate *cs, uchar *p, int n)
{
- int n;
- uchar mix[128];
- uchar key3[3][8];
- ulong *ulp;
+ Chachastate c;
- 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;
+ c = *cs;
+ chacha_encrypt((uchar*)&cs->input[4], 32, &c);
+ if(++cs->input[13] == 0)
+ if(++cs->input[14] == 0)
+ ++cs->input[15];
+
+ chacha_encrypt(p, n, &c);
+ memset(&c, 0, sizeof(c));
}
void
genrandom(uchar *p, int n)
{
- qlock(&x917state.lock);
- if(x917state.seeded == 0)
- X917init();
- X917(p, n);
- qunlock(&x917state.lock);
+ static QLock lk;
+ static Chachastate cs;
+
+ qlock(&lk);
+ if(cs.rounds == 0)
+ init(&cs);
+ cs.input[4] ^= getpid(); /* fork protection */
+ fill(&cs, p, n);
+ qunlock(&lk);
}