diff options
author | zbb <zbb@FreeBSD.org> | 2016-06-02 18:37:50 +0000 |
---|---|---|
committer | zbb <zbb@FreeBSD.org> | 2016-06-02 18:37:50 +0000 |
commit | 9682ecbee5ba7149a3b1de4ff2e5bf39c85d5ebc (patch) | |
tree | 297f0828d75b28b1d23c182ef6bad5e1f252bb8e | |
parent | f1fe5e60a7c3b37eccc78de804780b24fbc4eaf7 (diff) | |
download | FreeBSD-src-9682ecbee5ba7149a3b1de4ff2e5bf39c85d5ebc.zip FreeBSD-src-9682ecbee5ba7149a3b1de4ff2e5bf39c85d5ebc.tar.gz |
Truncate HMAC output only if requested by the client
The output of HMAC was previously truncated to 12 bytes. This was only
correct in case of one particular crypto client - the new version of IPSEC.
Fix by taking into account the cri_mlen field in cryptoini session request
filled in by the client.
Submitted by: Michal Stanek <mst@semihalf.com>
Obtained from: Semihalf
Sponsored by: Stormshield
Differential revision: https://reviews.freebsd.org/D6218
-rw-r--r-- | sys/dev/cesa/cesa.c | 24 | ||||
-rw-r--r-- | sys/dev/cesa/cesa.h | 8 |
2 files changed, 21 insertions, 11 deletions
diff --git a/sys/dev/cesa/cesa.c b/sys/dev/cesa/cesa.c index 97b9c4d..4f31668 100644 --- a/sys/dev/cesa/cesa.c +++ b/sys/dev/cesa/cesa.c @@ -1451,24 +1451,32 @@ cesa_newsession(device_t dev, uint32_t *sidp, struct cryptoini *cri) if (!error && mac) { switch (mac->cri_alg) { case CRYPTO_MD5: - cs->cs_config |= CESA_CSHD_MD5; cs->cs_mblen = 1; - cs->cs_hlen = MD5_HASH_LEN; + cs->cs_hlen = (mac->cri_mlen == 0) ? MD5_HASH_LEN : + mac->cri_mlen; + cs->cs_config |= CESA_CSHD_MD5; break; case CRYPTO_MD5_HMAC: - cs->cs_config |= CESA_CSHD_MD5_HMAC; cs->cs_mblen = MD5_HMAC_BLOCK_LEN; - cs->cs_hlen = CESA_HMAC_HASH_LENGTH; + cs->cs_hlen = (mac->cri_mlen == 0) ? MD5_HASH_LEN : + mac->cri_mlen; + cs->cs_config |= CESA_CSHD_MD5_HMAC; + if (cs->cs_hlen == CESA_HMAC_TRUNC_LEN) + cs->cs_config |= CESA_CSHD_96_BIT_HMAC; break; case CRYPTO_SHA1: - cs->cs_config |= CESA_CSHD_SHA1; cs->cs_mblen = 1; - cs->cs_hlen = SHA1_HASH_LEN; + cs->cs_hlen = (mac->cri_mlen == 0) ? SHA1_HASH_LEN : + mac->cri_mlen; + cs->cs_config |= CESA_CSHD_SHA1; break; case CRYPTO_SHA1_HMAC: - cs->cs_config |= CESA_CSHD_SHA1_HMAC; cs->cs_mblen = SHA1_HMAC_BLOCK_LEN; - cs->cs_hlen = CESA_HMAC_HASH_LENGTH; + cs->cs_hlen = (mac->cri_mlen == 0) ? SHA1_HASH_LEN : + mac->cri_mlen; + cs->cs_config |= CESA_CSHD_SHA1_HMAC; + if (cs->cs_hlen == CESA_HMAC_TRUNC_LEN) + cs->cs_config |= CESA_CSHD_96_BIT_HMAC; break; default: error = EINVAL; diff --git a/sys/dev/cesa/cesa.h b/sys/dev/cesa/cesa.h index 8fedb7e..a739835 100644 --- a/sys/dev/cesa/cesa.h +++ b/sys/dev/cesa/cesa.h @@ -68,7 +68,7 @@ #define CESA_TDMA_DESCRIPTORS (CESA_TDMA_DESC_PER_REQ * CESA_REQUESTS) /* Useful constants */ -#define CESA_HMAC_HASH_LENGTH 12 +#define CESA_HMAC_TRUNC_LEN 12 #define CESA_MAX_FRAGMENTS 64 #define CESA_SRAM_SIZE 2048 @@ -293,8 +293,10 @@ struct cesa_chain_info { #define CESA_CSHD_MD5 (4 << 4) #define CESA_CSHD_SHA1 (5 << 4) -#define CESA_CSHD_MD5_HMAC ((6 << 4) | (1 << 7)) -#define CESA_CSHD_SHA1_HMAC ((7 << 4) | (1 << 7)) +#define CESA_CSHD_MD5_HMAC (6 << 4) +#define CESA_CSHD_SHA1_HMAC (7 << 4) + +#define CESA_CSHD_96_BIT_HMAC (1 << 7) #define CESA_CSHD_DES (1 << 8) #define CESA_CSHD_3DES (2 << 8) |