162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 262306a36Sopenharmony_ci/* Copyright (C) 2012-2019 ARM Limited (or its affiliates). */ 362306a36Sopenharmony_ci 462306a36Sopenharmony_ci#include <linux/kernel.h> 562306a36Sopenharmony_ci#include <linux/module.h> 662306a36Sopenharmony_ci#include <crypto/algapi.h> 762306a36Sopenharmony_ci#include <crypto/internal/skcipher.h> 862306a36Sopenharmony_ci#include <crypto/internal/des.h> 962306a36Sopenharmony_ci#include <crypto/xts.h> 1062306a36Sopenharmony_ci#include <crypto/sm4.h> 1162306a36Sopenharmony_ci#include <crypto/scatterwalk.h> 1262306a36Sopenharmony_ci 1362306a36Sopenharmony_ci#include "cc_driver.h" 1462306a36Sopenharmony_ci#include "cc_lli_defs.h" 1562306a36Sopenharmony_ci#include "cc_buffer_mgr.h" 1662306a36Sopenharmony_ci#include "cc_cipher.h" 1762306a36Sopenharmony_ci#include "cc_request_mgr.h" 1862306a36Sopenharmony_ci 1962306a36Sopenharmony_ci#define MAX_SKCIPHER_SEQ_LEN 6 2062306a36Sopenharmony_ci 2162306a36Sopenharmony_ci#define template_skcipher template_u.skcipher 2262306a36Sopenharmony_ci 2362306a36Sopenharmony_cistruct cc_user_key_info { 2462306a36Sopenharmony_ci u8 *key; 2562306a36Sopenharmony_ci dma_addr_t key_dma_addr; 2662306a36Sopenharmony_ci}; 2762306a36Sopenharmony_ci 2862306a36Sopenharmony_cistruct cc_hw_key_info { 2962306a36Sopenharmony_ci enum cc_hw_crypto_key key1_slot; 3062306a36Sopenharmony_ci enum cc_hw_crypto_key key2_slot; 3162306a36Sopenharmony_ci}; 3262306a36Sopenharmony_ci 3362306a36Sopenharmony_cistruct cc_cpp_key_info { 3462306a36Sopenharmony_ci u8 slot; 3562306a36Sopenharmony_ci enum cc_cpp_alg alg; 3662306a36Sopenharmony_ci}; 3762306a36Sopenharmony_ci 3862306a36Sopenharmony_cienum cc_key_type { 3962306a36Sopenharmony_ci CC_UNPROTECTED_KEY, /* User key */ 4062306a36Sopenharmony_ci CC_HW_PROTECTED_KEY, /* HW (FDE) key */ 4162306a36Sopenharmony_ci CC_POLICY_PROTECTED_KEY, /* CPP key */ 4262306a36Sopenharmony_ci CC_INVALID_PROTECTED_KEY /* Invalid key */ 4362306a36Sopenharmony_ci}; 4462306a36Sopenharmony_ci 4562306a36Sopenharmony_cistruct cc_cipher_ctx { 4662306a36Sopenharmony_ci struct cc_drvdata *drvdata; 4762306a36Sopenharmony_ci int keylen; 4862306a36Sopenharmony_ci int cipher_mode; 4962306a36Sopenharmony_ci int flow_mode; 5062306a36Sopenharmony_ci unsigned int flags; 5162306a36Sopenharmony_ci enum cc_key_type key_type; 5262306a36Sopenharmony_ci struct cc_user_key_info user; 5362306a36Sopenharmony_ci union { 5462306a36Sopenharmony_ci struct cc_hw_key_info hw; 5562306a36Sopenharmony_ci struct cc_cpp_key_info cpp; 5662306a36Sopenharmony_ci }; 5762306a36Sopenharmony_ci struct crypto_shash *shash_tfm; 5862306a36Sopenharmony_ci struct crypto_skcipher *fallback_tfm; 5962306a36Sopenharmony_ci bool fallback_on; 6062306a36Sopenharmony_ci}; 6162306a36Sopenharmony_ci 6262306a36Sopenharmony_cistatic void cc_cipher_complete(struct device *dev, void *cc_req, int err); 6362306a36Sopenharmony_ci 6462306a36Sopenharmony_cistatic inline enum cc_key_type cc_key_type(struct crypto_tfm *tfm) 6562306a36Sopenharmony_ci{ 6662306a36Sopenharmony_ci struct cc_cipher_ctx *ctx_p = crypto_tfm_ctx(tfm); 6762306a36Sopenharmony_ci 6862306a36Sopenharmony_ci return ctx_p->key_type; 6962306a36Sopenharmony_ci} 7062306a36Sopenharmony_ci 7162306a36Sopenharmony_cistatic int validate_keys_sizes(struct cc_cipher_ctx *ctx_p, u32 size) 7262306a36Sopenharmony_ci{ 7362306a36Sopenharmony_ci switch (ctx_p->flow_mode) { 7462306a36Sopenharmony_ci case S_DIN_to_AES: 7562306a36Sopenharmony_ci switch (size) { 7662306a36Sopenharmony_ci case CC_AES_128_BIT_KEY_SIZE: 7762306a36Sopenharmony_ci case CC_AES_192_BIT_KEY_SIZE: 7862306a36Sopenharmony_ci if (ctx_p->cipher_mode != DRV_CIPHER_XTS) 7962306a36Sopenharmony_ci return 0; 8062306a36Sopenharmony_ci break; 8162306a36Sopenharmony_ci case CC_AES_256_BIT_KEY_SIZE: 8262306a36Sopenharmony_ci return 0; 8362306a36Sopenharmony_ci case (CC_AES_192_BIT_KEY_SIZE * 2): 8462306a36Sopenharmony_ci case (CC_AES_256_BIT_KEY_SIZE * 2): 8562306a36Sopenharmony_ci if (ctx_p->cipher_mode == DRV_CIPHER_XTS || 8662306a36Sopenharmony_ci ctx_p->cipher_mode == DRV_CIPHER_ESSIV) 8762306a36Sopenharmony_ci return 0; 8862306a36Sopenharmony_ci break; 8962306a36Sopenharmony_ci default: 9062306a36Sopenharmony_ci break; 9162306a36Sopenharmony_ci } 9262306a36Sopenharmony_ci break; 9362306a36Sopenharmony_ci case S_DIN_to_DES: 9462306a36Sopenharmony_ci if (size == DES3_EDE_KEY_SIZE || size == DES_KEY_SIZE) 9562306a36Sopenharmony_ci return 0; 9662306a36Sopenharmony_ci break; 9762306a36Sopenharmony_ci case S_DIN_to_SM4: 9862306a36Sopenharmony_ci if (size == SM4_KEY_SIZE) 9962306a36Sopenharmony_ci return 0; 10062306a36Sopenharmony_ci break; 10162306a36Sopenharmony_ci default: 10262306a36Sopenharmony_ci break; 10362306a36Sopenharmony_ci } 10462306a36Sopenharmony_ci return -EINVAL; 10562306a36Sopenharmony_ci} 10662306a36Sopenharmony_ci 10762306a36Sopenharmony_cistatic int validate_data_size(struct cc_cipher_ctx *ctx_p, 10862306a36Sopenharmony_ci unsigned int size) 10962306a36Sopenharmony_ci{ 11062306a36Sopenharmony_ci switch (ctx_p->flow_mode) { 11162306a36Sopenharmony_ci case S_DIN_to_AES: 11262306a36Sopenharmony_ci switch (ctx_p->cipher_mode) { 11362306a36Sopenharmony_ci case DRV_CIPHER_XTS: 11462306a36Sopenharmony_ci case DRV_CIPHER_CBC_CTS: 11562306a36Sopenharmony_ci if (size >= AES_BLOCK_SIZE) 11662306a36Sopenharmony_ci return 0; 11762306a36Sopenharmony_ci break; 11862306a36Sopenharmony_ci case DRV_CIPHER_OFB: 11962306a36Sopenharmony_ci case DRV_CIPHER_CTR: 12062306a36Sopenharmony_ci return 0; 12162306a36Sopenharmony_ci case DRV_CIPHER_ECB: 12262306a36Sopenharmony_ci case DRV_CIPHER_CBC: 12362306a36Sopenharmony_ci case DRV_CIPHER_ESSIV: 12462306a36Sopenharmony_ci if (IS_ALIGNED(size, AES_BLOCK_SIZE)) 12562306a36Sopenharmony_ci return 0; 12662306a36Sopenharmony_ci break; 12762306a36Sopenharmony_ci default: 12862306a36Sopenharmony_ci break; 12962306a36Sopenharmony_ci } 13062306a36Sopenharmony_ci break; 13162306a36Sopenharmony_ci case S_DIN_to_DES: 13262306a36Sopenharmony_ci if (IS_ALIGNED(size, DES_BLOCK_SIZE)) 13362306a36Sopenharmony_ci return 0; 13462306a36Sopenharmony_ci break; 13562306a36Sopenharmony_ci case S_DIN_to_SM4: 13662306a36Sopenharmony_ci switch (ctx_p->cipher_mode) { 13762306a36Sopenharmony_ci case DRV_CIPHER_CTR: 13862306a36Sopenharmony_ci return 0; 13962306a36Sopenharmony_ci case DRV_CIPHER_ECB: 14062306a36Sopenharmony_ci case DRV_CIPHER_CBC: 14162306a36Sopenharmony_ci if (IS_ALIGNED(size, SM4_BLOCK_SIZE)) 14262306a36Sopenharmony_ci return 0; 14362306a36Sopenharmony_ci break; 14462306a36Sopenharmony_ci default: 14562306a36Sopenharmony_ci break; 14662306a36Sopenharmony_ci } 14762306a36Sopenharmony_ci break; 14862306a36Sopenharmony_ci default: 14962306a36Sopenharmony_ci break; 15062306a36Sopenharmony_ci } 15162306a36Sopenharmony_ci return -EINVAL; 15262306a36Sopenharmony_ci} 15362306a36Sopenharmony_ci 15462306a36Sopenharmony_cistatic int cc_cipher_init(struct crypto_tfm *tfm) 15562306a36Sopenharmony_ci{ 15662306a36Sopenharmony_ci struct cc_cipher_ctx *ctx_p = crypto_tfm_ctx(tfm); 15762306a36Sopenharmony_ci struct cc_crypto_alg *cc_alg = 15862306a36Sopenharmony_ci container_of(tfm->__crt_alg, struct cc_crypto_alg, 15962306a36Sopenharmony_ci skcipher_alg.base); 16062306a36Sopenharmony_ci struct device *dev = drvdata_to_dev(cc_alg->drvdata); 16162306a36Sopenharmony_ci unsigned int max_key_buf_size = cc_alg->skcipher_alg.max_keysize; 16262306a36Sopenharmony_ci unsigned int fallback_req_size = 0; 16362306a36Sopenharmony_ci 16462306a36Sopenharmony_ci dev_dbg(dev, "Initializing context @%p for %s\n", ctx_p, 16562306a36Sopenharmony_ci crypto_tfm_alg_name(tfm)); 16662306a36Sopenharmony_ci 16762306a36Sopenharmony_ci ctx_p->cipher_mode = cc_alg->cipher_mode; 16862306a36Sopenharmony_ci ctx_p->flow_mode = cc_alg->flow_mode; 16962306a36Sopenharmony_ci ctx_p->drvdata = cc_alg->drvdata; 17062306a36Sopenharmony_ci 17162306a36Sopenharmony_ci if (ctx_p->cipher_mode == DRV_CIPHER_ESSIV) { 17262306a36Sopenharmony_ci const char *name = crypto_tfm_alg_name(tfm); 17362306a36Sopenharmony_ci 17462306a36Sopenharmony_ci /* Alloc hash tfm for essiv */ 17562306a36Sopenharmony_ci ctx_p->shash_tfm = crypto_alloc_shash("sha256", 0, 0); 17662306a36Sopenharmony_ci if (IS_ERR(ctx_p->shash_tfm)) { 17762306a36Sopenharmony_ci dev_err(dev, "Error allocating hash tfm for ESSIV.\n"); 17862306a36Sopenharmony_ci return PTR_ERR(ctx_p->shash_tfm); 17962306a36Sopenharmony_ci } 18062306a36Sopenharmony_ci max_key_buf_size <<= 1; 18162306a36Sopenharmony_ci 18262306a36Sopenharmony_ci /* Alloc fallabck tfm or essiv when key size != 256 bit */ 18362306a36Sopenharmony_ci ctx_p->fallback_tfm = 18462306a36Sopenharmony_ci crypto_alloc_skcipher(name, 0, CRYPTO_ALG_NEED_FALLBACK | CRYPTO_ALG_ASYNC); 18562306a36Sopenharmony_ci 18662306a36Sopenharmony_ci if (IS_ERR(ctx_p->fallback_tfm)) { 18762306a36Sopenharmony_ci /* Note we're still allowing registration with no fallback since it's 18862306a36Sopenharmony_ci * better to have most modes supported than none at all. 18962306a36Sopenharmony_ci */ 19062306a36Sopenharmony_ci dev_warn(dev, "Error allocating fallback algo %s. Some modes may be available.\n", 19162306a36Sopenharmony_ci name); 19262306a36Sopenharmony_ci ctx_p->fallback_tfm = NULL; 19362306a36Sopenharmony_ci } else { 19462306a36Sopenharmony_ci fallback_req_size = crypto_skcipher_reqsize(ctx_p->fallback_tfm); 19562306a36Sopenharmony_ci } 19662306a36Sopenharmony_ci } 19762306a36Sopenharmony_ci 19862306a36Sopenharmony_ci crypto_skcipher_set_reqsize(__crypto_skcipher_cast(tfm), 19962306a36Sopenharmony_ci sizeof(struct cipher_req_ctx) + fallback_req_size); 20062306a36Sopenharmony_ci 20162306a36Sopenharmony_ci /* Allocate key buffer, cache line aligned */ 20262306a36Sopenharmony_ci ctx_p->user.key = kzalloc(max_key_buf_size, GFP_KERNEL); 20362306a36Sopenharmony_ci if (!ctx_p->user.key) 20462306a36Sopenharmony_ci goto free_fallback; 20562306a36Sopenharmony_ci 20662306a36Sopenharmony_ci dev_dbg(dev, "Allocated key buffer in context. key=@%p\n", 20762306a36Sopenharmony_ci ctx_p->user.key); 20862306a36Sopenharmony_ci 20962306a36Sopenharmony_ci /* Map key buffer */ 21062306a36Sopenharmony_ci ctx_p->user.key_dma_addr = dma_map_single(dev, ctx_p->user.key, 21162306a36Sopenharmony_ci max_key_buf_size, 21262306a36Sopenharmony_ci DMA_TO_DEVICE); 21362306a36Sopenharmony_ci if (dma_mapping_error(dev, ctx_p->user.key_dma_addr)) { 21462306a36Sopenharmony_ci dev_err(dev, "Mapping Key %u B at va=%pK for DMA failed\n", 21562306a36Sopenharmony_ci max_key_buf_size, ctx_p->user.key); 21662306a36Sopenharmony_ci goto free_key; 21762306a36Sopenharmony_ci } 21862306a36Sopenharmony_ci dev_dbg(dev, "Mapped key %u B at va=%pK to dma=%pad\n", 21962306a36Sopenharmony_ci max_key_buf_size, ctx_p->user.key, &ctx_p->user.key_dma_addr); 22062306a36Sopenharmony_ci 22162306a36Sopenharmony_ci return 0; 22262306a36Sopenharmony_ci 22362306a36Sopenharmony_cifree_key: 22462306a36Sopenharmony_ci kfree(ctx_p->user.key); 22562306a36Sopenharmony_cifree_fallback: 22662306a36Sopenharmony_ci crypto_free_skcipher(ctx_p->fallback_tfm); 22762306a36Sopenharmony_ci crypto_free_shash(ctx_p->shash_tfm); 22862306a36Sopenharmony_ci 22962306a36Sopenharmony_ci return -ENOMEM; 23062306a36Sopenharmony_ci} 23162306a36Sopenharmony_ci 23262306a36Sopenharmony_cistatic void cc_cipher_exit(struct crypto_tfm *tfm) 23362306a36Sopenharmony_ci{ 23462306a36Sopenharmony_ci struct crypto_alg *alg = tfm->__crt_alg; 23562306a36Sopenharmony_ci struct cc_crypto_alg *cc_alg = 23662306a36Sopenharmony_ci container_of(alg, struct cc_crypto_alg, 23762306a36Sopenharmony_ci skcipher_alg.base); 23862306a36Sopenharmony_ci unsigned int max_key_buf_size = cc_alg->skcipher_alg.max_keysize; 23962306a36Sopenharmony_ci struct cc_cipher_ctx *ctx_p = crypto_tfm_ctx(tfm); 24062306a36Sopenharmony_ci struct device *dev = drvdata_to_dev(ctx_p->drvdata); 24162306a36Sopenharmony_ci 24262306a36Sopenharmony_ci dev_dbg(dev, "Clearing context @%p for %s\n", 24362306a36Sopenharmony_ci crypto_tfm_ctx(tfm), crypto_tfm_alg_name(tfm)); 24462306a36Sopenharmony_ci 24562306a36Sopenharmony_ci if (ctx_p->cipher_mode == DRV_CIPHER_ESSIV) { 24662306a36Sopenharmony_ci /* Free hash tfm for essiv */ 24762306a36Sopenharmony_ci crypto_free_shash(ctx_p->shash_tfm); 24862306a36Sopenharmony_ci ctx_p->shash_tfm = NULL; 24962306a36Sopenharmony_ci crypto_free_skcipher(ctx_p->fallback_tfm); 25062306a36Sopenharmony_ci ctx_p->fallback_tfm = NULL; 25162306a36Sopenharmony_ci } 25262306a36Sopenharmony_ci 25362306a36Sopenharmony_ci /* Unmap key buffer */ 25462306a36Sopenharmony_ci dma_unmap_single(dev, ctx_p->user.key_dma_addr, max_key_buf_size, 25562306a36Sopenharmony_ci DMA_TO_DEVICE); 25662306a36Sopenharmony_ci dev_dbg(dev, "Unmapped key buffer key_dma_addr=%pad\n", 25762306a36Sopenharmony_ci &ctx_p->user.key_dma_addr); 25862306a36Sopenharmony_ci 25962306a36Sopenharmony_ci /* Free key buffer in context */ 26062306a36Sopenharmony_ci dev_dbg(dev, "Free key buffer in context. key=@%p\n", ctx_p->user.key); 26162306a36Sopenharmony_ci kfree_sensitive(ctx_p->user.key); 26262306a36Sopenharmony_ci} 26362306a36Sopenharmony_ci 26462306a36Sopenharmony_cistruct tdes_keys { 26562306a36Sopenharmony_ci u8 key1[DES_KEY_SIZE]; 26662306a36Sopenharmony_ci u8 key2[DES_KEY_SIZE]; 26762306a36Sopenharmony_ci u8 key3[DES_KEY_SIZE]; 26862306a36Sopenharmony_ci}; 26962306a36Sopenharmony_ci 27062306a36Sopenharmony_cistatic enum cc_hw_crypto_key cc_slot_to_hw_key(u8 slot_num) 27162306a36Sopenharmony_ci{ 27262306a36Sopenharmony_ci switch (slot_num) { 27362306a36Sopenharmony_ci case 0: 27462306a36Sopenharmony_ci return KFDE0_KEY; 27562306a36Sopenharmony_ci case 1: 27662306a36Sopenharmony_ci return KFDE1_KEY; 27762306a36Sopenharmony_ci case 2: 27862306a36Sopenharmony_ci return KFDE2_KEY; 27962306a36Sopenharmony_ci case 3: 28062306a36Sopenharmony_ci return KFDE3_KEY; 28162306a36Sopenharmony_ci } 28262306a36Sopenharmony_ci return END_OF_KEYS; 28362306a36Sopenharmony_ci} 28462306a36Sopenharmony_ci 28562306a36Sopenharmony_cistatic u8 cc_slot_to_cpp_key(u8 slot_num) 28662306a36Sopenharmony_ci{ 28762306a36Sopenharmony_ci return (slot_num - CC_FIRST_CPP_KEY_SLOT); 28862306a36Sopenharmony_ci} 28962306a36Sopenharmony_ci 29062306a36Sopenharmony_cistatic inline enum cc_key_type cc_slot_to_key_type(u8 slot_num) 29162306a36Sopenharmony_ci{ 29262306a36Sopenharmony_ci if (slot_num >= CC_FIRST_HW_KEY_SLOT && slot_num <= CC_LAST_HW_KEY_SLOT) 29362306a36Sopenharmony_ci return CC_HW_PROTECTED_KEY; 29462306a36Sopenharmony_ci else if (slot_num >= CC_FIRST_CPP_KEY_SLOT && 29562306a36Sopenharmony_ci slot_num <= CC_LAST_CPP_KEY_SLOT) 29662306a36Sopenharmony_ci return CC_POLICY_PROTECTED_KEY; 29762306a36Sopenharmony_ci else 29862306a36Sopenharmony_ci return CC_INVALID_PROTECTED_KEY; 29962306a36Sopenharmony_ci} 30062306a36Sopenharmony_ci 30162306a36Sopenharmony_cistatic int cc_cipher_sethkey(struct crypto_skcipher *sktfm, const u8 *key, 30262306a36Sopenharmony_ci unsigned int keylen) 30362306a36Sopenharmony_ci{ 30462306a36Sopenharmony_ci struct crypto_tfm *tfm = crypto_skcipher_tfm(sktfm); 30562306a36Sopenharmony_ci struct cc_cipher_ctx *ctx_p = crypto_tfm_ctx(tfm); 30662306a36Sopenharmony_ci struct device *dev = drvdata_to_dev(ctx_p->drvdata); 30762306a36Sopenharmony_ci struct cc_hkey_info hki; 30862306a36Sopenharmony_ci 30962306a36Sopenharmony_ci dev_dbg(dev, "Setting HW key in context @%p for %s. keylen=%u\n", 31062306a36Sopenharmony_ci ctx_p, crypto_tfm_alg_name(tfm), keylen); 31162306a36Sopenharmony_ci dump_byte_array("key", key, keylen); 31262306a36Sopenharmony_ci 31362306a36Sopenharmony_ci /* STAT_PHASE_0: Init and sanity checks */ 31462306a36Sopenharmony_ci 31562306a36Sopenharmony_ci /* This check the size of the protected key token */ 31662306a36Sopenharmony_ci if (keylen != sizeof(hki)) { 31762306a36Sopenharmony_ci dev_err(dev, "Unsupported protected key size %d.\n", keylen); 31862306a36Sopenharmony_ci return -EINVAL; 31962306a36Sopenharmony_ci } 32062306a36Sopenharmony_ci 32162306a36Sopenharmony_ci memcpy(&hki, key, keylen); 32262306a36Sopenharmony_ci 32362306a36Sopenharmony_ci /* The real key len for crypto op is the size of the HW key 32462306a36Sopenharmony_ci * referenced by the HW key slot, not the hardware key token 32562306a36Sopenharmony_ci */ 32662306a36Sopenharmony_ci keylen = hki.keylen; 32762306a36Sopenharmony_ci 32862306a36Sopenharmony_ci if (validate_keys_sizes(ctx_p, keylen)) { 32962306a36Sopenharmony_ci dev_dbg(dev, "Unsupported key size %d.\n", keylen); 33062306a36Sopenharmony_ci return -EINVAL; 33162306a36Sopenharmony_ci } 33262306a36Sopenharmony_ci 33362306a36Sopenharmony_ci ctx_p->keylen = keylen; 33462306a36Sopenharmony_ci ctx_p->fallback_on = false; 33562306a36Sopenharmony_ci 33662306a36Sopenharmony_ci switch (cc_slot_to_key_type(hki.hw_key1)) { 33762306a36Sopenharmony_ci case CC_HW_PROTECTED_KEY: 33862306a36Sopenharmony_ci if (ctx_p->flow_mode == S_DIN_to_SM4) { 33962306a36Sopenharmony_ci dev_err(dev, "Only AES HW protected keys are supported\n"); 34062306a36Sopenharmony_ci return -EINVAL; 34162306a36Sopenharmony_ci } 34262306a36Sopenharmony_ci 34362306a36Sopenharmony_ci ctx_p->hw.key1_slot = cc_slot_to_hw_key(hki.hw_key1); 34462306a36Sopenharmony_ci if (ctx_p->hw.key1_slot == END_OF_KEYS) { 34562306a36Sopenharmony_ci dev_err(dev, "Unsupported hw key1 number (%d)\n", 34662306a36Sopenharmony_ci hki.hw_key1); 34762306a36Sopenharmony_ci return -EINVAL; 34862306a36Sopenharmony_ci } 34962306a36Sopenharmony_ci 35062306a36Sopenharmony_ci if (ctx_p->cipher_mode == DRV_CIPHER_XTS || 35162306a36Sopenharmony_ci ctx_p->cipher_mode == DRV_CIPHER_ESSIV) { 35262306a36Sopenharmony_ci if (hki.hw_key1 == hki.hw_key2) { 35362306a36Sopenharmony_ci dev_err(dev, "Illegal hw key numbers (%d,%d)\n", 35462306a36Sopenharmony_ci hki.hw_key1, hki.hw_key2); 35562306a36Sopenharmony_ci return -EINVAL; 35662306a36Sopenharmony_ci } 35762306a36Sopenharmony_ci 35862306a36Sopenharmony_ci ctx_p->hw.key2_slot = cc_slot_to_hw_key(hki.hw_key2); 35962306a36Sopenharmony_ci if (ctx_p->hw.key2_slot == END_OF_KEYS) { 36062306a36Sopenharmony_ci dev_err(dev, "Unsupported hw key2 number (%d)\n", 36162306a36Sopenharmony_ci hki.hw_key2); 36262306a36Sopenharmony_ci return -EINVAL; 36362306a36Sopenharmony_ci } 36462306a36Sopenharmony_ci } 36562306a36Sopenharmony_ci 36662306a36Sopenharmony_ci ctx_p->key_type = CC_HW_PROTECTED_KEY; 36762306a36Sopenharmony_ci dev_dbg(dev, "HW protected key %d/%d set\n.", 36862306a36Sopenharmony_ci ctx_p->hw.key1_slot, ctx_p->hw.key2_slot); 36962306a36Sopenharmony_ci break; 37062306a36Sopenharmony_ci 37162306a36Sopenharmony_ci case CC_POLICY_PROTECTED_KEY: 37262306a36Sopenharmony_ci if (ctx_p->drvdata->hw_rev < CC_HW_REV_713) { 37362306a36Sopenharmony_ci dev_err(dev, "CPP keys not supported in this hardware revision.\n"); 37462306a36Sopenharmony_ci return -EINVAL; 37562306a36Sopenharmony_ci } 37662306a36Sopenharmony_ci 37762306a36Sopenharmony_ci if (ctx_p->cipher_mode != DRV_CIPHER_CBC && 37862306a36Sopenharmony_ci ctx_p->cipher_mode != DRV_CIPHER_CTR) { 37962306a36Sopenharmony_ci dev_err(dev, "CPP keys only supported in CBC or CTR modes.\n"); 38062306a36Sopenharmony_ci return -EINVAL; 38162306a36Sopenharmony_ci } 38262306a36Sopenharmony_ci 38362306a36Sopenharmony_ci ctx_p->cpp.slot = cc_slot_to_cpp_key(hki.hw_key1); 38462306a36Sopenharmony_ci if (ctx_p->flow_mode == S_DIN_to_AES) 38562306a36Sopenharmony_ci ctx_p->cpp.alg = CC_CPP_AES; 38662306a36Sopenharmony_ci else /* Must be SM4 since due to sethkey registration */ 38762306a36Sopenharmony_ci ctx_p->cpp.alg = CC_CPP_SM4; 38862306a36Sopenharmony_ci ctx_p->key_type = CC_POLICY_PROTECTED_KEY; 38962306a36Sopenharmony_ci dev_dbg(dev, "policy protected key alg: %d slot: %d.\n", 39062306a36Sopenharmony_ci ctx_p->cpp.alg, ctx_p->cpp.slot); 39162306a36Sopenharmony_ci break; 39262306a36Sopenharmony_ci 39362306a36Sopenharmony_ci default: 39462306a36Sopenharmony_ci dev_err(dev, "Unsupported protected key (%d)\n", hki.hw_key1); 39562306a36Sopenharmony_ci return -EINVAL; 39662306a36Sopenharmony_ci } 39762306a36Sopenharmony_ci 39862306a36Sopenharmony_ci return 0; 39962306a36Sopenharmony_ci} 40062306a36Sopenharmony_ci 40162306a36Sopenharmony_cistatic int cc_cipher_setkey(struct crypto_skcipher *sktfm, const u8 *key, 40262306a36Sopenharmony_ci unsigned int keylen) 40362306a36Sopenharmony_ci{ 40462306a36Sopenharmony_ci struct crypto_tfm *tfm = crypto_skcipher_tfm(sktfm); 40562306a36Sopenharmony_ci struct cc_cipher_ctx *ctx_p = crypto_tfm_ctx(tfm); 40662306a36Sopenharmony_ci struct device *dev = drvdata_to_dev(ctx_p->drvdata); 40762306a36Sopenharmony_ci struct cc_crypto_alg *cc_alg = 40862306a36Sopenharmony_ci container_of(tfm->__crt_alg, struct cc_crypto_alg, 40962306a36Sopenharmony_ci skcipher_alg.base); 41062306a36Sopenharmony_ci unsigned int max_key_buf_size = cc_alg->skcipher_alg.max_keysize; 41162306a36Sopenharmony_ci 41262306a36Sopenharmony_ci dev_dbg(dev, "Setting key in context @%p for %s. keylen=%u\n", 41362306a36Sopenharmony_ci ctx_p, crypto_tfm_alg_name(tfm), keylen); 41462306a36Sopenharmony_ci dump_byte_array("key", key, keylen); 41562306a36Sopenharmony_ci 41662306a36Sopenharmony_ci /* STAT_PHASE_0: Init and sanity checks */ 41762306a36Sopenharmony_ci 41862306a36Sopenharmony_ci if (validate_keys_sizes(ctx_p, keylen)) { 41962306a36Sopenharmony_ci dev_dbg(dev, "Invalid key size %d.\n", keylen); 42062306a36Sopenharmony_ci return -EINVAL; 42162306a36Sopenharmony_ci } 42262306a36Sopenharmony_ci 42362306a36Sopenharmony_ci if (ctx_p->cipher_mode == DRV_CIPHER_ESSIV) { 42462306a36Sopenharmony_ci 42562306a36Sopenharmony_ci /* We only support 256 bit ESSIV-CBC-AES keys */ 42662306a36Sopenharmony_ci if (keylen != AES_KEYSIZE_256) { 42762306a36Sopenharmony_ci unsigned int flags = crypto_tfm_get_flags(tfm) & CRYPTO_TFM_REQ_MASK; 42862306a36Sopenharmony_ci 42962306a36Sopenharmony_ci if (likely(ctx_p->fallback_tfm)) { 43062306a36Sopenharmony_ci ctx_p->fallback_on = true; 43162306a36Sopenharmony_ci crypto_skcipher_clear_flags(ctx_p->fallback_tfm, 43262306a36Sopenharmony_ci CRYPTO_TFM_REQ_MASK); 43362306a36Sopenharmony_ci crypto_skcipher_clear_flags(ctx_p->fallback_tfm, flags); 43462306a36Sopenharmony_ci return crypto_skcipher_setkey(ctx_p->fallback_tfm, key, keylen); 43562306a36Sopenharmony_ci } 43662306a36Sopenharmony_ci 43762306a36Sopenharmony_ci dev_dbg(dev, "Unsupported key size %d and no fallback.\n", keylen); 43862306a36Sopenharmony_ci return -EINVAL; 43962306a36Sopenharmony_ci } 44062306a36Sopenharmony_ci 44162306a36Sopenharmony_ci /* Internal ESSIV key buffer is double sized */ 44262306a36Sopenharmony_ci max_key_buf_size <<= 1; 44362306a36Sopenharmony_ci } 44462306a36Sopenharmony_ci 44562306a36Sopenharmony_ci ctx_p->fallback_on = false; 44662306a36Sopenharmony_ci ctx_p->key_type = CC_UNPROTECTED_KEY; 44762306a36Sopenharmony_ci 44862306a36Sopenharmony_ci /* 44962306a36Sopenharmony_ci * Verify DES weak keys 45062306a36Sopenharmony_ci * Note that we're dropping the expanded key since the 45162306a36Sopenharmony_ci * HW does the expansion on its own. 45262306a36Sopenharmony_ci */ 45362306a36Sopenharmony_ci if (ctx_p->flow_mode == S_DIN_to_DES) { 45462306a36Sopenharmony_ci if ((keylen == DES3_EDE_KEY_SIZE && 45562306a36Sopenharmony_ci verify_skcipher_des3_key(sktfm, key)) || 45662306a36Sopenharmony_ci verify_skcipher_des_key(sktfm, key)) { 45762306a36Sopenharmony_ci dev_dbg(dev, "weak DES key"); 45862306a36Sopenharmony_ci return -EINVAL; 45962306a36Sopenharmony_ci } 46062306a36Sopenharmony_ci } 46162306a36Sopenharmony_ci 46262306a36Sopenharmony_ci if (ctx_p->cipher_mode == DRV_CIPHER_XTS && 46362306a36Sopenharmony_ci xts_verify_key(sktfm, key, keylen)) { 46462306a36Sopenharmony_ci dev_dbg(dev, "weak XTS key"); 46562306a36Sopenharmony_ci return -EINVAL; 46662306a36Sopenharmony_ci } 46762306a36Sopenharmony_ci 46862306a36Sopenharmony_ci /* STAT_PHASE_1: Copy key to ctx */ 46962306a36Sopenharmony_ci dma_sync_single_for_cpu(dev, ctx_p->user.key_dma_addr, 47062306a36Sopenharmony_ci max_key_buf_size, DMA_TO_DEVICE); 47162306a36Sopenharmony_ci 47262306a36Sopenharmony_ci memcpy(ctx_p->user.key, key, keylen); 47362306a36Sopenharmony_ci 47462306a36Sopenharmony_ci if (ctx_p->cipher_mode == DRV_CIPHER_ESSIV) { 47562306a36Sopenharmony_ci /* sha256 for key2 - use sw implementation */ 47662306a36Sopenharmony_ci int err; 47762306a36Sopenharmony_ci 47862306a36Sopenharmony_ci err = crypto_shash_tfm_digest(ctx_p->shash_tfm, 47962306a36Sopenharmony_ci ctx_p->user.key, keylen, 48062306a36Sopenharmony_ci ctx_p->user.key + keylen); 48162306a36Sopenharmony_ci if (err) { 48262306a36Sopenharmony_ci dev_err(dev, "Failed to hash ESSIV key.\n"); 48362306a36Sopenharmony_ci return err; 48462306a36Sopenharmony_ci } 48562306a36Sopenharmony_ci 48662306a36Sopenharmony_ci keylen <<= 1; 48762306a36Sopenharmony_ci } 48862306a36Sopenharmony_ci dma_sync_single_for_device(dev, ctx_p->user.key_dma_addr, 48962306a36Sopenharmony_ci max_key_buf_size, DMA_TO_DEVICE); 49062306a36Sopenharmony_ci ctx_p->keylen = keylen; 49162306a36Sopenharmony_ci 49262306a36Sopenharmony_ci dev_dbg(dev, "return safely"); 49362306a36Sopenharmony_ci return 0; 49462306a36Sopenharmony_ci} 49562306a36Sopenharmony_ci 49662306a36Sopenharmony_cistatic int cc_out_setup_mode(struct cc_cipher_ctx *ctx_p) 49762306a36Sopenharmony_ci{ 49862306a36Sopenharmony_ci switch (ctx_p->flow_mode) { 49962306a36Sopenharmony_ci case S_DIN_to_AES: 50062306a36Sopenharmony_ci return S_AES_to_DOUT; 50162306a36Sopenharmony_ci case S_DIN_to_DES: 50262306a36Sopenharmony_ci return S_DES_to_DOUT; 50362306a36Sopenharmony_ci case S_DIN_to_SM4: 50462306a36Sopenharmony_ci return S_SM4_to_DOUT; 50562306a36Sopenharmony_ci default: 50662306a36Sopenharmony_ci return ctx_p->flow_mode; 50762306a36Sopenharmony_ci } 50862306a36Sopenharmony_ci} 50962306a36Sopenharmony_ci 51062306a36Sopenharmony_cistatic void cc_setup_readiv_desc(struct crypto_tfm *tfm, 51162306a36Sopenharmony_ci struct cipher_req_ctx *req_ctx, 51262306a36Sopenharmony_ci unsigned int ivsize, struct cc_hw_desc desc[], 51362306a36Sopenharmony_ci unsigned int *seq_size) 51462306a36Sopenharmony_ci{ 51562306a36Sopenharmony_ci struct cc_cipher_ctx *ctx_p = crypto_tfm_ctx(tfm); 51662306a36Sopenharmony_ci struct device *dev = drvdata_to_dev(ctx_p->drvdata); 51762306a36Sopenharmony_ci int cipher_mode = ctx_p->cipher_mode; 51862306a36Sopenharmony_ci int flow_mode = cc_out_setup_mode(ctx_p); 51962306a36Sopenharmony_ci int direction = req_ctx->gen_ctx.op_type; 52062306a36Sopenharmony_ci dma_addr_t iv_dma_addr = req_ctx->gen_ctx.iv_dma_addr; 52162306a36Sopenharmony_ci 52262306a36Sopenharmony_ci if (ctx_p->key_type == CC_POLICY_PROTECTED_KEY) 52362306a36Sopenharmony_ci return; 52462306a36Sopenharmony_ci 52562306a36Sopenharmony_ci switch (cipher_mode) { 52662306a36Sopenharmony_ci case DRV_CIPHER_ECB: 52762306a36Sopenharmony_ci break; 52862306a36Sopenharmony_ci case DRV_CIPHER_CBC: 52962306a36Sopenharmony_ci case DRV_CIPHER_CBC_CTS: 53062306a36Sopenharmony_ci case DRV_CIPHER_CTR: 53162306a36Sopenharmony_ci case DRV_CIPHER_OFB: 53262306a36Sopenharmony_ci /* Read next IV */ 53362306a36Sopenharmony_ci hw_desc_init(&desc[*seq_size]); 53462306a36Sopenharmony_ci set_dout_dlli(&desc[*seq_size], iv_dma_addr, ivsize, NS_BIT, 1); 53562306a36Sopenharmony_ci set_cipher_config0(&desc[*seq_size], direction); 53662306a36Sopenharmony_ci set_flow_mode(&desc[*seq_size], flow_mode); 53762306a36Sopenharmony_ci set_cipher_mode(&desc[*seq_size], cipher_mode); 53862306a36Sopenharmony_ci if (cipher_mode == DRV_CIPHER_CTR || 53962306a36Sopenharmony_ci cipher_mode == DRV_CIPHER_OFB) { 54062306a36Sopenharmony_ci set_setup_mode(&desc[*seq_size], SETUP_WRITE_STATE1); 54162306a36Sopenharmony_ci } else { 54262306a36Sopenharmony_ci set_setup_mode(&desc[*seq_size], SETUP_WRITE_STATE0); 54362306a36Sopenharmony_ci } 54462306a36Sopenharmony_ci set_queue_last_ind(ctx_p->drvdata, &desc[*seq_size]); 54562306a36Sopenharmony_ci (*seq_size)++; 54662306a36Sopenharmony_ci break; 54762306a36Sopenharmony_ci case DRV_CIPHER_XTS: 54862306a36Sopenharmony_ci case DRV_CIPHER_ESSIV: 54962306a36Sopenharmony_ci /* IV */ 55062306a36Sopenharmony_ci hw_desc_init(&desc[*seq_size]); 55162306a36Sopenharmony_ci set_setup_mode(&desc[*seq_size], SETUP_WRITE_STATE1); 55262306a36Sopenharmony_ci set_cipher_mode(&desc[*seq_size], cipher_mode); 55362306a36Sopenharmony_ci set_cipher_config0(&desc[*seq_size], direction); 55462306a36Sopenharmony_ci set_flow_mode(&desc[*seq_size], flow_mode); 55562306a36Sopenharmony_ci set_dout_dlli(&desc[*seq_size], iv_dma_addr, CC_AES_BLOCK_SIZE, 55662306a36Sopenharmony_ci NS_BIT, 1); 55762306a36Sopenharmony_ci set_queue_last_ind(ctx_p->drvdata, &desc[*seq_size]); 55862306a36Sopenharmony_ci (*seq_size)++; 55962306a36Sopenharmony_ci break; 56062306a36Sopenharmony_ci default: 56162306a36Sopenharmony_ci dev_err(dev, "Unsupported cipher mode (%d)\n", cipher_mode); 56262306a36Sopenharmony_ci } 56362306a36Sopenharmony_ci} 56462306a36Sopenharmony_ci 56562306a36Sopenharmony_ci 56662306a36Sopenharmony_cistatic void cc_setup_state_desc(struct crypto_tfm *tfm, 56762306a36Sopenharmony_ci struct cipher_req_ctx *req_ctx, 56862306a36Sopenharmony_ci unsigned int ivsize, unsigned int nbytes, 56962306a36Sopenharmony_ci struct cc_hw_desc desc[], 57062306a36Sopenharmony_ci unsigned int *seq_size) 57162306a36Sopenharmony_ci{ 57262306a36Sopenharmony_ci struct cc_cipher_ctx *ctx_p = crypto_tfm_ctx(tfm); 57362306a36Sopenharmony_ci struct device *dev = drvdata_to_dev(ctx_p->drvdata); 57462306a36Sopenharmony_ci int cipher_mode = ctx_p->cipher_mode; 57562306a36Sopenharmony_ci int flow_mode = ctx_p->flow_mode; 57662306a36Sopenharmony_ci int direction = req_ctx->gen_ctx.op_type; 57762306a36Sopenharmony_ci dma_addr_t iv_dma_addr = req_ctx->gen_ctx.iv_dma_addr; 57862306a36Sopenharmony_ci 57962306a36Sopenharmony_ci switch (cipher_mode) { 58062306a36Sopenharmony_ci case DRV_CIPHER_ECB: 58162306a36Sopenharmony_ci break; 58262306a36Sopenharmony_ci case DRV_CIPHER_CBC: 58362306a36Sopenharmony_ci case DRV_CIPHER_CBC_CTS: 58462306a36Sopenharmony_ci case DRV_CIPHER_CTR: 58562306a36Sopenharmony_ci case DRV_CIPHER_OFB: 58662306a36Sopenharmony_ci /* Load IV */ 58762306a36Sopenharmony_ci hw_desc_init(&desc[*seq_size]); 58862306a36Sopenharmony_ci set_din_type(&desc[*seq_size], DMA_DLLI, iv_dma_addr, ivsize, 58962306a36Sopenharmony_ci NS_BIT); 59062306a36Sopenharmony_ci set_cipher_config0(&desc[*seq_size], direction); 59162306a36Sopenharmony_ci set_flow_mode(&desc[*seq_size], flow_mode); 59262306a36Sopenharmony_ci set_cipher_mode(&desc[*seq_size], cipher_mode); 59362306a36Sopenharmony_ci if (cipher_mode == DRV_CIPHER_CTR || 59462306a36Sopenharmony_ci cipher_mode == DRV_CIPHER_OFB) { 59562306a36Sopenharmony_ci set_setup_mode(&desc[*seq_size], SETUP_LOAD_STATE1); 59662306a36Sopenharmony_ci } else { 59762306a36Sopenharmony_ci set_setup_mode(&desc[*seq_size], SETUP_LOAD_STATE0); 59862306a36Sopenharmony_ci } 59962306a36Sopenharmony_ci (*seq_size)++; 60062306a36Sopenharmony_ci break; 60162306a36Sopenharmony_ci case DRV_CIPHER_XTS: 60262306a36Sopenharmony_ci case DRV_CIPHER_ESSIV: 60362306a36Sopenharmony_ci break; 60462306a36Sopenharmony_ci default: 60562306a36Sopenharmony_ci dev_err(dev, "Unsupported cipher mode (%d)\n", cipher_mode); 60662306a36Sopenharmony_ci } 60762306a36Sopenharmony_ci} 60862306a36Sopenharmony_ci 60962306a36Sopenharmony_ci 61062306a36Sopenharmony_cistatic void cc_setup_xex_state_desc(struct crypto_tfm *tfm, 61162306a36Sopenharmony_ci struct cipher_req_ctx *req_ctx, 61262306a36Sopenharmony_ci unsigned int ivsize, unsigned int nbytes, 61362306a36Sopenharmony_ci struct cc_hw_desc desc[], 61462306a36Sopenharmony_ci unsigned int *seq_size) 61562306a36Sopenharmony_ci{ 61662306a36Sopenharmony_ci struct cc_cipher_ctx *ctx_p = crypto_tfm_ctx(tfm); 61762306a36Sopenharmony_ci struct device *dev = drvdata_to_dev(ctx_p->drvdata); 61862306a36Sopenharmony_ci int cipher_mode = ctx_p->cipher_mode; 61962306a36Sopenharmony_ci int flow_mode = ctx_p->flow_mode; 62062306a36Sopenharmony_ci int direction = req_ctx->gen_ctx.op_type; 62162306a36Sopenharmony_ci dma_addr_t key_dma_addr = ctx_p->user.key_dma_addr; 62262306a36Sopenharmony_ci unsigned int key_len = (ctx_p->keylen / 2); 62362306a36Sopenharmony_ci dma_addr_t iv_dma_addr = req_ctx->gen_ctx.iv_dma_addr; 62462306a36Sopenharmony_ci unsigned int key_offset = key_len; 62562306a36Sopenharmony_ci 62662306a36Sopenharmony_ci switch (cipher_mode) { 62762306a36Sopenharmony_ci case DRV_CIPHER_ECB: 62862306a36Sopenharmony_ci break; 62962306a36Sopenharmony_ci case DRV_CIPHER_CBC: 63062306a36Sopenharmony_ci case DRV_CIPHER_CBC_CTS: 63162306a36Sopenharmony_ci case DRV_CIPHER_CTR: 63262306a36Sopenharmony_ci case DRV_CIPHER_OFB: 63362306a36Sopenharmony_ci break; 63462306a36Sopenharmony_ci case DRV_CIPHER_XTS: 63562306a36Sopenharmony_ci case DRV_CIPHER_ESSIV: 63662306a36Sopenharmony_ci 63762306a36Sopenharmony_ci if (cipher_mode == DRV_CIPHER_ESSIV) 63862306a36Sopenharmony_ci key_len = SHA256_DIGEST_SIZE; 63962306a36Sopenharmony_ci 64062306a36Sopenharmony_ci /* load XEX key */ 64162306a36Sopenharmony_ci hw_desc_init(&desc[*seq_size]); 64262306a36Sopenharmony_ci set_cipher_mode(&desc[*seq_size], cipher_mode); 64362306a36Sopenharmony_ci set_cipher_config0(&desc[*seq_size], direction); 64462306a36Sopenharmony_ci if (cc_key_type(tfm) == CC_HW_PROTECTED_KEY) { 64562306a36Sopenharmony_ci set_hw_crypto_key(&desc[*seq_size], 64662306a36Sopenharmony_ci ctx_p->hw.key2_slot); 64762306a36Sopenharmony_ci } else { 64862306a36Sopenharmony_ci set_din_type(&desc[*seq_size], DMA_DLLI, 64962306a36Sopenharmony_ci (key_dma_addr + key_offset), 65062306a36Sopenharmony_ci key_len, NS_BIT); 65162306a36Sopenharmony_ci } 65262306a36Sopenharmony_ci set_xex_data_unit_size(&desc[*seq_size], nbytes); 65362306a36Sopenharmony_ci set_flow_mode(&desc[*seq_size], S_DIN_to_AES2); 65462306a36Sopenharmony_ci set_key_size_aes(&desc[*seq_size], key_len); 65562306a36Sopenharmony_ci set_setup_mode(&desc[*seq_size], SETUP_LOAD_XEX_KEY); 65662306a36Sopenharmony_ci (*seq_size)++; 65762306a36Sopenharmony_ci 65862306a36Sopenharmony_ci /* Load IV */ 65962306a36Sopenharmony_ci hw_desc_init(&desc[*seq_size]); 66062306a36Sopenharmony_ci set_setup_mode(&desc[*seq_size], SETUP_LOAD_STATE1); 66162306a36Sopenharmony_ci set_cipher_mode(&desc[*seq_size], cipher_mode); 66262306a36Sopenharmony_ci set_cipher_config0(&desc[*seq_size], direction); 66362306a36Sopenharmony_ci set_key_size_aes(&desc[*seq_size], key_len); 66462306a36Sopenharmony_ci set_flow_mode(&desc[*seq_size], flow_mode); 66562306a36Sopenharmony_ci set_din_type(&desc[*seq_size], DMA_DLLI, iv_dma_addr, 66662306a36Sopenharmony_ci CC_AES_BLOCK_SIZE, NS_BIT); 66762306a36Sopenharmony_ci (*seq_size)++; 66862306a36Sopenharmony_ci break; 66962306a36Sopenharmony_ci default: 67062306a36Sopenharmony_ci dev_err(dev, "Unsupported cipher mode (%d)\n", cipher_mode); 67162306a36Sopenharmony_ci } 67262306a36Sopenharmony_ci} 67362306a36Sopenharmony_ci 67462306a36Sopenharmony_cistatic int cc_out_flow_mode(struct cc_cipher_ctx *ctx_p) 67562306a36Sopenharmony_ci{ 67662306a36Sopenharmony_ci switch (ctx_p->flow_mode) { 67762306a36Sopenharmony_ci case S_DIN_to_AES: 67862306a36Sopenharmony_ci return DIN_AES_DOUT; 67962306a36Sopenharmony_ci case S_DIN_to_DES: 68062306a36Sopenharmony_ci return DIN_DES_DOUT; 68162306a36Sopenharmony_ci case S_DIN_to_SM4: 68262306a36Sopenharmony_ci return DIN_SM4_DOUT; 68362306a36Sopenharmony_ci default: 68462306a36Sopenharmony_ci return ctx_p->flow_mode; 68562306a36Sopenharmony_ci } 68662306a36Sopenharmony_ci} 68762306a36Sopenharmony_ci 68862306a36Sopenharmony_cistatic void cc_setup_key_desc(struct crypto_tfm *tfm, 68962306a36Sopenharmony_ci struct cipher_req_ctx *req_ctx, 69062306a36Sopenharmony_ci unsigned int nbytes, struct cc_hw_desc desc[], 69162306a36Sopenharmony_ci unsigned int *seq_size) 69262306a36Sopenharmony_ci{ 69362306a36Sopenharmony_ci struct cc_cipher_ctx *ctx_p = crypto_tfm_ctx(tfm); 69462306a36Sopenharmony_ci struct device *dev = drvdata_to_dev(ctx_p->drvdata); 69562306a36Sopenharmony_ci int cipher_mode = ctx_p->cipher_mode; 69662306a36Sopenharmony_ci int flow_mode = ctx_p->flow_mode; 69762306a36Sopenharmony_ci int direction = req_ctx->gen_ctx.op_type; 69862306a36Sopenharmony_ci dma_addr_t key_dma_addr = ctx_p->user.key_dma_addr; 69962306a36Sopenharmony_ci unsigned int key_len = ctx_p->keylen; 70062306a36Sopenharmony_ci unsigned int din_size; 70162306a36Sopenharmony_ci 70262306a36Sopenharmony_ci switch (cipher_mode) { 70362306a36Sopenharmony_ci case DRV_CIPHER_CBC: 70462306a36Sopenharmony_ci case DRV_CIPHER_CBC_CTS: 70562306a36Sopenharmony_ci case DRV_CIPHER_CTR: 70662306a36Sopenharmony_ci case DRV_CIPHER_OFB: 70762306a36Sopenharmony_ci case DRV_CIPHER_ECB: 70862306a36Sopenharmony_ci /* Load key */ 70962306a36Sopenharmony_ci hw_desc_init(&desc[*seq_size]); 71062306a36Sopenharmony_ci set_cipher_mode(&desc[*seq_size], cipher_mode); 71162306a36Sopenharmony_ci set_cipher_config0(&desc[*seq_size], direction); 71262306a36Sopenharmony_ci 71362306a36Sopenharmony_ci if (cc_key_type(tfm) == CC_POLICY_PROTECTED_KEY) { 71462306a36Sopenharmony_ci /* We use the AES key size coding for all CPP algs */ 71562306a36Sopenharmony_ci set_key_size_aes(&desc[*seq_size], key_len); 71662306a36Sopenharmony_ci set_cpp_crypto_key(&desc[*seq_size], ctx_p->cpp.slot); 71762306a36Sopenharmony_ci flow_mode = cc_out_flow_mode(ctx_p); 71862306a36Sopenharmony_ci } else { 71962306a36Sopenharmony_ci if (flow_mode == S_DIN_to_AES) { 72062306a36Sopenharmony_ci if (cc_key_type(tfm) == CC_HW_PROTECTED_KEY) { 72162306a36Sopenharmony_ci set_hw_crypto_key(&desc[*seq_size], 72262306a36Sopenharmony_ci ctx_p->hw.key1_slot); 72362306a36Sopenharmony_ci } else { 72462306a36Sopenharmony_ci /* CC_POLICY_UNPROTECTED_KEY 72562306a36Sopenharmony_ci * Invalid keys are filtered out in 72662306a36Sopenharmony_ci * sethkey() 72762306a36Sopenharmony_ci */ 72862306a36Sopenharmony_ci din_size = (key_len == 24) ? 72962306a36Sopenharmony_ci AES_MAX_KEY_SIZE : key_len; 73062306a36Sopenharmony_ci 73162306a36Sopenharmony_ci set_din_type(&desc[*seq_size], DMA_DLLI, 73262306a36Sopenharmony_ci key_dma_addr, din_size, 73362306a36Sopenharmony_ci NS_BIT); 73462306a36Sopenharmony_ci } 73562306a36Sopenharmony_ci set_key_size_aes(&desc[*seq_size], key_len); 73662306a36Sopenharmony_ci } else { 73762306a36Sopenharmony_ci /*des*/ 73862306a36Sopenharmony_ci set_din_type(&desc[*seq_size], DMA_DLLI, 73962306a36Sopenharmony_ci key_dma_addr, key_len, NS_BIT); 74062306a36Sopenharmony_ci set_key_size_des(&desc[*seq_size], key_len); 74162306a36Sopenharmony_ci } 74262306a36Sopenharmony_ci set_setup_mode(&desc[*seq_size], SETUP_LOAD_KEY0); 74362306a36Sopenharmony_ci } 74462306a36Sopenharmony_ci set_flow_mode(&desc[*seq_size], flow_mode); 74562306a36Sopenharmony_ci (*seq_size)++; 74662306a36Sopenharmony_ci break; 74762306a36Sopenharmony_ci case DRV_CIPHER_XTS: 74862306a36Sopenharmony_ci case DRV_CIPHER_ESSIV: 74962306a36Sopenharmony_ci /* Load AES key */ 75062306a36Sopenharmony_ci hw_desc_init(&desc[*seq_size]); 75162306a36Sopenharmony_ci set_cipher_mode(&desc[*seq_size], cipher_mode); 75262306a36Sopenharmony_ci set_cipher_config0(&desc[*seq_size], direction); 75362306a36Sopenharmony_ci if (cc_key_type(tfm) == CC_HW_PROTECTED_KEY) { 75462306a36Sopenharmony_ci set_hw_crypto_key(&desc[*seq_size], 75562306a36Sopenharmony_ci ctx_p->hw.key1_slot); 75662306a36Sopenharmony_ci } else { 75762306a36Sopenharmony_ci set_din_type(&desc[*seq_size], DMA_DLLI, key_dma_addr, 75862306a36Sopenharmony_ci (key_len / 2), NS_BIT); 75962306a36Sopenharmony_ci } 76062306a36Sopenharmony_ci set_key_size_aes(&desc[*seq_size], (key_len / 2)); 76162306a36Sopenharmony_ci set_flow_mode(&desc[*seq_size], flow_mode); 76262306a36Sopenharmony_ci set_setup_mode(&desc[*seq_size], SETUP_LOAD_KEY0); 76362306a36Sopenharmony_ci (*seq_size)++; 76462306a36Sopenharmony_ci break; 76562306a36Sopenharmony_ci default: 76662306a36Sopenharmony_ci dev_err(dev, "Unsupported cipher mode (%d)\n", cipher_mode); 76762306a36Sopenharmony_ci } 76862306a36Sopenharmony_ci} 76962306a36Sopenharmony_ci 77062306a36Sopenharmony_cistatic void cc_setup_mlli_desc(struct crypto_tfm *tfm, 77162306a36Sopenharmony_ci struct cipher_req_ctx *req_ctx, 77262306a36Sopenharmony_ci struct scatterlist *dst, struct scatterlist *src, 77362306a36Sopenharmony_ci unsigned int nbytes, void *areq, 77462306a36Sopenharmony_ci struct cc_hw_desc desc[], unsigned int *seq_size) 77562306a36Sopenharmony_ci{ 77662306a36Sopenharmony_ci struct cc_cipher_ctx *ctx_p = crypto_tfm_ctx(tfm); 77762306a36Sopenharmony_ci struct device *dev = drvdata_to_dev(ctx_p->drvdata); 77862306a36Sopenharmony_ci 77962306a36Sopenharmony_ci if (req_ctx->dma_buf_type == CC_DMA_BUF_MLLI) { 78062306a36Sopenharmony_ci /* bypass */ 78162306a36Sopenharmony_ci dev_dbg(dev, " bypass params addr %pad length 0x%X addr 0x%08X\n", 78262306a36Sopenharmony_ci &req_ctx->mlli_params.mlli_dma_addr, 78362306a36Sopenharmony_ci req_ctx->mlli_params.mlli_len, 78462306a36Sopenharmony_ci ctx_p->drvdata->mlli_sram_addr); 78562306a36Sopenharmony_ci hw_desc_init(&desc[*seq_size]); 78662306a36Sopenharmony_ci set_din_type(&desc[*seq_size], DMA_DLLI, 78762306a36Sopenharmony_ci req_ctx->mlli_params.mlli_dma_addr, 78862306a36Sopenharmony_ci req_ctx->mlli_params.mlli_len, NS_BIT); 78962306a36Sopenharmony_ci set_dout_sram(&desc[*seq_size], 79062306a36Sopenharmony_ci ctx_p->drvdata->mlli_sram_addr, 79162306a36Sopenharmony_ci req_ctx->mlli_params.mlli_len); 79262306a36Sopenharmony_ci set_flow_mode(&desc[*seq_size], BYPASS); 79362306a36Sopenharmony_ci (*seq_size)++; 79462306a36Sopenharmony_ci } 79562306a36Sopenharmony_ci} 79662306a36Sopenharmony_ci 79762306a36Sopenharmony_cistatic void cc_setup_flow_desc(struct crypto_tfm *tfm, 79862306a36Sopenharmony_ci struct cipher_req_ctx *req_ctx, 79962306a36Sopenharmony_ci struct scatterlist *dst, struct scatterlist *src, 80062306a36Sopenharmony_ci unsigned int nbytes, struct cc_hw_desc desc[], 80162306a36Sopenharmony_ci unsigned int *seq_size) 80262306a36Sopenharmony_ci{ 80362306a36Sopenharmony_ci struct cc_cipher_ctx *ctx_p = crypto_tfm_ctx(tfm); 80462306a36Sopenharmony_ci struct device *dev = drvdata_to_dev(ctx_p->drvdata); 80562306a36Sopenharmony_ci unsigned int flow_mode = cc_out_flow_mode(ctx_p); 80662306a36Sopenharmony_ci bool last_desc = (ctx_p->key_type == CC_POLICY_PROTECTED_KEY || 80762306a36Sopenharmony_ci ctx_p->cipher_mode == DRV_CIPHER_ECB); 80862306a36Sopenharmony_ci 80962306a36Sopenharmony_ci /* Process */ 81062306a36Sopenharmony_ci if (req_ctx->dma_buf_type == CC_DMA_BUF_DLLI) { 81162306a36Sopenharmony_ci dev_dbg(dev, " data params addr %pad length 0x%X\n", 81262306a36Sopenharmony_ci &sg_dma_address(src), nbytes); 81362306a36Sopenharmony_ci dev_dbg(dev, " data params addr %pad length 0x%X\n", 81462306a36Sopenharmony_ci &sg_dma_address(dst), nbytes); 81562306a36Sopenharmony_ci hw_desc_init(&desc[*seq_size]); 81662306a36Sopenharmony_ci set_din_type(&desc[*seq_size], DMA_DLLI, sg_dma_address(src), 81762306a36Sopenharmony_ci nbytes, NS_BIT); 81862306a36Sopenharmony_ci set_dout_dlli(&desc[*seq_size], sg_dma_address(dst), 81962306a36Sopenharmony_ci nbytes, NS_BIT, (!last_desc ? 0 : 1)); 82062306a36Sopenharmony_ci if (last_desc) 82162306a36Sopenharmony_ci set_queue_last_ind(ctx_p->drvdata, &desc[*seq_size]); 82262306a36Sopenharmony_ci 82362306a36Sopenharmony_ci set_flow_mode(&desc[*seq_size], flow_mode); 82462306a36Sopenharmony_ci (*seq_size)++; 82562306a36Sopenharmony_ci } else { 82662306a36Sopenharmony_ci hw_desc_init(&desc[*seq_size]); 82762306a36Sopenharmony_ci set_din_type(&desc[*seq_size], DMA_MLLI, 82862306a36Sopenharmony_ci ctx_p->drvdata->mlli_sram_addr, 82962306a36Sopenharmony_ci req_ctx->in_mlli_nents, NS_BIT); 83062306a36Sopenharmony_ci if (req_ctx->out_nents == 0) { 83162306a36Sopenharmony_ci dev_dbg(dev, " din/dout params addr 0x%08X addr 0x%08X\n", 83262306a36Sopenharmony_ci ctx_p->drvdata->mlli_sram_addr, 83362306a36Sopenharmony_ci ctx_p->drvdata->mlli_sram_addr); 83462306a36Sopenharmony_ci set_dout_mlli(&desc[*seq_size], 83562306a36Sopenharmony_ci ctx_p->drvdata->mlli_sram_addr, 83662306a36Sopenharmony_ci req_ctx->in_mlli_nents, NS_BIT, 83762306a36Sopenharmony_ci (!last_desc ? 0 : 1)); 83862306a36Sopenharmony_ci } else { 83962306a36Sopenharmony_ci dev_dbg(dev, " din/dout params addr 0x%08X addr 0x%08X\n", 84062306a36Sopenharmony_ci ctx_p->drvdata->mlli_sram_addr, 84162306a36Sopenharmony_ci ctx_p->drvdata->mlli_sram_addr + 84262306a36Sopenharmony_ci (u32)LLI_ENTRY_BYTE_SIZE * req_ctx->in_nents); 84362306a36Sopenharmony_ci set_dout_mlli(&desc[*seq_size], 84462306a36Sopenharmony_ci (ctx_p->drvdata->mlli_sram_addr + 84562306a36Sopenharmony_ci (LLI_ENTRY_BYTE_SIZE * 84662306a36Sopenharmony_ci req_ctx->in_mlli_nents)), 84762306a36Sopenharmony_ci req_ctx->out_mlli_nents, NS_BIT, 84862306a36Sopenharmony_ci (!last_desc ? 0 : 1)); 84962306a36Sopenharmony_ci } 85062306a36Sopenharmony_ci if (last_desc) 85162306a36Sopenharmony_ci set_queue_last_ind(ctx_p->drvdata, &desc[*seq_size]); 85262306a36Sopenharmony_ci 85362306a36Sopenharmony_ci set_flow_mode(&desc[*seq_size], flow_mode); 85462306a36Sopenharmony_ci (*seq_size)++; 85562306a36Sopenharmony_ci } 85662306a36Sopenharmony_ci} 85762306a36Sopenharmony_ci 85862306a36Sopenharmony_cistatic void cc_cipher_complete(struct device *dev, void *cc_req, int err) 85962306a36Sopenharmony_ci{ 86062306a36Sopenharmony_ci struct skcipher_request *req = (struct skcipher_request *)cc_req; 86162306a36Sopenharmony_ci struct scatterlist *dst = req->dst; 86262306a36Sopenharmony_ci struct scatterlist *src = req->src; 86362306a36Sopenharmony_ci struct cipher_req_ctx *req_ctx = skcipher_request_ctx(req); 86462306a36Sopenharmony_ci struct crypto_skcipher *sk_tfm = crypto_skcipher_reqtfm(req); 86562306a36Sopenharmony_ci unsigned int ivsize = crypto_skcipher_ivsize(sk_tfm); 86662306a36Sopenharmony_ci 86762306a36Sopenharmony_ci if (err != -EINPROGRESS) { 86862306a36Sopenharmony_ci /* Not a BACKLOG notification */ 86962306a36Sopenharmony_ci cc_unmap_cipher_request(dev, req_ctx, ivsize, src, dst); 87062306a36Sopenharmony_ci memcpy(req->iv, req_ctx->iv, ivsize); 87162306a36Sopenharmony_ci kfree_sensitive(req_ctx->iv); 87262306a36Sopenharmony_ci } 87362306a36Sopenharmony_ci 87462306a36Sopenharmony_ci skcipher_request_complete(req, err); 87562306a36Sopenharmony_ci} 87662306a36Sopenharmony_ci 87762306a36Sopenharmony_cistatic int cc_cipher_process(struct skcipher_request *req, 87862306a36Sopenharmony_ci enum drv_crypto_direction direction) 87962306a36Sopenharmony_ci{ 88062306a36Sopenharmony_ci struct crypto_skcipher *sk_tfm = crypto_skcipher_reqtfm(req); 88162306a36Sopenharmony_ci struct crypto_tfm *tfm = crypto_skcipher_tfm(sk_tfm); 88262306a36Sopenharmony_ci struct cipher_req_ctx *req_ctx = skcipher_request_ctx(req); 88362306a36Sopenharmony_ci unsigned int ivsize = crypto_skcipher_ivsize(sk_tfm); 88462306a36Sopenharmony_ci struct scatterlist *dst = req->dst; 88562306a36Sopenharmony_ci struct scatterlist *src = req->src; 88662306a36Sopenharmony_ci unsigned int nbytes = req->cryptlen; 88762306a36Sopenharmony_ci void *iv = req->iv; 88862306a36Sopenharmony_ci struct cc_cipher_ctx *ctx_p = crypto_tfm_ctx(tfm); 88962306a36Sopenharmony_ci struct device *dev = drvdata_to_dev(ctx_p->drvdata); 89062306a36Sopenharmony_ci struct cc_hw_desc desc[MAX_SKCIPHER_SEQ_LEN]; 89162306a36Sopenharmony_ci struct cc_crypto_req cc_req = {}; 89262306a36Sopenharmony_ci int rc; 89362306a36Sopenharmony_ci unsigned int seq_len = 0; 89462306a36Sopenharmony_ci gfp_t flags = cc_gfp_flags(&req->base); 89562306a36Sopenharmony_ci 89662306a36Sopenharmony_ci dev_dbg(dev, "%s req=%p iv=%p nbytes=%d\n", 89762306a36Sopenharmony_ci ((direction == DRV_CRYPTO_DIRECTION_ENCRYPT) ? 89862306a36Sopenharmony_ci "Encrypt" : "Decrypt"), req, iv, nbytes); 89962306a36Sopenharmony_ci 90062306a36Sopenharmony_ci /* STAT_PHASE_0: Init and sanity checks */ 90162306a36Sopenharmony_ci 90262306a36Sopenharmony_ci if (validate_data_size(ctx_p, nbytes)) { 90362306a36Sopenharmony_ci dev_dbg(dev, "Unsupported data size %d.\n", nbytes); 90462306a36Sopenharmony_ci rc = -EINVAL; 90562306a36Sopenharmony_ci goto exit_process; 90662306a36Sopenharmony_ci } 90762306a36Sopenharmony_ci if (nbytes == 0) { 90862306a36Sopenharmony_ci /* No data to process is valid */ 90962306a36Sopenharmony_ci rc = 0; 91062306a36Sopenharmony_ci goto exit_process; 91162306a36Sopenharmony_ci } 91262306a36Sopenharmony_ci 91362306a36Sopenharmony_ci if (ctx_p->fallback_on) { 91462306a36Sopenharmony_ci struct skcipher_request *subreq = skcipher_request_ctx(req); 91562306a36Sopenharmony_ci 91662306a36Sopenharmony_ci *subreq = *req; 91762306a36Sopenharmony_ci skcipher_request_set_tfm(subreq, ctx_p->fallback_tfm); 91862306a36Sopenharmony_ci if (direction == DRV_CRYPTO_DIRECTION_ENCRYPT) 91962306a36Sopenharmony_ci return crypto_skcipher_encrypt(subreq); 92062306a36Sopenharmony_ci else 92162306a36Sopenharmony_ci return crypto_skcipher_decrypt(subreq); 92262306a36Sopenharmony_ci } 92362306a36Sopenharmony_ci 92462306a36Sopenharmony_ci /* The IV we are handed may be allocated from the stack so 92562306a36Sopenharmony_ci * we must copy it to a DMAable buffer before use. 92662306a36Sopenharmony_ci */ 92762306a36Sopenharmony_ci req_ctx->iv = kmemdup(iv, ivsize, flags); 92862306a36Sopenharmony_ci if (!req_ctx->iv) { 92962306a36Sopenharmony_ci rc = -ENOMEM; 93062306a36Sopenharmony_ci goto exit_process; 93162306a36Sopenharmony_ci } 93262306a36Sopenharmony_ci 93362306a36Sopenharmony_ci /* Setup request structure */ 93462306a36Sopenharmony_ci cc_req.user_cb = cc_cipher_complete; 93562306a36Sopenharmony_ci cc_req.user_arg = req; 93662306a36Sopenharmony_ci 93762306a36Sopenharmony_ci /* Setup CPP operation details */ 93862306a36Sopenharmony_ci if (ctx_p->key_type == CC_POLICY_PROTECTED_KEY) { 93962306a36Sopenharmony_ci cc_req.cpp.is_cpp = true; 94062306a36Sopenharmony_ci cc_req.cpp.alg = ctx_p->cpp.alg; 94162306a36Sopenharmony_ci cc_req.cpp.slot = ctx_p->cpp.slot; 94262306a36Sopenharmony_ci } 94362306a36Sopenharmony_ci 94462306a36Sopenharmony_ci /* Setup request context */ 94562306a36Sopenharmony_ci req_ctx->gen_ctx.op_type = direction; 94662306a36Sopenharmony_ci 94762306a36Sopenharmony_ci /* STAT_PHASE_1: Map buffers */ 94862306a36Sopenharmony_ci 94962306a36Sopenharmony_ci rc = cc_map_cipher_request(ctx_p->drvdata, req_ctx, ivsize, nbytes, 95062306a36Sopenharmony_ci req_ctx->iv, src, dst, flags); 95162306a36Sopenharmony_ci if (rc) { 95262306a36Sopenharmony_ci dev_err(dev, "map_request() failed\n"); 95362306a36Sopenharmony_ci goto exit_process; 95462306a36Sopenharmony_ci } 95562306a36Sopenharmony_ci 95662306a36Sopenharmony_ci /* STAT_PHASE_2: Create sequence */ 95762306a36Sopenharmony_ci 95862306a36Sopenharmony_ci /* Setup state (IV) */ 95962306a36Sopenharmony_ci cc_setup_state_desc(tfm, req_ctx, ivsize, nbytes, desc, &seq_len); 96062306a36Sopenharmony_ci /* Setup MLLI line, if needed */ 96162306a36Sopenharmony_ci cc_setup_mlli_desc(tfm, req_ctx, dst, src, nbytes, req, desc, &seq_len); 96262306a36Sopenharmony_ci /* Setup key */ 96362306a36Sopenharmony_ci cc_setup_key_desc(tfm, req_ctx, nbytes, desc, &seq_len); 96462306a36Sopenharmony_ci /* Setup state (IV and XEX key) */ 96562306a36Sopenharmony_ci cc_setup_xex_state_desc(tfm, req_ctx, ivsize, nbytes, desc, &seq_len); 96662306a36Sopenharmony_ci /* Data processing */ 96762306a36Sopenharmony_ci cc_setup_flow_desc(tfm, req_ctx, dst, src, nbytes, desc, &seq_len); 96862306a36Sopenharmony_ci /* Read next IV */ 96962306a36Sopenharmony_ci cc_setup_readiv_desc(tfm, req_ctx, ivsize, desc, &seq_len); 97062306a36Sopenharmony_ci 97162306a36Sopenharmony_ci /* STAT_PHASE_3: Lock HW and push sequence */ 97262306a36Sopenharmony_ci 97362306a36Sopenharmony_ci rc = cc_send_request(ctx_p->drvdata, &cc_req, desc, seq_len, 97462306a36Sopenharmony_ci &req->base); 97562306a36Sopenharmony_ci if (rc != -EINPROGRESS && rc != -EBUSY) { 97662306a36Sopenharmony_ci /* Failed to send the request or request completed 97762306a36Sopenharmony_ci * synchronously 97862306a36Sopenharmony_ci */ 97962306a36Sopenharmony_ci cc_unmap_cipher_request(dev, req_ctx, ivsize, src, dst); 98062306a36Sopenharmony_ci } 98162306a36Sopenharmony_ci 98262306a36Sopenharmony_ciexit_process: 98362306a36Sopenharmony_ci if (rc != -EINPROGRESS && rc != -EBUSY) { 98462306a36Sopenharmony_ci kfree_sensitive(req_ctx->iv); 98562306a36Sopenharmony_ci } 98662306a36Sopenharmony_ci 98762306a36Sopenharmony_ci return rc; 98862306a36Sopenharmony_ci} 98962306a36Sopenharmony_ci 99062306a36Sopenharmony_cistatic int cc_cipher_encrypt(struct skcipher_request *req) 99162306a36Sopenharmony_ci{ 99262306a36Sopenharmony_ci struct cipher_req_ctx *req_ctx = skcipher_request_ctx(req); 99362306a36Sopenharmony_ci 99462306a36Sopenharmony_ci memset(req_ctx, 0, sizeof(*req_ctx)); 99562306a36Sopenharmony_ci 99662306a36Sopenharmony_ci return cc_cipher_process(req, DRV_CRYPTO_DIRECTION_ENCRYPT); 99762306a36Sopenharmony_ci} 99862306a36Sopenharmony_ci 99962306a36Sopenharmony_cistatic int cc_cipher_decrypt(struct skcipher_request *req) 100062306a36Sopenharmony_ci{ 100162306a36Sopenharmony_ci struct cipher_req_ctx *req_ctx = skcipher_request_ctx(req); 100262306a36Sopenharmony_ci 100362306a36Sopenharmony_ci memset(req_ctx, 0, sizeof(*req_ctx)); 100462306a36Sopenharmony_ci 100562306a36Sopenharmony_ci return cc_cipher_process(req, DRV_CRYPTO_DIRECTION_DECRYPT); 100662306a36Sopenharmony_ci} 100762306a36Sopenharmony_ci 100862306a36Sopenharmony_ci/* Block cipher alg */ 100962306a36Sopenharmony_cistatic const struct cc_alg_template skcipher_algs[] = { 101062306a36Sopenharmony_ci { 101162306a36Sopenharmony_ci .name = "xts(paes)", 101262306a36Sopenharmony_ci .driver_name = "xts-paes-ccree", 101362306a36Sopenharmony_ci .blocksize = 1, 101462306a36Sopenharmony_ci .template_skcipher = { 101562306a36Sopenharmony_ci .setkey = cc_cipher_sethkey, 101662306a36Sopenharmony_ci .encrypt = cc_cipher_encrypt, 101762306a36Sopenharmony_ci .decrypt = cc_cipher_decrypt, 101862306a36Sopenharmony_ci .min_keysize = CC_HW_KEY_SIZE, 101962306a36Sopenharmony_ci .max_keysize = CC_HW_KEY_SIZE, 102062306a36Sopenharmony_ci .ivsize = AES_BLOCK_SIZE, 102162306a36Sopenharmony_ci }, 102262306a36Sopenharmony_ci .cipher_mode = DRV_CIPHER_XTS, 102362306a36Sopenharmony_ci .flow_mode = S_DIN_to_AES, 102462306a36Sopenharmony_ci .min_hw_rev = CC_HW_REV_630, 102562306a36Sopenharmony_ci .std_body = CC_STD_NIST, 102662306a36Sopenharmony_ci .sec_func = true, 102762306a36Sopenharmony_ci }, 102862306a36Sopenharmony_ci { 102962306a36Sopenharmony_ci .name = "essiv(cbc(paes),sha256)", 103062306a36Sopenharmony_ci .driver_name = "essiv-paes-ccree", 103162306a36Sopenharmony_ci .blocksize = AES_BLOCK_SIZE, 103262306a36Sopenharmony_ci .template_skcipher = { 103362306a36Sopenharmony_ci .setkey = cc_cipher_sethkey, 103462306a36Sopenharmony_ci .encrypt = cc_cipher_encrypt, 103562306a36Sopenharmony_ci .decrypt = cc_cipher_decrypt, 103662306a36Sopenharmony_ci .min_keysize = CC_HW_KEY_SIZE, 103762306a36Sopenharmony_ci .max_keysize = CC_HW_KEY_SIZE, 103862306a36Sopenharmony_ci .ivsize = AES_BLOCK_SIZE, 103962306a36Sopenharmony_ci }, 104062306a36Sopenharmony_ci .cipher_mode = DRV_CIPHER_ESSIV, 104162306a36Sopenharmony_ci .flow_mode = S_DIN_to_AES, 104262306a36Sopenharmony_ci .min_hw_rev = CC_HW_REV_712, 104362306a36Sopenharmony_ci .std_body = CC_STD_NIST, 104462306a36Sopenharmony_ci .sec_func = true, 104562306a36Sopenharmony_ci }, 104662306a36Sopenharmony_ci { 104762306a36Sopenharmony_ci .name = "ecb(paes)", 104862306a36Sopenharmony_ci .driver_name = "ecb-paes-ccree", 104962306a36Sopenharmony_ci .blocksize = AES_BLOCK_SIZE, 105062306a36Sopenharmony_ci .template_skcipher = { 105162306a36Sopenharmony_ci .setkey = cc_cipher_sethkey, 105262306a36Sopenharmony_ci .encrypt = cc_cipher_encrypt, 105362306a36Sopenharmony_ci .decrypt = cc_cipher_decrypt, 105462306a36Sopenharmony_ci .min_keysize = CC_HW_KEY_SIZE, 105562306a36Sopenharmony_ci .max_keysize = CC_HW_KEY_SIZE, 105662306a36Sopenharmony_ci .ivsize = 0, 105762306a36Sopenharmony_ci }, 105862306a36Sopenharmony_ci .cipher_mode = DRV_CIPHER_ECB, 105962306a36Sopenharmony_ci .flow_mode = S_DIN_to_AES, 106062306a36Sopenharmony_ci .min_hw_rev = CC_HW_REV_712, 106162306a36Sopenharmony_ci .std_body = CC_STD_NIST, 106262306a36Sopenharmony_ci .sec_func = true, 106362306a36Sopenharmony_ci }, 106462306a36Sopenharmony_ci { 106562306a36Sopenharmony_ci .name = "cbc(paes)", 106662306a36Sopenharmony_ci .driver_name = "cbc-paes-ccree", 106762306a36Sopenharmony_ci .blocksize = AES_BLOCK_SIZE, 106862306a36Sopenharmony_ci .template_skcipher = { 106962306a36Sopenharmony_ci .setkey = cc_cipher_sethkey, 107062306a36Sopenharmony_ci .encrypt = cc_cipher_encrypt, 107162306a36Sopenharmony_ci .decrypt = cc_cipher_decrypt, 107262306a36Sopenharmony_ci .min_keysize = CC_HW_KEY_SIZE, 107362306a36Sopenharmony_ci .max_keysize = CC_HW_KEY_SIZE, 107462306a36Sopenharmony_ci .ivsize = AES_BLOCK_SIZE, 107562306a36Sopenharmony_ci }, 107662306a36Sopenharmony_ci .cipher_mode = DRV_CIPHER_CBC, 107762306a36Sopenharmony_ci .flow_mode = S_DIN_to_AES, 107862306a36Sopenharmony_ci .min_hw_rev = CC_HW_REV_712, 107962306a36Sopenharmony_ci .std_body = CC_STD_NIST, 108062306a36Sopenharmony_ci .sec_func = true, 108162306a36Sopenharmony_ci }, 108262306a36Sopenharmony_ci { 108362306a36Sopenharmony_ci .name = "ofb(paes)", 108462306a36Sopenharmony_ci .driver_name = "ofb-paes-ccree", 108562306a36Sopenharmony_ci .blocksize = AES_BLOCK_SIZE, 108662306a36Sopenharmony_ci .template_skcipher = { 108762306a36Sopenharmony_ci .setkey = cc_cipher_sethkey, 108862306a36Sopenharmony_ci .encrypt = cc_cipher_encrypt, 108962306a36Sopenharmony_ci .decrypt = cc_cipher_decrypt, 109062306a36Sopenharmony_ci .min_keysize = CC_HW_KEY_SIZE, 109162306a36Sopenharmony_ci .max_keysize = CC_HW_KEY_SIZE, 109262306a36Sopenharmony_ci .ivsize = AES_BLOCK_SIZE, 109362306a36Sopenharmony_ci }, 109462306a36Sopenharmony_ci .cipher_mode = DRV_CIPHER_OFB, 109562306a36Sopenharmony_ci .flow_mode = S_DIN_to_AES, 109662306a36Sopenharmony_ci .min_hw_rev = CC_HW_REV_712, 109762306a36Sopenharmony_ci .std_body = CC_STD_NIST, 109862306a36Sopenharmony_ci .sec_func = true, 109962306a36Sopenharmony_ci }, 110062306a36Sopenharmony_ci { 110162306a36Sopenharmony_ci .name = "cts(cbc(paes))", 110262306a36Sopenharmony_ci .driver_name = "cts-cbc-paes-ccree", 110362306a36Sopenharmony_ci .blocksize = AES_BLOCK_SIZE, 110462306a36Sopenharmony_ci .template_skcipher = { 110562306a36Sopenharmony_ci .setkey = cc_cipher_sethkey, 110662306a36Sopenharmony_ci .encrypt = cc_cipher_encrypt, 110762306a36Sopenharmony_ci .decrypt = cc_cipher_decrypt, 110862306a36Sopenharmony_ci .min_keysize = CC_HW_KEY_SIZE, 110962306a36Sopenharmony_ci .max_keysize = CC_HW_KEY_SIZE, 111062306a36Sopenharmony_ci .ivsize = AES_BLOCK_SIZE, 111162306a36Sopenharmony_ci }, 111262306a36Sopenharmony_ci .cipher_mode = DRV_CIPHER_CBC_CTS, 111362306a36Sopenharmony_ci .flow_mode = S_DIN_to_AES, 111462306a36Sopenharmony_ci .min_hw_rev = CC_HW_REV_712, 111562306a36Sopenharmony_ci .std_body = CC_STD_NIST, 111662306a36Sopenharmony_ci .sec_func = true, 111762306a36Sopenharmony_ci }, 111862306a36Sopenharmony_ci { 111962306a36Sopenharmony_ci .name = "ctr(paes)", 112062306a36Sopenharmony_ci .driver_name = "ctr-paes-ccree", 112162306a36Sopenharmony_ci .blocksize = 1, 112262306a36Sopenharmony_ci .template_skcipher = { 112362306a36Sopenharmony_ci .setkey = cc_cipher_sethkey, 112462306a36Sopenharmony_ci .encrypt = cc_cipher_encrypt, 112562306a36Sopenharmony_ci .decrypt = cc_cipher_decrypt, 112662306a36Sopenharmony_ci .min_keysize = CC_HW_KEY_SIZE, 112762306a36Sopenharmony_ci .max_keysize = CC_HW_KEY_SIZE, 112862306a36Sopenharmony_ci .ivsize = AES_BLOCK_SIZE, 112962306a36Sopenharmony_ci }, 113062306a36Sopenharmony_ci .cipher_mode = DRV_CIPHER_CTR, 113162306a36Sopenharmony_ci .flow_mode = S_DIN_to_AES, 113262306a36Sopenharmony_ci .min_hw_rev = CC_HW_REV_712, 113362306a36Sopenharmony_ci .std_body = CC_STD_NIST, 113462306a36Sopenharmony_ci .sec_func = true, 113562306a36Sopenharmony_ci }, 113662306a36Sopenharmony_ci { 113762306a36Sopenharmony_ci /* See https://www.mail-archive.com/linux-crypto@vger.kernel.org/msg40576.html 113862306a36Sopenharmony_ci * for the reason why this differs from the generic 113962306a36Sopenharmony_ci * implementation. 114062306a36Sopenharmony_ci */ 114162306a36Sopenharmony_ci .name = "xts(aes)", 114262306a36Sopenharmony_ci .driver_name = "xts-aes-ccree", 114362306a36Sopenharmony_ci .blocksize = 1, 114462306a36Sopenharmony_ci .template_skcipher = { 114562306a36Sopenharmony_ci .setkey = cc_cipher_setkey, 114662306a36Sopenharmony_ci .encrypt = cc_cipher_encrypt, 114762306a36Sopenharmony_ci .decrypt = cc_cipher_decrypt, 114862306a36Sopenharmony_ci .min_keysize = AES_MIN_KEY_SIZE * 2, 114962306a36Sopenharmony_ci .max_keysize = AES_MAX_KEY_SIZE * 2, 115062306a36Sopenharmony_ci .ivsize = AES_BLOCK_SIZE, 115162306a36Sopenharmony_ci }, 115262306a36Sopenharmony_ci .cipher_mode = DRV_CIPHER_XTS, 115362306a36Sopenharmony_ci .flow_mode = S_DIN_to_AES, 115462306a36Sopenharmony_ci .min_hw_rev = CC_HW_REV_630, 115562306a36Sopenharmony_ci .std_body = CC_STD_NIST, 115662306a36Sopenharmony_ci }, 115762306a36Sopenharmony_ci { 115862306a36Sopenharmony_ci .name = "essiv(cbc(aes),sha256)", 115962306a36Sopenharmony_ci .driver_name = "essiv-aes-ccree", 116062306a36Sopenharmony_ci .blocksize = AES_BLOCK_SIZE, 116162306a36Sopenharmony_ci .template_skcipher = { 116262306a36Sopenharmony_ci .setkey = cc_cipher_setkey, 116362306a36Sopenharmony_ci .encrypt = cc_cipher_encrypt, 116462306a36Sopenharmony_ci .decrypt = cc_cipher_decrypt, 116562306a36Sopenharmony_ci .min_keysize = AES_MIN_KEY_SIZE, 116662306a36Sopenharmony_ci .max_keysize = AES_MAX_KEY_SIZE, 116762306a36Sopenharmony_ci .ivsize = AES_BLOCK_SIZE, 116862306a36Sopenharmony_ci }, 116962306a36Sopenharmony_ci .cipher_mode = DRV_CIPHER_ESSIV, 117062306a36Sopenharmony_ci .flow_mode = S_DIN_to_AES, 117162306a36Sopenharmony_ci .min_hw_rev = CC_HW_REV_712, 117262306a36Sopenharmony_ci .std_body = CC_STD_NIST, 117362306a36Sopenharmony_ci }, 117462306a36Sopenharmony_ci { 117562306a36Sopenharmony_ci .name = "ecb(aes)", 117662306a36Sopenharmony_ci .driver_name = "ecb-aes-ccree", 117762306a36Sopenharmony_ci .blocksize = AES_BLOCK_SIZE, 117862306a36Sopenharmony_ci .template_skcipher = { 117962306a36Sopenharmony_ci .setkey = cc_cipher_setkey, 118062306a36Sopenharmony_ci .encrypt = cc_cipher_encrypt, 118162306a36Sopenharmony_ci .decrypt = cc_cipher_decrypt, 118262306a36Sopenharmony_ci .min_keysize = AES_MIN_KEY_SIZE, 118362306a36Sopenharmony_ci .max_keysize = AES_MAX_KEY_SIZE, 118462306a36Sopenharmony_ci .ivsize = 0, 118562306a36Sopenharmony_ci }, 118662306a36Sopenharmony_ci .cipher_mode = DRV_CIPHER_ECB, 118762306a36Sopenharmony_ci .flow_mode = S_DIN_to_AES, 118862306a36Sopenharmony_ci .min_hw_rev = CC_HW_REV_630, 118962306a36Sopenharmony_ci .std_body = CC_STD_NIST, 119062306a36Sopenharmony_ci }, 119162306a36Sopenharmony_ci { 119262306a36Sopenharmony_ci .name = "cbc(aes)", 119362306a36Sopenharmony_ci .driver_name = "cbc-aes-ccree", 119462306a36Sopenharmony_ci .blocksize = AES_BLOCK_SIZE, 119562306a36Sopenharmony_ci .template_skcipher = { 119662306a36Sopenharmony_ci .setkey = cc_cipher_setkey, 119762306a36Sopenharmony_ci .encrypt = cc_cipher_encrypt, 119862306a36Sopenharmony_ci .decrypt = cc_cipher_decrypt, 119962306a36Sopenharmony_ci .min_keysize = AES_MIN_KEY_SIZE, 120062306a36Sopenharmony_ci .max_keysize = AES_MAX_KEY_SIZE, 120162306a36Sopenharmony_ci .ivsize = AES_BLOCK_SIZE, 120262306a36Sopenharmony_ci }, 120362306a36Sopenharmony_ci .cipher_mode = DRV_CIPHER_CBC, 120462306a36Sopenharmony_ci .flow_mode = S_DIN_to_AES, 120562306a36Sopenharmony_ci .min_hw_rev = CC_HW_REV_630, 120662306a36Sopenharmony_ci .std_body = CC_STD_NIST, 120762306a36Sopenharmony_ci }, 120862306a36Sopenharmony_ci { 120962306a36Sopenharmony_ci .name = "ofb(aes)", 121062306a36Sopenharmony_ci .driver_name = "ofb-aes-ccree", 121162306a36Sopenharmony_ci .blocksize = 1, 121262306a36Sopenharmony_ci .template_skcipher = { 121362306a36Sopenharmony_ci .setkey = cc_cipher_setkey, 121462306a36Sopenharmony_ci .encrypt = cc_cipher_encrypt, 121562306a36Sopenharmony_ci .decrypt = cc_cipher_decrypt, 121662306a36Sopenharmony_ci .min_keysize = AES_MIN_KEY_SIZE, 121762306a36Sopenharmony_ci .max_keysize = AES_MAX_KEY_SIZE, 121862306a36Sopenharmony_ci .ivsize = AES_BLOCK_SIZE, 121962306a36Sopenharmony_ci }, 122062306a36Sopenharmony_ci .cipher_mode = DRV_CIPHER_OFB, 122162306a36Sopenharmony_ci .flow_mode = S_DIN_to_AES, 122262306a36Sopenharmony_ci .min_hw_rev = CC_HW_REV_630, 122362306a36Sopenharmony_ci .std_body = CC_STD_NIST, 122462306a36Sopenharmony_ci }, 122562306a36Sopenharmony_ci { 122662306a36Sopenharmony_ci .name = "cts(cbc(aes))", 122762306a36Sopenharmony_ci .driver_name = "cts-cbc-aes-ccree", 122862306a36Sopenharmony_ci .blocksize = AES_BLOCK_SIZE, 122962306a36Sopenharmony_ci .template_skcipher = { 123062306a36Sopenharmony_ci .setkey = cc_cipher_setkey, 123162306a36Sopenharmony_ci .encrypt = cc_cipher_encrypt, 123262306a36Sopenharmony_ci .decrypt = cc_cipher_decrypt, 123362306a36Sopenharmony_ci .min_keysize = AES_MIN_KEY_SIZE, 123462306a36Sopenharmony_ci .max_keysize = AES_MAX_KEY_SIZE, 123562306a36Sopenharmony_ci .ivsize = AES_BLOCK_SIZE, 123662306a36Sopenharmony_ci }, 123762306a36Sopenharmony_ci .cipher_mode = DRV_CIPHER_CBC_CTS, 123862306a36Sopenharmony_ci .flow_mode = S_DIN_to_AES, 123962306a36Sopenharmony_ci .min_hw_rev = CC_HW_REV_630, 124062306a36Sopenharmony_ci .std_body = CC_STD_NIST, 124162306a36Sopenharmony_ci }, 124262306a36Sopenharmony_ci { 124362306a36Sopenharmony_ci .name = "ctr(aes)", 124462306a36Sopenharmony_ci .driver_name = "ctr-aes-ccree", 124562306a36Sopenharmony_ci .blocksize = 1, 124662306a36Sopenharmony_ci .template_skcipher = { 124762306a36Sopenharmony_ci .setkey = cc_cipher_setkey, 124862306a36Sopenharmony_ci .encrypt = cc_cipher_encrypt, 124962306a36Sopenharmony_ci .decrypt = cc_cipher_decrypt, 125062306a36Sopenharmony_ci .min_keysize = AES_MIN_KEY_SIZE, 125162306a36Sopenharmony_ci .max_keysize = AES_MAX_KEY_SIZE, 125262306a36Sopenharmony_ci .ivsize = AES_BLOCK_SIZE, 125362306a36Sopenharmony_ci }, 125462306a36Sopenharmony_ci .cipher_mode = DRV_CIPHER_CTR, 125562306a36Sopenharmony_ci .flow_mode = S_DIN_to_AES, 125662306a36Sopenharmony_ci .min_hw_rev = CC_HW_REV_630, 125762306a36Sopenharmony_ci .std_body = CC_STD_NIST, 125862306a36Sopenharmony_ci }, 125962306a36Sopenharmony_ci { 126062306a36Sopenharmony_ci .name = "cbc(des3_ede)", 126162306a36Sopenharmony_ci .driver_name = "cbc-3des-ccree", 126262306a36Sopenharmony_ci .blocksize = DES3_EDE_BLOCK_SIZE, 126362306a36Sopenharmony_ci .template_skcipher = { 126462306a36Sopenharmony_ci .setkey = cc_cipher_setkey, 126562306a36Sopenharmony_ci .encrypt = cc_cipher_encrypt, 126662306a36Sopenharmony_ci .decrypt = cc_cipher_decrypt, 126762306a36Sopenharmony_ci .min_keysize = DES3_EDE_KEY_SIZE, 126862306a36Sopenharmony_ci .max_keysize = DES3_EDE_KEY_SIZE, 126962306a36Sopenharmony_ci .ivsize = DES3_EDE_BLOCK_SIZE, 127062306a36Sopenharmony_ci }, 127162306a36Sopenharmony_ci .cipher_mode = DRV_CIPHER_CBC, 127262306a36Sopenharmony_ci .flow_mode = S_DIN_to_DES, 127362306a36Sopenharmony_ci .min_hw_rev = CC_HW_REV_630, 127462306a36Sopenharmony_ci .std_body = CC_STD_NIST, 127562306a36Sopenharmony_ci }, 127662306a36Sopenharmony_ci { 127762306a36Sopenharmony_ci .name = "ecb(des3_ede)", 127862306a36Sopenharmony_ci .driver_name = "ecb-3des-ccree", 127962306a36Sopenharmony_ci .blocksize = DES3_EDE_BLOCK_SIZE, 128062306a36Sopenharmony_ci .template_skcipher = { 128162306a36Sopenharmony_ci .setkey = cc_cipher_setkey, 128262306a36Sopenharmony_ci .encrypt = cc_cipher_encrypt, 128362306a36Sopenharmony_ci .decrypt = cc_cipher_decrypt, 128462306a36Sopenharmony_ci .min_keysize = DES3_EDE_KEY_SIZE, 128562306a36Sopenharmony_ci .max_keysize = DES3_EDE_KEY_SIZE, 128662306a36Sopenharmony_ci .ivsize = 0, 128762306a36Sopenharmony_ci }, 128862306a36Sopenharmony_ci .cipher_mode = DRV_CIPHER_ECB, 128962306a36Sopenharmony_ci .flow_mode = S_DIN_to_DES, 129062306a36Sopenharmony_ci .min_hw_rev = CC_HW_REV_630, 129162306a36Sopenharmony_ci .std_body = CC_STD_NIST, 129262306a36Sopenharmony_ci }, 129362306a36Sopenharmony_ci { 129462306a36Sopenharmony_ci .name = "cbc(des)", 129562306a36Sopenharmony_ci .driver_name = "cbc-des-ccree", 129662306a36Sopenharmony_ci .blocksize = DES_BLOCK_SIZE, 129762306a36Sopenharmony_ci .template_skcipher = { 129862306a36Sopenharmony_ci .setkey = cc_cipher_setkey, 129962306a36Sopenharmony_ci .encrypt = cc_cipher_encrypt, 130062306a36Sopenharmony_ci .decrypt = cc_cipher_decrypt, 130162306a36Sopenharmony_ci .min_keysize = DES_KEY_SIZE, 130262306a36Sopenharmony_ci .max_keysize = DES_KEY_SIZE, 130362306a36Sopenharmony_ci .ivsize = DES_BLOCK_SIZE, 130462306a36Sopenharmony_ci }, 130562306a36Sopenharmony_ci .cipher_mode = DRV_CIPHER_CBC, 130662306a36Sopenharmony_ci .flow_mode = S_DIN_to_DES, 130762306a36Sopenharmony_ci .min_hw_rev = CC_HW_REV_630, 130862306a36Sopenharmony_ci .std_body = CC_STD_NIST, 130962306a36Sopenharmony_ci }, 131062306a36Sopenharmony_ci { 131162306a36Sopenharmony_ci .name = "ecb(des)", 131262306a36Sopenharmony_ci .driver_name = "ecb-des-ccree", 131362306a36Sopenharmony_ci .blocksize = DES_BLOCK_SIZE, 131462306a36Sopenharmony_ci .template_skcipher = { 131562306a36Sopenharmony_ci .setkey = cc_cipher_setkey, 131662306a36Sopenharmony_ci .encrypt = cc_cipher_encrypt, 131762306a36Sopenharmony_ci .decrypt = cc_cipher_decrypt, 131862306a36Sopenharmony_ci .min_keysize = DES_KEY_SIZE, 131962306a36Sopenharmony_ci .max_keysize = DES_KEY_SIZE, 132062306a36Sopenharmony_ci .ivsize = 0, 132162306a36Sopenharmony_ci }, 132262306a36Sopenharmony_ci .cipher_mode = DRV_CIPHER_ECB, 132362306a36Sopenharmony_ci .flow_mode = S_DIN_to_DES, 132462306a36Sopenharmony_ci .min_hw_rev = CC_HW_REV_630, 132562306a36Sopenharmony_ci .std_body = CC_STD_NIST, 132662306a36Sopenharmony_ci }, 132762306a36Sopenharmony_ci { 132862306a36Sopenharmony_ci .name = "cbc(sm4)", 132962306a36Sopenharmony_ci .driver_name = "cbc-sm4-ccree", 133062306a36Sopenharmony_ci .blocksize = SM4_BLOCK_SIZE, 133162306a36Sopenharmony_ci .template_skcipher = { 133262306a36Sopenharmony_ci .setkey = cc_cipher_setkey, 133362306a36Sopenharmony_ci .encrypt = cc_cipher_encrypt, 133462306a36Sopenharmony_ci .decrypt = cc_cipher_decrypt, 133562306a36Sopenharmony_ci .min_keysize = SM4_KEY_SIZE, 133662306a36Sopenharmony_ci .max_keysize = SM4_KEY_SIZE, 133762306a36Sopenharmony_ci .ivsize = SM4_BLOCK_SIZE, 133862306a36Sopenharmony_ci }, 133962306a36Sopenharmony_ci .cipher_mode = DRV_CIPHER_CBC, 134062306a36Sopenharmony_ci .flow_mode = S_DIN_to_SM4, 134162306a36Sopenharmony_ci .min_hw_rev = CC_HW_REV_713, 134262306a36Sopenharmony_ci .std_body = CC_STD_OSCCA, 134362306a36Sopenharmony_ci }, 134462306a36Sopenharmony_ci { 134562306a36Sopenharmony_ci .name = "ecb(sm4)", 134662306a36Sopenharmony_ci .driver_name = "ecb-sm4-ccree", 134762306a36Sopenharmony_ci .blocksize = SM4_BLOCK_SIZE, 134862306a36Sopenharmony_ci .template_skcipher = { 134962306a36Sopenharmony_ci .setkey = cc_cipher_setkey, 135062306a36Sopenharmony_ci .encrypt = cc_cipher_encrypt, 135162306a36Sopenharmony_ci .decrypt = cc_cipher_decrypt, 135262306a36Sopenharmony_ci .min_keysize = SM4_KEY_SIZE, 135362306a36Sopenharmony_ci .max_keysize = SM4_KEY_SIZE, 135462306a36Sopenharmony_ci .ivsize = 0, 135562306a36Sopenharmony_ci }, 135662306a36Sopenharmony_ci .cipher_mode = DRV_CIPHER_ECB, 135762306a36Sopenharmony_ci .flow_mode = S_DIN_to_SM4, 135862306a36Sopenharmony_ci .min_hw_rev = CC_HW_REV_713, 135962306a36Sopenharmony_ci .std_body = CC_STD_OSCCA, 136062306a36Sopenharmony_ci }, 136162306a36Sopenharmony_ci { 136262306a36Sopenharmony_ci .name = "ctr(sm4)", 136362306a36Sopenharmony_ci .driver_name = "ctr-sm4-ccree", 136462306a36Sopenharmony_ci .blocksize = 1, 136562306a36Sopenharmony_ci .template_skcipher = { 136662306a36Sopenharmony_ci .setkey = cc_cipher_setkey, 136762306a36Sopenharmony_ci .encrypt = cc_cipher_encrypt, 136862306a36Sopenharmony_ci .decrypt = cc_cipher_decrypt, 136962306a36Sopenharmony_ci .min_keysize = SM4_KEY_SIZE, 137062306a36Sopenharmony_ci .max_keysize = SM4_KEY_SIZE, 137162306a36Sopenharmony_ci .ivsize = SM4_BLOCK_SIZE, 137262306a36Sopenharmony_ci }, 137362306a36Sopenharmony_ci .cipher_mode = DRV_CIPHER_CTR, 137462306a36Sopenharmony_ci .flow_mode = S_DIN_to_SM4, 137562306a36Sopenharmony_ci .min_hw_rev = CC_HW_REV_713, 137662306a36Sopenharmony_ci .std_body = CC_STD_OSCCA, 137762306a36Sopenharmony_ci }, 137862306a36Sopenharmony_ci { 137962306a36Sopenharmony_ci .name = "cbc(psm4)", 138062306a36Sopenharmony_ci .driver_name = "cbc-psm4-ccree", 138162306a36Sopenharmony_ci .blocksize = SM4_BLOCK_SIZE, 138262306a36Sopenharmony_ci .template_skcipher = { 138362306a36Sopenharmony_ci .setkey = cc_cipher_sethkey, 138462306a36Sopenharmony_ci .encrypt = cc_cipher_encrypt, 138562306a36Sopenharmony_ci .decrypt = cc_cipher_decrypt, 138662306a36Sopenharmony_ci .min_keysize = CC_HW_KEY_SIZE, 138762306a36Sopenharmony_ci .max_keysize = CC_HW_KEY_SIZE, 138862306a36Sopenharmony_ci .ivsize = SM4_BLOCK_SIZE, 138962306a36Sopenharmony_ci }, 139062306a36Sopenharmony_ci .cipher_mode = DRV_CIPHER_CBC, 139162306a36Sopenharmony_ci .flow_mode = S_DIN_to_SM4, 139262306a36Sopenharmony_ci .min_hw_rev = CC_HW_REV_713, 139362306a36Sopenharmony_ci .std_body = CC_STD_OSCCA, 139462306a36Sopenharmony_ci .sec_func = true, 139562306a36Sopenharmony_ci }, 139662306a36Sopenharmony_ci { 139762306a36Sopenharmony_ci .name = "ctr(psm4)", 139862306a36Sopenharmony_ci .driver_name = "ctr-psm4-ccree", 139962306a36Sopenharmony_ci .blocksize = SM4_BLOCK_SIZE, 140062306a36Sopenharmony_ci .template_skcipher = { 140162306a36Sopenharmony_ci .setkey = cc_cipher_sethkey, 140262306a36Sopenharmony_ci .encrypt = cc_cipher_encrypt, 140362306a36Sopenharmony_ci .decrypt = cc_cipher_decrypt, 140462306a36Sopenharmony_ci .min_keysize = CC_HW_KEY_SIZE, 140562306a36Sopenharmony_ci .max_keysize = CC_HW_KEY_SIZE, 140662306a36Sopenharmony_ci .ivsize = SM4_BLOCK_SIZE, 140762306a36Sopenharmony_ci }, 140862306a36Sopenharmony_ci .cipher_mode = DRV_CIPHER_CTR, 140962306a36Sopenharmony_ci .flow_mode = S_DIN_to_SM4, 141062306a36Sopenharmony_ci .min_hw_rev = CC_HW_REV_713, 141162306a36Sopenharmony_ci .std_body = CC_STD_OSCCA, 141262306a36Sopenharmony_ci .sec_func = true, 141362306a36Sopenharmony_ci }, 141462306a36Sopenharmony_ci}; 141562306a36Sopenharmony_ci 141662306a36Sopenharmony_cistatic struct cc_crypto_alg *cc_create_alg(const struct cc_alg_template *tmpl, 141762306a36Sopenharmony_ci struct device *dev) 141862306a36Sopenharmony_ci{ 141962306a36Sopenharmony_ci struct cc_crypto_alg *t_alg; 142062306a36Sopenharmony_ci struct skcipher_alg *alg; 142162306a36Sopenharmony_ci 142262306a36Sopenharmony_ci t_alg = devm_kzalloc(dev, sizeof(*t_alg), GFP_KERNEL); 142362306a36Sopenharmony_ci if (!t_alg) 142462306a36Sopenharmony_ci return ERR_PTR(-ENOMEM); 142562306a36Sopenharmony_ci 142662306a36Sopenharmony_ci alg = &t_alg->skcipher_alg; 142762306a36Sopenharmony_ci 142862306a36Sopenharmony_ci memcpy(alg, &tmpl->template_skcipher, sizeof(*alg)); 142962306a36Sopenharmony_ci 143062306a36Sopenharmony_ci snprintf(alg->base.cra_name, CRYPTO_MAX_ALG_NAME, "%s", tmpl->name); 143162306a36Sopenharmony_ci snprintf(alg->base.cra_driver_name, CRYPTO_MAX_ALG_NAME, "%s", 143262306a36Sopenharmony_ci tmpl->driver_name); 143362306a36Sopenharmony_ci alg->base.cra_module = THIS_MODULE; 143462306a36Sopenharmony_ci alg->base.cra_priority = CC_CRA_PRIO; 143562306a36Sopenharmony_ci alg->base.cra_blocksize = tmpl->blocksize; 143662306a36Sopenharmony_ci alg->base.cra_alignmask = 0; 143762306a36Sopenharmony_ci alg->base.cra_ctxsize = sizeof(struct cc_cipher_ctx); 143862306a36Sopenharmony_ci 143962306a36Sopenharmony_ci alg->base.cra_init = cc_cipher_init; 144062306a36Sopenharmony_ci alg->base.cra_exit = cc_cipher_exit; 144162306a36Sopenharmony_ci alg->base.cra_flags = CRYPTO_ALG_ASYNC | CRYPTO_ALG_KERN_DRIVER_ONLY; 144262306a36Sopenharmony_ci 144362306a36Sopenharmony_ci t_alg->cipher_mode = tmpl->cipher_mode; 144462306a36Sopenharmony_ci t_alg->flow_mode = tmpl->flow_mode; 144562306a36Sopenharmony_ci 144662306a36Sopenharmony_ci return t_alg; 144762306a36Sopenharmony_ci} 144862306a36Sopenharmony_ci 144962306a36Sopenharmony_ciint cc_cipher_free(struct cc_drvdata *drvdata) 145062306a36Sopenharmony_ci{ 145162306a36Sopenharmony_ci struct cc_crypto_alg *t_alg, *n; 145262306a36Sopenharmony_ci 145362306a36Sopenharmony_ci /* Remove registered algs */ 145462306a36Sopenharmony_ci list_for_each_entry_safe(t_alg, n, &drvdata->alg_list, entry) { 145562306a36Sopenharmony_ci crypto_unregister_skcipher(&t_alg->skcipher_alg); 145662306a36Sopenharmony_ci list_del(&t_alg->entry); 145762306a36Sopenharmony_ci } 145862306a36Sopenharmony_ci return 0; 145962306a36Sopenharmony_ci} 146062306a36Sopenharmony_ci 146162306a36Sopenharmony_ciint cc_cipher_alloc(struct cc_drvdata *drvdata) 146262306a36Sopenharmony_ci{ 146362306a36Sopenharmony_ci struct cc_crypto_alg *t_alg; 146462306a36Sopenharmony_ci struct device *dev = drvdata_to_dev(drvdata); 146562306a36Sopenharmony_ci int rc = -ENOMEM; 146662306a36Sopenharmony_ci int alg; 146762306a36Sopenharmony_ci 146862306a36Sopenharmony_ci INIT_LIST_HEAD(&drvdata->alg_list); 146962306a36Sopenharmony_ci 147062306a36Sopenharmony_ci /* Linux crypto */ 147162306a36Sopenharmony_ci dev_dbg(dev, "Number of algorithms = %zu\n", 147262306a36Sopenharmony_ci ARRAY_SIZE(skcipher_algs)); 147362306a36Sopenharmony_ci for (alg = 0; alg < ARRAY_SIZE(skcipher_algs); alg++) { 147462306a36Sopenharmony_ci if ((skcipher_algs[alg].min_hw_rev > drvdata->hw_rev) || 147562306a36Sopenharmony_ci !(drvdata->std_bodies & skcipher_algs[alg].std_body) || 147662306a36Sopenharmony_ci (drvdata->sec_disabled && skcipher_algs[alg].sec_func)) 147762306a36Sopenharmony_ci continue; 147862306a36Sopenharmony_ci 147962306a36Sopenharmony_ci dev_dbg(dev, "creating %s\n", skcipher_algs[alg].driver_name); 148062306a36Sopenharmony_ci t_alg = cc_create_alg(&skcipher_algs[alg], dev); 148162306a36Sopenharmony_ci if (IS_ERR(t_alg)) { 148262306a36Sopenharmony_ci rc = PTR_ERR(t_alg); 148362306a36Sopenharmony_ci dev_err(dev, "%s alg allocation failed\n", 148462306a36Sopenharmony_ci skcipher_algs[alg].driver_name); 148562306a36Sopenharmony_ci goto fail0; 148662306a36Sopenharmony_ci } 148762306a36Sopenharmony_ci t_alg->drvdata = drvdata; 148862306a36Sopenharmony_ci 148962306a36Sopenharmony_ci dev_dbg(dev, "registering %s\n", 149062306a36Sopenharmony_ci skcipher_algs[alg].driver_name); 149162306a36Sopenharmony_ci rc = crypto_register_skcipher(&t_alg->skcipher_alg); 149262306a36Sopenharmony_ci dev_dbg(dev, "%s alg registration rc = %x\n", 149362306a36Sopenharmony_ci t_alg->skcipher_alg.base.cra_driver_name, rc); 149462306a36Sopenharmony_ci if (rc) { 149562306a36Sopenharmony_ci dev_err(dev, "%s alg registration failed\n", 149662306a36Sopenharmony_ci t_alg->skcipher_alg.base.cra_driver_name); 149762306a36Sopenharmony_ci goto fail0; 149862306a36Sopenharmony_ci } 149962306a36Sopenharmony_ci 150062306a36Sopenharmony_ci list_add_tail(&t_alg->entry, &drvdata->alg_list); 150162306a36Sopenharmony_ci dev_dbg(dev, "Registered %s\n", 150262306a36Sopenharmony_ci t_alg->skcipher_alg.base.cra_driver_name); 150362306a36Sopenharmony_ci } 150462306a36Sopenharmony_ci return 0; 150562306a36Sopenharmony_ci 150662306a36Sopenharmony_cifail0: 150762306a36Sopenharmony_ci cc_cipher_free(drvdata); 150862306a36Sopenharmony_ci return rc; 150962306a36Sopenharmony_ci} 1510