1ce0183cbSArd Biesheuvel // SPDX-License-Identifier: GPL-2.0-only 2ce0183cbSArd Biesheuvel /* 3ce0183cbSArd Biesheuvel * Crypto acceleration support for Rockchip RK3288 4ce0183cbSArd Biesheuvel * 5ce0183cbSArd Biesheuvel * Copyright (c) 2015, Fuzhou Rockchip Electronics Co., Ltd 6ce0183cbSArd Biesheuvel * 7ce0183cbSArd Biesheuvel * Author: Zain Wang <zain.wang@rock-chips.com> 8ce0183cbSArd Biesheuvel * 9ce0183cbSArd Biesheuvel * Some ideas are from marvell-cesa.c and s5p-sss.c driver. 10ce0183cbSArd Biesheuvel */ 11*0c3dc787SHerbert Xu #include <linux/device.h> 12ce0183cbSArd Biesheuvel #include "rk3288_crypto.h" 13ce0183cbSArd Biesheuvel 14ce0183cbSArd Biesheuvel #define RK_CRYPTO_DEC BIT(0) 15ce0183cbSArd Biesheuvel 16ce0183cbSArd Biesheuvel static void rk_crypto_complete(struct crypto_async_request *base, int err) 17ce0183cbSArd Biesheuvel { 18ce0183cbSArd Biesheuvel if (base->complete) 19ce0183cbSArd Biesheuvel base->complete(base, err); 20ce0183cbSArd Biesheuvel } 21ce0183cbSArd Biesheuvel 22ce0183cbSArd Biesheuvel static int rk_handle_req(struct rk_crypto_info *dev, 23ce0183cbSArd Biesheuvel struct skcipher_request *req) 24ce0183cbSArd Biesheuvel { 25ce0183cbSArd Biesheuvel if (!IS_ALIGNED(req->cryptlen, dev->align_size)) 26ce0183cbSArd Biesheuvel return -EINVAL; 27ce0183cbSArd Biesheuvel else 28ce0183cbSArd Biesheuvel return dev->enqueue(dev, &req->base); 29ce0183cbSArd Biesheuvel } 30ce0183cbSArd Biesheuvel 31ce0183cbSArd Biesheuvel static int rk_aes_setkey(struct crypto_skcipher *cipher, 32ce0183cbSArd Biesheuvel const u8 *key, unsigned int keylen) 33ce0183cbSArd Biesheuvel { 34ce0183cbSArd Biesheuvel struct crypto_tfm *tfm = crypto_skcipher_tfm(cipher); 35ce0183cbSArd Biesheuvel struct rk_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 36ce0183cbSArd Biesheuvel 37ce0183cbSArd Biesheuvel if (keylen != AES_KEYSIZE_128 && keylen != AES_KEYSIZE_192 && 38674f368aSEric Biggers keylen != AES_KEYSIZE_256) 39ce0183cbSArd Biesheuvel return -EINVAL; 40ce0183cbSArd Biesheuvel ctx->keylen = keylen; 41ce0183cbSArd Biesheuvel memcpy_toio(ctx->dev->reg + RK_CRYPTO_AES_KEY_0, key, keylen); 42ce0183cbSArd Biesheuvel return 0; 43ce0183cbSArd Biesheuvel } 44ce0183cbSArd Biesheuvel 45ce0183cbSArd Biesheuvel static int rk_des_setkey(struct crypto_skcipher *cipher, 46ce0183cbSArd Biesheuvel const u8 *key, unsigned int keylen) 47ce0183cbSArd Biesheuvel { 48ce0183cbSArd Biesheuvel struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(cipher); 49ce0183cbSArd Biesheuvel int err; 50ce0183cbSArd Biesheuvel 51ce0183cbSArd Biesheuvel err = verify_skcipher_des_key(cipher, key); 52ce0183cbSArd Biesheuvel if (err) 53ce0183cbSArd Biesheuvel return err; 54ce0183cbSArd Biesheuvel 55ce0183cbSArd Biesheuvel ctx->keylen = keylen; 56ce0183cbSArd Biesheuvel memcpy_toio(ctx->dev->reg + RK_CRYPTO_TDES_KEY1_0, key, keylen); 57ce0183cbSArd Biesheuvel return 0; 58ce0183cbSArd Biesheuvel } 59ce0183cbSArd Biesheuvel 60ce0183cbSArd Biesheuvel static int rk_tdes_setkey(struct crypto_skcipher *cipher, 61ce0183cbSArd Biesheuvel const u8 *key, unsigned int keylen) 62ce0183cbSArd Biesheuvel { 63ce0183cbSArd Biesheuvel struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(cipher); 64ce0183cbSArd Biesheuvel int err; 65ce0183cbSArd Biesheuvel 66ce0183cbSArd Biesheuvel err = verify_skcipher_des3_key(cipher, key); 67ce0183cbSArd Biesheuvel if (err) 68ce0183cbSArd Biesheuvel return err; 69ce0183cbSArd Biesheuvel 70ce0183cbSArd Biesheuvel ctx->keylen = keylen; 71ce0183cbSArd Biesheuvel memcpy_toio(ctx->dev->reg + RK_CRYPTO_TDES_KEY1_0, key, keylen); 72ce0183cbSArd Biesheuvel return 0; 73ce0183cbSArd Biesheuvel } 74ce0183cbSArd Biesheuvel 75ce0183cbSArd Biesheuvel static int rk_aes_ecb_encrypt(struct skcipher_request *req) 76ce0183cbSArd Biesheuvel { 77ce0183cbSArd Biesheuvel struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); 78ce0183cbSArd Biesheuvel struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm); 79ce0183cbSArd Biesheuvel struct rk_crypto_info *dev = ctx->dev; 80ce0183cbSArd Biesheuvel 81ce0183cbSArd Biesheuvel ctx->mode = RK_CRYPTO_AES_ECB_MODE; 82ce0183cbSArd Biesheuvel return rk_handle_req(dev, req); 83ce0183cbSArd Biesheuvel } 84ce0183cbSArd Biesheuvel 85ce0183cbSArd Biesheuvel static int rk_aes_ecb_decrypt(struct skcipher_request *req) 86ce0183cbSArd Biesheuvel { 87ce0183cbSArd Biesheuvel struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); 88ce0183cbSArd Biesheuvel struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm); 89ce0183cbSArd Biesheuvel struct rk_crypto_info *dev = ctx->dev; 90ce0183cbSArd Biesheuvel 91ce0183cbSArd Biesheuvel ctx->mode = RK_CRYPTO_AES_ECB_MODE | RK_CRYPTO_DEC; 92ce0183cbSArd Biesheuvel return rk_handle_req(dev, req); 93ce0183cbSArd Biesheuvel } 94ce0183cbSArd Biesheuvel 95ce0183cbSArd Biesheuvel static int rk_aes_cbc_encrypt(struct skcipher_request *req) 96ce0183cbSArd Biesheuvel { 97ce0183cbSArd Biesheuvel struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); 98ce0183cbSArd Biesheuvel struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm); 99ce0183cbSArd Biesheuvel struct rk_crypto_info *dev = ctx->dev; 100ce0183cbSArd Biesheuvel 101ce0183cbSArd Biesheuvel ctx->mode = RK_CRYPTO_AES_CBC_MODE; 102ce0183cbSArd Biesheuvel return rk_handle_req(dev, req); 103ce0183cbSArd Biesheuvel } 104ce0183cbSArd Biesheuvel 105ce0183cbSArd Biesheuvel static int rk_aes_cbc_decrypt(struct skcipher_request *req) 106ce0183cbSArd Biesheuvel { 107ce0183cbSArd Biesheuvel struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); 108ce0183cbSArd Biesheuvel struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm); 109ce0183cbSArd Biesheuvel struct rk_crypto_info *dev = ctx->dev; 110ce0183cbSArd Biesheuvel 111ce0183cbSArd Biesheuvel ctx->mode = RK_CRYPTO_AES_CBC_MODE | RK_CRYPTO_DEC; 112ce0183cbSArd Biesheuvel return rk_handle_req(dev, req); 113ce0183cbSArd Biesheuvel } 114ce0183cbSArd Biesheuvel 115ce0183cbSArd Biesheuvel static int rk_des_ecb_encrypt(struct skcipher_request *req) 116ce0183cbSArd Biesheuvel { 117ce0183cbSArd Biesheuvel struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); 118ce0183cbSArd Biesheuvel struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm); 119ce0183cbSArd Biesheuvel struct rk_crypto_info *dev = ctx->dev; 120ce0183cbSArd Biesheuvel 121ce0183cbSArd Biesheuvel ctx->mode = 0; 122ce0183cbSArd Biesheuvel return rk_handle_req(dev, req); 123ce0183cbSArd Biesheuvel } 124ce0183cbSArd Biesheuvel 125ce0183cbSArd Biesheuvel static int rk_des_ecb_decrypt(struct skcipher_request *req) 126ce0183cbSArd Biesheuvel { 127ce0183cbSArd Biesheuvel struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); 128ce0183cbSArd Biesheuvel struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm); 129ce0183cbSArd Biesheuvel struct rk_crypto_info *dev = ctx->dev; 130ce0183cbSArd Biesheuvel 131ce0183cbSArd Biesheuvel ctx->mode = RK_CRYPTO_DEC; 132ce0183cbSArd Biesheuvel return rk_handle_req(dev, req); 133ce0183cbSArd Biesheuvel } 134ce0183cbSArd Biesheuvel 135ce0183cbSArd Biesheuvel static int rk_des_cbc_encrypt(struct skcipher_request *req) 136ce0183cbSArd Biesheuvel { 137ce0183cbSArd Biesheuvel struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); 138ce0183cbSArd Biesheuvel struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm); 139ce0183cbSArd Biesheuvel struct rk_crypto_info *dev = ctx->dev; 140ce0183cbSArd Biesheuvel 141ce0183cbSArd Biesheuvel ctx->mode = RK_CRYPTO_TDES_CHAINMODE_CBC; 142ce0183cbSArd Biesheuvel return rk_handle_req(dev, req); 143ce0183cbSArd Biesheuvel } 144ce0183cbSArd Biesheuvel 145ce0183cbSArd Biesheuvel static int rk_des_cbc_decrypt(struct skcipher_request *req) 146ce0183cbSArd Biesheuvel { 147ce0183cbSArd Biesheuvel struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); 148ce0183cbSArd Biesheuvel struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm); 149ce0183cbSArd Biesheuvel struct rk_crypto_info *dev = ctx->dev; 150ce0183cbSArd Biesheuvel 151ce0183cbSArd Biesheuvel ctx->mode = RK_CRYPTO_TDES_CHAINMODE_CBC | RK_CRYPTO_DEC; 152ce0183cbSArd Biesheuvel return rk_handle_req(dev, req); 153ce0183cbSArd Biesheuvel } 154ce0183cbSArd Biesheuvel 155ce0183cbSArd Biesheuvel static int rk_des3_ede_ecb_encrypt(struct skcipher_request *req) 156ce0183cbSArd Biesheuvel { 157ce0183cbSArd Biesheuvel struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); 158ce0183cbSArd Biesheuvel struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm); 159ce0183cbSArd Biesheuvel struct rk_crypto_info *dev = ctx->dev; 160ce0183cbSArd Biesheuvel 161ce0183cbSArd Biesheuvel ctx->mode = RK_CRYPTO_TDES_SELECT; 162ce0183cbSArd Biesheuvel return rk_handle_req(dev, req); 163ce0183cbSArd Biesheuvel } 164ce0183cbSArd Biesheuvel 165ce0183cbSArd Biesheuvel static int rk_des3_ede_ecb_decrypt(struct skcipher_request *req) 166ce0183cbSArd Biesheuvel { 167ce0183cbSArd Biesheuvel struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); 168ce0183cbSArd Biesheuvel struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm); 169ce0183cbSArd Biesheuvel struct rk_crypto_info *dev = ctx->dev; 170ce0183cbSArd Biesheuvel 171ce0183cbSArd Biesheuvel ctx->mode = RK_CRYPTO_TDES_SELECT | RK_CRYPTO_DEC; 172ce0183cbSArd Biesheuvel return rk_handle_req(dev, req); 173ce0183cbSArd Biesheuvel } 174ce0183cbSArd Biesheuvel 175ce0183cbSArd Biesheuvel static int rk_des3_ede_cbc_encrypt(struct skcipher_request *req) 176ce0183cbSArd Biesheuvel { 177ce0183cbSArd Biesheuvel struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); 178ce0183cbSArd Biesheuvel struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm); 179ce0183cbSArd Biesheuvel struct rk_crypto_info *dev = ctx->dev; 180ce0183cbSArd Biesheuvel 181ce0183cbSArd Biesheuvel ctx->mode = RK_CRYPTO_TDES_SELECT | RK_CRYPTO_TDES_CHAINMODE_CBC; 182ce0183cbSArd Biesheuvel return rk_handle_req(dev, req); 183ce0183cbSArd Biesheuvel } 184ce0183cbSArd Biesheuvel 185ce0183cbSArd Biesheuvel static int rk_des3_ede_cbc_decrypt(struct skcipher_request *req) 186ce0183cbSArd Biesheuvel { 187ce0183cbSArd Biesheuvel struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); 188ce0183cbSArd Biesheuvel struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm); 189ce0183cbSArd Biesheuvel struct rk_crypto_info *dev = ctx->dev; 190ce0183cbSArd Biesheuvel 191ce0183cbSArd Biesheuvel ctx->mode = RK_CRYPTO_TDES_SELECT | RK_CRYPTO_TDES_CHAINMODE_CBC | 192ce0183cbSArd Biesheuvel RK_CRYPTO_DEC; 193ce0183cbSArd Biesheuvel return rk_handle_req(dev, req); 194ce0183cbSArd Biesheuvel } 195ce0183cbSArd Biesheuvel 196ce0183cbSArd Biesheuvel static void rk_ablk_hw_init(struct rk_crypto_info *dev) 197ce0183cbSArd Biesheuvel { 198ce0183cbSArd Biesheuvel struct skcipher_request *req = 199ce0183cbSArd Biesheuvel skcipher_request_cast(dev->async_req); 200ce0183cbSArd Biesheuvel struct crypto_skcipher *cipher = crypto_skcipher_reqtfm(req); 201ce0183cbSArd Biesheuvel struct crypto_tfm *tfm = crypto_skcipher_tfm(cipher); 202ce0183cbSArd Biesheuvel struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(cipher); 203ce0183cbSArd Biesheuvel u32 ivsize, block, conf_reg = 0; 204ce0183cbSArd Biesheuvel 205ce0183cbSArd Biesheuvel block = crypto_tfm_alg_blocksize(tfm); 206ce0183cbSArd Biesheuvel ivsize = crypto_skcipher_ivsize(cipher); 207ce0183cbSArd Biesheuvel 208ce0183cbSArd Biesheuvel if (block == DES_BLOCK_SIZE) { 209ce0183cbSArd Biesheuvel ctx->mode |= RK_CRYPTO_TDES_FIFO_MODE | 210ce0183cbSArd Biesheuvel RK_CRYPTO_TDES_BYTESWAP_KEY | 211ce0183cbSArd Biesheuvel RK_CRYPTO_TDES_BYTESWAP_IV; 212ce0183cbSArd Biesheuvel CRYPTO_WRITE(dev, RK_CRYPTO_TDES_CTRL, ctx->mode); 213ce0183cbSArd Biesheuvel memcpy_toio(dev->reg + RK_CRYPTO_TDES_IV_0, req->iv, ivsize); 214ce0183cbSArd Biesheuvel conf_reg = RK_CRYPTO_DESSEL; 215ce0183cbSArd Biesheuvel } else { 216ce0183cbSArd Biesheuvel ctx->mode |= RK_CRYPTO_AES_FIFO_MODE | 217ce0183cbSArd Biesheuvel RK_CRYPTO_AES_KEY_CHANGE | 218ce0183cbSArd Biesheuvel RK_CRYPTO_AES_BYTESWAP_KEY | 219ce0183cbSArd Biesheuvel RK_CRYPTO_AES_BYTESWAP_IV; 220ce0183cbSArd Biesheuvel if (ctx->keylen == AES_KEYSIZE_192) 221ce0183cbSArd Biesheuvel ctx->mode |= RK_CRYPTO_AES_192BIT_key; 222ce0183cbSArd Biesheuvel else if (ctx->keylen == AES_KEYSIZE_256) 223ce0183cbSArd Biesheuvel ctx->mode |= RK_CRYPTO_AES_256BIT_key; 224ce0183cbSArd Biesheuvel CRYPTO_WRITE(dev, RK_CRYPTO_AES_CTRL, ctx->mode); 225ce0183cbSArd Biesheuvel memcpy_toio(dev->reg + RK_CRYPTO_AES_IV_0, req->iv, ivsize); 226ce0183cbSArd Biesheuvel } 227ce0183cbSArd Biesheuvel conf_reg |= RK_CRYPTO_BYTESWAP_BTFIFO | 228ce0183cbSArd Biesheuvel RK_CRYPTO_BYTESWAP_BRFIFO; 229ce0183cbSArd Biesheuvel CRYPTO_WRITE(dev, RK_CRYPTO_CONF, conf_reg); 230ce0183cbSArd Biesheuvel CRYPTO_WRITE(dev, RK_CRYPTO_INTENA, 231ce0183cbSArd Biesheuvel RK_CRYPTO_BCDMA_ERR_ENA | RK_CRYPTO_BCDMA_DONE_ENA); 232ce0183cbSArd Biesheuvel } 233ce0183cbSArd Biesheuvel 234ce0183cbSArd Biesheuvel static void crypto_dma_start(struct rk_crypto_info *dev) 235ce0183cbSArd Biesheuvel { 236ce0183cbSArd Biesheuvel CRYPTO_WRITE(dev, RK_CRYPTO_BRDMAS, dev->addr_in); 237ce0183cbSArd Biesheuvel CRYPTO_WRITE(dev, RK_CRYPTO_BRDMAL, dev->count / 4); 238ce0183cbSArd Biesheuvel CRYPTO_WRITE(dev, RK_CRYPTO_BTDMAS, dev->addr_out); 239ce0183cbSArd Biesheuvel CRYPTO_WRITE(dev, RK_CRYPTO_CTRL, RK_CRYPTO_BLOCK_START | 240ce0183cbSArd Biesheuvel _SBF(RK_CRYPTO_BLOCK_START, 16)); 241ce0183cbSArd Biesheuvel } 242ce0183cbSArd Biesheuvel 243ce0183cbSArd Biesheuvel static int rk_set_data_start(struct rk_crypto_info *dev) 244ce0183cbSArd Biesheuvel { 245ce0183cbSArd Biesheuvel int err; 246ce0183cbSArd Biesheuvel struct skcipher_request *req = 247ce0183cbSArd Biesheuvel skcipher_request_cast(dev->async_req); 248ce0183cbSArd Biesheuvel struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); 249ce0183cbSArd Biesheuvel struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm); 250ce0183cbSArd Biesheuvel u32 ivsize = crypto_skcipher_ivsize(tfm); 251ce0183cbSArd Biesheuvel u8 *src_last_blk = page_address(sg_page(dev->sg_src)) + 252ce0183cbSArd Biesheuvel dev->sg_src->offset + dev->sg_src->length - ivsize; 253ce0183cbSArd Biesheuvel 254ce0183cbSArd Biesheuvel /* Store the iv that need to be updated in chain mode. 255ce0183cbSArd Biesheuvel * And update the IV buffer to contain the next IV for decryption mode. 256ce0183cbSArd Biesheuvel */ 257ce0183cbSArd Biesheuvel if (ctx->mode & RK_CRYPTO_DEC) { 258ce0183cbSArd Biesheuvel memcpy(ctx->iv, src_last_blk, ivsize); 259ce0183cbSArd Biesheuvel sg_pcopy_to_buffer(dev->first, dev->src_nents, req->iv, 260ce0183cbSArd Biesheuvel ivsize, dev->total - ivsize); 261ce0183cbSArd Biesheuvel } 262ce0183cbSArd Biesheuvel 263ce0183cbSArd Biesheuvel err = dev->load_data(dev, dev->sg_src, dev->sg_dst); 264ce0183cbSArd Biesheuvel if (!err) 265ce0183cbSArd Biesheuvel crypto_dma_start(dev); 266ce0183cbSArd Biesheuvel return err; 267ce0183cbSArd Biesheuvel } 268ce0183cbSArd Biesheuvel 269ce0183cbSArd Biesheuvel static int rk_ablk_start(struct rk_crypto_info *dev) 270ce0183cbSArd Biesheuvel { 271ce0183cbSArd Biesheuvel struct skcipher_request *req = 272ce0183cbSArd Biesheuvel skcipher_request_cast(dev->async_req); 273ce0183cbSArd Biesheuvel unsigned long flags; 274ce0183cbSArd Biesheuvel int err = 0; 275ce0183cbSArd Biesheuvel 276ce0183cbSArd Biesheuvel dev->left_bytes = req->cryptlen; 277ce0183cbSArd Biesheuvel dev->total = req->cryptlen; 278ce0183cbSArd Biesheuvel dev->sg_src = req->src; 279ce0183cbSArd Biesheuvel dev->first = req->src; 280ce0183cbSArd Biesheuvel dev->src_nents = sg_nents(req->src); 281ce0183cbSArd Biesheuvel dev->sg_dst = req->dst; 282ce0183cbSArd Biesheuvel dev->dst_nents = sg_nents(req->dst); 283ce0183cbSArd Biesheuvel dev->aligned = 1; 284ce0183cbSArd Biesheuvel 285ce0183cbSArd Biesheuvel spin_lock_irqsave(&dev->lock, flags); 286ce0183cbSArd Biesheuvel rk_ablk_hw_init(dev); 287ce0183cbSArd Biesheuvel err = rk_set_data_start(dev); 288ce0183cbSArd Biesheuvel spin_unlock_irqrestore(&dev->lock, flags); 289ce0183cbSArd Biesheuvel return err; 290ce0183cbSArd Biesheuvel } 291ce0183cbSArd Biesheuvel 292ce0183cbSArd Biesheuvel static void rk_iv_copyback(struct rk_crypto_info *dev) 293ce0183cbSArd Biesheuvel { 294ce0183cbSArd Biesheuvel struct skcipher_request *req = 295ce0183cbSArd Biesheuvel skcipher_request_cast(dev->async_req); 296ce0183cbSArd Biesheuvel struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); 297ce0183cbSArd Biesheuvel struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm); 298ce0183cbSArd Biesheuvel u32 ivsize = crypto_skcipher_ivsize(tfm); 299ce0183cbSArd Biesheuvel 300ce0183cbSArd Biesheuvel /* Update the IV buffer to contain the next IV for encryption mode. */ 301ce0183cbSArd Biesheuvel if (!(ctx->mode & RK_CRYPTO_DEC)) { 302ce0183cbSArd Biesheuvel if (dev->aligned) { 303ce0183cbSArd Biesheuvel memcpy(req->iv, sg_virt(dev->sg_dst) + 304ce0183cbSArd Biesheuvel dev->sg_dst->length - ivsize, ivsize); 305ce0183cbSArd Biesheuvel } else { 306ce0183cbSArd Biesheuvel memcpy(req->iv, dev->addr_vir + 307ce0183cbSArd Biesheuvel dev->count - ivsize, ivsize); 308ce0183cbSArd Biesheuvel } 309ce0183cbSArd Biesheuvel } 310ce0183cbSArd Biesheuvel } 311ce0183cbSArd Biesheuvel 312ce0183cbSArd Biesheuvel static void rk_update_iv(struct rk_crypto_info *dev) 313ce0183cbSArd Biesheuvel { 314ce0183cbSArd Biesheuvel struct skcipher_request *req = 315ce0183cbSArd Biesheuvel skcipher_request_cast(dev->async_req); 316ce0183cbSArd Biesheuvel struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); 317ce0183cbSArd Biesheuvel struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm); 318ce0183cbSArd Biesheuvel u32 ivsize = crypto_skcipher_ivsize(tfm); 319ce0183cbSArd Biesheuvel u8 *new_iv = NULL; 320ce0183cbSArd Biesheuvel 321ce0183cbSArd Biesheuvel if (ctx->mode & RK_CRYPTO_DEC) { 322ce0183cbSArd Biesheuvel new_iv = ctx->iv; 323ce0183cbSArd Biesheuvel } else { 324ce0183cbSArd Biesheuvel new_iv = page_address(sg_page(dev->sg_dst)) + 325ce0183cbSArd Biesheuvel dev->sg_dst->offset + dev->sg_dst->length - ivsize; 326ce0183cbSArd Biesheuvel } 327ce0183cbSArd Biesheuvel 328ce0183cbSArd Biesheuvel if (ivsize == DES_BLOCK_SIZE) 329ce0183cbSArd Biesheuvel memcpy_toio(dev->reg + RK_CRYPTO_TDES_IV_0, new_iv, ivsize); 330ce0183cbSArd Biesheuvel else if (ivsize == AES_BLOCK_SIZE) 331ce0183cbSArd Biesheuvel memcpy_toio(dev->reg + RK_CRYPTO_AES_IV_0, new_iv, ivsize); 332ce0183cbSArd Biesheuvel } 333ce0183cbSArd Biesheuvel 334ce0183cbSArd Biesheuvel /* return: 335ce0183cbSArd Biesheuvel * true some err was occurred 336ce0183cbSArd Biesheuvel * fault no err, continue 337ce0183cbSArd Biesheuvel */ 338ce0183cbSArd Biesheuvel static int rk_ablk_rx(struct rk_crypto_info *dev) 339ce0183cbSArd Biesheuvel { 340ce0183cbSArd Biesheuvel int err = 0; 341ce0183cbSArd Biesheuvel struct skcipher_request *req = 342ce0183cbSArd Biesheuvel skcipher_request_cast(dev->async_req); 343ce0183cbSArd Biesheuvel 344ce0183cbSArd Biesheuvel dev->unload_data(dev); 345ce0183cbSArd Biesheuvel if (!dev->aligned) { 346ce0183cbSArd Biesheuvel if (!sg_pcopy_from_buffer(req->dst, dev->dst_nents, 347ce0183cbSArd Biesheuvel dev->addr_vir, dev->count, 348ce0183cbSArd Biesheuvel dev->total - dev->left_bytes - 349ce0183cbSArd Biesheuvel dev->count)) { 350ce0183cbSArd Biesheuvel err = -EINVAL; 351ce0183cbSArd Biesheuvel goto out_rx; 352ce0183cbSArd Biesheuvel } 353ce0183cbSArd Biesheuvel } 354ce0183cbSArd Biesheuvel if (dev->left_bytes) { 355ce0183cbSArd Biesheuvel rk_update_iv(dev); 356ce0183cbSArd Biesheuvel if (dev->aligned) { 357ce0183cbSArd Biesheuvel if (sg_is_last(dev->sg_src)) { 358ce0183cbSArd Biesheuvel dev_err(dev->dev, "[%s:%d] Lack of data\n", 359ce0183cbSArd Biesheuvel __func__, __LINE__); 360ce0183cbSArd Biesheuvel err = -ENOMEM; 361ce0183cbSArd Biesheuvel goto out_rx; 362ce0183cbSArd Biesheuvel } 363ce0183cbSArd Biesheuvel dev->sg_src = sg_next(dev->sg_src); 364ce0183cbSArd Biesheuvel dev->sg_dst = sg_next(dev->sg_dst); 365ce0183cbSArd Biesheuvel } 366ce0183cbSArd Biesheuvel err = rk_set_data_start(dev); 367ce0183cbSArd Biesheuvel } else { 368ce0183cbSArd Biesheuvel rk_iv_copyback(dev); 369ce0183cbSArd Biesheuvel /* here show the calculation is over without any err */ 370ce0183cbSArd Biesheuvel dev->complete(dev->async_req, 0); 371ce0183cbSArd Biesheuvel tasklet_schedule(&dev->queue_task); 372ce0183cbSArd Biesheuvel } 373ce0183cbSArd Biesheuvel out_rx: 374ce0183cbSArd Biesheuvel return err; 375ce0183cbSArd Biesheuvel } 376ce0183cbSArd Biesheuvel 377ce0183cbSArd Biesheuvel static int rk_ablk_init_tfm(struct crypto_skcipher *tfm) 378ce0183cbSArd Biesheuvel { 379ce0183cbSArd Biesheuvel struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm); 380ce0183cbSArd Biesheuvel struct skcipher_alg *alg = crypto_skcipher_alg(tfm); 381ce0183cbSArd Biesheuvel struct rk_crypto_tmp *algt; 382ce0183cbSArd Biesheuvel 383ce0183cbSArd Biesheuvel algt = container_of(alg, struct rk_crypto_tmp, alg.skcipher); 384ce0183cbSArd Biesheuvel 385ce0183cbSArd Biesheuvel ctx->dev = algt->dev; 386ce0183cbSArd Biesheuvel ctx->dev->align_size = crypto_tfm_alg_alignmask(crypto_skcipher_tfm(tfm)) + 1; 387ce0183cbSArd Biesheuvel ctx->dev->start = rk_ablk_start; 388ce0183cbSArd Biesheuvel ctx->dev->update = rk_ablk_rx; 389ce0183cbSArd Biesheuvel ctx->dev->complete = rk_crypto_complete; 390ce0183cbSArd Biesheuvel ctx->dev->addr_vir = (char *)__get_free_page(GFP_KERNEL); 391ce0183cbSArd Biesheuvel 392ce0183cbSArd Biesheuvel return ctx->dev->addr_vir ? ctx->dev->enable_clk(ctx->dev) : -ENOMEM; 393ce0183cbSArd Biesheuvel } 394ce0183cbSArd Biesheuvel 395ce0183cbSArd Biesheuvel static void rk_ablk_exit_tfm(struct crypto_skcipher *tfm) 396ce0183cbSArd Biesheuvel { 397ce0183cbSArd Biesheuvel struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm); 398ce0183cbSArd Biesheuvel 399ce0183cbSArd Biesheuvel free_page((unsigned long)ctx->dev->addr_vir); 400ce0183cbSArd Biesheuvel ctx->dev->disable_clk(ctx->dev); 401ce0183cbSArd Biesheuvel } 402ce0183cbSArd Biesheuvel 403ce0183cbSArd Biesheuvel struct rk_crypto_tmp rk_ecb_aes_alg = { 404ce0183cbSArd Biesheuvel .type = ALG_TYPE_CIPHER, 405ce0183cbSArd Biesheuvel .alg.skcipher = { 406ce0183cbSArd Biesheuvel .base.cra_name = "ecb(aes)", 407ce0183cbSArd Biesheuvel .base.cra_driver_name = "ecb-aes-rk", 408ce0183cbSArd Biesheuvel .base.cra_priority = 300, 409ce0183cbSArd Biesheuvel .base.cra_flags = CRYPTO_ALG_ASYNC, 410ce0183cbSArd Biesheuvel .base.cra_blocksize = AES_BLOCK_SIZE, 411ce0183cbSArd Biesheuvel .base.cra_ctxsize = sizeof(struct rk_cipher_ctx), 412ce0183cbSArd Biesheuvel .base.cra_alignmask = 0x0f, 413ce0183cbSArd Biesheuvel .base.cra_module = THIS_MODULE, 414ce0183cbSArd Biesheuvel 415ce0183cbSArd Biesheuvel .init = rk_ablk_init_tfm, 416ce0183cbSArd Biesheuvel .exit = rk_ablk_exit_tfm, 417ce0183cbSArd Biesheuvel .min_keysize = AES_MIN_KEY_SIZE, 418ce0183cbSArd Biesheuvel .max_keysize = AES_MAX_KEY_SIZE, 419ce0183cbSArd Biesheuvel .setkey = rk_aes_setkey, 420ce0183cbSArd Biesheuvel .encrypt = rk_aes_ecb_encrypt, 421ce0183cbSArd Biesheuvel .decrypt = rk_aes_ecb_decrypt, 422ce0183cbSArd Biesheuvel } 423ce0183cbSArd Biesheuvel }; 424ce0183cbSArd Biesheuvel 425ce0183cbSArd Biesheuvel struct rk_crypto_tmp rk_cbc_aes_alg = { 426ce0183cbSArd Biesheuvel .type = ALG_TYPE_CIPHER, 427ce0183cbSArd Biesheuvel .alg.skcipher = { 428ce0183cbSArd Biesheuvel .base.cra_name = "cbc(aes)", 429ce0183cbSArd Biesheuvel .base.cra_driver_name = "cbc-aes-rk", 430ce0183cbSArd Biesheuvel .base.cra_priority = 300, 431ce0183cbSArd Biesheuvel .base.cra_flags = CRYPTO_ALG_ASYNC, 432ce0183cbSArd Biesheuvel .base.cra_blocksize = AES_BLOCK_SIZE, 433ce0183cbSArd Biesheuvel .base.cra_ctxsize = sizeof(struct rk_cipher_ctx), 434ce0183cbSArd Biesheuvel .base.cra_alignmask = 0x0f, 435ce0183cbSArd Biesheuvel .base.cra_module = THIS_MODULE, 436ce0183cbSArd Biesheuvel 437ce0183cbSArd Biesheuvel .init = rk_ablk_init_tfm, 438ce0183cbSArd Biesheuvel .exit = rk_ablk_exit_tfm, 439ce0183cbSArd Biesheuvel .min_keysize = AES_MIN_KEY_SIZE, 440ce0183cbSArd Biesheuvel .max_keysize = AES_MAX_KEY_SIZE, 441ce0183cbSArd Biesheuvel .ivsize = AES_BLOCK_SIZE, 442ce0183cbSArd Biesheuvel .setkey = rk_aes_setkey, 443ce0183cbSArd Biesheuvel .encrypt = rk_aes_cbc_encrypt, 444ce0183cbSArd Biesheuvel .decrypt = rk_aes_cbc_decrypt, 445ce0183cbSArd Biesheuvel } 446ce0183cbSArd Biesheuvel }; 447ce0183cbSArd Biesheuvel 448ce0183cbSArd Biesheuvel struct rk_crypto_tmp rk_ecb_des_alg = { 449ce0183cbSArd Biesheuvel .type = ALG_TYPE_CIPHER, 450ce0183cbSArd Biesheuvel .alg.skcipher = { 451ce0183cbSArd Biesheuvel .base.cra_name = "ecb(des)", 452ce0183cbSArd Biesheuvel .base.cra_driver_name = "ecb-des-rk", 453ce0183cbSArd Biesheuvel .base.cra_priority = 300, 454ce0183cbSArd Biesheuvel .base.cra_flags = CRYPTO_ALG_ASYNC, 455ce0183cbSArd Biesheuvel .base.cra_blocksize = DES_BLOCK_SIZE, 456ce0183cbSArd Biesheuvel .base.cra_ctxsize = sizeof(struct rk_cipher_ctx), 457ce0183cbSArd Biesheuvel .base.cra_alignmask = 0x07, 458ce0183cbSArd Biesheuvel .base.cra_module = THIS_MODULE, 459ce0183cbSArd Biesheuvel 460ce0183cbSArd Biesheuvel .init = rk_ablk_init_tfm, 461ce0183cbSArd Biesheuvel .exit = rk_ablk_exit_tfm, 462ce0183cbSArd Biesheuvel .min_keysize = DES_KEY_SIZE, 463ce0183cbSArd Biesheuvel .max_keysize = DES_KEY_SIZE, 464ce0183cbSArd Biesheuvel .setkey = rk_des_setkey, 465ce0183cbSArd Biesheuvel .encrypt = rk_des_ecb_encrypt, 466ce0183cbSArd Biesheuvel .decrypt = rk_des_ecb_decrypt, 467ce0183cbSArd Biesheuvel } 468ce0183cbSArd Biesheuvel }; 469ce0183cbSArd Biesheuvel 470ce0183cbSArd Biesheuvel struct rk_crypto_tmp rk_cbc_des_alg = { 471ce0183cbSArd Biesheuvel .type = ALG_TYPE_CIPHER, 472ce0183cbSArd Biesheuvel .alg.skcipher = { 473ce0183cbSArd Biesheuvel .base.cra_name = "cbc(des)", 474ce0183cbSArd Biesheuvel .base.cra_driver_name = "cbc-des-rk", 475ce0183cbSArd Biesheuvel .base.cra_priority = 300, 476ce0183cbSArd Biesheuvel .base.cra_flags = CRYPTO_ALG_ASYNC, 477ce0183cbSArd Biesheuvel .base.cra_blocksize = DES_BLOCK_SIZE, 478ce0183cbSArd Biesheuvel .base.cra_ctxsize = sizeof(struct rk_cipher_ctx), 479ce0183cbSArd Biesheuvel .base.cra_alignmask = 0x07, 480ce0183cbSArd Biesheuvel .base.cra_module = THIS_MODULE, 481ce0183cbSArd Biesheuvel 482ce0183cbSArd Biesheuvel .init = rk_ablk_init_tfm, 483ce0183cbSArd Biesheuvel .exit = rk_ablk_exit_tfm, 484ce0183cbSArd Biesheuvel .min_keysize = DES_KEY_SIZE, 485ce0183cbSArd Biesheuvel .max_keysize = DES_KEY_SIZE, 486ce0183cbSArd Biesheuvel .ivsize = DES_BLOCK_SIZE, 487ce0183cbSArd Biesheuvel .setkey = rk_des_setkey, 488ce0183cbSArd Biesheuvel .encrypt = rk_des_cbc_encrypt, 489ce0183cbSArd Biesheuvel .decrypt = rk_des_cbc_decrypt, 490ce0183cbSArd Biesheuvel } 491ce0183cbSArd Biesheuvel }; 492ce0183cbSArd Biesheuvel 493ce0183cbSArd Biesheuvel struct rk_crypto_tmp rk_ecb_des3_ede_alg = { 494ce0183cbSArd Biesheuvel .type = ALG_TYPE_CIPHER, 495ce0183cbSArd Biesheuvel .alg.skcipher = { 496ce0183cbSArd Biesheuvel .base.cra_name = "ecb(des3_ede)", 497ce0183cbSArd Biesheuvel .base.cra_driver_name = "ecb-des3-ede-rk", 498ce0183cbSArd Biesheuvel .base.cra_priority = 300, 499ce0183cbSArd Biesheuvel .base.cra_flags = CRYPTO_ALG_ASYNC, 500ce0183cbSArd Biesheuvel .base.cra_blocksize = DES_BLOCK_SIZE, 501ce0183cbSArd Biesheuvel .base.cra_ctxsize = sizeof(struct rk_cipher_ctx), 502ce0183cbSArd Biesheuvel .base.cra_alignmask = 0x07, 503ce0183cbSArd Biesheuvel .base.cra_module = THIS_MODULE, 504ce0183cbSArd Biesheuvel 505ce0183cbSArd Biesheuvel .init = rk_ablk_init_tfm, 506ce0183cbSArd Biesheuvel .exit = rk_ablk_exit_tfm, 507ce0183cbSArd Biesheuvel .min_keysize = DES3_EDE_KEY_SIZE, 508ce0183cbSArd Biesheuvel .max_keysize = DES3_EDE_KEY_SIZE, 509ce0183cbSArd Biesheuvel .ivsize = DES_BLOCK_SIZE, 510ce0183cbSArd Biesheuvel .setkey = rk_tdes_setkey, 511ce0183cbSArd Biesheuvel .encrypt = rk_des3_ede_ecb_encrypt, 512ce0183cbSArd Biesheuvel .decrypt = rk_des3_ede_ecb_decrypt, 513ce0183cbSArd Biesheuvel } 514ce0183cbSArd Biesheuvel }; 515ce0183cbSArd Biesheuvel 516ce0183cbSArd Biesheuvel struct rk_crypto_tmp rk_cbc_des3_ede_alg = { 517ce0183cbSArd Biesheuvel .type = ALG_TYPE_CIPHER, 518ce0183cbSArd Biesheuvel .alg.skcipher = { 519ce0183cbSArd Biesheuvel .base.cra_name = "cbc(des3_ede)", 520ce0183cbSArd Biesheuvel .base.cra_driver_name = "cbc-des3-ede-rk", 521ce0183cbSArd Biesheuvel .base.cra_priority = 300, 522ce0183cbSArd Biesheuvel .base.cra_flags = CRYPTO_ALG_ASYNC, 523ce0183cbSArd Biesheuvel .base.cra_blocksize = DES_BLOCK_SIZE, 524ce0183cbSArd Biesheuvel .base.cra_ctxsize = sizeof(struct rk_cipher_ctx), 525ce0183cbSArd Biesheuvel .base.cra_alignmask = 0x07, 526ce0183cbSArd Biesheuvel .base.cra_module = THIS_MODULE, 527ce0183cbSArd Biesheuvel 528ce0183cbSArd Biesheuvel .init = rk_ablk_init_tfm, 529ce0183cbSArd Biesheuvel .exit = rk_ablk_exit_tfm, 530ce0183cbSArd Biesheuvel .min_keysize = DES3_EDE_KEY_SIZE, 531ce0183cbSArd Biesheuvel .max_keysize = DES3_EDE_KEY_SIZE, 532ce0183cbSArd Biesheuvel .ivsize = DES_BLOCK_SIZE, 533ce0183cbSArd Biesheuvel .setkey = rk_tdes_setkey, 534ce0183cbSArd Biesheuvel .encrypt = rk_des3_ede_cbc_encrypt, 535ce0183cbSArd Biesheuvel .decrypt = rk_des3_ede_cbc_decrypt, 536ce0183cbSArd Biesheuvel } 537ce0183cbSArd Biesheuvel }; 538