summaryrefslogtreecommitdiffstats
path: root/sys/opencrypto
diff options
context:
space:
mode:
authorjmg <jmg@FreeBSD.org>2015-08-04 17:47:11 +0000
committerjmg <jmg@FreeBSD.org>2015-08-04 17:47:11 +0000
commit20a77876c747677e14860ccb77e37ba572e7b1f2 (patch)
tree90da08143badbf5312e624a76e8aa042d2715ade /sys/opencrypto
parent97d3fe874dc469ad842c648127f280946d3c08ed (diff)
downloadFreeBSD-src-20a77876c747677e14860ccb77e37ba572e7b1f2.zip
FreeBSD-src-20a77876c747677e14860ccb77e37ba572e7b1f2.tar.gz
Make IPsec work with AES-GCM and AES-ICM (aka CTR) in OCF... IPsec
defines the keys differently than NIST does, so we have to muck with key lengths and nonce/IVs to be standard compliant... Remove the iv from secasvar as it was unused... Add a counter protected by a mutex to ensure that the counter for GCM and ICM will never be repeated.. This is a requirement for security.. I would use atomics, but we don't have a 64bit one on all platforms.. Fix a bug where IPsec was depending upon the OCF to ensure that the blocksize was always at least 4 bytes to maintain alignment... Move this logic into IPsec so changes to OCF won't break IPsec... In one place, espx was always non-NULL, so don't test that it's non-NULL before doing work.. minor style cleanups... drop setting key and klen as they were not used... Enforce that OCF won't pass invalid key lengths to AES that would panic the machine... This was has been tested by others too... I tested this against NetBSD 6.1.5 using mini-test suite in https://github.com/jmgurney/ipseccfgs and the only things that don't pass are keyed md5 and sha1, and 3des-deriv (setkey syntax error), all other modes listed in setkey's man page... The nice thing is that NetBSD uses setkey, so same config files were used on both... Reviewed by: gnn
Diffstat (limited to 'sys/opencrypto')
-rw-r--r--sys/opencrypto/cryptodev.h10
-rw-r--r--sys/opencrypto/cryptosoft.c8
-rw-r--r--sys/opencrypto/xform.c13
3 files changed, 18 insertions, 13 deletions
diff --git a/sys/opencrypto/cryptodev.h b/sys/opencrypto/cryptodev.h
index 5aa450f..d14fb3a 100644
--- a/sys/opencrypto/cryptodev.h
+++ b/sys/opencrypto/cryptodev.h
@@ -78,7 +78,7 @@
#define SHA2_512_HASH_LEN 64
#define MD5_KPDK_HASH_LEN 16
#define SHA1_KPDK_HASH_LEN 20
-#define AES_HASH_LEN 16
+#define AES_GMAC_HASH_LEN 16
/* Maximum hash algorithm result length */
#define HASH_MAX_LEN SHA2_512_HASH_LEN /* Keep this updated */
@@ -102,12 +102,12 @@
#define SHA2_256_HMAC_KEY_LEN 32
#define SHA2_384_HMAC_KEY_LEN 48
#define SHA2_512_HMAC_KEY_LEN 64
-#define AES_128_HMAC_KEY_LEN 16
-#define AES_192_HMAC_KEY_LEN 24
-#define AES_256_HMAC_KEY_LEN 32
+#define AES_128_GMAC_KEY_LEN 16
+#define AES_192_GMAC_KEY_LEN 24
+#define AES_256_GMAC_KEY_LEN 32
/* Encryption algorithm block sizes */
-#define NULL_BLOCK_LEN 4
+#define NULL_BLOCK_LEN 4 /* IPsec to maintain alignment */
#define DES_BLOCK_LEN 8
#define DES3_BLOCK_LEN 8
#define BLOWFISH_BLOCK_LEN 8
diff --git a/sys/opencrypto/cryptosoft.c b/sys/opencrypto/cryptosoft.c
index 77ab507..052916b 100644
--- a/sys/opencrypto/cryptosoft.c
+++ b/sys/opencrypto/cryptosoft.c
@@ -711,6 +711,7 @@ swcr_newsession(device_t dev, u_int32_t *sid, struct cryptoini *cri)
struct enc_xform *txf;
struct comp_algo *cxf;
u_int32_t i;
+ int len;
int error;
if (sid == NULL || cri == NULL)
@@ -928,6 +929,10 @@ swcr_newsession(device_t dev, u_int32_t *sid, struct cryptoini *cri)
case CRYPTO_AES_256_NIST_GMAC:
axf = &auth_hash_nist_gmac_aes_256;
auth4common:
+ len = cri->cri_klen / 8;
+ if (len != 16 && len != 24 && len != 32)
+ return EINVAL;
+
(*swd)->sw_ictx = malloc(axf->ctxsize, M_CRYPTO_DATA,
M_NOWAIT);
if ((*swd)->sw_ictx == NULL) {
@@ -936,8 +941,7 @@ swcr_newsession(device_t dev, u_int32_t *sid, struct cryptoini *cri)
return ENOBUFS;
}
axf->Init((*swd)->sw_ictx);
- axf->Setkey((*swd)->sw_ictx, cri->cri_key,
- cri->cri_klen / 8);
+ axf->Setkey((*swd)->sw_ictx, cri->cri_key, len);
(*swd)->sw_axf = axf;
break;
diff --git a/sys/opencrypto/xform.c b/sys/opencrypto/xform.c
index 9e8a1c1..cb44bfa 100644
--- a/sys/opencrypto/xform.c
+++ b/sys/opencrypto/xform.c
@@ -139,7 +139,7 @@ static int SHA512Update_int(void *, const u_int8_t *, u_int16_t);
static u_int32_t deflate_compress(u_int8_t *, u_int32_t, u_int8_t **);
static u_int32_t deflate_decompress(u_int8_t *, u_int32_t, u_int8_t **);
-#define AESICM_BLOCKSIZE 16
+#define AESICM_BLOCKSIZE AES_BLOCK_LEN
struct aes_icm_ctx {
u_int32_t ac_ek[4*(RIJNDAEL_MAXNR + 1)];
@@ -353,7 +353,7 @@ struct auth_hash auth_hash_hmac_sha2_512 = {
struct auth_hash auth_hash_nist_gmac_aes_128 = {
CRYPTO_AES_128_NIST_GMAC, "GMAC-AES-128",
- AES_128_HMAC_KEY_LEN, AES_HASH_LEN, sizeof(struct aes_gmac_ctx),
+ AES_128_GMAC_KEY_LEN, AES_GMAC_HASH_LEN, sizeof(struct aes_gmac_ctx),
GMAC_BLOCK_LEN,
(void (*)(void *)) AES_GMAC_Init,
(void (*)(void *, const u_int8_t *, u_int16_t)) AES_GMAC_Setkey,
@@ -364,7 +364,7 @@ struct auth_hash auth_hash_nist_gmac_aes_128 = {
struct auth_hash auth_hash_nist_gmac_aes_192 = {
CRYPTO_AES_192_NIST_GMAC, "GMAC-AES-192",
- AES_192_HMAC_KEY_LEN, AES_HASH_LEN, sizeof(struct aes_gmac_ctx),
+ AES_192_GMAC_KEY_LEN, AES_GMAC_HASH_LEN, sizeof(struct aes_gmac_ctx),
GMAC_BLOCK_LEN,
(void (*)(void *)) AES_GMAC_Init,
(void (*)(void *, const u_int8_t *, u_int16_t)) AES_GMAC_Setkey,
@@ -375,7 +375,7 @@ struct auth_hash auth_hash_nist_gmac_aes_192 = {
struct auth_hash auth_hash_nist_gmac_aes_256 = {
CRYPTO_AES_256_NIST_GMAC, "GMAC-AES-256",
- AES_256_HMAC_KEY_LEN, AES_HASH_LEN, sizeof(struct aes_gmac_ctx),
+ AES_256_GMAC_KEY_LEN, AES_GMAC_HASH_LEN, sizeof(struct aes_gmac_ctx),
GMAC_BLOCK_LEN,
(void (*)(void *)) AES_GMAC_Init,
(void (*)(void *, const u_int8_t *, u_int16_t)) AES_GMAC_Setkey,
@@ -719,6 +719,9 @@ aes_icm_setkey(u_int8_t **sched, u_int8_t *key, int len)
{
struct aes_icm_ctx *ctx;
+ if (len != 16 && len != 24 && len != 32)
+ return EINVAL;
+
*sched = malloc(sizeof(struct aes_icm_ctx), M_CRYPTO_DATA,
M_NOWAIT | M_ZERO);
if (*sched == NULL)
@@ -726,8 +729,6 @@ aes_icm_setkey(u_int8_t **sched, u_int8_t *key, int len)
ctx = (struct aes_icm_ctx *)*sched;
ctx->ac_nr = rijndaelKeySetupEnc(ctx->ac_ek, (u_char *)key, len * 8);
- if (ctx->ac_nr == 0)
- return EINVAL;
return 0;
}
OpenPOWER on IntegriCloud