Module Name: src Committed By: drochner Date: Thu Aug 30 12:16:49 UTC 2012
Modified Files: src/include: string.h src/lib/libc/string: Makefile.inc src/lib/libcrypt: bcrypt.c crypt-sha1.c md5crypt.c src/sys/dev: cgd_crypto.c src/sys/lib/libkern: Makefile.libkern libkern.h src/sys/netipsec: key.c xform_ah.c xform_esp.c src/sys/opencrypto: cryptosoft.c Added Files: src/common/lib/libc/string: consttime_bcmp.c explicit_bzero.c Log Message: Add "consttime_bcmp" and "explicit_bzero" functions for both kernel abd userland, as proposed on tech-security, with explicit_bzero using a volatile function pointer as suggested by Alan Barrett. Both do what the name says. For userland, both are prefixed by "__" to keep them out of the user namespace. Change some memset/memcmp uses to the new functions where it makes sense -- these are just some examples, more to come. To generate a diff of this commit: cvs rdiff -u -r0 -r1.1 src/common/lib/libc/string/consttime_bcmp.c \ src/common/lib/libc/string/explicit_bzero.c cvs rdiff -u -r1.40 -r1.41 src/include/string.h cvs rdiff -u -r1.75 -r1.76 src/lib/libc/string/Makefile.inc cvs rdiff -u -r1.16 -r1.17 src/lib/libcrypt/bcrypt.c cvs rdiff -u -r1.4 -r1.5 src/lib/libcrypt/crypt-sha1.c cvs rdiff -u -r1.11 -r1.12 src/lib/libcrypt/md5crypt.c cvs rdiff -u -r1.9 -r1.10 src/sys/dev/cgd_crypto.c cvs rdiff -u -r1.17 -r1.18 src/sys/lib/libkern/Makefile.libkern cvs rdiff -u -r1.105 -r1.106 src/sys/lib/libkern/libkern.h cvs rdiff -u -r1.77 -r1.78 src/sys/netipsec/key.c cvs rdiff -u -r1.37 -r1.38 src/sys/netipsec/xform_ah.c cvs rdiff -u -r1.40 -r1.41 src/sys/netipsec/xform_esp.c cvs rdiff -u -r1.39 -r1.40 src/sys/opencrypto/cryptosoft.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/include/string.h diff -u src/include/string.h:1.40 src/include/string.h:1.41 --- src/include/string.h:1.40 Fri Apr 20 16:20:45 2012 +++ src/include/string.h Thu Aug 30 12:16:48 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: string.h,v 1.40 2012/04/20 16:20:45 joerg Exp $ */ +/* $NetBSD: string.h,v 1.41 2012/08/30 12:16:48 drochner Exp $ */ /*- * Copyright (c) 1990, 1993 @@ -109,6 +109,8 @@ char *strsep(char **, const char *); char *stresep(char **, const char *, int); char *strndup(const char *, size_t); void *memrchr(const void *, int, size_t); +void __explicit_bzero(void *, size_t); +int __consttime_bcmp(const void *, const void *, size_t); __END_DECLS #endif Index: src/lib/libc/string/Makefile.inc diff -u src/lib/libc/string/Makefile.inc:1.75 src/lib/libc/string/Makefile.inc:1.76 --- src/lib/libc/string/Makefile.inc:1.75 Thu Jul 30 20:57:15 2009 +++ src/lib/libc/string/Makefile.inc Thu Aug 30 12:16:48 2012 @@ -1,5 +1,5 @@ # from: @(#)Makefile.inc 8.1 (Berkeley) 6/4/93 -# $NetBSD: Makefile.inc,v 1.75 2009/07/30 20:57:15 dsl Exp $ +# $NetBSD: Makefile.inc,v 1.76 2012/08/30 12:16:48 drochner Exp $ # string sources .PATH: ${ARCHDIR}/string ${.CURDIR}/string @@ -19,6 +19,7 @@ SRCS+= bcmp.c bcopy.c bzero.c ffs.c memc SRCS+= strcat.c strcmp.c strcpy.c strcspn.c strlen.c SRCS+= strncat.c strncmp.c strncpy.c strpbrk.c strsep.c SRCS+= strspn.c strstr.c swab.c +SRCS+= explicit_bzero.c consttime_bcmp.c SRCS+= memccpy.c memcpy.c memmem.c memmove.c SRCS+= strchr.c strrchr.c Index: src/lib/libcrypt/bcrypt.c diff -u src/lib/libcrypt/bcrypt.c:1.16 src/lib/libcrypt/bcrypt.c:1.17 --- src/lib/libcrypt/bcrypt.c:1.16 Wed Mar 21 05:33:26 2012 +++ src/lib/libcrypt/bcrypt.c Thu Aug 30 12:16:49 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: bcrypt.c,v 1.16 2012/03/21 05:33:26 matt Exp $ */ +/* $NetBSD: bcrypt.c,v 1.17 2012/08/30 12:16:49 drochner Exp $ */ /* $OpenBSD: bcrypt.c,v 1.16 2002/02/19 19:39:36 millert Exp $ */ /* @@ -46,7 +46,7 @@ * */ #include <sys/cdefs.h> -__RCSID("$NetBSD: bcrypt.c,v 1.16 2012/03/21 05:33:26 matt Exp $"); +__RCSID("$NetBSD: bcrypt.c,v 1.17 2012/08/30 12:16:49 drochner Exp $"); #include <stdio.h> #include <stdlib.h> @@ -314,7 +314,7 @@ __bcrypt(const char *key, const char *sa encode_base64((u_int8_t *) encrypted + i + 3, csalt, BCRYPT_MAXSALT); encode_base64((u_int8_t *) encrypted + strlen(encrypted), ciphertext, 4 * BCRYPT_BLOCKS - 1); - memset(&state, 0, sizeof(state)); + __explicit_bzero(&state, sizeof(state)); return encrypted; } Index: src/lib/libcrypt/crypt-sha1.c diff -u src/lib/libcrypt/crypt-sha1.c:1.4 src/lib/libcrypt/crypt-sha1.c:1.5 --- src/lib/libcrypt/crypt-sha1.c:1.4 Mon May 9 19:15:28 2011 +++ src/lib/libcrypt/crypt-sha1.c Thu Aug 30 12:16:49 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: crypt-sha1.c,v 1.4 2011/05/09 19:15:28 drochner Exp $ */ +/* $NetBSD: crypt-sha1.c,v 1.5 2012/08/30 12:16:49 drochner Exp $ */ /* * Copyright (c) 2004, Juniper Networks, Inc. @@ -31,7 +31,7 @@ #include <sys/cdefs.h> #if !defined(lint) -__RCSID("$NetBSD: crypt-sha1.c,v 1.4 2011/05/09 19:15:28 drochner Exp $"); +__RCSID("$NetBSD: crypt-sha1.c,v 1.5 2012/08/30 12:16:49 drochner Exp $"); #endif /* not lint */ #include <stdlib.h> @@ -190,7 +190,7 @@ __crypt_sha1 (const char *pw, const char *ep = '\0'; /* Don't leave anything around in vm they could use. */ - memset(hmac_buf, 0, sizeof hmac_buf); + __explicit_bzero(hmac_buf, sizeof hmac_buf); return passwd; } Index: src/lib/libcrypt/md5crypt.c diff -u src/lib/libcrypt/md5crypt.c:1.11 src/lib/libcrypt/md5crypt.c:1.12 --- src/lib/libcrypt/md5crypt.c:1.11 Tue Nov 29 17:27:10 2011 +++ src/lib/libcrypt/md5crypt.c Thu Aug 30 12:16:49 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: md5crypt.c,v 1.11 2011/11/29 17:27:10 drochner Exp $ */ +/* $NetBSD: md5crypt.c,v 1.12 2012/08/30 12:16:49 drochner Exp $ */ /* * ---------------------------------------------------------------------------- @@ -15,7 +15,7 @@ #include <sys/cdefs.h> #if !defined(lint) -__RCSID("$NetBSD: md5crypt.c,v 1.11 2011/11/29 17:27:10 drochner Exp $"); +__RCSID("$NetBSD: md5crypt.c,v 1.12 2012/08/30 12:16:49 drochner Exp $"); #endif /* not lint */ #include <unistd.h> @@ -143,6 +143,6 @@ __md5crypt(const char *pw, const char *s *p = '\0'; /* Don't leave anything around in vm they could use. */ - memset(final, 0, sizeof(final)); + __explicit_bzero(final, sizeof(final)); return (passwd); } Index: src/sys/dev/cgd_crypto.c diff -u src/sys/dev/cgd_crypto.c:1.9 src/sys/dev/cgd_crypto.c:1.10 --- src/sys/dev/cgd_crypto.c:1.9 Mon Apr 28 20:23:46 2008 +++ src/sys/dev/cgd_crypto.c Thu Aug 30 12:16:48 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: cgd_crypto.c,v 1.9 2008/04/28 20:23:46 martin Exp $ */ +/* $NetBSD: cgd_crypto.c,v 1.10 2012/08/30 12:16:48 drochner Exp $ */ /*- * Copyright (c) 2002 The NetBSD Foundation, Inc. @@ -37,7 +37,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: cgd_crypto.c,v 1.9 2008/04/28 20:23:46 martin Exp $"); +__KERNEL_RCSID(0, "$NetBSD: cgd_crypto.c,v 1.10 2012/08/30 12:16:48 drochner Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -195,7 +195,7 @@ cgd_cipher_aes_destroy(void *data) { struct aes_privdata *apd = data; - (void)memset(apd, 0, sizeof(*apd)); + explicit_bzero(apd, sizeof(*apd)); free(apd, M_DEVBUF); } @@ -296,7 +296,7 @@ cgd_cipher_3des_init(size_t keylen, cons error |= des_key_sched(block + 1, cp->cp_key2); error |= des_key_sched(block + 2, cp->cp_key3); if (error) { - (void)memset(cp, 0, sizeof(*cp)); + explicit_bzero(cp, sizeof(*cp)); free(cp, M_DEVBUF); return NULL; } @@ -308,7 +308,7 @@ cgd_cipher_3des_destroy(void *data) { struct c3des_privdata *cp = data; - (void)memset(cp, 0, sizeof(*cp)); + explicit_bzero(cp, sizeof(*cp)); free(cp, M_DEVBUF); } @@ -408,7 +408,7 @@ cgd_cipher_bf_destroy(void *data) { struct bf_privdata *bp = data; - (void)memset(bp, 0, sizeof(*bp)); + explicit_bzero(bp, sizeof(*bp)); free(bp, M_DEVBUF); } Index: src/sys/lib/libkern/Makefile.libkern diff -u src/sys/lib/libkern/Makefile.libkern:1.17 src/sys/lib/libkern/Makefile.libkern:1.18 --- src/sys/lib/libkern/Makefile.libkern:1.17 Sun Feb 5 14:19:03 2012 +++ src/sys/lib/libkern/Makefile.libkern Thu Aug 30 12:16:49 2012 @@ -1,4 +1,4 @@ -# $NetBSD: Makefile.libkern,v 1.17 2012/02/05 14:19:03 dholland Exp $ +# $NetBSD: Makefile.libkern,v 1.18 2012/08/30 12:16:49 drochner Exp $ # # Variable definitions for libkern. @@ -92,6 +92,9 @@ SRCS+= xlat_mbr_fstype.c SRCS+= heapsort.c ptree.c rb.c +# for crypto +SRCS+= explicit_bzero.c consttime_bcmp.c + # Files to clean up CLEANFILES+= lib${LIB}.o lib${LIB}.po Index: src/sys/lib/libkern/libkern.h diff -u src/sys/lib/libkern/libkern.h:1.105 src/sys/lib/libkern/libkern.h:1.106 --- src/sys/lib/libkern/libkern.h:1.105 Sun Jan 22 02:57:36 2012 +++ src/sys/lib/libkern/libkern.h Thu Aug 30 12:16:49 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: libkern.h,v 1.105 2012/01/22 02:57:36 rmind Exp $ */ +/* $NetBSD: libkern.h,v 1.106 2012/08/30 12:16:49 drochner Exp $ */ /*- * Copyright (c) 1992, 1993 @@ -345,4 +345,7 @@ unsigned int popcountl(unsigned long) __ unsigned int popcountll(unsigned long long) __constfunc; unsigned int popcount32(uint32_t) __constfunc; unsigned int popcount64(uint64_t) __constfunc; + +void explicit_bzero(void *, size_t); +int consttime_bcmp(const void *, const void *, size_t); #endif /* !_LIB_LIBKERN_LIBKERN_H_ */ Index: src/sys/netipsec/key.c diff -u src/sys/netipsec/key.c:1.77 src/sys/netipsec/key.c:1.78 --- src/sys/netipsec/key.c:1.77 Wed Aug 29 20:37:50 2012 +++ src/sys/netipsec/key.c Thu Aug 30 12:16:49 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: key.c,v 1.77 2012/08/29 20:37:50 drochner Exp $ */ +/* $NetBSD: key.c,v 1.78 2012/08/30 12:16:49 drochner Exp $ */ /* $FreeBSD: src/sys/netipsec/key.c,v 1.3.2.3 2004/02/14 22:23:23 bms Exp $ */ /* $KAME: key.c,v 1.191 2001/06/27 10:46:49 sakane Exp $ */ @@ -32,7 +32,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: key.c,v 1.77 2012/08/29 20:37:50 drochner Exp $"); +__KERNEL_RCSID(0, "$NetBSD: key.c,v 1.78 2012/08/30 12:16:49 drochner Exp $"); /* * This code is referd to RFC 2367 @@ -3040,9 +3040,9 @@ key_delsav(struct secasvar *sav) sav->tdb_xform = NULL; } else { if (sav->key_auth != NULL) - memset(_KEYBUF(sav->key_auth), 0, _KEYLEN(sav->key_auth)); + explicit_bzero(_KEYBUF(sav->key_auth), _KEYLEN(sav->key_auth)); if (sav->key_enc != NULL) - memset(_KEYBUF(sav->key_enc), 0, _KEYLEN(sav->key_enc)); + explicit_bzero(_KEYBUF(sav->key_enc), _KEYLEN(sav->key_enc)); } if (sav->key_auth != NULL) { KFREE(sav->key_auth); Index: src/sys/netipsec/xform_ah.c diff -u src/sys/netipsec/xform_ah.c:1.37 src/sys/netipsec/xform_ah.c:1.38 --- src/sys/netipsec/xform_ah.c:1.37 Thu Jan 26 21:10:24 2012 +++ src/sys/netipsec/xform_ah.c Thu Aug 30 12:16:49 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: xform_ah.c,v 1.37 2012/01/26 21:10:24 drochner Exp $ */ +/* $NetBSD: xform_ah.c,v 1.38 2012/08/30 12:16:49 drochner Exp $ */ /* $FreeBSD: src/sys/netipsec/xform_ah.c,v 1.1.4.1 2003/01/24 05:11:36 sam Exp $ */ /* $OpenBSD: ip_ah.c,v 1.63 2001/06/26 06:18:58 angelos Exp $ */ /* @@ -39,7 +39,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: xform_ah.c,v 1.37 2012/01/26 21:10:24 drochner Exp $"); +__KERNEL_RCSID(0, "$NetBSD: xform_ah.c,v 1.38 2012/08/30 12:16:49 drochner Exp $"); #include "opt_inet.h" #ifdef __FreeBSD__ @@ -918,7 +918,7 @@ ah_input_cb(struct cryptop *crp) ptr = (char *) (tc + 1); /* Verify authenticator. */ - if (memcmp(ptr + skip + rplen, calc, authsize)) { + if (consttime_bcmp(ptr + skip + rplen, calc, authsize)) { u_int8_t *pppp = ptr + skip+rplen; DPRINTF(("ah_input: authentication hash mismatch " \ "over %d bytes " \ Index: src/sys/netipsec/xform_esp.c diff -u src/sys/netipsec/xform_esp.c:1.40 src/sys/netipsec/xform_esp.c:1.41 --- src/sys/netipsec/xform_esp.c:1.40 Wed Jan 25 20:31:23 2012 +++ src/sys/netipsec/xform_esp.c Thu Aug 30 12:16:49 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: xform_esp.c,v 1.40 2012/01/25 20:31:23 drochner Exp $ */ +/* $NetBSD: xform_esp.c,v 1.41 2012/08/30 12:16:49 drochner Exp $ */ /* $FreeBSD: src/sys/netipsec/xform_esp.c,v 1.2.2.1 2003/01/24 05:11:36 sam Exp $ */ /* $OpenBSD: ip_esp.c,v 1.69 2001/06/26 06:18:59 angelos Exp $ */ @@ -39,7 +39,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: xform_esp.c,v 1.40 2012/01/25 20:31:23 drochner Exp $"); +__KERNEL_RCSID(0, "$NetBSD: xform_esp.c,v 1.41 2012/08/30 12:16:49 drochner Exp $"); #include "opt_inet.h" #ifdef __FreeBSD__ @@ -601,7 +601,7 @@ esp_input_cb(struct cryptop *crp) ptr = (tc + 1); /* Verify authenticator */ - if (memcmp(ptr, aalg, esph->authsize) != 0) { + if (consttime_bcmp(ptr, aalg, esph->authsize) != 0) { DPRINTF(("esp_input_cb: " "authentication hash mismatch for packet in SA %s/%08lx\n", ipsec_address(&saidx->dst), Index: src/sys/opencrypto/cryptosoft.c diff -u src/sys/opencrypto/cryptosoft.c:1.39 src/sys/opencrypto/cryptosoft.c:1.40 --- src/sys/opencrypto/cryptosoft.c:1.39 Mon Nov 28 08:05:06 2011 +++ src/sys/opencrypto/cryptosoft.c Thu Aug 30 12:16:49 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: cryptosoft.c,v 1.39 2011/11/28 08:05:06 tls Exp $ */ +/* $NetBSD: cryptosoft.c,v 1.40 2012/08/30 12:16:49 drochner Exp $ */ /* $FreeBSD: src/sys/opencrypto/cryptosoft.c,v 1.2.2.1 2002/11/21 23:34:23 sam Exp $ */ /* $OpenBSD: cryptosoft.c,v 1.35 2002/04/26 08:43:50 deraadt Exp $ */ @@ -24,7 +24,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: cryptosoft.c,v 1.39 2011/11/28 08:05:06 tls Exp $"); +__KERNEL_RCSID(0, "$NetBSD: cryptosoft.c,v 1.40 2012/08/30 12:16:49 drochner Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -1089,11 +1089,11 @@ swcr_freesession(void *arg, u_int64_t ti axf = swd->sw_axf; if (swd->sw_ictx) { - memset(swd->sw_ictx, 0, axf->ctxsize); + explicit_bzero(swd->sw_ictx, axf->ctxsize); free(swd->sw_ictx, M_CRYPTO_DATA); } if (swd->sw_octx) { - memset(swd->sw_octx, 0, axf->ctxsize); + explicit_bzero(swd->sw_octx, axf->ctxsize); free(swd->sw_octx, M_CRYPTO_DATA); } break; @@ -1103,11 +1103,11 @@ swcr_freesession(void *arg, u_int64_t ti axf = swd->sw_axf; if (swd->sw_ictx) { - memset(swd->sw_ictx, 0, axf->ctxsize); + explicit_bzero(swd->sw_ictx, axf->ctxsize); free(swd->sw_ictx, M_CRYPTO_DATA); } if (swd->sw_octx) { - memset(swd->sw_octx, 0, swd->sw_klen); + explicit_bzero(swd->sw_octx, swd->sw_klen); free(swd->sw_octx, M_CRYPTO_DATA); } break; @@ -1120,8 +1120,10 @@ swcr_freesession(void *arg, u_int64_t ti case CRYPTO_AES_256_GMAC: axf = swd->sw_axf; - if (swd->sw_ictx) + if (swd->sw_ictx) { + explicit_bzero(swd->sw_ictx, axf->ctxsize); free(swd->sw_ictx, M_CRYPTO_DATA); + } break; case CRYPTO_DEFLATE_COMP: Added files: Index: src/common/lib/libc/string/consttime_bcmp.c diff -u /dev/null src/common/lib/libc/string/consttime_bcmp.c:1.1 --- /dev/null Thu Aug 30 12:16:50 2012 +++ src/common/lib/libc/string/consttime_bcmp.c Thu Aug 30 12:16:49 2012 @@ -0,0 +1,19 @@ +/* $NetBSD: consttime_bcmp.c,v 1.1 2012/08/30 12:16:49 drochner Exp $ */ + +#if !defined(_KERNEL) && !defined(_STANDALONE) +#include <string.h> +#define consttime_bcmp __consttime_bcmp +#else +#include <lib/libkern/libkern.h> +#endif + +int +consttime_bcmp(const void *b1, const void *b2, size_t len) +{ + const char *c1 = b1, *c2 = b2; + int res = 0; + + while (len --) + res |= *c1++ ^ *c2++; + return res; +} Index: src/common/lib/libc/string/explicit_bzero.c diff -u /dev/null src/common/lib/libc/string/explicit_bzero.c:1.1 --- /dev/null Thu Aug 30 12:16:50 2012 +++ src/common/lib/libc/string/explicit_bzero.c Thu Aug 30 12:16:49 2012 @@ -0,0 +1,22 @@ +/* $NetBSD: explicit_bzero.c,v 1.1 2012/08/30 12:16:49 drochner Exp $ */ + +#if !defined(_KERNEL) && !defined(_STANDALONE) +#include <string.h> +#define explicit_bzero __explicit_bzero +#define explicit_memset_impl __explicit_memset_impl +#else +#include <lib/libkern/libkern.h> +#endif + +/* + * The use of a volatile pointer guarantees that the compiler + * will not optimise the call away. + */ +void *(* volatile explicit_memset_impl)(void *, int, size_t) = memset; + +void +explicit_bzero(void *b, size_t len) +{ + + (*explicit_memset_impl)(b, 0, len); +}