mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-16 00:34:20 +08:00
62f58b1637
Add HACE crypto driver to support symmetric-key encryption and decryption with multiple modes of operation. Signed-off-by: Neal Liu <neal_liu@aspeedtech.com> Signed-off-by: Johnny Huang <johnny_huang@aspeedtech.com> Reviewed-by: Dhananjay Phadke <dphadke@linux.microsoft.com> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
299 lines
8.1 KiB
C
299 lines
8.1 KiB
C
/* SPDX-License-Identifier: GPL-2.0+ */
|
|
#ifndef __ASPEED_HACE_H__
|
|
#define __ASPEED_HACE_H__
|
|
|
|
#include <linux/interrupt.h>
|
|
#include <linux/delay.h>
|
|
#include <linux/err.h>
|
|
#include <linux/fips.h>
|
|
#include <linux/dma-mapping.h>
|
|
#include <crypto/aes.h>
|
|
#include <crypto/des.h>
|
|
#include <crypto/scatterwalk.h>
|
|
#include <crypto/internal/aead.h>
|
|
#include <crypto/internal/akcipher.h>
|
|
#include <crypto/internal/des.h>
|
|
#include <crypto/internal/hash.h>
|
|
#include <crypto/internal/kpp.h>
|
|
#include <crypto/internal/skcipher.h>
|
|
#include <crypto/algapi.h>
|
|
#include <crypto/engine.h>
|
|
#include <crypto/hmac.h>
|
|
#include <crypto/sha1.h>
|
|
#include <crypto/sha2.h>
|
|
|
|
/*****************************
|
|
* *
|
|
* HACE register definitions *
|
|
* *
|
|
* ***************************/
|
|
#define ASPEED_HACE_SRC 0x00 /* Crypto Data Source Base Address Register */
|
|
#define ASPEED_HACE_DEST 0x04 /* Crypto Data Destination Base Address Register */
|
|
#define ASPEED_HACE_CONTEXT 0x08 /* Crypto Context Buffer Base Address Register */
|
|
#define ASPEED_HACE_DATA_LEN 0x0C /* Crypto Data Length Register */
|
|
#define ASPEED_HACE_CMD 0x10 /* Crypto Engine Command Register */
|
|
|
|
/* G5 */
|
|
#define ASPEED_HACE_TAG 0x18 /* HACE Tag Register */
|
|
/* G6 */
|
|
#define ASPEED_HACE_GCM_ADD_LEN 0x14 /* Crypto AES-GCM Additional Data Length Register */
|
|
#define ASPEED_HACE_GCM_TAG_BASE_ADDR 0x18 /* Crypto AES-GCM Tag Write Buff Base Address Reg */
|
|
|
|
#define ASPEED_HACE_STS 0x1C /* HACE Status Register */
|
|
|
|
#define ASPEED_HACE_HASH_SRC 0x20 /* Hash Data Source Base Address Register */
|
|
#define ASPEED_HACE_HASH_DIGEST_BUFF 0x24 /* Hash Digest Write Buffer Base Address Register */
|
|
#define ASPEED_HACE_HASH_KEY_BUFF 0x28 /* Hash HMAC Key Buffer Base Address Register */
|
|
#define ASPEED_HACE_HASH_DATA_LEN 0x2C /* Hash Data Length Register */
|
|
#define ASPEED_HACE_HASH_CMD 0x30 /* Hash Engine Command Register */
|
|
|
|
/* crypto cmd */
|
|
#define HACE_CMD_SINGLE_DES 0
|
|
#define HACE_CMD_TRIPLE_DES BIT(17)
|
|
#define HACE_CMD_AES_SELECT 0
|
|
#define HACE_CMD_DES_SELECT BIT(16)
|
|
#define HACE_CMD_ISR_EN BIT(12)
|
|
#define HACE_CMD_CONTEXT_SAVE_ENABLE (0)
|
|
#define HACE_CMD_CONTEXT_SAVE_DISABLE BIT(9)
|
|
#define HACE_CMD_AES (0)
|
|
#define HACE_CMD_DES (0)
|
|
#define HACE_CMD_RC4 BIT(8)
|
|
#define HACE_CMD_DECRYPT (0)
|
|
#define HACE_CMD_ENCRYPT BIT(7)
|
|
|
|
#define HACE_CMD_ECB (0x0 << 4)
|
|
#define HACE_CMD_CBC (0x1 << 4)
|
|
#define HACE_CMD_CFB (0x2 << 4)
|
|
#define HACE_CMD_OFB (0x3 << 4)
|
|
#define HACE_CMD_CTR (0x4 << 4)
|
|
#define HACE_CMD_OP_MODE_MASK (0x7 << 4)
|
|
|
|
#define HACE_CMD_AES128 (0x0 << 2)
|
|
#define HACE_CMD_AES192 (0x1 << 2)
|
|
#define HACE_CMD_AES256 (0x2 << 2)
|
|
#define HACE_CMD_OP_CASCADE (0x3)
|
|
#define HACE_CMD_OP_INDEPENDENT (0x1)
|
|
|
|
/* G5 */
|
|
#define HACE_CMD_RI_WO_DATA_ENABLE (0)
|
|
#define HACE_CMD_RI_WO_DATA_DISABLE BIT(11)
|
|
#define HACE_CMD_CONTEXT_LOAD_ENABLE (0)
|
|
#define HACE_CMD_CONTEXT_LOAD_DISABLE BIT(10)
|
|
/* G6 */
|
|
#define HACE_CMD_AES_KEY_FROM_OTP BIT(24)
|
|
#define HACE_CMD_GHASH_TAG_XOR_EN BIT(23)
|
|
#define HACE_CMD_GHASH_PAD_LEN_INV BIT(22)
|
|
#define HACE_CMD_GCM_TAG_ADDR_SEL BIT(21)
|
|
#define HACE_CMD_MBUS_REQ_SYNC_EN BIT(20)
|
|
#define HACE_CMD_DES_SG_CTRL BIT(19)
|
|
#define HACE_CMD_SRC_SG_CTRL BIT(18)
|
|
#define HACE_CMD_CTR_IV_AES_96 (0x1 << 14)
|
|
#define HACE_CMD_CTR_IV_DES_32 (0x1 << 14)
|
|
#define HACE_CMD_CTR_IV_AES_64 (0x2 << 14)
|
|
#define HACE_CMD_CTR_IV_AES_32 (0x3 << 14)
|
|
#define HACE_CMD_AES_KEY_HW_EXP BIT(13)
|
|
#define HACE_CMD_GCM (0x5 << 4)
|
|
|
|
/* interrupt status reg */
|
|
#define HACE_CRYPTO_ISR BIT(12)
|
|
#define HACE_HASH_ISR BIT(9)
|
|
#define HACE_HASH_BUSY BIT(0)
|
|
|
|
/* hash cmd reg */
|
|
#define HASH_CMD_MBUS_REQ_SYNC_EN BIT(20)
|
|
#define HASH_CMD_HASH_SRC_SG_CTRL BIT(18)
|
|
#define HASH_CMD_SHA512_224 (0x3 << 10)
|
|
#define HASH_CMD_SHA512_256 (0x2 << 10)
|
|
#define HASH_CMD_SHA384 (0x1 << 10)
|
|
#define HASH_CMD_SHA512 (0)
|
|
#define HASH_CMD_INT_ENABLE BIT(9)
|
|
#define HASH_CMD_HMAC (0x1 << 7)
|
|
#define HASH_CMD_ACC_MODE (0x2 << 7)
|
|
#define HASH_CMD_HMAC_KEY (0x3 << 7)
|
|
#define HASH_CMD_SHA1 (0x2 << 4)
|
|
#define HASH_CMD_SHA224 (0x4 << 4)
|
|
#define HASH_CMD_SHA256 (0x5 << 4)
|
|
#define HASH_CMD_SHA512_SER (0x6 << 4)
|
|
#define HASH_CMD_SHA_SWAP (0x2 << 2)
|
|
|
|
#define HASH_SG_LAST_LIST BIT(31)
|
|
|
|
#define CRYPTO_FLAGS_BUSY BIT(1)
|
|
|
|
#define SHA_OP_UPDATE 1
|
|
#define SHA_OP_FINAL 2
|
|
|
|
#define SHA_FLAGS_SHA1 BIT(0)
|
|
#define SHA_FLAGS_SHA224 BIT(1)
|
|
#define SHA_FLAGS_SHA256 BIT(2)
|
|
#define SHA_FLAGS_SHA384 BIT(3)
|
|
#define SHA_FLAGS_SHA512 BIT(4)
|
|
#define SHA_FLAGS_SHA512_224 BIT(5)
|
|
#define SHA_FLAGS_SHA512_256 BIT(6)
|
|
#define SHA_FLAGS_HMAC BIT(8)
|
|
#define SHA_FLAGS_FINUP BIT(9)
|
|
#define SHA_FLAGS_MASK (0xff)
|
|
|
|
#define ASPEED_CRYPTO_SRC_DMA_BUF_LEN 0xa000
|
|
#define ASPEED_CRYPTO_DST_DMA_BUF_LEN 0xa000
|
|
#define ASPEED_CRYPTO_GCM_TAG_OFFSET 0x9ff0
|
|
#define ASPEED_HASH_SRC_DMA_BUF_LEN 0xa000
|
|
#define ASPEED_HASH_QUEUE_LENGTH 50
|
|
|
|
#define HACE_CMD_IV_REQUIRE (HACE_CMD_CBC | HACE_CMD_CFB | \
|
|
HACE_CMD_OFB | HACE_CMD_CTR)
|
|
|
|
struct aspeed_hace_dev;
|
|
|
|
typedef int (*aspeed_hace_fn_t)(struct aspeed_hace_dev *);
|
|
|
|
struct aspeed_sg_list {
|
|
__le32 len;
|
|
__le32 phy_addr;
|
|
};
|
|
|
|
struct aspeed_engine_hash {
|
|
struct tasklet_struct done_task;
|
|
unsigned long flags;
|
|
struct ahash_request *req;
|
|
|
|
/* input buffer */
|
|
void *ahash_src_addr;
|
|
dma_addr_t ahash_src_dma_addr;
|
|
|
|
dma_addr_t src_dma;
|
|
dma_addr_t digest_dma;
|
|
|
|
size_t src_length;
|
|
|
|
/* callback func */
|
|
aspeed_hace_fn_t resume;
|
|
aspeed_hace_fn_t dma_prepare;
|
|
};
|
|
|
|
struct aspeed_sha_hmac_ctx {
|
|
struct crypto_shash *shash;
|
|
u8 ipad[SHA512_BLOCK_SIZE];
|
|
u8 opad[SHA512_BLOCK_SIZE];
|
|
};
|
|
|
|
struct aspeed_sham_ctx {
|
|
struct crypto_engine_ctx enginectx;
|
|
|
|
struct aspeed_hace_dev *hace_dev;
|
|
unsigned long flags; /* hmac flag */
|
|
|
|
struct aspeed_sha_hmac_ctx base[0];
|
|
};
|
|
|
|
struct aspeed_sham_reqctx {
|
|
unsigned long flags; /* final update flag should no use*/
|
|
unsigned long op; /* final or update */
|
|
u32 cmd; /* trigger cmd */
|
|
|
|
/* walk state */
|
|
struct scatterlist *src_sg;
|
|
int src_nents;
|
|
unsigned int offset; /* offset in current sg */
|
|
unsigned int total; /* per update length */
|
|
|
|
size_t digsize;
|
|
size_t block_size;
|
|
size_t ivsize;
|
|
const __be32 *sha_iv;
|
|
|
|
/* remain data buffer */
|
|
u8 buffer[SHA512_BLOCK_SIZE * 2];
|
|
dma_addr_t buffer_dma_addr;
|
|
size_t bufcnt; /* buffer counter */
|
|
|
|
/* output buffer */
|
|
u8 digest[SHA512_DIGEST_SIZE] __aligned(64);
|
|
dma_addr_t digest_dma_addr;
|
|
u64 digcnt[2];
|
|
};
|
|
|
|
struct aspeed_engine_crypto {
|
|
struct tasklet_struct done_task;
|
|
unsigned long flags;
|
|
struct skcipher_request *req;
|
|
|
|
/* context buffer */
|
|
void *cipher_ctx;
|
|
dma_addr_t cipher_ctx_dma;
|
|
|
|
/* input buffer, could be single/scatter-gather lists */
|
|
void *cipher_addr;
|
|
dma_addr_t cipher_dma_addr;
|
|
|
|
/* output buffer, only used in scatter-gather lists */
|
|
void *dst_sg_addr;
|
|
dma_addr_t dst_sg_dma_addr;
|
|
|
|
/* callback func */
|
|
aspeed_hace_fn_t resume;
|
|
};
|
|
|
|
struct aspeed_cipher_ctx {
|
|
struct crypto_engine_ctx enginectx;
|
|
|
|
struct aspeed_hace_dev *hace_dev;
|
|
int key_len;
|
|
u8 key[AES_MAX_KEYLENGTH];
|
|
|
|
/* callback func */
|
|
aspeed_hace_fn_t start;
|
|
|
|
struct crypto_skcipher *fallback_tfm;
|
|
};
|
|
|
|
struct aspeed_cipher_reqctx {
|
|
int enc_cmd;
|
|
int src_nents;
|
|
int dst_nents;
|
|
|
|
struct skcipher_request fallback_req; /* keep at the end */
|
|
};
|
|
|
|
struct aspeed_hace_dev {
|
|
void __iomem *regs;
|
|
struct device *dev;
|
|
int irq;
|
|
struct clk *clk;
|
|
unsigned long version;
|
|
|
|
struct crypto_engine *crypt_engine_hash;
|
|
struct crypto_engine *crypt_engine_crypto;
|
|
|
|
struct aspeed_engine_hash hash_engine;
|
|
struct aspeed_engine_crypto crypto_engine;
|
|
};
|
|
|
|
struct aspeed_hace_alg {
|
|
struct aspeed_hace_dev *hace_dev;
|
|
|
|
const char *alg_base;
|
|
|
|
union {
|
|
struct skcipher_alg skcipher;
|
|
struct ahash_alg ahash;
|
|
} alg;
|
|
};
|
|
|
|
enum aspeed_version {
|
|
AST2500_VERSION = 5,
|
|
AST2600_VERSION
|
|
};
|
|
|
|
#define ast_hace_write(hace, val, offset) \
|
|
writel((val), (hace)->regs + (offset))
|
|
#define ast_hace_read(hace, offset) \
|
|
readl((hace)->regs + (offset))
|
|
|
|
void aspeed_register_hace_hash_algs(struct aspeed_hace_dev *hace_dev);
|
|
void aspeed_unregister_hace_hash_algs(struct aspeed_hace_dev *hace_dev);
|
|
void aspeed_register_hace_crypto_algs(struct aspeed_hace_dev *hace_dev);
|
|
void aspeed_unregister_hace_crypto_algs(struct aspeed_hace_dev *hace_dev);
|
|
|
|
#endif
|