163ee04c8SGilad Ben-Yossef // SPDX-License-Identifier: GPL-2.0 263ee04c8SGilad Ben-Yossef /* Copyright (C) 2012-2018 ARM Limited or its affiliates. */ 363ee04c8SGilad Ben-Yossef 463ee04c8SGilad Ben-Yossef #include <linux/kernel.h> 563ee04c8SGilad Ben-Yossef #include <linux/module.h> 663ee04c8SGilad Ben-Yossef #include <crypto/algapi.h> 763ee04c8SGilad Ben-Yossef #include <crypto/internal/skcipher.h> 863ee04c8SGilad Ben-Yossef #include <crypto/des.h> 963ee04c8SGilad Ben-Yossef #include <crypto/xts.h> 1063ee04c8SGilad Ben-Yossef #include <crypto/scatterwalk.h> 1163ee04c8SGilad Ben-Yossef 1263ee04c8SGilad Ben-Yossef #include "cc_driver.h" 1363ee04c8SGilad Ben-Yossef #include "cc_lli_defs.h" 1463ee04c8SGilad Ben-Yossef #include "cc_buffer_mgr.h" 1563ee04c8SGilad Ben-Yossef #include "cc_cipher.h" 1663ee04c8SGilad Ben-Yossef #include "cc_request_mgr.h" 1763ee04c8SGilad Ben-Yossef 1863ee04c8SGilad Ben-Yossef #define MAX_ABLKCIPHER_SEQ_LEN 6 1963ee04c8SGilad Ben-Yossef 2063ee04c8SGilad Ben-Yossef #define template_skcipher template_u.skcipher 2163ee04c8SGilad Ben-Yossef 2263ee04c8SGilad Ben-Yossef #define CC_MIN_AES_XTS_SIZE 0x10 2363ee04c8SGilad Ben-Yossef #define CC_MAX_AES_XTS_SIZE 0x2000 2463ee04c8SGilad Ben-Yossef struct cc_cipher_handle { 2563ee04c8SGilad Ben-Yossef struct list_head alg_list; 2663ee04c8SGilad Ben-Yossef }; 2763ee04c8SGilad Ben-Yossef 2863ee04c8SGilad Ben-Yossef struct cc_user_key_info { 2963ee04c8SGilad Ben-Yossef u8 *key; 3063ee04c8SGilad Ben-Yossef dma_addr_t key_dma_addr; 3163ee04c8SGilad Ben-Yossef }; 3263ee04c8SGilad Ben-Yossef 3363ee04c8SGilad Ben-Yossef struct cc_hw_key_info { 3463ee04c8SGilad Ben-Yossef enum cc_hw_crypto_key key1_slot; 3563ee04c8SGilad Ben-Yossef enum cc_hw_crypto_key key2_slot; 3663ee04c8SGilad Ben-Yossef }; 3763ee04c8SGilad Ben-Yossef 3863ee04c8SGilad Ben-Yossef struct cc_cipher_ctx { 3963ee04c8SGilad Ben-Yossef struct cc_drvdata *drvdata; 4063ee04c8SGilad Ben-Yossef int keylen; 4163ee04c8SGilad Ben-Yossef int key_round_number; 4263ee04c8SGilad Ben-Yossef int cipher_mode; 4363ee04c8SGilad Ben-Yossef int flow_mode; 4463ee04c8SGilad Ben-Yossef unsigned int flags; 4563ee04c8SGilad Ben-Yossef struct cc_user_key_info user; 4663ee04c8SGilad Ben-Yossef struct cc_hw_key_info hw; 4763ee04c8SGilad Ben-Yossef struct crypto_shash *shash_tfm; 4863ee04c8SGilad Ben-Yossef }; 4963ee04c8SGilad Ben-Yossef 5063ee04c8SGilad Ben-Yossef static void cc_cipher_complete(struct device *dev, void *cc_req, int err); 5163ee04c8SGilad Ben-Yossef 5263ee04c8SGilad Ben-Yossef static int validate_keys_sizes(struct cc_cipher_ctx *ctx_p, u32 size) 5363ee04c8SGilad Ben-Yossef { 5463ee04c8SGilad Ben-Yossef switch (ctx_p->flow_mode) { 5563ee04c8SGilad Ben-Yossef case S_DIN_to_AES: 5663ee04c8SGilad Ben-Yossef switch (size) { 5763ee04c8SGilad Ben-Yossef case CC_AES_128_BIT_KEY_SIZE: 5863ee04c8SGilad Ben-Yossef case CC_AES_192_BIT_KEY_SIZE: 5963ee04c8SGilad Ben-Yossef if (ctx_p->cipher_mode != DRV_CIPHER_XTS && 6063ee04c8SGilad Ben-Yossef ctx_p->cipher_mode != DRV_CIPHER_ESSIV && 6163ee04c8SGilad Ben-Yossef ctx_p->cipher_mode != DRV_CIPHER_BITLOCKER) 6263ee04c8SGilad Ben-Yossef return 0; 6363ee04c8SGilad Ben-Yossef break; 6463ee04c8SGilad Ben-Yossef case CC_AES_256_BIT_KEY_SIZE: 6563ee04c8SGilad Ben-Yossef return 0; 6663ee04c8SGilad Ben-Yossef case (CC_AES_192_BIT_KEY_SIZE * 2): 6763ee04c8SGilad Ben-Yossef case (CC_AES_256_BIT_KEY_SIZE * 2): 6863ee04c8SGilad Ben-Yossef if (ctx_p->cipher_mode == DRV_CIPHER_XTS || 6963ee04c8SGilad Ben-Yossef ctx_p->cipher_mode == DRV_CIPHER_ESSIV || 7063ee04c8SGilad Ben-Yossef ctx_p->cipher_mode == DRV_CIPHER_BITLOCKER) 7163ee04c8SGilad Ben-Yossef return 0; 7263ee04c8SGilad Ben-Yossef break; 7363ee04c8SGilad Ben-Yossef default: 7463ee04c8SGilad Ben-Yossef break; 7563ee04c8SGilad Ben-Yossef } 7663ee04c8SGilad Ben-Yossef case S_DIN_to_DES: 7763ee04c8SGilad Ben-Yossef if (size == DES3_EDE_KEY_SIZE || size == DES_KEY_SIZE) 7863ee04c8SGilad Ben-Yossef return 0; 7963ee04c8SGilad Ben-Yossef break; 8063ee04c8SGilad Ben-Yossef default: 8163ee04c8SGilad Ben-Yossef break; 8263ee04c8SGilad Ben-Yossef } 8363ee04c8SGilad Ben-Yossef return -EINVAL; 8463ee04c8SGilad Ben-Yossef } 8563ee04c8SGilad Ben-Yossef 8663ee04c8SGilad Ben-Yossef static int validate_data_size(struct cc_cipher_ctx *ctx_p, 8763ee04c8SGilad Ben-Yossef unsigned int size) 8863ee04c8SGilad Ben-Yossef { 8963ee04c8SGilad Ben-Yossef switch (ctx_p->flow_mode) { 9063ee04c8SGilad Ben-Yossef case S_DIN_to_AES: 9163ee04c8SGilad Ben-Yossef switch (ctx_p->cipher_mode) { 9263ee04c8SGilad Ben-Yossef case DRV_CIPHER_XTS: 9363ee04c8SGilad Ben-Yossef if (size >= CC_MIN_AES_XTS_SIZE && 9463ee04c8SGilad Ben-Yossef size <= CC_MAX_AES_XTS_SIZE && 9563ee04c8SGilad Ben-Yossef IS_ALIGNED(size, AES_BLOCK_SIZE)) 9663ee04c8SGilad Ben-Yossef return 0; 9763ee04c8SGilad Ben-Yossef break; 9863ee04c8SGilad Ben-Yossef case DRV_CIPHER_CBC_CTS: 9963ee04c8SGilad Ben-Yossef if (size >= AES_BLOCK_SIZE) 10063ee04c8SGilad Ben-Yossef return 0; 10163ee04c8SGilad Ben-Yossef break; 10263ee04c8SGilad Ben-Yossef case DRV_CIPHER_OFB: 10363ee04c8SGilad Ben-Yossef case DRV_CIPHER_CTR: 10463ee04c8SGilad Ben-Yossef return 0; 10563ee04c8SGilad Ben-Yossef case DRV_CIPHER_ECB: 10663ee04c8SGilad Ben-Yossef case DRV_CIPHER_CBC: 10763ee04c8SGilad Ben-Yossef case DRV_CIPHER_ESSIV: 10863ee04c8SGilad Ben-Yossef case DRV_CIPHER_BITLOCKER: 10963ee04c8SGilad Ben-Yossef if (IS_ALIGNED(size, AES_BLOCK_SIZE)) 11063ee04c8SGilad Ben-Yossef return 0; 11163ee04c8SGilad Ben-Yossef break; 11263ee04c8SGilad Ben-Yossef default: 11363ee04c8SGilad Ben-Yossef break; 11463ee04c8SGilad Ben-Yossef } 11563ee04c8SGilad Ben-Yossef break; 11663ee04c8SGilad Ben-Yossef case S_DIN_to_DES: 11763ee04c8SGilad Ben-Yossef if (IS_ALIGNED(size, DES_BLOCK_SIZE)) 11863ee04c8SGilad Ben-Yossef return 0; 11963ee04c8SGilad Ben-Yossef break; 12063ee04c8SGilad Ben-Yossef default: 12163ee04c8SGilad Ben-Yossef break; 12263ee04c8SGilad Ben-Yossef } 12363ee04c8SGilad Ben-Yossef return -EINVAL; 12463ee04c8SGilad Ben-Yossef } 12563ee04c8SGilad Ben-Yossef 12663ee04c8SGilad Ben-Yossef static int cc_cipher_init(struct crypto_tfm *tfm) 12763ee04c8SGilad Ben-Yossef { 12863ee04c8SGilad Ben-Yossef struct cc_cipher_ctx *ctx_p = crypto_tfm_ctx(tfm); 12963ee04c8SGilad Ben-Yossef struct cc_crypto_alg *cc_alg = 13063ee04c8SGilad Ben-Yossef container_of(tfm->__crt_alg, struct cc_crypto_alg, 13163ee04c8SGilad Ben-Yossef skcipher_alg.base); 13263ee04c8SGilad Ben-Yossef struct device *dev = drvdata_to_dev(cc_alg->drvdata); 13363ee04c8SGilad Ben-Yossef unsigned int max_key_buf_size = cc_alg->skcipher_alg.max_keysize; 13463ee04c8SGilad Ben-Yossef int rc = 0; 13563ee04c8SGilad Ben-Yossef 13663ee04c8SGilad Ben-Yossef dev_dbg(dev, "Initializing context @%p for %s\n", ctx_p, 13763ee04c8SGilad Ben-Yossef crypto_tfm_alg_name(tfm)); 13863ee04c8SGilad Ben-Yossef 13963ee04c8SGilad Ben-Yossef crypto_skcipher_set_reqsize(__crypto_skcipher_cast(tfm), 14063ee04c8SGilad Ben-Yossef sizeof(struct cipher_req_ctx)); 14163ee04c8SGilad Ben-Yossef 14263ee04c8SGilad Ben-Yossef ctx_p->cipher_mode = cc_alg->cipher_mode; 14363ee04c8SGilad Ben-Yossef ctx_p->flow_mode = cc_alg->flow_mode; 14463ee04c8SGilad Ben-Yossef ctx_p->drvdata = cc_alg->drvdata; 14563ee04c8SGilad Ben-Yossef 14663ee04c8SGilad Ben-Yossef /* Allocate key buffer, cache line aligned */ 14763ee04c8SGilad Ben-Yossef ctx_p->user.key = kmalloc(max_key_buf_size, GFP_KERNEL); 14863ee04c8SGilad Ben-Yossef if (!ctx_p->user.key) 14963ee04c8SGilad Ben-Yossef return -ENOMEM; 15063ee04c8SGilad Ben-Yossef 15163ee04c8SGilad Ben-Yossef dev_dbg(dev, "Allocated key buffer in context. key=@%p\n", 15263ee04c8SGilad Ben-Yossef ctx_p->user.key); 15363ee04c8SGilad Ben-Yossef 15463ee04c8SGilad Ben-Yossef /* Map key buffer */ 15563ee04c8SGilad Ben-Yossef ctx_p->user.key_dma_addr = dma_map_single(dev, (void *)ctx_p->user.key, 15663ee04c8SGilad Ben-Yossef max_key_buf_size, 15763ee04c8SGilad Ben-Yossef DMA_TO_DEVICE); 15863ee04c8SGilad Ben-Yossef if (dma_mapping_error(dev, ctx_p->user.key_dma_addr)) { 15963ee04c8SGilad Ben-Yossef dev_err(dev, "Mapping Key %u B at va=%pK for DMA failed\n", 16063ee04c8SGilad Ben-Yossef max_key_buf_size, ctx_p->user.key); 16163ee04c8SGilad Ben-Yossef return -ENOMEM; 16263ee04c8SGilad Ben-Yossef } 16363ee04c8SGilad Ben-Yossef dev_dbg(dev, "Mapped key %u B at va=%pK to dma=%pad\n", 16463ee04c8SGilad Ben-Yossef max_key_buf_size, ctx_p->user.key, &ctx_p->user.key_dma_addr); 16563ee04c8SGilad Ben-Yossef 16663ee04c8SGilad Ben-Yossef if (ctx_p->cipher_mode == DRV_CIPHER_ESSIV) { 16763ee04c8SGilad Ben-Yossef /* Alloc hash tfm for essiv */ 16863ee04c8SGilad Ben-Yossef ctx_p->shash_tfm = crypto_alloc_shash("sha256-generic", 0, 0); 16963ee04c8SGilad Ben-Yossef if (IS_ERR(ctx_p->shash_tfm)) { 17063ee04c8SGilad Ben-Yossef dev_err(dev, "Error allocating hash tfm for ESSIV.\n"); 17163ee04c8SGilad Ben-Yossef return PTR_ERR(ctx_p->shash_tfm); 17263ee04c8SGilad Ben-Yossef } 17363ee04c8SGilad Ben-Yossef } 17463ee04c8SGilad Ben-Yossef 17563ee04c8SGilad Ben-Yossef return rc; 17663ee04c8SGilad Ben-Yossef } 17763ee04c8SGilad Ben-Yossef 17863ee04c8SGilad Ben-Yossef static void cc_cipher_exit(struct crypto_tfm *tfm) 17963ee04c8SGilad Ben-Yossef { 18063ee04c8SGilad Ben-Yossef struct crypto_alg *alg = tfm->__crt_alg; 18163ee04c8SGilad Ben-Yossef struct cc_crypto_alg *cc_alg = 18263ee04c8SGilad Ben-Yossef container_of(alg, struct cc_crypto_alg, 18363ee04c8SGilad Ben-Yossef skcipher_alg.base); 18463ee04c8SGilad Ben-Yossef unsigned int max_key_buf_size = cc_alg->skcipher_alg.max_keysize; 18563ee04c8SGilad Ben-Yossef struct cc_cipher_ctx *ctx_p = crypto_tfm_ctx(tfm); 18663ee04c8SGilad Ben-Yossef struct device *dev = drvdata_to_dev(ctx_p->drvdata); 18763ee04c8SGilad Ben-Yossef 18863ee04c8SGilad Ben-Yossef dev_dbg(dev, "Clearing context @%p for %s\n", 18963ee04c8SGilad Ben-Yossef crypto_tfm_ctx(tfm), crypto_tfm_alg_name(tfm)); 19063ee04c8SGilad Ben-Yossef 19163ee04c8SGilad Ben-Yossef if (ctx_p->cipher_mode == DRV_CIPHER_ESSIV) { 19263ee04c8SGilad Ben-Yossef /* Free hash tfm for essiv */ 19363ee04c8SGilad Ben-Yossef crypto_free_shash(ctx_p->shash_tfm); 19463ee04c8SGilad Ben-Yossef ctx_p->shash_tfm = NULL; 19563ee04c8SGilad Ben-Yossef } 19663ee04c8SGilad Ben-Yossef 19763ee04c8SGilad Ben-Yossef /* Unmap key buffer */ 19863ee04c8SGilad Ben-Yossef dma_unmap_single(dev, ctx_p->user.key_dma_addr, max_key_buf_size, 19963ee04c8SGilad Ben-Yossef DMA_TO_DEVICE); 20063ee04c8SGilad Ben-Yossef dev_dbg(dev, "Unmapped key buffer key_dma_addr=%pad\n", 20163ee04c8SGilad Ben-Yossef &ctx_p->user.key_dma_addr); 20263ee04c8SGilad Ben-Yossef 20363ee04c8SGilad Ben-Yossef /* Free key buffer in context */ 20463ee04c8SGilad Ben-Yossef kzfree(ctx_p->user.key); 20563ee04c8SGilad Ben-Yossef dev_dbg(dev, "Free key buffer in context. key=@%p\n", ctx_p->user.key); 20663ee04c8SGilad Ben-Yossef } 20763ee04c8SGilad Ben-Yossef 20863ee04c8SGilad Ben-Yossef struct tdes_keys { 20963ee04c8SGilad Ben-Yossef u8 key1[DES_KEY_SIZE]; 21063ee04c8SGilad Ben-Yossef u8 key2[DES_KEY_SIZE]; 21163ee04c8SGilad Ben-Yossef u8 key3[DES_KEY_SIZE]; 21263ee04c8SGilad Ben-Yossef }; 21363ee04c8SGilad Ben-Yossef 21463ee04c8SGilad Ben-Yossef static enum cc_hw_crypto_key hw_key_to_cc_hw_key(int slot_num) 21563ee04c8SGilad Ben-Yossef { 21663ee04c8SGilad Ben-Yossef switch (slot_num) { 21763ee04c8SGilad Ben-Yossef case 0: 21863ee04c8SGilad Ben-Yossef return KFDE0_KEY; 21963ee04c8SGilad Ben-Yossef case 1: 22063ee04c8SGilad Ben-Yossef return KFDE1_KEY; 22163ee04c8SGilad Ben-Yossef case 2: 22263ee04c8SGilad Ben-Yossef return KFDE2_KEY; 22363ee04c8SGilad Ben-Yossef case 3: 22463ee04c8SGilad Ben-Yossef return KFDE3_KEY; 22563ee04c8SGilad Ben-Yossef } 22663ee04c8SGilad Ben-Yossef return END_OF_KEYS; 22763ee04c8SGilad Ben-Yossef } 22863ee04c8SGilad Ben-Yossef 22963ee04c8SGilad Ben-Yossef static int cc_cipher_setkey(struct crypto_skcipher *sktfm, const u8 *key, 23063ee04c8SGilad Ben-Yossef unsigned int keylen) 23163ee04c8SGilad Ben-Yossef { 23263ee04c8SGilad Ben-Yossef struct crypto_tfm *tfm = crypto_skcipher_tfm(sktfm); 23363ee04c8SGilad Ben-Yossef struct cc_cipher_ctx *ctx_p = crypto_tfm_ctx(tfm); 23463ee04c8SGilad Ben-Yossef struct device *dev = drvdata_to_dev(ctx_p->drvdata); 23563ee04c8SGilad Ben-Yossef u32 tmp[DES3_EDE_EXPKEY_WORDS]; 23663ee04c8SGilad Ben-Yossef struct cc_crypto_alg *cc_alg = 23763ee04c8SGilad Ben-Yossef container_of(tfm->__crt_alg, struct cc_crypto_alg, 23863ee04c8SGilad Ben-Yossef skcipher_alg.base); 23963ee04c8SGilad Ben-Yossef unsigned int max_key_buf_size = cc_alg->skcipher_alg.max_keysize; 24063ee04c8SGilad Ben-Yossef 24163ee04c8SGilad Ben-Yossef dev_dbg(dev, "Setting key in context @%p for %s. keylen=%u\n", 24263ee04c8SGilad Ben-Yossef ctx_p, crypto_tfm_alg_name(tfm), keylen); 24363ee04c8SGilad Ben-Yossef dump_byte_array("key", (u8 *)key, keylen); 24463ee04c8SGilad Ben-Yossef 24563ee04c8SGilad Ben-Yossef /* STAT_PHASE_0: Init and sanity checks */ 24663ee04c8SGilad Ben-Yossef 24763ee04c8SGilad Ben-Yossef if (validate_keys_sizes(ctx_p, keylen)) { 24863ee04c8SGilad Ben-Yossef dev_err(dev, "Unsupported key size %d.\n", keylen); 24963ee04c8SGilad Ben-Yossef crypto_tfm_set_flags(tfm, CRYPTO_TFM_RES_BAD_KEY_LEN); 25063ee04c8SGilad Ben-Yossef return -EINVAL; 25163ee04c8SGilad Ben-Yossef } 25263ee04c8SGilad Ben-Yossef 25363ee04c8SGilad Ben-Yossef if (cc_is_hw_key(tfm)) { 25463ee04c8SGilad Ben-Yossef /* setting HW key slots */ 25563ee04c8SGilad Ben-Yossef struct arm_hw_key_info *hki = (struct arm_hw_key_info *)key; 25663ee04c8SGilad Ben-Yossef 25763ee04c8SGilad Ben-Yossef if (ctx_p->flow_mode != S_DIN_to_AES) { 25863ee04c8SGilad Ben-Yossef dev_err(dev, "HW key not supported for non-AES flows\n"); 25963ee04c8SGilad Ben-Yossef return -EINVAL; 26063ee04c8SGilad Ben-Yossef } 26163ee04c8SGilad Ben-Yossef 26263ee04c8SGilad Ben-Yossef ctx_p->hw.key1_slot = hw_key_to_cc_hw_key(hki->hw_key1); 26363ee04c8SGilad Ben-Yossef if (ctx_p->hw.key1_slot == END_OF_KEYS) { 26463ee04c8SGilad Ben-Yossef dev_err(dev, "Unsupported hw key1 number (%d)\n", 26563ee04c8SGilad Ben-Yossef hki->hw_key1); 26663ee04c8SGilad Ben-Yossef return -EINVAL; 26763ee04c8SGilad Ben-Yossef } 26863ee04c8SGilad Ben-Yossef 26963ee04c8SGilad Ben-Yossef if (ctx_p->cipher_mode == DRV_CIPHER_XTS || 27063ee04c8SGilad Ben-Yossef ctx_p->cipher_mode == DRV_CIPHER_ESSIV || 27163ee04c8SGilad Ben-Yossef ctx_p->cipher_mode == DRV_CIPHER_BITLOCKER) { 27263ee04c8SGilad Ben-Yossef if (hki->hw_key1 == hki->hw_key2) { 27363ee04c8SGilad Ben-Yossef dev_err(dev, "Illegal hw key numbers (%d,%d)\n", 27463ee04c8SGilad Ben-Yossef hki->hw_key1, hki->hw_key2); 27563ee04c8SGilad Ben-Yossef return -EINVAL; 27663ee04c8SGilad Ben-Yossef } 27763ee04c8SGilad Ben-Yossef ctx_p->hw.key2_slot = 27863ee04c8SGilad Ben-Yossef hw_key_to_cc_hw_key(hki->hw_key2); 27963ee04c8SGilad Ben-Yossef if (ctx_p->hw.key2_slot == END_OF_KEYS) { 28063ee04c8SGilad Ben-Yossef dev_err(dev, "Unsupported hw key2 number (%d)\n", 28163ee04c8SGilad Ben-Yossef hki->hw_key2); 28263ee04c8SGilad Ben-Yossef return -EINVAL; 28363ee04c8SGilad Ben-Yossef } 28463ee04c8SGilad Ben-Yossef } 28563ee04c8SGilad Ben-Yossef 28663ee04c8SGilad Ben-Yossef ctx_p->keylen = keylen; 28763ee04c8SGilad Ben-Yossef dev_dbg(dev, "cc_is_hw_key ret 0"); 28863ee04c8SGilad Ben-Yossef 28963ee04c8SGilad Ben-Yossef return 0; 29063ee04c8SGilad Ben-Yossef } 29163ee04c8SGilad Ben-Yossef 29263ee04c8SGilad Ben-Yossef /* 29363ee04c8SGilad Ben-Yossef * Verify DES weak keys 29463ee04c8SGilad Ben-Yossef * Note that we're dropping the expanded key since the 29563ee04c8SGilad Ben-Yossef * HW does the expansion on its own. 29663ee04c8SGilad Ben-Yossef */ 29763ee04c8SGilad Ben-Yossef if (ctx_p->flow_mode == S_DIN_to_DES) { 29863ee04c8SGilad Ben-Yossef if (keylen == DES3_EDE_KEY_SIZE && 29963ee04c8SGilad Ben-Yossef __des3_ede_setkey(tmp, &tfm->crt_flags, key, 30063ee04c8SGilad Ben-Yossef DES3_EDE_KEY_SIZE)) { 30163ee04c8SGilad Ben-Yossef dev_dbg(dev, "weak 3DES key"); 30263ee04c8SGilad Ben-Yossef return -EINVAL; 30363ee04c8SGilad Ben-Yossef } else if (!des_ekey(tmp, key) && 30463ee04c8SGilad Ben-Yossef (crypto_tfm_get_flags(tfm) & CRYPTO_TFM_REQ_WEAK_KEY)) { 30563ee04c8SGilad Ben-Yossef tfm->crt_flags |= CRYPTO_TFM_RES_WEAK_KEY; 30663ee04c8SGilad Ben-Yossef dev_dbg(dev, "weak DES key"); 30763ee04c8SGilad Ben-Yossef return -EINVAL; 30863ee04c8SGilad Ben-Yossef } 30963ee04c8SGilad Ben-Yossef } 31063ee04c8SGilad Ben-Yossef 31163ee04c8SGilad Ben-Yossef if (ctx_p->cipher_mode == DRV_CIPHER_XTS && 31263ee04c8SGilad Ben-Yossef xts_check_key(tfm, key, keylen)) { 31363ee04c8SGilad Ben-Yossef dev_dbg(dev, "weak XTS key"); 31463ee04c8SGilad Ben-Yossef return -EINVAL; 31563ee04c8SGilad Ben-Yossef } 31663ee04c8SGilad Ben-Yossef 31763ee04c8SGilad Ben-Yossef /* STAT_PHASE_1: Copy key to ctx */ 31863ee04c8SGilad Ben-Yossef dma_sync_single_for_cpu(dev, ctx_p->user.key_dma_addr, 31963ee04c8SGilad Ben-Yossef max_key_buf_size, DMA_TO_DEVICE); 32063ee04c8SGilad Ben-Yossef 32163ee04c8SGilad Ben-Yossef memcpy(ctx_p->user.key, key, keylen); 32263ee04c8SGilad Ben-Yossef if (keylen == 24) 32363ee04c8SGilad Ben-Yossef memset(ctx_p->user.key + 24, 0, CC_AES_KEY_SIZE_MAX - 24); 32463ee04c8SGilad Ben-Yossef 32563ee04c8SGilad Ben-Yossef if (ctx_p->cipher_mode == DRV_CIPHER_ESSIV) { 32663ee04c8SGilad Ben-Yossef /* sha256 for key2 - use sw implementation */ 32763ee04c8SGilad Ben-Yossef int key_len = keylen >> 1; 32863ee04c8SGilad Ben-Yossef int err; 32963ee04c8SGilad Ben-Yossef 33063ee04c8SGilad Ben-Yossef SHASH_DESC_ON_STACK(desc, ctx_p->shash_tfm); 33163ee04c8SGilad Ben-Yossef 33263ee04c8SGilad Ben-Yossef desc->tfm = ctx_p->shash_tfm; 33363ee04c8SGilad Ben-Yossef 33463ee04c8SGilad Ben-Yossef err = crypto_shash_digest(desc, ctx_p->user.key, key_len, 33563ee04c8SGilad Ben-Yossef ctx_p->user.key + key_len); 33663ee04c8SGilad Ben-Yossef if (err) { 33763ee04c8SGilad Ben-Yossef dev_err(dev, "Failed to hash ESSIV key.\n"); 33863ee04c8SGilad Ben-Yossef return err; 33963ee04c8SGilad Ben-Yossef } 34063ee04c8SGilad Ben-Yossef } 34163ee04c8SGilad Ben-Yossef dma_sync_single_for_device(dev, ctx_p->user.key_dma_addr, 34263ee04c8SGilad Ben-Yossef max_key_buf_size, DMA_TO_DEVICE); 34363ee04c8SGilad Ben-Yossef ctx_p->keylen = keylen; 34463ee04c8SGilad Ben-Yossef 34563ee04c8SGilad Ben-Yossef dev_dbg(dev, "return safely"); 34663ee04c8SGilad Ben-Yossef return 0; 34763ee04c8SGilad Ben-Yossef } 34863ee04c8SGilad Ben-Yossef 34963ee04c8SGilad Ben-Yossef static void cc_setup_cipher_desc(struct crypto_tfm *tfm, 35063ee04c8SGilad Ben-Yossef struct cipher_req_ctx *req_ctx, 35163ee04c8SGilad Ben-Yossef unsigned int ivsize, unsigned int nbytes, 35263ee04c8SGilad Ben-Yossef struct cc_hw_desc desc[], 35363ee04c8SGilad Ben-Yossef unsigned int *seq_size) 35463ee04c8SGilad Ben-Yossef { 35563ee04c8SGilad Ben-Yossef struct cc_cipher_ctx *ctx_p = crypto_tfm_ctx(tfm); 35663ee04c8SGilad Ben-Yossef struct device *dev = drvdata_to_dev(ctx_p->drvdata); 35763ee04c8SGilad Ben-Yossef int cipher_mode = ctx_p->cipher_mode; 35863ee04c8SGilad Ben-Yossef int flow_mode = ctx_p->flow_mode; 35963ee04c8SGilad Ben-Yossef int direction = req_ctx->gen_ctx.op_type; 36063ee04c8SGilad Ben-Yossef dma_addr_t key_dma_addr = ctx_p->user.key_dma_addr; 36163ee04c8SGilad Ben-Yossef unsigned int key_len = ctx_p->keylen; 36263ee04c8SGilad Ben-Yossef dma_addr_t iv_dma_addr = req_ctx->gen_ctx.iv_dma_addr; 36363ee04c8SGilad Ben-Yossef unsigned int du_size = nbytes; 36463ee04c8SGilad Ben-Yossef 36563ee04c8SGilad Ben-Yossef struct cc_crypto_alg *cc_alg = 36663ee04c8SGilad Ben-Yossef container_of(tfm->__crt_alg, struct cc_crypto_alg, 36763ee04c8SGilad Ben-Yossef skcipher_alg.base); 36863ee04c8SGilad Ben-Yossef 36963ee04c8SGilad Ben-Yossef if (cc_alg->data_unit) 37063ee04c8SGilad Ben-Yossef du_size = cc_alg->data_unit; 37163ee04c8SGilad Ben-Yossef 37263ee04c8SGilad Ben-Yossef switch (cipher_mode) { 37363ee04c8SGilad Ben-Yossef case DRV_CIPHER_CBC: 37463ee04c8SGilad Ben-Yossef case DRV_CIPHER_CBC_CTS: 37563ee04c8SGilad Ben-Yossef case DRV_CIPHER_CTR: 37663ee04c8SGilad Ben-Yossef case DRV_CIPHER_OFB: 37763ee04c8SGilad Ben-Yossef /* Load cipher state */ 37863ee04c8SGilad Ben-Yossef hw_desc_init(&desc[*seq_size]); 37963ee04c8SGilad Ben-Yossef set_din_type(&desc[*seq_size], DMA_DLLI, iv_dma_addr, ivsize, 38063ee04c8SGilad Ben-Yossef NS_BIT); 38163ee04c8SGilad Ben-Yossef set_cipher_config0(&desc[*seq_size], direction); 38263ee04c8SGilad Ben-Yossef set_flow_mode(&desc[*seq_size], flow_mode); 38363ee04c8SGilad Ben-Yossef set_cipher_mode(&desc[*seq_size], cipher_mode); 38463ee04c8SGilad Ben-Yossef if (cipher_mode == DRV_CIPHER_CTR || 38563ee04c8SGilad Ben-Yossef cipher_mode == DRV_CIPHER_OFB) { 38663ee04c8SGilad Ben-Yossef set_setup_mode(&desc[*seq_size], SETUP_LOAD_STATE1); 38763ee04c8SGilad Ben-Yossef } else { 38863ee04c8SGilad Ben-Yossef set_setup_mode(&desc[*seq_size], SETUP_LOAD_STATE0); 38963ee04c8SGilad Ben-Yossef } 39063ee04c8SGilad Ben-Yossef (*seq_size)++; 39163ee04c8SGilad Ben-Yossef /*FALLTHROUGH*/ 39263ee04c8SGilad Ben-Yossef case DRV_CIPHER_ECB: 39363ee04c8SGilad Ben-Yossef /* Load key */ 39463ee04c8SGilad Ben-Yossef hw_desc_init(&desc[*seq_size]); 39563ee04c8SGilad Ben-Yossef set_cipher_mode(&desc[*seq_size], cipher_mode); 39663ee04c8SGilad Ben-Yossef set_cipher_config0(&desc[*seq_size], direction); 39763ee04c8SGilad Ben-Yossef if (flow_mode == S_DIN_to_AES) { 39863ee04c8SGilad Ben-Yossef if (cc_is_hw_key(tfm)) { 39963ee04c8SGilad Ben-Yossef set_hw_crypto_key(&desc[*seq_size], 40063ee04c8SGilad Ben-Yossef ctx_p->hw.key1_slot); 40163ee04c8SGilad Ben-Yossef } else { 40263ee04c8SGilad Ben-Yossef set_din_type(&desc[*seq_size], DMA_DLLI, 40363ee04c8SGilad Ben-Yossef key_dma_addr, ((key_len == 24) ? 40463ee04c8SGilad Ben-Yossef AES_MAX_KEY_SIZE : 40563ee04c8SGilad Ben-Yossef key_len), NS_BIT); 40663ee04c8SGilad Ben-Yossef } 40763ee04c8SGilad Ben-Yossef set_key_size_aes(&desc[*seq_size], key_len); 40863ee04c8SGilad Ben-Yossef } else { 40963ee04c8SGilad Ben-Yossef /*des*/ 41063ee04c8SGilad Ben-Yossef set_din_type(&desc[*seq_size], DMA_DLLI, key_dma_addr, 41163ee04c8SGilad Ben-Yossef key_len, NS_BIT); 41263ee04c8SGilad Ben-Yossef set_key_size_des(&desc[*seq_size], key_len); 41363ee04c8SGilad Ben-Yossef } 41463ee04c8SGilad Ben-Yossef set_flow_mode(&desc[*seq_size], flow_mode); 41563ee04c8SGilad Ben-Yossef set_setup_mode(&desc[*seq_size], SETUP_LOAD_KEY0); 41663ee04c8SGilad Ben-Yossef (*seq_size)++; 41763ee04c8SGilad Ben-Yossef break; 41863ee04c8SGilad Ben-Yossef case DRV_CIPHER_XTS: 41963ee04c8SGilad Ben-Yossef case DRV_CIPHER_ESSIV: 42063ee04c8SGilad Ben-Yossef case DRV_CIPHER_BITLOCKER: 42163ee04c8SGilad Ben-Yossef /* Load AES key */ 42263ee04c8SGilad Ben-Yossef hw_desc_init(&desc[*seq_size]); 42363ee04c8SGilad Ben-Yossef set_cipher_mode(&desc[*seq_size], cipher_mode); 42463ee04c8SGilad Ben-Yossef set_cipher_config0(&desc[*seq_size], direction); 42563ee04c8SGilad Ben-Yossef if (cc_is_hw_key(tfm)) { 42663ee04c8SGilad Ben-Yossef set_hw_crypto_key(&desc[*seq_size], 42763ee04c8SGilad Ben-Yossef ctx_p->hw.key1_slot); 42863ee04c8SGilad Ben-Yossef } else { 42963ee04c8SGilad Ben-Yossef set_din_type(&desc[*seq_size], DMA_DLLI, key_dma_addr, 43063ee04c8SGilad Ben-Yossef (key_len / 2), NS_BIT); 43163ee04c8SGilad Ben-Yossef } 43263ee04c8SGilad Ben-Yossef set_key_size_aes(&desc[*seq_size], (key_len / 2)); 43363ee04c8SGilad Ben-Yossef set_flow_mode(&desc[*seq_size], flow_mode); 43463ee04c8SGilad Ben-Yossef set_setup_mode(&desc[*seq_size], SETUP_LOAD_KEY0); 43563ee04c8SGilad Ben-Yossef (*seq_size)++; 43663ee04c8SGilad Ben-Yossef 43763ee04c8SGilad Ben-Yossef /* load XEX key */ 43863ee04c8SGilad Ben-Yossef hw_desc_init(&desc[*seq_size]); 43963ee04c8SGilad Ben-Yossef set_cipher_mode(&desc[*seq_size], cipher_mode); 44063ee04c8SGilad Ben-Yossef set_cipher_config0(&desc[*seq_size], direction); 44163ee04c8SGilad Ben-Yossef if (cc_is_hw_key(tfm)) { 44263ee04c8SGilad Ben-Yossef set_hw_crypto_key(&desc[*seq_size], 44363ee04c8SGilad Ben-Yossef ctx_p->hw.key2_slot); 44463ee04c8SGilad Ben-Yossef } else { 44563ee04c8SGilad Ben-Yossef set_din_type(&desc[*seq_size], DMA_DLLI, 44663ee04c8SGilad Ben-Yossef (key_dma_addr + (key_len / 2)), 44763ee04c8SGilad Ben-Yossef (key_len / 2), NS_BIT); 44863ee04c8SGilad Ben-Yossef } 44963ee04c8SGilad Ben-Yossef set_xex_data_unit_size(&desc[*seq_size], du_size); 45063ee04c8SGilad Ben-Yossef set_flow_mode(&desc[*seq_size], S_DIN_to_AES2); 45163ee04c8SGilad Ben-Yossef set_key_size_aes(&desc[*seq_size], (key_len / 2)); 45263ee04c8SGilad Ben-Yossef set_setup_mode(&desc[*seq_size], SETUP_LOAD_XEX_KEY); 45363ee04c8SGilad Ben-Yossef (*seq_size)++; 45463ee04c8SGilad Ben-Yossef 45563ee04c8SGilad Ben-Yossef /* Set state */ 45663ee04c8SGilad Ben-Yossef hw_desc_init(&desc[*seq_size]); 45763ee04c8SGilad Ben-Yossef set_setup_mode(&desc[*seq_size], SETUP_LOAD_STATE1); 45863ee04c8SGilad Ben-Yossef set_cipher_mode(&desc[*seq_size], cipher_mode); 45963ee04c8SGilad Ben-Yossef set_cipher_config0(&desc[*seq_size], direction); 46063ee04c8SGilad Ben-Yossef set_key_size_aes(&desc[*seq_size], (key_len / 2)); 46163ee04c8SGilad Ben-Yossef set_flow_mode(&desc[*seq_size], flow_mode); 46263ee04c8SGilad Ben-Yossef set_din_type(&desc[*seq_size], DMA_DLLI, iv_dma_addr, 46363ee04c8SGilad Ben-Yossef CC_AES_BLOCK_SIZE, NS_BIT); 46463ee04c8SGilad Ben-Yossef (*seq_size)++; 46563ee04c8SGilad Ben-Yossef break; 46663ee04c8SGilad Ben-Yossef default: 46763ee04c8SGilad Ben-Yossef dev_err(dev, "Unsupported cipher mode (%d)\n", cipher_mode); 46863ee04c8SGilad Ben-Yossef } 46963ee04c8SGilad Ben-Yossef } 47063ee04c8SGilad Ben-Yossef 47163ee04c8SGilad Ben-Yossef static void cc_setup_cipher_data(struct crypto_tfm *tfm, 47263ee04c8SGilad Ben-Yossef struct cipher_req_ctx *req_ctx, 47363ee04c8SGilad Ben-Yossef struct scatterlist *dst, 47463ee04c8SGilad Ben-Yossef struct scatterlist *src, unsigned int nbytes, 47563ee04c8SGilad Ben-Yossef void *areq, struct cc_hw_desc desc[], 47663ee04c8SGilad Ben-Yossef unsigned int *seq_size) 47763ee04c8SGilad Ben-Yossef { 47863ee04c8SGilad Ben-Yossef struct cc_cipher_ctx *ctx_p = crypto_tfm_ctx(tfm); 47963ee04c8SGilad Ben-Yossef struct device *dev = drvdata_to_dev(ctx_p->drvdata); 48063ee04c8SGilad Ben-Yossef unsigned int flow_mode = ctx_p->flow_mode; 48163ee04c8SGilad Ben-Yossef 48263ee04c8SGilad Ben-Yossef switch (ctx_p->flow_mode) { 48363ee04c8SGilad Ben-Yossef case S_DIN_to_AES: 48463ee04c8SGilad Ben-Yossef flow_mode = DIN_AES_DOUT; 48563ee04c8SGilad Ben-Yossef break; 48663ee04c8SGilad Ben-Yossef case S_DIN_to_DES: 48763ee04c8SGilad Ben-Yossef flow_mode = DIN_DES_DOUT; 48863ee04c8SGilad Ben-Yossef break; 48963ee04c8SGilad Ben-Yossef default: 49063ee04c8SGilad Ben-Yossef dev_err(dev, "invalid flow mode, flow_mode = %d\n", flow_mode); 49163ee04c8SGilad Ben-Yossef return; 49263ee04c8SGilad Ben-Yossef } 49363ee04c8SGilad Ben-Yossef /* Process */ 49463ee04c8SGilad Ben-Yossef if (req_ctx->dma_buf_type == CC_DMA_BUF_DLLI) { 49563ee04c8SGilad Ben-Yossef dev_dbg(dev, " data params addr %pad length 0x%X\n", 49663ee04c8SGilad Ben-Yossef &sg_dma_address(src), nbytes); 49763ee04c8SGilad Ben-Yossef dev_dbg(dev, " data params addr %pad length 0x%X\n", 49863ee04c8SGilad Ben-Yossef &sg_dma_address(dst), nbytes); 49963ee04c8SGilad Ben-Yossef hw_desc_init(&desc[*seq_size]); 50063ee04c8SGilad Ben-Yossef set_din_type(&desc[*seq_size], DMA_DLLI, sg_dma_address(src), 50163ee04c8SGilad Ben-Yossef nbytes, NS_BIT); 50263ee04c8SGilad Ben-Yossef set_dout_dlli(&desc[*seq_size], sg_dma_address(dst), 50363ee04c8SGilad Ben-Yossef nbytes, NS_BIT, (!areq ? 0 : 1)); 50463ee04c8SGilad Ben-Yossef if (areq) 50563ee04c8SGilad Ben-Yossef set_queue_last_ind(&desc[*seq_size]); 50663ee04c8SGilad Ben-Yossef 50763ee04c8SGilad Ben-Yossef set_flow_mode(&desc[*seq_size], flow_mode); 50863ee04c8SGilad Ben-Yossef (*seq_size)++; 50963ee04c8SGilad Ben-Yossef } else { 51063ee04c8SGilad Ben-Yossef /* bypass */ 51163ee04c8SGilad Ben-Yossef dev_dbg(dev, " bypass params addr %pad length 0x%X addr 0x%08X\n", 51263ee04c8SGilad Ben-Yossef &req_ctx->mlli_params.mlli_dma_addr, 51363ee04c8SGilad Ben-Yossef req_ctx->mlli_params.mlli_len, 51463ee04c8SGilad Ben-Yossef (unsigned int)ctx_p->drvdata->mlli_sram_addr); 51563ee04c8SGilad Ben-Yossef hw_desc_init(&desc[*seq_size]); 51663ee04c8SGilad Ben-Yossef set_din_type(&desc[*seq_size], DMA_DLLI, 51763ee04c8SGilad Ben-Yossef req_ctx->mlli_params.mlli_dma_addr, 51863ee04c8SGilad Ben-Yossef req_ctx->mlli_params.mlli_len, NS_BIT); 51963ee04c8SGilad Ben-Yossef set_dout_sram(&desc[*seq_size], 52063ee04c8SGilad Ben-Yossef ctx_p->drvdata->mlli_sram_addr, 52163ee04c8SGilad Ben-Yossef req_ctx->mlli_params.mlli_len); 52263ee04c8SGilad Ben-Yossef set_flow_mode(&desc[*seq_size], BYPASS); 52363ee04c8SGilad Ben-Yossef (*seq_size)++; 52463ee04c8SGilad Ben-Yossef 52563ee04c8SGilad Ben-Yossef hw_desc_init(&desc[*seq_size]); 52663ee04c8SGilad Ben-Yossef set_din_type(&desc[*seq_size], DMA_MLLI, 52763ee04c8SGilad Ben-Yossef ctx_p->drvdata->mlli_sram_addr, 52863ee04c8SGilad Ben-Yossef req_ctx->in_mlli_nents, NS_BIT); 52963ee04c8SGilad Ben-Yossef if (req_ctx->out_nents == 0) { 53063ee04c8SGilad Ben-Yossef dev_dbg(dev, " din/dout params addr 0x%08X addr 0x%08X\n", 53163ee04c8SGilad Ben-Yossef (unsigned int)ctx_p->drvdata->mlli_sram_addr, 53263ee04c8SGilad Ben-Yossef (unsigned int)ctx_p->drvdata->mlli_sram_addr); 53363ee04c8SGilad Ben-Yossef set_dout_mlli(&desc[*seq_size], 53463ee04c8SGilad Ben-Yossef ctx_p->drvdata->mlli_sram_addr, 53563ee04c8SGilad Ben-Yossef req_ctx->in_mlli_nents, NS_BIT, 53663ee04c8SGilad Ben-Yossef (!areq ? 0 : 1)); 53763ee04c8SGilad Ben-Yossef } else { 53863ee04c8SGilad Ben-Yossef dev_dbg(dev, " din/dout params addr 0x%08X addr 0x%08X\n", 53963ee04c8SGilad Ben-Yossef (unsigned int)ctx_p->drvdata->mlli_sram_addr, 54063ee04c8SGilad Ben-Yossef (unsigned int)ctx_p->drvdata->mlli_sram_addr + 54163ee04c8SGilad Ben-Yossef (u32)LLI_ENTRY_BYTE_SIZE * req_ctx->in_nents); 54263ee04c8SGilad Ben-Yossef set_dout_mlli(&desc[*seq_size], 54363ee04c8SGilad Ben-Yossef (ctx_p->drvdata->mlli_sram_addr + 54463ee04c8SGilad Ben-Yossef (LLI_ENTRY_BYTE_SIZE * 54563ee04c8SGilad Ben-Yossef req_ctx->in_mlli_nents)), 54663ee04c8SGilad Ben-Yossef req_ctx->out_mlli_nents, NS_BIT, 54763ee04c8SGilad Ben-Yossef (!areq ? 0 : 1)); 54863ee04c8SGilad Ben-Yossef } 54963ee04c8SGilad Ben-Yossef if (areq) 55063ee04c8SGilad Ben-Yossef set_queue_last_ind(&desc[*seq_size]); 55163ee04c8SGilad Ben-Yossef 55263ee04c8SGilad Ben-Yossef set_flow_mode(&desc[*seq_size], flow_mode); 55363ee04c8SGilad Ben-Yossef (*seq_size)++; 55463ee04c8SGilad Ben-Yossef } 55563ee04c8SGilad Ben-Yossef } 55663ee04c8SGilad Ben-Yossef 55763ee04c8SGilad Ben-Yossef static void cc_cipher_complete(struct device *dev, void *cc_req, int err) 55863ee04c8SGilad Ben-Yossef { 55963ee04c8SGilad Ben-Yossef struct skcipher_request *req = (struct skcipher_request *)cc_req; 56063ee04c8SGilad Ben-Yossef struct scatterlist *dst = req->dst; 56163ee04c8SGilad Ben-Yossef struct scatterlist *src = req->src; 56263ee04c8SGilad Ben-Yossef struct cipher_req_ctx *req_ctx = skcipher_request_ctx(req); 56363ee04c8SGilad Ben-Yossef struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); 56463ee04c8SGilad Ben-Yossef unsigned int ivsize = crypto_skcipher_ivsize(tfm); 56563ee04c8SGilad Ben-Yossef 56663ee04c8SGilad Ben-Yossef cc_unmap_cipher_request(dev, req_ctx, ivsize, src, dst); 56763ee04c8SGilad Ben-Yossef kzfree(req_ctx->iv); 56863ee04c8SGilad Ben-Yossef 56963ee04c8SGilad Ben-Yossef /* 57063ee04c8SGilad Ben-Yossef * The crypto API expects us to set the req->iv to the last 57163ee04c8SGilad Ben-Yossef * ciphertext block. For encrypt, simply copy from the result. 57263ee04c8SGilad Ben-Yossef * For decrypt, we must copy from a saved buffer since this 57363ee04c8SGilad Ben-Yossef * could be an in-place decryption operation and the src is 57463ee04c8SGilad Ben-Yossef * lost by this point. 57563ee04c8SGilad Ben-Yossef */ 57663ee04c8SGilad Ben-Yossef if (req_ctx->gen_ctx.op_type == DRV_CRYPTO_DIRECTION_DECRYPT) { 57763ee04c8SGilad Ben-Yossef memcpy(req->iv, req_ctx->backup_info, ivsize); 57863ee04c8SGilad Ben-Yossef kzfree(req_ctx->backup_info); 57963ee04c8SGilad Ben-Yossef } else if (!err) { 58063ee04c8SGilad Ben-Yossef scatterwalk_map_and_copy(req->iv, req->dst, 58163ee04c8SGilad Ben-Yossef (req->cryptlen - ivsize), 58263ee04c8SGilad Ben-Yossef ivsize, 0); 58363ee04c8SGilad Ben-Yossef } 58463ee04c8SGilad Ben-Yossef 58563ee04c8SGilad Ben-Yossef skcipher_request_complete(req, err); 58663ee04c8SGilad Ben-Yossef } 58763ee04c8SGilad Ben-Yossef 58863ee04c8SGilad Ben-Yossef static int cc_cipher_process(struct skcipher_request *req, 58963ee04c8SGilad Ben-Yossef enum drv_crypto_direction direction) 59063ee04c8SGilad Ben-Yossef { 59163ee04c8SGilad Ben-Yossef struct crypto_skcipher *sk_tfm = crypto_skcipher_reqtfm(req); 59263ee04c8SGilad Ben-Yossef struct crypto_tfm *tfm = crypto_skcipher_tfm(sk_tfm); 59363ee04c8SGilad Ben-Yossef struct cipher_req_ctx *req_ctx = skcipher_request_ctx(req); 59463ee04c8SGilad Ben-Yossef unsigned int ivsize = crypto_skcipher_ivsize(sk_tfm); 59563ee04c8SGilad Ben-Yossef struct scatterlist *dst = req->dst; 59663ee04c8SGilad Ben-Yossef struct scatterlist *src = req->src; 59763ee04c8SGilad Ben-Yossef unsigned int nbytes = req->cryptlen; 59863ee04c8SGilad Ben-Yossef void *iv = req->iv; 59963ee04c8SGilad Ben-Yossef struct cc_cipher_ctx *ctx_p = crypto_tfm_ctx(tfm); 60063ee04c8SGilad Ben-Yossef struct device *dev = drvdata_to_dev(ctx_p->drvdata); 60163ee04c8SGilad Ben-Yossef struct cc_hw_desc desc[MAX_ABLKCIPHER_SEQ_LEN]; 60263ee04c8SGilad Ben-Yossef struct cc_crypto_req cc_req = {}; 60363ee04c8SGilad Ben-Yossef int rc, cts_restore_flag = 0; 60463ee04c8SGilad Ben-Yossef unsigned int seq_len = 0; 60563ee04c8SGilad Ben-Yossef gfp_t flags = cc_gfp_flags(&req->base); 60663ee04c8SGilad Ben-Yossef 60763ee04c8SGilad Ben-Yossef dev_dbg(dev, "%s req=%p iv=%p nbytes=%d\n", 60863ee04c8SGilad Ben-Yossef ((direction == DRV_CRYPTO_DIRECTION_ENCRYPT) ? 60963ee04c8SGilad Ben-Yossef "Encrypt" : "Decrypt"), req, iv, nbytes); 61063ee04c8SGilad Ben-Yossef 61163ee04c8SGilad Ben-Yossef /* STAT_PHASE_0: Init and sanity checks */ 61263ee04c8SGilad Ben-Yossef 61363ee04c8SGilad Ben-Yossef /* TODO: check data length according to mode */ 61463ee04c8SGilad Ben-Yossef if (validate_data_size(ctx_p, nbytes)) { 61563ee04c8SGilad Ben-Yossef dev_err(dev, "Unsupported data size %d.\n", nbytes); 61663ee04c8SGilad Ben-Yossef crypto_tfm_set_flags(tfm, CRYPTO_TFM_RES_BAD_BLOCK_LEN); 61763ee04c8SGilad Ben-Yossef rc = -EINVAL; 61863ee04c8SGilad Ben-Yossef goto exit_process; 61963ee04c8SGilad Ben-Yossef } 62063ee04c8SGilad Ben-Yossef if (nbytes == 0) { 62163ee04c8SGilad Ben-Yossef /* No data to process is valid */ 62263ee04c8SGilad Ben-Yossef rc = 0; 62363ee04c8SGilad Ben-Yossef goto exit_process; 62463ee04c8SGilad Ben-Yossef } 62563ee04c8SGilad Ben-Yossef 62663ee04c8SGilad Ben-Yossef /* The IV we are handed may be allocted from the stack so 62763ee04c8SGilad Ben-Yossef * we must copy it to a DMAable buffer before use. 62863ee04c8SGilad Ben-Yossef */ 62963ee04c8SGilad Ben-Yossef req_ctx->iv = kmalloc(ivsize, flags); 63063ee04c8SGilad Ben-Yossef if (!req_ctx->iv) { 63163ee04c8SGilad Ben-Yossef rc = -ENOMEM; 63263ee04c8SGilad Ben-Yossef goto exit_process; 63363ee04c8SGilad Ben-Yossef } 63463ee04c8SGilad Ben-Yossef memcpy(req_ctx->iv, iv, ivsize); 63563ee04c8SGilad Ben-Yossef 63663ee04c8SGilad Ben-Yossef /*For CTS in case of data size aligned to 16 use CBC mode*/ 63763ee04c8SGilad Ben-Yossef if (((nbytes % AES_BLOCK_SIZE) == 0) && 63863ee04c8SGilad Ben-Yossef ctx_p->cipher_mode == DRV_CIPHER_CBC_CTS) { 63963ee04c8SGilad Ben-Yossef ctx_p->cipher_mode = DRV_CIPHER_CBC; 64063ee04c8SGilad Ben-Yossef cts_restore_flag = 1; 64163ee04c8SGilad Ben-Yossef } 64263ee04c8SGilad Ben-Yossef 64363ee04c8SGilad Ben-Yossef /* Setup request structure */ 64463ee04c8SGilad Ben-Yossef cc_req.user_cb = (void *)cc_cipher_complete; 64563ee04c8SGilad Ben-Yossef cc_req.user_arg = (void *)req; 64663ee04c8SGilad Ben-Yossef 64763ee04c8SGilad Ben-Yossef #ifdef ENABLE_CYCLE_COUNT 64863ee04c8SGilad Ben-Yossef cc_req.op_type = (direction == DRV_CRYPTO_DIRECTION_DECRYPT) ? 64963ee04c8SGilad Ben-Yossef STAT_OP_TYPE_DECODE : STAT_OP_TYPE_ENCODE; 65063ee04c8SGilad Ben-Yossef 65163ee04c8SGilad Ben-Yossef #endif 65263ee04c8SGilad Ben-Yossef 65363ee04c8SGilad Ben-Yossef /* Setup request context */ 65463ee04c8SGilad Ben-Yossef req_ctx->gen_ctx.op_type = direction; 65563ee04c8SGilad Ben-Yossef 65663ee04c8SGilad Ben-Yossef /* STAT_PHASE_1: Map buffers */ 65763ee04c8SGilad Ben-Yossef 65863ee04c8SGilad Ben-Yossef rc = cc_map_cipher_request(ctx_p->drvdata, req_ctx, ivsize, nbytes, 65963ee04c8SGilad Ben-Yossef req_ctx->iv, src, dst, flags); 66063ee04c8SGilad Ben-Yossef if (rc) { 66163ee04c8SGilad Ben-Yossef dev_err(dev, "map_request() failed\n"); 66263ee04c8SGilad Ben-Yossef goto exit_process; 66363ee04c8SGilad Ben-Yossef } 66463ee04c8SGilad Ben-Yossef 66563ee04c8SGilad Ben-Yossef /* STAT_PHASE_2: Create sequence */ 66663ee04c8SGilad Ben-Yossef 66763ee04c8SGilad Ben-Yossef /* Setup processing */ 66863ee04c8SGilad Ben-Yossef cc_setup_cipher_desc(tfm, req_ctx, ivsize, nbytes, desc, &seq_len); 66963ee04c8SGilad Ben-Yossef /* Data processing */ 67063ee04c8SGilad Ben-Yossef cc_setup_cipher_data(tfm, req_ctx, dst, src, nbytes, req, desc, 67163ee04c8SGilad Ben-Yossef &seq_len); 67263ee04c8SGilad Ben-Yossef 67363ee04c8SGilad Ben-Yossef /* do we need to generate IV? */ 67463ee04c8SGilad Ben-Yossef if (req_ctx->is_giv) { 67563ee04c8SGilad Ben-Yossef cc_req.ivgen_dma_addr[0] = req_ctx->gen_ctx.iv_dma_addr; 67663ee04c8SGilad Ben-Yossef cc_req.ivgen_dma_addr_len = 1; 67763ee04c8SGilad Ben-Yossef /* set the IV size (8/16 B long)*/ 67863ee04c8SGilad Ben-Yossef cc_req.ivgen_size = ivsize; 67963ee04c8SGilad Ben-Yossef } 68063ee04c8SGilad Ben-Yossef 68163ee04c8SGilad Ben-Yossef /* STAT_PHASE_3: Lock HW and push sequence */ 68263ee04c8SGilad Ben-Yossef 68363ee04c8SGilad Ben-Yossef rc = cc_send_request(ctx_p->drvdata, &cc_req, desc, seq_len, 68463ee04c8SGilad Ben-Yossef &req->base); 68563ee04c8SGilad Ben-Yossef if (rc != -EINPROGRESS && rc != -EBUSY) { 68663ee04c8SGilad Ben-Yossef /* Failed to send the request or request completed 68763ee04c8SGilad Ben-Yossef * synchronously 68863ee04c8SGilad Ben-Yossef */ 68963ee04c8SGilad Ben-Yossef cc_unmap_cipher_request(dev, req_ctx, ivsize, src, dst); 69063ee04c8SGilad Ben-Yossef } 69163ee04c8SGilad Ben-Yossef 69263ee04c8SGilad Ben-Yossef exit_process: 69363ee04c8SGilad Ben-Yossef if (cts_restore_flag) 69463ee04c8SGilad Ben-Yossef ctx_p->cipher_mode = DRV_CIPHER_CBC_CTS; 69563ee04c8SGilad Ben-Yossef 69663ee04c8SGilad Ben-Yossef if (rc != -EINPROGRESS && rc != -EBUSY) { 69763ee04c8SGilad Ben-Yossef kzfree(req_ctx->backup_info); 69863ee04c8SGilad Ben-Yossef kzfree(req_ctx->iv); 69963ee04c8SGilad Ben-Yossef } 70063ee04c8SGilad Ben-Yossef 70163ee04c8SGilad Ben-Yossef return rc; 70263ee04c8SGilad Ben-Yossef } 70363ee04c8SGilad Ben-Yossef 70463ee04c8SGilad Ben-Yossef static int cc_cipher_encrypt(struct skcipher_request *req) 70563ee04c8SGilad Ben-Yossef { 70663ee04c8SGilad Ben-Yossef struct cipher_req_ctx *req_ctx = skcipher_request_ctx(req); 70763ee04c8SGilad Ben-Yossef 70863ee04c8SGilad Ben-Yossef req_ctx->is_giv = false; 70963ee04c8SGilad Ben-Yossef req_ctx->backup_info = NULL; 71063ee04c8SGilad Ben-Yossef 71163ee04c8SGilad Ben-Yossef return cc_cipher_process(req, DRV_CRYPTO_DIRECTION_ENCRYPT); 71263ee04c8SGilad Ben-Yossef } 71363ee04c8SGilad Ben-Yossef 71463ee04c8SGilad Ben-Yossef static int cc_cipher_decrypt(struct skcipher_request *req) 71563ee04c8SGilad Ben-Yossef { 71663ee04c8SGilad Ben-Yossef struct crypto_skcipher *sk_tfm = crypto_skcipher_reqtfm(req); 71763ee04c8SGilad Ben-Yossef struct cipher_req_ctx *req_ctx = skcipher_request_ctx(req); 71863ee04c8SGilad Ben-Yossef unsigned int ivsize = crypto_skcipher_ivsize(sk_tfm); 71963ee04c8SGilad Ben-Yossef gfp_t flags = cc_gfp_flags(&req->base); 72063ee04c8SGilad Ben-Yossef 72163ee04c8SGilad Ben-Yossef /* 72263ee04c8SGilad Ben-Yossef * Allocate and save the last IV sized bytes of the source, which will 72363ee04c8SGilad Ben-Yossef * be lost in case of in-place decryption and might be needed for CTS. 72463ee04c8SGilad Ben-Yossef */ 72563ee04c8SGilad Ben-Yossef req_ctx->backup_info = kmalloc(ivsize, flags); 72663ee04c8SGilad Ben-Yossef if (!req_ctx->backup_info) 72763ee04c8SGilad Ben-Yossef return -ENOMEM; 72863ee04c8SGilad Ben-Yossef 72963ee04c8SGilad Ben-Yossef scatterwalk_map_and_copy(req_ctx->backup_info, req->src, 73063ee04c8SGilad Ben-Yossef (req->cryptlen - ivsize), ivsize, 0); 73163ee04c8SGilad Ben-Yossef req_ctx->is_giv = false; 73263ee04c8SGilad Ben-Yossef 73363ee04c8SGilad Ben-Yossef return cc_cipher_process(req, DRV_CRYPTO_DIRECTION_DECRYPT); 73463ee04c8SGilad Ben-Yossef } 73563ee04c8SGilad Ben-Yossef 73663ee04c8SGilad Ben-Yossef /* Block cipher alg */ 73763ee04c8SGilad Ben-Yossef static const struct cc_alg_template skcipher_algs[] = { 73863ee04c8SGilad Ben-Yossef { 73963ee04c8SGilad Ben-Yossef .name = "xts(aes)", 74063ee04c8SGilad Ben-Yossef .driver_name = "xts-aes-ccree", 74163ee04c8SGilad Ben-Yossef .blocksize = AES_BLOCK_SIZE, 74263ee04c8SGilad Ben-Yossef .template_skcipher = { 74363ee04c8SGilad Ben-Yossef .setkey = cc_cipher_setkey, 74463ee04c8SGilad Ben-Yossef .encrypt = cc_cipher_encrypt, 74563ee04c8SGilad Ben-Yossef .decrypt = cc_cipher_decrypt, 74663ee04c8SGilad Ben-Yossef .min_keysize = AES_MIN_KEY_SIZE * 2, 74763ee04c8SGilad Ben-Yossef .max_keysize = AES_MAX_KEY_SIZE * 2, 74863ee04c8SGilad Ben-Yossef .ivsize = AES_BLOCK_SIZE, 74963ee04c8SGilad Ben-Yossef }, 75063ee04c8SGilad Ben-Yossef .cipher_mode = DRV_CIPHER_XTS, 75163ee04c8SGilad Ben-Yossef .flow_mode = S_DIN_to_AES, 75263ee04c8SGilad Ben-Yossef }, 75363ee04c8SGilad Ben-Yossef { 75463ee04c8SGilad Ben-Yossef .name = "xts512(aes)", 75563ee04c8SGilad Ben-Yossef .driver_name = "xts-aes-du512-ccree", 75663ee04c8SGilad Ben-Yossef .blocksize = AES_BLOCK_SIZE, 75763ee04c8SGilad Ben-Yossef .template_skcipher = { 75863ee04c8SGilad Ben-Yossef .setkey = cc_cipher_setkey, 75963ee04c8SGilad Ben-Yossef .encrypt = cc_cipher_encrypt, 76063ee04c8SGilad Ben-Yossef .decrypt = cc_cipher_decrypt, 76163ee04c8SGilad Ben-Yossef .min_keysize = AES_MIN_KEY_SIZE * 2, 76263ee04c8SGilad Ben-Yossef .max_keysize = AES_MAX_KEY_SIZE * 2, 76363ee04c8SGilad Ben-Yossef .ivsize = AES_BLOCK_SIZE, 76463ee04c8SGilad Ben-Yossef }, 76563ee04c8SGilad Ben-Yossef .cipher_mode = DRV_CIPHER_XTS, 76663ee04c8SGilad Ben-Yossef .flow_mode = S_DIN_to_AES, 76763ee04c8SGilad Ben-Yossef .data_unit = 512, 76863ee04c8SGilad Ben-Yossef }, 76963ee04c8SGilad Ben-Yossef { 77063ee04c8SGilad Ben-Yossef .name = "xts4096(aes)", 77163ee04c8SGilad Ben-Yossef .driver_name = "xts-aes-du4096-ccree", 77263ee04c8SGilad Ben-Yossef .blocksize = AES_BLOCK_SIZE, 77363ee04c8SGilad Ben-Yossef .template_skcipher = { 77463ee04c8SGilad Ben-Yossef .setkey = cc_cipher_setkey, 77563ee04c8SGilad Ben-Yossef .encrypt = cc_cipher_encrypt, 77663ee04c8SGilad Ben-Yossef .decrypt = cc_cipher_decrypt, 77763ee04c8SGilad Ben-Yossef .min_keysize = AES_MIN_KEY_SIZE * 2, 77863ee04c8SGilad Ben-Yossef .max_keysize = AES_MAX_KEY_SIZE * 2, 77963ee04c8SGilad Ben-Yossef .ivsize = AES_BLOCK_SIZE, 78063ee04c8SGilad Ben-Yossef }, 78163ee04c8SGilad Ben-Yossef .cipher_mode = DRV_CIPHER_XTS, 78263ee04c8SGilad Ben-Yossef .flow_mode = S_DIN_to_AES, 78363ee04c8SGilad Ben-Yossef .data_unit = 4096, 78463ee04c8SGilad Ben-Yossef }, 78563ee04c8SGilad Ben-Yossef { 78663ee04c8SGilad Ben-Yossef .name = "essiv(aes)", 78763ee04c8SGilad Ben-Yossef .driver_name = "essiv-aes-ccree", 78863ee04c8SGilad Ben-Yossef .blocksize = AES_BLOCK_SIZE, 78963ee04c8SGilad Ben-Yossef .template_skcipher = { 79063ee04c8SGilad Ben-Yossef .setkey = cc_cipher_setkey, 79163ee04c8SGilad Ben-Yossef .encrypt = cc_cipher_encrypt, 79263ee04c8SGilad Ben-Yossef .decrypt = cc_cipher_decrypt, 79363ee04c8SGilad Ben-Yossef .min_keysize = AES_MIN_KEY_SIZE * 2, 79463ee04c8SGilad Ben-Yossef .max_keysize = AES_MAX_KEY_SIZE * 2, 79563ee04c8SGilad Ben-Yossef .ivsize = AES_BLOCK_SIZE, 79663ee04c8SGilad Ben-Yossef }, 79763ee04c8SGilad Ben-Yossef .cipher_mode = DRV_CIPHER_ESSIV, 79863ee04c8SGilad Ben-Yossef .flow_mode = S_DIN_to_AES, 79963ee04c8SGilad Ben-Yossef }, 80063ee04c8SGilad Ben-Yossef { 80163ee04c8SGilad Ben-Yossef .name = "essiv512(aes)", 80263ee04c8SGilad Ben-Yossef .driver_name = "essiv-aes-du512-ccree", 80363ee04c8SGilad Ben-Yossef .blocksize = AES_BLOCK_SIZE, 80463ee04c8SGilad Ben-Yossef .template_skcipher = { 80563ee04c8SGilad Ben-Yossef .setkey = cc_cipher_setkey, 80663ee04c8SGilad Ben-Yossef .encrypt = cc_cipher_encrypt, 80763ee04c8SGilad Ben-Yossef .decrypt = cc_cipher_decrypt, 80863ee04c8SGilad Ben-Yossef .min_keysize = AES_MIN_KEY_SIZE * 2, 80963ee04c8SGilad Ben-Yossef .max_keysize = AES_MAX_KEY_SIZE * 2, 81063ee04c8SGilad Ben-Yossef .ivsize = AES_BLOCK_SIZE, 81163ee04c8SGilad Ben-Yossef }, 81263ee04c8SGilad Ben-Yossef .cipher_mode = DRV_CIPHER_ESSIV, 81363ee04c8SGilad Ben-Yossef .flow_mode = S_DIN_to_AES, 81463ee04c8SGilad Ben-Yossef .data_unit = 512, 81563ee04c8SGilad Ben-Yossef }, 81663ee04c8SGilad Ben-Yossef { 81763ee04c8SGilad Ben-Yossef .name = "essiv4096(aes)", 81863ee04c8SGilad Ben-Yossef .driver_name = "essiv-aes-du4096-ccree", 81963ee04c8SGilad Ben-Yossef .blocksize = AES_BLOCK_SIZE, 82063ee04c8SGilad Ben-Yossef .template_skcipher = { 82163ee04c8SGilad Ben-Yossef .setkey = cc_cipher_setkey, 82263ee04c8SGilad Ben-Yossef .encrypt = cc_cipher_encrypt, 82363ee04c8SGilad Ben-Yossef .decrypt = cc_cipher_decrypt, 82463ee04c8SGilad Ben-Yossef .min_keysize = AES_MIN_KEY_SIZE * 2, 82563ee04c8SGilad Ben-Yossef .max_keysize = AES_MAX_KEY_SIZE * 2, 82663ee04c8SGilad Ben-Yossef .ivsize = AES_BLOCK_SIZE, 82763ee04c8SGilad Ben-Yossef }, 82863ee04c8SGilad Ben-Yossef .cipher_mode = DRV_CIPHER_ESSIV, 82963ee04c8SGilad Ben-Yossef .flow_mode = S_DIN_to_AES, 83063ee04c8SGilad Ben-Yossef .data_unit = 4096, 83163ee04c8SGilad Ben-Yossef }, 83263ee04c8SGilad Ben-Yossef { 83363ee04c8SGilad Ben-Yossef .name = "bitlocker(aes)", 83463ee04c8SGilad Ben-Yossef .driver_name = "bitlocker-aes-ccree", 83563ee04c8SGilad Ben-Yossef .blocksize = AES_BLOCK_SIZE, 83663ee04c8SGilad Ben-Yossef .template_skcipher = { 83763ee04c8SGilad Ben-Yossef .setkey = cc_cipher_setkey, 83863ee04c8SGilad Ben-Yossef .encrypt = cc_cipher_encrypt, 83963ee04c8SGilad Ben-Yossef .decrypt = cc_cipher_decrypt, 84063ee04c8SGilad Ben-Yossef .min_keysize = AES_MIN_KEY_SIZE * 2, 84163ee04c8SGilad Ben-Yossef .max_keysize = AES_MAX_KEY_SIZE * 2, 84263ee04c8SGilad Ben-Yossef .ivsize = AES_BLOCK_SIZE, 84363ee04c8SGilad Ben-Yossef }, 84463ee04c8SGilad Ben-Yossef .cipher_mode = DRV_CIPHER_BITLOCKER, 84563ee04c8SGilad Ben-Yossef .flow_mode = S_DIN_to_AES, 84663ee04c8SGilad Ben-Yossef }, 84763ee04c8SGilad Ben-Yossef { 84863ee04c8SGilad Ben-Yossef .name = "bitlocker512(aes)", 84963ee04c8SGilad Ben-Yossef .driver_name = "bitlocker-aes-du512-ccree", 85063ee04c8SGilad Ben-Yossef .blocksize = AES_BLOCK_SIZE, 85163ee04c8SGilad Ben-Yossef .template_skcipher = { 85263ee04c8SGilad Ben-Yossef .setkey = cc_cipher_setkey, 85363ee04c8SGilad Ben-Yossef .encrypt = cc_cipher_encrypt, 85463ee04c8SGilad Ben-Yossef .decrypt = cc_cipher_decrypt, 85563ee04c8SGilad Ben-Yossef .min_keysize = AES_MIN_KEY_SIZE * 2, 85663ee04c8SGilad Ben-Yossef .max_keysize = AES_MAX_KEY_SIZE * 2, 85763ee04c8SGilad Ben-Yossef .ivsize = AES_BLOCK_SIZE, 85863ee04c8SGilad Ben-Yossef }, 85963ee04c8SGilad Ben-Yossef .cipher_mode = DRV_CIPHER_BITLOCKER, 86063ee04c8SGilad Ben-Yossef .flow_mode = S_DIN_to_AES, 86163ee04c8SGilad Ben-Yossef .data_unit = 512, 86263ee04c8SGilad Ben-Yossef }, 86363ee04c8SGilad Ben-Yossef { 86463ee04c8SGilad Ben-Yossef .name = "bitlocker4096(aes)", 86563ee04c8SGilad Ben-Yossef .driver_name = "bitlocker-aes-du4096-ccree", 86663ee04c8SGilad Ben-Yossef .blocksize = AES_BLOCK_SIZE, 86763ee04c8SGilad Ben-Yossef .template_skcipher = { 86863ee04c8SGilad Ben-Yossef .setkey = cc_cipher_setkey, 86963ee04c8SGilad Ben-Yossef .encrypt = cc_cipher_encrypt, 87063ee04c8SGilad Ben-Yossef .decrypt = cc_cipher_decrypt, 87163ee04c8SGilad Ben-Yossef .min_keysize = AES_MIN_KEY_SIZE * 2, 87263ee04c8SGilad Ben-Yossef .max_keysize = AES_MAX_KEY_SIZE * 2, 87363ee04c8SGilad Ben-Yossef .ivsize = AES_BLOCK_SIZE, 87463ee04c8SGilad Ben-Yossef }, 87563ee04c8SGilad Ben-Yossef .cipher_mode = DRV_CIPHER_BITLOCKER, 87663ee04c8SGilad Ben-Yossef .flow_mode = S_DIN_to_AES, 87763ee04c8SGilad Ben-Yossef .data_unit = 4096, 87863ee04c8SGilad Ben-Yossef }, 87963ee04c8SGilad Ben-Yossef { 88063ee04c8SGilad Ben-Yossef .name = "ecb(aes)", 88163ee04c8SGilad Ben-Yossef .driver_name = "ecb-aes-ccree", 88263ee04c8SGilad Ben-Yossef .blocksize = AES_BLOCK_SIZE, 88363ee04c8SGilad Ben-Yossef .type = CRYPTO_ALG_TYPE_ABLKCIPHER, 88463ee04c8SGilad Ben-Yossef .template_skcipher = { 88563ee04c8SGilad Ben-Yossef .setkey = cc_cipher_setkey, 88663ee04c8SGilad Ben-Yossef .encrypt = cc_cipher_encrypt, 88763ee04c8SGilad Ben-Yossef .decrypt = cc_cipher_decrypt, 88863ee04c8SGilad Ben-Yossef .min_keysize = AES_MIN_KEY_SIZE, 88963ee04c8SGilad Ben-Yossef .max_keysize = AES_MAX_KEY_SIZE, 89063ee04c8SGilad Ben-Yossef .ivsize = 0, 89163ee04c8SGilad Ben-Yossef }, 89263ee04c8SGilad Ben-Yossef .cipher_mode = DRV_CIPHER_ECB, 89363ee04c8SGilad Ben-Yossef .flow_mode = S_DIN_to_AES, 89463ee04c8SGilad Ben-Yossef }, 89563ee04c8SGilad Ben-Yossef { 89663ee04c8SGilad Ben-Yossef .name = "cbc(aes)", 89763ee04c8SGilad Ben-Yossef .driver_name = "cbc-aes-ccree", 89863ee04c8SGilad Ben-Yossef .blocksize = AES_BLOCK_SIZE, 89963ee04c8SGilad Ben-Yossef .type = CRYPTO_ALG_TYPE_ABLKCIPHER, 90063ee04c8SGilad Ben-Yossef .template_skcipher = { 90163ee04c8SGilad Ben-Yossef .setkey = cc_cipher_setkey, 90263ee04c8SGilad Ben-Yossef .encrypt = cc_cipher_encrypt, 90363ee04c8SGilad Ben-Yossef .decrypt = cc_cipher_decrypt, 90463ee04c8SGilad Ben-Yossef .min_keysize = AES_MIN_KEY_SIZE, 90563ee04c8SGilad Ben-Yossef .max_keysize = AES_MAX_KEY_SIZE, 90663ee04c8SGilad Ben-Yossef .ivsize = AES_BLOCK_SIZE, 90763ee04c8SGilad Ben-Yossef }, 90863ee04c8SGilad Ben-Yossef .cipher_mode = DRV_CIPHER_CBC, 90963ee04c8SGilad Ben-Yossef .flow_mode = S_DIN_to_AES, 91063ee04c8SGilad Ben-Yossef }, 91163ee04c8SGilad Ben-Yossef { 91263ee04c8SGilad Ben-Yossef .name = "ofb(aes)", 91363ee04c8SGilad Ben-Yossef .driver_name = "ofb-aes-ccree", 91463ee04c8SGilad Ben-Yossef .blocksize = AES_BLOCK_SIZE, 91563ee04c8SGilad Ben-Yossef .type = CRYPTO_ALG_TYPE_ABLKCIPHER, 91663ee04c8SGilad Ben-Yossef .template_skcipher = { 91763ee04c8SGilad Ben-Yossef .setkey = cc_cipher_setkey, 91863ee04c8SGilad Ben-Yossef .encrypt = cc_cipher_encrypt, 91963ee04c8SGilad Ben-Yossef .decrypt = cc_cipher_decrypt, 92063ee04c8SGilad Ben-Yossef .min_keysize = AES_MIN_KEY_SIZE, 92163ee04c8SGilad Ben-Yossef .max_keysize = AES_MAX_KEY_SIZE, 92263ee04c8SGilad Ben-Yossef .ivsize = AES_BLOCK_SIZE, 92363ee04c8SGilad Ben-Yossef }, 92463ee04c8SGilad Ben-Yossef .cipher_mode = DRV_CIPHER_OFB, 92563ee04c8SGilad Ben-Yossef .flow_mode = S_DIN_to_AES, 92663ee04c8SGilad Ben-Yossef }, 92763ee04c8SGilad Ben-Yossef { 92863ee04c8SGilad Ben-Yossef .name = "cts1(cbc(aes))", 92963ee04c8SGilad Ben-Yossef .driver_name = "cts1-cbc-aes-ccree", 93063ee04c8SGilad Ben-Yossef .blocksize = AES_BLOCK_SIZE, 93163ee04c8SGilad Ben-Yossef .type = CRYPTO_ALG_TYPE_ABLKCIPHER, 93263ee04c8SGilad Ben-Yossef .template_skcipher = { 93363ee04c8SGilad Ben-Yossef .setkey = cc_cipher_setkey, 93463ee04c8SGilad Ben-Yossef .encrypt = cc_cipher_encrypt, 93563ee04c8SGilad Ben-Yossef .decrypt = cc_cipher_decrypt, 93663ee04c8SGilad Ben-Yossef .min_keysize = AES_MIN_KEY_SIZE, 93763ee04c8SGilad Ben-Yossef .max_keysize = AES_MAX_KEY_SIZE, 93863ee04c8SGilad Ben-Yossef .ivsize = AES_BLOCK_SIZE, 93963ee04c8SGilad Ben-Yossef }, 94063ee04c8SGilad Ben-Yossef .cipher_mode = DRV_CIPHER_CBC_CTS, 94163ee04c8SGilad Ben-Yossef .flow_mode = S_DIN_to_AES, 94263ee04c8SGilad Ben-Yossef }, 94363ee04c8SGilad Ben-Yossef { 94463ee04c8SGilad Ben-Yossef .name = "ctr(aes)", 94563ee04c8SGilad Ben-Yossef .driver_name = "ctr-aes-ccree", 94663ee04c8SGilad Ben-Yossef .blocksize = 1, 94763ee04c8SGilad Ben-Yossef .type = CRYPTO_ALG_TYPE_ABLKCIPHER, 94863ee04c8SGilad Ben-Yossef .template_skcipher = { 94963ee04c8SGilad Ben-Yossef .setkey = cc_cipher_setkey, 95063ee04c8SGilad Ben-Yossef .encrypt = cc_cipher_encrypt, 95163ee04c8SGilad Ben-Yossef .decrypt = cc_cipher_decrypt, 95263ee04c8SGilad Ben-Yossef .min_keysize = AES_MIN_KEY_SIZE, 95363ee04c8SGilad Ben-Yossef .max_keysize = AES_MAX_KEY_SIZE, 95463ee04c8SGilad Ben-Yossef .ivsize = AES_BLOCK_SIZE, 95563ee04c8SGilad Ben-Yossef }, 95663ee04c8SGilad Ben-Yossef .cipher_mode = DRV_CIPHER_CTR, 95763ee04c8SGilad Ben-Yossef .flow_mode = S_DIN_to_AES, 95863ee04c8SGilad Ben-Yossef }, 95963ee04c8SGilad Ben-Yossef { 96063ee04c8SGilad Ben-Yossef .name = "cbc(des3_ede)", 96163ee04c8SGilad Ben-Yossef .driver_name = "cbc-3des-ccree", 96263ee04c8SGilad Ben-Yossef .blocksize = DES3_EDE_BLOCK_SIZE, 96363ee04c8SGilad Ben-Yossef .type = CRYPTO_ALG_TYPE_ABLKCIPHER, 96463ee04c8SGilad Ben-Yossef .template_skcipher = { 96563ee04c8SGilad Ben-Yossef .setkey = cc_cipher_setkey, 96663ee04c8SGilad Ben-Yossef .encrypt = cc_cipher_encrypt, 96763ee04c8SGilad Ben-Yossef .decrypt = cc_cipher_decrypt, 96863ee04c8SGilad Ben-Yossef .min_keysize = DES3_EDE_KEY_SIZE, 96963ee04c8SGilad Ben-Yossef .max_keysize = DES3_EDE_KEY_SIZE, 97063ee04c8SGilad Ben-Yossef .ivsize = DES3_EDE_BLOCK_SIZE, 97163ee04c8SGilad Ben-Yossef }, 97263ee04c8SGilad Ben-Yossef .cipher_mode = DRV_CIPHER_CBC, 97363ee04c8SGilad Ben-Yossef .flow_mode = S_DIN_to_DES, 97463ee04c8SGilad Ben-Yossef }, 97563ee04c8SGilad Ben-Yossef { 97663ee04c8SGilad Ben-Yossef .name = "ecb(des3_ede)", 97763ee04c8SGilad Ben-Yossef .driver_name = "ecb-3des-ccree", 97863ee04c8SGilad Ben-Yossef .blocksize = DES3_EDE_BLOCK_SIZE, 97963ee04c8SGilad Ben-Yossef .type = CRYPTO_ALG_TYPE_ABLKCIPHER, 98063ee04c8SGilad Ben-Yossef .template_skcipher = { 98163ee04c8SGilad Ben-Yossef .setkey = cc_cipher_setkey, 98263ee04c8SGilad Ben-Yossef .encrypt = cc_cipher_encrypt, 98363ee04c8SGilad Ben-Yossef .decrypt = cc_cipher_decrypt, 98463ee04c8SGilad Ben-Yossef .min_keysize = DES3_EDE_KEY_SIZE, 98563ee04c8SGilad Ben-Yossef .max_keysize = DES3_EDE_KEY_SIZE, 98663ee04c8SGilad Ben-Yossef .ivsize = 0, 98763ee04c8SGilad Ben-Yossef }, 98863ee04c8SGilad Ben-Yossef .cipher_mode = DRV_CIPHER_ECB, 98963ee04c8SGilad Ben-Yossef .flow_mode = S_DIN_to_DES, 99063ee04c8SGilad Ben-Yossef }, 99163ee04c8SGilad Ben-Yossef { 99263ee04c8SGilad Ben-Yossef .name = "cbc(des)", 99363ee04c8SGilad Ben-Yossef .driver_name = "cbc-des-ccree", 99463ee04c8SGilad Ben-Yossef .blocksize = DES_BLOCK_SIZE, 99563ee04c8SGilad Ben-Yossef .type = CRYPTO_ALG_TYPE_ABLKCIPHER, 99663ee04c8SGilad Ben-Yossef .template_skcipher = { 99763ee04c8SGilad Ben-Yossef .setkey = cc_cipher_setkey, 99863ee04c8SGilad Ben-Yossef .encrypt = cc_cipher_encrypt, 99963ee04c8SGilad Ben-Yossef .decrypt = cc_cipher_decrypt, 100063ee04c8SGilad Ben-Yossef .min_keysize = DES_KEY_SIZE, 100163ee04c8SGilad Ben-Yossef .max_keysize = DES_KEY_SIZE, 100263ee04c8SGilad Ben-Yossef .ivsize = DES_BLOCK_SIZE, 100363ee04c8SGilad Ben-Yossef }, 100463ee04c8SGilad Ben-Yossef .cipher_mode = DRV_CIPHER_CBC, 100563ee04c8SGilad Ben-Yossef .flow_mode = S_DIN_to_DES, 100663ee04c8SGilad Ben-Yossef }, 100763ee04c8SGilad Ben-Yossef { 100863ee04c8SGilad Ben-Yossef .name = "ecb(des)", 100963ee04c8SGilad Ben-Yossef .driver_name = "ecb-des-ccree", 101063ee04c8SGilad Ben-Yossef .blocksize = DES_BLOCK_SIZE, 101163ee04c8SGilad Ben-Yossef .type = CRYPTO_ALG_TYPE_ABLKCIPHER, 101263ee04c8SGilad Ben-Yossef .template_skcipher = { 101363ee04c8SGilad Ben-Yossef .setkey = cc_cipher_setkey, 101463ee04c8SGilad Ben-Yossef .encrypt = cc_cipher_encrypt, 101563ee04c8SGilad Ben-Yossef .decrypt = cc_cipher_decrypt, 101663ee04c8SGilad Ben-Yossef .min_keysize = DES_KEY_SIZE, 101763ee04c8SGilad Ben-Yossef .max_keysize = DES_KEY_SIZE, 101863ee04c8SGilad Ben-Yossef .ivsize = 0, 101963ee04c8SGilad Ben-Yossef }, 102063ee04c8SGilad Ben-Yossef .cipher_mode = DRV_CIPHER_ECB, 102163ee04c8SGilad Ben-Yossef .flow_mode = S_DIN_to_DES, 102263ee04c8SGilad Ben-Yossef }, 102363ee04c8SGilad Ben-Yossef }; 102463ee04c8SGilad Ben-Yossef 102563ee04c8SGilad Ben-Yossef static struct cc_crypto_alg *cc_create_alg(const struct cc_alg_template *tmpl, 102663ee04c8SGilad Ben-Yossef struct device *dev) 102763ee04c8SGilad Ben-Yossef { 102863ee04c8SGilad Ben-Yossef struct cc_crypto_alg *t_alg; 102963ee04c8SGilad Ben-Yossef struct skcipher_alg *alg; 103063ee04c8SGilad Ben-Yossef 103163ee04c8SGilad Ben-Yossef t_alg = kzalloc(sizeof(*t_alg), GFP_KERNEL); 103263ee04c8SGilad Ben-Yossef if (!t_alg) 103363ee04c8SGilad Ben-Yossef return ERR_PTR(-ENOMEM); 103463ee04c8SGilad Ben-Yossef 103563ee04c8SGilad Ben-Yossef alg = &t_alg->skcipher_alg; 103663ee04c8SGilad Ben-Yossef 103763ee04c8SGilad Ben-Yossef memcpy(alg, &tmpl->template_skcipher, sizeof(*alg)); 103863ee04c8SGilad Ben-Yossef 103963ee04c8SGilad Ben-Yossef snprintf(alg->base.cra_name, CRYPTO_MAX_ALG_NAME, "%s", tmpl->name); 104063ee04c8SGilad Ben-Yossef snprintf(alg->base.cra_driver_name, CRYPTO_MAX_ALG_NAME, "%s", 104163ee04c8SGilad Ben-Yossef tmpl->driver_name); 104263ee04c8SGilad Ben-Yossef alg->base.cra_module = THIS_MODULE; 104363ee04c8SGilad Ben-Yossef alg->base.cra_priority = CC_CRA_PRIO; 104463ee04c8SGilad Ben-Yossef alg->base.cra_blocksize = tmpl->blocksize; 104563ee04c8SGilad Ben-Yossef alg->base.cra_alignmask = 0; 104663ee04c8SGilad Ben-Yossef alg->base.cra_ctxsize = sizeof(struct cc_cipher_ctx); 104763ee04c8SGilad Ben-Yossef 104863ee04c8SGilad Ben-Yossef alg->base.cra_init = cc_cipher_init; 104963ee04c8SGilad Ben-Yossef alg->base.cra_exit = cc_cipher_exit; 105063ee04c8SGilad Ben-Yossef alg->base.cra_flags = CRYPTO_ALG_ASYNC | CRYPTO_ALG_KERN_DRIVER_ONLY | 105163ee04c8SGilad Ben-Yossef CRYPTO_ALG_TYPE_SKCIPHER; 105263ee04c8SGilad Ben-Yossef 105363ee04c8SGilad Ben-Yossef t_alg->cipher_mode = tmpl->cipher_mode; 105463ee04c8SGilad Ben-Yossef t_alg->flow_mode = tmpl->flow_mode; 105563ee04c8SGilad Ben-Yossef t_alg->data_unit = tmpl->data_unit; 105663ee04c8SGilad Ben-Yossef 105763ee04c8SGilad Ben-Yossef return t_alg; 105863ee04c8SGilad Ben-Yossef } 105963ee04c8SGilad Ben-Yossef 106063ee04c8SGilad Ben-Yossef int cc_cipher_free(struct cc_drvdata *drvdata) 106163ee04c8SGilad Ben-Yossef { 106263ee04c8SGilad Ben-Yossef struct cc_crypto_alg *t_alg, *n; 106363ee04c8SGilad Ben-Yossef struct cc_cipher_handle *cipher_handle = drvdata->cipher_handle; 106463ee04c8SGilad Ben-Yossef 106563ee04c8SGilad Ben-Yossef if (cipher_handle) { 106663ee04c8SGilad Ben-Yossef /* Remove registered algs */ 106763ee04c8SGilad Ben-Yossef list_for_each_entry_safe(t_alg, n, &cipher_handle->alg_list, 106863ee04c8SGilad Ben-Yossef entry) { 106963ee04c8SGilad Ben-Yossef crypto_unregister_skcipher(&t_alg->skcipher_alg); 107063ee04c8SGilad Ben-Yossef list_del(&t_alg->entry); 107163ee04c8SGilad Ben-Yossef kfree(t_alg); 107263ee04c8SGilad Ben-Yossef } 107363ee04c8SGilad Ben-Yossef kfree(cipher_handle); 107463ee04c8SGilad Ben-Yossef drvdata->cipher_handle = NULL; 107563ee04c8SGilad Ben-Yossef } 107663ee04c8SGilad Ben-Yossef return 0; 107763ee04c8SGilad Ben-Yossef } 107863ee04c8SGilad Ben-Yossef 107963ee04c8SGilad Ben-Yossef int cc_cipher_alloc(struct cc_drvdata *drvdata) 108063ee04c8SGilad Ben-Yossef { 108163ee04c8SGilad Ben-Yossef struct cc_cipher_handle *cipher_handle; 108263ee04c8SGilad Ben-Yossef struct cc_crypto_alg *t_alg; 108363ee04c8SGilad Ben-Yossef struct device *dev = drvdata_to_dev(drvdata); 108463ee04c8SGilad Ben-Yossef int rc = -ENOMEM; 108563ee04c8SGilad Ben-Yossef int alg; 108663ee04c8SGilad Ben-Yossef 108763ee04c8SGilad Ben-Yossef cipher_handle = kmalloc(sizeof(*cipher_handle), GFP_KERNEL); 108863ee04c8SGilad Ben-Yossef if (!cipher_handle) 108963ee04c8SGilad Ben-Yossef return -ENOMEM; 109063ee04c8SGilad Ben-Yossef 109163ee04c8SGilad Ben-Yossef INIT_LIST_HEAD(&cipher_handle->alg_list); 109263ee04c8SGilad Ben-Yossef drvdata->cipher_handle = cipher_handle; 109363ee04c8SGilad Ben-Yossef 109463ee04c8SGilad Ben-Yossef /* Linux crypto */ 109563ee04c8SGilad Ben-Yossef dev_dbg(dev, "Number of algorithms = %zu\n", 109663ee04c8SGilad Ben-Yossef ARRAY_SIZE(skcipher_algs)); 109763ee04c8SGilad Ben-Yossef for (alg = 0; alg < ARRAY_SIZE(skcipher_algs); alg++) { 109863ee04c8SGilad Ben-Yossef dev_dbg(dev, "creating %s\n", skcipher_algs[alg].driver_name); 109963ee04c8SGilad Ben-Yossef t_alg = cc_create_alg(&skcipher_algs[alg], dev); 110063ee04c8SGilad Ben-Yossef if (IS_ERR(t_alg)) { 110163ee04c8SGilad Ben-Yossef rc = PTR_ERR(t_alg); 110263ee04c8SGilad Ben-Yossef dev_err(dev, "%s alg allocation failed\n", 110363ee04c8SGilad Ben-Yossef skcipher_algs[alg].driver_name); 110463ee04c8SGilad Ben-Yossef goto fail0; 110563ee04c8SGilad Ben-Yossef } 110663ee04c8SGilad Ben-Yossef t_alg->drvdata = drvdata; 110763ee04c8SGilad Ben-Yossef 110863ee04c8SGilad Ben-Yossef dev_dbg(dev, "registering %s\n", 110963ee04c8SGilad Ben-Yossef skcipher_algs[alg].driver_name); 111063ee04c8SGilad Ben-Yossef rc = crypto_register_skcipher(&t_alg->skcipher_alg); 111163ee04c8SGilad Ben-Yossef dev_dbg(dev, "%s alg registration rc = %x\n", 111263ee04c8SGilad Ben-Yossef t_alg->skcipher_alg.base.cra_driver_name, rc); 111363ee04c8SGilad Ben-Yossef if (rc) { 111463ee04c8SGilad Ben-Yossef dev_err(dev, "%s alg registration failed\n", 111563ee04c8SGilad Ben-Yossef t_alg->skcipher_alg.base.cra_driver_name); 111663ee04c8SGilad Ben-Yossef kfree(t_alg); 111763ee04c8SGilad Ben-Yossef goto fail0; 111863ee04c8SGilad Ben-Yossef } else { 111963ee04c8SGilad Ben-Yossef list_add_tail(&t_alg->entry, 112063ee04c8SGilad Ben-Yossef &cipher_handle->alg_list); 112163ee04c8SGilad Ben-Yossef dev_dbg(dev, "Registered %s\n", 112263ee04c8SGilad Ben-Yossef t_alg->skcipher_alg.base.cra_driver_name); 112363ee04c8SGilad Ben-Yossef } 112463ee04c8SGilad Ben-Yossef } 112563ee04c8SGilad Ben-Yossef return 0; 112663ee04c8SGilad Ben-Yossef 112763ee04c8SGilad Ben-Yossef fail0: 112863ee04c8SGilad Ben-Yossef cc_cipher_free(drvdata); 112963ee04c8SGilad Ben-Yossef return rc; 113063ee04c8SGilad Ben-Yossef } 1131