summaryrefslogtreecommitdiffstats
path: root/sys/netipsec/xform_esp.c
diff options
context:
space:
mode:
authorvanhu <vanhu@FreeBSD.org>2011-02-18 09:40:13 +0000
committervanhu <vanhu@FreeBSD.org>2011-02-18 09:40:13 +0000
commitb5386e15c14dd35dcd82a748b00a7a741b1238f9 (patch)
tree7caf902dec994fcea8dd9be967378950d398ba35 /sys/netipsec/xform_esp.c
parentf9ba5edcb6ab519d38ac8a40899df85ba5713843 (diff)
downloadFreeBSD-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.c63
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
OpenPOWER on IntegriCloud