summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorzbb <zbb@FreeBSD.org>2016-06-02 18:37:50 +0000
committerzbb <zbb@FreeBSD.org>2016-06-02 18:37:50 +0000
commit9682ecbee5ba7149a3b1de4ff2e5bf39c85d5ebc (patch)
tree297f0828d75b28b1d23c182ef6bad5e1f252bb8e
parentf1fe5e60a7c3b37eccc78de804780b24fbc4eaf7 (diff)
downloadFreeBSD-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.c24
-rw-r--r--sys/dev/cesa/cesa.h8
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)
OpenPOWER on IntegriCloud