1*9e054ec2SFabien DESSENNE /* 2*9e054ec2SFabien DESSENNE * Copyright (C) STMicroelectronics SA 2017 3*9e054ec2SFabien DESSENNE * Author: Fabien Dessenne <fabien.dessenne@st.com> 4*9e054ec2SFabien DESSENNE * License terms: GNU General Public License (GPL), version 2 5*9e054ec2SFabien DESSENNE */ 6*9e054ec2SFabien DESSENNE 7*9e054ec2SFabien DESSENNE #include <linux/clk.h> 8*9e054ec2SFabien DESSENNE #include <linux/delay.h> 9*9e054ec2SFabien DESSENNE #include <linux/interrupt.h> 10*9e054ec2SFabien DESSENNE #include <linux/iopoll.h> 11*9e054ec2SFabien DESSENNE #include <linux/module.h> 12*9e054ec2SFabien DESSENNE #include <linux/of_device.h> 13*9e054ec2SFabien DESSENNE #include <linux/platform_device.h> 14*9e054ec2SFabien DESSENNE #include <linux/reset.h> 15*9e054ec2SFabien DESSENNE 16*9e054ec2SFabien DESSENNE #include <crypto/aes.h> 17*9e054ec2SFabien DESSENNE #include <crypto/des.h> 18*9e054ec2SFabien DESSENNE #include <crypto/engine.h> 19*9e054ec2SFabien DESSENNE #include <crypto/scatterwalk.h> 20*9e054ec2SFabien DESSENNE 21*9e054ec2SFabien DESSENNE #define DRIVER_NAME "stm32-cryp" 22*9e054ec2SFabien DESSENNE 23*9e054ec2SFabien DESSENNE /* Bit [0] encrypt / decrypt */ 24*9e054ec2SFabien DESSENNE #define FLG_ENCRYPT BIT(0) 25*9e054ec2SFabien DESSENNE /* Bit [8..1] algo & operation mode */ 26*9e054ec2SFabien DESSENNE #define FLG_AES BIT(1) 27*9e054ec2SFabien DESSENNE #define FLG_DES BIT(2) 28*9e054ec2SFabien DESSENNE #define FLG_TDES BIT(3) 29*9e054ec2SFabien DESSENNE #define FLG_ECB BIT(4) 30*9e054ec2SFabien DESSENNE #define FLG_CBC BIT(5) 31*9e054ec2SFabien DESSENNE #define FLG_CTR BIT(6) 32*9e054ec2SFabien DESSENNE /* Mode mask = bits [15..0] */ 33*9e054ec2SFabien DESSENNE #define FLG_MODE_MASK GENMASK(15, 0) 34*9e054ec2SFabien DESSENNE 35*9e054ec2SFabien DESSENNE /* Registers */ 36*9e054ec2SFabien DESSENNE #define CRYP_CR 0x00000000 37*9e054ec2SFabien DESSENNE #define CRYP_SR 0x00000004 38*9e054ec2SFabien DESSENNE #define CRYP_DIN 0x00000008 39*9e054ec2SFabien DESSENNE #define CRYP_DOUT 0x0000000C 40*9e054ec2SFabien DESSENNE #define CRYP_DMACR 0x00000010 41*9e054ec2SFabien DESSENNE #define CRYP_IMSCR 0x00000014 42*9e054ec2SFabien DESSENNE #define CRYP_RISR 0x00000018 43*9e054ec2SFabien DESSENNE #define CRYP_MISR 0x0000001C 44*9e054ec2SFabien DESSENNE #define CRYP_K0LR 0x00000020 45*9e054ec2SFabien DESSENNE #define CRYP_K0RR 0x00000024 46*9e054ec2SFabien DESSENNE #define CRYP_K1LR 0x00000028 47*9e054ec2SFabien DESSENNE #define CRYP_K1RR 0x0000002C 48*9e054ec2SFabien DESSENNE #define CRYP_K2LR 0x00000030 49*9e054ec2SFabien DESSENNE #define CRYP_K2RR 0x00000034 50*9e054ec2SFabien DESSENNE #define CRYP_K3LR 0x00000038 51*9e054ec2SFabien DESSENNE #define CRYP_K3RR 0x0000003C 52*9e054ec2SFabien DESSENNE #define CRYP_IV0LR 0x00000040 53*9e054ec2SFabien DESSENNE #define CRYP_IV0RR 0x00000044 54*9e054ec2SFabien DESSENNE #define CRYP_IV1LR 0x00000048 55*9e054ec2SFabien DESSENNE #define CRYP_IV1RR 0x0000004C 56*9e054ec2SFabien DESSENNE 57*9e054ec2SFabien DESSENNE /* Registers values */ 58*9e054ec2SFabien DESSENNE #define CR_DEC_NOT_ENC 0x00000004 59*9e054ec2SFabien DESSENNE #define CR_TDES_ECB 0x00000000 60*9e054ec2SFabien DESSENNE #define CR_TDES_CBC 0x00000008 61*9e054ec2SFabien DESSENNE #define CR_DES_ECB 0x00000010 62*9e054ec2SFabien DESSENNE #define CR_DES_CBC 0x00000018 63*9e054ec2SFabien DESSENNE #define CR_AES_ECB 0x00000020 64*9e054ec2SFabien DESSENNE #define CR_AES_CBC 0x00000028 65*9e054ec2SFabien DESSENNE #define CR_AES_CTR 0x00000030 66*9e054ec2SFabien DESSENNE #define CR_AES_KP 0x00000038 67*9e054ec2SFabien DESSENNE #define CR_AES_UNKNOWN 0xFFFFFFFF 68*9e054ec2SFabien DESSENNE #define CR_ALGO_MASK 0x00080038 69*9e054ec2SFabien DESSENNE #define CR_DATA32 0x00000000 70*9e054ec2SFabien DESSENNE #define CR_DATA16 0x00000040 71*9e054ec2SFabien DESSENNE #define CR_DATA8 0x00000080 72*9e054ec2SFabien DESSENNE #define CR_DATA1 0x000000C0 73*9e054ec2SFabien DESSENNE #define CR_KEY128 0x00000000 74*9e054ec2SFabien DESSENNE #define CR_KEY192 0x00000100 75*9e054ec2SFabien DESSENNE #define CR_KEY256 0x00000200 76*9e054ec2SFabien DESSENNE #define CR_FFLUSH 0x00004000 77*9e054ec2SFabien DESSENNE #define CR_CRYPEN 0x00008000 78*9e054ec2SFabien DESSENNE 79*9e054ec2SFabien DESSENNE #define SR_BUSY 0x00000010 80*9e054ec2SFabien DESSENNE #define SR_OFNE 0x00000004 81*9e054ec2SFabien DESSENNE 82*9e054ec2SFabien DESSENNE #define IMSCR_IN BIT(0) 83*9e054ec2SFabien DESSENNE #define IMSCR_OUT BIT(1) 84*9e054ec2SFabien DESSENNE 85*9e054ec2SFabien DESSENNE #define MISR_IN BIT(0) 86*9e054ec2SFabien DESSENNE #define MISR_OUT BIT(1) 87*9e054ec2SFabien DESSENNE 88*9e054ec2SFabien DESSENNE /* Misc */ 89*9e054ec2SFabien DESSENNE #define AES_BLOCK_32 (AES_BLOCK_SIZE / sizeof(u32)) 90*9e054ec2SFabien DESSENNE #define _walked_in (cryp->in_walk.offset - cryp->in_sg->offset) 91*9e054ec2SFabien DESSENNE #define _walked_out (cryp->out_walk.offset - cryp->out_sg->offset) 92*9e054ec2SFabien DESSENNE 93*9e054ec2SFabien DESSENNE struct stm32_cryp_ctx { 94*9e054ec2SFabien DESSENNE struct stm32_cryp *cryp; 95*9e054ec2SFabien DESSENNE int keylen; 96*9e054ec2SFabien DESSENNE u32 key[AES_KEYSIZE_256 / sizeof(u32)]; 97*9e054ec2SFabien DESSENNE unsigned long flags; 98*9e054ec2SFabien DESSENNE }; 99*9e054ec2SFabien DESSENNE 100*9e054ec2SFabien DESSENNE struct stm32_cryp_reqctx { 101*9e054ec2SFabien DESSENNE unsigned long mode; 102*9e054ec2SFabien DESSENNE }; 103*9e054ec2SFabien DESSENNE 104*9e054ec2SFabien DESSENNE struct stm32_cryp { 105*9e054ec2SFabien DESSENNE struct list_head list; 106*9e054ec2SFabien DESSENNE struct device *dev; 107*9e054ec2SFabien DESSENNE void __iomem *regs; 108*9e054ec2SFabien DESSENNE struct clk *clk; 109*9e054ec2SFabien DESSENNE unsigned long flags; 110*9e054ec2SFabien DESSENNE u32 irq_status; 111*9e054ec2SFabien DESSENNE struct stm32_cryp_ctx *ctx; 112*9e054ec2SFabien DESSENNE 113*9e054ec2SFabien DESSENNE struct crypto_engine *engine; 114*9e054ec2SFabien DESSENNE 115*9e054ec2SFabien DESSENNE struct mutex lock; /* protects req */ 116*9e054ec2SFabien DESSENNE struct ablkcipher_request *req; 117*9e054ec2SFabien DESSENNE 118*9e054ec2SFabien DESSENNE size_t hw_blocksize; 119*9e054ec2SFabien DESSENNE 120*9e054ec2SFabien DESSENNE size_t total_in; 121*9e054ec2SFabien DESSENNE size_t total_in_save; 122*9e054ec2SFabien DESSENNE size_t total_out; 123*9e054ec2SFabien DESSENNE size_t total_out_save; 124*9e054ec2SFabien DESSENNE 125*9e054ec2SFabien DESSENNE struct scatterlist *in_sg; 126*9e054ec2SFabien DESSENNE struct scatterlist *out_sg; 127*9e054ec2SFabien DESSENNE struct scatterlist *out_sg_save; 128*9e054ec2SFabien DESSENNE 129*9e054ec2SFabien DESSENNE struct scatterlist in_sgl; 130*9e054ec2SFabien DESSENNE struct scatterlist out_sgl; 131*9e054ec2SFabien DESSENNE bool sgs_copied; 132*9e054ec2SFabien DESSENNE 133*9e054ec2SFabien DESSENNE int in_sg_len; 134*9e054ec2SFabien DESSENNE int out_sg_len; 135*9e054ec2SFabien DESSENNE 136*9e054ec2SFabien DESSENNE struct scatter_walk in_walk; 137*9e054ec2SFabien DESSENNE struct scatter_walk out_walk; 138*9e054ec2SFabien DESSENNE 139*9e054ec2SFabien DESSENNE u32 last_ctr[4]; 140*9e054ec2SFabien DESSENNE }; 141*9e054ec2SFabien DESSENNE 142*9e054ec2SFabien DESSENNE struct stm32_cryp_list { 143*9e054ec2SFabien DESSENNE struct list_head dev_list; 144*9e054ec2SFabien DESSENNE spinlock_t lock; /* protect dev_list */ 145*9e054ec2SFabien DESSENNE }; 146*9e054ec2SFabien DESSENNE 147*9e054ec2SFabien DESSENNE static struct stm32_cryp_list cryp_list = { 148*9e054ec2SFabien DESSENNE .dev_list = LIST_HEAD_INIT(cryp_list.dev_list), 149*9e054ec2SFabien DESSENNE .lock = __SPIN_LOCK_UNLOCKED(cryp_list.lock), 150*9e054ec2SFabien DESSENNE }; 151*9e054ec2SFabien DESSENNE 152*9e054ec2SFabien DESSENNE static inline bool is_aes(struct stm32_cryp *cryp) 153*9e054ec2SFabien DESSENNE { 154*9e054ec2SFabien DESSENNE return cryp->flags & FLG_AES; 155*9e054ec2SFabien DESSENNE } 156*9e054ec2SFabien DESSENNE 157*9e054ec2SFabien DESSENNE static inline bool is_des(struct stm32_cryp *cryp) 158*9e054ec2SFabien DESSENNE { 159*9e054ec2SFabien DESSENNE return cryp->flags & FLG_DES; 160*9e054ec2SFabien DESSENNE } 161*9e054ec2SFabien DESSENNE 162*9e054ec2SFabien DESSENNE static inline bool is_tdes(struct stm32_cryp *cryp) 163*9e054ec2SFabien DESSENNE { 164*9e054ec2SFabien DESSENNE return cryp->flags & FLG_TDES; 165*9e054ec2SFabien DESSENNE } 166*9e054ec2SFabien DESSENNE 167*9e054ec2SFabien DESSENNE static inline bool is_ecb(struct stm32_cryp *cryp) 168*9e054ec2SFabien DESSENNE { 169*9e054ec2SFabien DESSENNE return cryp->flags & FLG_ECB; 170*9e054ec2SFabien DESSENNE } 171*9e054ec2SFabien DESSENNE 172*9e054ec2SFabien DESSENNE static inline bool is_cbc(struct stm32_cryp *cryp) 173*9e054ec2SFabien DESSENNE { 174*9e054ec2SFabien DESSENNE return cryp->flags & FLG_CBC; 175*9e054ec2SFabien DESSENNE } 176*9e054ec2SFabien DESSENNE 177*9e054ec2SFabien DESSENNE static inline bool is_ctr(struct stm32_cryp *cryp) 178*9e054ec2SFabien DESSENNE { 179*9e054ec2SFabien DESSENNE return cryp->flags & FLG_CTR; 180*9e054ec2SFabien DESSENNE } 181*9e054ec2SFabien DESSENNE 182*9e054ec2SFabien DESSENNE static inline bool is_encrypt(struct stm32_cryp *cryp) 183*9e054ec2SFabien DESSENNE { 184*9e054ec2SFabien DESSENNE return cryp->flags & FLG_ENCRYPT; 185*9e054ec2SFabien DESSENNE } 186*9e054ec2SFabien DESSENNE 187*9e054ec2SFabien DESSENNE static inline bool is_decrypt(struct stm32_cryp *cryp) 188*9e054ec2SFabien DESSENNE { 189*9e054ec2SFabien DESSENNE return !is_encrypt(cryp); 190*9e054ec2SFabien DESSENNE } 191*9e054ec2SFabien DESSENNE 192*9e054ec2SFabien DESSENNE static inline u32 stm32_cryp_read(struct stm32_cryp *cryp, u32 ofst) 193*9e054ec2SFabien DESSENNE { 194*9e054ec2SFabien DESSENNE return readl_relaxed(cryp->regs + ofst); 195*9e054ec2SFabien DESSENNE } 196*9e054ec2SFabien DESSENNE 197*9e054ec2SFabien DESSENNE static inline void stm32_cryp_write(struct stm32_cryp *cryp, u32 ofst, u32 val) 198*9e054ec2SFabien DESSENNE { 199*9e054ec2SFabien DESSENNE writel_relaxed(val, cryp->regs + ofst); 200*9e054ec2SFabien DESSENNE } 201*9e054ec2SFabien DESSENNE 202*9e054ec2SFabien DESSENNE static inline int stm32_cryp_wait_busy(struct stm32_cryp *cryp) 203*9e054ec2SFabien DESSENNE { 204*9e054ec2SFabien DESSENNE u32 status; 205*9e054ec2SFabien DESSENNE 206*9e054ec2SFabien DESSENNE return readl_relaxed_poll_timeout(cryp->regs + CRYP_SR, status, 207*9e054ec2SFabien DESSENNE !(status & SR_BUSY), 10, 100000); 208*9e054ec2SFabien DESSENNE } 209*9e054ec2SFabien DESSENNE 210*9e054ec2SFabien DESSENNE static struct stm32_cryp *stm32_cryp_find_dev(struct stm32_cryp_ctx *ctx) 211*9e054ec2SFabien DESSENNE { 212*9e054ec2SFabien DESSENNE struct stm32_cryp *tmp, *cryp = NULL; 213*9e054ec2SFabien DESSENNE 214*9e054ec2SFabien DESSENNE spin_lock_bh(&cryp_list.lock); 215*9e054ec2SFabien DESSENNE if (!ctx->cryp) { 216*9e054ec2SFabien DESSENNE list_for_each_entry(tmp, &cryp_list.dev_list, list) { 217*9e054ec2SFabien DESSENNE cryp = tmp; 218*9e054ec2SFabien DESSENNE break; 219*9e054ec2SFabien DESSENNE } 220*9e054ec2SFabien DESSENNE ctx->cryp = cryp; 221*9e054ec2SFabien DESSENNE } else { 222*9e054ec2SFabien DESSENNE cryp = ctx->cryp; 223*9e054ec2SFabien DESSENNE } 224*9e054ec2SFabien DESSENNE 225*9e054ec2SFabien DESSENNE spin_unlock_bh(&cryp_list.lock); 226*9e054ec2SFabien DESSENNE 227*9e054ec2SFabien DESSENNE return cryp; 228*9e054ec2SFabien DESSENNE } 229*9e054ec2SFabien DESSENNE 230*9e054ec2SFabien DESSENNE static int stm32_cryp_check_aligned(struct scatterlist *sg, size_t total, 231*9e054ec2SFabien DESSENNE size_t align) 232*9e054ec2SFabien DESSENNE { 233*9e054ec2SFabien DESSENNE int len = 0; 234*9e054ec2SFabien DESSENNE 235*9e054ec2SFabien DESSENNE if (!total) 236*9e054ec2SFabien DESSENNE return 0; 237*9e054ec2SFabien DESSENNE 238*9e054ec2SFabien DESSENNE if (!IS_ALIGNED(total, align)) 239*9e054ec2SFabien DESSENNE return -EINVAL; 240*9e054ec2SFabien DESSENNE 241*9e054ec2SFabien DESSENNE while (sg) { 242*9e054ec2SFabien DESSENNE if (!IS_ALIGNED(sg->offset, sizeof(u32))) 243*9e054ec2SFabien DESSENNE return -EINVAL; 244*9e054ec2SFabien DESSENNE 245*9e054ec2SFabien DESSENNE if (!IS_ALIGNED(sg->length, align)) 246*9e054ec2SFabien DESSENNE return -EINVAL; 247*9e054ec2SFabien DESSENNE 248*9e054ec2SFabien DESSENNE len += sg->length; 249*9e054ec2SFabien DESSENNE sg = sg_next(sg); 250*9e054ec2SFabien DESSENNE } 251*9e054ec2SFabien DESSENNE 252*9e054ec2SFabien DESSENNE if (len != total) 253*9e054ec2SFabien DESSENNE return -EINVAL; 254*9e054ec2SFabien DESSENNE 255*9e054ec2SFabien DESSENNE return 0; 256*9e054ec2SFabien DESSENNE } 257*9e054ec2SFabien DESSENNE 258*9e054ec2SFabien DESSENNE static int stm32_cryp_check_io_aligned(struct stm32_cryp *cryp) 259*9e054ec2SFabien DESSENNE { 260*9e054ec2SFabien DESSENNE int ret; 261*9e054ec2SFabien DESSENNE 262*9e054ec2SFabien DESSENNE ret = stm32_cryp_check_aligned(cryp->in_sg, cryp->total_in, 263*9e054ec2SFabien DESSENNE cryp->hw_blocksize); 264*9e054ec2SFabien DESSENNE if (ret) 265*9e054ec2SFabien DESSENNE return ret; 266*9e054ec2SFabien DESSENNE 267*9e054ec2SFabien DESSENNE ret = stm32_cryp_check_aligned(cryp->out_sg, cryp->total_out, 268*9e054ec2SFabien DESSENNE cryp->hw_blocksize); 269*9e054ec2SFabien DESSENNE 270*9e054ec2SFabien DESSENNE return ret; 271*9e054ec2SFabien DESSENNE } 272*9e054ec2SFabien DESSENNE 273*9e054ec2SFabien DESSENNE static void sg_copy_buf(void *buf, struct scatterlist *sg, 274*9e054ec2SFabien DESSENNE unsigned int start, unsigned int nbytes, int out) 275*9e054ec2SFabien DESSENNE { 276*9e054ec2SFabien DESSENNE struct scatter_walk walk; 277*9e054ec2SFabien DESSENNE 278*9e054ec2SFabien DESSENNE if (!nbytes) 279*9e054ec2SFabien DESSENNE return; 280*9e054ec2SFabien DESSENNE 281*9e054ec2SFabien DESSENNE scatterwalk_start(&walk, sg); 282*9e054ec2SFabien DESSENNE scatterwalk_advance(&walk, start); 283*9e054ec2SFabien DESSENNE scatterwalk_copychunks(buf, &walk, nbytes, out); 284*9e054ec2SFabien DESSENNE scatterwalk_done(&walk, out, 0); 285*9e054ec2SFabien DESSENNE } 286*9e054ec2SFabien DESSENNE 287*9e054ec2SFabien DESSENNE static int stm32_cryp_copy_sgs(struct stm32_cryp *cryp) 288*9e054ec2SFabien DESSENNE { 289*9e054ec2SFabien DESSENNE void *buf_in, *buf_out; 290*9e054ec2SFabien DESSENNE int pages, total_in, total_out; 291*9e054ec2SFabien DESSENNE 292*9e054ec2SFabien DESSENNE if (!stm32_cryp_check_io_aligned(cryp)) { 293*9e054ec2SFabien DESSENNE cryp->sgs_copied = 0; 294*9e054ec2SFabien DESSENNE return 0; 295*9e054ec2SFabien DESSENNE } 296*9e054ec2SFabien DESSENNE 297*9e054ec2SFabien DESSENNE total_in = ALIGN(cryp->total_in, cryp->hw_blocksize); 298*9e054ec2SFabien DESSENNE pages = total_in ? get_order(total_in) : 1; 299*9e054ec2SFabien DESSENNE buf_in = (void *)__get_free_pages(GFP_ATOMIC, pages); 300*9e054ec2SFabien DESSENNE 301*9e054ec2SFabien DESSENNE total_out = ALIGN(cryp->total_out, cryp->hw_blocksize); 302*9e054ec2SFabien DESSENNE pages = total_out ? get_order(total_out) : 1; 303*9e054ec2SFabien DESSENNE buf_out = (void *)__get_free_pages(GFP_ATOMIC, pages); 304*9e054ec2SFabien DESSENNE 305*9e054ec2SFabien DESSENNE if (!buf_in || !buf_out) { 306*9e054ec2SFabien DESSENNE dev_err(cryp->dev, "Can't allocate pages when unaligned\n"); 307*9e054ec2SFabien DESSENNE cryp->sgs_copied = 0; 308*9e054ec2SFabien DESSENNE return -EFAULT; 309*9e054ec2SFabien DESSENNE } 310*9e054ec2SFabien DESSENNE 311*9e054ec2SFabien DESSENNE sg_copy_buf(buf_in, cryp->in_sg, 0, cryp->total_in, 0); 312*9e054ec2SFabien DESSENNE 313*9e054ec2SFabien DESSENNE sg_init_one(&cryp->in_sgl, buf_in, total_in); 314*9e054ec2SFabien DESSENNE cryp->in_sg = &cryp->in_sgl; 315*9e054ec2SFabien DESSENNE cryp->in_sg_len = 1; 316*9e054ec2SFabien DESSENNE 317*9e054ec2SFabien DESSENNE sg_init_one(&cryp->out_sgl, buf_out, total_out); 318*9e054ec2SFabien DESSENNE cryp->out_sg_save = cryp->out_sg; 319*9e054ec2SFabien DESSENNE cryp->out_sg = &cryp->out_sgl; 320*9e054ec2SFabien DESSENNE cryp->out_sg_len = 1; 321*9e054ec2SFabien DESSENNE 322*9e054ec2SFabien DESSENNE cryp->sgs_copied = 1; 323*9e054ec2SFabien DESSENNE 324*9e054ec2SFabien DESSENNE return 0; 325*9e054ec2SFabien DESSENNE } 326*9e054ec2SFabien DESSENNE 327*9e054ec2SFabien DESSENNE static void stm32_cryp_hw_write_iv(struct stm32_cryp *cryp, u32 *iv) 328*9e054ec2SFabien DESSENNE { 329*9e054ec2SFabien DESSENNE if (!iv) 330*9e054ec2SFabien DESSENNE return; 331*9e054ec2SFabien DESSENNE 332*9e054ec2SFabien DESSENNE stm32_cryp_write(cryp, CRYP_IV0LR, cpu_to_be32(*iv++)); 333*9e054ec2SFabien DESSENNE stm32_cryp_write(cryp, CRYP_IV0RR, cpu_to_be32(*iv++)); 334*9e054ec2SFabien DESSENNE 335*9e054ec2SFabien DESSENNE if (is_aes(cryp)) { 336*9e054ec2SFabien DESSENNE stm32_cryp_write(cryp, CRYP_IV1LR, cpu_to_be32(*iv++)); 337*9e054ec2SFabien DESSENNE stm32_cryp_write(cryp, CRYP_IV1RR, cpu_to_be32(*iv++)); 338*9e054ec2SFabien DESSENNE } 339*9e054ec2SFabien DESSENNE } 340*9e054ec2SFabien DESSENNE 341*9e054ec2SFabien DESSENNE static void stm32_cryp_hw_write_key(struct stm32_cryp *c) 342*9e054ec2SFabien DESSENNE { 343*9e054ec2SFabien DESSENNE unsigned int i; 344*9e054ec2SFabien DESSENNE int r_id; 345*9e054ec2SFabien DESSENNE 346*9e054ec2SFabien DESSENNE if (is_des(c)) { 347*9e054ec2SFabien DESSENNE stm32_cryp_write(c, CRYP_K1LR, cpu_to_be32(c->ctx->key[0])); 348*9e054ec2SFabien DESSENNE stm32_cryp_write(c, CRYP_K1RR, cpu_to_be32(c->ctx->key[1])); 349*9e054ec2SFabien DESSENNE } else { 350*9e054ec2SFabien DESSENNE r_id = CRYP_K3RR; 351*9e054ec2SFabien DESSENNE for (i = c->ctx->keylen / sizeof(u32); i > 0; i--, r_id -= 4) 352*9e054ec2SFabien DESSENNE stm32_cryp_write(c, r_id, 353*9e054ec2SFabien DESSENNE cpu_to_be32(c->ctx->key[i - 1])); 354*9e054ec2SFabien DESSENNE } 355*9e054ec2SFabien DESSENNE } 356*9e054ec2SFabien DESSENNE 357*9e054ec2SFabien DESSENNE static u32 stm32_cryp_get_hw_mode(struct stm32_cryp *cryp) 358*9e054ec2SFabien DESSENNE { 359*9e054ec2SFabien DESSENNE if (is_aes(cryp) && is_ecb(cryp)) 360*9e054ec2SFabien DESSENNE return CR_AES_ECB; 361*9e054ec2SFabien DESSENNE 362*9e054ec2SFabien DESSENNE if (is_aes(cryp) && is_cbc(cryp)) 363*9e054ec2SFabien DESSENNE return CR_AES_CBC; 364*9e054ec2SFabien DESSENNE 365*9e054ec2SFabien DESSENNE if (is_aes(cryp) && is_ctr(cryp)) 366*9e054ec2SFabien DESSENNE return CR_AES_CTR; 367*9e054ec2SFabien DESSENNE 368*9e054ec2SFabien DESSENNE if (is_des(cryp) && is_ecb(cryp)) 369*9e054ec2SFabien DESSENNE return CR_DES_ECB; 370*9e054ec2SFabien DESSENNE 371*9e054ec2SFabien DESSENNE if (is_des(cryp) && is_cbc(cryp)) 372*9e054ec2SFabien DESSENNE return CR_DES_CBC; 373*9e054ec2SFabien DESSENNE 374*9e054ec2SFabien DESSENNE if (is_tdes(cryp) && is_ecb(cryp)) 375*9e054ec2SFabien DESSENNE return CR_TDES_ECB; 376*9e054ec2SFabien DESSENNE 377*9e054ec2SFabien DESSENNE if (is_tdes(cryp) && is_cbc(cryp)) 378*9e054ec2SFabien DESSENNE return CR_TDES_CBC; 379*9e054ec2SFabien DESSENNE 380*9e054ec2SFabien DESSENNE dev_err(cryp->dev, "Unknown mode\n"); 381*9e054ec2SFabien DESSENNE return CR_AES_UNKNOWN; 382*9e054ec2SFabien DESSENNE } 383*9e054ec2SFabien DESSENNE 384*9e054ec2SFabien DESSENNE static int stm32_cryp_hw_init(struct stm32_cryp *cryp) 385*9e054ec2SFabien DESSENNE { 386*9e054ec2SFabien DESSENNE int ret; 387*9e054ec2SFabien DESSENNE u32 cfg, hw_mode; 388*9e054ec2SFabien DESSENNE 389*9e054ec2SFabien DESSENNE /* Disable interrupt */ 390*9e054ec2SFabien DESSENNE stm32_cryp_write(cryp, CRYP_IMSCR, 0); 391*9e054ec2SFabien DESSENNE 392*9e054ec2SFabien DESSENNE /* Set key */ 393*9e054ec2SFabien DESSENNE stm32_cryp_hw_write_key(cryp); 394*9e054ec2SFabien DESSENNE 395*9e054ec2SFabien DESSENNE /* Set configuration */ 396*9e054ec2SFabien DESSENNE cfg = CR_DATA8 | CR_FFLUSH; 397*9e054ec2SFabien DESSENNE 398*9e054ec2SFabien DESSENNE switch (cryp->ctx->keylen) { 399*9e054ec2SFabien DESSENNE case AES_KEYSIZE_128: 400*9e054ec2SFabien DESSENNE cfg |= CR_KEY128; 401*9e054ec2SFabien DESSENNE break; 402*9e054ec2SFabien DESSENNE 403*9e054ec2SFabien DESSENNE case AES_KEYSIZE_192: 404*9e054ec2SFabien DESSENNE cfg |= CR_KEY192; 405*9e054ec2SFabien DESSENNE break; 406*9e054ec2SFabien DESSENNE 407*9e054ec2SFabien DESSENNE default: 408*9e054ec2SFabien DESSENNE case AES_KEYSIZE_256: 409*9e054ec2SFabien DESSENNE cfg |= CR_KEY256; 410*9e054ec2SFabien DESSENNE break; 411*9e054ec2SFabien DESSENNE } 412*9e054ec2SFabien DESSENNE 413*9e054ec2SFabien DESSENNE hw_mode = stm32_cryp_get_hw_mode(cryp); 414*9e054ec2SFabien DESSENNE if (hw_mode == CR_AES_UNKNOWN) 415*9e054ec2SFabien DESSENNE return -EINVAL; 416*9e054ec2SFabien DESSENNE 417*9e054ec2SFabien DESSENNE /* AES ECB/CBC decrypt: run key preparation first */ 418*9e054ec2SFabien DESSENNE if (is_decrypt(cryp) && 419*9e054ec2SFabien DESSENNE ((hw_mode == CR_AES_ECB) || (hw_mode == CR_AES_CBC))) { 420*9e054ec2SFabien DESSENNE stm32_cryp_write(cryp, CRYP_CR, cfg | CR_AES_KP | CR_CRYPEN); 421*9e054ec2SFabien DESSENNE 422*9e054ec2SFabien DESSENNE /* Wait for end of processing */ 423*9e054ec2SFabien DESSENNE ret = stm32_cryp_wait_busy(cryp); 424*9e054ec2SFabien DESSENNE if (ret) { 425*9e054ec2SFabien DESSENNE dev_err(cryp->dev, "Timeout (key preparation)\n"); 426*9e054ec2SFabien DESSENNE return ret; 427*9e054ec2SFabien DESSENNE } 428*9e054ec2SFabien DESSENNE } 429*9e054ec2SFabien DESSENNE 430*9e054ec2SFabien DESSENNE cfg |= hw_mode; 431*9e054ec2SFabien DESSENNE 432*9e054ec2SFabien DESSENNE if (is_decrypt(cryp)) 433*9e054ec2SFabien DESSENNE cfg |= CR_DEC_NOT_ENC; 434*9e054ec2SFabien DESSENNE 435*9e054ec2SFabien DESSENNE /* Apply config and flush (valid when CRYPEN = 0) */ 436*9e054ec2SFabien DESSENNE stm32_cryp_write(cryp, CRYP_CR, cfg); 437*9e054ec2SFabien DESSENNE 438*9e054ec2SFabien DESSENNE switch (hw_mode) { 439*9e054ec2SFabien DESSENNE case CR_DES_CBC: 440*9e054ec2SFabien DESSENNE case CR_TDES_CBC: 441*9e054ec2SFabien DESSENNE case CR_AES_CBC: 442*9e054ec2SFabien DESSENNE case CR_AES_CTR: 443*9e054ec2SFabien DESSENNE stm32_cryp_hw_write_iv(cryp, (u32 *)cryp->req->info); 444*9e054ec2SFabien DESSENNE break; 445*9e054ec2SFabien DESSENNE 446*9e054ec2SFabien DESSENNE default: 447*9e054ec2SFabien DESSENNE break; 448*9e054ec2SFabien DESSENNE } 449*9e054ec2SFabien DESSENNE 450*9e054ec2SFabien DESSENNE /* Enable now */ 451*9e054ec2SFabien DESSENNE cfg |= CR_CRYPEN; 452*9e054ec2SFabien DESSENNE 453*9e054ec2SFabien DESSENNE stm32_cryp_write(cryp, CRYP_CR, cfg); 454*9e054ec2SFabien DESSENNE 455*9e054ec2SFabien DESSENNE return 0; 456*9e054ec2SFabien DESSENNE } 457*9e054ec2SFabien DESSENNE 458*9e054ec2SFabien DESSENNE static void stm32_cryp_finish_req(struct stm32_cryp *cryp) 459*9e054ec2SFabien DESSENNE { 460*9e054ec2SFabien DESSENNE int err = 0; 461*9e054ec2SFabien DESSENNE 462*9e054ec2SFabien DESSENNE if (cryp->sgs_copied) { 463*9e054ec2SFabien DESSENNE void *buf_in, *buf_out; 464*9e054ec2SFabien DESSENNE int pages, len; 465*9e054ec2SFabien DESSENNE 466*9e054ec2SFabien DESSENNE buf_in = sg_virt(&cryp->in_sgl); 467*9e054ec2SFabien DESSENNE buf_out = sg_virt(&cryp->out_sgl); 468*9e054ec2SFabien DESSENNE 469*9e054ec2SFabien DESSENNE sg_copy_buf(buf_out, cryp->out_sg_save, 0, 470*9e054ec2SFabien DESSENNE cryp->total_out_save, 1); 471*9e054ec2SFabien DESSENNE 472*9e054ec2SFabien DESSENNE len = ALIGN(cryp->total_in_save, cryp->hw_blocksize); 473*9e054ec2SFabien DESSENNE pages = len ? get_order(len) : 1; 474*9e054ec2SFabien DESSENNE free_pages((unsigned long)buf_in, pages); 475*9e054ec2SFabien DESSENNE 476*9e054ec2SFabien DESSENNE len = ALIGN(cryp->total_out_save, cryp->hw_blocksize); 477*9e054ec2SFabien DESSENNE pages = len ? get_order(len) : 1; 478*9e054ec2SFabien DESSENNE free_pages((unsigned long)buf_out, pages); 479*9e054ec2SFabien DESSENNE } 480*9e054ec2SFabien DESSENNE 481*9e054ec2SFabien DESSENNE crypto_finalize_cipher_request(cryp->engine, cryp->req, err); 482*9e054ec2SFabien DESSENNE cryp->req = NULL; 483*9e054ec2SFabien DESSENNE 484*9e054ec2SFabien DESSENNE memset(cryp->ctx->key, 0, cryp->ctx->keylen); 485*9e054ec2SFabien DESSENNE 486*9e054ec2SFabien DESSENNE mutex_unlock(&cryp->lock); 487*9e054ec2SFabien DESSENNE } 488*9e054ec2SFabien DESSENNE 489*9e054ec2SFabien DESSENNE static int stm32_cryp_cpu_start(struct stm32_cryp *cryp) 490*9e054ec2SFabien DESSENNE { 491*9e054ec2SFabien DESSENNE /* Enable interrupt and let the IRQ handler do everything */ 492*9e054ec2SFabien DESSENNE stm32_cryp_write(cryp, CRYP_IMSCR, IMSCR_IN | IMSCR_OUT); 493*9e054ec2SFabien DESSENNE 494*9e054ec2SFabien DESSENNE return 0; 495*9e054ec2SFabien DESSENNE } 496*9e054ec2SFabien DESSENNE 497*9e054ec2SFabien DESSENNE static int stm32_cryp_cra_init(struct crypto_tfm *tfm) 498*9e054ec2SFabien DESSENNE { 499*9e054ec2SFabien DESSENNE tfm->crt_ablkcipher.reqsize = sizeof(struct stm32_cryp_reqctx); 500*9e054ec2SFabien DESSENNE 501*9e054ec2SFabien DESSENNE return 0; 502*9e054ec2SFabien DESSENNE } 503*9e054ec2SFabien DESSENNE 504*9e054ec2SFabien DESSENNE static int stm32_cryp_crypt(struct ablkcipher_request *req, unsigned long mode) 505*9e054ec2SFabien DESSENNE { 506*9e054ec2SFabien DESSENNE struct stm32_cryp_ctx *ctx = crypto_ablkcipher_ctx( 507*9e054ec2SFabien DESSENNE crypto_ablkcipher_reqtfm(req)); 508*9e054ec2SFabien DESSENNE struct stm32_cryp_reqctx *rctx = ablkcipher_request_ctx(req); 509*9e054ec2SFabien DESSENNE struct stm32_cryp *cryp = stm32_cryp_find_dev(ctx); 510*9e054ec2SFabien DESSENNE 511*9e054ec2SFabien DESSENNE if (!cryp) 512*9e054ec2SFabien DESSENNE return -ENODEV; 513*9e054ec2SFabien DESSENNE 514*9e054ec2SFabien DESSENNE rctx->mode = mode; 515*9e054ec2SFabien DESSENNE 516*9e054ec2SFabien DESSENNE return crypto_transfer_cipher_request_to_engine(cryp->engine, req); 517*9e054ec2SFabien DESSENNE } 518*9e054ec2SFabien DESSENNE 519*9e054ec2SFabien DESSENNE static int stm32_cryp_setkey(struct crypto_ablkcipher *tfm, const u8 *key, 520*9e054ec2SFabien DESSENNE unsigned int keylen) 521*9e054ec2SFabien DESSENNE { 522*9e054ec2SFabien DESSENNE struct stm32_cryp_ctx *ctx = crypto_ablkcipher_ctx(tfm); 523*9e054ec2SFabien DESSENNE 524*9e054ec2SFabien DESSENNE memcpy(ctx->key, key, keylen); 525*9e054ec2SFabien DESSENNE ctx->keylen = keylen; 526*9e054ec2SFabien DESSENNE 527*9e054ec2SFabien DESSENNE return 0; 528*9e054ec2SFabien DESSENNE } 529*9e054ec2SFabien DESSENNE 530*9e054ec2SFabien DESSENNE static int stm32_cryp_aes_setkey(struct crypto_ablkcipher *tfm, const u8 *key, 531*9e054ec2SFabien DESSENNE unsigned int keylen) 532*9e054ec2SFabien DESSENNE { 533*9e054ec2SFabien DESSENNE if (keylen != AES_KEYSIZE_128 && keylen != AES_KEYSIZE_192 && 534*9e054ec2SFabien DESSENNE keylen != AES_KEYSIZE_256) 535*9e054ec2SFabien DESSENNE return -EINVAL; 536*9e054ec2SFabien DESSENNE else 537*9e054ec2SFabien DESSENNE return stm32_cryp_setkey(tfm, key, keylen); 538*9e054ec2SFabien DESSENNE } 539*9e054ec2SFabien DESSENNE 540*9e054ec2SFabien DESSENNE static int stm32_cryp_des_setkey(struct crypto_ablkcipher *tfm, const u8 *key, 541*9e054ec2SFabien DESSENNE unsigned int keylen) 542*9e054ec2SFabien DESSENNE { 543*9e054ec2SFabien DESSENNE if (keylen != DES_KEY_SIZE) 544*9e054ec2SFabien DESSENNE return -EINVAL; 545*9e054ec2SFabien DESSENNE else 546*9e054ec2SFabien DESSENNE return stm32_cryp_setkey(tfm, key, keylen); 547*9e054ec2SFabien DESSENNE } 548*9e054ec2SFabien DESSENNE 549*9e054ec2SFabien DESSENNE static int stm32_cryp_tdes_setkey(struct crypto_ablkcipher *tfm, const u8 *key, 550*9e054ec2SFabien DESSENNE unsigned int keylen) 551*9e054ec2SFabien DESSENNE { 552*9e054ec2SFabien DESSENNE if (keylen != (3 * DES_KEY_SIZE)) 553*9e054ec2SFabien DESSENNE return -EINVAL; 554*9e054ec2SFabien DESSENNE else 555*9e054ec2SFabien DESSENNE return stm32_cryp_setkey(tfm, key, keylen); 556*9e054ec2SFabien DESSENNE } 557*9e054ec2SFabien DESSENNE 558*9e054ec2SFabien DESSENNE static int stm32_cryp_aes_ecb_encrypt(struct ablkcipher_request *req) 559*9e054ec2SFabien DESSENNE { 560*9e054ec2SFabien DESSENNE return stm32_cryp_crypt(req, FLG_AES | FLG_ECB | FLG_ENCRYPT); 561*9e054ec2SFabien DESSENNE } 562*9e054ec2SFabien DESSENNE 563*9e054ec2SFabien DESSENNE static int stm32_cryp_aes_ecb_decrypt(struct ablkcipher_request *req) 564*9e054ec2SFabien DESSENNE { 565*9e054ec2SFabien DESSENNE return stm32_cryp_crypt(req, FLG_AES | FLG_ECB); 566*9e054ec2SFabien DESSENNE } 567*9e054ec2SFabien DESSENNE 568*9e054ec2SFabien DESSENNE static int stm32_cryp_aes_cbc_encrypt(struct ablkcipher_request *req) 569*9e054ec2SFabien DESSENNE { 570*9e054ec2SFabien DESSENNE return stm32_cryp_crypt(req, FLG_AES | FLG_CBC | FLG_ENCRYPT); 571*9e054ec2SFabien DESSENNE } 572*9e054ec2SFabien DESSENNE 573*9e054ec2SFabien DESSENNE static int stm32_cryp_aes_cbc_decrypt(struct ablkcipher_request *req) 574*9e054ec2SFabien DESSENNE { 575*9e054ec2SFabien DESSENNE return stm32_cryp_crypt(req, FLG_AES | FLG_CBC); 576*9e054ec2SFabien DESSENNE } 577*9e054ec2SFabien DESSENNE 578*9e054ec2SFabien DESSENNE static int stm32_cryp_aes_ctr_encrypt(struct ablkcipher_request *req) 579*9e054ec2SFabien DESSENNE { 580*9e054ec2SFabien DESSENNE return stm32_cryp_crypt(req, FLG_AES | FLG_CTR | FLG_ENCRYPT); 581*9e054ec2SFabien DESSENNE } 582*9e054ec2SFabien DESSENNE 583*9e054ec2SFabien DESSENNE static int stm32_cryp_aes_ctr_decrypt(struct ablkcipher_request *req) 584*9e054ec2SFabien DESSENNE { 585*9e054ec2SFabien DESSENNE return stm32_cryp_crypt(req, FLG_AES | FLG_CTR); 586*9e054ec2SFabien DESSENNE } 587*9e054ec2SFabien DESSENNE 588*9e054ec2SFabien DESSENNE static int stm32_cryp_des_ecb_encrypt(struct ablkcipher_request *req) 589*9e054ec2SFabien DESSENNE { 590*9e054ec2SFabien DESSENNE return stm32_cryp_crypt(req, FLG_DES | FLG_ECB | FLG_ENCRYPT); 591*9e054ec2SFabien DESSENNE } 592*9e054ec2SFabien DESSENNE 593*9e054ec2SFabien DESSENNE static int stm32_cryp_des_ecb_decrypt(struct ablkcipher_request *req) 594*9e054ec2SFabien DESSENNE { 595*9e054ec2SFabien DESSENNE return stm32_cryp_crypt(req, FLG_DES | FLG_ECB); 596*9e054ec2SFabien DESSENNE } 597*9e054ec2SFabien DESSENNE 598*9e054ec2SFabien DESSENNE static int stm32_cryp_des_cbc_encrypt(struct ablkcipher_request *req) 599*9e054ec2SFabien DESSENNE { 600*9e054ec2SFabien DESSENNE return stm32_cryp_crypt(req, FLG_DES | FLG_CBC | FLG_ENCRYPT); 601*9e054ec2SFabien DESSENNE } 602*9e054ec2SFabien DESSENNE 603*9e054ec2SFabien DESSENNE static int stm32_cryp_des_cbc_decrypt(struct ablkcipher_request *req) 604*9e054ec2SFabien DESSENNE { 605*9e054ec2SFabien DESSENNE return stm32_cryp_crypt(req, FLG_DES | FLG_CBC); 606*9e054ec2SFabien DESSENNE } 607*9e054ec2SFabien DESSENNE 608*9e054ec2SFabien DESSENNE static int stm32_cryp_tdes_ecb_encrypt(struct ablkcipher_request *req) 609*9e054ec2SFabien DESSENNE { 610*9e054ec2SFabien DESSENNE return stm32_cryp_crypt(req, FLG_TDES | FLG_ECB | FLG_ENCRYPT); 611*9e054ec2SFabien DESSENNE } 612*9e054ec2SFabien DESSENNE 613*9e054ec2SFabien DESSENNE static int stm32_cryp_tdes_ecb_decrypt(struct ablkcipher_request *req) 614*9e054ec2SFabien DESSENNE { 615*9e054ec2SFabien DESSENNE return stm32_cryp_crypt(req, FLG_TDES | FLG_ECB); 616*9e054ec2SFabien DESSENNE } 617*9e054ec2SFabien DESSENNE 618*9e054ec2SFabien DESSENNE static int stm32_cryp_tdes_cbc_encrypt(struct ablkcipher_request *req) 619*9e054ec2SFabien DESSENNE { 620*9e054ec2SFabien DESSENNE return stm32_cryp_crypt(req, FLG_TDES | FLG_CBC | FLG_ENCRYPT); 621*9e054ec2SFabien DESSENNE } 622*9e054ec2SFabien DESSENNE 623*9e054ec2SFabien DESSENNE static int stm32_cryp_tdes_cbc_decrypt(struct ablkcipher_request *req) 624*9e054ec2SFabien DESSENNE { 625*9e054ec2SFabien DESSENNE return stm32_cryp_crypt(req, FLG_TDES | FLG_CBC); 626*9e054ec2SFabien DESSENNE } 627*9e054ec2SFabien DESSENNE 628*9e054ec2SFabien DESSENNE static int stm32_cryp_prepare_req(struct crypto_engine *engine, 629*9e054ec2SFabien DESSENNE struct ablkcipher_request *req) 630*9e054ec2SFabien DESSENNE { 631*9e054ec2SFabien DESSENNE struct stm32_cryp_ctx *ctx; 632*9e054ec2SFabien DESSENNE struct stm32_cryp *cryp; 633*9e054ec2SFabien DESSENNE struct stm32_cryp_reqctx *rctx; 634*9e054ec2SFabien DESSENNE int ret; 635*9e054ec2SFabien DESSENNE 636*9e054ec2SFabien DESSENNE if (!req) 637*9e054ec2SFabien DESSENNE return -EINVAL; 638*9e054ec2SFabien DESSENNE 639*9e054ec2SFabien DESSENNE ctx = crypto_ablkcipher_ctx(crypto_ablkcipher_reqtfm(req)); 640*9e054ec2SFabien DESSENNE 641*9e054ec2SFabien DESSENNE cryp = ctx->cryp; 642*9e054ec2SFabien DESSENNE 643*9e054ec2SFabien DESSENNE if (!cryp) 644*9e054ec2SFabien DESSENNE return -ENODEV; 645*9e054ec2SFabien DESSENNE 646*9e054ec2SFabien DESSENNE mutex_lock(&cryp->lock); 647*9e054ec2SFabien DESSENNE 648*9e054ec2SFabien DESSENNE rctx = ablkcipher_request_ctx(req); 649*9e054ec2SFabien DESSENNE rctx->mode &= FLG_MODE_MASK; 650*9e054ec2SFabien DESSENNE 651*9e054ec2SFabien DESSENNE ctx->cryp = cryp; 652*9e054ec2SFabien DESSENNE 653*9e054ec2SFabien DESSENNE cryp->flags = (cryp->flags & ~FLG_MODE_MASK) | rctx->mode; 654*9e054ec2SFabien DESSENNE cryp->hw_blocksize = is_aes(cryp) ? AES_BLOCK_SIZE : DES_BLOCK_SIZE; 655*9e054ec2SFabien DESSENNE cryp->ctx = ctx; 656*9e054ec2SFabien DESSENNE 657*9e054ec2SFabien DESSENNE cryp->req = req; 658*9e054ec2SFabien DESSENNE cryp->total_in = req->nbytes; 659*9e054ec2SFabien DESSENNE cryp->total_out = cryp->total_in; 660*9e054ec2SFabien DESSENNE 661*9e054ec2SFabien DESSENNE cryp->total_in_save = cryp->total_in; 662*9e054ec2SFabien DESSENNE cryp->total_out_save = cryp->total_out; 663*9e054ec2SFabien DESSENNE 664*9e054ec2SFabien DESSENNE cryp->in_sg = req->src; 665*9e054ec2SFabien DESSENNE cryp->out_sg = req->dst; 666*9e054ec2SFabien DESSENNE cryp->out_sg_save = cryp->out_sg; 667*9e054ec2SFabien DESSENNE 668*9e054ec2SFabien DESSENNE cryp->in_sg_len = sg_nents_for_len(cryp->in_sg, cryp->total_in); 669*9e054ec2SFabien DESSENNE if (cryp->in_sg_len < 0) { 670*9e054ec2SFabien DESSENNE dev_err(cryp->dev, "Cannot get in_sg_len\n"); 671*9e054ec2SFabien DESSENNE ret = cryp->in_sg_len; 672*9e054ec2SFabien DESSENNE goto out; 673*9e054ec2SFabien DESSENNE } 674*9e054ec2SFabien DESSENNE 675*9e054ec2SFabien DESSENNE cryp->out_sg_len = sg_nents_for_len(cryp->out_sg, cryp->total_out); 676*9e054ec2SFabien DESSENNE if (cryp->out_sg_len < 0) { 677*9e054ec2SFabien DESSENNE dev_err(cryp->dev, "Cannot get out_sg_len\n"); 678*9e054ec2SFabien DESSENNE ret = cryp->out_sg_len; 679*9e054ec2SFabien DESSENNE goto out; 680*9e054ec2SFabien DESSENNE } 681*9e054ec2SFabien DESSENNE 682*9e054ec2SFabien DESSENNE ret = stm32_cryp_copy_sgs(cryp); 683*9e054ec2SFabien DESSENNE if (ret) 684*9e054ec2SFabien DESSENNE goto out; 685*9e054ec2SFabien DESSENNE 686*9e054ec2SFabien DESSENNE scatterwalk_start(&cryp->in_walk, cryp->in_sg); 687*9e054ec2SFabien DESSENNE scatterwalk_start(&cryp->out_walk, cryp->out_sg); 688*9e054ec2SFabien DESSENNE 689*9e054ec2SFabien DESSENNE ret = stm32_cryp_hw_init(cryp); 690*9e054ec2SFabien DESSENNE out: 691*9e054ec2SFabien DESSENNE if (ret) 692*9e054ec2SFabien DESSENNE mutex_unlock(&cryp->lock); 693*9e054ec2SFabien DESSENNE 694*9e054ec2SFabien DESSENNE return ret; 695*9e054ec2SFabien DESSENNE } 696*9e054ec2SFabien DESSENNE 697*9e054ec2SFabien DESSENNE static int stm32_cryp_prepare_cipher_req(struct crypto_engine *engine, 698*9e054ec2SFabien DESSENNE struct ablkcipher_request *req) 699*9e054ec2SFabien DESSENNE { 700*9e054ec2SFabien DESSENNE return stm32_cryp_prepare_req(engine, req); 701*9e054ec2SFabien DESSENNE } 702*9e054ec2SFabien DESSENNE 703*9e054ec2SFabien DESSENNE static int stm32_cryp_cipher_one_req(struct crypto_engine *engine, 704*9e054ec2SFabien DESSENNE struct ablkcipher_request *req) 705*9e054ec2SFabien DESSENNE { 706*9e054ec2SFabien DESSENNE struct stm32_cryp_ctx *ctx = crypto_ablkcipher_ctx( 707*9e054ec2SFabien DESSENNE crypto_ablkcipher_reqtfm(req)); 708*9e054ec2SFabien DESSENNE struct stm32_cryp *cryp = ctx->cryp; 709*9e054ec2SFabien DESSENNE 710*9e054ec2SFabien DESSENNE if (!cryp) 711*9e054ec2SFabien DESSENNE return -ENODEV; 712*9e054ec2SFabien DESSENNE 713*9e054ec2SFabien DESSENNE return stm32_cryp_cpu_start(cryp); 714*9e054ec2SFabien DESSENNE } 715*9e054ec2SFabien DESSENNE 716*9e054ec2SFabien DESSENNE static u32 *stm32_cryp_next_out(struct stm32_cryp *cryp, u32 *dst, 717*9e054ec2SFabien DESSENNE unsigned int n) 718*9e054ec2SFabien DESSENNE { 719*9e054ec2SFabien DESSENNE scatterwalk_advance(&cryp->out_walk, n); 720*9e054ec2SFabien DESSENNE 721*9e054ec2SFabien DESSENNE if (unlikely(cryp->out_sg->length == _walked_out)) { 722*9e054ec2SFabien DESSENNE cryp->out_sg = sg_next(cryp->out_sg); 723*9e054ec2SFabien DESSENNE if (cryp->out_sg) { 724*9e054ec2SFabien DESSENNE scatterwalk_start(&cryp->out_walk, cryp->out_sg); 725*9e054ec2SFabien DESSENNE return (sg_virt(cryp->out_sg) + _walked_out); 726*9e054ec2SFabien DESSENNE } 727*9e054ec2SFabien DESSENNE } 728*9e054ec2SFabien DESSENNE 729*9e054ec2SFabien DESSENNE return (u32 *)((u8 *)dst + n); 730*9e054ec2SFabien DESSENNE } 731*9e054ec2SFabien DESSENNE 732*9e054ec2SFabien DESSENNE static u32 *stm32_cryp_next_in(struct stm32_cryp *cryp, u32 *src, 733*9e054ec2SFabien DESSENNE unsigned int n) 734*9e054ec2SFabien DESSENNE { 735*9e054ec2SFabien DESSENNE scatterwalk_advance(&cryp->in_walk, n); 736*9e054ec2SFabien DESSENNE 737*9e054ec2SFabien DESSENNE if (unlikely(cryp->in_sg->length == _walked_in)) { 738*9e054ec2SFabien DESSENNE cryp->in_sg = sg_next(cryp->in_sg); 739*9e054ec2SFabien DESSENNE if (cryp->in_sg) { 740*9e054ec2SFabien DESSENNE scatterwalk_start(&cryp->in_walk, cryp->in_sg); 741*9e054ec2SFabien DESSENNE return (sg_virt(cryp->in_sg) + _walked_in); 742*9e054ec2SFabien DESSENNE } 743*9e054ec2SFabien DESSENNE } 744*9e054ec2SFabien DESSENNE 745*9e054ec2SFabien DESSENNE return (u32 *)((u8 *)src + n); 746*9e054ec2SFabien DESSENNE } 747*9e054ec2SFabien DESSENNE 748*9e054ec2SFabien DESSENNE static void stm32_cryp_check_ctr_counter(struct stm32_cryp *cryp) 749*9e054ec2SFabien DESSENNE { 750*9e054ec2SFabien DESSENNE u32 cr; 751*9e054ec2SFabien DESSENNE 752*9e054ec2SFabien DESSENNE if (unlikely(cryp->last_ctr[3] == 0xFFFFFFFF)) { 753*9e054ec2SFabien DESSENNE cryp->last_ctr[3] = 0; 754*9e054ec2SFabien DESSENNE cryp->last_ctr[2]++; 755*9e054ec2SFabien DESSENNE if (!cryp->last_ctr[2]) { 756*9e054ec2SFabien DESSENNE cryp->last_ctr[1]++; 757*9e054ec2SFabien DESSENNE if (!cryp->last_ctr[1]) 758*9e054ec2SFabien DESSENNE cryp->last_ctr[0]++; 759*9e054ec2SFabien DESSENNE } 760*9e054ec2SFabien DESSENNE 761*9e054ec2SFabien DESSENNE cr = stm32_cryp_read(cryp, CRYP_CR); 762*9e054ec2SFabien DESSENNE stm32_cryp_write(cryp, CRYP_CR, cr & ~CR_CRYPEN); 763*9e054ec2SFabien DESSENNE 764*9e054ec2SFabien DESSENNE stm32_cryp_hw_write_iv(cryp, (u32 *)cryp->last_ctr); 765*9e054ec2SFabien DESSENNE 766*9e054ec2SFabien DESSENNE stm32_cryp_write(cryp, CRYP_CR, cr); 767*9e054ec2SFabien DESSENNE } 768*9e054ec2SFabien DESSENNE 769*9e054ec2SFabien DESSENNE cryp->last_ctr[0] = stm32_cryp_read(cryp, CRYP_IV0LR); 770*9e054ec2SFabien DESSENNE cryp->last_ctr[1] = stm32_cryp_read(cryp, CRYP_IV0RR); 771*9e054ec2SFabien DESSENNE cryp->last_ctr[2] = stm32_cryp_read(cryp, CRYP_IV1LR); 772*9e054ec2SFabien DESSENNE cryp->last_ctr[3] = stm32_cryp_read(cryp, CRYP_IV1RR); 773*9e054ec2SFabien DESSENNE } 774*9e054ec2SFabien DESSENNE 775*9e054ec2SFabien DESSENNE static bool stm32_cryp_irq_read_data(struct stm32_cryp *cryp) 776*9e054ec2SFabien DESSENNE { 777*9e054ec2SFabien DESSENNE unsigned int i, j; 778*9e054ec2SFabien DESSENNE u32 d32, *dst; 779*9e054ec2SFabien DESSENNE u8 *d8; 780*9e054ec2SFabien DESSENNE 781*9e054ec2SFabien DESSENNE dst = sg_virt(cryp->out_sg) + _walked_out; 782*9e054ec2SFabien DESSENNE 783*9e054ec2SFabien DESSENNE for (i = 0; i < cryp->hw_blocksize / sizeof(u32); i++) { 784*9e054ec2SFabien DESSENNE if (likely(cryp->total_out >= sizeof(u32))) { 785*9e054ec2SFabien DESSENNE /* Read a full u32 */ 786*9e054ec2SFabien DESSENNE *dst = stm32_cryp_read(cryp, CRYP_DOUT); 787*9e054ec2SFabien DESSENNE 788*9e054ec2SFabien DESSENNE dst = stm32_cryp_next_out(cryp, dst, sizeof(u32)); 789*9e054ec2SFabien DESSENNE cryp->total_out -= sizeof(u32); 790*9e054ec2SFabien DESSENNE } else if (!cryp->total_out) { 791*9e054ec2SFabien DESSENNE /* Empty fifo out (data from input padding) */ 792*9e054ec2SFabien DESSENNE d32 = stm32_cryp_read(cryp, CRYP_DOUT); 793*9e054ec2SFabien DESSENNE } else { 794*9e054ec2SFabien DESSENNE /* Read less than an u32 */ 795*9e054ec2SFabien DESSENNE d32 = stm32_cryp_read(cryp, CRYP_DOUT); 796*9e054ec2SFabien DESSENNE d8 = (u8 *)&d32; 797*9e054ec2SFabien DESSENNE 798*9e054ec2SFabien DESSENNE for (j = 0; j < cryp->total_out; j++) { 799*9e054ec2SFabien DESSENNE *((u8 *)dst) = *(d8++); 800*9e054ec2SFabien DESSENNE dst = stm32_cryp_next_out(cryp, dst, 1); 801*9e054ec2SFabien DESSENNE } 802*9e054ec2SFabien DESSENNE cryp->total_out = 0; 803*9e054ec2SFabien DESSENNE } 804*9e054ec2SFabien DESSENNE } 805*9e054ec2SFabien DESSENNE 806*9e054ec2SFabien DESSENNE return !cryp->total_out || !cryp->total_in; 807*9e054ec2SFabien DESSENNE } 808*9e054ec2SFabien DESSENNE 809*9e054ec2SFabien DESSENNE static void stm32_cryp_irq_write_block(struct stm32_cryp *cryp) 810*9e054ec2SFabien DESSENNE { 811*9e054ec2SFabien DESSENNE unsigned int i, j; 812*9e054ec2SFabien DESSENNE u32 *src; 813*9e054ec2SFabien DESSENNE u8 d8[4]; 814*9e054ec2SFabien DESSENNE 815*9e054ec2SFabien DESSENNE src = sg_virt(cryp->in_sg) + _walked_in; 816*9e054ec2SFabien DESSENNE 817*9e054ec2SFabien DESSENNE for (i = 0; i < cryp->hw_blocksize / sizeof(u32); i++) { 818*9e054ec2SFabien DESSENNE if (likely(cryp->total_in >= sizeof(u32))) { 819*9e054ec2SFabien DESSENNE /* Write a full u32 */ 820*9e054ec2SFabien DESSENNE stm32_cryp_write(cryp, CRYP_DIN, *src); 821*9e054ec2SFabien DESSENNE 822*9e054ec2SFabien DESSENNE src = stm32_cryp_next_in(cryp, src, sizeof(u32)); 823*9e054ec2SFabien DESSENNE cryp->total_in -= sizeof(u32); 824*9e054ec2SFabien DESSENNE } else if (!cryp->total_in) { 825*9e054ec2SFabien DESSENNE /* Write padding data */ 826*9e054ec2SFabien DESSENNE stm32_cryp_write(cryp, CRYP_DIN, 0); 827*9e054ec2SFabien DESSENNE } else { 828*9e054ec2SFabien DESSENNE /* Write less than an u32 */ 829*9e054ec2SFabien DESSENNE memset(d8, 0, sizeof(u32)); 830*9e054ec2SFabien DESSENNE for (j = 0; j < cryp->total_in; j++) { 831*9e054ec2SFabien DESSENNE d8[j] = *((u8 *)src); 832*9e054ec2SFabien DESSENNE src = stm32_cryp_next_in(cryp, src, 1); 833*9e054ec2SFabien DESSENNE } 834*9e054ec2SFabien DESSENNE 835*9e054ec2SFabien DESSENNE stm32_cryp_write(cryp, CRYP_DIN, *(u32 *)d8); 836*9e054ec2SFabien DESSENNE cryp->total_in = 0; 837*9e054ec2SFabien DESSENNE } 838*9e054ec2SFabien DESSENNE } 839*9e054ec2SFabien DESSENNE } 840*9e054ec2SFabien DESSENNE 841*9e054ec2SFabien DESSENNE static void stm32_cryp_irq_write_data(struct stm32_cryp *cryp) 842*9e054ec2SFabien DESSENNE { 843*9e054ec2SFabien DESSENNE if (unlikely(!cryp->total_in)) { 844*9e054ec2SFabien DESSENNE dev_warn(cryp->dev, "No more data to process\n"); 845*9e054ec2SFabien DESSENNE return; 846*9e054ec2SFabien DESSENNE } 847*9e054ec2SFabien DESSENNE 848*9e054ec2SFabien DESSENNE if (is_aes(cryp) && is_ctr(cryp)) 849*9e054ec2SFabien DESSENNE stm32_cryp_check_ctr_counter(cryp); 850*9e054ec2SFabien DESSENNE 851*9e054ec2SFabien DESSENNE stm32_cryp_irq_write_block(cryp); 852*9e054ec2SFabien DESSENNE } 853*9e054ec2SFabien DESSENNE 854*9e054ec2SFabien DESSENNE static irqreturn_t stm32_cryp_irq_thread(int irq, void *arg) 855*9e054ec2SFabien DESSENNE { 856*9e054ec2SFabien DESSENNE struct stm32_cryp *cryp = arg; 857*9e054ec2SFabien DESSENNE 858*9e054ec2SFabien DESSENNE if (cryp->irq_status & MISR_OUT) 859*9e054ec2SFabien DESSENNE /* Output FIFO IRQ: read data */ 860*9e054ec2SFabien DESSENNE if (unlikely(stm32_cryp_irq_read_data(cryp))) { 861*9e054ec2SFabien DESSENNE /* All bytes processed, finish */ 862*9e054ec2SFabien DESSENNE stm32_cryp_write(cryp, CRYP_IMSCR, 0); 863*9e054ec2SFabien DESSENNE stm32_cryp_finish_req(cryp); 864*9e054ec2SFabien DESSENNE return IRQ_HANDLED; 865*9e054ec2SFabien DESSENNE } 866*9e054ec2SFabien DESSENNE 867*9e054ec2SFabien DESSENNE if (cryp->irq_status & MISR_IN) { 868*9e054ec2SFabien DESSENNE /* Input FIFO IRQ: write data */ 869*9e054ec2SFabien DESSENNE stm32_cryp_irq_write_data(cryp); 870*9e054ec2SFabien DESSENNE } 871*9e054ec2SFabien DESSENNE 872*9e054ec2SFabien DESSENNE return IRQ_HANDLED; 873*9e054ec2SFabien DESSENNE } 874*9e054ec2SFabien DESSENNE 875*9e054ec2SFabien DESSENNE static irqreturn_t stm32_cryp_irq(int irq, void *arg) 876*9e054ec2SFabien DESSENNE { 877*9e054ec2SFabien DESSENNE struct stm32_cryp *cryp = arg; 878*9e054ec2SFabien DESSENNE 879*9e054ec2SFabien DESSENNE cryp->irq_status = stm32_cryp_read(cryp, CRYP_MISR); 880*9e054ec2SFabien DESSENNE 881*9e054ec2SFabien DESSENNE return IRQ_WAKE_THREAD; 882*9e054ec2SFabien DESSENNE } 883*9e054ec2SFabien DESSENNE 884*9e054ec2SFabien DESSENNE static struct crypto_alg crypto_algs[] = { 885*9e054ec2SFabien DESSENNE { 886*9e054ec2SFabien DESSENNE .cra_name = "ecb(aes)", 887*9e054ec2SFabien DESSENNE .cra_driver_name = "stm32-ecb-aes", 888*9e054ec2SFabien DESSENNE .cra_priority = 200, 889*9e054ec2SFabien DESSENNE .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | 890*9e054ec2SFabien DESSENNE CRYPTO_ALG_ASYNC, 891*9e054ec2SFabien DESSENNE .cra_blocksize = AES_BLOCK_SIZE, 892*9e054ec2SFabien DESSENNE .cra_ctxsize = sizeof(struct stm32_cryp_ctx), 893*9e054ec2SFabien DESSENNE .cra_alignmask = 0xf, 894*9e054ec2SFabien DESSENNE .cra_type = &crypto_ablkcipher_type, 895*9e054ec2SFabien DESSENNE .cra_module = THIS_MODULE, 896*9e054ec2SFabien DESSENNE .cra_init = stm32_cryp_cra_init, 897*9e054ec2SFabien DESSENNE .cra_ablkcipher = { 898*9e054ec2SFabien DESSENNE .min_keysize = AES_MIN_KEY_SIZE, 899*9e054ec2SFabien DESSENNE .max_keysize = AES_MAX_KEY_SIZE, 900*9e054ec2SFabien DESSENNE .setkey = stm32_cryp_aes_setkey, 901*9e054ec2SFabien DESSENNE .encrypt = stm32_cryp_aes_ecb_encrypt, 902*9e054ec2SFabien DESSENNE .decrypt = stm32_cryp_aes_ecb_decrypt, 903*9e054ec2SFabien DESSENNE } 904*9e054ec2SFabien DESSENNE }, 905*9e054ec2SFabien DESSENNE { 906*9e054ec2SFabien DESSENNE .cra_name = "cbc(aes)", 907*9e054ec2SFabien DESSENNE .cra_driver_name = "stm32-cbc-aes", 908*9e054ec2SFabien DESSENNE .cra_priority = 200, 909*9e054ec2SFabien DESSENNE .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | 910*9e054ec2SFabien DESSENNE CRYPTO_ALG_ASYNC, 911*9e054ec2SFabien DESSENNE .cra_blocksize = AES_BLOCK_SIZE, 912*9e054ec2SFabien DESSENNE .cra_ctxsize = sizeof(struct stm32_cryp_ctx), 913*9e054ec2SFabien DESSENNE .cra_alignmask = 0xf, 914*9e054ec2SFabien DESSENNE .cra_type = &crypto_ablkcipher_type, 915*9e054ec2SFabien DESSENNE .cra_module = THIS_MODULE, 916*9e054ec2SFabien DESSENNE .cra_init = stm32_cryp_cra_init, 917*9e054ec2SFabien DESSENNE .cra_ablkcipher = { 918*9e054ec2SFabien DESSENNE .min_keysize = AES_MIN_KEY_SIZE, 919*9e054ec2SFabien DESSENNE .max_keysize = AES_MAX_KEY_SIZE, 920*9e054ec2SFabien DESSENNE .ivsize = AES_BLOCK_SIZE, 921*9e054ec2SFabien DESSENNE .setkey = stm32_cryp_aes_setkey, 922*9e054ec2SFabien DESSENNE .encrypt = stm32_cryp_aes_cbc_encrypt, 923*9e054ec2SFabien DESSENNE .decrypt = stm32_cryp_aes_cbc_decrypt, 924*9e054ec2SFabien DESSENNE } 925*9e054ec2SFabien DESSENNE }, 926*9e054ec2SFabien DESSENNE { 927*9e054ec2SFabien DESSENNE .cra_name = "ctr(aes)", 928*9e054ec2SFabien DESSENNE .cra_driver_name = "stm32-ctr-aes", 929*9e054ec2SFabien DESSENNE .cra_priority = 200, 930*9e054ec2SFabien DESSENNE .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | 931*9e054ec2SFabien DESSENNE CRYPTO_ALG_ASYNC, 932*9e054ec2SFabien DESSENNE .cra_blocksize = 1, 933*9e054ec2SFabien DESSENNE .cra_ctxsize = sizeof(struct stm32_cryp_ctx), 934*9e054ec2SFabien DESSENNE .cra_alignmask = 0xf, 935*9e054ec2SFabien DESSENNE .cra_type = &crypto_ablkcipher_type, 936*9e054ec2SFabien DESSENNE .cra_module = THIS_MODULE, 937*9e054ec2SFabien DESSENNE .cra_init = stm32_cryp_cra_init, 938*9e054ec2SFabien DESSENNE .cra_ablkcipher = { 939*9e054ec2SFabien DESSENNE .min_keysize = AES_MIN_KEY_SIZE, 940*9e054ec2SFabien DESSENNE .max_keysize = AES_MAX_KEY_SIZE, 941*9e054ec2SFabien DESSENNE .ivsize = AES_BLOCK_SIZE, 942*9e054ec2SFabien DESSENNE .setkey = stm32_cryp_aes_setkey, 943*9e054ec2SFabien DESSENNE .encrypt = stm32_cryp_aes_ctr_encrypt, 944*9e054ec2SFabien DESSENNE .decrypt = stm32_cryp_aes_ctr_decrypt, 945*9e054ec2SFabien DESSENNE } 946*9e054ec2SFabien DESSENNE }, 947*9e054ec2SFabien DESSENNE { 948*9e054ec2SFabien DESSENNE .cra_name = "ecb(des)", 949*9e054ec2SFabien DESSENNE .cra_driver_name = "stm32-ecb-des", 950*9e054ec2SFabien DESSENNE .cra_priority = 200, 951*9e054ec2SFabien DESSENNE .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | 952*9e054ec2SFabien DESSENNE CRYPTO_ALG_ASYNC, 953*9e054ec2SFabien DESSENNE .cra_blocksize = DES_BLOCK_SIZE, 954*9e054ec2SFabien DESSENNE .cra_ctxsize = sizeof(struct stm32_cryp_ctx), 955*9e054ec2SFabien DESSENNE .cra_alignmask = 0xf, 956*9e054ec2SFabien DESSENNE .cra_type = &crypto_ablkcipher_type, 957*9e054ec2SFabien DESSENNE .cra_module = THIS_MODULE, 958*9e054ec2SFabien DESSENNE .cra_init = stm32_cryp_cra_init, 959*9e054ec2SFabien DESSENNE .cra_ablkcipher = { 960*9e054ec2SFabien DESSENNE .min_keysize = DES_BLOCK_SIZE, 961*9e054ec2SFabien DESSENNE .max_keysize = DES_BLOCK_SIZE, 962*9e054ec2SFabien DESSENNE .setkey = stm32_cryp_des_setkey, 963*9e054ec2SFabien DESSENNE .encrypt = stm32_cryp_des_ecb_encrypt, 964*9e054ec2SFabien DESSENNE .decrypt = stm32_cryp_des_ecb_decrypt, 965*9e054ec2SFabien DESSENNE } 966*9e054ec2SFabien DESSENNE }, 967*9e054ec2SFabien DESSENNE { 968*9e054ec2SFabien DESSENNE .cra_name = "cbc(des)", 969*9e054ec2SFabien DESSENNE .cra_driver_name = "stm32-cbc-des", 970*9e054ec2SFabien DESSENNE .cra_priority = 200, 971*9e054ec2SFabien DESSENNE .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | 972*9e054ec2SFabien DESSENNE CRYPTO_ALG_ASYNC, 973*9e054ec2SFabien DESSENNE .cra_blocksize = DES_BLOCK_SIZE, 974*9e054ec2SFabien DESSENNE .cra_ctxsize = sizeof(struct stm32_cryp_ctx), 975*9e054ec2SFabien DESSENNE .cra_alignmask = 0xf, 976*9e054ec2SFabien DESSENNE .cra_type = &crypto_ablkcipher_type, 977*9e054ec2SFabien DESSENNE .cra_module = THIS_MODULE, 978*9e054ec2SFabien DESSENNE .cra_init = stm32_cryp_cra_init, 979*9e054ec2SFabien DESSENNE .cra_ablkcipher = { 980*9e054ec2SFabien DESSENNE .min_keysize = DES_BLOCK_SIZE, 981*9e054ec2SFabien DESSENNE .max_keysize = DES_BLOCK_SIZE, 982*9e054ec2SFabien DESSENNE .ivsize = DES_BLOCK_SIZE, 983*9e054ec2SFabien DESSENNE .setkey = stm32_cryp_des_setkey, 984*9e054ec2SFabien DESSENNE .encrypt = stm32_cryp_des_cbc_encrypt, 985*9e054ec2SFabien DESSENNE .decrypt = stm32_cryp_des_cbc_decrypt, 986*9e054ec2SFabien DESSENNE } 987*9e054ec2SFabien DESSENNE }, 988*9e054ec2SFabien DESSENNE { 989*9e054ec2SFabien DESSENNE .cra_name = "ecb(des3_ede)", 990*9e054ec2SFabien DESSENNE .cra_driver_name = "stm32-ecb-des3", 991*9e054ec2SFabien DESSENNE .cra_priority = 200, 992*9e054ec2SFabien DESSENNE .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | 993*9e054ec2SFabien DESSENNE CRYPTO_ALG_ASYNC, 994*9e054ec2SFabien DESSENNE .cra_blocksize = DES_BLOCK_SIZE, 995*9e054ec2SFabien DESSENNE .cra_ctxsize = sizeof(struct stm32_cryp_ctx), 996*9e054ec2SFabien DESSENNE .cra_alignmask = 0xf, 997*9e054ec2SFabien DESSENNE .cra_type = &crypto_ablkcipher_type, 998*9e054ec2SFabien DESSENNE .cra_module = THIS_MODULE, 999*9e054ec2SFabien DESSENNE .cra_init = stm32_cryp_cra_init, 1000*9e054ec2SFabien DESSENNE .cra_ablkcipher = { 1001*9e054ec2SFabien DESSENNE .min_keysize = 3 * DES_BLOCK_SIZE, 1002*9e054ec2SFabien DESSENNE .max_keysize = 3 * DES_BLOCK_SIZE, 1003*9e054ec2SFabien DESSENNE .setkey = stm32_cryp_tdes_setkey, 1004*9e054ec2SFabien DESSENNE .encrypt = stm32_cryp_tdes_ecb_encrypt, 1005*9e054ec2SFabien DESSENNE .decrypt = stm32_cryp_tdes_ecb_decrypt, 1006*9e054ec2SFabien DESSENNE } 1007*9e054ec2SFabien DESSENNE }, 1008*9e054ec2SFabien DESSENNE { 1009*9e054ec2SFabien DESSENNE .cra_name = "cbc(des3_ede)", 1010*9e054ec2SFabien DESSENNE .cra_driver_name = "stm32-cbc-des3", 1011*9e054ec2SFabien DESSENNE .cra_priority = 200, 1012*9e054ec2SFabien DESSENNE .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | 1013*9e054ec2SFabien DESSENNE CRYPTO_ALG_ASYNC, 1014*9e054ec2SFabien DESSENNE .cra_blocksize = DES_BLOCK_SIZE, 1015*9e054ec2SFabien DESSENNE .cra_ctxsize = sizeof(struct stm32_cryp_ctx), 1016*9e054ec2SFabien DESSENNE .cra_alignmask = 0xf, 1017*9e054ec2SFabien DESSENNE .cra_type = &crypto_ablkcipher_type, 1018*9e054ec2SFabien DESSENNE .cra_module = THIS_MODULE, 1019*9e054ec2SFabien DESSENNE .cra_init = stm32_cryp_cra_init, 1020*9e054ec2SFabien DESSENNE .cra_ablkcipher = { 1021*9e054ec2SFabien DESSENNE .min_keysize = 3 * DES_BLOCK_SIZE, 1022*9e054ec2SFabien DESSENNE .max_keysize = 3 * DES_BLOCK_SIZE, 1023*9e054ec2SFabien DESSENNE .ivsize = DES_BLOCK_SIZE, 1024*9e054ec2SFabien DESSENNE .setkey = stm32_cryp_tdes_setkey, 1025*9e054ec2SFabien DESSENNE .encrypt = stm32_cryp_tdes_cbc_encrypt, 1026*9e054ec2SFabien DESSENNE .decrypt = stm32_cryp_tdes_cbc_decrypt, 1027*9e054ec2SFabien DESSENNE } 1028*9e054ec2SFabien DESSENNE }, 1029*9e054ec2SFabien DESSENNE }; 1030*9e054ec2SFabien DESSENNE 1031*9e054ec2SFabien DESSENNE static const struct of_device_id stm32_dt_ids[] = { 1032*9e054ec2SFabien DESSENNE { .compatible = "st,stm32f756-cryp", }, 1033*9e054ec2SFabien DESSENNE {}, 1034*9e054ec2SFabien DESSENNE }; 1035*9e054ec2SFabien DESSENNE MODULE_DEVICE_TABLE(of, sti_dt_ids); 1036*9e054ec2SFabien DESSENNE 1037*9e054ec2SFabien DESSENNE static int stm32_cryp_probe(struct platform_device *pdev) 1038*9e054ec2SFabien DESSENNE { 1039*9e054ec2SFabien DESSENNE struct device *dev = &pdev->dev; 1040*9e054ec2SFabien DESSENNE struct stm32_cryp *cryp; 1041*9e054ec2SFabien DESSENNE struct resource *res; 1042*9e054ec2SFabien DESSENNE struct reset_control *rst; 1043*9e054ec2SFabien DESSENNE int irq, ret; 1044*9e054ec2SFabien DESSENNE 1045*9e054ec2SFabien DESSENNE cryp = devm_kzalloc(dev, sizeof(*cryp), GFP_KERNEL); 1046*9e054ec2SFabien DESSENNE if (!cryp) 1047*9e054ec2SFabien DESSENNE return -ENOMEM; 1048*9e054ec2SFabien DESSENNE 1049*9e054ec2SFabien DESSENNE cryp->dev = dev; 1050*9e054ec2SFabien DESSENNE 1051*9e054ec2SFabien DESSENNE mutex_init(&cryp->lock); 1052*9e054ec2SFabien DESSENNE 1053*9e054ec2SFabien DESSENNE res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 1054*9e054ec2SFabien DESSENNE cryp->regs = devm_ioremap_resource(dev, res); 1055*9e054ec2SFabien DESSENNE if (IS_ERR(cryp->regs)) { 1056*9e054ec2SFabien DESSENNE dev_err(dev, "Cannot map CRYP IO\n"); 1057*9e054ec2SFabien DESSENNE return PTR_ERR(cryp->regs); 1058*9e054ec2SFabien DESSENNE } 1059*9e054ec2SFabien DESSENNE 1060*9e054ec2SFabien DESSENNE irq = platform_get_irq(pdev, 0); 1061*9e054ec2SFabien DESSENNE if (irq < 0) { 1062*9e054ec2SFabien DESSENNE dev_err(dev, "Cannot get IRQ resource\n"); 1063*9e054ec2SFabien DESSENNE return irq; 1064*9e054ec2SFabien DESSENNE } 1065*9e054ec2SFabien DESSENNE 1066*9e054ec2SFabien DESSENNE ret = devm_request_threaded_irq(dev, irq, stm32_cryp_irq, 1067*9e054ec2SFabien DESSENNE stm32_cryp_irq_thread, IRQF_ONESHOT, 1068*9e054ec2SFabien DESSENNE dev_name(dev), cryp); 1069*9e054ec2SFabien DESSENNE if (ret) { 1070*9e054ec2SFabien DESSENNE dev_err(dev, "Cannot grab IRQ\n"); 1071*9e054ec2SFabien DESSENNE return ret; 1072*9e054ec2SFabien DESSENNE } 1073*9e054ec2SFabien DESSENNE 1074*9e054ec2SFabien DESSENNE cryp->clk = devm_clk_get(dev, NULL); 1075*9e054ec2SFabien DESSENNE if (IS_ERR(cryp->clk)) { 1076*9e054ec2SFabien DESSENNE dev_err(dev, "Could not get clock\n"); 1077*9e054ec2SFabien DESSENNE return PTR_ERR(cryp->clk); 1078*9e054ec2SFabien DESSENNE } 1079*9e054ec2SFabien DESSENNE 1080*9e054ec2SFabien DESSENNE ret = clk_prepare_enable(cryp->clk); 1081*9e054ec2SFabien DESSENNE if (ret) { 1082*9e054ec2SFabien DESSENNE dev_err(cryp->dev, "Failed to enable clock\n"); 1083*9e054ec2SFabien DESSENNE return ret; 1084*9e054ec2SFabien DESSENNE } 1085*9e054ec2SFabien DESSENNE 1086*9e054ec2SFabien DESSENNE rst = devm_reset_control_get(dev, NULL); 1087*9e054ec2SFabien DESSENNE if (!IS_ERR(rst)) { 1088*9e054ec2SFabien DESSENNE reset_control_assert(rst); 1089*9e054ec2SFabien DESSENNE udelay(2); 1090*9e054ec2SFabien DESSENNE reset_control_deassert(rst); 1091*9e054ec2SFabien DESSENNE } 1092*9e054ec2SFabien DESSENNE 1093*9e054ec2SFabien DESSENNE platform_set_drvdata(pdev, cryp); 1094*9e054ec2SFabien DESSENNE 1095*9e054ec2SFabien DESSENNE spin_lock(&cryp_list.lock); 1096*9e054ec2SFabien DESSENNE list_add(&cryp->list, &cryp_list.dev_list); 1097*9e054ec2SFabien DESSENNE spin_unlock(&cryp_list.lock); 1098*9e054ec2SFabien DESSENNE 1099*9e054ec2SFabien DESSENNE /* Initialize crypto engine */ 1100*9e054ec2SFabien DESSENNE cryp->engine = crypto_engine_alloc_init(dev, 1); 1101*9e054ec2SFabien DESSENNE if (!cryp->engine) { 1102*9e054ec2SFabien DESSENNE dev_err(dev, "Could not init crypto engine\n"); 1103*9e054ec2SFabien DESSENNE ret = -ENOMEM; 1104*9e054ec2SFabien DESSENNE goto err_engine1; 1105*9e054ec2SFabien DESSENNE } 1106*9e054ec2SFabien DESSENNE 1107*9e054ec2SFabien DESSENNE cryp->engine->prepare_cipher_request = stm32_cryp_prepare_cipher_req; 1108*9e054ec2SFabien DESSENNE cryp->engine->cipher_one_request = stm32_cryp_cipher_one_req; 1109*9e054ec2SFabien DESSENNE 1110*9e054ec2SFabien DESSENNE ret = crypto_engine_start(cryp->engine); 1111*9e054ec2SFabien DESSENNE if (ret) { 1112*9e054ec2SFabien DESSENNE dev_err(dev, "Could not start crypto engine\n"); 1113*9e054ec2SFabien DESSENNE goto err_engine2; 1114*9e054ec2SFabien DESSENNE } 1115*9e054ec2SFabien DESSENNE 1116*9e054ec2SFabien DESSENNE ret = crypto_register_algs(crypto_algs, ARRAY_SIZE(crypto_algs)); 1117*9e054ec2SFabien DESSENNE if (ret) { 1118*9e054ec2SFabien DESSENNE dev_err(dev, "Could not register algs\n"); 1119*9e054ec2SFabien DESSENNE goto err_algs; 1120*9e054ec2SFabien DESSENNE } 1121*9e054ec2SFabien DESSENNE 1122*9e054ec2SFabien DESSENNE dev_info(dev, "Initialized\n"); 1123*9e054ec2SFabien DESSENNE 1124*9e054ec2SFabien DESSENNE return 0; 1125*9e054ec2SFabien DESSENNE 1126*9e054ec2SFabien DESSENNE err_algs: 1127*9e054ec2SFabien DESSENNE err_engine2: 1128*9e054ec2SFabien DESSENNE crypto_engine_exit(cryp->engine); 1129*9e054ec2SFabien DESSENNE err_engine1: 1130*9e054ec2SFabien DESSENNE spin_lock(&cryp_list.lock); 1131*9e054ec2SFabien DESSENNE list_del(&cryp->list); 1132*9e054ec2SFabien DESSENNE spin_unlock(&cryp_list.lock); 1133*9e054ec2SFabien DESSENNE 1134*9e054ec2SFabien DESSENNE clk_disable_unprepare(cryp->clk); 1135*9e054ec2SFabien DESSENNE 1136*9e054ec2SFabien DESSENNE return ret; 1137*9e054ec2SFabien DESSENNE } 1138*9e054ec2SFabien DESSENNE 1139*9e054ec2SFabien DESSENNE static int stm32_cryp_remove(struct platform_device *pdev) 1140*9e054ec2SFabien DESSENNE { 1141*9e054ec2SFabien DESSENNE struct stm32_cryp *cryp = platform_get_drvdata(pdev); 1142*9e054ec2SFabien DESSENNE 1143*9e054ec2SFabien DESSENNE if (!cryp) 1144*9e054ec2SFabien DESSENNE return -ENODEV; 1145*9e054ec2SFabien DESSENNE 1146*9e054ec2SFabien DESSENNE crypto_unregister_algs(crypto_algs, ARRAY_SIZE(crypto_algs)); 1147*9e054ec2SFabien DESSENNE 1148*9e054ec2SFabien DESSENNE crypto_engine_exit(cryp->engine); 1149*9e054ec2SFabien DESSENNE 1150*9e054ec2SFabien DESSENNE spin_lock(&cryp_list.lock); 1151*9e054ec2SFabien DESSENNE list_del(&cryp->list); 1152*9e054ec2SFabien DESSENNE spin_unlock(&cryp_list.lock); 1153*9e054ec2SFabien DESSENNE 1154*9e054ec2SFabien DESSENNE clk_disable_unprepare(cryp->clk); 1155*9e054ec2SFabien DESSENNE 1156*9e054ec2SFabien DESSENNE return 0; 1157*9e054ec2SFabien DESSENNE } 1158*9e054ec2SFabien DESSENNE 1159*9e054ec2SFabien DESSENNE static struct platform_driver stm32_cryp_driver = { 1160*9e054ec2SFabien DESSENNE .probe = stm32_cryp_probe, 1161*9e054ec2SFabien DESSENNE .remove = stm32_cryp_remove, 1162*9e054ec2SFabien DESSENNE .driver = { 1163*9e054ec2SFabien DESSENNE .name = DRIVER_NAME, 1164*9e054ec2SFabien DESSENNE .of_match_table = stm32_dt_ids, 1165*9e054ec2SFabien DESSENNE }, 1166*9e054ec2SFabien DESSENNE }; 1167*9e054ec2SFabien DESSENNE 1168*9e054ec2SFabien DESSENNE module_platform_driver(stm32_cryp_driver); 1169*9e054ec2SFabien DESSENNE 1170*9e054ec2SFabien DESSENNE MODULE_AUTHOR("Fabien Dessenne <fabien.dessenne@st.com>"); 1171*9e054ec2SFabien DESSENNE MODULE_DESCRIPTION("STMicrolectronics STM32 CRYP hardware driver"); 1172*9e054ec2SFabien DESSENNE MODULE_LICENSE("GPL"); 1173