1c9613335SNagadheeraj Rottela // SPDX-License-Identifier: GPL-2.0 2c9613335SNagadheeraj Rottela #include <linux/crypto.h> 3c9613335SNagadheeraj Rottela #include <linux/kernel.h> 4c9613335SNagadheeraj Rottela #include <linux/module.h> 5c9613335SNagadheeraj Rottela #include <linux/printk.h> 6c9613335SNagadheeraj Rottela 7c9613335SNagadheeraj Rottela #include <crypto/aes.h> 8c9613335SNagadheeraj Rottela #include <crypto/skcipher.h> 9ced0a170SNagadheeraj Rottela #include <crypto/scatterwalk.h> 10c9613335SNagadheeraj Rottela #include <crypto/ctr.h> 1143d81a8bSArd Biesheuvel #include <crypto/internal/des.h> 12c9613335SNagadheeraj Rottela #include <crypto/xts.h> 13c9613335SNagadheeraj Rottela 14c9613335SNagadheeraj Rottela #include "nitrox_dev.h" 15c9613335SNagadheeraj Rottela #include "nitrox_common.h" 16c9613335SNagadheeraj Rottela #include "nitrox_req.h" 17c9613335SNagadheeraj Rottela 18c9613335SNagadheeraj Rottela struct nitrox_cipher { 19c9613335SNagadheeraj Rottela const char *name; 20c9613335SNagadheeraj Rottela enum flexi_cipher value; 21c9613335SNagadheeraj Rottela }; 22c9613335SNagadheeraj Rottela 23c4d7d318SLee Jones /* 24c9613335SNagadheeraj Rottela * supported cipher list 25c9613335SNagadheeraj Rottela */ 26c9613335SNagadheeraj Rottela static const struct nitrox_cipher flexi_cipher_table[] = { 27c9613335SNagadheeraj Rottela { "null", CIPHER_NULL }, 28c9613335SNagadheeraj Rottela { "cbc(des3_ede)", CIPHER_3DES_CBC }, 29c9613335SNagadheeraj Rottela { "ecb(des3_ede)", CIPHER_3DES_ECB }, 30c9613335SNagadheeraj Rottela { "cbc(aes)", CIPHER_AES_CBC }, 31c9613335SNagadheeraj Rottela { "ecb(aes)", CIPHER_AES_ECB }, 32c9613335SNagadheeraj Rottela { "cfb(aes)", CIPHER_AES_CFB }, 33c9613335SNagadheeraj Rottela { "rfc3686(ctr(aes))", CIPHER_AES_CTR }, 34c9613335SNagadheeraj Rottela { "xts(aes)", CIPHER_AES_XTS }, 35c9613335SNagadheeraj Rottela { "cts(cbc(aes))", CIPHER_AES_CBC_CTS }, 36c9613335SNagadheeraj Rottela { NULL, CIPHER_INVALID } 37c9613335SNagadheeraj Rottela }; 38c9613335SNagadheeraj Rottela 39c9613335SNagadheeraj Rottela static enum flexi_cipher flexi_cipher_type(const char *name) 40c9613335SNagadheeraj Rottela { 41c9613335SNagadheeraj Rottela const struct nitrox_cipher *cipher = flexi_cipher_table; 42c9613335SNagadheeraj Rottela 43c9613335SNagadheeraj Rottela while (cipher->name) { 44c9613335SNagadheeraj Rottela if (!strcmp(cipher->name, name)) 45c9613335SNagadheeraj Rottela break; 46c9613335SNagadheeraj Rottela cipher++; 47c9613335SNagadheeraj Rottela } 48c9613335SNagadheeraj Rottela return cipher->value; 49c9613335SNagadheeraj Rottela } 50c9613335SNagadheeraj Rottela 51ced0a170SNagadheeraj Rottela static void free_src_sglist(struct skcipher_request *skreq) 52ced0a170SNagadheeraj Rottela { 53ced0a170SNagadheeraj Rottela struct nitrox_kcrypt_request *nkreq = skcipher_request_ctx(skreq); 54ced0a170SNagadheeraj Rottela 55ced0a170SNagadheeraj Rottela kfree(nkreq->src); 56ced0a170SNagadheeraj Rottela } 57ced0a170SNagadheeraj Rottela 58ced0a170SNagadheeraj Rottela static void free_dst_sglist(struct skcipher_request *skreq) 59ced0a170SNagadheeraj Rottela { 60ced0a170SNagadheeraj Rottela struct nitrox_kcrypt_request *nkreq = skcipher_request_ctx(skreq); 61ced0a170SNagadheeraj Rottela 62ced0a170SNagadheeraj Rottela kfree(nkreq->dst); 63ced0a170SNagadheeraj Rottela } 64ced0a170SNagadheeraj Rottela 65ced0a170SNagadheeraj Rottela static void nitrox_skcipher_callback(void *arg, int err) 66ced0a170SNagadheeraj Rottela { 67ced0a170SNagadheeraj Rottela struct skcipher_request *skreq = arg; 68ced0a170SNagadheeraj Rottela 69ced0a170SNagadheeraj Rottela free_src_sglist(skreq); 70ced0a170SNagadheeraj Rottela free_dst_sglist(skreq); 71ced0a170SNagadheeraj Rottela if (err) { 72ced0a170SNagadheeraj Rottela pr_err_ratelimited("request failed status 0x%0x\n", err); 73ced0a170SNagadheeraj Rottela err = -EINVAL; 74ced0a170SNagadheeraj Rottela } 75ced0a170SNagadheeraj Rottela 76ced0a170SNagadheeraj Rottela skcipher_request_complete(skreq, err); 77ced0a170SNagadheeraj Rottela } 78ced0a170SNagadheeraj Rottela 79ced0a170SNagadheeraj Rottela static void nitrox_cbc_cipher_callback(void *arg, int err) 80ced0a170SNagadheeraj Rottela { 81ced0a170SNagadheeraj Rottela struct skcipher_request *skreq = arg; 82ced0a170SNagadheeraj Rottela struct nitrox_kcrypt_request *nkreq = skcipher_request_ctx(skreq); 83ced0a170SNagadheeraj Rottela struct crypto_skcipher *cipher = crypto_skcipher_reqtfm(skreq); 84ced0a170SNagadheeraj Rottela int ivsize = crypto_skcipher_ivsize(cipher); 85ced0a170SNagadheeraj Rottela unsigned int start = skreq->cryptlen - ivsize; 86ced0a170SNagadheeraj Rottela 87ced0a170SNagadheeraj Rottela if (err) { 88ced0a170SNagadheeraj Rottela nitrox_skcipher_callback(arg, err); 89ced0a170SNagadheeraj Rottela return; 90ced0a170SNagadheeraj Rottela } 91ced0a170SNagadheeraj Rottela 92ced0a170SNagadheeraj Rottela if (nkreq->creq.ctrl.s.arg == ENCRYPT) { 93ced0a170SNagadheeraj Rottela scatterwalk_map_and_copy(skreq->iv, skreq->dst, start, ivsize, 94ced0a170SNagadheeraj Rottela 0); 95ced0a170SNagadheeraj Rottela } else { 96ced0a170SNagadheeraj Rottela if (skreq->src != skreq->dst) { 97ced0a170SNagadheeraj Rottela scatterwalk_map_and_copy(skreq->iv, skreq->src, start, 98ced0a170SNagadheeraj Rottela ivsize, 0); 99ced0a170SNagadheeraj Rottela } else { 100ced0a170SNagadheeraj Rottela memcpy(skreq->iv, nkreq->iv_out, ivsize); 101ced0a170SNagadheeraj Rottela kfree(nkreq->iv_out); 102ced0a170SNagadheeraj Rottela } 103ced0a170SNagadheeraj Rottela } 104ced0a170SNagadheeraj Rottela 105ced0a170SNagadheeraj Rottela nitrox_skcipher_callback(arg, err); 106ced0a170SNagadheeraj Rottela } 107ced0a170SNagadheeraj Rottela 108c9613335SNagadheeraj Rottela static int nitrox_skcipher_init(struct crypto_skcipher *tfm) 109c9613335SNagadheeraj Rottela { 110c9613335SNagadheeraj Rottela struct nitrox_crypto_ctx *nctx = crypto_skcipher_ctx(tfm); 111c9613335SNagadheeraj Rottela struct crypto_ctx_hdr *chdr; 112c9613335SNagadheeraj Rottela 113c9613335SNagadheeraj Rottela /* get the first device */ 114c9613335SNagadheeraj Rottela nctx->ndev = nitrox_get_first_device(); 115c9613335SNagadheeraj Rottela if (!nctx->ndev) 116c9613335SNagadheeraj Rottela return -ENODEV; 117c9613335SNagadheeraj Rottela 118c9613335SNagadheeraj Rottela /* allocate nitrox crypto context */ 119c9613335SNagadheeraj Rottela chdr = crypto_alloc_context(nctx->ndev); 120c9613335SNagadheeraj Rottela if (!chdr) { 121c9613335SNagadheeraj Rottela nitrox_put_device(nctx->ndev); 122c9613335SNagadheeraj Rottela return -ENOMEM; 123c9613335SNagadheeraj Rottela } 124ced0a170SNagadheeraj Rottela 125ced0a170SNagadheeraj Rottela nctx->callback = nitrox_skcipher_callback; 126c9613335SNagadheeraj Rottela nctx->chdr = chdr; 127c9613335SNagadheeraj Rottela nctx->u.ctx_handle = (uintptr_t)((u8 *)chdr->vaddr + 128c9613335SNagadheeraj Rottela sizeof(struct ctx_hdr)); 129c9613335SNagadheeraj Rottela crypto_skcipher_set_reqsize(tfm, crypto_skcipher_reqsize(tfm) + 130c9613335SNagadheeraj Rottela sizeof(struct nitrox_kcrypt_request)); 131c9613335SNagadheeraj Rottela return 0; 132c9613335SNagadheeraj Rottela } 133c9613335SNagadheeraj Rottela 134ced0a170SNagadheeraj Rottela static int nitrox_cbc_init(struct crypto_skcipher *tfm) 135ced0a170SNagadheeraj Rottela { 136ced0a170SNagadheeraj Rottela int err; 137ced0a170SNagadheeraj Rottela struct nitrox_crypto_ctx *nctx = crypto_skcipher_ctx(tfm); 138ced0a170SNagadheeraj Rottela 139ced0a170SNagadheeraj Rottela err = nitrox_skcipher_init(tfm); 140ced0a170SNagadheeraj Rottela if (err) 141ced0a170SNagadheeraj Rottela return err; 142ced0a170SNagadheeraj Rottela 143ced0a170SNagadheeraj Rottela nctx->callback = nitrox_cbc_cipher_callback; 144ced0a170SNagadheeraj Rottela return 0; 145ced0a170SNagadheeraj Rottela } 146ced0a170SNagadheeraj Rottela 147c9613335SNagadheeraj Rottela static void nitrox_skcipher_exit(struct crypto_skcipher *tfm) 148c9613335SNagadheeraj Rottela { 149c9613335SNagadheeraj Rottela struct nitrox_crypto_ctx *nctx = crypto_skcipher_ctx(tfm); 150c9613335SNagadheeraj Rottela 151c9613335SNagadheeraj Rottela /* free the nitrox crypto context */ 152c9613335SNagadheeraj Rottela if (nctx->u.ctx_handle) { 153c9613335SNagadheeraj Rottela struct flexi_crypto_context *fctx = nctx->u.fctx; 154c9613335SNagadheeraj Rottela 155c9613335SNagadheeraj Rottela memzero_explicit(&fctx->crypto, sizeof(struct crypto_keys)); 156c9613335SNagadheeraj Rottela memzero_explicit(&fctx->auth, sizeof(struct auth_keys)); 157c9613335SNagadheeraj Rottela crypto_free_context((void *)nctx->chdr); 158c9613335SNagadheeraj Rottela } 159c9613335SNagadheeraj Rottela nitrox_put_device(nctx->ndev); 160c9613335SNagadheeraj Rottela 161c9613335SNagadheeraj Rottela nctx->u.ctx_handle = 0; 162c9613335SNagadheeraj Rottela nctx->ndev = NULL; 163c9613335SNagadheeraj Rottela } 164c9613335SNagadheeraj Rottela 165c9613335SNagadheeraj Rottela static inline int nitrox_skcipher_setkey(struct crypto_skcipher *cipher, 166c9613335SNagadheeraj Rottela int aes_keylen, const u8 *key, 167c9613335SNagadheeraj Rottela unsigned int keylen) 168c9613335SNagadheeraj Rottela { 169c9613335SNagadheeraj Rottela struct crypto_tfm *tfm = crypto_skcipher_tfm(cipher); 170c9613335SNagadheeraj Rottela struct nitrox_crypto_ctx *nctx = crypto_tfm_ctx(tfm); 171c9613335SNagadheeraj Rottela struct flexi_crypto_context *fctx; 172c9613335SNagadheeraj Rottela union fc_ctx_flags *flags; 173c9613335SNagadheeraj Rottela enum flexi_cipher cipher_type; 174c9613335SNagadheeraj Rottela const char *name; 175c9613335SNagadheeraj Rottela 176c9613335SNagadheeraj Rottela name = crypto_tfm_alg_name(tfm); 177c9613335SNagadheeraj Rottela cipher_type = flexi_cipher_type(name); 178c9613335SNagadheeraj Rottela if (unlikely(cipher_type == CIPHER_INVALID)) { 179c9613335SNagadheeraj Rottela pr_err("unsupported cipher: %s\n", name); 180c9613335SNagadheeraj Rottela return -EINVAL; 181c9613335SNagadheeraj Rottela } 182c9613335SNagadheeraj Rottela 183c9613335SNagadheeraj Rottela /* fill crypto context */ 184c9613335SNagadheeraj Rottela fctx = nctx->u.fctx; 185c9613335SNagadheeraj Rottela flags = &fctx->flags; 186c9613335SNagadheeraj Rottela flags->f = 0; 187c9613335SNagadheeraj Rottela flags->w0.cipher_type = cipher_type; 188c9613335SNagadheeraj Rottela flags->w0.aes_keylen = aes_keylen; 189c9613335SNagadheeraj Rottela flags->w0.iv_source = IV_FROM_DPTR; 190c9613335SNagadheeraj Rottela flags->f = cpu_to_be64(*(u64 *)&flags->w0); 191c9613335SNagadheeraj Rottela /* copy the key to context */ 192c9613335SNagadheeraj Rottela memcpy(fctx->crypto.u.key, key, keylen); 193c9613335SNagadheeraj Rottela 194c9613335SNagadheeraj Rottela return 0; 195c9613335SNagadheeraj Rottela } 196c9613335SNagadheeraj Rottela 197c9613335SNagadheeraj Rottela static int nitrox_aes_setkey(struct crypto_skcipher *cipher, const u8 *key, 198c9613335SNagadheeraj Rottela unsigned int keylen) 199c9613335SNagadheeraj Rottela { 200c9613335SNagadheeraj Rottela int aes_keylen; 201c9613335SNagadheeraj Rottela 202c9613335SNagadheeraj Rottela aes_keylen = flexi_aes_keylen(keylen); 203674f368aSEric Biggers if (aes_keylen < 0) 204c9613335SNagadheeraj Rottela return -EINVAL; 205c9613335SNagadheeraj Rottela return nitrox_skcipher_setkey(cipher, aes_keylen, key, keylen); 206c9613335SNagadheeraj Rottela } 207c9613335SNagadheeraj Rottela 208c9613335SNagadheeraj Rottela static int alloc_src_sglist(struct skcipher_request *skreq, int ivsize) 209c9613335SNagadheeraj Rottela { 210c9613335SNagadheeraj Rottela struct nitrox_kcrypt_request *nkreq = skcipher_request_ctx(skreq); 211c9613335SNagadheeraj Rottela int nents = sg_nents(skreq->src) + 1; 212c9613335SNagadheeraj Rottela int ret; 213c9613335SNagadheeraj Rottela 214c9613335SNagadheeraj Rottela /* Allocate buffer to hold IV and input scatterlist array */ 215c9613335SNagadheeraj Rottela ret = alloc_src_req_buf(nkreq, nents, ivsize); 216c9613335SNagadheeraj Rottela if (ret) 217c9613335SNagadheeraj Rottela return ret; 218c9613335SNagadheeraj Rottela 219c9613335SNagadheeraj Rottela nitrox_creq_copy_iv(nkreq->src, skreq->iv, ivsize); 220c9613335SNagadheeraj Rottela nitrox_creq_set_src_sg(nkreq, nents, ivsize, skreq->src, 221c9613335SNagadheeraj Rottela skreq->cryptlen); 222c9613335SNagadheeraj Rottela 223c9613335SNagadheeraj Rottela return 0; 224c9613335SNagadheeraj Rottela } 225c9613335SNagadheeraj Rottela 226c9613335SNagadheeraj Rottela static int alloc_dst_sglist(struct skcipher_request *skreq, int ivsize) 227c9613335SNagadheeraj Rottela { 228c9613335SNagadheeraj Rottela struct nitrox_kcrypt_request *nkreq = skcipher_request_ctx(skreq); 229c9613335SNagadheeraj Rottela int nents = sg_nents(skreq->dst) + 3; 230c9613335SNagadheeraj Rottela int ret; 231c9613335SNagadheeraj Rottela 232c9613335SNagadheeraj Rottela /* Allocate buffer to hold ORH, COMPLETION and output scatterlist 233c9613335SNagadheeraj Rottela * array 234c9613335SNagadheeraj Rottela */ 235c9613335SNagadheeraj Rottela ret = alloc_dst_req_buf(nkreq, nents); 236c9613335SNagadheeraj Rottela if (ret) 237c9613335SNagadheeraj Rottela return ret; 238c9613335SNagadheeraj Rottela 239c9613335SNagadheeraj Rottela nitrox_creq_set_orh(nkreq); 240c9613335SNagadheeraj Rottela nitrox_creq_set_comp(nkreq); 241c9613335SNagadheeraj Rottela nitrox_creq_set_dst_sg(nkreq, nents, ivsize, skreq->dst, 242c9613335SNagadheeraj Rottela skreq->cryptlen); 243c9613335SNagadheeraj Rottela 244c9613335SNagadheeraj Rottela return 0; 245c9613335SNagadheeraj Rottela } 246c9613335SNagadheeraj Rottela 247c9613335SNagadheeraj Rottela static int nitrox_skcipher_crypt(struct skcipher_request *skreq, bool enc) 248c9613335SNagadheeraj Rottela { 249c9613335SNagadheeraj Rottela struct crypto_skcipher *cipher = crypto_skcipher_reqtfm(skreq); 250c9613335SNagadheeraj Rottela struct nitrox_crypto_ctx *nctx = crypto_skcipher_ctx(cipher); 251c9613335SNagadheeraj Rottela struct nitrox_kcrypt_request *nkreq = skcipher_request_ctx(skreq); 252c9613335SNagadheeraj Rottela int ivsize = crypto_skcipher_ivsize(cipher); 253c9613335SNagadheeraj Rottela struct se_crypto_request *creq; 254c9613335SNagadheeraj Rottela int ret; 255c9613335SNagadheeraj Rottela 256c9613335SNagadheeraj Rottela creq = &nkreq->creq; 257c9613335SNagadheeraj Rottela creq->flags = skreq->base.flags; 258c9613335SNagadheeraj Rottela creq->gfp = (skreq->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP) ? 259c9613335SNagadheeraj Rottela GFP_KERNEL : GFP_ATOMIC; 260c9613335SNagadheeraj Rottela 261c9613335SNagadheeraj Rottela /* fill the request */ 262c9613335SNagadheeraj Rottela creq->ctrl.value = 0; 263c9613335SNagadheeraj Rottela creq->opcode = FLEXI_CRYPTO_ENCRYPT_HMAC; 264c9613335SNagadheeraj Rottela creq->ctrl.s.arg = (enc ? ENCRYPT : DECRYPT); 265c9613335SNagadheeraj Rottela /* param0: length of the data to be encrypted */ 266c9613335SNagadheeraj Rottela creq->gph.param0 = cpu_to_be16(skreq->cryptlen); 267c9613335SNagadheeraj Rottela creq->gph.param1 = 0; 268c9613335SNagadheeraj Rottela /* param2: encryption data offset */ 269c9613335SNagadheeraj Rottela creq->gph.param2 = cpu_to_be16(ivsize); 270c9613335SNagadheeraj Rottela creq->gph.param3 = 0; 271c9613335SNagadheeraj Rottela 272c9613335SNagadheeraj Rottela creq->ctx_handle = nctx->u.ctx_handle; 273c9613335SNagadheeraj Rottela creq->ctrl.s.ctxl = sizeof(struct flexi_crypto_context); 274c9613335SNagadheeraj Rottela 275c9613335SNagadheeraj Rottela ret = alloc_src_sglist(skreq, ivsize); 276c9613335SNagadheeraj Rottela if (ret) 277c9613335SNagadheeraj Rottela return ret; 278c9613335SNagadheeraj Rottela 279c9613335SNagadheeraj Rottela ret = alloc_dst_sglist(skreq, ivsize); 280c9613335SNagadheeraj Rottela if (ret) { 281c9613335SNagadheeraj Rottela free_src_sglist(skreq); 282c9613335SNagadheeraj Rottela return ret; 283c9613335SNagadheeraj Rottela } 284c9613335SNagadheeraj Rottela 285c9613335SNagadheeraj Rottela /* send the crypto request */ 286ced0a170SNagadheeraj Rottela return nitrox_process_se_request(nctx->ndev, creq, nctx->callback, 287ced0a170SNagadheeraj Rottela skreq); 288ced0a170SNagadheeraj Rottela } 289ced0a170SNagadheeraj Rottela 290ced0a170SNagadheeraj Rottela static int nitrox_cbc_decrypt(struct skcipher_request *skreq) 291ced0a170SNagadheeraj Rottela { 292ced0a170SNagadheeraj Rottela struct nitrox_kcrypt_request *nkreq = skcipher_request_ctx(skreq); 293ced0a170SNagadheeraj Rottela struct crypto_skcipher *cipher = crypto_skcipher_reqtfm(skreq); 294ced0a170SNagadheeraj Rottela int ivsize = crypto_skcipher_ivsize(cipher); 295ced0a170SNagadheeraj Rottela gfp_t flags = (skreq->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP) ? 296ced0a170SNagadheeraj Rottela GFP_KERNEL : GFP_ATOMIC; 297ced0a170SNagadheeraj Rottela unsigned int start = skreq->cryptlen - ivsize; 298ced0a170SNagadheeraj Rottela 299ced0a170SNagadheeraj Rottela if (skreq->src != skreq->dst) 300ced0a170SNagadheeraj Rottela return nitrox_skcipher_crypt(skreq, false); 301ced0a170SNagadheeraj Rottela 302ced0a170SNagadheeraj Rottela nkreq->iv_out = kmalloc(ivsize, flags); 303ced0a170SNagadheeraj Rottela if (!nkreq->iv_out) 304ced0a170SNagadheeraj Rottela return -ENOMEM; 305ced0a170SNagadheeraj Rottela 306ced0a170SNagadheeraj Rottela scatterwalk_map_and_copy(nkreq->iv_out, skreq->src, start, ivsize, 0); 307ced0a170SNagadheeraj Rottela return nitrox_skcipher_crypt(skreq, false); 308c9613335SNagadheeraj Rottela } 309c9613335SNagadheeraj Rottela 310c9613335SNagadheeraj Rottela static int nitrox_aes_encrypt(struct skcipher_request *skreq) 311c9613335SNagadheeraj Rottela { 312c9613335SNagadheeraj Rottela return nitrox_skcipher_crypt(skreq, true); 313c9613335SNagadheeraj Rottela } 314c9613335SNagadheeraj Rottela 315c9613335SNagadheeraj Rottela static int nitrox_aes_decrypt(struct skcipher_request *skreq) 316c9613335SNagadheeraj Rottela { 317c9613335SNagadheeraj Rottela return nitrox_skcipher_crypt(skreq, false); 318c9613335SNagadheeraj Rottela } 319c9613335SNagadheeraj Rottela 320c9613335SNagadheeraj Rottela static int nitrox_3des_setkey(struct crypto_skcipher *cipher, 321c9613335SNagadheeraj Rottela const u8 *key, unsigned int keylen) 322c9613335SNagadheeraj Rottela { 32343d81a8bSArd Biesheuvel return verify_skcipher_des3_key(cipher, key) ?: 32419291691SHerbert Xu nitrox_skcipher_setkey(cipher, 0, key, keylen); 325c9613335SNagadheeraj Rottela } 326c9613335SNagadheeraj Rottela 327c9613335SNagadheeraj Rottela static int nitrox_3des_encrypt(struct skcipher_request *skreq) 328c9613335SNagadheeraj Rottela { 329c9613335SNagadheeraj Rottela return nitrox_skcipher_crypt(skreq, true); 330c9613335SNagadheeraj Rottela } 331c9613335SNagadheeraj Rottela 332c9613335SNagadheeraj Rottela static int nitrox_3des_decrypt(struct skcipher_request *skreq) 333c9613335SNagadheeraj Rottela { 334c9613335SNagadheeraj Rottela return nitrox_skcipher_crypt(skreq, false); 335c9613335SNagadheeraj Rottela } 336c9613335SNagadheeraj Rottela 337c9613335SNagadheeraj Rottela static int nitrox_aes_xts_setkey(struct crypto_skcipher *cipher, 338c9613335SNagadheeraj Rottela const u8 *key, unsigned int keylen) 339c9613335SNagadheeraj Rottela { 340*0ee43367SVladis Dronov struct nitrox_crypto_ctx *nctx = crypto_skcipher_ctx(cipher); 341c9613335SNagadheeraj Rottela struct flexi_crypto_context *fctx; 342c9613335SNagadheeraj Rottela int aes_keylen, ret; 343c9613335SNagadheeraj Rottela 344*0ee43367SVladis Dronov ret = xts_verify_key(cipher, key, keylen); 345c9613335SNagadheeraj Rottela if (ret) 346c9613335SNagadheeraj Rottela return ret; 347c9613335SNagadheeraj Rottela 348c9613335SNagadheeraj Rottela keylen /= 2; 349c9613335SNagadheeraj Rottela 350c9613335SNagadheeraj Rottela aes_keylen = flexi_aes_keylen(keylen); 351674f368aSEric Biggers if (aes_keylen < 0) 352c9613335SNagadheeraj Rottela return -EINVAL; 353c9613335SNagadheeraj Rottela 354c9613335SNagadheeraj Rottela fctx = nctx->u.fctx; 355c9613335SNagadheeraj Rottela /* copy KEY2 */ 356c9613335SNagadheeraj Rottela memcpy(fctx->auth.u.key2, (key + keylen), keylen); 357c9613335SNagadheeraj Rottela 358c9613335SNagadheeraj Rottela return nitrox_skcipher_setkey(cipher, aes_keylen, key, keylen); 359c9613335SNagadheeraj Rottela } 360c9613335SNagadheeraj Rottela 361c9613335SNagadheeraj Rottela static int nitrox_aes_ctr_rfc3686_setkey(struct crypto_skcipher *cipher, 362c9613335SNagadheeraj Rottela const u8 *key, unsigned int keylen) 363c9613335SNagadheeraj Rottela { 364*0ee43367SVladis Dronov struct nitrox_crypto_ctx *nctx = crypto_skcipher_ctx(cipher); 365c9613335SNagadheeraj Rottela struct flexi_crypto_context *fctx; 366c9613335SNagadheeraj Rottela int aes_keylen; 367c9613335SNagadheeraj Rottela 368c9613335SNagadheeraj Rottela if (keylen < CTR_RFC3686_NONCE_SIZE) 369c9613335SNagadheeraj Rottela return -EINVAL; 370c9613335SNagadheeraj Rottela 371c9613335SNagadheeraj Rottela fctx = nctx->u.fctx; 372c9613335SNagadheeraj Rottela 373c9613335SNagadheeraj Rottela memcpy(fctx->crypto.iv, key + (keylen - CTR_RFC3686_NONCE_SIZE), 374c9613335SNagadheeraj Rottela CTR_RFC3686_NONCE_SIZE); 375c9613335SNagadheeraj Rottela 376c9613335SNagadheeraj Rottela keylen -= CTR_RFC3686_NONCE_SIZE; 377c9613335SNagadheeraj Rottela 378c9613335SNagadheeraj Rottela aes_keylen = flexi_aes_keylen(keylen); 379674f368aSEric Biggers if (aes_keylen < 0) 380c9613335SNagadheeraj Rottela return -EINVAL; 381c9613335SNagadheeraj Rottela return nitrox_skcipher_setkey(cipher, aes_keylen, key, keylen); 382c9613335SNagadheeraj Rottela } 383c9613335SNagadheeraj Rottela 384c9613335SNagadheeraj Rottela static struct skcipher_alg nitrox_skciphers[] = { { 385c9613335SNagadheeraj Rottela .base = { 386c9613335SNagadheeraj Rottela .cra_name = "cbc(aes)", 387c9613335SNagadheeraj Rottela .cra_driver_name = "n5_cbc(aes)", 388c9613335SNagadheeraj Rottela .cra_priority = PRIO, 389b8aa7dc5SMikulas Patocka .cra_flags = CRYPTO_ALG_ASYNC | CRYPTO_ALG_ALLOCATES_MEMORY, 390c9613335SNagadheeraj Rottela .cra_blocksize = AES_BLOCK_SIZE, 391c9613335SNagadheeraj Rottela .cra_ctxsize = sizeof(struct nitrox_crypto_ctx), 392c9613335SNagadheeraj Rottela .cra_alignmask = 0, 393c9613335SNagadheeraj Rottela .cra_module = THIS_MODULE, 394c9613335SNagadheeraj Rottela }, 395c9613335SNagadheeraj Rottela .min_keysize = AES_MIN_KEY_SIZE, 396c9613335SNagadheeraj Rottela .max_keysize = AES_MAX_KEY_SIZE, 397c9613335SNagadheeraj Rottela .ivsize = AES_BLOCK_SIZE, 398c9613335SNagadheeraj Rottela .setkey = nitrox_aes_setkey, 399c9613335SNagadheeraj Rottela .encrypt = nitrox_aes_encrypt, 400ced0a170SNagadheeraj Rottela .decrypt = nitrox_cbc_decrypt, 401ced0a170SNagadheeraj Rottela .init = nitrox_cbc_init, 402c9613335SNagadheeraj Rottela .exit = nitrox_skcipher_exit, 403c9613335SNagadheeraj Rottela }, { 404c9613335SNagadheeraj Rottela .base = { 405c9613335SNagadheeraj Rottela .cra_name = "ecb(aes)", 406c9613335SNagadheeraj Rottela .cra_driver_name = "n5_ecb(aes)", 407c9613335SNagadheeraj Rottela .cra_priority = PRIO, 408b8aa7dc5SMikulas Patocka .cra_flags = CRYPTO_ALG_ASYNC | CRYPTO_ALG_ALLOCATES_MEMORY, 409c9613335SNagadheeraj Rottela .cra_blocksize = AES_BLOCK_SIZE, 410c9613335SNagadheeraj Rottela .cra_ctxsize = sizeof(struct nitrox_crypto_ctx), 411c9613335SNagadheeraj Rottela .cra_alignmask = 0, 412c9613335SNagadheeraj Rottela .cra_module = THIS_MODULE, 413c9613335SNagadheeraj Rottela }, 414c9613335SNagadheeraj Rottela .min_keysize = AES_MIN_KEY_SIZE, 415c9613335SNagadheeraj Rottela .max_keysize = AES_MAX_KEY_SIZE, 416c9613335SNagadheeraj Rottela .ivsize = AES_BLOCK_SIZE, 417c9613335SNagadheeraj Rottela .setkey = nitrox_aes_setkey, 418c9613335SNagadheeraj Rottela .encrypt = nitrox_aes_encrypt, 419c9613335SNagadheeraj Rottela .decrypt = nitrox_aes_decrypt, 420c9613335SNagadheeraj Rottela .init = nitrox_skcipher_init, 421c9613335SNagadheeraj Rottela .exit = nitrox_skcipher_exit, 422c9613335SNagadheeraj Rottela }, { 423c9613335SNagadheeraj Rottela .base = { 424c9613335SNagadheeraj Rottela .cra_name = "cfb(aes)", 425c9613335SNagadheeraj Rottela .cra_driver_name = "n5_cfb(aes)", 426c9613335SNagadheeraj Rottela .cra_priority = PRIO, 427b8aa7dc5SMikulas Patocka .cra_flags = CRYPTO_ALG_ASYNC | CRYPTO_ALG_ALLOCATES_MEMORY, 428c9613335SNagadheeraj Rottela .cra_blocksize = AES_BLOCK_SIZE, 429c9613335SNagadheeraj Rottela .cra_ctxsize = sizeof(struct nitrox_crypto_ctx), 430c9613335SNagadheeraj Rottela .cra_alignmask = 0, 431c9613335SNagadheeraj Rottela .cra_module = THIS_MODULE, 432c9613335SNagadheeraj Rottela }, 433c9613335SNagadheeraj Rottela .min_keysize = AES_MIN_KEY_SIZE, 434c9613335SNagadheeraj Rottela .max_keysize = AES_MAX_KEY_SIZE, 435c9613335SNagadheeraj Rottela .ivsize = AES_BLOCK_SIZE, 436c9613335SNagadheeraj Rottela .setkey = nitrox_aes_setkey, 437c9613335SNagadheeraj Rottela .encrypt = nitrox_aes_encrypt, 438c9613335SNagadheeraj Rottela .decrypt = nitrox_aes_decrypt, 439c9613335SNagadheeraj Rottela .init = nitrox_skcipher_init, 440c9613335SNagadheeraj Rottela .exit = nitrox_skcipher_exit, 441c9613335SNagadheeraj Rottela }, { 442c9613335SNagadheeraj Rottela .base = { 443c9613335SNagadheeraj Rottela .cra_name = "xts(aes)", 444c9613335SNagadheeraj Rottela .cra_driver_name = "n5_xts(aes)", 445c9613335SNagadheeraj Rottela .cra_priority = PRIO, 446b8aa7dc5SMikulas Patocka .cra_flags = CRYPTO_ALG_ASYNC | CRYPTO_ALG_ALLOCATES_MEMORY, 447c9613335SNagadheeraj Rottela .cra_blocksize = AES_BLOCK_SIZE, 448c9613335SNagadheeraj Rottela .cra_ctxsize = sizeof(struct nitrox_crypto_ctx), 449c9613335SNagadheeraj Rottela .cra_alignmask = 0, 450c9613335SNagadheeraj Rottela .cra_module = THIS_MODULE, 451c9613335SNagadheeraj Rottela }, 452c9613335SNagadheeraj Rottela .min_keysize = 2 * AES_MIN_KEY_SIZE, 453c9613335SNagadheeraj Rottela .max_keysize = 2 * AES_MAX_KEY_SIZE, 454c9613335SNagadheeraj Rottela .ivsize = AES_BLOCK_SIZE, 455c9613335SNagadheeraj Rottela .setkey = nitrox_aes_xts_setkey, 456c9613335SNagadheeraj Rottela .encrypt = nitrox_aes_encrypt, 457c9613335SNagadheeraj Rottela .decrypt = nitrox_aes_decrypt, 458c9613335SNagadheeraj Rottela .init = nitrox_skcipher_init, 459c9613335SNagadheeraj Rottela .exit = nitrox_skcipher_exit, 460c9613335SNagadheeraj Rottela }, { 461c9613335SNagadheeraj Rottela .base = { 462c9613335SNagadheeraj Rottela .cra_name = "rfc3686(ctr(aes))", 463c9613335SNagadheeraj Rottela .cra_driver_name = "n5_rfc3686(ctr(aes))", 464c9613335SNagadheeraj Rottela .cra_priority = PRIO, 465b8aa7dc5SMikulas Patocka .cra_flags = CRYPTO_ALG_ASYNC | CRYPTO_ALG_ALLOCATES_MEMORY, 466c9613335SNagadheeraj Rottela .cra_blocksize = 1, 467c9613335SNagadheeraj Rottela .cra_ctxsize = sizeof(struct nitrox_crypto_ctx), 468c9613335SNagadheeraj Rottela .cra_alignmask = 0, 469c9613335SNagadheeraj Rottela .cra_module = THIS_MODULE, 470c9613335SNagadheeraj Rottela }, 471c9613335SNagadheeraj Rottela .min_keysize = AES_MIN_KEY_SIZE + CTR_RFC3686_NONCE_SIZE, 472c9613335SNagadheeraj Rottela .max_keysize = AES_MAX_KEY_SIZE + CTR_RFC3686_NONCE_SIZE, 473c9613335SNagadheeraj Rottela .ivsize = CTR_RFC3686_IV_SIZE, 474c9613335SNagadheeraj Rottela .init = nitrox_skcipher_init, 475c9613335SNagadheeraj Rottela .exit = nitrox_skcipher_exit, 476c9613335SNagadheeraj Rottela .setkey = nitrox_aes_ctr_rfc3686_setkey, 477c9613335SNagadheeraj Rottela .encrypt = nitrox_aes_encrypt, 478c9613335SNagadheeraj Rottela .decrypt = nitrox_aes_decrypt, 479c9613335SNagadheeraj Rottela }, { 480c9613335SNagadheeraj Rottela .base = { 481c9613335SNagadheeraj Rottela .cra_name = "cts(cbc(aes))", 482c9613335SNagadheeraj Rottela .cra_driver_name = "n5_cts(cbc(aes))", 483c9613335SNagadheeraj Rottela .cra_priority = PRIO, 484b8aa7dc5SMikulas Patocka .cra_flags = CRYPTO_ALG_ASYNC | CRYPTO_ALG_ALLOCATES_MEMORY, 485c9613335SNagadheeraj Rottela .cra_blocksize = AES_BLOCK_SIZE, 486c9613335SNagadheeraj Rottela .cra_ctxsize = sizeof(struct nitrox_crypto_ctx), 487c9613335SNagadheeraj Rottela .cra_alignmask = 0, 488c9613335SNagadheeraj Rottela .cra_module = THIS_MODULE, 489c9613335SNagadheeraj Rottela }, 490c9613335SNagadheeraj Rottela .min_keysize = AES_MIN_KEY_SIZE, 491c9613335SNagadheeraj Rottela .max_keysize = AES_MAX_KEY_SIZE, 492c9613335SNagadheeraj Rottela .ivsize = AES_BLOCK_SIZE, 493c9613335SNagadheeraj Rottela .setkey = nitrox_aes_setkey, 494c9613335SNagadheeraj Rottela .encrypt = nitrox_aes_encrypt, 495c9613335SNagadheeraj Rottela .decrypt = nitrox_aes_decrypt, 496c9613335SNagadheeraj Rottela .init = nitrox_skcipher_init, 497c9613335SNagadheeraj Rottela .exit = nitrox_skcipher_exit, 498c9613335SNagadheeraj Rottela }, { 499c9613335SNagadheeraj Rottela .base = { 500c9613335SNagadheeraj Rottela .cra_name = "cbc(des3_ede)", 501c9613335SNagadheeraj Rottela .cra_driver_name = "n5_cbc(des3_ede)", 502c9613335SNagadheeraj Rottela .cra_priority = PRIO, 503b8aa7dc5SMikulas Patocka .cra_flags = CRYPTO_ALG_ASYNC | CRYPTO_ALG_ALLOCATES_MEMORY, 504c9613335SNagadheeraj Rottela .cra_blocksize = DES3_EDE_BLOCK_SIZE, 505c9613335SNagadheeraj Rottela .cra_ctxsize = sizeof(struct nitrox_crypto_ctx), 506c9613335SNagadheeraj Rottela .cra_alignmask = 0, 507c9613335SNagadheeraj Rottela .cra_module = THIS_MODULE, 508c9613335SNagadheeraj Rottela }, 509c9613335SNagadheeraj Rottela .min_keysize = DES3_EDE_KEY_SIZE, 510c9613335SNagadheeraj Rottela .max_keysize = DES3_EDE_KEY_SIZE, 511c9613335SNagadheeraj Rottela .ivsize = DES3_EDE_BLOCK_SIZE, 512c9613335SNagadheeraj Rottela .setkey = nitrox_3des_setkey, 513c9613335SNagadheeraj Rottela .encrypt = nitrox_3des_encrypt, 514ced0a170SNagadheeraj Rottela .decrypt = nitrox_cbc_decrypt, 515ced0a170SNagadheeraj Rottela .init = nitrox_cbc_init, 516c9613335SNagadheeraj Rottela .exit = nitrox_skcipher_exit, 517c9613335SNagadheeraj Rottela }, { 518c9613335SNagadheeraj Rottela .base = { 519c9613335SNagadheeraj Rottela .cra_name = "ecb(des3_ede)", 520c9613335SNagadheeraj Rottela .cra_driver_name = "n5_ecb(des3_ede)", 521c9613335SNagadheeraj Rottela .cra_priority = PRIO, 522b8aa7dc5SMikulas Patocka .cra_flags = CRYPTO_ALG_ASYNC | CRYPTO_ALG_ALLOCATES_MEMORY, 523c9613335SNagadheeraj Rottela .cra_blocksize = DES3_EDE_BLOCK_SIZE, 524c9613335SNagadheeraj Rottela .cra_ctxsize = sizeof(struct nitrox_crypto_ctx), 525c9613335SNagadheeraj Rottela .cra_alignmask = 0, 526c9613335SNagadheeraj Rottela .cra_module = THIS_MODULE, 527c9613335SNagadheeraj Rottela }, 528c9613335SNagadheeraj Rottela .min_keysize = DES3_EDE_KEY_SIZE, 529c9613335SNagadheeraj Rottela .max_keysize = DES3_EDE_KEY_SIZE, 530c9613335SNagadheeraj Rottela .ivsize = DES3_EDE_BLOCK_SIZE, 531c9613335SNagadheeraj Rottela .setkey = nitrox_3des_setkey, 532c9613335SNagadheeraj Rottela .encrypt = nitrox_3des_encrypt, 533c9613335SNagadheeraj Rottela .decrypt = nitrox_3des_decrypt, 534c9613335SNagadheeraj Rottela .init = nitrox_skcipher_init, 535c9613335SNagadheeraj Rottela .exit = nitrox_skcipher_exit, 536c9613335SNagadheeraj Rottela } 537c9613335SNagadheeraj Rottela 538c9613335SNagadheeraj Rottela }; 539c9613335SNagadheeraj Rottela 540c9613335SNagadheeraj Rottela int nitrox_register_skciphers(void) 541c9613335SNagadheeraj Rottela { 542c9613335SNagadheeraj Rottela return crypto_register_skciphers(nitrox_skciphers, 543c9613335SNagadheeraj Rottela ARRAY_SIZE(nitrox_skciphers)); 544c9613335SNagadheeraj Rottela } 545c9613335SNagadheeraj Rottela 546c9613335SNagadheeraj Rottela void nitrox_unregister_skciphers(void) 547c9613335SNagadheeraj Rottela { 548c9613335SNagadheeraj Rottela crypto_unregister_skciphers(nitrox_skciphers, 549c9613335SNagadheeraj Rottela ARRAY_SIZE(nitrox_skciphers)); 550c9613335SNagadheeraj Rottela } 551