1108713a7SNeal Liu /* SPDX-License-Identifier: GPL-2.0+ */ 2108713a7SNeal Liu #ifndef __ASPEED_HACE_H__ 3108713a7SNeal Liu #define __ASPEED_HACE_H__ 4108713a7SNeal Liu 5108713a7SNeal Liu #include <linux/interrupt.h> 6108713a7SNeal Liu #include <linux/delay.h> 7108713a7SNeal Liu #include <linux/err.h> 8108713a7SNeal Liu #include <linux/fips.h> 9108713a7SNeal Liu #include <linux/dma-mapping.h> 1062f58b16SNeal Liu #include <crypto/aes.h> 1162f58b16SNeal Liu #include <crypto/des.h> 12108713a7SNeal Liu #include <crypto/scatterwalk.h> 13108713a7SNeal Liu #include <crypto/internal/aead.h> 14108713a7SNeal Liu #include <crypto/internal/akcipher.h> 1562f58b16SNeal Liu #include <crypto/internal/des.h> 16108713a7SNeal Liu #include <crypto/internal/hash.h> 17108713a7SNeal Liu #include <crypto/internal/kpp.h> 18108713a7SNeal Liu #include <crypto/internal/skcipher.h> 19108713a7SNeal Liu #include <crypto/algapi.h> 20108713a7SNeal Liu #include <crypto/engine.h> 21108713a7SNeal Liu #include <crypto/hmac.h> 22108713a7SNeal Liu #include <crypto/sha1.h> 23108713a7SNeal Liu #include <crypto/sha2.h> 24108713a7SNeal Liu 25108713a7SNeal Liu /***************************** 26108713a7SNeal Liu * * 27108713a7SNeal Liu * HACE register definitions * 28108713a7SNeal Liu * * 29108713a7SNeal Liu * ***************************/ 3062f58b16SNeal Liu #define ASPEED_HACE_SRC 0x00 /* Crypto Data Source Base Address Register */ 3162f58b16SNeal Liu #define ASPEED_HACE_DEST 0x04 /* Crypto Data Destination Base Address Register */ 3262f58b16SNeal Liu #define ASPEED_HACE_CONTEXT 0x08 /* Crypto Context Buffer Base Address Register */ 3362f58b16SNeal Liu #define ASPEED_HACE_DATA_LEN 0x0C /* Crypto Data Length Register */ 3462f58b16SNeal Liu #define ASPEED_HACE_CMD 0x10 /* Crypto Engine Command Register */ 3562f58b16SNeal Liu 3662f58b16SNeal Liu /* G5 */ 3762f58b16SNeal Liu #define ASPEED_HACE_TAG 0x18 /* HACE Tag Register */ 3862f58b16SNeal Liu /* G6 */ 3962f58b16SNeal Liu #define ASPEED_HACE_GCM_ADD_LEN 0x14 /* Crypto AES-GCM Additional Data Length Register */ 4062f58b16SNeal Liu #define ASPEED_HACE_GCM_TAG_BASE_ADDR 0x18 /* Crypto AES-GCM Tag Write Buff Base Address Reg */ 41108713a7SNeal Liu 42108713a7SNeal Liu #define ASPEED_HACE_STS 0x1C /* HACE Status Register */ 4362f58b16SNeal Liu 44108713a7SNeal Liu #define ASPEED_HACE_HASH_SRC 0x20 /* Hash Data Source Base Address Register */ 45108713a7SNeal Liu #define ASPEED_HACE_HASH_DIGEST_BUFF 0x24 /* Hash Digest Write Buffer Base Address Register */ 46108713a7SNeal Liu #define ASPEED_HACE_HASH_KEY_BUFF 0x28 /* Hash HMAC Key Buffer Base Address Register */ 47108713a7SNeal Liu #define ASPEED_HACE_HASH_DATA_LEN 0x2C /* Hash Data Length Register */ 48108713a7SNeal Liu #define ASPEED_HACE_HASH_CMD 0x30 /* Hash Engine Command Register */ 49108713a7SNeal Liu 5062f58b16SNeal Liu /* crypto cmd */ 5162f58b16SNeal Liu #define HACE_CMD_SINGLE_DES 0 5262f58b16SNeal Liu #define HACE_CMD_TRIPLE_DES BIT(17) 5362f58b16SNeal Liu #define HACE_CMD_AES_SELECT 0 5462f58b16SNeal Liu #define HACE_CMD_DES_SELECT BIT(16) 5562f58b16SNeal Liu #define HACE_CMD_ISR_EN BIT(12) 5662f58b16SNeal Liu #define HACE_CMD_CONTEXT_SAVE_ENABLE (0) 5762f58b16SNeal Liu #define HACE_CMD_CONTEXT_SAVE_DISABLE BIT(9) 5862f58b16SNeal Liu #define HACE_CMD_AES (0) 5962f58b16SNeal Liu #define HACE_CMD_DES (0) 6062f58b16SNeal Liu #define HACE_CMD_RC4 BIT(8) 6162f58b16SNeal Liu #define HACE_CMD_DECRYPT (0) 6262f58b16SNeal Liu #define HACE_CMD_ENCRYPT BIT(7) 6362f58b16SNeal Liu 6462f58b16SNeal Liu #define HACE_CMD_ECB (0x0 << 4) 6562f58b16SNeal Liu #define HACE_CMD_CBC (0x1 << 4) 6662f58b16SNeal Liu #define HACE_CMD_CFB (0x2 << 4) 6762f58b16SNeal Liu #define HACE_CMD_OFB (0x3 << 4) 6862f58b16SNeal Liu #define HACE_CMD_CTR (0x4 << 4) 6962f58b16SNeal Liu #define HACE_CMD_OP_MODE_MASK (0x7 << 4) 7062f58b16SNeal Liu 7162f58b16SNeal Liu #define HACE_CMD_AES128 (0x0 << 2) 7262f58b16SNeal Liu #define HACE_CMD_AES192 (0x1 << 2) 7362f58b16SNeal Liu #define HACE_CMD_AES256 (0x2 << 2) 7462f58b16SNeal Liu #define HACE_CMD_OP_CASCADE (0x3) 7562f58b16SNeal Liu #define HACE_CMD_OP_INDEPENDENT (0x1) 7662f58b16SNeal Liu 7762f58b16SNeal Liu /* G5 */ 7862f58b16SNeal Liu #define HACE_CMD_RI_WO_DATA_ENABLE (0) 7962f58b16SNeal Liu #define HACE_CMD_RI_WO_DATA_DISABLE BIT(11) 8062f58b16SNeal Liu #define HACE_CMD_CONTEXT_LOAD_ENABLE (0) 8162f58b16SNeal Liu #define HACE_CMD_CONTEXT_LOAD_DISABLE BIT(10) 8262f58b16SNeal Liu /* G6 */ 8362f58b16SNeal Liu #define HACE_CMD_AES_KEY_FROM_OTP BIT(24) 8462f58b16SNeal Liu #define HACE_CMD_GHASH_TAG_XOR_EN BIT(23) 8562f58b16SNeal Liu #define HACE_CMD_GHASH_PAD_LEN_INV BIT(22) 8662f58b16SNeal Liu #define HACE_CMD_GCM_TAG_ADDR_SEL BIT(21) 8762f58b16SNeal Liu #define HACE_CMD_MBUS_REQ_SYNC_EN BIT(20) 8862f58b16SNeal Liu #define HACE_CMD_DES_SG_CTRL BIT(19) 8962f58b16SNeal Liu #define HACE_CMD_SRC_SG_CTRL BIT(18) 9062f58b16SNeal Liu #define HACE_CMD_CTR_IV_AES_96 (0x1 << 14) 9162f58b16SNeal Liu #define HACE_CMD_CTR_IV_DES_32 (0x1 << 14) 9262f58b16SNeal Liu #define HACE_CMD_CTR_IV_AES_64 (0x2 << 14) 9362f58b16SNeal Liu #define HACE_CMD_CTR_IV_AES_32 (0x3 << 14) 9462f58b16SNeal Liu #define HACE_CMD_AES_KEY_HW_EXP BIT(13) 9562f58b16SNeal Liu #define HACE_CMD_GCM (0x5 << 4) 9662f58b16SNeal Liu 97108713a7SNeal Liu /* interrupt status reg */ 9862f58b16SNeal Liu #define HACE_CRYPTO_ISR BIT(12) 99108713a7SNeal Liu #define HACE_HASH_ISR BIT(9) 100108713a7SNeal Liu #define HACE_HASH_BUSY BIT(0) 101108713a7SNeal Liu 102108713a7SNeal Liu /* hash cmd reg */ 103108713a7SNeal Liu #define HASH_CMD_MBUS_REQ_SYNC_EN BIT(20) 104108713a7SNeal Liu #define HASH_CMD_HASH_SRC_SG_CTRL BIT(18) 105108713a7SNeal Liu #define HASH_CMD_SHA512_224 (0x3 << 10) 106108713a7SNeal Liu #define HASH_CMD_SHA512_256 (0x2 << 10) 107108713a7SNeal Liu #define HASH_CMD_SHA384 (0x1 << 10) 108108713a7SNeal Liu #define HASH_CMD_SHA512 (0) 109108713a7SNeal Liu #define HASH_CMD_INT_ENABLE BIT(9) 110108713a7SNeal Liu #define HASH_CMD_HMAC (0x1 << 7) 111108713a7SNeal Liu #define HASH_CMD_ACC_MODE (0x2 << 7) 112108713a7SNeal Liu #define HASH_CMD_HMAC_KEY (0x3 << 7) 113108713a7SNeal Liu #define HASH_CMD_SHA1 (0x2 << 4) 114108713a7SNeal Liu #define HASH_CMD_SHA224 (0x4 << 4) 115108713a7SNeal Liu #define HASH_CMD_SHA256 (0x5 << 4) 116108713a7SNeal Liu #define HASH_CMD_SHA512_SER (0x6 << 4) 117108713a7SNeal Liu #define HASH_CMD_SHA_SWAP (0x2 << 2) 118108713a7SNeal Liu 119108713a7SNeal Liu #define HASH_SG_LAST_LIST BIT(31) 120108713a7SNeal Liu 121108713a7SNeal Liu #define CRYPTO_FLAGS_BUSY BIT(1) 122108713a7SNeal Liu 123108713a7SNeal Liu #define SHA_OP_UPDATE 1 124108713a7SNeal Liu #define SHA_OP_FINAL 2 125108713a7SNeal Liu 126108713a7SNeal Liu #define SHA_FLAGS_SHA1 BIT(0) 127108713a7SNeal Liu #define SHA_FLAGS_SHA224 BIT(1) 128108713a7SNeal Liu #define SHA_FLAGS_SHA256 BIT(2) 129108713a7SNeal Liu #define SHA_FLAGS_SHA384 BIT(3) 130108713a7SNeal Liu #define SHA_FLAGS_SHA512 BIT(4) 131108713a7SNeal Liu #define SHA_FLAGS_SHA512_224 BIT(5) 132108713a7SNeal Liu #define SHA_FLAGS_SHA512_256 BIT(6) 133108713a7SNeal Liu #define SHA_FLAGS_HMAC BIT(8) 134108713a7SNeal Liu #define SHA_FLAGS_FINUP BIT(9) 135108713a7SNeal Liu #define SHA_FLAGS_MASK (0xff) 136108713a7SNeal Liu 137108713a7SNeal Liu #define ASPEED_CRYPTO_SRC_DMA_BUF_LEN 0xa000 138108713a7SNeal Liu #define ASPEED_CRYPTO_DST_DMA_BUF_LEN 0xa000 139108713a7SNeal Liu #define ASPEED_CRYPTO_GCM_TAG_OFFSET 0x9ff0 140108713a7SNeal Liu #define ASPEED_HASH_SRC_DMA_BUF_LEN 0xa000 141108713a7SNeal Liu #define ASPEED_HASH_QUEUE_LENGTH 50 142108713a7SNeal Liu 14362f58b16SNeal Liu #define HACE_CMD_IV_REQUIRE (HACE_CMD_CBC | HACE_CMD_CFB | \ 14462f58b16SNeal Liu HACE_CMD_OFB | HACE_CMD_CTR) 14562f58b16SNeal Liu 146108713a7SNeal Liu struct aspeed_hace_dev; 147108713a7SNeal Liu 148108713a7SNeal Liu typedef int (*aspeed_hace_fn_t)(struct aspeed_hace_dev *); 149108713a7SNeal Liu 150108713a7SNeal Liu struct aspeed_sg_list { 151108713a7SNeal Liu __le32 len; 152108713a7SNeal Liu __le32 phy_addr; 153108713a7SNeal Liu }; 154108713a7SNeal Liu 155108713a7SNeal Liu struct aspeed_engine_hash { 156108713a7SNeal Liu struct tasklet_struct done_task; 157108713a7SNeal Liu unsigned long flags; 158108713a7SNeal Liu struct ahash_request *req; 159108713a7SNeal Liu 160108713a7SNeal Liu /* input buffer */ 161108713a7SNeal Liu void *ahash_src_addr; 162108713a7SNeal Liu dma_addr_t ahash_src_dma_addr; 163108713a7SNeal Liu 164108713a7SNeal Liu dma_addr_t src_dma; 165108713a7SNeal Liu dma_addr_t digest_dma; 166108713a7SNeal Liu 167108713a7SNeal Liu size_t src_length; 168108713a7SNeal Liu 169108713a7SNeal Liu /* callback func */ 170108713a7SNeal Liu aspeed_hace_fn_t resume; 171108713a7SNeal Liu aspeed_hace_fn_t dma_prepare; 172108713a7SNeal Liu }; 173108713a7SNeal Liu 174108713a7SNeal Liu struct aspeed_sha_hmac_ctx { 175108713a7SNeal Liu struct crypto_shash *shash; 176108713a7SNeal Liu u8 ipad[SHA512_BLOCK_SIZE]; 177108713a7SNeal Liu u8 opad[SHA512_BLOCK_SIZE]; 178108713a7SNeal Liu }; 179108713a7SNeal Liu 180108713a7SNeal Liu struct aspeed_sham_ctx { 181108713a7SNeal Liu struct crypto_engine_ctx enginectx; 182108713a7SNeal Liu 183108713a7SNeal Liu struct aspeed_hace_dev *hace_dev; 184108713a7SNeal Liu unsigned long flags; /* hmac flag */ 185108713a7SNeal Liu 186*f104b216SGustavo A. R. Silva struct aspeed_sha_hmac_ctx base[]; 187108713a7SNeal Liu }; 188108713a7SNeal Liu 189108713a7SNeal Liu struct aspeed_sham_reqctx { 190108713a7SNeal Liu unsigned long flags; /* final update flag should no use*/ 191108713a7SNeal Liu unsigned long op; /* final or update */ 192108713a7SNeal Liu u32 cmd; /* trigger cmd */ 193108713a7SNeal Liu 194108713a7SNeal Liu /* walk state */ 195108713a7SNeal Liu struct scatterlist *src_sg; 196108713a7SNeal Liu int src_nents; 197108713a7SNeal Liu unsigned int offset; /* offset in current sg */ 198108713a7SNeal Liu unsigned int total; /* per update length */ 199108713a7SNeal Liu 200108713a7SNeal Liu size_t digsize; 201108713a7SNeal Liu size_t block_size; 202108713a7SNeal Liu size_t ivsize; 203108713a7SNeal Liu const __be32 *sha_iv; 204108713a7SNeal Liu 205108713a7SNeal Liu /* remain data buffer */ 206108713a7SNeal Liu u8 buffer[SHA512_BLOCK_SIZE * 2]; 207108713a7SNeal Liu dma_addr_t buffer_dma_addr; 208108713a7SNeal Liu size_t bufcnt; /* buffer counter */ 209108713a7SNeal Liu 210108713a7SNeal Liu /* output buffer */ 211108713a7SNeal Liu u8 digest[SHA512_DIGEST_SIZE] __aligned(64); 212108713a7SNeal Liu dma_addr_t digest_dma_addr; 213108713a7SNeal Liu u64 digcnt[2]; 214108713a7SNeal Liu }; 215108713a7SNeal Liu 21662f58b16SNeal Liu struct aspeed_engine_crypto { 21762f58b16SNeal Liu struct tasklet_struct done_task; 21862f58b16SNeal Liu unsigned long flags; 21962f58b16SNeal Liu struct skcipher_request *req; 22062f58b16SNeal Liu 22162f58b16SNeal Liu /* context buffer */ 22262f58b16SNeal Liu void *cipher_ctx; 22362f58b16SNeal Liu dma_addr_t cipher_ctx_dma; 22462f58b16SNeal Liu 22562f58b16SNeal Liu /* input buffer, could be single/scatter-gather lists */ 22662f58b16SNeal Liu void *cipher_addr; 22762f58b16SNeal Liu dma_addr_t cipher_dma_addr; 22862f58b16SNeal Liu 22962f58b16SNeal Liu /* output buffer, only used in scatter-gather lists */ 23062f58b16SNeal Liu void *dst_sg_addr; 23162f58b16SNeal Liu dma_addr_t dst_sg_dma_addr; 23262f58b16SNeal Liu 23362f58b16SNeal Liu /* callback func */ 23462f58b16SNeal Liu aspeed_hace_fn_t resume; 23562f58b16SNeal Liu }; 23662f58b16SNeal Liu 23762f58b16SNeal Liu struct aspeed_cipher_ctx { 23862f58b16SNeal Liu struct crypto_engine_ctx enginectx; 23962f58b16SNeal Liu 24062f58b16SNeal Liu struct aspeed_hace_dev *hace_dev; 24162f58b16SNeal Liu int key_len; 24262f58b16SNeal Liu u8 key[AES_MAX_KEYLENGTH]; 24362f58b16SNeal Liu 24462f58b16SNeal Liu /* callback func */ 24562f58b16SNeal Liu aspeed_hace_fn_t start; 24662f58b16SNeal Liu 24762f58b16SNeal Liu struct crypto_skcipher *fallback_tfm; 24862f58b16SNeal Liu }; 24962f58b16SNeal Liu 25062f58b16SNeal Liu struct aspeed_cipher_reqctx { 25162f58b16SNeal Liu int enc_cmd; 25262f58b16SNeal Liu int src_nents; 25362f58b16SNeal Liu int dst_nents; 25462f58b16SNeal Liu 25562f58b16SNeal Liu struct skcipher_request fallback_req; /* keep at the end */ 25662f58b16SNeal Liu }; 25762f58b16SNeal Liu 258108713a7SNeal Liu struct aspeed_hace_dev { 259108713a7SNeal Liu void __iomem *regs; 260108713a7SNeal Liu struct device *dev; 261108713a7SNeal Liu int irq; 262108713a7SNeal Liu struct clk *clk; 263108713a7SNeal Liu unsigned long version; 264108713a7SNeal Liu 265108713a7SNeal Liu struct crypto_engine *crypt_engine_hash; 26662f58b16SNeal Liu struct crypto_engine *crypt_engine_crypto; 267108713a7SNeal Liu 268108713a7SNeal Liu struct aspeed_engine_hash hash_engine; 26962f58b16SNeal Liu struct aspeed_engine_crypto crypto_engine; 270108713a7SNeal Liu }; 271108713a7SNeal Liu 272108713a7SNeal Liu struct aspeed_hace_alg { 273108713a7SNeal Liu struct aspeed_hace_dev *hace_dev; 274108713a7SNeal Liu 275108713a7SNeal Liu const char *alg_base; 276108713a7SNeal Liu 277108713a7SNeal Liu union { 278108713a7SNeal Liu struct skcipher_alg skcipher; 279108713a7SNeal Liu struct ahash_alg ahash; 280108713a7SNeal Liu } alg; 281108713a7SNeal Liu }; 282108713a7SNeal Liu 283108713a7SNeal Liu enum aspeed_version { 284108713a7SNeal Liu AST2500_VERSION = 5, 285108713a7SNeal Liu AST2600_VERSION 286108713a7SNeal Liu }; 287108713a7SNeal Liu 288108713a7SNeal Liu #define ast_hace_write(hace, val, offset) \ 289108713a7SNeal Liu writel((val), (hace)->regs + (offset)) 290108713a7SNeal Liu #define ast_hace_read(hace, offset) \ 291108713a7SNeal Liu readl((hace)->regs + (offset)) 292108713a7SNeal Liu 293108713a7SNeal Liu void aspeed_register_hace_hash_algs(struct aspeed_hace_dev *hace_dev); 294108713a7SNeal Liu void aspeed_unregister_hace_hash_algs(struct aspeed_hace_dev *hace_dev); 29562f58b16SNeal Liu void aspeed_register_hace_crypto_algs(struct aspeed_hace_dev *hace_dev); 29662f58b16SNeal Liu void aspeed_unregister_hace_crypto_algs(struct aspeed_hace_dev *hace_dev); 297108713a7SNeal Liu 298108713a7SNeal Liu #endif 299