162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 262306a36Sopenharmony_ci#include <linux/crypto.h> 362306a36Sopenharmony_ci#include <linux/kernel.h> 462306a36Sopenharmony_ci#include <linux/module.h> 562306a36Sopenharmony_ci#include <linux/printk.h> 662306a36Sopenharmony_ci 762306a36Sopenharmony_ci#include <crypto/aes.h> 862306a36Sopenharmony_ci#include <crypto/skcipher.h> 962306a36Sopenharmony_ci#include <crypto/scatterwalk.h> 1062306a36Sopenharmony_ci#include <crypto/ctr.h> 1162306a36Sopenharmony_ci#include <crypto/internal/des.h> 1262306a36Sopenharmony_ci#include <crypto/xts.h> 1362306a36Sopenharmony_ci 1462306a36Sopenharmony_ci#include "nitrox_dev.h" 1562306a36Sopenharmony_ci#include "nitrox_common.h" 1662306a36Sopenharmony_ci#include "nitrox_req.h" 1762306a36Sopenharmony_ci 1862306a36Sopenharmony_cistruct nitrox_cipher { 1962306a36Sopenharmony_ci const char *name; 2062306a36Sopenharmony_ci enum flexi_cipher value; 2162306a36Sopenharmony_ci}; 2262306a36Sopenharmony_ci 2362306a36Sopenharmony_ci/* 2462306a36Sopenharmony_ci * supported cipher list 2562306a36Sopenharmony_ci */ 2662306a36Sopenharmony_cistatic const struct nitrox_cipher flexi_cipher_table[] = { 2762306a36Sopenharmony_ci { "null", CIPHER_NULL }, 2862306a36Sopenharmony_ci { "cbc(des3_ede)", CIPHER_3DES_CBC }, 2962306a36Sopenharmony_ci { "ecb(des3_ede)", CIPHER_3DES_ECB }, 3062306a36Sopenharmony_ci { "cbc(aes)", CIPHER_AES_CBC }, 3162306a36Sopenharmony_ci { "ecb(aes)", CIPHER_AES_ECB }, 3262306a36Sopenharmony_ci { "cfb(aes)", CIPHER_AES_CFB }, 3362306a36Sopenharmony_ci { "rfc3686(ctr(aes))", CIPHER_AES_CTR }, 3462306a36Sopenharmony_ci { "xts(aes)", CIPHER_AES_XTS }, 3562306a36Sopenharmony_ci { "cts(cbc(aes))", CIPHER_AES_CBC_CTS }, 3662306a36Sopenharmony_ci { NULL, CIPHER_INVALID } 3762306a36Sopenharmony_ci}; 3862306a36Sopenharmony_ci 3962306a36Sopenharmony_cistatic enum flexi_cipher flexi_cipher_type(const char *name) 4062306a36Sopenharmony_ci{ 4162306a36Sopenharmony_ci const struct nitrox_cipher *cipher = flexi_cipher_table; 4262306a36Sopenharmony_ci 4362306a36Sopenharmony_ci while (cipher->name) { 4462306a36Sopenharmony_ci if (!strcmp(cipher->name, name)) 4562306a36Sopenharmony_ci break; 4662306a36Sopenharmony_ci cipher++; 4762306a36Sopenharmony_ci } 4862306a36Sopenharmony_ci return cipher->value; 4962306a36Sopenharmony_ci} 5062306a36Sopenharmony_ci 5162306a36Sopenharmony_cistatic void free_src_sglist(struct skcipher_request *skreq) 5262306a36Sopenharmony_ci{ 5362306a36Sopenharmony_ci struct nitrox_kcrypt_request *nkreq = skcipher_request_ctx(skreq); 5462306a36Sopenharmony_ci 5562306a36Sopenharmony_ci kfree(nkreq->src); 5662306a36Sopenharmony_ci} 5762306a36Sopenharmony_ci 5862306a36Sopenharmony_cistatic void free_dst_sglist(struct skcipher_request *skreq) 5962306a36Sopenharmony_ci{ 6062306a36Sopenharmony_ci struct nitrox_kcrypt_request *nkreq = skcipher_request_ctx(skreq); 6162306a36Sopenharmony_ci 6262306a36Sopenharmony_ci kfree(nkreq->dst); 6362306a36Sopenharmony_ci} 6462306a36Sopenharmony_ci 6562306a36Sopenharmony_cistatic void nitrox_skcipher_callback(void *arg, int err) 6662306a36Sopenharmony_ci{ 6762306a36Sopenharmony_ci struct skcipher_request *skreq = arg; 6862306a36Sopenharmony_ci 6962306a36Sopenharmony_ci free_src_sglist(skreq); 7062306a36Sopenharmony_ci free_dst_sglist(skreq); 7162306a36Sopenharmony_ci if (err) { 7262306a36Sopenharmony_ci pr_err_ratelimited("request failed status 0x%0x\n", err); 7362306a36Sopenharmony_ci err = -EINVAL; 7462306a36Sopenharmony_ci } 7562306a36Sopenharmony_ci 7662306a36Sopenharmony_ci skcipher_request_complete(skreq, err); 7762306a36Sopenharmony_ci} 7862306a36Sopenharmony_ci 7962306a36Sopenharmony_cistatic void nitrox_cbc_cipher_callback(void *arg, int err) 8062306a36Sopenharmony_ci{ 8162306a36Sopenharmony_ci struct skcipher_request *skreq = arg; 8262306a36Sopenharmony_ci struct nitrox_kcrypt_request *nkreq = skcipher_request_ctx(skreq); 8362306a36Sopenharmony_ci struct crypto_skcipher *cipher = crypto_skcipher_reqtfm(skreq); 8462306a36Sopenharmony_ci int ivsize = crypto_skcipher_ivsize(cipher); 8562306a36Sopenharmony_ci unsigned int start = skreq->cryptlen - ivsize; 8662306a36Sopenharmony_ci 8762306a36Sopenharmony_ci if (err) { 8862306a36Sopenharmony_ci nitrox_skcipher_callback(arg, err); 8962306a36Sopenharmony_ci return; 9062306a36Sopenharmony_ci } 9162306a36Sopenharmony_ci 9262306a36Sopenharmony_ci if (nkreq->creq.ctrl.s.arg == ENCRYPT) { 9362306a36Sopenharmony_ci scatterwalk_map_and_copy(skreq->iv, skreq->dst, start, ivsize, 9462306a36Sopenharmony_ci 0); 9562306a36Sopenharmony_ci } else { 9662306a36Sopenharmony_ci if (skreq->src != skreq->dst) { 9762306a36Sopenharmony_ci scatterwalk_map_and_copy(skreq->iv, skreq->src, start, 9862306a36Sopenharmony_ci ivsize, 0); 9962306a36Sopenharmony_ci } else { 10062306a36Sopenharmony_ci memcpy(skreq->iv, nkreq->iv_out, ivsize); 10162306a36Sopenharmony_ci kfree(nkreq->iv_out); 10262306a36Sopenharmony_ci } 10362306a36Sopenharmony_ci } 10462306a36Sopenharmony_ci 10562306a36Sopenharmony_ci nitrox_skcipher_callback(arg, err); 10662306a36Sopenharmony_ci} 10762306a36Sopenharmony_ci 10862306a36Sopenharmony_cistatic int nitrox_skcipher_init(struct crypto_skcipher *tfm) 10962306a36Sopenharmony_ci{ 11062306a36Sopenharmony_ci struct nitrox_crypto_ctx *nctx = crypto_skcipher_ctx(tfm); 11162306a36Sopenharmony_ci struct crypto_ctx_hdr *chdr; 11262306a36Sopenharmony_ci 11362306a36Sopenharmony_ci /* get the first device */ 11462306a36Sopenharmony_ci nctx->ndev = nitrox_get_first_device(); 11562306a36Sopenharmony_ci if (!nctx->ndev) 11662306a36Sopenharmony_ci return -ENODEV; 11762306a36Sopenharmony_ci 11862306a36Sopenharmony_ci /* allocate nitrox crypto context */ 11962306a36Sopenharmony_ci chdr = crypto_alloc_context(nctx->ndev); 12062306a36Sopenharmony_ci if (!chdr) { 12162306a36Sopenharmony_ci nitrox_put_device(nctx->ndev); 12262306a36Sopenharmony_ci return -ENOMEM; 12362306a36Sopenharmony_ci } 12462306a36Sopenharmony_ci 12562306a36Sopenharmony_ci nctx->callback = nitrox_skcipher_callback; 12662306a36Sopenharmony_ci nctx->chdr = chdr; 12762306a36Sopenharmony_ci nctx->u.ctx_handle = (uintptr_t)((u8 *)chdr->vaddr + 12862306a36Sopenharmony_ci sizeof(struct ctx_hdr)); 12962306a36Sopenharmony_ci crypto_skcipher_set_reqsize(tfm, crypto_skcipher_reqsize(tfm) + 13062306a36Sopenharmony_ci sizeof(struct nitrox_kcrypt_request)); 13162306a36Sopenharmony_ci return 0; 13262306a36Sopenharmony_ci} 13362306a36Sopenharmony_ci 13462306a36Sopenharmony_cistatic int nitrox_cbc_init(struct crypto_skcipher *tfm) 13562306a36Sopenharmony_ci{ 13662306a36Sopenharmony_ci int err; 13762306a36Sopenharmony_ci struct nitrox_crypto_ctx *nctx = crypto_skcipher_ctx(tfm); 13862306a36Sopenharmony_ci 13962306a36Sopenharmony_ci err = nitrox_skcipher_init(tfm); 14062306a36Sopenharmony_ci if (err) 14162306a36Sopenharmony_ci return err; 14262306a36Sopenharmony_ci 14362306a36Sopenharmony_ci nctx->callback = nitrox_cbc_cipher_callback; 14462306a36Sopenharmony_ci return 0; 14562306a36Sopenharmony_ci} 14662306a36Sopenharmony_ci 14762306a36Sopenharmony_cistatic void nitrox_skcipher_exit(struct crypto_skcipher *tfm) 14862306a36Sopenharmony_ci{ 14962306a36Sopenharmony_ci struct nitrox_crypto_ctx *nctx = crypto_skcipher_ctx(tfm); 15062306a36Sopenharmony_ci 15162306a36Sopenharmony_ci /* free the nitrox crypto context */ 15262306a36Sopenharmony_ci if (nctx->u.ctx_handle) { 15362306a36Sopenharmony_ci struct flexi_crypto_context *fctx = nctx->u.fctx; 15462306a36Sopenharmony_ci 15562306a36Sopenharmony_ci memzero_explicit(&fctx->crypto, sizeof(struct crypto_keys)); 15662306a36Sopenharmony_ci memzero_explicit(&fctx->auth, sizeof(struct auth_keys)); 15762306a36Sopenharmony_ci crypto_free_context((void *)nctx->chdr); 15862306a36Sopenharmony_ci } 15962306a36Sopenharmony_ci nitrox_put_device(nctx->ndev); 16062306a36Sopenharmony_ci 16162306a36Sopenharmony_ci nctx->u.ctx_handle = 0; 16262306a36Sopenharmony_ci nctx->ndev = NULL; 16362306a36Sopenharmony_ci} 16462306a36Sopenharmony_ci 16562306a36Sopenharmony_cistatic inline int nitrox_skcipher_setkey(struct crypto_skcipher *cipher, 16662306a36Sopenharmony_ci int aes_keylen, const u8 *key, 16762306a36Sopenharmony_ci unsigned int keylen) 16862306a36Sopenharmony_ci{ 16962306a36Sopenharmony_ci struct crypto_tfm *tfm = crypto_skcipher_tfm(cipher); 17062306a36Sopenharmony_ci struct nitrox_crypto_ctx *nctx = crypto_tfm_ctx(tfm); 17162306a36Sopenharmony_ci struct flexi_crypto_context *fctx; 17262306a36Sopenharmony_ci union fc_ctx_flags *flags; 17362306a36Sopenharmony_ci enum flexi_cipher cipher_type; 17462306a36Sopenharmony_ci const char *name; 17562306a36Sopenharmony_ci 17662306a36Sopenharmony_ci name = crypto_tfm_alg_name(tfm); 17762306a36Sopenharmony_ci cipher_type = flexi_cipher_type(name); 17862306a36Sopenharmony_ci if (unlikely(cipher_type == CIPHER_INVALID)) { 17962306a36Sopenharmony_ci pr_err("unsupported cipher: %s\n", name); 18062306a36Sopenharmony_ci return -EINVAL; 18162306a36Sopenharmony_ci } 18262306a36Sopenharmony_ci 18362306a36Sopenharmony_ci /* fill crypto context */ 18462306a36Sopenharmony_ci fctx = nctx->u.fctx; 18562306a36Sopenharmony_ci flags = &fctx->flags; 18662306a36Sopenharmony_ci flags->f = 0; 18762306a36Sopenharmony_ci flags->w0.cipher_type = cipher_type; 18862306a36Sopenharmony_ci flags->w0.aes_keylen = aes_keylen; 18962306a36Sopenharmony_ci flags->w0.iv_source = IV_FROM_DPTR; 19062306a36Sopenharmony_ci flags->f = cpu_to_be64(*(u64 *)&flags->w0); 19162306a36Sopenharmony_ci /* copy the key to context */ 19262306a36Sopenharmony_ci memcpy(fctx->crypto.u.key, key, keylen); 19362306a36Sopenharmony_ci 19462306a36Sopenharmony_ci return 0; 19562306a36Sopenharmony_ci} 19662306a36Sopenharmony_ci 19762306a36Sopenharmony_cistatic int nitrox_aes_setkey(struct crypto_skcipher *cipher, const u8 *key, 19862306a36Sopenharmony_ci unsigned int keylen) 19962306a36Sopenharmony_ci{ 20062306a36Sopenharmony_ci int aes_keylen; 20162306a36Sopenharmony_ci 20262306a36Sopenharmony_ci aes_keylen = flexi_aes_keylen(keylen); 20362306a36Sopenharmony_ci if (aes_keylen < 0) 20462306a36Sopenharmony_ci return -EINVAL; 20562306a36Sopenharmony_ci return nitrox_skcipher_setkey(cipher, aes_keylen, key, keylen); 20662306a36Sopenharmony_ci} 20762306a36Sopenharmony_ci 20862306a36Sopenharmony_cistatic int alloc_src_sglist(struct skcipher_request *skreq, int ivsize) 20962306a36Sopenharmony_ci{ 21062306a36Sopenharmony_ci struct nitrox_kcrypt_request *nkreq = skcipher_request_ctx(skreq); 21162306a36Sopenharmony_ci int nents = sg_nents(skreq->src) + 1; 21262306a36Sopenharmony_ci int ret; 21362306a36Sopenharmony_ci 21462306a36Sopenharmony_ci /* Allocate buffer to hold IV and input scatterlist array */ 21562306a36Sopenharmony_ci ret = alloc_src_req_buf(nkreq, nents, ivsize); 21662306a36Sopenharmony_ci if (ret) 21762306a36Sopenharmony_ci return ret; 21862306a36Sopenharmony_ci 21962306a36Sopenharmony_ci nitrox_creq_copy_iv(nkreq->src, skreq->iv, ivsize); 22062306a36Sopenharmony_ci nitrox_creq_set_src_sg(nkreq, nents, ivsize, skreq->src, 22162306a36Sopenharmony_ci skreq->cryptlen); 22262306a36Sopenharmony_ci 22362306a36Sopenharmony_ci return 0; 22462306a36Sopenharmony_ci} 22562306a36Sopenharmony_ci 22662306a36Sopenharmony_cistatic int alloc_dst_sglist(struct skcipher_request *skreq, int ivsize) 22762306a36Sopenharmony_ci{ 22862306a36Sopenharmony_ci struct nitrox_kcrypt_request *nkreq = skcipher_request_ctx(skreq); 22962306a36Sopenharmony_ci int nents = sg_nents(skreq->dst) + 3; 23062306a36Sopenharmony_ci int ret; 23162306a36Sopenharmony_ci 23262306a36Sopenharmony_ci /* Allocate buffer to hold ORH, COMPLETION and output scatterlist 23362306a36Sopenharmony_ci * array 23462306a36Sopenharmony_ci */ 23562306a36Sopenharmony_ci ret = alloc_dst_req_buf(nkreq, nents); 23662306a36Sopenharmony_ci if (ret) 23762306a36Sopenharmony_ci return ret; 23862306a36Sopenharmony_ci 23962306a36Sopenharmony_ci nitrox_creq_set_orh(nkreq); 24062306a36Sopenharmony_ci nitrox_creq_set_comp(nkreq); 24162306a36Sopenharmony_ci nitrox_creq_set_dst_sg(nkreq, nents, ivsize, skreq->dst, 24262306a36Sopenharmony_ci skreq->cryptlen); 24362306a36Sopenharmony_ci 24462306a36Sopenharmony_ci return 0; 24562306a36Sopenharmony_ci} 24662306a36Sopenharmony_ci 24762306a36Sopenharmony_cistatic int nitrox_skcipher_crypt(struct skcipher_request *skreq, bool enc) 24862306a36Sopenharmony_ci{ 24962306a36Sopenharmony_ci struct crypto_skcipher *cipher = crypto_skcipher_reqtfm(skreq); 25062306a36Sopenharmony_ci struct nitrox_crypto_ctx *nctx = crypto_skcipher_ctx(cipher); 25162306a36Sopenharmony_ci struct nitrox_kcrypt_request *nkreq = skcipher_request_ctx(skreq); 25262306a36Sopenharmony_ci int ivsize = crypto_skcipher_ivsize(cipher); 25362306a36Sopenharmony_ci struct se_crypto_request *creq; 25462306a36Sopenharmony_ci int ret; 25562306a36Sopenharmony_ci 25662306a36Sopenharmony_ci creq = &nkreq->creq; 25762306a36Sopenharmony_ci creq->flags = skreq->base.flags; 25862306a36Sopenharmony_ci creq->gfp = (skreq->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP) ? 25962306a36Sopenharmony_ci GFP_KERNEL : GFP_ATOMIC; 26062306a36Sopenharmony_ci 26162306a36Sopenharmony_ci /* fill the request */ 26262306a36Sopenharmony_ci creq->ctrl.value = 0; 26362306a36Sopenharmony_ci creq->opcode = FLEXI_CRYPTO_ENCRYPT_HMAC; 26462306a36Sopenharmony_ci creq->ctrl.s.arg = (enc ? ENCRYPT : DECRYPT); 26562306a36Sopenharmony_ci /* param0: length of the data to be encrypted */ 26662306a36Sopenharmony_ci creq->gph.param0 = cpu_to_be16(skreq->cryptlen); 26762306a36Sopenharmony_ci creq->gph.param1 = 0; 26862306a36Sopenharmony_ci /* param2: encryption data offset */ 26962306a36Sopenharmony_ci creq->gph.param2 = cpu_to_be16(ivsize); 27062306a36Sopenharmony_ci creq->gph.param3 = 0; 27162306a36Sopenharmony_ci 27262306a36Sopenharmony_ci creq->ctx_handle = nctx->u.ctx_handle; 27362306a36Sopenharmony_ci creq->ctrl.s.ctxl = sizeof(struct flexi_crypto_context); 27462306a36Sopenharmony_ci 27562306a36Sopenharmony_ci ret = alloc_src_sglist(skreq, ivsize); 27662306a36Sopenharmony_ci if (ret) 27762306a36Sopenharmony_ci return ret; 27862306a36Sopenharmony_ci 27962306a36Sopenharmony_ci ret = alloc_dst_sglist(skreq, ivsize); 28062306a36Sopenharmony_ci if (ret) { 28162306a36Sopenharmony_ci free_src_sglist(skreq); 28262306a36Sopenharmony_ci return ret; 28362306a36Sopenharmony_ci } 28462306a36Sopenharmony_ci 28562306a36Sopenharmony_ci /* send the crypto request */ 28662306a36Sopenharmony_ci return nitrox_process_se_request(nctx->ndev, creq, nctx->callback, 28762306a36Sopenharmony_ci skreq); 28862306a36Sopenharmony_ci} 28962306a36Sopenharmony_ci 29062306a36Sopenharmony_cistatic int nitrox_cbc_decrypt(struct skcipher_request *skreq) 29162306a36Sopenharmony_ci{ 29262306a36Sopenharmony_ci struct nitrox_kcrypt_request *nkreq = skcipher_request_ctx(skreq); 29362306a36Sopenharmony_ci struct crypto_skcipher *cipher = crypto_skcipher_reqtfm(skreq); 29462306a36Sopenharmony_ci int ivsize = crypto_skcipher_ivsize(cipher); 29562306a36Sopenharmony_ci gfp_t flags = (skreq->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP) ? 29662306a36Sopenharmony_ci GFP_KERNEL : GFP_ATOMIC; 29762306a36Sopenharmony_ci unsigned int start = skreq->cryptlen - ivsize; 29862306a36Sopenharmony_ci 29962306a36Sopenharmony_ci if (skreq->src != skreq->dst) 30062306a36Sopenharmony_ci return nitrox_skcipher_crypt(skreq, false); 30162306a36Sopenharmony_ci 30262306a36Sopenharmony_ci nkreq->iv_out = kmalloc(ivsize, flags); 30362306a36Sopenharmony_ci if (!nkreq->iv_out) 30462306a36Sopenharmony_ci return -ENOMEM; 30562306a36Sopenharmony_ci 30662306a36Sopenharmony_ci scatterwalk_map_and_copy(nkreq->iv_out, skreq->src, start, ivsize, 0); 30762306a36Sopenharmony_ci return nitrox_skcipher_crypt(skreq, false); 30862306a36Sopenharmony_ci} 30962306a36Sopenharmony_ci 31062306a36Sopenharmony_cistatic int nitrox_aes_encrypt(struct skcipher_request *skreq) 31162306a36Sopenharmony_ci{ 31262306a36Sopenharmony_ci return nitrox_skcipher_crypt(skreq, true); 31362306a36Sopenharmony_ci} 31462306a36Sopenharmony_ci 31562306a36Sopenharmony_cistatic int nitrox_aes_decrypt(struct skcipher_request *skreq) 31662306a36Sopenharmony_ci{ 31762306a36Sopenharmony_ci return nitrox_skcipher_crypt(skreq, false); 31862306a36Sopenharmony_ci} 31962306a36Sopenharmony_ci 32062306a36Sopenharmony_cistatic int nitrox_3des_setkey(struct crypto_skcipher *cipher, 32162306a36Sopenharmony_ci const u8 *key, unsigned int keylen) 32262306a36Sopenharmony_ci{ 32362306a36Sopenharmony_ci return verify_skcipher_des3_key(cipher, key) ?: 32462306a36Sopenharmony_ci nitrox_skcipher_setkey(cipher, 0, key, keylen); 32562306a36Sopenharmony_ci} 32662306a36Sopenharmony_ci 32762306a36Sopenharmony_cistatic int nitrox_3des_encrypt(struct skcipher_request *skreq) 32862306a36Sopenharmony_ci{ 32962306a36Sopenharmony_ci return nitrox_skcipher_crypt(skreq, true); 33062306a36Sopenharmony_ci} 33162306a36Sopenharmony_ci 33262306a36Sopenharmony_cistatic int nitrox_3des_decrypt(struct skcipher_request *skreq) 33362306a36Sopenharmony_ci{ 33462306a36Sopenharmony_ci return nitrox_skcipher_crypt(skreq, false); 33562306a36Sopenharmony_ci} 33662306a36Sopenharmony_ci 33762306a36Sopenharmony_cistatic int nitrox_aes_xts_setkey(struct crypto_skcipher *cipher, 33862306a36Sopenharmony_ci const u8 *key, unsigned int keylen) 33962306a36Sopenharmony_ci{ 34062306a36Sopenharmony_ci struct nitrox_crypto_ctx *nctx = crypto_skcipher_ctx(cipher); 34162306a36Sopenharmony_ci struct flexi_crypto_context *fctx; 34262306a36Sopenharmony_ci int aes_keylen, ret; 34362306a36Sopenharmony_ci 34462306a36Sopenharmony_ci ret = xts_verify_key(cipher, key, keylen); 34562306a36Sopenharmony_ci if (ret) 34662306a36Sopenharmony_ci return ret; 34762306a36Sopenharmony_ci 34862306a36Sopenharmony_ci keylen /= 2; 34962306a36Sopenharmony_ci 35062306a36Sopenharmony_ci aes_keylen = flexi_aes_keylen(keylen); 35162306a36Sopenharmony_ci if (aes_keylen < 0) 35262306a36Sopenharmony_ci return -EINVAL; 35362306a36Sopenharmony_ci 35462306a36Sopenharmony_ci fctx = nctx->u.fctx; 35562306a36Sopenharmony_ci /* copy KEY2 */ 35662306a36Sopenharmony_ci memcpy(fctx->auth.u.key2, (key + keylen), keylen); 35762306a36Sopenharmony_ci 35862306a36Sopenharmony_ci return nitrox_skcipher_setkey(cipher, aes_keylen, key, keylen); 35962306a36Sopenharmony_ci} 36062306a36Sopenharmony_ci 36162306a36Sopenharmony_cistatic int nitrox_aes_ctr_rfc3686_setkey(struct crypto_skcipher *cipher, 36262306a36Sopenharmony_ci const u8 *key, unsigned int keylen) 36362306a36Sopenharmony_ci{ 36462306a36Sopenharmony_ci struct nitrox_crypto_ctx *nctx = crypto_skcipher_ctx(cipher); 36562306a36Sopenharmony_ci struct flexi_crypto_context *fctx; 36662306a36Sopenharmony_ci int aes_keylen; 36762306a36Sopenharmony_ci 36862306a36Sopenharmony_ci if (keylen < CTR_RFC3686_NONCE_SIZE) 36962306a36Sopenharmony_ci return -EINVAL; 37062306a36Sopenharmony_ci 37162306a36Sopenharmony_ci fctx = nctx->u.fctx; 37262306a36Sopenharmony_ci 37362306a36Sopenharmony_ci memcpy(fctx->crypto.iv, key + (keylen - CTR_RFC3686_NONCE_SIZE), 37462306a36Sopenharmony_ci CTR_RFC3686_NONCE_SIZE); 37562306a36Sopenharmony_ci 37662306a36Sopenharmony_ci keylen -= CTR_RFC3686_NONCE_SIZE; 37762306a36Sopenharmony_ci 37862306a36Sopenharmony_ci aes_keylen = flexi_aes_keylen(keylen); 37962306a36Sopenharmony_ci if (aes_keylen < 0) 38062306a36Sopenharmony_ci return -EINVAL; 38162306a36Sopenharmony_ci return nitrox_skcipher_setkey(cipher, aes_keylen, key, keylen); 38262306a36Sopenharmony_ci} 38362306a36Sopenharmony_ci 38462306a36Sopenharmony_cistatic struct skcipher_alg nitrox_skciphers[] = { { 38562306a36Sopenharmony_ci .base = { 38662306a36Sopenharmony_ci .cra_name = "cbc(aes)", 38762306a36Sopenharmony_ci .cra_driver_name = "n5_cbc(aes)", 38862306a36Sopenharmony_ci .cra_priority = PRIO, 38962306a36Sopenharmony_ci .cra_flags = CRYPTO_ALG_ASYNC | CRYPTO_ALG_ALLOCATES_MEMORY, 39062306a36Sopenharmony_ci .cra_blocksize = AES_BLOCK_SIZE, 39162306a36Sopenharmony_ci .cra_ctxsize = sizeof(struct nitrox_crypto_ctx), 39262306a36Sopenharmony_ci .cra_alignmask = 0, 39362306a36Sopenharmony_ci .cra_module = THIS_MODULE, 39462306a36Sopenharmony_ci }, 39562306a36Sopenharmony_ci .min_keysize = AES_MIN_KEY_SIZE, 39662306a36Sopenharmony_ci .max_keysize = AES_MAX_KEY_SIZE, 39762306a36Sopenharmony_ci .ivsize = AES_BLOCK_SIZE, 39862306a36Sopenharmony_ci .setkey = nitrox_aes_setkey, 39962306a36Sopenharmony_ci .encrypt = nitrox_aes_encrypt, 40062306a36Sopenharmony_ci .decrypt = nitrox_cbc_decrypt, 40162306a36Sopenharmony_ci .init = nitrox_cbc_init, 40262306a36Sopenharmony_ci .exit = nitrox_skcipher_exit, 40362306a36Sopenharmony_ci}, { 40462306a36Sopenharmony_ci .base = { 40562306a36Sopenharmony_ci .cra_name = "ecb(aes)", 40662306a36Sopenharmony_ci .cra_driver_name = "n5_ecb(aes)", 40762306a36Sopenharmony_ci .cra_priority = PRIO, 40862306a36Sopenharmony_ci .cra_flags = CRYPTO_ALG_ASYNC | CRYPTO_ALG_ALLOCATES_MEMORY, 40962306a36Sopenharmony_ci .cra_blocksize = AES_BLOCK_SIZE, 41062306a36Sopenharmony_ci .cra_ctxsize = sizeof(struct nitrox_crypto_ctx), 41162306a36Sopenharmony_ci .cra_alignmask = 0, 41262306a36Sopenharmony_ci .cra_module = THIS_MODULE, 41362306a36Sopenharmony_ci }, 41462306a36Sopenharmony_ci .min_keysize = AES_MIN_KEY_SIZE, 41562306a36Sopenharmony_ci .max_keysize = AES_MAX_KEY_SIZE, 41662306a36Sopenharmony_ci .ivsize = AES_BLOCK_SIZE, 41762306a36Sopenharmony_ci .setkey = nitrox_aes_setkey, 41862306a36Sopenharmony_ci .encrypt = nitrox_aes_encrypt, 41962306a36Sopenharmony_ci .decrypt = nitrox_aes_decrypt, 42062306a36Sopenharmony_ci .init = nitrox_skcipher_init, 42162306a36Sopenharmony_ci .exit = nitrox_skcipher_exit, 42262306a36Sopenharmony_ci}, { 42362306a36Sopenharmony_ci .base = { 42462306a36Sopenharmony_ci .cra_name = "cfb(aes)", 42562306a36Sopenharmony_ci .cra_driver_name = "n5_cfb(aes)", 42662306a36Sopenharmony_ci .cra_priority = PRIO, 42762306a36Sopenharmony_ci .cra_flags = CRYPTO_ALG_ASYNC | CRYPTO_ALG_ALLOCATES_MEMORY, 42862306a36Sopenharmony_ci .cra_blocksize = AES_BLOCK_SIZE, 42962306a36Sopenharmony_ci .cra_ctxsize = sizeof(struct nitrox_crypto_ctx), 43062306a36Sopenharmony_ci .cra_alignmask = 0, 43162306a36Sopenharmony_ci .cra_module = THIS_MODULE, 43262306a36Sopenharmony_ci }, 43362306a36Sopenharmony_ci .min_keysize = AES_MIN_KEY_SIZE, 43462306a36Sopenharmony_ci .max_keysize = AES_MAX_KEY_SIZE, 43562306a36Sopenharmony_ci .ivsize = AES_BLOCK_SIZE, 43662306a36Sopenharmony_ci .setkey = nitrox_aes_setkey, 43762306a36Sopenharmony_ci .encrypt = nitrox_aes_encrypt, 43862306a36Sopenharmony_ci .decrypt = nitrox_aes_decrypt, 43962306a36Sopenharmony_ci .init = nitrox_skcipher_init, 44062306a36Sopenharmony_ci .exit = nitrox_skcipher_exit, 44162306a36Sopenharmony_ci}, { 44262306a36Sopenharmony_ci .base = { 44362306a36Sopenharmony_ci .cra_name = "xts(aes)", 44462306a36Sopenharmony_ci .cra_driver_name = "n5_xts(aes)", 44562306a36Sopenharmony_ci .cra_priority = PRIO, 44662306a36Sopenharmony_ci .cra_flags = CRYPTO_ALG_ASYNC | CRYPTO_ALG_ALLOCATES_MEMORY, 44762306a36Sopenharmony_ci .cra_blocksize = AES_BLOCK_SIZE, 44862306a36Sopenharmony_ci .cra_ctxsize = sizeof(struct nitrox_crypto_ctx), 44962306a36Sopenharmony_ci .cra_alignmask = 0, 45062306a36Sopenharmony_ci .cra_module = THIS_MODULE, 45162306a36Sopenharmony_ci }, 45262306a36Sopenharmony_ci .min_keysize = 2 * AES_MIN_KEY_SIZE, 45362306a36Sopenharmony_ci .max_keysize = 2 * AES_MAX_KEY_SIZE, 45462306a36Sopenharmony_ci .ivsize = AES_BLOCK_SIZE, 45562306a36Sopenharmony_ci .setkey = nitrox_aes_xts_setkey, 45662306a36Sopenharmony_ci .encrypt = nitrox_aes_encrypt, 45762306a36Sopenharmony_ci .decrypt = nitrox_aes_decrypt, 45862306a36Sopenharmony_ci .init = nitrox_skcipher_init, 45962306a36Sopenharmony_ci .exit = nitrox_skcipher_exit, 46062306a36Sopenharmony_ci}, { 46162306a36Sopenharmony_ci .base = { 46262306a36Sopenharmony_ci .cra_name = "rfc3686(ctr(aes))", 46362306a36Sopenharmony_ci .cra_driver_name = "n5_rfc3686(ctr(aes))", 46462306a36Sopenharmony_ci .cra_priority = PRIO, 46562306a36Sopenharmony_ci .cra_flags = CRYPTO_ALG_ASYNC | CRYPTO_ALG_ALLOCATES_MEMORY, 46662306a36Sopenharmony_ci .cra_blocksize = 1, 46762306a36Sopenharmony_ci .cra_ctxsize = sizeof(struct nitrox_crypto_ctx), 46862306a36Sopenharmony_ci .cra_alignmask = 0, 46962306a36Sopenharmony_ci .cra_module = THIS_MODULE, 47062306a36Sopenharmony_ci }, 47162306a36Sopenharmony_ci .min_keysize = AES_MIN_KEY_SIZE + CTR_RFC3686_NONCE_SIZE, 47262306a36Sopenharmony_ci .max_keysize = AES_MAX_KEY_SIZE + CTR_RFC3686_NONCE_SIZE, 47362306a36Sopenharmony_ci .ivsize = CTR_RFC3686_IV_SIZE, 47462306a36Sopenharmony_ci .init = nitrox_skcipher_init, 47562306a36Sopenharmony_ci .exit = nitrox_skcipher_exit, 47662306a36Sopenharmony_ci .setkey = nitrox_aes_ctr_rfc3686_setkey, 47762306a36Sopenharmony_ci .encrypt = nitrox_aes_encrypt, 47862306a36Sopenharmony_ci .decrypt = nitrox_aes_decrypt, 47962306a36Sopenharmony_ci}, { 48062306a36Sopenharmony_ci .base = { 48162306a36Sopenharmony_ci .cra_name = "cts(cbc(aes))", 48262306a36Sopenharmony_ci .cra_driver_name = "n5_cts(cbc(aes))", 48362306a36Sopenharmony_ci .cra_priority = PRIO, 48462306a36Sopenharmony_ci .cra_flags = CRYPTO_ALG_ASYNC | CRYPTO_ALG_ALLOCATES_MEMORY, 48562306a36Sopenharmony_ci .cra_blocksize = AES_BLOCK_SIZE, 48662306a36Sopenharmony_ci .cra_ctxsize = sizeof(struct nitrox_crypto_ctx), 48762306a36Sopenharmony_ci .cra_alignmask = 0, 48862306a36Sopenharmony_ci .cra_module = THIS_MODULE, 48962306a36Sopenharmony_ci }, 49062306a36Sopenharmony_ci .min_keysize = AES_MIN_KEY_SIZE, 49162306a36Sopenharmony_ci .max_keysize = AES_MAX_KEY_SIZE, 49262306a36Sopenharmony_ci .ivsize = AES_BLOCK_SIZE, 49362306a36Sopenharmony_ci .setkey = nitrox_aes_setkey, 49462306a36Sopenharmony_ci .encrypt = nitrox_aes_encrypt, 49562306a36Sopenharmony_ci .decrypt = nitrox_aes_decrypt, 49662306a36Sopenharmony_ci .init = nitrox_skcipher_init, 49762306a36Sopenharmony_ci .exit = nitrox_skcipher_exit, 49862306a36Sopenharmony_ci}, { 49962306a36Sopenharmony_ci .base = { 50062306a36Sopenharmony_ci .cra_name = "cbc(des3_ede)", 50162306a36Sopenharmony_ci .cra_driver_name = "n5_cbc(des3_ede)", 50262306a36Sopenharmony_ci .cra_priority = PRIO, 50362306a36Sopenharmony_ci .cra_flags = CRYPTO_ALG_ASYNC | CRYPTO_ALG_ALLOCATES_MEMORY, 50462306a36Sopenharmony_ci .cra_blocksize = DES3_EDE_BLOCK_SIZE, 50562306a36Sopenharmony_ci .cra_ctxsize = sizeof(struct nitrox_crypto_ctx), 50662306a36Sopenharmony_ci .cra_alignmask = 0, 50762306a36Sopenharmony_ci .cra_module = THIS_MODULE, 50862306a36Sopenharmony_ci }, 50962306a36Sopenharmony_ci .min_keysize = DES3_EDE_KEY_SIZE, 51062306a36Sopenharmony_ci .max_keysize = DES3_EDE_KEY_SIZE, 51162306a36Sopenharmony_ci .ivsize = DES3_EDE_BLOCK_SIZE, 51262306a36Sopenharmony_ci .setkey = nitrox_3des_setkey, 51362306a36Sopenharmony_ci .encrypt = nitrox_3des_encrypt, 51462306a36Sopenharmony_ci .decrypt = nitrox_cbc_decrypt, 51562306a36Sopenharmony_ci .init = nitrox_cbc_init, 51662306a36Sopenharmony_ci .exit = nitrox_skcipher_exit, 51762306a36Sopenharmony_ci}, { 51862306a36Sopenharmony_ci .base = { 51962306a36Sopenharmony_ci .cra_name = "ecb(des3_ede)", 52062306a36Sopenharmony_ci .cra_driver_name = "n5_ecb(des3_ede)", 52162306a36Sopenharmony_ci .cra_priority = PRIO, 52262306a36Sopenharmony_ci .cra_flags = CRYPTO_ALG_ASYNC | CRYPTO_ALG_ALLOCATES_MEMORY, 52362306a36Sopenharmony_ci .cra_blocksize = DES3_EDE_BLOCK_SIZE, 52462306a36Sopenharmony_ci .cra_ctxsize = sizeof(struct nitrox_crypto_ctx), 52562306a36Sopenharmony_ci .cra_alignmask = 0, 52662306a36Sopenharmony_ci .cra_module = THIS_MODULE, 52762306a36Sopenharmony_ci }, 52862306a36Sopenharmony_ci .min_keysize = DES3_EDE_KEY_SIZE, 52962306a36Sopenharmony_ci .max_keysize = DES3_EDE_KEY_SIZE, 53062306a36Sopenharmony_ci .ivsize = DES3_EDE_BLOCK_SIZE, 53162306a36Sopenharmony_ci .setkey = nitrox_3des_setkey, 53262306a36Sopenharmony_ci .encrypt = nitrox_3des_encrypt, 53362306a36Sopenharmony_ci .decrypt = nitrox_3des_decrypt, 53462306a36Sopenharmony_ci .init = nitrox_skcipher_init, 53562306a36Sopenharmony_ci .exit = nitrox_skcipher_exit, 53662306a36Sopenharmony_ci} 53762306a36Sopenharmony_ci 53862306a36Sopenharmony_ci}; 53962306a36Sopenharmony_ci 54062306a36Sopenharmony_ciint nitrox_register_skciphers(void) 54162306a36Sopenharmony_ci{ 54262306a36Sopenharmony_ci return crypto_register_skciphers(nitrox_skciphers, 54362306a36Sopenharmony_ci ARRAY_SIZE(nitrox_skciphers)); 54462306a36Sopenharmony_ci} 54562306a36Sopenharmony_ci 54662306a36Sopenharmony_civoid nitrox_unregister_skciphers(void) 54762306a36Sopenharmony_ci{ 54862306a36Sopenharmony_ci crypto_unregister_skciphers(nitrox_skciphers, 54962306a36Sopenharmony_ci ARRAY_SIZE(nitrox_skciphers)); 55062306a36Sopenharmony_ci} 551