diff options
author | Renato Botelho <renato@netgate.com> | 2015-08-17 13:53:21 -0300 |
---|---|---|
committer | Renato Botelho <renato@netgate.com> | 2015-08-17 13:53:21 -0300 |
commit | 46e99a8858f1c843c1774e472c11d422ca2163ae (patch) | |
tree | 485743dc4862158e7bb3b19eccf8f9b54fb8927b /sys/netipsec | |
parent | fb8160d0fb248c35e8bc74d67dcca6c22e974db3 (diff) | |
download | FreeBSD-src-46e99a8858f1c843c1774e472c11d422ca2163ae.zip FreeBSD-src-46e99a8858f1c843c1774e472c11d422ca2163ae.tar.gz |
Importing pfSense patch aesgcm.soft.1.patch
Diffstat (limited to 'sys/netipsec')
-rw-r--r-- | sys/netipsec/xform_ah.c | 24 | ||||
-rw-r--r-- | sys/netipsec/xform_esp.c | 148 |
2 files changed, 102 insertions, 70 deletions
diff --git a/sys/netipsec/xform_ah.c b/sys/netipsec/xform_ah.c index afa452c..86b4fa2 100644 --- a/sys/netipsec/xform_ah.c +++ b/sys/netipsec/xform_ah.c @@ -84,7 +84,8 @@ * to use a fixed 16-byte authenticator. The new algorithm use 12-byte * authenticator. */ -#define AUTHSIZE(sav) ah_authsize(sav) +#define AUTHSIZE(sav) \ + ((sav->flags & SADB_X_EXT_OLD) ? 16 : (sav)->tdb_authalgxform->authsize) VNET_DEFINE(int, ah_enable) = 1; /* control flow of packets with AH */ VNET_DEFINE(int, ah_cleartos) = 1; /* clear ip_tos when doing AH calc */ @@ -110,27 +111,6 @@ static unsigned char ipseczeroes[256]; /* larger than an ip6 extension hdr */ static int ah_input_cb(struct cryptop*); static int ah_output_cb(struct cryptop*); -static int -ah_authsize(struct secasvar *sav) -{ - - IPSEC_ASSERT(sav != NULL, ("%s: sav == NULL", __func__)); - - if (sav->flags & SADB_X_EXT_OLD) - return 16; - - switch (sav->alg_auth) { - case SADB_X_AALG_SHA2_256: - return 16; - case SADB_X_AALG_SHA2_384: - return 24; - case SADB_X_AALG_SHA2_512: - return 32; - default: - return AH_HMAC_HASHLEN; - } - /* NOTREACHED */ -} /* * NB: this is public for use by the PF_KEY support. */ diff --git a/sys/netipsec/xform_esp.c b/sys/netipsec/xform_esp.c index 90f6d56..3870c5b 100644 --- a/sys/netipsec/xform_esp.c +++ b/sys/netipsec/xform_esp.c @@ -119,6 +119,14 @@ esp_algorithm_lookup(int alg) return &enc_xform_null; case SADB_X_EALG_CAMELLIACBC: return &enc_xform_camellia; + case SADB_X_EALG_AESCTR: + return &enc_xform_aes_ctr; + case SADB_X_EALG_AESGCM8: + case SADB_X_EALG_AESGCM12: + case SADB_X_EALG_AESGCM16: + return &enc_xform_aes_gcm; + case SADB_X_EALG_AESGMAC: + return &enc_xform_aes_gmac; } return NULL; } @@ -196,7 +204,7 @@ esp_init(struct secasvar *sav, struct xformsw *xsp) * the ESP header will be processed incorrectly. The * compromise is to force it to zero here. */ - sav->ivlen = (txform == &enc_xform_null ? 0 : txform->blocksize); + sav->ivlen = (txform == &enc_xform_null ? 0 : txform->ivsize); sav->iv = (caddr_t) malloc(sav->ivlen, M_XDATA, M_WAITOK); key_randomfill(sav->iv, sav->ivlen); /*XXX*/ @@ -213,6 +221,31 @@ esp_init(struct secasvar *sav, struct xformsw *xsp) sav->tdb_xform = xsp; sav->tdb_encalgxform = txform; + switch (sav->alg_enc) { + case SADB_X_EALG_AESGCM8: + case SADB_X_EALG_AESGCM12: + case SADB_X_EALG_AESGCM16: + switch (keylen) { + case 20: + sav->alg_auth = SADB_X_AALG_AES128GMAC; + sav->tdb_authalgxform = &auth_hash_gmac_aes_128; + break; + case 28: + sav->alg_auth = SADB_X_AALG_AES192GMAC; + sav->tdb_authalgxform = &auth_hash_gmac_aes_192; + break; + case 36: + sav->alg_auth = SADB_X_AALG_AES256GMAC; + sav->tdb_authalgxform = &auth_hash_gmac_aes_256; + break; + } + bzero(&cria, sizeof(cria)); + cria.cri_alg = sav->tdb_authalgxform->type; + cria.cri_klen = _KEYBITS(sav->key_enc); + cria.cri_key = sav->key_enc->key_data; + break; + } + /* Initialize crypto session. */ bzero(&crie, sizeof (crie)); crie.cri_alg = sav->tdb_encalgxform->type; @@ -260,6 +293,22 @@ esp_zeroize(struct secasvar *sav) return error; } +static void +esp_authenticator_size(struct enc_xform *espx, int alg, int *alen) +{ + switch (alg) { + case SADB_X_EALG_AESGCM8: + *alen = 8; + break; + case SADB_X_EALG_AESGCM12: + *alen = 12; + break; + case SADB_X_EALG_AESGCM16: + *alen = 16; + break; + } +} + /* * ESP input processing, called (eventually) through the protocol switch. */ @@ -301,19 +350,9 @@ esp_input(struct mbuf *m, struct secasvar *sav, int skip, int protoff) else hlen = sizeof (struct newesp) + sav->ivlen; /* Authenticator hash size */ - if (esph != NULL) { - switch (esph->type) { - case CRYPTO_SHA2_256_HMAC: - case CRYPTO_SHA2_384_HMAC: - case CRYPTO_SHA2_512_HMAC: - alen = esph->hashsize/2; - break; - default: - alen = AH_HMAC_HASHLEN; - break; - } - }else - alen = 0; + alen = esph ? esph->authsize : 0; + if (espx != NULL) + esp_authenticator_size(espx, sav->alg_enc, &alen); /* * Verify payload length is multiple of encryption algorithm @@ -325,14 +364,16 @@ esp_input(struct mbuf *m, struct secasvar *sav, int skip, int protoff) */ plen = m->m_pkthdr.len - (skip + hlen + alen); if ((plen & (espx->blocksize - 1)) || (plen <= 0)) { - DPRINTF(("%s: payload of %d octets not a multiple of %d octets," - " SA %s/%08lx\n", __func__, - plen, espx->blocksize, - ipsec_address(&sav->sah->saidx.dst), - (u_long) ntohl(sav->spi))); - ESPSTAT_INC(esps_badilen); - m_freem(m); - return EINVAL; + if (!espx || espx->type != CRYPTO_AES_RFC4106_GCM_16) { + DPRINTF(("%s: payload of %d octets not a multiple of %d octets," + " SA %s/%08lx\n", __func__, + plen, espx->blocksize, + ipsec_address(&sav->sah->saidx.dst), + (u_long) ntohl(sav->spi))); + ESPSTAT_INC(esps_badilen); + m_freem(m); + return EINVAL; + } } /* @@ -395,12 +436,20 @@ esp_input(struct mbuf *m, struct secasvar *sav, int skip, int protoff) /* Authentication descriptor */ crda->crd_skip = skip; - crda->crd_len = m->m_pkthdr.len - (skip + alen); + if (espx && espx->type == CRYPTO_AES_RFC4106_GCM_16) + crda->crd_len = hlen - sav->ivlen; + else + crda->crd_len = m->m_pkthdr.len - (skip + alen); crda->crd_inject = m->m_pkthdr.len - alen; crda->crd_alg = esph->type; - crda->crd_key = sav->key_auth->key_data; - crda->crd_klen = _KEYBITS(sav->key_auth); + if (espx && (espx->type == CRYPTO_AES_RFC4106_GCM_16)) { + crda->crd_key = sav->key_enc->key_data; + crda->crd_klen = _KEYBITS(sav->key_enc); + } else { + crda->crd_key = sav->key_auth->key_data; + crda->crd_klen = _KEYBITS(sav->key_auth); + } /* Copy the authenticator */ if (mtag == NULL) @@ -514,16 +563,10 @@ esp_input_cb(struct cryptop *crp) /* If authentication was performed, check now. */ if (esph != NULL) { - switch (esph->type) { - case CRYPTO_SHA2_256_HMAC: - case CRYPTO_SHA2_384_HMAC: - case CRYPTO_SHA2_512_HMAC: - alen = esph->hashsize/2; - break; - default: - alen = AH_HMAC_HASHLEN; - break; - } + alen = esph->authsize; + if (espx != NULL) + esp_authenticator_size(espx, sav->alg_enc, &alen); + /* * If we have a tag, it means an IPsec-aware NIC did * the verification for us. Otherwise we need to @@ -708,18 +751,11 @@ esp_output( padding = ((blks - ((rlen + 2) % blks)) % blks) + 2; if (esph) - switch (esph->type) { - case CRYPTO_SHA2_256_HMAC: - case CRYPTO_SHA2_384_HMAC: - case CRYPTO_SHA2_512_HMAC: - alen = esph->hashsize/2; - break; - default: - alen = AH_HMAC_HASHLEN; - break; - } + alen = esph->authsize; else alen = 0; + if (espx != NULL) + esp_authenticator_size(espx, sav->alg_enc, &alen); ESPSTAT_INC(esps_output); @@ -890,13 +926,21 @@ esp_output( if (esph) { /* Authentication descriptor. */ crda->crd_skip = skip; - crda->crd_len = m->m_pkthdr.len - (skip + alen); + if (espx && espx->type == CRYPTO_AES_RFC4106_GCM_16) + crda->crd_len = hlen - sav->ivlen; + else + crda->crd_len = m->m_pkthdr.len - (skip + alen); crda->crd_inject = m->m_pkthdr.len - alen; /* Authentication operation. */ crda->crd_alg = esph->type; - crda->crd_key = sav->key_auth->key_data; - crda->crd_klen = _KEYBITS(sav->key_auth); + if (espx && espx->type == CRYPTO_AES_RFC4106_GCM_16) { + crda->crd_key = sav->key_enc->key_data; + crda->crd_klen = _KEYBITS(sav->key_enc); + } else { + crda->crd_key = sav->key_auth->key_data; + crda->crd_klen = _KEYBITS(sav->key_auth); + } } return crypto_dispatch(crp); @@ -987,10 +1031,18 @@ esp_output_cb(struct cryptop *crp) case CRYPTO_SHA2_512_HMAC: alen = esph->hashsize/2; break; + case CRYPTO_AES_128_GMAC: + case CRYPTO_AES_192_GMAC: + case CRYPTO_AES_256_GMAC: + alen = esph->hashsize; + break; default: alen = AH_HMAC_HASHLEN; break; } + if (espx != NULL) + esp_authenticator_size(espx, sav->alg_enc, &alen); + m_copyback(m, m->m_pkthdr.len - alen, alen, ipseczeroes); } |