shithub: drawterm

Download patch

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);
 }