diff options
author | zbb <zbb@FreeBSD.org> | 2016-06-02 18:39:33 +0000 |
---|---|---|
committer | zbb <zbb@FreeBSD.org> | 2016-06-02 18:39:33 +0000 |
commit | 03c47d2a4c933c1fbe6b5993c1fa18d213495da8 (patch) | |
tree | 97f7c5f902b50d199cf23e60989cf1a57c8ae664 | |
parent | 9682ecbee5ba7149a3b1de4ff2e5bf39c85d5ebc (diff) | |
download | FreeBSD-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.c | 25 | ||||
-rw-r--r-- | sys/dev/cesa/cesa.h | 16 |
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 |