diff options
author | vanhu <vanhu@FreeBSD.org> | 2011-02-18 09:40:13 +0000 |
---|---|---|
committer | vanhu <vanhu@FreeBSD.org> | 2011-02-18 09:40:13 +0000 |
commit | b5386e15c14dd35dcd82a748b00a7a741b1238f9 (patch) | |
tree | 7caf902dec994fcea8dd9be967378950d398ba35 /sys/netipsec/xform_esp.c | |
parent | f9ba5edcb6ab519d38ac8a40899df85ba5713843 (diff) | |
download | FreeBSD-src-b5386e15c14dd35dcd82a748b00a7a741b1238f9.zip FreeBSD-src-b5386e15c14dd35dcd82a748b00a7a741b1238f9.tar.gz |
Fixed IPsec's HMAC_SHA256-512 support to be RFC4868 compliant.
This will break interoperability with all older versions of
FreeBSD for those algorithms.
Reviewed by: bz, gnn
Obtained from: NETASQ
MFC after: 1w
Diffstat (limited to 'sys/netipsec/xform_esp.c')
-rw-r--r-- | sys/netipsec/xform_esp.c | 63 |
1 files changed, 53 insertions, 10 deletions
diff --git a/sys/netipsec/xform_esp.c b/sys/netipsec/xform_esp.c index 6186b59..ddfdbcc 100644 --- a/sys/netipsec/xform_esp.c +++ b/sys/netipsec/xform_esp.c @@ -303,7 +303,19 @@ esp_input(struct mbuf *m, struct secasvar *sav, int skip, int protoff) else hlen = sizeof (struct newesp) + sav->ivlen; /* Authenticator hash size */ - alen = esph ? AH_HMAC_HASHLEN : 0; + 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; /* * Verify payload length is multiple of encryption algorithm @@ -456,8 +468,8 @@ esp_input(struct mbuf *m, struct secasvar *sav, int skip, int protoff) static int esp_input_cb(struct cryptop *crp) { - u_int8_t lastthree[3], aalg[AH_HMAC_HASHLEN]; - int hlen, skip, protoff, error; + u_int8_t lastthree[3], aalg[AH_HMAC_MAXHASHLEN]; + int hlen, skip, protoff, error, alen; struct mbuf *m; struct cryptodesc *crd; struct auth_hash *esph; @@ -525,6 +537,16 @@ 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; + } /* * If we have a tag, it means an IPsec-aware NIC did * the verification for us. Otherwise we need to @@ -533,13 +555,13 @@ esp_input_cb(struct cryptop *crp) V_ahstat.ahs_hist[sav->alg_auth]++; if (mtag == NULL) { /* Copy the authenticator from the packet */ - m_copydata(m, m->m_pkthdr.len - AH_HMAC_HASHLEN, - AH_HMAC_HASHLEN, aalg); + m_copydata(m, m->m_pkthdr.len - alen, + alen, aalg); ptr = (caddr_t) (tc + 1); /* Verify authenticator */ - if (bcmp(ptr, aalg, AH_HMAC_HASHLEN) != 0) { + if (bcmp(ptr, aalg, alen) != 0) { DPRINTF(("%s: " "authentication hash mismatch for packet in SA %s/%08lx\n", __func__, @@ -552,7 +574,7 @@ esp_input_cb(struct cryptop *crp) } /* Remove trailing authenticator */ - m_adj(m, -AH_HMAC_HASHLEN); + m_adj(m, -alen); } /* Release the crypto descriptors */ @@ -696,7 +718,16 @@ esp_output( plen = rlen + padding; /* Padded payload length. */ 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; + } else alen = 0; @@ -950,7 +981,7 @@ esp_output_cb(struct cryptop *crp) #ifdef REGRESSION /* Emulate man-in-the-middle attack when ipsec_integrity is TRUE. */ if (V_ipsec_integrity) { - static unsigned char ipseczeroes[AH_HMAC_HASHLEN]; + static unsigned char ipseczeroes[AH_HMAC_MAXHASHLEN]; struct auth_hash *esph; /* @@ -959,8 +990,20 @@ 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); + int alen; + + 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; + } + m_copyback(m, m->m_pkthdr.len - alen, + alen, ipseczeroes); } } #endif |