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
This commit is contained in:
zbb 2016-06-02 18:39:33 +00:00
parent 9682ecbee5
commit 03c47d2a4c
2 changed files with 37 additions and 4 deletions

View File

@ -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;

View File

@ -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