summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorzbb <zbb@FreeBSD.org>2016-06-02 18:39:33 +0000
committerzbb <zbb@FreeBSD.org>2016-06-02 18:39:33 +0000
commit03c47d2a4c933c1fbe6b5993c1fa18d213495da8 (patch)
tree97f7c5f902b50d199cf23e60989cf1a57c8ae664
parent9682ecbee5ba7149a3b1de4ff2e5bf39c85d5ebc (diff)
downloadFreeBSD-src-03c47d2a4c933c1fbe6b5993c1fa18d213495da8.zip
FreeBSD-src-03c47d2a4c933c1fbe6b5993c1fa18d213495da8.tar.gz
Add HMAC-SHA256 support in CESA
Only HMAC-SHA256 is added as it is the only SHA-2 variant supported by cryptodev. It is not possible to register hardware support for other algorithms in the family including regular non-keyed SHA256. Submitted by: Michal Stanek <mst@semihalf.com> Obtained from: Semihalf Sponsored by: Stormshield Differential revision: https://reviews.freebsd.org/D6219
-rw-r--r--sys/dev/cesa/cesa.c25
-rw-r--r--sys/dev/cesa/cesa.h16
2 files changed, 37 insertions, 4 deletions
diff --git a/sys/dev/cesa/cesa.c b/sys/dev/cesa/cesa.c
index 4f31668..ea35ae7 100644
--- a/sys/dev/cesa/cesa.c
+++ b/sys/dev/cesa/cesa.c
@@ -63,6 +63,7 @@ __FBSDID("$FreeBSD$");
#include <sys/md5.h>
#include <crypto/sha1.h>
+#include <crypto/sha2/sha256.h>
#include <crypto/rijndael/rijndael.h>
#include <opencrypto/cryptodev.h>
#include "cryptodev_if.h"
@@ -449,6 +450,7 @@ cesa_set_mkey(struct cesa_session *cs, int alg, const uint8_t *mkey, int mklen)
uint8_t ipad[CESA_MAX_HMAC_BLOCK_LEN];
uint8_t opad[CESA_MAX_HMAC_BLOCK_LEN];
SHA1_CTX sha1ctx;
+ SHA256_CTX sha256ctx;
MD5_CTX md5ctx;
uint32_t *hout;
uint32_t *hin;
@@ -481,6 +483,14 @@ cesa_set_mkey(struct cesa_session *cs, int alg, const uint8_t *mkey, int mklen)
SHA1Update(&sha1ctx, opad, SHA1_HMAC_BLOCK_LEN);
memcpy(hout, sha1ctx.h.b32, sizeof(sha1ctx.h.b32));
break;
+ case CRYPTO_SHA2_256_HMAC:
+ SHA256_Init(&sha256ctx);
+ SHA256_Update(&sha256ctx, ipad, SHA2_256_HMAC_BLOCK_LEN);
+ memcpy(hin, sha256ctx.state, sizeof(sha256ctx.state));
+ SHA256_Init(&sha256ctx);
+ SHA256_Update(&sha256ctx, opad, SHA2_256_HMAC_BLOCK_LEN);
+ memcpy(hout, sha256ctx.state, sizeof(sha256ctx.state));
+ break;
default:
return (EINVAL);
}
@@ -541,6 +551,7 @@ cesa_is_hash(int alg)
case CRYPTO_MD5_HMAC:
case CRYPTO_SHA1:
case CRYPTO_SHA1_HMAC:
+ case CRYPTO_SHA2_256_HMAC:
return (1);
default:
return (0);
@@ -942,7 +953,11 @@ cesa_execute(struct cesa_softc *sc)
ctd = STAILQ_FIRST(&cr->cr_tdesc);
CESA_TDMA_WRITE(sc, CESA_TDMA_ND, ctd->ctd_cthd_paddr);
+#if defined (SOC_MV_ARMADA38X)
+ CESA_REG_WRITE(sc, CESA_SA_CMD, CESA_SA_CMD_ACTVATE | CESA_SA_CMD_SHA2);
+#else
CESA_REG_WRITE(sc, CESA_SA_CMD, CESA_SA_CMD_ACTVATE);
+#endif
CESA_UNLOCK(sc, requests);
}
@@ -1174,6 +1189,9 @@ cesa_attach(device_t dev)
*/
CESA_TDMA_WRITE(sc, CESA_TDMA_CR, CESA_TDMA_CR_DBL128 |
CESA_TDMA_CR_SBL128 | CESA_TDMA_CR_ORDEN | CESA_TDMA_CR_NBS |
+#if defined (SOC_MV_ARMADA38X)
+ CESA_TDMA_NUM_OUTSTAND |
+#endif
CESA_TDMA_CR_ENABLE);
/*
@@ -1208,6 +1226,7 @@ cesa_attach(device_t dev)
crypto_register(sc->sc_cid, CRYPTO_MD5_HMAC, 0, 0);
crypto_register(sc->sc_cid, CRYPTO_SHA1, 0, 0);
crypto_register(sc->sc_cid, CRYPTO_SHA1_HMAC, 0, 0);
+ crypto_register(sc->sc_cid, CRYPTO_SHA2_256_HMAC, 0, 0);
return (0);
err8:
@@ -1478,6 +1497,12 @@ cesa_newsession(device_t dev, uint32_t *sidp, struct cryptoini *cri)
if (cs->cs_hlen == CESA_HMAC_TRUNC_LEN)
cs->cs_config |= CESA_CSHD_96_BIT_HMAC;
break;
+ case CRYPTO_SHA2_256_HMAC:
+ cs->cs_mblen = SHA2_256_HMAC_BLOCK_LEN;
+ cs->cs_hlen = (mac->cri_mlen == 0) ? SHA2_256_HASH_LEN :
+ mac->cri_mlen;
+ cs->cs_config |= CESA_CSHD_SHA2_256_HMAC;
+ break;
default:
error = EINVAL;
break;
diff --git a/sys/dev/cesa/cesa.h b/sys/dev/cesa/cesa.h
index a739835..4819d3d 100644
--- a/sys/dev/cesa/cesa.h
+++ b/sys/dev/cesa/cesa.h
@@ -74,11 +74,9 @@
/*
* CESA_MAX_HASH_LEN is maximum length of hash generated by CESA.
- * As CESA suports only MD5 and SHA1 this equals to 20 bytes.
- * However we increase the value to 24 bytes to meet alignment
- * requirements in cesa_sa_data structure.
+ * As CESA supports MD5, SHA1 and SHA-256 this equals to 32 bytes.
*/
-#define CESA_MAX_HASH_LEN 24
+#define CESA_MAX_HASH_LEN 32
#define CESA_MAX_KEY_LEN 32
#define CESA_MAX_IV_LEN 16
#define CESA_MAX_HMAC_BLOCK_LEN 64
@@ -293,8 +291,10 @@ struct cesa_chain_info {
#define CESA_CSHD_MD5 (4 << 4)
#define CESA_CSHD_SHA1 (5 << 4)
+#define CESA_CSHD_SHA2_256 (1 << 4)
#define CESA_CSHD_MD5_HMAC (6 << 4)
#define CESA_CSHD_SHA1_HMAC (7 << 4)
+#define CESA_CSHD_SHA2_256_HMAC (3 << 4)
#define CESA_CSHD_96_BIT_HMAC (1 << 7)
@@ -336,6 +336,10 @@ struct cesa_chain_info {
#define CESA_TDMA_CR_FETCHND (1 << 13)
#define CESA_TDMA_CR_ACTIVE (1 << 14)
+#if defined (SOC_MV_ARMADA38X)
+#define CESA_TDMA_NUM_OUTSTAND (2 << 16)
+#endif
+
#define CESA_TDMA_ECR 0x08C8
#define CESA_TDMA_ECR_MISS (1 << 0)
#define CESA_TDMA_ECR_DOUBLE_HIT (1 << 1)
@@ -357,6 +361,10 @@ struct cesa_chain_info {
#define CESA_SA_CMD 0x0E00
#define CESA_SA_CMD_ACTVATE (1 << 0)
+#if defined (SOC_MV_ARMADA38X)
+#define CESA_SA_CMD_SHA2 (1 << 31)
+#endif
+
#define CESA_SA_DPR 0x0E04
#define CESA_SA_CR 0x0E08
OpenPOWER on IntegriCloud