Plan 9 from Bell Labs’s /usr/web/sources/contrib/mospak/tls-1.2/tls-record-zeroize-on-free.diff

Copyright © 2021 Plan 9 Foundation.
Distributed under the MIT License.
Download the Plan 9 distribution.


--- sys/src/9/port/devtls.c
+++ sys/src/9/port/devtls.c
@@ -93,6 +93,7 @@ struct Secret
 	int		recivlen;	/* explicit record IV length (AEAD only, else 0) */
 	int		maclen;
 	void		*enckey;
+	int		enckeylen;	/* sizeof(*enckey) for zeroize-on-free */
 	uchar	mackey[MaxMacLen];
 };
 
@@ -1502,6 +1503,7 @@ initRC4key(Encalg *ea, Secret *s, uchar *p, uchar *)
 initRC4key(Encalg *ea, Secret *s, uchar *p, uchar *)
 {
 	s->enckey = smalloc(sizeof(RC4state));
+	s->enckeylen = sizeof(RC4state);
 	s->enc = rc4enc;
 	s->dec = rc4enc;
 	s->block = 0;
@@ -1512,6 +1514,7 @@ initDES3key(Encalg *, Secret *s, uchar *p, uchar *iv)
 initDES3key(Encalg *, Secret *s, uchar *p, uchar *iv)
 {
 	s->enckey = smalloc(sizeof(DES3state));
+	s->enckeylen = sizeof(DES3state);
 	s->enc = des3enc;
 	s->dec = des3dec;
 	s->block = 8;
@@ -1522,6 +1525,7 @@ initAESkey(Encalg *ea, Secret *s, uchar *p, uchar *iv)
 initAESkey(Encalg *ea, Secret *s, uchar *p, uchar *iv)
 {
 	s->enckey = smalloc(sizeof(AESstate));
+	s->enckeylen = sizeof(AESstate);
 	s->enc = aesenc;
 	s->dec = aesdec;
 	s->block = 16;
@@ -1532,6 +1536,7 @@ initccpolykey(Encalg *ea, Secret *s, uchar *p, uchar *
 initccpolykey(Encalg *ea, Secret *s, uchar *p, uchar *iv)
 {
 	s->enckey = smalloc(sizeof(Chachastate));
+	s->enckeylen = sizeof(Chachastate);
 	s->aead_enc = ccpoly_aead_enc;
 	s->aead_dec = ccpoly_aead_dec;
 	s->maclen = Poly1305dlen;
@@ -1544,6 +1549,7 @@ initaesgcmkey(Encalg *ea, Secret *s, uchar *p, uchar *
 initaesgcmkey(Encalg *ea, Secret *s, uchar *p, uchar *iv)
 {
 	s->enckey = smalloc(sizeof(AESGCMstate));
+	s->enckeylen = sizeof(AESGCMstate);
 	s->aead_enc = aesgcm_aead_enc;
 	s->aead_dec = aesgcm_aead_dec;
 	s->maclen = 16;
@@ -2071,11 +2077,27 @@ tlsstate(int s)
 	return "Unknown";
 }
 
+/* secmemset zeroes through a volatile pointer so dead-store elimination
+ * cannot drop the writes.  Plan 9 8c/kencc do not currently elide, but
+ * gcc/clang would; the volatile is defense against future toolchain ports. */
 static void
+secmemset(void *p, int v, int n)
+{
+	volatile uchar *vp;
+
+	vp = p;
+	while(n-- > 0)
+		*vp++ = v;
+}
+
+static void
 freeSec(Secret *s)
 {
 	if(s != nil){
+		if(s->enckey != nil && s->enckeylen > 0)
+			secmemset(s->enckey, 0, s->enckeylen);
 		free(s->enckey);
+		secmemset(s, 0, sizeof(*s));
 		free(s);
 	}
 }
--- sys/src/9k/port/devtls.c
+++ sys/src/9k/port/devtls.c
@@ -93,6 +93,7 @@ struct Secret
 	int		recivlen;	/* explicit record IV length (AEAD only, else 0) */
 	int		maclen;
 	void		*enckey;
+	int		enckeylen;	/* sizeof(*enckey) for zeroize-on-free */
 	uchar	mackey[MaxMacLen];
 };
 
@@ -1502,6 +1503,7 @@ initRC4key(Encalg *ea, Secret *s, uchar *p, uchar *)
 initRC4key(Encalg *ea, Secret *s, uchar *p, uchar *)
 {
 	s->enckey = smalloc(sizeof(RC4state));
+	s->enckeylen = sizeof(RC4state);
 	s->enc = rc4enc;
 	s->dec = rc4enc;
 	s->block = 0;
@@ -1512,6 +1514,7 @@ initDES3key(Encalg *, Secret *s, uchar *p, uchar *iv)
 initDES3key(Encalg *, Secret *s, uchar *p, uchar *iv)
 {
 	s->enckey = smalloc(sizeof(DES3state));
+	s->enckeylen = sizeof(DES3state);
 	s->enc = des3enc;
 	s->dec = des3dec;
 	s->block = 8;
@@ -1522,6 +1525,7 @@ initAESkey(Encalg *ea, Secret *s, uchar *p, uchar *iv)
 initAESkey(Encalg *ea, Secret *s, uchar *p, uchar *iv)
 {
 	s->enckey = smalloc(sizeof(AESstate));
+	s->enckeylen = sizeof(AESstate);
 	s->enc = aesenc;
 	s->dec = aesdec;
 	s->block = 16;
@@ -1532,6 +1536,7 @@ initccpolykey(Encalg *ea, Secret *s, uchar *p, uchar *
 initccpolykey(Encalg *ea, Secret *s, uchar *p, uchar *iv)
 {
 	s->enckey = smalloc(sizeof(Chachastate));
+	s->enckeylen = sizeof(Chachastate);
 	s->aead_enc = ccpoly_aead_enc;
 	s->aead_dec = ccpoly_aead_dec;
 	s->maclen = Poly1305dlen;
@@ -1544,6 +1549,7 @@ initaesgcmkey(Encalg *ea, Secret *s, uchar *p, uchar *
 initaesgcmkey(Encalg *ea, Secret *s, uchar *p, uchar *iv)
 {
 	s->enckey = smalloc(sizeof(AESGCMstate));
+	s->enckeylen = sizeof(AESGCMstate);
 	s->aead_enc = aesgcm_aead_enc;
 	s->aead_dec = aesgcm_aead_dec;
 	s->maclen = 16;
@@ -2071,11 +2077,27 @@ tlsstate(int s)
 	return "Unknown";
 }
 
+/* secmemset zeroes through a volatile pointer so dead-store elimination
+ * cannot drop the writes.  Plan 9 8c/kencc do not currently elide, but
+ * gcc/clang would; the volatile is defense against future toolchain ports. */
 static void
+secmemset(void *p, int v, int n)
+{
+	volatile uchar *vp;
+
+	vp = p;
+	while(n-- > 0)
+		*vp++ = v;
+}
+
+static void
 freeSec(Secret *s)
 {
 	if(s != nil){
+		if(s->enckey != nil && s->enckeylen > 0)
+			secmemset(s->enckey, 0, s->enckeylen);
 		free(s->enckey);
+		secmemset(s, 0, sizeof(*s));
 		free(s);
 	}
 }

Bell Labs OSI certified Powered by Plan 9

(Return to Plan 9 Home Page)

Copyright © 2021 Plan 9 Foundation. All Rights Reserved.
Comments to webmaster@9p.io.