shithub: drawterm

Download patch

ref: 3084c76351b83338becd8a36d691ce076ea31c89
parent: 88f161d1786b19af9c1a79275ed57de0333918bd
author: cinap_lenrek <cinap_lenrek@felloff.net>
date: Sun Aug 28 15:28:16 EDT 2016

import secalloc()/secfre() from from 9front

--- a/kern/Makefile
+++ b/kern/Makefile
@@ -3,6 +3,7 @@
 LIB=libkern.a
 
 OFILES=\
+	alloc.$O\
 	allocb.$O\
 	cache.$O\
 	chan.$O\
@@ -30,7 +31,6 @@
 	procinit.$O\
 	rwlock.$O\
 	sleep.$O\
-	smalloc.$O\
 	stub.$O\
 	sysfile.$O\
 	qio.$O\
--- /dev/null
+++ b/kern/alloc.c
@@ -1,0 +1,34 @@
+#include "u.h"
+#include "lib.h"
+#include "dat.h"
+#include "fns.h"
+#include "error.h"
+
+void*
+smalloc(ulong n)
+{
+	return mallocz(n, 1);
+}
+
+void*
+malloc(ulong n)
+{
+	return mallocz(n, 1);
+}
+
+void*
+secalloc(ulong n)
+{
+	void *p = mallocz(n+sizeof(ulong), 1);
+	*(ulong*)p = n;
+	return (ulong*)p+1;
+}
+
+void
+secfree(void *p)
+{
+	if(p != nil){
+		memset(p, 0, ((ulong*)p)[-1]);
+		free((ulong*)p-1);
+	}
+}
--- a/kern/devssl.c
+++ b/kern/devssl.c
@@ -373,14 +373,10 @@
 		sslhangup(s);
 		if(s->c)
 			cclose(s->c);
-		if(s->in.secret)
-			free(s->in.secret);
-		if(s->out.secret)
-			free(s->out.secret);
-		if(s->in.state)
-			free(s->in.state);
-		if(s->out.state)
-			free(s->out.state);
+		secfree(s->in.secret);
+		secfree(s->out.secret);
+		secfree(s->in.state);
+		secfree(s->out.state);
 		free(s);
 
 	}
@@ -828,10 +824,8 @@
 static void
 setsecret(OneWay *w, uchar *secret, int n)
 {
-	if(w->secret)
-		free(w->secret);
-
-	w->secret = smalloc(n);
+	secfree(w->secret);
+	w->secret = secalloc(n);
 	memmove(w->secret, secret, n);
 	w->slen = n;
 }
@@ -839,12 +833,8 @@
 static void
 initDESkey(OneWay *w)
 {
-	if(w->state){
-		free(w->state);
-		w->state = 0;
-	}
-
-	w->state = smalloc(sizeof(DESstate));
+	secfree(w->state);
+	w->state = secalloc(sizeof(DESstate));
 	if(w->slen >= 16)
 		setupDESstate(w->state, w->secret, w->secret+8);
 	else if(w->slen >= 8)
@@ -862,11 +852,6 @@
 {
 	uchar key[8];
 
-	if(w->state){
-		free(w->state);
-		w->state = 0;
-	}
-
 	if(w->slen >= 8){
 		memmove(key, w->secret, 8);
 		key[0] &= 0x0f;
@@ -874,25 +859,14 @@
 		key[4] &= 0x0f;
 		key[6] &= 0x0f;
 	}
-
-	w->state = smalloc(sizeof(DESstate));
-	if(w->slen >= 16)
-		setupDESstate(w->state, key, w->secret+8);
-	else if(w->slen >= 8)
-		setupDESstate(w->state, key, 0);
-	else
-		error("secret too short");
+	initDESkey(w);
 }
 
 static void
 initRC4key(OneWay *w)
 {
-	if(w->state){
-		free(w->state);
-		w->state = 0;
-	}
-
-	w->state = smalloc(sizeof(RC4state));
+	secfree(w->state);
+	w->state = secalloc(sizeof(RC4state));
 	setupRC4state(w->state, w->secret, w->slen);
 }
 
@@ -903,16 +877,9 @@
 static void
 initRC4key_40(OneWay *w)
 {
-	if(w->state){
-		free(w->state);
-		w->state = 0;
-	}
-
 	if(w->slen > 5)
 		w->slen = 5;
-
-	w->state = smalloc(sizeof(RC4state));
-	setupRC4state(w->state, w->secret, w->slen);
+	initRC4key(w);
 }
 
 /*
@@ -922,16 +889,9 @@
 static void
 initRC4key_128(OneWay *w)
 {
-	if(w->state){
-		free(w->state);
-		w->state = 0;
-	}
-
 	if(w->slen > 16)
 		w->slen = 16;
-
-	w->state = smalloc(sizeof(RC4state));
-	setupRC4state(w->state, w->secret, w->slen);
+	initRC4key(w);
 }
 
 
@@ -1180,27 +1140,29 @@
 		break;
 	case Csin:
 		p = cb->f[1];
-		m = (strlen(p)*3)/2;
-		x = smalloc(m);
+		m = (strlen(p)*3)/2 + 1;
+		x = secalloc(m);
 		t = dec64(x, m, p, strlen(p));
+		memset(p, 0, strlen(p));
 		if(t <= 0){
-			free(x);
+			secfree(x);
 			error(Ebadarg);
 		}
 		setsecret(&s->in, x, t);
-		free(x);
+		secfree(x);
 		break;
 	case Csout:
 		p = cb->f[1];
 		m = (strlen(p)*3)/2 + 1;
-		x = smalloc(m);
+		x = secalloc(m);
 		t = dec64(x, m, p, strlen(p));
+		memset(p, 0, strlen(p));
 		if(t <= 0){
-			free(x);
+			secfree(x);
 			error(Ebadarg);
 		}
 		setsecret(&s->out, x, t);
-		free(x);
+		secfree(x);
 		break;
 	}
 	poperror();
--- a/kern/devtls.c
+++ b/kern/devtls.c
@@ -1468,7 +1468,7 @@
 static void
 initRC4key(Encalg *ea, Secret *s, uchar *p, uchar *iv)
 {
-	s->enckey = smalloc(sizeof(RC4state));
+	s->enckey = secalloc(sizeof(RC4state));
 	s->enc = rc4enc;
 	s->dec = rc4enc;
 	setupRC4state(s->enckey, p, ea->keylen);
@@ -1477,7 +1477,7 @@
 static void
 initDES3key(Encalg *ea, Secret *s, uchar *p, uchar *iv)
 {
-	s->enckey = smalloc(sizeof(DES3state));
+	s->enckey = secalloc(sizeof(DES3state));
 	s->enc = des3enc;
 	s->dec = des3dec;
 	s->block = 8;
@@ -1487,7 +1487,7 @@
 static void
 initAESkey(Encalg *ea, Secret *s, uchar *p, uchar *iv)
 {
-	s->enckey = smalloc(sizeof(AESstate));
+	s->enckey = secalloc(sizeof(AESstate));
 	s->enc = aesenc;
 	s->dec = aesdec;
 	s->block = 16;
@@ -1497,7 +1497,7 @@
 static void
 initccpolykey(Encalg *ea, Secret *s, uchar *p, uchar *iv)
 {
-	s->enckey = smalloc(sizeof(Chachastate));
+	s->enckey = secalloc(sizeof(Chachastate));
 	s->aead_enc = ccpoly_aead_enc;
 	s->aead_dec = ccpoly_aead_dec;
 	s->maclen = Poly1305dlen;
@@ -1514,7 +1514,7 @@
 static void
 initaesgcmkey(Encalg *ea, Secret *s, uchar *p, uchar *iv)
 {
-	s->enckey = smalloc(sizeof(AESGCMstate));
+	s->enckey = secalloc(sizeof(AESGCMstate));
 	s->aead_enc = aesgcm_aead_enc;
 	s->aead_dec = aesgcm_aead_dec;
 	s->maclen = 16;
@@ -1670,18 +1670,19 @@
 		ea = parseencalg(cb->f[2]);
 
 		p = cb->f[4];
-		m = (strlen(p)*3)/2;
-		x = smalloc(m);
-		tos = smalloc(sizeof(Secret));
-		toc = smalloc(sizeof(Secret));
+		m = (strlen(p)*3)/2 + 1;
+		x = secalloc(m);
+		tos = secalloc(sizeof(Secret));
+		toc = secalloc(sizeof(Secret));
 		if(waserror()){
+			secfree(x);
 			freeSec(tos);
 			freeSec(toc);
-			free(x);
 			nexterror();
 		}
 
 		m = dec64(x, m, p, strlen(p));
+		memset(p, 0, strlen(p));
 		if(m < 2 * ha->maclen + 2 * ea->keylen + 2 * ea->ivlen)
 			error("not enough secret data provided");
 
@@ -1716,7 +1717,7 @@
 		tos->encalg = ea->name;
 		tos->hashalg = ha->name;
 
-		free(x);
+		secfree(x);
 		poperror();
 	}else if(strcmp(cb->f[0], "changecipher") == 0){
 		if(cb->nf != 1)
@@ -2045,15 +2046,10 @@
 static void
 freeSec(Secret *s)
 {
-	void *k;
-
 	if(s == nil)
 		return;
-	k = s->enckey;
-	if(k != nil)
-		free(k);
-	memset(s, 0, sizeof(*s));
-	free(s);
+	secfree(s->enckey);
+	secfree(s);
 }
 
 static int
@@ -2157,6 +2153,8 @@
 		iv[i+(ChachaIVlen-8)] ^= seq[i];
 
 	chacha_setiv(cs, iv);
+
+	memset(iv, 0, sizeof(iv));
 }
 
 static int
@@ -2191,6 +2189,7 @@
 	for(i=0; i<8; i++) iv[4+i] ^= aad[i];
 	memmove(reciv, iv+4, 8);
 	aesgcm_setiv(sec->enckey, iv, 12);
+	memset(iv, 0, sizeof(iv));
 	aesgcm_encrypt(data, len, aad, aadlen, data+len, sec->enckey);
 	return len + sec->maclen;
 }
@@ -2206,6 +2205,7 @@
 	memmove(iv, sec->mackey, 4);
 	memmove(iv+4, reciv, 8);
 	aesgcm_setiv(sec->enckey, iv, 12);
+	memset(iv, 0, sizeof(iv));
 	if(aesgcm_decrypt(data, len, aad, aadlen, data+len, sec->enckey) != 0)
 		return -1;
 	return len;
--- a/kern/fns.h
+++ b/kern/fns.h
@@ -295,6 +295,8 @@
 void		scheddump(void);
 void		schedinit(void);
 extern void		(*screenputs)(char*, int);
+void*		secalloc(ulong);
+void		secfree(void*);
 long		seconds(void);
 ulong		segattach(Proc*, ulong, char *, ulong, ulong);
 void		segclock(ulong);
--- a/kern/smalloc.c
+++ /dev/null
@@ -1,18 +1,0 @@
-#include "u.h"
-#include "lib.h"
-#include "dat.h"
-#include "fns.h"
-#include "error.h"
-
-void*
-smalloc(ulong n)
-{
-	return mallocz(n, 1);
-}
-
-void*
-malloc(ulong n)
-{
-	return mallocz(n, 1);
-}
-