mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-11-01 17:08:10 +00:00
ae832e329a
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>
106 lines
2.9 KiB
C
106 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 */
|