linux/drivers/crypto/keembay/ocs-hcu.h
Daniele Alessandrelli ae832e329a crypto: keembay-ocs-hcu - Add HMAC support
Add HMAC support to the Keem Bay OCS HCU driver, thus making it provide
the following additional transformations:
- hmac(sha256)
- hmac(sha384)
- hmac(sha512)
- hmac(sm3)

The Keem Bay OCS HCU hardware does not allow "context-switch" for HMAC
operations, i.e., it does not support computing a partial HMAC, save its
state and then continue it later. Therefore, full hardware acceleration
is provided only when possible (e.g., when crypto_ahash_digest() is
called); in all other cases hardware acceleration is only partial (OPAD
and IPAD calculation is done in software, while hashing is hardware
accelerated).

Co-developed-by: Declan Murphy <declan.murphy@intel.com>
Signed-off-by: Declan Murphy <declan.murphy@intel.com>
Signed-off-by: Daniele Alessandrelli <daniele.alessandrelli@intel.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2021-01-03 08:41:36 +11:00

107 lines
2.9 KiB
C

/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Intel Keem Bay OCS HCU Crypto Driver.
*
* Copyright (C) 2018-2020 Intel Corporation
*/
#include <linux/dma-mapping.h>
#ifndef _CRYPTO_OCS_HCU_H
#define _CRYPTO_OCS_HCU_H
#define OCS_HCU_DMA_BIT_MASK DMA_BIT_MASK(32)
#define OCS_HCU_HW_KEY_LEN 64
struct ocs_hcu_dma_list;
enum ocs_hcu_algo {
OCS_HCU_ALGO_SHA256 = 2,
OCS_HCU_ALGO_SHA224 = 3,
OCS_HCU_ALGO_SHA384 = 4,
OCS_HCU_ALGO_SHA512 = 5,
OCS_HCU_ALGO_SM3 = 6,
};
/**
* struct ocs_hcu_dev - OCS HCU device context.
* @list: List of device contexts.
* @dev: OCS HCU device.
* @io_base: Base address of OCS HCU registers.
* @engine: Crypto engine for the device.
* @irq: IRQ number.
* @irq_done: Completion for IRQ.
* @irq_err: Flag indicating an IRQ error has happened.
*/
struct ocs_hcu_dev {
struct list_head list;
struct device *dev;
void __iomem *io_base;
struct crypto_engine *engine;
int irq;
struct completion irq_done;
bool irq_err;
};
/**
* struct ocs_hcu_idata - Intermediate data generated by the HCU.
* @msg_len_lo: Length of data the HCU has operated on in bits, low 32b.
* @msg_len_hi: Length of data the HCU has operated on in bits, high 32b.
* @digest: The digest read from the HCU. If the HCU is terminated, it will
* contain the actual hash digest. Otherwise it is the intermediate
* state.
*/
struct ocs_hcu_idata {
u32 msg_len_lo;
u32 msg_len_hi;
u8 digest[SHA512_DIGEST_SIZE];
};
/**
* struct ocs_hcu_hash_ctx - Context for OCS HCU hashing operation.
* @algo: The hashing algorithm being used.
* @idata: The current intermediate data.
*/
struct ocs_hcu_hash_ctx {
enum ocs_hcu_algo algo;
struct ocs_hcu_idata idata;
};
irqreturn_t ocs_hcu_irq_handler(int irq, void *dev_id);
struct ocs_hcu_dma_list *ocs_hcu_dma_list_alloc(struct ocs_hcu_dev *hcu_dev,
int max_nents);
void ocs_hcu_dma_list_free(struct ocs_hcu_dev *hcu_dev,
struct ocs_hcu_dma_list *dma_list);
int ocs_hcu_dma_list_add_tail(struct ocs_hcu_dev *hcu_dev,
struct ocs_hcu_dma_list *dma_list,
dma_addr_t addr, u32 len);
int ocs_hcu_hash_init(struct ocs_hcu_hash_ctx *ctx, enum ocs_hcu_algo algo);
int ocs_hcu_hash_update(struct ocs_hcu_dev *hcu_dev,
struct ocs_hcu_hash_ctx *ctx,
const struct ocs_hcu_dma_list *dma_list);
int ocs_hcu_hash_finup(struct ocs_hcu_dev *hcu_dev,
const struct ocs_hcu_hash_ctx *ctx,
const struct ocs_hcu_dma_list *dma_list,
u8 *dgst, size_t dgst_len);
int ocs_hcu_hash_final(struct ocs_hcu_dev *hcu_dev,
const struct ocs_hcu_hash_ctx *ctx, u8 *dgst,
size_t dgst_len);
int ocs_hcu_digest(struct ocs_hcu_dev *hcu_dev, enum ocs_hcu_algo algo,
void *data, size_t data_len, u8 *dgst, size_t dgst_len);
int ocs_hcu_hmac(struct ocs_hcu_dev *hcu_dev, enum ocs_hcu_algo algo,
const u8 *key, size_t key_len,
const struct ocs_hcu_dma_list *dma_list,
u8 *dgst, size_t dgst_len);
#endif /* _CRYPTO_OCS_HCU_H */