Module Name: src Committed By: drochner Date: Fri Feb 25 20:13:10 UTC 2011
Modified Files: src/share/man/man4: crypto.4 src/sys/netipsec: xform.h xform_esp.c src/sys/opencrypto: cryptodev.h cryptosoft.c xform.c xform.h Log Message: make the use of SHA2-HMAC by FAST_IPSEC compliant to current standards: -RFC2104 says that the block size of the hash algorithm must be used for key/ipad/opad calculations. While formerly all ciphers used a block length of 64, SHA384 and SHA512 use 128 bytes. So we can't use the HMAC_BLOCK_LEN constant anymore. Add a new field to "struct auth_hash" for the per-cipher blocksize. -Due to this, there can't be a single "CRYPTO_SHA2_HMAC" external name anymore. Replace this by 3 for the 3 different keysizes. This was done by Open/FreeBSD before. -Also fix the number of authenticator bits used tor ESP and AH to conform to RFC4868, and remove uses of AH_HMAC_HASHLEN which did assume a fixed authenticator size of 12 bytes. FAST_IPSEC will not interoperate with KAME IPSEC anymore if sha2 is used, because the latter doesn't implement these standards. It should interoperate with at least modern Free/OpenBSD now. (I've only tested with NetBSD-current/FAST_IPSEC on both ends.) To generate a diff of this commit: cvs rdiff -u -r1.21 -r1.22 src/share/man/man4/crypto.4 cvs rdiff -u -r1.6 -r1.7 src/sys/netipsec/xform.h cvs rdiff -u -r1.29 -r1.30 src/sys/netipsec/xform_esp.c cvs rdiff -u -r1.18 -r1.19 src/sys/opencrypto/cryptodev.h cvs rdiff -u -r1.28 -r1.29 src/sys/opencrypto/cryptosoft.c cvs rdiff -u -r1.19 -r1.20 src/sys/opencrypto/xform.c cvs rdiff -u -r1.11 -r1.12 src/sys/opencrypto/xform.h Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/share/man/man4/crypto.4 diff -u src/share/man/man4/crypto.4:1.21 src/share/man/man4/crypto.4:1.22 --- src/share/man/man4/crypto.4:1.21 Tue Apr 20 08:37:22 2010 +++ src/share/man/man4/crypto.4 Fri Feb 25 20:13:10 2011 @@ -1,4 +1,4 @@ -.\" $NetBSD: crypto.4,v 1.21 2010/04/20 08:37:22 jruoho Exp $ +.\" $NetBSD: crypto.4,v 1.22 2011/02/25 20:13:10 drochner Exp $ .\" .\" Copyright (c) 2008 The NetBSD Foundation, Inc. .\" All rights reserved. @@ -207,7 +207,9 @@ .It CRYPTO_SHA1_KPDK .It CRYPTO_MD5_HMAC .It CRYPTO_SHA1_HMAC -.It CRYPTO_SHA2_HMAC +.It CRYPTO_SHA2_256_HMAC +.It CRYPTO_SHA2_384_HMAC +.It CRYPTO_SHA2_512_HMAC .It CRYPTO_MD5 .It CRYPTO_SHA1 .El Index: src/sys/netipsec/xform.h diff -u src/sys/netipsec/xform.h:1.6 src/sys/netipsec/xform.h:1.7 --- src/sys/netipsec/xform.h:1.6 Fri Feb 18 20:40:58 2011 +++ src/sys/netipsec/xform.h Fri Feb 25 20:13:10 2011 @@ -1,4 +1,4 @@ -/* $NetBSD: xform.h,v 1.6 2011/02/18 20:40:58 drochner Exp $ */ +/* $NetBSD: xform.h,v 1.7 2011/02/25 20:13:10 drochner Exp $ */ /* $FreeBSD: src/sys/netipsec/xform.h,v 1.1.4.1 2003/01/24 05:11:36 sam Exp $ */ /* $OpenBSD: ip_ipsp.h,v 1.119 2002/03/14 01:27:11 millert Exp $ */ /* @@ -46,7 +46,6 @@ #include <netinet/in.h> #include <opencrypto/xform.h> -#define AH_HMAC_HASHLEN 12 /* 96 bits of authenticator */ #define AH_HMAC_INITIAL_RPL 1 /* replay counter initial value */ /* Index: src/sys/netipsec/xform_esp.c diff -u src/sys/netipsec/xform_esp.c:1.29 src/sys/netipsec/xform_esp.c:1.30 --- src/sys/netipsec/xform_esp.c:1.29 Sat Feb 19 18:26:50 2011 +++ src/sys/netipsec/xform_esp.c Fri Feb 25 20:13:10 2011 @@ -1,4 +1,4 @@ -/* $NetBSD: xform_esp.c,v 1.29 2011/02/19 18:26:50 degroote Exp $ */ +/* $NetBSD: xform_esp.c,v 1.30 2011/02/25 20:13:10 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.29 2011/02/19 18:26:50 degroote Exp $"); +__KERNEL_RCSID(0, "$NetBSD: xform_esp.c,v 1.30 2011/02/25 20:13:10 drochner Exp $"); #include "opt_inet.h" #ifdef __FreeBSD__ @@ -310,7 +310,7 @@ else hlen = sizeof (struct newesp) + sav->ivlen; /* Authenticator hash size */ - alen = esph ? AH_HMAC_HASHLEN : 0; + alen = esph ? esph->authsize : 0; /* * Verify payload length is multiple of encryption algorithm @@ -463,7 +463,7 @@ static int esp_input_cb(struct cryptop *crp) { - u_int8_t lastthree[3], aalg[AH_HMAC_HASHLEN]; + u_int8_t lastthree[3], aalg[AH_ALEN_MAX]; int s, hlen, skip, protoff, error; struct mbuf *m; struct cryptodesc *crd; @@ -735,7 +735,7 @@ plen = rlen + padding; /* Padded payload length. */ if (esph) - alen = AH_HMAC_HASHLEN; + alen = esph->authsize; else alen = 0; @@ -992,7 +992,7 @@ #ifdef IPSEC_DEBUG /* Emulate man-in-the-middle attack when ipsec_integrity is TRUE. */ if (ipsec_integrity) { - static unsigned char ipseczeroes[AH_HMAC_HASHLEN]; + static unsigned char ipseczeroes[AH_ALEN_MAX]; const struct auth_hash *esph; /* @@ -1001,8 +1001,8 @@ */ esph = sav->tdb_authalgxform; if (esph != NULL) { - m_copyback(m, m->m_pkthdr.len - AH_HMAC_HASHLEN, - AH_HMAC_HASHLEN, ipseczeroes); + m_copyback(m, m->m_pkthdr.len - esph->authlen, + esph->authlen, ipseczeroes); } } #endif Index: src/sys/opencrypto/cryptodev.h diff -u src/sys/opencrypto/cryptodev.h:1.18 src/sys/opencrypto/cryptodev.h:1.19 --- src/sys/opencrypto/cryptodev.h:1.18 Thu Feb 24 20:03:41 2011 +++ src/sys/opencrypto/cryptodev.h Fri Feb 25 20:13:10 2011 @@ -1,4 +1,4 @@ -/* $NetBSD: cryptodev.h,v 1.18 2011/02/24 20:03:41 drochner Exp $ */ +/* $NetBSD: cryptodev.h,v 1.19 2011/02/25 20:13:10 drochner Exp $ */ /* $FreeBSD: src/sys/opencrypto/cryptodev.h,v 1.2.2.6 2003/07/02 17:04:50 sam Exp $ */ /* $OpenBSD: cryptodev.h,v 1.33 2002/07/17 23:52:39 art Exp $ */ @@ -93,7 +93,7 @@ #define CRYPTO_SW_SESSIONS 32 /* HMAC values */ -#define HMAC_BLOCK_LEN 64 +#define HMAC_BLOCK_LEN 64 /* for compatibility */ #define HMAC_IPAD_VAL 0x36 #define HMAC_OPAD_VAL 0x5C @@ -125,7 +125,8 @@ #define CRYPTO_ARC4 12 #define CRYPTO_MD5 13 #define CRYPTO_SHA1 14 -#define CRYPTO_SHA2_HMAC 15 +#define CRYPTO_SHA2_256_HMAC 15 +#define CRYPTO_SHA2_HMAC CRYPTO_SHA2_256_HMAC /* for compatibility */ #define CRYPTO_NULL_HMAC 16 #define CRYPTO_NULL_CBC 17 #define CRYPTO_DEFLATE_COMP 18 /* Deflate compression algorithm */ @@ -134,7 +135,9 @@ #define CRYPTO_RIPEMD160_HMAC_96 21 #define CRYPTO_GZIP_COMP 22 /* gzip compression algorithm */ #define CRYPTO_DEFLATE_COMP_NOGROW 23 /* Deflate, fail if not compressible */ -#define CRYPTO_ALGORITHM_MAX 24 /* Keep updated - see below */ +#define CRYPTO_SHA2_384_HMAC 24 +#define CRYPTO_SHA2_512_HMAC 25 +#define CRYPTO_ALGORITHM_MAX 26 /* Keep updated - see below */ /* Algorithm flags */ #define CRYPTO_ALG_FLAG_SUPPORTED 0x01 /* Algorithm is supported */ Index: src/sys/opencrypto/cryptosoft.c diff -u src/sys/opencrypto/cryptosoft.c:1.28 src/sys/opencrypto/cryptosoft.c:1.29 --- src/sys/opencrypto/cryptosoft.c:1.28 Thu Feb 24 20:03:41 2011 +++ src/sys/opencrypto/cryptosoft.c Fri Feb 25 20:13:10 2011 @@ -1,4 +1,4 @@ -/* $NetBSD: cryptosoft.c,v 1.28 2011/02/24 20:03:41 drochner Exp $ */ +/* $NetBSD: cryptosoft.c,v 1.29 2011/02/25 20:13:10 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.28 2011/02/24 20:03:41 drochner Exp $"); +__KERNEL_RCSID(0, "$NetBSD: cryptosoft.c,v 1.29 2011/02/25 20:13:10 drochner Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -461,7 +461,9 @@ case CRYPTO_MD5_HMAC_96: case CRYPTO_SHA1_HMAC: case CRYPTO_SHA1_HMAC_96: - case CRYPTO_SHA2_HMAC: + case CRYPTO_SHA2_256_HMAC: + case CRYPTO_SHA2_384_HMAC: + case CRYPTO_SHA2_512_HMAC: case CRYPTO_RIPEMD160_HMAC: case CRYPTO_RIPEMD160_HMAC_96: if (sw->sw_octx == NULL) @@ -676,17 +678,14 @@ case CRYPTO_SHA1_HMAC_96: axf = &swcr_auth_hash_hmac_sha1_96; goto authcommon; - case CRYPTO_SHA2_HMAC: - if (cri->cri_klen == 256) - axf = &swcr_auth_hash_hmac_sha2_256; - else if (cri->cri_klen == 384) - axf = &swcr_auth_hash_hmac_sha2_384; - else if (cri->cri_klen == 512) - axf = &swcr_auth_hash_hmac_sha2_512; - else { - swcr_freesession(NULL, i); - return EINVAL; - } + case CRYPTO_SHA2_256_HMAC: + axf = &swcr_auth_hash_hmac_sha2_256; + goto authcommon; + case CRYPTO_SHA2_384_HMAC: + axf = &swcr_auth_hash_hmac_sha2_384; + goto authcommon; + case CRYPTO_SHA2_512_HMAC: + axf = &swcr_auth_hash_hmac_sha2_512; goto authcommon; case CRYPTO_NULL_HMAC: axf = &swcr_auth_hash_null; @@ -719,7 +718,7 @@ axf->Update((*swd)->sw_ictx, cri->cri_key, cri->cri_klen / 8); axf->Update((*swd)->sw_ictx, hmac_ipad_buffer, - HMAC_BLOCK_LEN - (cri->cri_klen / 8)); + axf->auth_hash->blocksize - (cri->cri_klen / 8)); for (k = 0; k < cri->cri_klen / 8; k++) cri->cri_key[k] ^= (HMAC_IPAD_VAL ^ HMAC_OPAD_VAL); @@ -728,7 +727,7 @@ axf->Update((*swd)->sw_octx, cri->cri_key, cri->cri_klen / 8); axf->Update((*swd)->sw_octx, hmac_opad_buffer, - HMAC_BLOCK_LEN - (cri->cri_klen / 8)); + axf->auth_hash->blocksize - (cri->cri_klen / 8)); for (k = 0; k < cri->cri_klen / 8; k++) cri->cri_key[k] ^= HMAC_OPAD_VAL; @@ -851,7 +850,9 @@ case CRYPTO_MD5_HMAC_96: case CRYPTO_SHA1_HMAC: case CRYPTO_SHA1_HMAC_96: - case CRYPTO_SHA2_HMAC: + case CRYPTO_SHA2_256_HMAC: + case CRYPTO_SHA2_384_HMAC: + case CRYPTO_SHA2_512_HMAC: case CRYPTO_RIPEMD160_HMAC: case CRYPTO_RIPEMD160_HMAC_96: case CRYPTO_NULL_HMAC: @@ -976,7 +977,9 @@ case CRYPTO_MD5_HMAC_96: case CRYPTO_SHA1_HMAC: case CRYPTO_SHA1_HMAC_96: - case CRYPTO_SHA2_HMAC: + case CRYPTO_SHA2_256_HMAC: + case CRYPTO_SHA2_384_HMAC: + case CRYPTO_SHA2_512_HMAC: case CRYPTO_RIPEMD160_HMAC: case CRYPTO_RIPEMD160_HMAC_96: case CRYPTO_NULL_HMAC: @@ -1034,7 +1037,9 @@ REGISTER(CRYPTO_MD5_HMAC_96); REGISTER(CRYPTO_SHA1_HMAC); REGISTER(CRYPTO_SHA1_HMAC_96); - REGISTER(CRYPTO_SHA2_HMAC); + REGISTER(CRYPTO_SHA2_256_HMAC); + REGISTER(CRYPTO_SHA2_384_HMAC); + REGISTER(CRYPTO_SHA2_512_HMAC); REGISTER(CRYPTO_RIPEMD160_HMAC); REGISTER(CRYPTO_RIPEMD160_HMAC_96); REGISTER(CRYPTO_NULL_HMAC); Index: src/sys/opencrypto/xform.c diff -u src/sys/opencrypto/xform.c:1.19 src/sys/opencrypto/xform.c:1.20 --- src/sys/opencrypto/xform.c:1.19 Thu Feb 24 20:03:41 2011 +++ src/sys/opencrypto/xform.c Fri Feb 25 20:13:10 2011 @@ -1,4 +1,4 @@ -/* $NetBSD: xform.c,v 1.19 2011/02/24 20:03:41 drochner Exp $ */ +/* $NetBSD: xform.c,v 1.20 2011/02/25 20:13:10 drochner Exp $ */ /* $FreeBSD: src/sys/opencrypto/xform.c,v 1.1.2.1 2002/11/21 23:34:23 sam Exp $ */ /* $OpenBSD: xform.c,v 1.19 2002/08/16 22:47:25 dhartmei Exp $ */ @@ -40,7 +40,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: xform.c,v 1.19 2011/02/24 20:03:41 drochner Exp $"); +__KERNEL_RCSID(0, "$NetBSD: xform.c,v 1.20 2011/02/25 20:13:10 drochner Exp $"); #include <sys/param.h> #include <sys/malloc.h> @@ -50,7 +50,15 @@ MALLOC_DEFINE(M_XDATA, "xform", "xform data buffers"); -const u_int8_t hmac_ipad_buffer[64] = { +const u_int8_t hmac_ipad_buffer[128] = { + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, @@ -61,7 +69,15 @@ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36 }; -const u_int8_t hmac_opad_buffer[64] = { +const u_int8_t hmac_opad_buffer[128] = { + 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, + 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, + 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, + 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, + 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, + 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, + 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, + 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, @@ -117,72 +133,72 @@ /* Authentication instances */ struct auth_hash auth_hash_null = { CRYPTO_NULL_HMAC, "NULL-HMAC", - 0, 0, 12, sizeof(int) /* NB: context isn't used */ + 0, 0, 12, 64, sizeof(int) /* NB: context isn't used */ }; struct auth_hash auth_hash_hmac_md5 = { CRYPTO_MD5_HMAC, "HMAC-MD5", - 16, 16, 16, sizeof(MD5_CTX) + 16, 16, 16, 64, sizeof(MD5_CTX) }; struct auth_hash auth_hash_hmac_sha1 = { CRYPTO_SHA1_HMAC, "HMAC-SHA1", - 20, 20, 20, sizeof(SHA1_CTX) + 20, 20, 20, 64, sizeof(SHA1_CTX) }; struct auth_hash auth_hash_hmac_ripemd_160 = { CRYPTO_RIPEMD160_HMAC, "HMAC-RIPEMD-160", - 20, 20, 20, sizeof(RMD160_CTX) + 20, 20, 20, 64, sizeof(RMD160_CTX) }; struct auth_hash auth_hash_hmac_md5_96 = { CRYPTO_MD5_HMAC_96, "HMAC-MD5-96", - 16, 16, 12, sizeof(MD5_CTX) + 16, 16, 12, 64, sizeof(MD5_CTX) }; struct auth_hash auth_hash_hmac_sha1_96 = { CRYPTO_SHA1_HMAC_96, "HMAC-SHA1-96", - 20, 20, 12, sizeof(SHA1_CTX) + 20, 20, 12, 64, sizeof(SHA1_CTX) }; struct auth_hash auth_hash_hmac_ripemd_160_96 = { CRYPTO_RIPEMD160_HMAC_96, "HMAC-RIPEMD-160", - 20, 20, 12, sizeof(RMD160_CTX) + 20, 20, 12, 64, sizeof(RMD160_CTX) }; struct auth_hash auth_hash_key_md5 = { CRYPTO_MD5_KPDK, "Keyed MD5", - 0, 16, 16, sizeof(MD5_CTX) + 0, 16, 16, 0, sizeof(MD5_CTX) }; struct auth_hash auth_hash_key_sha1 = { CRYPTO_SHA1_KPDK, "Keyed SHA1", - 0, 20, 20, sizeof(SHA1_CTX) + 0, 20, 20, 0, sizeof(SHA1_CTX) }; struct auth_hash auth_hash_md5 = { CRYPTO_MD5, "MD5", - 0, 16, 16, sizeof(MD5_CTX) + 0, 16, 16, 0, sizeof(MD5_CTX) }; struct auth_hash auth_hash_sha1 = { CRYPTO_SHA1, "SHA1", - 0, 20, 20, sizeof(SHA1_CTX) + 0, 20, 20, 0, sizeof(SHA1_CTX) }; struct auth_hash auth_hash_hmac_sha2_256 = { - CRYPTO_SHA2_HMAC, "HMAC-SHA2", - 32, 32, 12, sizeof(SHA256_CTX) + CRYPTO_SHA2_256_HMAC, "HMAC-SHA2", + 32, 32, 16, 64, sizeof(SHA256_CTX) }; struct auth_hash auth_hash_hmac_sha2_384 = { - CRYPTO_SHA2_HMAC, "HMAC-SHA2-384", - 48, 48, 12, sizeof(SHA384_CTX) + CRYPTO_SHA2_384_HMAC, "HMAC-SHA2-384", + 48, 48, 24, 128, sizeof(SHA384_CTX) }; struct auth_hash auth_hash_hmac_sha2_512 = { - CRYPTO_SHA2_HMAC, "HMAC-SHA2-512", - 64, 64, 12, sizeof(SHA512_CTX) + CRYPTO_SHA2_512_HMAC, "HMAC-SHA2-512", + 64, 64, 32, 128, sizeof(SHA512_CTX) }; /* Compression instance */ Index: src/sys/opencrypto/xform.h diff -u src/sys/opencrypto/xform.h:1.11 src/sys/opencrypto/xform.h:1.12 --- src/sys/opencrypto/xform.h:1.11 Thu Feb 24 20:03:41 2011 +++ src/sys/opencrypto/xform.h Fri Feb 25 20:13:10 2011 @@ -1,4 +1,4 @@ -/* $NetBSD: xform.h,v 1.11 2011/02/24 20:03:41 drochner Exp $ */ +/* $NetBSD: xform.h,v 1.12 2011/02/25 20:13:10 drochner Exp $ */ /* $FreeBSD: src/sys/opencrypto/xform.h,v 1.1.2.1 2002/11/21 23:34:23 sam Exp $ */ /* $OpenBSD: xform.h,v 1.10 2002/04/22 23:10:09 deraadt Exp $ */ @@ -38,11 +38,12 @@ u_int16_t keysize; u_int16_t hashsize; u_int16_t authsize; + u_int16_t blocksize; u_int16_t ctxsize; }; /* Provide array-limit for clients (e.g., netipsec) */ -#define AH_ALEN_MAX 20 /* max authenticator hash length */ +#define AH_ALEN_MAX 32 /* max authenticator hash length */ struct enc_xform { int type; @@ -57,8 +58,8 @@ size_t minlen; }; -extern const u_int8_t hmac_ipad_buffer[64]; -extern const u_int8_t hmac_opad_buffer[64]; +extern const u_int8_t hmac_ipad_buffer[128]; +extern const u_int8_t hmac_opad_buffer[128]; extern struct enc_xform enc_xform_null; extern struct enc_xform enc_xform_des;