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.)
This commit is contained in:
drochner 2011-02-25 20:13:10 +00:00
parent a080ec141b
commit b4da53f1e6
7 changed files with 86 additions and 60 deletions

View File

@ -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 @@ keyed one-way hash algorithms may be available:
.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

View File

@ -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 */
/*

View File

@ -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 @@ esp_input(struct mbuf *m, const struct secasvar *sav, int skip, int protoff)
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 @@ esp_input(struct mbuf *m, const struct secasvar *sav, int skip, int protoff)
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 @@ esp_output(
plen = rlen + padding; /* Padded payload length. */
if (esph)
alen = AH_HMAC_HASHLEN;
alen = esph->authsize;
else
alen = 0;
@ -992,7 +992,7 @@ esp_output_cb(struct cryptop *crp)
#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 @@ esp_output_cb(struct cryptop *crp)
*/
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

View File

@ -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 */

View File

@ -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 @@ swcr_authcompute(struct cryptop *crp, struct cryptodesc *crd,
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 @@ swcr_newsession(void *arg, u_int32_t *sid, struct cryptoini *cri)
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 @@ swcr_newsession(void *arg, u_int32_t *sid, struct cryptoini *cri)
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 @@ swcr_newsession(void *arg, u_int32_t *sid, struct cryptoini *cri)
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 @@ swcr_freesession(void *arg, u_int64_t tid)
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 @@ swcr_process(void *arg, struct cryptop *crp, int hint)
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 @@ swcr_init(void)
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);

View File

@ -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 @@ __KERNEL_RCSID(0, "$NetBSD: xform.c,v 1.19 2011/02/24 20:03:41 drochner Exp $");
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 @@ const u_int8_t hmac_ipad_buffer[64] = {
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 @@ struct enc_xform enc_xform_arc4 = {
/* 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 */

View File

@ -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 @@ struct auth_hash {
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 @@ struct comp_algo {
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;