19e054ec2SFabien DESSENNE /* 29e054ec2SFabien DESSENNE * Copyright (C) STMicroelectronics SA 2017 39e054ec2SFabien DESSENNE * Author: Fabien Dessenne <fabien.dessenne@st.com> 49e054ec2SFabien DESSENNE * License terms: GNU General Public License (GPL), version 2 59e054ec2SFabien DESSENNE */ 69e054ec2SFabien DESSENNE 79e054ec2SFabien DESSENNE #include <linux/clk.h> 89e054ec2SFabien DESSENNE #include <linux/delay.h> 99e054ec2SFabien DESSENNE #include <linux/interrupt.h> 109e054ec2SFabien DESSENNE #include <linux/iopoll.h> 119e054ec2SFabien DESSENNE #include <linux/module.h> 129e054ec2SFabien DESSENNE #include <linux/of_device.h> 139e054ec2SFabien DESSENNE #include <linux/platform_device.h> 149e054ec2SFabien DESSENNE #include <linux/reset.h> 159e054ec2SFabien DESSENNE 169e054ec2SFabien DESSENNE #include <crypto/aes.h> 179e054ec2SFabien DESSENNE #include <crypto/des.h> 189e054ec2SFabien DESSENNE #include <crypto/engine.h> 199e054ec2SFabien DESSENNE #include <crypto/scatterwalk.h> 209d3b5030SFabien DESSENNE #include <crypto/internal/aead.h> 219e054ec2SFabien DESSENNE 229e054ec2SFabien DESSENNE #define DRIVER_NAME "stm32-cryp" 239e054ec2SFabien DESSENNE 249e054ec2SFabien DESSENNE /* Bit [0] encrypt / decrypt */ 259e054ec2SFabien DESSENNE #define FLG_ENCRYPT BIT(0) 269e054ec2SFabien DESSENNE /* Bit [8..1] algo & operation mode */ 279e054ec2SFabien DESSENNE #define FLG_AES BIT(1) 289e054ec2SFabien DESSENNE #define FLG_DES BIT(2) 299e054ec2SFabien DESSENNE #define FLG_TDES BIT(3) 309e054ec2SFabien DESSENNE #define FLG_ECB BIT(4) 319e054ec2SFabien DESSENNE #define FLG_CBC BIT(5) 329e054ec2SFabien DESSENNE #define FLG_CTR BIT(6) 339d3b5030SFabien DESSENNE #define FLG_GCM BIT(7) 349d3b5030SFabien DESSENNE #define FLG_CCM BIT(8) 359e054ec2SFabien DESSENNE /* Mode mask = bits [15..0] */ 369e054ec2SFabien DESSENNE #define FLG_MODE_MASK GENMASK(15, 0) 379d3b5030SFabien DESSENNE /* Bit [31..16] status */ 389d3b5030SFabien DESSENNE #define FLG_CCM_PADDED_WA BIT(16) 399e054ec2SFabien DESSENNE 409e054ec2SFabien DESSENNE /* Registers */ 419e054ec2SFabien DESSENNE #define CRYP_CR 0x00000000 429e054ec2SFabien DESSENNE #define CRYP_SR 0x00000004 439e054ec2SFabien DESSENNE #define CRYP_DIN 0x00000008 449e054ec2SFabien DESSENNE #define CRYP_DOUT 0x0000000C 459e054ec2SFabien DESSENNE #define CRYP_DMACR 0x00000010 469e054ec2SFabien DESSENNE #define CRYP_IMSCR 0x00000014 479e054ec2SFabien DESSENNE #define CRYP_RISR 0x00000018 489e054ec2SFabien DESSENNE #define CRYP_MISR 0x0000001C 499e054ec2SFabien DESSENNE #define CRYP_K0LR 0x00000020 509e054ec2SFabien DESSENNE #define CRYP_K0RR 0x00000024 519e054ec2SFabien DESSENNE #define CRYP_K1LR 0x00000028 529e054ec2SFabien DESSENNE #define CRYP_K1RR 0x0000002C 539e054ec2SFabien DESSENNE #define CRYP_K2LR 0x00000030 549e054ec2SFabien DESSENNE #define CRYP_K2RR 0x00000034 559e054ec2SFabien DESSENNE #define CRYP_K3LR 0x00000038 569e054ec2SFabien DESSENNE #define CRYP_K3RR 0x0000003C 579e054ec2SFabien DESSENNE #define CRYP_IV0LR 0x00000040 589e054ec2SFabien DESSENNE #define CRYP_IV0RR 0x00000044 599e054ec2SFabien DESSENNE #define CRYP_IV1LR 0x00000048 609e054ec2SFabien DESSENNE #define CRYP_IV1RR 0x0000004C 619d3b5030SFabien DESSENNE #define CRYP_CSGCMCCM0R 0x00000050 629d3b5030SFabien DESSENNE #define CRYP_CSGCM0R 0x00000070 639e054ec2SFabien DESSENNE 649e054ec2SFabien DESSENNE /* Registers values */ 659e054ec2SFabien DESSENNE #define CR_DEC_NOT_ENC 0x00000004 669e054ec2SFabien DESSENNE #define CR_TDES_ECB 0x00000000 679e054ec2SFabien DESSENNE #define CR_TDES_CBC 0x00000008 689e054ec2SFabien DESSENNE #define CR_DES_ECB 0x00000010 699e054ec2SFabien DESSENNE #define CR_DES_CBC 0x00000018 709e054ec2SFabien DESSENNE #define CR_AES_ECB 0x00000020 719e054ec2SFabien DESSENNE #define CR_AES_CBC 0x00000028 729e054ec2SFabien DESSENNE #define CR_AES_CTR 0x00000030 739e054ec2SFabien DESSENNE #define CR_AES_KP 0x00000038 749d3b5030SFabien DESSENNE #define CR_AES_GCM 0x00080000 759d3b5030SFabien DESSENNE #define CR_AES_CCM 0x00080008 769e054ec2SFabien DESSENNE #define CR_AES_UNKNOWN 0xFFFFFFFF 779e054ec2SFabien DESSENNE #define CR_ALGO_MASK 0x00080038 789e054ec2SFabien DESSENNE #define CR_DATA32 0x00000000 799e054ec2SFabien DESSENNE #define CR_DATA16 0x00000040 809e054ec2SFabien DESSENNE #define CR_DATA8 0x00000080 819e054ec2SFabien DESSENNE #define CR_DATA1 0x000000C0 829e054ec2SFabien DESSENNE #define CR_KEY128 0x00000000 839e054ec2SFabien DESSENNE #define CR_KEY192 0x00000100 849e054ec2SFabien DESSENNE #define CR_KEY256 0x00000200 859e054ec2SFabien DESSENNE #define CR_FFLUSH 0x00004000 869e054ec2SFabien DESSENNE #define CR_CRYPEN 0x00008000 879d3b5030SFabien DESSENNE #define CR_PH_INIT 0x00000000 889d3b5030SFabien DESSENNE #define CR_PH_HEADER 0x00010000 899d3b5030SFabien DESSENNE #define CR_PH_PAYLOAD 0x00020000 909d3b5030SFabien DESSENNE #define CR_PH_FINAL 0x00030000 919d3b5030SFabien DESSENNE #define CR_PH_MASK 0x00030000 929d3b5030SFabien DESSENNE #define CR_NBPBL_SHIFT 20 939e054ec2SFabien DESSENNE 949e054ec2SFabien DESSENNE #define SR_BUSY 0x00000010 959e054ec2SFabien DESSENNE #define SR_OFNE 0x00000004 969e054ec2SFabien DESSENNE 979e054ec2SFabien DESSENNE #define IMSCR_IN BIT(0) 989e054ec2SFabien DESSENNE #define IMSCR_OUT BIT(1) 999e054ec2SFabien DESSENNE 1009e054ec2SFabien DESSENNE #define MISR_IN BIT(0) 1019e054ec2SFabien DESSENNE #define MISR_OUT BIT(1) 1029e054ec2SFabien DESSENNE 1039e054ec2SFabien DESSENNE /* Misc */ 1049e054ec2SFabien DESSENNE #define AES_BLOCK_32 (AES_BLOCK_SIZE / sizeof(u32)) 1059d3b5030SFabien DESSENNE #define GCM_CTR_INIT 2 1069e054ec2SFabien DESSENNE #define _walked_in (cryp->in_walk.offset - cryp->in_sg->offset) 1079e054ec2SFabien DESSENNE #define _walked_out (cryp->out_walk.offset - cryp->out_sg->offset) 1089e054ec2SFabien DESSENNE 1099d3b5030SFabien DESSENNE struct stm32_cryp_caps { 1109d3b5030SFabien DESSENNE bool swap_final; 1119d3b5030SFabien DESSENNE bool padding_wa; 1129d3b5030SFabien DESSENNE }; 1139d3b5030SFabien DESSENNE 1149e054ec2SFabien DESSENNE struct stm32_cryp_ctx { 115dc7bcef5SCorentin LABBE struct crypto_engine_ctx enginectx; 1169e054ec2SFabien DESSENNE struct stm32_cryp *cryp; 1179e054ec2SFabien DESSENNE int keylen; 1189e054ec2SFabien DESSENNE u32 key[AES_KEYSIZE_256 / sizeof(u32)]; 1199e054ec2SFabien DESSENNE unsigned long flags; 1209e054ec2SFabien DESSENNE }; 1219e054ec2SFabien DESSENNE 1229e054ec2SFabien DESSENNE struct stm32_cryp_reqctx { 1239e054ec2SFabien DESSENNE unsigned long mode; 1249e054ec2SFabien DESSENNE }; 1259e054ec2SFabien DESSENNE 1269e054ec2SFabien DESSENNE struct stm32_cryp { 1279e054ec2SFabien DESSENNE struct list_head list; 1289e054ec2SFabien DESSENNE struct device *dev; 1299e054ec2SFabien DESSENNE void __iomem *regs; 1309e054ec2SFabien DESSENNE struct clk *clk; 1319e054ec2SFabien DESSENNE unsigned long flags; 1329e054ec2SFabien DESSENNE u32 irq_status; 1339d3b5030SFabien DESSENNE const struct stm32_cryp_caps *caps; 1349e054ec2SFabien DESSENNE struct stm32_cryp_ctx *ctx; 1359e054ec2SFabien DESSENNE 1369e054ec2SFabien DESSENNE struct crypto_engine *engine; 1379e054ec2SFabien DESSENNE 1389d3b5030SFabien DESSENNE struct mutex lock; /* protects req / areq */ 1399e054ec2SFabien DESSENNE struct ablkcipher_request *req; 1409d3b5030SFabien DESSENNE struct aead_request *areq; 1419e054ec2SFabien DESSENNE 1429d3b5030SFabien DESSENNE size_t authsize; 1439e054ec2SFabien DESSENNE size_t hw_blocksize; 1449e054ec2SFabien DESSENNE 1459e054ec2SFabien DESSENNE size_t total_in; 1469e054ec2SFabien DESSENNE size_t total_in_save; 1479e054ec2SFabien DESSENNE size_t total_out; 1489e054ec2SFabien DESSENNE size_t total_out_save; 1499e054ec2SFabien DESSENNE 1509e054ec2SFabien DESSENNE struct scatterlist *in_sg; 1519e054ec2SFabien DESSENNE struct scatterlist *out_sg; 1529e054ec2SFabien DESSENNE struct scatterlist *out_sg_save; 1539e054ec2SFabien DESSENNE 1549e054ec2SFabien DESSENNE struct scatterlist in_sgl; 1559e054ec2SFabien DESSENNE struct scatterlist out_sgl; 1569e054ec2SFabien DESSENNE bool sgs_copied; 1579e054ec2SFabien DESSENNE 1589e054ec2SFabien DESSENNE int in_sg_len; 1599e054ec2SFabien DESSENNE int out_sg_len; 1609e054ec2SFabien DESSENNE 1619e054ec2SFabien DESSENNE struct scatter_walk in_walk; 1629e054ec2SFabien DESSENNE struct scatter_walk out_walk; 1639e054ec2SFabien DESSENNE 1649e054ec2SFabien DESSENNE u32 last_ctr[4]; 1659d3b5030SFabien DESSENNE u32 gcm_ctr; 1669e054ec2SFabien DESSENNE }; 1679e054ec2SFabien DESSENNE 1689e054ec2SFabien DESSENNE struct stm32_cryp_list { 1699e054ec2SFabien DESSENNE struct list_head dev_list; 1709e054ec2SFabien DESSENNE spinlock_t lock; /* protect dev_list */ 1719e054ec2SFabien DESSENNE }; 1729e054ec2SFabien DESSENNE 1739e054ec2SFabien DESSENNE static struct stm32_cryp_list cryp_list = { 1749e054ec2SFabien DESSENNE .dev_list = LIST_HEAD_INIT(cryp_list.dev_list), 1759e054ec2SFabien DESSENNE .lock = __SPIN_LOCK_UNLOCKED(cryp_list.lock), 1769e054ec2SFabien DESSENNE }; 1779e054ec2SFabien DESSENNE 1789e054ec2SFabien DESSENNE static inline bool is_aes(struct stm32_cryp *cryp) 1799e054ec2SFabien DESSENNE { 1809e054ec2SFabien DESSENNE return cryp->flags & FLG_AES; 1819e054ec2SFabien DESSENNE } 1829e054ec2SFabien DESSENNE 1839e054ec2SFabien DESSENNE static inline bool is_des(struct stm32_cryp *cryp) 1849e054ec2SFabien DESSENNE { 1859e054ec2SFabien DESSENNE return cryp->flags & FLG_DES; 1869e054ec2SFabien DESSENNE } 1879e054ec2SFabien DESSENNE 1889e054ec2SFabien DESSENNE static inline bool is_tdes(struct stm32_cryp *cryp) 1899e054ec2SFabien DESSENNE { 1909e054ec2SFabien DESSENNE return cryp->flags & FLG_TDES; 1919e054ec2SFabien DESSENNE } 1929e054ec2SFabien DESSENNE 1939e054ec2SFabien DESSENNE static inline bool is_ecb(struct stm32_cryp *cryp) 1949e054ec2SFabien DESSENNE { 1959e054ec2SFabien DESSENNE return cryp->flags & FLG_ECB; 1969e054ec2SFabien DESSENNE } 1979e054ec2SFabien DESSENNE 1989e054ec2SFabien DESSENNE static inline bool is_cbc(struct stm32_cryp *cryp) 1999e054ec2SFabien DESSENNE { 2009e054ec2SFabien DESSENNE return cryp->flags & FLG_CBC; 2019e054ec2SFabien DESSENNE } 2029e054ec2SFabien DESSENNE 2039e054ec2SFabien DESSENNE static inline bool is_ctr(struct stm32_cryp *cryp) 2049e054ec2SFabien DESSENNE { 2059e054ec2SFabien DESSENNE return cryp->flags & FLG_CTR; 2069e054ec2SFabien DESSENNE } 2079e054ec2SFabien DESSENNE 2089d3b5030SFabien DESSENNE static inline bool is_gcm(struct stm32_cryp *cryp) 2099d3b5030SFabien DESSENNE { 2109d3b5030SFabien DESSENNE return cryp->flags & FLG_GCM; 2119d3b5030SFabien DESSENNE } 2129d3b5030SFabien DESSENNE 2139d3b5030SFabien DESSENNE static inline bool is_ccm(struct stm32_cryp *cryp) 2149d3b5030SFabien DESSENNE { 2159d3b5030SFabien DESSENNE return cryp->flags & FLG_CCM; 2169d3b5030SFabien DESSENNE } 2179d3b5030SFabien DESSENNE 2189e054ec2SFabien DESSENNE static inline bool is_encrypt(struct stm32_cryp *cryp) 2199e054ec2SFabien DESSENNE { 2209e054ec2SFabien DESSENNE return cryp->flags & FLG_ENCRYPT; 2219e054ec2SFabien DESSENNE } 2229e054ec2SFabien DESSENNE 2239e054ec2SFabien DESSENNE static inline bool is_decrypt(struct stm32_cryp *cryp) 2249e054ec2SFabien DESSENNE { 2259e054ec2SFabien DESSENNE return !is_encrypt(cryp); 2269e054ec2SFabien DESSENNE } 2279e054ec2SFabien DESSENNE 2289e054ec2SFabien DESSENNE static inline u32 stm32_cryp_read(struct stm32_cryp *cryp, u32 ofst) 2299e054ec2SFabien DESSENNE { 2309e054ec2SFabien DESSENNE return readl_relaxed(cryp->regs + ofst); 2319e054ec2SFabien DESSENNE } 2329e054ec2SFabien DESSENNE 2339e054ec2SFabien DESSENNE static inline void stm32_cryp_write(struct stm32_cryp *cryp, u32 ofst, u32 val) 2349e054ec2SFabien DESSENNE { 2359e054ec2SFabien DESSENNE writel_relaxed(val, cryp->regs + ofst); 2369e054ec2SFabien DESSENNE } 2379e054ec2SFabien DESSENNE 2389e054ec2SFabien DESSENNE static inline int stm32_cryp_wait_busy(struct stm32_cryp *cryp) 2399e054ec2SFabien DESSENNE { 2409e054ec2SFabien DESSENNE u32 status; 2419e054ec2SFabien DESSENNE 2429e054ec2SFabien DESSENNE return readl_relaxed_poll_timeout(cryp->regs + CRYP_SR, status, 2439e054ec2SFabien DESSENNE !(status & SR_BUSY), 10, 100000); 2449e054ec2SFabien DESSENNE } 2459e054ec2SFabien DESSENNE 2469d3b5030SFabien DESSENNE static inline int stm32_cryp_wait_enable(struct stm32_cryp *cryp) 2479d3b5030SFabien DESSENNE { 2489d3b5030SFabien DESSENNE u32 status; 2499d3b5030SFabien DESSENNE 2509d3b5030SFabien DESSENNE return readl_relaxed_poll_timeout(cryp->regs + CRYP_CR, status, 2519d3b5030SFabien DESSENNE !(status & CR_CRYPEN), 10, 100000); 2529d3b5030SFabien DESSENNE } 2539d3b5030SFabien DESSENNE 2549d3b5030SFabien DESSENNE static inline int stm32_cryp_wait_output(struct stm32_cryp *cryp) 2559d3b5030SFabien DESSENNE { 2569d3b5030SFabien DESSENNE u32 status; 2579d3b5030SFabien DESSENNE 2589d3b5030SFabien DESSENNE return readl_relaxed_poll_timeout(cryp->regs + CRYP_SR, status, 2599d3b5030SFabien DESSENNE status & SR_OFNE, 10, 100000); 2609d3b5030SFabien DESSENNE } 2619d3b5030SFabien DESSENNE 2629d3b5030SFabien DESSENNE static int stm32_cryp_read_auth_tag(struct stm32_cryp *cryp); 2639d3b5030SFabien DESSENNE 2649e054ec2SFabien DESSENNE static struct stm32_cryp *stm32_cryp_find_dev(struct stm32_cryp_ctx *ctx) 2659e054ec2SFabien DESSENNE { 2669e054ec2SFabien DESSENNE struct stm32_cryp *tmp, *cryp = NULL; 2679e054ec2SFabien DESSENNE 2689e054ec2SFabien DESSENNE spin_lock_bh(&cryp_list.lock); 2699e054ec2SFabien DESSENNE if (!ctx->cryp) { 2709e054ec2SFabien DESSENNE list_for_each_entry(tmp, &cryp_list.dev_list, list) { 2719e054ec2SFabien DESSENNE cryp = tmp; 2729e054ec2SFabien DESSENNE break; 2739e054ec2SFabien DESSENNE } 2749e054ec2SFabien DESSENNE ctx->cryp = cryp; 2759e054ec2SFabien DESSENNE } else { 2769e054ec2SFabien DESSENNE cryp = ctx->cryp; 2779e054ec2SFabien DESSENNE } 2789e054ec2SFabien DESSENNE 2799e054ec2SFabien DESSENNE spin_unlock_bh(&cryp_list.lock); 2809e054ec2SFabien DESSENNE 2819e054ec2SFabien DESSENNE return cryp; 2829e054ec2SFabien DESSENNE } 2839e054ec2SFabien DESSENNE 2849e054ec2SFabien DESSENNE static int stm32_cryp_check_aligned(struct scatterlist *sg, size_t total, 2859e054ec2SFabien DESSENNE size_t align) 2869e054ec2SFabien DESSENNE { 2879e054ec2SFabien DESSENNE int len = 0; 2889e054ec2SFabien DESSENNE 2899e054ec2SFabien DESSENNE if (!total) 2909e054ec2SFabien DESSENNE return 0; 2919e054ec2SFabien DESSENNE 2929e054ec2SFabien DESSENNE if (!IS_ALIGNED(total, align)) 2939e054ec2SFabien DESSENNE return -EINVAL; 2949e054ec2SFabien DESSENNE 2959e054ec2SFabien DESSENNE while (sg) { 2969e054ec2SFabien DESSENNE if (!IS_ALIGNED(sg->offset, sizeof(u32))) 2979e054ec2SFabien DESSENNE return -EINVAL; 2989e054ec2SFabien DESSENNE 2999e054ec2SFabien DESSENNE if (!IS_ALIGNED(sg->length, align)) 3009e054ec2SFabien DESSENNE return -EINVAL; 3019e054ec2SFabien DESSENNE 3029e054ec2SFabien DESSENNE len += sg->length; 3039e054ec2SFabien DESSENNE sg = sg_next(sg); 3049e054ec2SFabien DESSENNE } 3059e054ec2SFabien DESSENNE 3069e054ec2SFabien DESSENNE if (len != total) 3079e054ec2SFabien DESSENNE return -EINVAL; 3089e054ec2SFabien DESSENNE 3099e054ec2SFabien DESSENNE return 0; 3109e054ec2SFabien DESSENNE } 3119e054ec2SFabien DESSENNE 3129e054ec2SFabien DESSENNE static int stm32_cryp_check_io_aligned(struct stm32_cryp *cryp) 3139e054ec2SFabien DESSENNE { 3149e054ec2SFabien DESSENNE int ret; 3159e054ec2SFabien DESSENNE 3169e054ec2SFabien DESSENNE ret = stm32_cryp_check_aligned(cryp->in_sg, cryp->total_in, 3179e054ec2SFabien DESSENNE cryp->hw_blocksize); 3189e054ec2SFabien DESSENNE if (ret) 3199e054ec2SFabien DESSENNE return ret; 3209e054ec2SFabien DESSENNE 3219e054ec2SFabien DESSENNE ret = stm32_cryp_check_aligned(cryp->out_sg, cryp->total_out, 3229e054ec2SFabien DESSENNE cryp->hw_blocksize); 3239e054ec2SFabien DESSENNE 3249e054ec2SFabien DESSENNE return ret; 3259e054ec2SFabien DESSENNE } 3269e054ec2SFabien DESSENNE 3279e054ec2SFabien DESSENNE static void sg_copy_buf(void *buf, struct scatterlist *sg, 3289e054ec2SFabien DESSENNE unsigned int start, unsigned int nbytes, int out) 3299e054ec2SFabien DESSENNE { 3309e054ec2SFabien DESSENNE struct scatter_walk walk; 3319e054ec2SFabien DESSENNE 3329e054ec2SFabien DESSENNE if (!nbytes) 3339e054ec2SFabien DESSENNE return; 3349e054ec2SFabien DESSENNE 3359e054ec2SFabien DESSENNE scatterwalk_start(&walk, sg); 3369e054ec2SFabien DESSENNE scatterwalk_advance(&walk, start); 3379e054ec2SFabien DESSENNE scatterwalk_copychunks(buf, &walk, nbytes, out); 3389e054ec2SFabien DESSENNE scatterwalk_done(&walk, out, 0); 3399e054ec2SFabien DESSENNE } 3409e054ec2SFabien DESSENNE 3419e054ec2SFabien DESSENNE static int stm32_cryp_copy_sgs(struct stm32_cryp *cryp) 3429e054ec2SFabien DESSENNE { 3439e054ec2SFabien DESSENNE void *buf_in, *buf_out; 3449e054ec2SFabien DESSENNE int pages, total_in, total_out; 3459e054ec2SFabien DESSENNE 3469e054ec2SFabien DESSENNE if (!stm32_cryp_check_io_aligned(cryp)) { 3479e054ec2SFabien DESSENNE cryp->sgs_copied = 0; 3489e054ec2SFabien DESSENNE return 0; 3499e054ec2SFabien DESSENNE } 3509e054ec2SFabien DESSENNE 3519e054ec2SFabien DESSENNE total_in = ALIGN(cryp->total_in, cryp->hw_blocksize); 3529e054ec2SFabien DESSENNE pages = total_in ? get_order(total_in) : 1; 3539e054ec2SFabien DESSENNE buf_in = (void *)__get_free_pages(GFP_ATOMIC, pages); 3549e054ec2SFabien DESSENNE 3559e054ec2SFabien DESSENNE total_out = ALIGN(cryp->total_out, cryp->hw_blocksize); 3569e054ec2SFabien DESSENNE pages = total_out ? get_order(total_out) : 1; 3579e054ec2SFabien DESSENNE buf_out = (void *)__get_free_pages(GFP_ATOMIC, pages); 3589e054ec2SFabien DESSENNE 3599e054ec2SFabien DESSENNE if (!buf_in || !buf_out) { 3609e054ec2SFabien DESSENNE dev_err(cryp->dev, "Can't allocate pages when unaligned\n"); 3619e054ec2SFabien DESSENNE cryp->sgs_copied = 0; 3629e054ec2SFabien DESSENNE return -EFAULT; 3639e054ec2SFabien DESSENNE } 3649e054ec2SFabien DESSENNE 3659e054ec2SFabien DESSENNE sg_copy_buf(buf_in, cryp->in_sg, 0, cryp->total_in, 0); 3669e054ec2SFabien DESSENNE 3679e054ec2SFabien DESSENNE sg_init_one(&cryp->in_sgl, buf_in, total_in); 3689e054ec2SFabien DESSENNE cryp->in_sg = &cryp->in_sgl; 3699e054ec2SFabien DESSENNE cryp->in_sg_len = 1; 3709e054ec2SFabien DESSENNE 3719e054ec2SFabien DESSENNE sg_init_one(&cryp->out_sgl, buf_out, total_out); 3729e054ec2SFabien DESSENNE cryp->out_sg_save = cryp->out_sg; 3739e054ec2SFabien DESSENNE cryp->out_sg = &cryp->out_sgl; 3749e054ec2SFabien DESSENNE cryp->out_sg_len = 1; 3759e054ec2SFabien DESSENNE 3769e054ec2SFabien DESSENNE cryp->sgs_copied = 1; 3779e054ec2SFabien DESSENNE 3789e054ec2SFabien DESSENNE return 0; 3799e054ec2SFabien DESSENNE } 3809e054ec2SFabien DESSENNE 3819e054ec2SFabien DESSENNE static void stm32_cryp_hw_write_iv(struct stm32_cryp *cryp, u32 *iv) 3829e054ec2SFabien DESSENNE { 3839e054ec2SFabien DESSENNE if (!iv) 3849e054ec2SFabien DESSENNE return; 3859e054ec2SFabien DESSENNE 3869e054ec2SFabien DESSENNE stm32_cryp_write(cryp, CRYP_IV0LR, cpu_to_be32(*iv++)); 3879e054ec2SFabien DESSENNE stm32_cryp_write(cryp, CRYP_IV0RR, cpu_to_be32(*iv++)); 3889e054ec2SFabien DESSENNE 3899e054ec2SFabien DESSENNE if (is_aes(cryp)) { 3909e054ec2SFabien DESSENNE stm32_cryp_write(cryp, CRYP_IV1LR, cpu_to_be32(*iv++)); 3919e054ec2SFabien DESSENNE stm32_cryp_write(cryp, CRYP_IV1RR, cpu_to_be32(*iv++)); 3929e054ec2SFabien DESSENNE } 3939e054ec2SFabien DESSENNE } 3949e054ec2SFabien DESSENNE 3959e054ec2SFabien DESSENNE static void stm32_cryp_hw_write_key(struct stm32_cryp *c) 3969e054ec2SFabien DESSENNE { 3979e054ec2SFabien DESSENNE unsigned int i; 3989e054ec2SFabien DESSENNE int r_id; 3999e054ec2SFabien DESSENNE 4009e054ec2SFabien DESSENNE if (is_des(c)) { 4019e054ec2SFabien DESSENNE stm32_cryp_write(c, CRYP_K1LR, cpu_to_be32(c->ctx->key[0])); 4029e054ec2SFabien DESSENNE stm32_cryp_write(c, CRYP_K1RR, cpu_to_be32(c->ctx->key[1])); 4039e054ec2SFabien DESSENNE } else { 4049e054ec2SFabien DESSENNE r_id = CRYP_K3RR; 4059e054ec2SFabien DESSENNE for (i = c->ctx->keylen / sizeof(u32); i > 0; i--, r_id -= 4) 4069e054ec2SFabien DESSENNE stm32_cryp_write(c, r_id, 4079e054ec2SFabien DESSENNE cpu_to_be32(c->ctx->key[i - 1])); 4089e054ec2SFabien DESSENNE } 4099e054ec2SFabien DESSENNE } 4109e054ec2SFabien DESSENNE 4119e054ec2SFabien DESSENNE static u32 stm32_cryp_get_hw_mode(struct stm32_cryp *cryp) 4129e054ec2SFabien DESSENNE { 4139e054ec2SFabien DESSENNE if (is_aes(cryp) && is_ecb(cryp)) 4149e054ec2SFabien DESSENNE return CR_AES_ECB; 4159e054ec2SFabien DESSENNE 4169e054ec2SFabien DESSENNE if (is_aes(cryp) && is_cbc(cryp)) 4179e054ec2SFabien DESSENNE return CR_AES_CBC; 4189e054ec2SFabien DESSENNE 4199e054ec2SFabien DESSENNE if (is_aes(cryp) && is_ctr(cryp)) 4209e054ec2SFabien DESSENNE return CR_AES_CTR; 4219e054ec2SFabien DESSENNE 4229d3b5030SFabien DESSENNE if (is_aes(cryp) && is_gcm(cryp)) 4239d3b5030SFabien DESSENNE return CR_AES_GCM; 4249d3b5030SFabien DESSENNE 4259d3b5030SFabien DESSENNE if (is_aes(cryp) && is_ccm(cryp)) 4269d3b5030SFabien DESSENNE return CR_AES_CCM; 4279d3b5030SFabien DESSENNE 4289e054ec2SFabien DESSENNE if (is_des(cryp) && is_ecb(cryp)) 4299e054ec2SFabien DESSENNE return CR_DES_ECB; 4309e054ec2SFabien DESSENNE 4319e054ec2SFabien DESSENNE if (is_des(cryp) && is_cbc(cryp)) 4329e054ec2SFabien DESSENNE return CR_DES_CBC; 4339e054ec2SFabien DESSENNE 4349e054ec2SFabien DESSENNE if (is_tdes(cryp) && is_ecb(cryp)) 4359e054ec2SFabien DESSENNE return CR_TDES_ECB; 4369e054ec2SFabien DESSENNE 4379e054ec2SFabien DESSENNE if (is_tdes(cryp) && is_cbc(cryp)) 4389e054ec2SFabien DESSENNE return CR_TDES_CBC; 4399e054ec2SFabien DESSENNE 4409e054ec2SFabien DESSENNE dev_err(cryp->dev, "Unknown mode\n"); 4419e054ec2SFabien DESSENNE return CR_AES_UNKNOWN; 4429e054ec2SFabien DESSENNE } 4439e054ec2SFabien DESSENNE 4449d3b5030SFabien DESSENNE static unsigned int stm32_cryp_get_input_text_len(struct stm32_cryp *cryp) 4459d3b5030SFabien DESSENNE { 4469d3b5030SFabien DESSENNE return is_encrypt(cryp) ? cryp->areq->cryptlen : 4479d3b5030SFabien DESSENNE cryp->areq->cryptlen - cryp->authsize; 4489d3b5030SFabien DESSENNE } 4499d3b5030SFabien DESSENNE 4509d3b5030SFabien DESSENNE static int stm32_cryp_gcm_init(struct stm32_cryp *cryp, u32 cfg) 4519d3b5030SFabien DESSENNE { 4529d3b5030SFabien DESSENNE int ret; 4539d3b5030SFabien DESSENNE u32 iv[4]; 4549d3b5030SFabien DESSENNE 4559d3b5030SFabien DESSENNE /* Phase 1 : init */ 4569d3b5030SFabien DESSENNE memcpy(iv, cryp->areq->iv, 12); 4579d3b5030SFabien DESSENNE iv[3] = cpu_to_be32(GCM_CTR_INIT); 4589d3b5030SFabien DESSENNE cryp->gcm_ctr = GCM_CTR_INIT; 4599d3b5030SFabien DESSENNE stm32_cryp_hw_write_iv(cryp, iv); 4609d3b5030SFabien DESSENNE 4619d3b5030SFabien DESSENNE stm32_cryp_write(cryp, CRYP_CR, cfg | CR_PH_INIT | CR_CRYPEN); 4629d3b5030SFabien DESSENNE 4639d3b5030SFabien DESSENNE /* Wait for end of processing */ 4649d3b5030SFabien DESSENNE ret = stm32_cryp_wait_enable(cryp); 4659d3b5030SFabien DESSENNE if (ret) 4669d3b5030SFabien DESSENNE dev_err(cryp->dev, "Timeout (gcm init)\n"); 4679d3b5030SFabien DESSENNE 4689d3b5030SFabien DESSENNE return ret; 4699d3b5030SFabien DESSENNE } 4709d3b5030SFabien DESSENNE 4719d3b5030SFabien DESSENNE static int stm32_cryp_ccm_init(struct stm32_cryp *cryp, u32 cfg) 4729d3b5030SFabien DESSENNE { 4739d3b5030SFabien DESSENNE int ret; 4749d3b5030SFabien DESSENNE u8 iv[AES_BLOCK_SIZE], b0[AES_BLOCK_SIZE]; 4759d3b5030SFabien DESSENNE u32 *d; 4769d3b5030SFabien DESSENNE unsigned int i, textlen; 4779d3b5030SFabien DESSENNE 4789d3b5030SFabien DESSENNE /* Phase 1 : init. Firstly set the CTR value to 1 (not 0) */ 4799d3b5030SFabien DESSENNE memcpy(iv, cryp->areq->iv, AES_BLOCK_SIZE); 4809d3b5030SFabien DESSENNE memset(iv + AES_BLOCK_SIZE - 1 - iv[0], 0, iv[0] + 1); 4819d3b5030SFabien DESSENNE iv[AES_BLOCK_SIZE - 1] = 1; 4829d3b5030SFabien DESSENNE stm32_cryp_hw_write_iv(cryp, (u32 *)iv); 4839d3b5030SFabien DESSENNE 4849d3b5030SFabien DESSENNE /* Build B0 */ 4859d3b5030SFabien DESSENNE memcpy(b0, iv, AES_BLOCK_SIZE); 4869d3b5030SFabien DESSENNE 4879d3b5030SFabien DESSENNE b0[0] |= (8 * ((cryp->authsize - 2) / 2)); 4889d3b5030SFabien DESSENNE 4899d3b5030SFabien DESSENNE if (cryp->areq->assoclen) 4909d3b5030SFabien DESSENNE b0[0] |= 0x40; 4919d3b5030SFabien DESSENNE 4929d3b5030SFabien DESSENNE textlen = stm32_cryp_get_input_text_len(cryp); 4939d3b5030SFabien DESSENNE 4949d3b5030SFabien DESSENNE b0[AES_BLOCK_SIZE - 2] = textlen >> 8; 4959d3b5030SFabien DESSENNE b0[AES_BLOCK_SIZE - 1] = textlen & 0xFF; 4969d3b5030SFabien DESSENNE 4979d3b5030SFabien DESSENNE /* Enable HW */ 4989d3b5030SFabien DESSENNE stm32_cryp_write(cryp, CRYP_CR, cfg | CR_PH_INIT | CR_CRYPEN); 4999d3b5030SFabien DESSENNE 5009d3b5030SFabien DESSENNE /* Write B0 */ 5019d3b5030SFabien DESSENNE d = (u32 *)b0; 5029d3b5030SFabien DESSENNE 5039d3b5030SFabien DESSENNE for (i = 0; i < AES_BLOCK_32; i++) { 5049d3b5030SFabien DESSENNE if (!cryp->caps->padding_wa) 5059d3b5030SFabien DESSENNE *d = cpu_to_be32(*d); 5069d3b5030SFabien DESSENNE stm32_cryp_write(cryp, CRYP_DIN, *d++); 5079d3b5030SFabien DESSENNE } 5089d3b5030SFabien DESSENNE 5099d3b5030SFabien DESSENNE /* Wait for end of processing */ 5109d3b5030SFabien DESSENNE ret = stm32_cryp_wait_enable(cryp); 5119d3b5030SFabien DESSENNE if (ret) 5129d3b5030SFabien DESSENNE dev_err(cryp->dev, "Timeout (ccm init)\n"); 5139d3b5030SFabien DESSENNE 5149d3b5030SFabien DESSENNE return ret; 5159d3b5030SFabien DESSENNE } 5169d3b5030SFabien DESSENNE 5179e054ec2SFabien DESSENNE static int stm32_cryp_hw_init(struct stm32_cryp *cryp) 5189e054ec2SFabien DESSENNE { 5199e054ec2SFabien DESSENNE int ret; 5209e054ec2SFabien DESSENNE u32 cfg, hw_mode; 5219e054ec2SFabien DESSENNE 5229e054ec2SFabien DESSENNE /* Disable interrupt */ 5239e054ec2SFabien DESSENNE stm32_cryp_write(cryp, CRYP_IMSCR, 0); 5249e054ec2SFabien DESSENNE 5259e054ec2SFabien DESSENNE /* Set key */ 5269e054ec2SFabien DESSENNE stm32_cryp_hw_write_key(cryp); 5279e054ec2SFabien DESSENNE 5289e054ec2SFabien DESSENNE /* Set configuration */ 5299e054ec2SFabien DESSENNE cfg = CR_DATA8 | CR_FFLUSH; 5309e054ec2SFabien DESSENNE 5319e054ec2SFabien DESSENNE switch (cryp->ctx->keylen) { 5329e054ec2SFabien DESSENNE case AES_KEYSIZE_128: 5339e054ec2SFabien DESSENNE cfg |= CR_KEY128; 5349e054ec2SFabien DESSENNE break; 5359e054ec2SFabien DESSENNE 5369e054ec2SFabien DESSENNE case AES_KEYSIZE_192: 5379e054ec2SFabien DESSENNE cfg |= CR_KEY192; 5389e054ec2SFabien DESSENNE break; 5399e054ec2SFabien DESSENNE 5409e054ec2SFabien DESSENNE default: 5419e054ec2SFabien DESSENNE case AES_KEYSIZE_256: 5429e054ec2SFabien DESSENNE cfg |= CR_KEY256; 5439e054ec2SFabien DESSENNE break; 5449e054ec2SFabien DESSENNE } 5459e054ec2SFabien DESSENNE 5469e054ec2SFabien DESSENNE hw_mode = stm32_cryp_get_hw_mode(cryp); 5479e054ec2SFabien DESSENNE if (hw_mode == CR_AES_UNKNOWN) 5489e054ec2SFabien DESSENNE return -EINVAL; 5499e054ec2SFabien DESSENNE 5509e054ec2SFabien DESSENNE /* AES ECB/CBC decrypt: run key preparation first */ 5519e054ec2SFabien DESSENNE if (is_decrypt(cryp) && 5529e054ec2SFabien DESSENNE ((hw_mode == CR_AES_ECB) || (hw_mode == CR_AES_CBC))) { 5539e054ec2SFabien DESSENNE stm32_cryp_write(cryp, CRYP_CR, cfg | CR_AES_KP | CR_CRYPEN); 5549e054ec2SFabien DESSENNE 5559e054ec2SFabien DESSENNE /* Wait for end of processing */ 5569e054ec2SFabien DESSENNE ret = stm32_cryp_wait_busy(cryp); 5579e054ec2SFabien DESSENNE if (ret) { 5589e054ec2SFabien DESSENNE dev_err(cryp->dev, "Timeout (key preparation)\n"); 5599e054ec2SFabien DESSENNE return ret; 5609e054ec2SFabien DESSENNE } 5619e054ec2SFabien DESSENNE } 5629e054ec2SFabien DESSENNE 5639e054ec2SFabien DESSENNE cfg |= hw_mode; 5649e054ec2SFabien DESSENNE 5659e054ec2SFabien DESSENNE if (is_decrypt(cryp)) 5669e054ec2SFabien DESSENNE cfg |= CR_DEC_NOT_ENC; 5679e054ec2SFabien DESSENNE 5689e054ec2SFabien DESSENNE /* Apply config and flush (valid when CRYPEN = 0) */ 5699e054ec2SFabien DESSENNE stm32_cryp_write(cryp, CRYP_CR, cfg); 5709e054ec2SFabien DESSENNE 5719e054ec2SFabien DESSENNE switch (hw_mode) { 5729d3b5030SFabien DESSENNE case CR_AES_GCM: 5739d3b5030SFabien DESSENNE case CR_AES_CCM: 5749d3b5030SFabien DESSENNE /* Phase 1 : init */ 5759d3b5030SFabien DESSENNE if (hw_mode == CR_AES_CCM) 5769d3b5030SFabien DESSENNE ret = stm32_cryp_ccm_init(cryp, cfg); 5779d3b5030SFabien DESSENNE else 5789d3b5030SFabien DESSENNE ret = stm32_cryp_gcm_init(cryp, cfg); 5799d3b5030SFabien DESSENNE 5809d3b5030SFabien DESSENNE if (ret) 5819d3b5030SFabien DESSENNE return ret; 5829d3b5030SFabien DESSENNE 5839d3b5030SFabien DESSENNE /* Phase 2 : header (authenticated data) */ 5849d3b5030SFabien DESSENNE if (cryp->areq->assoclen) { 5859d3b5030SFabien DESSENNE cfg |= CR_PH_HEADER; 5869d3b5030SFabien DESSENNE } else if (stm32_cryp_get_input_text_len(cryp)) { 5879d3b5030SFabien DESSENNE cfg |= CR_PH_PAYLOAD; 5889d3b5030SFabien DESSENNE stm32_cryp_write(cryp, CRYP_CR, cfg); 5899d3b5030SFabien DESSENNE } else { 5909d3b5030SFabien DESSENNE cfg |= CR_PH_INIT; 5919d3b5030SFabien DESSENNE } 5929d3b5030SFabien DESSENNE 5939d3b5030SFabien DESSENNE break; 5949d3b5030SFabien DESSENNE 5959e054ec2SFabien DESSENNE case CR_DES_CBC: 5969e054ec2SFabien DESSENNE case CR_TDES_CBC: 5979e054ec2SFabien DESSENNE case CR_AES_CBC: 5989e054ec2SFabien DESSENNE case CR_AES_CTR: 5999e054ec2SFabien DESSENNE stm32_cryp_hw_write_iv(cryp, (u32 *)cryp->req->info); 6009e054ec2SFabien DESSENNE break; 6019e054ec2SFabien DESSENNE 6029e054ec2SFabien DESSENNE default: 6039e054ec2SFabien DESSENNE break; 6049e054ec2SFabien DESSENNE } 6059e054ec2SFabien DESSENNE 6069e054ec2SFabien DESSENNE /* Enable now */ 6079e054ec2SFabien DESSENNE cfg |= CR_CRYPEN; 6089e054ec2SFabien DESSENNE 6099e054ec2SFabien DESSENNE stm32_cryp_write(cryp, CRYP_CR, cfg); 6109e054ec2SFabien DESSENNE 6119d3b5030SFabien DESSENNE cryp->flags &= ~FLG_CCM_PADDED_WA; 6129d3b5030SFabien DESSENNE 6139e054ec2SFabien DESSENNE return 0; 6149e054ec2SFabien DESSENNE } 6159e054ec2SFabien DESSENNE 6169d3b5030SFabien DESSENNE static void stm32_cryp_finish_req(struct stm32_cryp *cryp, int err) 6179e054ec2SFabien DESSENNE { 6189d3b5030SFabien DESSENNE if (!err && (is_gcm(cryp) || is_ccm(cryp))) 6199d3b5030SFabien DESSENNE /* Phase 4 : output tag */ 6209d3b5030SFabien DESSENNE err = stm32_cryp_read_auth_tag(cryp); 6219e054ec2SFabien DESSENNE 6229e054ec2SFabien DESSENNE if (cryp->sgs_copied) { 6239e054ec2SFabien DESSENNE void *buf_in, *buf_out; 6249e054ec2SFabien DESSENNE int pages, len; 6259e054ec2SFabien DESSENNE 6269e054ec2SFabien DESSENNE buf_in = sg_virt(&cryp->in_sgl); 6279e054ec2SFabien DESSENNE buf_out = sg_virt(&cryp->out_sgl); 6289e054ec2SFabien DESSENNE 6299e054ec2SFabien DESSENNE sg_copy_buf(buf_out, cryp->out_sg_save, 0, 6309e054ec2SFabien DESSENNE cryp->total_out_save, 1); 6319e054ec2SFabien DESSENNE 6329e054ec2SFabien DESSENNE len = ALIGN(cryp->total_in_save, cryp->hw_blocksize); 6339e054ec2SFabien DESSENNE pages = len ? get_order(len) : 1; 6349e054ec2SFabien DESSENNE free_pages((unsigned long)buf_in, pages); 6359e054ec2SFabien DESSENNE 6369e054ec2SFabien DESSENNE len = ALIGN(cryp->total_out_save, cryp->hw_blocksize); 6379e054ec2SFabien DESSENNE pages = len ? get_order(len) : 1; 6389e054ec2SFabien DESSENNE free_pages((unsigned long)buf_out, pages); 6399e054ec2SFabien DESSENNE } 6409e054ec2SFabien DESSENNE 6419d3b5030SFabien DESSENNE if (is_gcm(cryp) || is_ccm(cryp)) { 6429d3b5030SFabien DESSENNE crypto_finalize_aead_request(cryp->engine, cryp->areq, err); 6439d3b5030SFabien DESSENNE cryp->areq = NULL; 6449d3b5030SFabien DESSENNE } else { 6459d3b5030SFabien DESSENNE crypto_finalize_ablkcipher_request(cryp->engine, cryp->req, 6469d3b5030SFabien DESSENNE err); 6479e054ec2SFabien DESSENNE cryp->req = NULL; 6489d3b5030SFabien DESSENNE } 6499e054ec2SFabien DESSENNE 6509e054ec2SFabien DESSENNE memset(cryp->ctx->key, 0, cryp->ctx->keylen); 6519e054ec2SFabien DESSENNE 6529e054ec2SFabien DESSENNE mutex_unlock(&cryp->lock); 6539e054ec2SFabien DESSENNE } 6549e054ec2SFabien DESSENNE 6559e054ec2SFabien DESSENNE static int stm32_cryp_cpu_start(struct stm32_cryp *cryp) 6569e054ec2SFabien DESSENNE { 6579e054ec2SFabien DESSENNE /* Enable interrupt and let the IRQ handler do everything */ 6589e054ec2SFabien DESSENNE stm32_cryp_write(cryp, CRYP_IMSCR, IMSCR_IN | IMSCR_OUT); 6599e054ec2SFabien DESSENNE 6609e054ec2SFabien DESSENNE return 0; 6619e054ec2SFabien DESSENNE } 6629e054ec2SFabien DESSENNE 663dc7bcef5SCorentin LABBE static int stm32_cryp_cipher_one_req(struct crypto_engine *engine, void *areq); 664dc7bcef5SCorentin LABBE static int stm32_cryp_prepare_cipher_req(struct crypto_engine *engine, 665dc7bcef5SCorentin LABBE void *areq); 666dc7bcef5SCorentin LABBE 6679e054ec2SFabien DESSENNE static int stm32_cryp_cra_init(struct crypto_tfm *tfm) 6689e054ec2SFabien DESSENNE { 669dc7bcef5SCorentin LABBE struct stm32_cryp_ctx *ctx = crypto_tfm_ctx(tfm); 670dc7bcef5SCorentin LABBE 6719e054ec2SFabien DESSENNE tfm->crt_ablkcipher.reqsize = sizeof(struct stm32_cryp_reqctx); 6729e054ec2SFabien DESSENNE 673dc7bcef5SCorentin LABBE ctx->enginectx.op.do_one_request = stm32_cryp_cipher_one_req; 674dc7bcef5SCorentin LABBE ctx->enginectx.op.prepare_request = stm32_cryp_prepare_cipher_req; 675dc7bcef5SCorentin LABBE ctx->enginectx.op.unprepare_request = NULL; 6769e054ec2SFabien DESSENNE return 0; 6779e054ec2SFabien DESSENNE } 6789e054ec2SFabien DESSENNE 6799d3b5030SFabien DESSENNE static int stm32_cryp_aead_one_req(struct crypto_engine *engine, void *areq); 6809d3b5030SFabien DESSENNE static int stm32_cryp_prepare_aead_req(struct crypto_engine *engine, 6819d3b5030SFabien DESSENNE void *areq); 6829d3b5030SFabien DESSENNE 6839d3b5030SFabien DESSENNE static int stm32_cryp_aes_aead_init(struct crypto_aead *tfm) 6849d3b5030SFabien DESSENNE { 6859d3b5030SFabien DESSENNE struct stm32_cryp_ctx *ctx = crypto_aead_ctx(tfm); 6869d3b5030SFabien DESSENNE 6879d3b5030SFabien DESSENNE tfm->reqsize = sizeof(struct stm32_cryp_reqctx); 6889d3b5030SFabien DESSENNE 6899d3b5030SFabien DESSENNE ctx->enginectx.op.do_one_request = stm32_cryp_aead_one_req; 6909d3b5030SFabien DESSENNE ctx->enginectx.op.prepare_request = stm32_cryp_prepare_aead_req; 6919d3b5030SFabien DESSENNE ctx->enginectx.op.unprepare_request = NULL; 6929d3b5030SFabien DESSENNE 6939d3b5030SFabien DESSENNE return 0; 6949d3b5030SFabien DESSENNE } 6959d3b5030SFabien DESSENNE 6969e054ec2SFabien DESSENNE static int stm32_cryp_crypt(struct ablkcipher_request *req, unsigned long mode) 6979e054ec2SFabien DESSENNE { 6989e054ec2SFabien DESSENNE struct stm32_cryp_ctx *ctx = crypto_ablkcipher_ctx( 6999e054ec2SFabien DESSENNE crypto_ablkcipher_reqtfm(req)); 7009e054ec2SFabien DESSENNE struct stm32_cryp_reqctx *rctx = ablkcipher_request_ctx(req); 7019e054ec2SFabien DESSENNE struct stm32_cryp *cryp = stm32_cryp_find_dev(ctx); 7029e054ec2SFabien DESSENNE 7039e054ec2SFabien DESSENNE if (!cryp) 7049e054ec2SFabien DESSENNE return -ENODEV; 7059e054ec2SFabien DESSENNE 7069e054ec2SFabien DESSENNE rctx->mode = mode; 7079e054ec2SFabien DESSENNE 708dc7bcef5SCorentin LABBE return crypto_transfer_ablkcipher_request_to_engine(cryp->engine, req); 7099e054ec2SFabien DESSENNE } 7109e054ec2SFabien DESSENNE 7119d3b5030SFabien DESSENNE static int stm32_cryp_aead_crypt(struct aead_request *req, unsigned long mode) 7129d3b5030SFabien DESSENNE { 7139d3b5030SFabien DESSENNE struct stm32_cryp_ctx *ctx = crypto_aead_ctx(crypto_aead_reqtfm(req)); 7149d3b5030SFabien DESSENNE struct stm32_cryp_reqctx *rctx = aead_request_ctx(req); 7159d3b5030SFabien DESSENNE struct stm32_cryp *cryp = stm32_cryp_find_dev(ctx); 7169d3b5030SFabien DESSENNE 7179d3b5030SFabien DESSENNE if (!cryp) 7189d3b5030SFabien DESSENNE return -ENODEV; 7199d3b5030SFabien DESSENNE 7209d3b5030SFabien DESSENNE rctx->mode = mode; 7219d3b5030SFabien DESSENNE 7229d3b5030SFabien DESSENNE return crypto_transfer_aead_request_to_engine(cryp->engine, req); 7239d3b5030SFabien DESSENNE } 7249d3b5030SFabien DESSENNE 7259e054ec2SFabien DESSENNE static int stm32_cryp_setkey(struct crypto_ablkcipher *tfm, const u8 *key, 7269e054ec2SFabien DESSENNE unsigned int keylen) 7279e054ec2SFabien DESSENNE { 7289e054ec2SFabien DESSENNE struct stm32_cryp_ctx *ctx = crypto_ablkcipher_ctx(tfm); 7299e054ec2SFabien DESSENNE 7309e054ec2SFabien DESSENNE memcpy(ctx->key, key, keylen); 7319e054ec2SFabien DESSENNE ctx->keylen = keylen; 7329e054ec2SFabien DESSENNE 7339e054ec2SFabien DESSENNE return 0; 7349e054ec2SFabien DESSENNE } 7359e054ec2SFabien DESSENNE 7369e054ec2SFabien DESSENNE static int stm32_cryp_aes_setkey(struct crypto_ablkcipher *tfm, const u8 *key, 7379e054ec2SFabien DESSENNE unsigned int keylen) 7389e054ec2SFabien DESSENNE { 7399e054ec2SFabien DESSENNE if (keylen != AES_KEYSIZE_128 && keylen != AES_KEYSIZE_192 && 7409e054ec2SFabien DESSENNE keylen != AES_KEYSIZE_256) 7419e054ec2SFabien DESSENNE return -EINVAL; 7429e054ec2SFabien DESSENNE else 7439e054ec2SFabien DESSENNE return stm32_cryp_setkey(tfm, key, keylen); 7449e054ec2SFabien DESSENNE } 7459e054ec2SFabien DESSENNE 7469e054ec2SFabien DESSENNE static int stm32_cryp_des_setkey(struct crypto_ablkcipher *tfm, const u8 *key, 7479e054ec2SFabien DESSENNE unsigned int keylen) 7489e054ec2SFabien DESSENNE { 7499e054ec2SFabien DESSENNE if (keylen != DES_KEY_SIZE) 7509e054ec2SFabien DESSENNE return -EINVAL; 7519e054ec2SFabien DESSENNE else 7529e054ec2SFabien DESSENNE return stm32_cryp_setkey(tfm, key, keylen); 7539e054ec2SFabien DESSENNE } 7549e054ec2SFabien DESSENNE 7559e054ec2SFabien DESSENNE static int stm32_cryp_tdes_setkey(struct crypto_ablkcipher *tfm, const u8 *key, 7569e054ec2SFabien DESSENNE unsigned int keylen) 7579e054ec2SFabien DESSENNE { 7589e054ec2SFabien DESSENNE if (keylen != (3 * DES_KEY_SIZE)) 7599e054ec2SFabien DESSENNE return -EINVAL; 7609e054ec2SFabien DESSENNE else 7619e054ec2SFabien DESSENNE return stm32_cryp_setkey(tfm, key, keylen); 7629e054ec2SFabien DESSENNE } 7639e054ec2SFabien DESSENNE 7649d3b5030SFabien DESSENNE static int stm32_cryp_aes_aead_setkey(struct crypto_aead *tfm, const u8 *key, 7659d3b5030SFabien DESSENNE unsigned int keylen) 7669d3b5030SFabien DESSENNE { 7679d3b5030SFabien DESSENNE struct stm32_cryp_ctx *ctx = crypto_aead_ctx(tfm); 7689d3b5030SFabien DESSENNE 7699d3b5030SFabien DESSENNE if (keylen != AES_KEYSIZE_128 && keylen != AES_KEYSIZE_192 && 7709d3b5030SFabien DESSENNE keylen != AES_KEYSIZE_256) 7719d3b5030SFabien DESSENNE return -EINVAL; 7729d3b5030SFabien DESSENNE 7739d3b5030SFabien DESSENNE memcpy(ctx->key, key, keylen); 7749d3b5030SFabien DESSENNE ctx->keylen = keylen; 7759d3b5030SFabien DESSENNE 7769d3b5030SFabien DESSENNE return 0; 7779d3b5030SFabien DESSENNE } 7789d3b5030SFabien DESSENNE 7799d3b5030SFabien DESSENNE static int stm32_cryp_aes_gcm_setauthsize(struct crypto_aead *tfm, 7809d3b5030SFabien DESSENNE unsigned int authsize) 7819d3b5030SFabien DESSENNE { 7829d3b5030SFabien DESSENNE return authsize == AES_BLOCK_SIZE ? 0 : -EINVAL; 7839d3b5030SFabien DESSENNE } 7849d3b5030SFabien DESSENNE 7859d3b5030SFabien DESSENNE static int stm32_cryp_aes_ccm_setauthsize(struct crypto_aead *tfm, 7869d3b5030SFabien DESSENNE unsigned int authsize) 7879d3b5030SFabien DESSENNE { 7889d3b5030SFabien DESSENNE switch (authsize) { 7899d3b5030SFabien DESSENNE case 4: 7909d3b5030SFabien DESSENNE case 6: 7919d3b5030SFabien DESSENNE case 8: 7929d3b5030SFabien DESSENNE case 10: 7939d3b5030SFabien DESSENNE case 12: 7949d3b5030SFabien DESSENNE case 14: 7959d3b5030SFabien DESSENNE case 16: 7969d3b5030SFabien DESSENNE break; 7979d3b5030SFabien DESSENNE default: 7989d3b5030SFabien DESSENNE return -EINVAL; 7999d3b5030SFabien DESSENNE } 8009d3b5030SFabien DESSENNE 8019d3b5030SFabien DESSENNE return 0; 8029d3b5030SFabien DESSENNE } 8039d3b5030SFabien DESSENNE 8049e054ec2SFabien DESSENNE static int stm32_cryp_aes_ecb_encrypt(struct ablkcipher_request *req) 8059e054ec2SFabien DESSENNE { 8069e054ec2SFabien DESSENNE return stm32_cryp_crypt(req, FLG_AES | FLG_ECB | FLG_ENCRYPT); 8079e054ec2SFabien DESSENNE } 8089e054ec2SFabien DESSENNE 8099e054ec2SFabien DESSENNE static int stm32_cryp_aes_ecb_decrypt(struct ablkcipher_request *req) 8109e054ec2SFabien DESSENNE { 8119e054ec2SFabien DESSENNE return stm32_cryp_crypt(req, FLG_AES | FLG_ECB); 8129e054ec2SFabien DESSENNE } 8139e054ec2SFabien DESSENNE 8149e054ec2SFabien DESSENNE static int stm32_cryp_aes_cbc_encrypt(struct ablkcipher_request *req) 8159e054ec2SFabien DESSENNE { 8169e054ec2SFabien DESSENNE return stm32_cryp_crypt(req, FLG_AES | FLG_CBC | FLG_ENCRYPT); 8179e054ec2SFabien DESSENNE } 8189e054ec2SFabien DESSENNE 8199e054ec2SFabien DESSENNE static int stm32_cryp_aes_cbc_decrypt(struct ablkcipher_request *req) 8209e054ec2SFabien DESSENNE { 8219e054ec2SFabien DESSENNE return stm32_cryp_crypt(req, FLG_AES | FLG_CBC); 8229e054ec2SFabien DESSENNE } 8239e054ec2SFabien DESSENNE 8249e054ec2SFabien DESSENNE static int stm32_cryp_aes_ctr_encrypt(struct ablkcipher_request *req) 8259e054ec2SFabien DESSENNE { 8269e054ec2SFabien DESSENNE return stm32_cryp_crypt(req, FLG_AES | FLG_CTR | FLG_ENCRYPT); 8279e054ec2SFabien DESSENNE } 8289e054ec2SFabien DESSENNE 8299e054ec2SFabien DESSENNE static int stm32_cryp_aes_ctr_decrypt(struct ablkcipher_request *req) 8309e054ec2SFabien DESSENNE { 8319e054ec2SFabien DESSENNE return stm32_cryp_crypt(req, FLG_AES | FLG_CTR); 8329e054ec2SFabien DESSENNE } 8339e054ec2SFabien DESSENNE 8349d3b5030SFabien DESSENNE static int stm32_cryp_aes_gcm_encrypt(struct aead_request *req) 8359d3b5030SFabien DESSENNE { 8369d3b5030SFabien DESSENNE return stm32_cryp_aead_crypt(req, FLG_AES | FLG_GCM | FLG_ENCRYPT); 8379d3b5030SFabien DESSENNE } 8389d3b5030SFabien DESSENNE 8399d3b5030SFabien DESSENNE static int stm32_cryp_aes_gcm_decrypt(struct aead_request *req) 8409d3b5030SFabien DESSENNE { 8419d3b5030SFabien DESSENNE return stm32_cryp_aead_crypt(req, FLG_AES | FLG_GCM); 8429d3b5030SFabien DESSENNE } 8439d3b5030SFabien DESSENNE 8449d3b5030SFabien DESSENNE static int stm32_cryp_aes_ccm_encrypt(struct aead_request *req) 8459d3b5030SFabien DESSENNE { 8469d3b5030SFabien DESSENNE return stm32_cryp_aead_crypt(req, FLG_AES | FLG_CCM | FLG_ENCRYPT); 8479d3b5030SFabien DESSENNE } 8489d3b5030SFabien DESSENNE 8499d3b5030SFabien DESSENNE static int stm32_cryp_aes_ccm_decrypt(struct aead_request *req) 8509d3b5030SFabien DESSENNE { 8519d3b5030SFabien DESSENNE return stm32_cryp_aead_crypt(req, FLG_AES | FLG_CCM); 8529d3b5030SFabien DESSENNE } 8539d3b5030SFabien DESSENNE 8549e054ec2SFabien DESSENNE static int stm32_cryp_des_ecb_encrypt(struct ablkcipher_request *req) 8559e054ec2SFabien DESSENNE { 8569e054ec2SFabien DESSENNE return stm32_cryp_crypt(req, FLG_DES | FLG_ECB | FLG_ENCRYPT); 8579e054ec2SFabien DESSENNE } 8589e054ec2SFabien DESSENNE 8599e054ec2SFabien DESSENNE static int stm32_cryp_des_ecb_decrypt(struct ablkcipher_request *req) 8609e054ec2SFabien DESSENNE { 8619e054ec2SFabien DESSENNE return stm32_cryp_crypt(req, FLG_DES | FLG_ECB); 8629e054ec2SFabien DESSENNE } 8639e054ec2SFabien DESSENNE 8649e054ec2SFabien DESSENNE static int stm32_cryp_des_cbc_encrypt(struct ablkcipher_request *req) 8659e054ec2SFabien DESSENNE { 8669e054ec2SFabien DESSENNE return stm32_cryp_crypt(req, FLG_DES | FLG_CBC | FLG_ENCRYPT); 8679e054ec2SFabien DESSENNE } 8689e054ec2SFabien DESSENNE 8699e054ec2SFabien DESSENNE static int stm32_cryp_des_cbc_decrypt(struct ablkcipher_request *req) 8709e054ec2SFabien DESSENNE { 8719e054ec2SFabien DESSENNE return stm32_cryp_crypt(req, FLG_DES | FLG_CBC); 8729e054ec2SFabien DESSENNE } 8739e054ec2SFabien DESSENNE 8749e054ec2SFabien DESSENNE static int stm32_cryp_tdes_ecb_encrypt(struct ablkcipher_request *req) 8759e054ec2SFabien DESSENNE { 8769e054ec2SFabien DESSENNE return stm32_cryp_crypt(req, FLG_TDES | FLG_ECB | FLG_ENCRYPT); 8779e054ec2SFabien DESSENNE } 8789e054ec2SFabien DESSENNE 8799e054ec2SFabien DESSENNE static int stm32_cryp_tdes_ecb_decrypt(struct ablkcipher_request *req) 8809e054ec2SFabien DESSENNE { 8819e054ec2SFabien DESSENNE return stm32_cryp_crypt(req, FLG_TDES | FLG_ECB); 8829e054ec2SFabien DESSENNE } 8839e054ec2SFabien DESSENNE 8849e054ec2SFabien DESSENNE static int stm32_cryp_tdes_cbc_encrypt(struct ablkcipher_request *req) 8859e054ec2SFabien DESSENNE { 8869e054ec2SFabien DESSENNE return stm32_cryp_crypt(req, FLG_TDES | FLG_CBC | FLG_ENCRYPT); 8879e054ec2SFabien DESSENNE } 8889e054ec2SFabien DESSENNE 8899e054ec2SFabien DESSENNE static int stm32_cryp_tdes_cbc_decrypt(struct ablkcipher_request *req) 8909e054ec2SFabien DESSENNE { 8919e054ec2SFabien DESSENNE return stm32_cryp_crypt(req, FLG_TDES | FLG_CBC); 8929e054ec2SFabien DESSENNE } 8939e054ec2SFabien DESSENNE 8949d3b5030SFabien DESSENNE static int stm32_cryp_prepare_req(struct ablkcipher_request *req, 8959d3b5030SFabien DESSENNE struct aead_request *areq) 8969e054ec2SFabien DESSENNE { 8979e054ec2SFabien DESSENNE struct stm32_cryp_ctx *ctx; 8989e054ec2SFabien DESSENNE struct stm32_cryp *cryp; 8999e054ec2SFabien DESSENNE struct stm32_cryp_reqctx *rctx; 9009e054ec2SFabien DESSENNE int ret; 9019e054ec2SFabien DESSENNE 9029d3b5030SFabien DESSENNE if (!req && !areq) 9039e054ec2SFabien DESSENNE return -EINVAL; 9049e054ec2SFabien DESSENNE 9059d3b5030SFabien DESSENNE ctx = req ? crypto_ablkcipher_ctx(crypto_ablkcipher_reqtfm(req)) : 9069d3b5030SFabien DESSENNE crypto_aead_ctx(crypto_aead_reqtfm(areq)); 9079e054ec2SFabien DESSENNE 9089e054ec2SFabien DESSENNE cryp = ctx->cryp; 9099e054ec2SFabien DESSENNE 9109e054ec2SFabien DESSENNE if (!cryp) 9119e054ec2SFabien DESSENNE return -ENODEV; 9129e054ec2SFabien DESSENNE 9139e054ec2SFabien DESSENNE mutex_lock(&cryp->lock); 9149e054ec2SFabien DESSENNE 9159d3b5030SFabien DESSENNE rctx = req ? ablkcipher_request_ctx(req) : aead_request_ctx(areq); 9169e054ec2SFabien DESSENNE rctx->mode &= FLG_MODE_MASK; 9179e054ec2SFabien DESSENNE 9189e054ec2SFabien DESSENNE ctx->cryp = cryp; 9199e054ec2SFabien DESSENNE 9209e054ec2SFabien DESSENNE cryp->flags = (cryp->flags & ~FLG_MODE_MASK) | rctx->mode; 9219e054ec2SFabien DESSENNE cryp->hw_blocksize = is_aes(cryp) ? AES_BLOCK_SIZE : DES_BLOCK_SIZE; 9229e054ec2SFabien DESSENNE cryp->ctx = ctx; 9239e054ec2SFabien DESSENNE 9249d3b5030SFabien DESSENNE if (req) { 9259e054ec2SFabien DESSENNE cryp->req = req; 9269e054ec2SFabien DESSENNE cryp->total_in = req->nbytes; 9279e054ec2SFabien DESSENNE cryp->total_out = cryp->total_in; 9289d3b5030SFabien DESSENNE } else { 9299d3b5030SFabien DESSENNE /* 9309d3b5030SFabien DESSENNE * Length of input and output data: 9319d3b5030SFabien DESSENNE * Encryption case: 9329d3b5030SFabien DESSENNE * INPUT = AssocData || PlainText 9339d3b5030SFabien DESSENNE * <- assoclen -> <- cryptlen -> 9349d3b5030SFabien DESSENNE * <------- total_in -----------> 9359d3b5030SFabien DESSENNE * 9369d3b5030SFabien DESSENNE * OUTPUT = AssocData || CipherText || AuthTag 9379d3b5030SFabien DESSENNE * <- assoclen -> <- cryptlen -> <- authsize -> 9389d3b5030SFabien DESSENNE * <---------------- total_out -----------------> 9399d3b5030SFabien DESSENNE * 9409d3b5030SFabien DESSENNE * Decryption case: 9419d3b5030SFabien DESSENNE * INPUT = AssocData || CipherText || AuthTag 9429d3b5030SFabien DESSENNE * <- assoclen -> <--------- cryptlen ---------> 9439d3b5030SFabien DESSENNE * <- authsize -> 9449d3b5030SFabien DESSENNE * <---------------- total_in ------------------> 9459d3b5030SFabien DESSENNE * 9469d3b5030SFabien DESSENNE * OUTPUT = AssocData || PlainText 9479d3b5030SFabien DESSENNE * <- assoclen -> <- crypten - authsize -> 9489d3b5030SFabien DESSENNE * <---------- total_out -----------------> 9499d3b5030SFabien DESSENNE */ 9509d3b5030SFabien DESSENNE cryp->areq = areq; 9519d3b5030SFabien DESSENNE cryp->authsize = crypto_aead_authsize(crypto_aead_reqtfm(areq)); 9529d3b5030SFabien DESSENNE cryp->total_in = areq->assoclen + areq->cryptlen; 9539d3b5030SFabien DESSENNE if (is_encrypt(cryp)) 9549d3b5030SFabien DESSENNE /* Append auth tag to output */ 9559d3b5030SFabien DESSENNE cryp->total_out = cryp->total_in + cryp->authsize; 9569d3b5030SFabien DESSENNE else 9579d3b5030SFabien DESSENNE /* No auth tag in output */ 9589d3b5030SFabien DESSENNE cryp->total_out = cryp->total_in - cryp->authsize; 9599d3b5030SFabien DESSENNE } 9609e054ec2SFabien DESSENNE 9619e054ec2SFabien DESSENNE cryp->total_in_save = cryp->total_in; 9629e054ec2SFabien DESSENNE cryp->total_out_save = cryp->total_out; 9639e054ec2SFabien DESSENNE 9649d3b5030SFabien DESSENNE cryp->in_sg = req ? req->src : areq->src; 9659d3b5030SFabien DESSENNE cryp->out_sg = req ? req->dst : areq->dst; 9669e054ec2SFabien DESSENNE cryp->out_sg_save = cryp->out_sg; 9679e054ec2SFabien DESSENNE 9689e054ec2SFabien DESSENNE cryp->in_sg_len = sg_nents_for_len(cryp->in_sg, cryp->total_in); 9699e054ec2SFabien DESSENNE if (cryp->in_sg_len < 0) { 9709e054ec2SFabien DESSENNE dev_err(cryp->dev, "Cannot get in_sg_len\n"); 9719e054ec2SFabien DESSENNE ret = cryp->in_sg_len; 9729e054ec2SFabien DESSENNE goto out; 9739e054ec2SFabien DESSENNE } 9749e054ec2SFabien DESSENNE 9759e054ec2SFabien DESSENNE cryp->out_sg_len = sg_nents_for_len(cryp->out_sg, cryp->total_out); 9769e054ec2SFabien DESSENNE if (cryp->out_sg_len < 0) { 9779e054ec2SFabien DESSENNE dev_err(cryp->dev, "Cannot get out_sg_len\n"); 9789e054ec2SFabien DESSENNE ret = cryp->out_sg_len; 9799e054ec2SFabien DESSENNE goto out; 9809e054ec2SFabien DESSENNE } 9819e054ec2SFabien DESSENNE 9829e054ec2SFabien DESSENNE ret = stm32_cryp_copy_sgs(cryp); 9839e054ec2SFabien DESSENNE if (ret) 9849e054ec2SFabien DESSENNE goto out; 9859e054ec2SFabien DESSENNE 9869e054ec2SFabien DESSENNE scatterwalk_start(&cryp->in_walk, cryp->in_sg); 9879e054ec2SFabien DESSENNE scatterwalk_start(&cryp->out_walk, cryp->out_sg); 9889e054ec2SFabien DESSENNE 9899d3b5030SFabien DESSENNE if (is_gcm(cryp) || is_ccm(cryp)) { 9909d3b5030SFabien DESSENNE /* In output, jump after assoc data */ 9919d3b5030SFabien DESSENNE scatterwalk_advance(&cryp->out_walk, cryp->areq->assoclen); 9929d3b5030SFabien DESSENNE cryp->total_out -= cryp->areq->assoclen; 9939d3b5030SFabien DESSENNE } 9949d3b5030SFabien DESSENNE 9959e054ec2SFabien DESSENNE ret = stm32_cryp_hw_init(cryp); 9969e054ec2SFabien DESSENNE out: 9979e054ec2SFabien DESSENNE if (ret) 9989e054ec2SFabien DESSENNE mutex_unlock(&cryp->lock); 9999e054ec2SFabien DESSENNE 10009e054ec2SFabien DESSENNE return ret; 10019e054ec2SFabien DESSENNE } 10029e054ec2SFabien DESSENNE 10039e054ec2SFabien DESSENNE static int stm32_cryp_prepare_cipher_req(struct crypto_engine *engine, 1004dc7bcef5SCorentin LABBE void *areq) 10059e054ec2SFabien DESSENNE { 1006dc7bcef5SCorentin LABBE struct ablkcipher_request *req = container_of(areq, 1007dc7bcef5SCorentin LABBE struct ablkcipher_request, 1008dc7bcef5SCorentin LABBE base); 1009dc7bcef5SCorentin LABBE 10109d3b5030SFabien DESSENNE return stm32_cryp_prepare_req(req, NULL); 10119e054ec2SFabien DESSENNE } 10129e054ec2SFabien DESSENNE 1013dc7bcef5SCorentin LABBE static int stm32_cryp_cipher_one_req(struct crypto_engine *engine, void *areq) 10149e054ec2SFabien DESSENNE { 1015dc7bcef5SCorentin LABBE struct ablkcipher_request *req = container_of(areq, 1016dc7bcef5SCorentin LABBE struct ablkcipher_request, 1017dc7bcef5SCorentin LABBE base); 10189e054ec2SFabien DESSENNE struct stm32_cryp_ctx *ctx = crypto_ablkcipher_ctx( 10199e054ec2SFabien DESSENNE crypto_ablkcipher_reqtfm(req)); 10209e054ec2SFabien DESSENNE struct stm32_cryp *cryp = ctx->cryp; 10219e054ec2SFabien DESSENNE 10229e054ec2SFabien DESSENNE if (!cryp) 10239e054ec2SFabien DESSENNE return -ENODEV; 10249e054ec2SFabien DESSENNE 10259e054ec2SFabien DESSENNE return stm32_cryp_cpu_start(cryp); 10269e054ec2SFabien DESSENNE } 10279e054ec2SFabien DESSENNE 10289d3b5030SFabien DESSENNE static int stm32_cryp_prepare_aead_req(struct crypto_engine *engine, void *areq) 10299d3b5030SFabien DESSENNE { 10309d3b5030SFabien DESSENNE struct aead_request *req = container_of(areq, struct aead_request, 10319d3b5030SFabien DESSENNE base); 10329d3b5030SFabien DESSENNE 10339d3b5030SFabien DESSENNE return stm32_cryp_prepare_req(NULL, req); 10349d3b5030SFabien DESSENNE } 10359d3b5030SFabien DESSENNE 10369d3b5030SFabien DESSENNE static int stm32_cryp_aead_one_req(struct crypto_engine *engine, void *areq) 10379d3b5030SFabien DESSENNE { 10389d3b5030SFabien DESSENNE struct aead_request *req = container_of(areq, struct aead_request, 10399d3b5030SFabien DESSENNE base); 10409d3b5030SFabien DESSENNE struct stm32_cryp_ctx *ctx = crypto_aead_ctx(crypto_aead_reqtfm(req)); 10419d3b5030SFabien DESSENNE struct stm32_cryp *cryp = ctx->cryp; 10429d3b5030SFabien DESSENNE 10439d3b5030SFabien DESSENNE if (!cryp) 10449d3b5030SFabien DESSENNE return -ENODEV; 10459d3b5030SFabien DESSENNE 10469d3b5030SFabien DESSENNE if (unlikely(!cryp->areq->assoclen && 10479d3b5030SFabien DESSENNE !stm32_cryp_get_input_text_len(cryp))) { 10489d3b5030SFabien DESSENNE /* No input data to process: get tag and finish */ 10499d3b5030SFabien DESSENNE stm32_cryp_finish_req(cryp, 0); 10509d3b5030SFabien DESSENNE return 0; 10519d3b5030SFabien DESSENNE } 10529d3b5030SFabien DESSENNE 10539d3b5030SFabien DESSENNE return stm32_cryp_cpu_start(cryp); 10549d3b5030SFabien DESSENNE } 10559d3b5030SFabien DESSENNE 10569e054ec2SFabien DESSENNE static u32 *stm32_cryp_next_out(struct stm32_cryp *cryp, u32 *dst, 10579e054ec2SFabien DESSENNE unsigned int n) 10589e054ec2SFabien DESSENNE { 10599e054ec2SFabien DESSENNE scatterwalk_advance(&cryp->out_walk, n); 10609e054ec2SFabien DESSENNE 10619e054ec2SFabien DESSENNE if (unlikely(cryp->out_sg->length == _walked_out)) { 10629e054ec2SFabien DESSENNE cryp->out_sg = sg_next(cryp->out_sg); 10639e054ec2SFabien DESSENNE if (cryp->out_sg) { 10649e054ec2SFabien DESSENNE scatterwalk_start(&cryp->out_walk, cryp->out_sg); 10659e054ec2SFabien DESSENNE return (sg_virt(cryp->out_sg) + _walked_out); 10669e054ec2SFabien DESSENNE } 10679e054ec2SFabien DESSENNE } 10689e054ec2SFabien DESSENNE 10699e054ec2SFabien DESSENNE return (u32 *)((u8 *)dst + n); 10709e054ec2SFabien DESSENNE } 10719e054ec2SFabien DESSENNE 10729e054ec2SFabien DESSENNE static u32 *stm32_cryp_next_in(struct stm32_cryp *cryp, u32 *src, 10739e054ec2SFabien DESSENNE unsigned int n) 10749e054ec2SFabien DESSENNE { 10759e054ec2SFabien DESSENNE scatterwalk_advance(&cryp->in_walk, n); 10769e054ec2SFabien DESSENNE 10779e054ec2SFabien DESSENNE if (unlikely(cryp->in_sg->length == _walked_in)) { 10789e054ec2SFabien DESSENNE cryp->in_sg = sg_next(cryp->in_sg); 10799e054ec2SFabien DESSENNE if (cryp->in_sg) { 10809e054ec2SFabien DESSENNE scatterwalk_start(&cryp->in_walk, cryp->in_sg); 10819e054ec2SFabien DESSENNE return (sg_virt(cryp->in_sg) + _walked_in); 10829e054ec2SFabien DESSENNE } 10839e054ec2SFabien DESSENNE } 10849e054ec2SFabien DESSENNE 10859e054ec2SFabien DESSENNE return (u32 *)((u8 *)src + n); 10869e054ec2SFabien DESSENNE } 10879e054ec2SFabien DESSENNE 10889d3b5030SFabien DESSENNE static int stm32_cryp_read_auth_tag(struct stm32_cryp *cryp) 10899d3b5030SFabien DESSENNE { 10909d3b5030SFabien DESSENNE u32 cfg, size_bit, *dst, d32; 10919d3b5030SFabien DESSENNE u8 *d8; 10929d3b5030SFabien DESSENNE unsigned int i, j; 10939d3b5030SFabien DESSENNE int ret = 0; 10949d3b5030SFabien DESSENNE 10959d3b5030SFabien DESSENNE /* Update Config */ 10969d3b5030SFabien DESSENNE cfg = stm32_cryp_read(cryp, CRYP_CR); 10979d3b5030SFabien DESSENNE 10989d3b5030SFabien DESSENNE cfg &= ~CR_PH_MASK; 10999d3b5030SFabien DESSENNE cfg |= CR_PH_FINAL; 11009d3b5030SFabien DESSENNE cfg &= ~CR_DEC_NOT_ENC; 11019d3b5030SFabien DESSENNE cfg |= CR_CRYPEN; 11029d3b5030SFabien DESSENNE 11039d3b5030SFabien DESSENNE stm32_cryp_write(cryp, CRYP_CR, cfg); 11049d3b5030SFabien DESSENNE 11059d3b5030SFabien DESSENNE if (is_gcm(cryp)) { 11069d3b5030SFabien DESSENNE /* GCM: write aad and payload size (in bits) */ 11079d3b5030SFabien DESSENNE size_bit = cryp->areq->assoclen * 8; 11089d3b5030SFabien DESSENNE if (cryp->caps->swap_final) 11099d3b5030SFabien DESSENNE size_bit = cpu_to_be32(size_bit); 11109d3b5030SFabien DESSENNE 11119d3b5030SFabien DESSENNE stm32_cryp_write(cryp, CRYP_DIN, 0); 11129d3b5030SFabien DESSENNE stm32_cryp_write(cryp, CRYP_DIN, size_bit); 11139d3b5030SFabien DESSENNE 11149d3b5030SFabien DESSENNE size_bit = is_encrypt(cryp) ? cryp->areq->cryptlen : 11159d3b5030SFabien DESSENNE cryp->areq->cryptlen - AES_BLOCK_SIZE; 11169d3b5030SFabien DESSENNE size_bit *= 8; 11179d3b5030SFabien DESSENNE if (cryp->caps->swap_final) 11189d3b5030SFabien DESSENNE size_bit = cpu_to_be32(size_bit); 11199d3b5030SFabien DESSENNE 11209d3b5030SFabien DESSENNE stm32_cryp_write(cryp, CRYP_DIN, 0); 11219d3b5030SFabien DESSENNE stm32_cryp_write(cryp, CRYP_DIN, size_bit); 11229d3b5030SFabien DESSENNE } else { 11239d3b5030SFabien DESSENNE /* CCM: write CTR0 */ 11249d3b5030SFabien DESSENNE u8 iv[AES_BLOCK_SIZE]; 11259d3b5030SFabien DESSENNE u32 *iv32 = (u32 *)iv; 11269d3b5030SFabien DESSENNE 11279d3b5030SFabien DESSENNE memcpy(iv, cryp->areq->iv, AES_BLOCK_SIZE); 11289d3b5030SFabien DESSENNE memset(iv + AES_BLOCK_SIZE - 1 - iv[0], 0, iv[0] + 1); 11299d3b5030SFabien DESSENNE 11309d3b5030SFabien DESSENNE for (i = 0; i < AES_BLOCK_32; i++) { 11319d3b5030SFabien DESSENNE if (!cryp->caps->padding_wa) 11329d3b5030SFabien DESSENNE *iv32 = cpu_to_be32(*iv32); 11339d3b5030SFabien DESSENNE stm32_cryp_write(cryp, CRYP_DIN, *iv32++); 11349d3b5030SFabien DESSENNE } 11359d3b5030SFabien DESSENNE } 11369d3b5030SFabien DESSENNE 11379d3b5030SFabien DESSENNE /* Wait for output data */ 11389d3b5030SFabien DESSENNE ret = stm32_cryp_wait_output(cryp); 11399d3b5030SFabien DESSENNE if (ret) { 11409d3b5030SFabien DESSENNE dev_err(cryp->dev, "Timeout (read tag)\n"); 11419d3b5030SFabien DESSENNE return ret; 11429d3b5030SFabien DESSENNE } 11439d3b5030SFabien DESSENNE 11449d3b5030SFabien DESSENNE if (is_encrypt(cryp)) { 11459d3b5030SFabien DESSENNE /* Get and write tag */ 11469d3b5030SFabien DESSENNE dst = sg_virt(cryp->out_sg) + _walked_out; 11479d3b5030SFabien DESSENNE 11489d3b5030SFabien DESSENNE for (i = 0; i < AES_BLOCK_32; i++) { 11499d3b5030SFabien DESSENNE if (cryp->total_out >= sizeof(u32)) { 11509d3b5030SFabien DESSENNE /* Read a full u32 */ 11519d3b5030SFabien DESSENNE *dst = stm32_cryp_read(cryp, CRYP_DOUT); 11529d3b5030SFabien DESSENNE 11539d3b5030SFabien DESSENNE dst = stm32_cryp_next_out(cryp, dst, 11549d3b5030SFabien DESSENNE sizeof(u32)); 11559d3b5030SFabien DESSENNE cryp->total_out -= sizeof(u32); 11569d3b5030SFabien DESSENNE } else if (!cryp->total_out) { 11579d3b5030SFabien DESSENNE /* Empty fifo out (data from input padding) */ 11589d3b5030SFabien DESSENNE stm32_cryp_read(cryp, CRYP_DOUT); 11599d3b5030SFabien DESSENNE } else { 11609d3b5030SFabien DESSENNE /* Read less than an u32 */ 11619d3b5030SFabien DESSENNE d32 = stm32_cryp_read(cryp, CRYP_DOUT); 11629d3b5030SFabien DESSENNE d8 = (u8 *)&d32; 11639d3b5030SFabien DESSENNE 11649d3b5030SFabien DESSENNE for (j = 0; j < cryp->total_out; j++) { 11659d3b5030SFabien DESSENNE *((u8 *)dst) = *(d8++); 11669d3b5030SFabien DESSENNE dst = stm32_cryp_next_out(cryp, dst, 1); 11679d3b5030SFabien DESSENNE } 11689d3b5030SFabien DESSENNE cryp->total_out = 0; 11699d3b5030SFabien DESSENNE } 11709d3b5030SFabien DESSENNE } 11719d3b5030SFabien DESSENNE } else { 11729d3b5030SFabien DESSENNE /* Get and check tag */ 11739d3b5030SFabien DESSENNE u32 in_tag[AES_BLOCK_32], out_tag[AES_BLOCK_32]; 11749d3b5030SFabien DESSENNE 11759d3b5030SFabien DESSENNE scatterwalk_map_and_copy(in_tag, cryp->in_sg, 11769d3b5030SFabien DESSENNE cryp->total_in_save - cryp->authsize, 11779d3b5030SFabien DESSENNE cryp->authsize, 0); 11789d3b5030SFabien DESSENNE 11799d3b5030SFabien DESSENNE for (i = 0; i < AES_BLOCK_32; i++) 11809d3b5030SFabien DESSENNE out_tag[i] = stm32_cryp_read(cryp, CRYP_DOUT); 11819d3b5030SFabien DESSENNE 11829d3b5030SFabien DESSENNE if (crypto_memneq(in_tag, out_tag, cryp->authsize)) 11839d3b5030SFabien DESSENNE ret = -EBADMSG; 11849d3b5030SFabien DESSENNE } 11859d3b5030SFabien DESSENNE 11869d3b5030SFabien DESSENNE /* Disable cryp */ 11879d3b5030SFabien DESSENNE cfg &= ~CR_CRYPEN; 11889d3b5030SFabien DESSENNE stm32_cryp_write(cryp, CRYP_CR, cfg); 11899d3b5030SFabien DESSENNE 11909d3b5030SFabien DESSENNE return ret; 11919d3b5030SFabien DESSENNE } 11929d3b5030SFabien DESSENNE 11939e054ec2SFabien DESSENNE static void stm32_cryp_check_ctr_counter(struct stm32_cryp *cryp) 11949e054ec2SFabien DESSENNE { 11959e054ec2SFabien DESSENNE u32 cr; 11969e054ec2SFabien DESSENNE 11979e054ec2SFabien DESSENNE if (unlikely(cryp->last_ctr[3] == 0xFFFFFFFF)) { 11989e054ec2SFabien DESSENNE cryp->last_ctr[3] = 0; 11999e054ec2SFabien DESSENNE cryp->last_ctr[2]++; 12009e054ec2SFabien DESSENNE if (!cryp->last_ctr[2]) { 12019e054ec2SFabien DESSENNE cryp->last_ctr[1]++; 12029e054ec2SFabien DESSENNE if (!cryp->last_ctr[1]) 12039e054ec2SFabien DESSENNE cryp->last_ctr[0]++; 12049e054ec2SFabien DESSENNE } 12059e054ec2SFabien DESSENNE 12069e054ec2SFabien DESSENNE cr = stm32_cryp_read(cryp, CRYP_CR); 12079e054ec2SFabien DESSENNE stm32_cryp_write(cryp, CRYP_CR, cr & ~CR_CRYPEN); 12089e054ec2SFabien DESSENNE 12099e054ec2SFabien DESSENNE stm32_cryp_hw_write_iv(cryp, (u32 *)cryp->last_ctr); 12109e054ec2SFabien DESSENNE 12119e054ec2SFabien DESSENNE stm32_cryp_write(cryp, CRYP_CR, cr); 12129e054ec2SFabien DESSENNE } 12139e054ec2SFabien DESSENNE 12149e054ec2SFabien DESSENNE cryp->last_ctr[0] = stm32_cryp_read(cryp, CRYP_IV0LR); 12159e054ec2SFabien DESSENNE cryp->last_ctr[1] = stm32_cryp_read(cryp, CRYP_IV0RR); 12169e054ec2SFabien DESSENNE cryp->last_ctr[2] = stm32_cryp_read(cryp, CRYP_IV1LR); 12179e054ec2SFabien DESSENNE cryp->last_ctr[3] = stm32_cryp_read(cryp, CRYP_IV1RR); 12189e054ec2SFabien DESSENNE } 12199e054ec2SFabien DESSENNE 12209e054ec2SFabien DESSENNE static bool stm32_cryp_irq_read_data(struct stm32_cryp *cryp) 12219e054ec2SFabien DESSENNE { 12229e054ec2SFabien DESSENNE unsigned int i, j; 12239e054ec2SFabien DESSENNE u32 d32, *dst; 12249e054ec2SFabien DESSENNE u8 *d8; 12259d3b5030SFabien DESSENNE size_t tag_size; 12269d3b5030SFabien DESSENNE 12279d3b5030SFabien DESSENNE /* Do no read tag now (if any) */ 12289d3b5030SFabien DESSENNE if (is_encrypt(cryp) && (is_gcm(cryp) || is_ccm(cryp))) 12299d3b5030SFabien DESSENNE tag_size = cryp->authsize; 12309d3b5030SFabien DESSENNE else 12319d3b5030SFabien DESSENNE tag_size = 0; 12329e054ec2SFabien DESSENNE 12339e054ec2SFabien DESSENNE dst = sg_virt(cryp->out_sg) + _walked_out; 12349e054ec2SFabien DESSENNE 12359e054ec2SFabien DESSENNE for (i = 0; i < cryp->hw_blocksize / sizeof(u32); i++) { 12369d3b5030SFabien DESSENNE if (likely(cryp->total_out - tag_size >= sizeof(u32))) { 12379e054ec2SFabien DESSENNE /* Read a full u32 */ 12389e054ec2SFabien DESSENNE *dst = stm32_cryp_read(cryp, CRYP_DOUT); 12399e054ec2SFabien DESSENNE 12409e054ec2SFabien DESSENNE dst = stm32_cryp_next_out(cryp, dst, sizeof(u32)); 12419e054ec2SFabien DESSENNE cryp->total_out -= sizeof(u32); 12429d3b5030SFabien DESSENNE } else if (cryp->total_out == tag_size) { 12439e054ec2SFabien DESSENNE /* Empty fifo out (data from input padding) */ 12449e054ec2SFabien DESSENNE d32 = stm32_cryp_read(cryp, CRYP_DOUT); 12459e054ec2SFabien DESSENNE } else { 12469e054ec2SFabien DESSENNE /* Read less than an u32 */ 12479e054ec2SFabien DESSENNE d32 = stm32_cryp_read(cryp, CRYP_DOUT); 12489e054ec2SFabien DESSENNE d8 = (u8 *)&d32; 12499e054ec2SFabien DESSENNE 12509d3b5030SFabien DESSENNE for (j = 0; j < cryp->total_out - tag_size; j++) { 12519e054ec2SFabien DESSENNE *((u8 *)dst) = *(d8++); 12529e054ec2SFabien DESSENNE dst = stm32_cryp_next_out(cryp, dst, 1); 12539e054ec2SFabien DESSENNE } 12549d3b5030SFabien DESSENNE cryp->total_out = tag_size; 12559e054ec2SFabien DESSENNE } 12569e054ec2SFabien DESSENNE } 12579e054ec2SFabien DESSENNE 12589d3b5030SFabien DESSENNE return !(cryp->total_out - tag_size) || !cryp->total_in; 12599e054ec2SFabien DESSENNE } 12609e054ec2SFabien DESSENNE 12619e054ec2SFabien DESSENNE static void stm32_cryp_irq_write_block(struct stm32_cryp *cryp) 12629e054ec2SFabien DESSENNE { 12639e054ec2SFabien DESSENNE unsigned int i, j; 12649e054ec2SFabien DESSENNE u32 *src; 12659e054ec2SFabien DESSENNE u8 d8[4]; 12669d3b5030SFabien DESSENNE size_t tag_size; 12679d3b5030SFabien DESSENNE 12689d3b5030SFabien DESSENNE /* Do no write tag (if any) */ 12699d3b5030SFabien DESSENNE if (is_decrypt(cryp) && (is_gcm(cryp) || is_ccm(cryp))) 12709d3b5030SFabien DESSENNE tag_size = cryp->authsize; 12719d3b5030SFabien DESSENNE else 12729d3b5030SFabien DESSENNE tag_size = 0; 12739e054ec2SFabien DESSENNE 12749e054ec2SFabien DESSENNE src = sg_virt(cryp->in_sg) + _walked_in; 12759e054ec2SFabien DESSENNE 12769e054ec2SFabien DESSENNE for (i = 0; i < cryp->hw_blocksize / sizeof(u32); i++) { 12779d3b5030SFabien DESSENNE if (likely(cryp->total_in - tag_size >= sizeof(u32))) { 12789e054ec2SFabien DESSENNE /* Write a full u32 */ 12799e054ec2SFabien DESSENNE stm32_cryp_write(cryp, CRYP_DIN, *src); 12809e054ec2SFabien DESSENNE 12819e054ec2SFabien DESSENNE src = stm32_cryp_next_in(cryp, src, sizeof(u32)); 12829e054ec2SFabien DESSENNE cryp->total_in -= sizeof(u32); 12839d3b5030SFabien DESSENNE } else if (cryp->total_in == tag_size) { 12849e054ec2SFabien DESSENNE /* Write padding data */ 12859e054ec2SFabien DESSENNE stm32_cryp_write(cryp, CRYP_DIN, 0); 12869e054ec2SFabien DESSENNE } else { 12879e054ec2SFabien DESSENNE /* Write less than an u32 */ 12889e054ec2SFabien DESSENNE memset(d8, 0, sizeof(u32)); 12899d3b5030SFabien DESSENNE for (j = 0; j < cryp->total_in - tag_size; j++) { 12909e054ec2SFabien DESSENNE d8[j] = *((u8 *)src); 12919e054ec2SFabien DESSENNE src = stm32_cryp_next_in(cryp, src, 1); 12929e054ec2SFabien DESSENNE } 12939e054ec2SFabien DESSENNE 12949e054ec2SFabien DESSENNE stm32_cryp_write(cryp, CRYP_DIN, *(u32 *)d8); 12959d3b5030SFabien DESSENNE cryp->total_in = tag_size; 12969e054ec2SFabien DESSENNE } 12979e054ec2SFabien DESSENNE } 12989e054ec2SFabien DESSENNE } 12999e054ec2SFabien DESSENNE 13009d3b5030SFabien DESSENNE static void stm32_cryp_irq_write_gcm_padded_data(struct stm32_cryp *cryp) 13019d3b5030SFabien DESSENNE { 13029d3b5030SFabien DESSENNE int err; 13039d3b5030SFabien DESSENNE u32 cfg, tmp[AES_BLOCK_32]; 13049d3b5030SFabien DESSENNE size_t total_in_ori = cryp->total_in; 13059d3b5030SFabien DESSENNE struct scatterlist *out_sg_ori = cryp->out_sg; 13069d3b5030SFabien DESSENNE unsigned int i; 13079d3b5030SFabien DESSENNE 13089d3b5030SFabien DESSENNE /* 'Special workaround' procedure described in the datasheet */ 13099d3b5030SFabien DESSENNE 13109d3b5030SFabien DESSENNE /* a) disable ip */ 13119d3b5030SFabien DESSENNE stm32_cryp_write(cryp, CRYP_IMSCR, 0); 13129d3b5030SFabien DESSENNE cfg = stm32_cryp_read(cryp, CRYP_CR); 13139d3b5030SFabien DESSENNE cfg &= ~CR_CRYPEN; 13149d3b5030SFabien DESSENNE stm32_cryp_write(cryp, CRYP_CR, cfg); 13159d3b5030SFabien DESSENNE 13169d3b5030SFabien DESSENNE /* b) Update IV1R */ 13179d3b5030SFabien DESSENNE stm32_cryp_write(cryp, CRYP_IV1RR, cryp->gcm_ctr - 2); 13189d3b5030SFabien DESSENNE 13199d3b5030SFabien DESSENNE /* c) change mode to CTR */ 13209d3b5030SFabien DESSENNE cfg &= ~CR_ALGO_MASK; 13219d3b5030SFabien DESSENNE cfg |= CR_AES_CTR; 13229d3b5030SFabien DESSENNE stm32_cryp_write(cryp, CRYP_CR, cfg); 13239d3b5030SFabien DESSENNE 13249d3b5030SFabien DESSENNE /* a) enable IP */ 13259d3b5030SFabien DESSENNE cfg |= CR_CRYPEN; 13269d3b5030SFabien DESSENNE stm32_cryp_write(cryp, CRYP_CR, cfg); 13279d3b5030SFabien DESSENNE 13289d3b5030SFabien DESSENNE /* b) pad and write the last block */ 13299d3b5030SFabien DESSENNE stm32_cryp_irq_write_block(cryp); 13309d3b5030SFabien DESSENNE cryp->total_in = total_in_ori; 13319d3b5030SFabien DESSENNE err = stm32_cryp_wait_output(cryp); 13329d3b5030SFabien DESSENNE if (err) { 13339d3b5030SFabien DESSENNE dev_err(cryp->dev, "Timeout (write gcm header)\n"); 13349d3b5030SFabien DESSENNE return stm32_cryp_finish_req(cryp, err); 13359d3b5030SFabien DESSENNE } 13369d3b5030SFabien DESSENNE 13379d3b5030SFabien DESSENNE /* c) get and store encrypted data */ 13389d3b5030SFabien DESSENNE stm32_cryp_irq_read_data(cryp); 13399d3b5030SFabien DESSENNE scatterwalk_map_and_copy(tmp, out_sg_ori, 13409d3b5030SFabien DESSENNE cryp->total_in_save - total_in_ori, 13419d3b5030SFabien DESSENNE total_in_ori, 0); 13429d3b5030SFabien DESSENNE 13439d3b5030SFabien DESSENNE /* d) change mode back to AES GCM */ 13449d3b5030SFabien DESSENNE cfg &= ~CR_ALGO_MASK; 13459d3b5030SFabien DESSENNE cfg |= CR_AES_GCM; 13469d3b5030SFabien DESSENNE stm32_cryp_write(cryp, CRYP_CR, cfg); 13479d3b5030SFabien DESSENNE 13489d3b5030SFabien DESSENNE /* e) change phase to Final */ 13499d3b5030SFabien DESSENNE cfg &= ~CR_PH_MASK; 13509d3b5030SFabien DESSENNE cfg |= CR_PH_FINAL; 13519d3b5030SFabien DESSENNE stm32_cryp_write(cryp, CRYP_CR, cfg); 13529d3b5030SFabien DESSENNE 13539d3b5030SFabien DESSENNE /* f) write padded data */ 13549d3b5030SFabien DESSENNE for (i = 0; i < AES_BLOCK_32; i++) { 13559d3b5030SFabien DESSENNE if (cryp->total_in) 13569d3b5030SFabien DESSENNE stm32_cryp_write(cryp, CRYP_DIN, tmp[i]); 13579d3b5030SFabien DESSENNE else 13589d3b5030SFabien DESSENNE stm32_cryp_write(cryp, CRYP_DIN, 0); 13599d3b5030SFabien DESSENNE 13609d3b5030SFabien DESSENNE cryp->total_in -= min_t(size_t, sizeof(u32), cryp->total_in); 13619d3b5030SFabien DESSENNE } 13629d3b5030SFabien DESSENNE 13639d3b5030SFabien DESSENNE /* g) Empty fifo out */ 13649d3b5030SFabien DESSENNE err = stm32_cryp_wait_output(cryp); 13659d3b5030SFabien DESSENNE if (err) { 13669d3b5030SFabien DESSENNE dev_err(cryp->dev, "Timeout (write gcm header)\n"); 13679d3b5030SFabien DESSENNE return stm32_cryp_finish_req(cryp, err); 13689d3b5030SFabien DESSENNE } 13699d3b5030SFabien DESSENNE 13709d3b5030SFabien DESSENNE for (i = 0; i < AES_BLOCK_32; i++) 13719d3b5030SFabien DESSENNE stm32_cryp_read(cryp, CRYP_DOUT); 13729d3b5030SFabien DESSENNE 13739d3b5030SFabien DESSENNE /* h) run the he normal Final phase */ 13749d3b5030SFabien DESSENNE stm32_cryp_finish_req(cryp, 0); 13759d3b5030SFabien DESSENNE } 13769d3b5030SFabien DESSENNE 13779d3b5030SFabien DESSENNE static void stm32_cryp_irq_set_npblb(struct stm32_cryp *cryp) 13789d3b5030SFabien DESSENNE { 13799d3b5030SFabien DESSENNE u32 cfg, payload_bytes; 13809d3b5030SFabien DESSENNE 13819d3b5030SFabien DESSENNE /* disable ip, set NPBLB and reneable ip */ 13829d3b5030SFabien DESSENNE cfg = stm32_cryp_read(cryp, CRYP_CR); 13839d3b5030SFabien DESSENNE cfg &= ~CR_CRYPEN; 13849d3b5030SFabien DESSENNE stm32_cryp_write(cryp, CRYP_CR, cfg); 13859d3b5030SFabien DESSENNE 13869d3b5030SFabien DESSENNE payload_bytes = is_decrypt(cryp) ? cryp->total_in - cryp->authsize : 13879d3b5030SFabien DESSENNE cryp->total_in; 13889d3b5030SFabien DESSENNE cfg |= (cryp->hw_blocksize - payload_bytes) << CR_NBPBL_SHIFT; 13899d3b5030SFabien DESSENNE cfg |= CR_CRYPEN; 13909d3b5030SFabien DESSENNE stm32_cryp_write(cryp, CRYP_CR, cfg); 13919d3b5030SFabien DESSENNE } 13929d3b5030SFabien DESSENNE 13939d3b5030SFabien DESSENNE static void stm32_cryp_irq_write_ccm_padded_data(struct stm32_cryp *cryp) 13949d3b5030SFabien DESSENNE { 13959d3b5030SFabien DESSENNE int err = 0; 13969d3b5030SFabien DESSENNE u32 cfg, iv1tmp; 13979d3b5030SFabien DESSENNE u32 cstmp1[AES_BLOCK_32], cstmp2[AES_BLOCK_32], tmp[AES_BLOCK_32]; 13989d3b5030SFabien DESSENNE size_t last_total_out, total_in_ori = cryp->total_in; 13999d3b5030SFabien DESSENNE struct scatterlist *out_sg_ori = cryp->out_sg; 14009d3b5030SFabien DESSENNE unsigned int i; 14019d3b5030SFabien DESSENNE 14029d3b5030SFabien DESSENNE /* 'Special workaround' procedure described in the datasheet */ 14039d3b5030SFabien DESSENNE cryp->flags |= FLG_CCM_PADDED_WA; 14049d3b5030SFabien DESSENNE 14059d3b5030SFabien DESSENNE /* a) disable ip */ 14069d3b5030SFabien DESSENNE stm32_cryp_write(cryp, CRYP_IMSCR, 0); 14079d3b5030SFabien DESSENNE 14089d3b5030SFabien DESSENNE cfg = stm32_cryp_read(cryp, CRYP_CR); 14099d3b5030SFabien DESSENNE cfg &= ~CR_CRYPEN; 14109d3b5030SFabien DESSENNE stm32_cryp_write(cryp, CRYP_CR, cfg); 14119d3b5030SFabien DESSENNE 14129d3b5030SFabien DESSENNE /* b) get IV1 from CRYP_CSGCMCCM7 */ 14139d3b5030SFabien DESSENNE iv1tmp = stm32_cryp_read(cryp, CRYP_CSGCMCCM0R + 7 * 4); 14149d3b5030SFabien DESSENNE 14159d3b5030SFabien DESSENNE /* c) Load CRYP_CSGCMCCMxR */ 14169d3b5030SFabien DESSENNE for (i = 0; i < ARRAY_SIZE(cstmp1); i++) 14179d3b5030SFabien DESSENNE cstmp1[i] = stm32_cryp_read(cryp, CRYP_CSGCMCCM0R + i * 4); 14189d3b5030SFabien DESSENNE 14199d3b5030SFabien DESSENNE /* d) Write IV1R */ 14209d3b5030SFabien DESSENNE stm32_cryp_write(cryp, CRYP_IV1RR, iv1tmp); 14219d3b5030SFabien DESSENNE 14229d3b5030SFabien DESSENNE /* e) change mode to CTR */ 14239d3b5030SFabien DESSENNE cfg &= ~CR_ALGO_MASK; 14249d3b5030SFabien DESSENNE cfg |= CR_AES_CTR; 14259d3b5030SFabien DESSENNE stm32_cryp_write(cryp, CRYP_CR, cfg); 14269d3b5030SFabien DESSENNE 14279d3b5030SFabien DESSENNE /* a) enable IP */ 14289d3b5030SFabien DESSENNE cfg |= CR_CRYPEN; 14299d3b5030SFabien DESSENNE stm32_cryp_write(cryp, CRYP_CR, cfg); 14309d3b5030SFabien DESSENNE 14319d3b5030SFabien DESSENNE /* b) pad and write the last block */ 14329d3b5030SFabien DESSENNE stm32_cryp_irq_write_block(cryp); 14339d3b5030SFabien DESSENNE cryp->total_in = total_in_ori; 14349d3b5030SFabien DESSENNE err = stm32_cryp_wait_output(cryp); 14359d3b5030SFabien DESSENNE if (err) { 14369d3b5030SFabien DESSENNE dev_err(cryp->dev, "Timeout (wite ccm padded data)\n"); 14379d3b5030SFabien DESSENNE return stm32_cryp_finish_req(cryp, err); 14389d3b5030SFabien DESSENNE } 14399d3b5030SFabien DESSENNE 14409d3b5030SFabien DESSENNE /* c) get and store decrypted data */ 14419d3b5030SFabien DESSENNE last_total_out = cryp->total_out; 14429d3b5030SFabien DESSENNE stm32_cryp_irq_read_data(cryp); 14439d3b5030SFabien DESSENNE 14449d3b5030SFabien DESSENNE memset(tmp, 0, sizeof(tmp)); 14459d3b5030SFabien DESSENNE scatterwalk_map_and_copy(tmp, out_sg_ori, 14469d3b5030SFabien DESSENNE cryp->total_out_save - last_total_out, 14479d3b5030SFabien DESSENNE last_total_out, 0); 14489d3b5030SFabien DESSENNE 14499d3b5030SFabien DESSENNE /* d) Load again CRYP_CSGCMCCMxR */ 14509d3b5030SFabien DESSENNE for (i = 0; i < ARRAY_SIZE(cstmp2); i++) 14519d3b5030SFabien DESSENNE cstmp2[i] = stm32_cryp_read(cryp, CRYP_CSGCMCCM0R + i * 4); 14529d3b5030SFabien DESSENNE 14539d3b5030SFabien DESSENNE /* e) change mode back to AES CCM */ 14549d3b5030SFabien DESSENNE cfg &= ~CR_ALGO_MASK; 14559d3b5030SFabien DESSENNE cfg |= CR_AES_CCM; 14569d3b5030SFabien DESSENNE stm32_cryp_write(cryp, CRYP_CR, cfg); 14579d3b5030SFabien DESSENNE 14589d3b5030SFabien DESSENNE /* f) change phase to header */ 14599d3b5030SFabien DESSENNE cfg &= ~CR_PH_MASK; 14609d3b5030SFabien DESSENNE cfg |= CR_PH_HEADER; 14619d3b5030SFabien DESSENNE stm32_cryp_write(cryp, CRYP_CR, cfg); 14629d3b5030SFabien DESSENNE 14639d3b5030SFabien DESSENNE /* g) XOR and write padded data */ 14649d3b5030SFabien DESSENNE for (i = 0; i < ARRAY_SIZE(tmp); i++) { 14659d3b5030SFabien DESSENNE tmp[i] ^= cstmp1[i]; 14669d3b5030SFabien DESSENNE tmp[i] ^= cstmp2[i]; 14679d3b5030SFabien DESSENNE stm32_cryp_write(cryp, CRYP_DIN, tmp[i]); 14689d3b5030SFabien DESSENNE } 14699d3b5030SFabien DESSENNE 14709d3b5030SFabien DESSENNE /* h) wait for completion */ 14719d3b5030SFabien DESSENNE err = stm32_cryp_wait_busy(cryp); 14729d3b5030SFabien DESSENNE if (err) 14739d3b5030SFabien DESSENNE dev_err(cryp->dev, "Timeout (wite ccm padded data)\n"); 14749d3b5030SFabien DESSENNE 14759d3b5030SFabien DESSENNE /* i) run the he normal Final phase */ 14769d3b5030SFabien DESSENNE stm32_cryp_finish_req(cryp, err); 14779d3b5030SFabien DESSENNE } 14789d3b5030SFabien DESSENNE 14799e054ec2SFabien DESSENNE static void stm32_cryp_irq_write_data(struct stm32_cryp *cryp) 14809e054ec2SFabien DESSENNE { 14819e054ec2SFabien DESSENNE if (unlikely(!cryp->total_in)) { 14829e054ec2SFabien DESSENNE dev_warn(cryp->dev, "No more data to process\n"); 14839e054ec2SFabien DESSENNE return; 14849e054ec2SFabien DESSENNE } 14859e054ec2SFabien DESSENNE 14869d3b5030SFabien DESSENNE if (unlikely(cryp->total_in < AES_BLOCK_SIZE && 14879d3b5030SFabien DESSENNE (stm32_cryp_get_hw_mode(cryp) == CR_AES_GCM) && 14889d3b5030SFabien DESSENNE is_encrypt(cryp))) { 14899d3b5030SFabien DESSENNE /* Padding for AES GCM encryption */ 14909d3b5030SFabien DESSENNE if (cryp->caps->padding_wa) 14919d3b5030SFabien DESSENNE /* Special case 1 */ 14929d3b5030SFabien DESSENNE return stm32_cryp_irq_write_gcm_padded_data(cryp); 14939d3b5030SFabien DESSENNE 14949d3b5030SFabien DESSENNE /* Setting padding bytes (NBBLB) */ 14959d3b5030SFabien DESSENNE stm32_cryp_irq_set_npblb(cryp); 14969d3b5030SFabien DESSENNE } 14979d3b5030SFabien DESSENNE 14989d3b5030SFabien DESSENNE if (unlikely((cryp->total_in - cryp->authsize < AES_BLOCK_SIZE) && 14999d3b5030SFabien DESSENNE (stm32_cryp_get_hw_mode(cryp) == CR_AES_CCM) && 15009d3b5030SFabien DESSENNE is_decrypt(cryp))) { 15019d3b5030SFabien DESSENNE /* Padding for AES CCM decryption */ 15029d3b5030SFabien DESSENNE if (cryp->caps->padding_wa) 15039d3b5030SFabien DESSENNE /* Special case 2 */ 15049d3b5030SFabien DESSENNE return stm32_cryp_irq_write_ccm_padded_data(cryp); 15059d3b5030SFabien DESSENNE 15069d3b5030SFabien DESSENNE /* Setting padding bytes (NBBLB) */ 15079d3b5030SFabien DESSENNE stm32_cryp_irq_set_npblb(cryp); 15089d3b5030SFabien DESSENNE } 15099d3b5030SFabien DESSENNE 15109e054ec2SFabien DESSENNE if (is_aes(cryp) && is_ctr(cryp)) 15119e054ec2SFabien DESSENNE stm32_cryp_check_ctr_counter(cryp); 15129e054ec2SFabien DESSENNE 15139e054ec2SFabien DESSENNE stm32_cryp_irq_write_block(cryp); 15149e054ec2SFabien DESSENNE } 15159e054ec2SFabien DESSENNE 15169d3b5030SFabien DESSENNE static void stm32_cryp_irq_write_gcm_header(struct stm32_cryp *cryp) 15179d3b5030SFabien DESSENNE { 15189d3b5030SFabien DESSENNE int err; 15199d3b5030SFabien DESSENNE unsigned int i, j; 15209d3b5030SFabien DESSENNE u32 cfg, *src; 15219d3b5030SFabien DESSENNE 15229d3b5030SFabien DESSENNE src = sg_virt(cryp->in_sg) + _walked_in; 15239d3b5030SFabien DESSENNE 15249d3b5030SFabien DESSENNE for (i = 0; i < AES_BLOCK_32; i++) { 15259d3b5030SFabien DESSENNE stm32_cryp_write(cryp, CRYP_DIN, *src); 15269d3b5030SFabien DESSENNE 15279d3b5030SFabien DESSENNE src = stm32_cryp_next_in(cryp, src, sizeof(u32)); 15289d3b5030SFabien DESSENNE cryp->total_in -= min_t(size_t, sizeof(u32), cryp->total_in); 15299d3b5030SFabien DESSENNE 15309d3b5030SFabien DESSENNE /* Check if whole header written */ 15319d3b5030SFabien DESSENNE if ((cryp->total_in_save - cryp->total_in) == 15329d3b5030SFabien DESSENNE cryp->areq->assoclen) { 15339d3b5030SFabien DESSENNE /* Write padding if needed */ 15349d3b5030SFabien DESSENNE for (j = i + 1; j < AES_BLOCK_32; j++) 15359d3b5030SFabien DESSENNE stm32_cryp_write(cryp, CRYP_DIN, 0); 15369d3b5030SFabien DESSENNE 15379d3b5030SFabien DESSENNE /* Wait for completion */ 15389d3b5030SFabien DESSENNE err = stm32_cryp_wait_busy(cryp); 15399d3b5030SFabien DESSENNE if (err) { 15409d3b5030SFabien DESSENNE dev_err(cryp->dev, "Timeout (gcm header)\n"); 15419d3b5030SFabien DESSENNE return stm32_cryp_finish_req(cryp, err); 15429d3b5030SFabien DESSENNE } 15439d3b5030SFabien DESSENNE 15449d3b5030SFabien DESSENNE if (stm32_cryp_get_input_text_len(cryp)) { 15459d3b5030SFabien DESSENNE /* Phase 3 : payload */ 15469d3b5030SFabien DESSENNE cfg = stm32_cryp_read(cryp, CRYP_CR); 15479d3b5030SFabien DESSENNE cfg &= ~CR_CRYPEN; 15489d3b5030SFabien DESSENNE stm32_cryp_write(cryp, CRYP_CR, cfg); 15499d3b5030SFabien DESSENNE 15509d3b5030SFabien DESSENNE cfg &= ~CR_PH_MASK; 15519d3b5030SFabien DESSENNE cfg |= CR_PH_PAYLOAD; 15529d3b5030SFabien DESSENNE cfg |= CR_CRYPEN; 15539d3b5030SFabien DESSENNE stm32_cryp_write(cryp, CRYP_CR, cfg); 15549d3b5030SFabien DESSENNE } else { 15559d3b5030SFabien DESSENNE /* Phase 4 : tag */ 15569d3b5030SFabien DESSENNE stm32_cryp_write(cryp, CRYP_IMSCR, 0); 15579d3b5030SFabien DESSENNE stm32_cryp_finish_req(cryp, 0); 15589d3b5030SFabien DESSENNE } 15599d3b5030SFabien DESSENNE 15609d3b5030SFabien DESSENNE break; 15619d3b5030SFabien DESSENNE } 15629d3b5030SFabien DESSENNE 15639d3b5030SFabien DESSENNE if (!cryp->total_in) 15649d3b5030SFabien DESSENNE break; 15659d3b5030SFabien DESSENNE } 15669d3b5030SFabien DESSENNE } 15679d3b5030SFabien DESSENNE 15689d3b5030SFabien DESSENNE static void stm32_cryp_irq_write_ccm_header(struct stm32_cryp *cryp) 15699d3b5030SFabien DESSENNE { 15709d3b5030SFabien DESSENNE int err; 15719d3b5030SFabien DESSENNE unsigned int i = 0, j, k; 15729d3b5030SFabien DESSENNE u32 alen, cfg, *src; 15739d3b5030SFabien DESSENNE u8 d8[4]; 15749d3b5030SFabien DESSENNE 15759d3b5030SFabien DESSENNE src = sg_virt(cryp->in_sg) + _walked_in; 15769d3b5030SFabien DESSENNE alen = cryp->areq->assoclen; 15779d3b5030SFabien DESSENNE 15789d3b5030SFabien DESSENNE if (!_walked_in) { 15799d3b5030SFabien DESSENNE if (cryp->areq->assoclen <= 65280) { 15809d3b5030SFabien DESSENNE /* Write first u32 of B1 */ 15819d3b5030SFabien DESSENNE d8[0] = (alen >> 8) & 0xFF; 15829d3b5030SFabien DESSENNE d8[1] = alen & 0xFF; 15839d3b5030SFabien DESSENNE d8[2] = *((u8 *)src); 15849d3b5030SFabien DESSENNE src = stm32_cryp_next_in(cryp, src, 1); 15859d3b5030SFabien DESSENNE d8[3] = *((u8 *)src); 15869d3b5030SFabien DESSENNE src = stm32_cryp_next_in(cryp, src, 1); 15879d3b5030SFabien DESSENNE 15889d3b5030SFabien DESSENNE stm32_cryp_write(cryp, CRYP_DIN, *(u32 *)d8); 15899d3b5030SFabien DESSENNE i++; 15909d3b5030SFabien DESSENNE 15919d3b5030SFabien DESSENNE cryp->total_in -= min_t(size_t, 2, cryp->total_in); 15929d3b5030SFabien DESSENNE } else { 15939d3b5030SFabien DESSENNE /* Build the two first u32 of B1 */ 15949d3b5030SFabien DESSENNE d8[0] = 0xFF; 15959d3b5030SFabien DESSENNE d8[1] = 0xFE; 15969d3b5030SFabien DESSENNE d8[2] = alen & 0xFF000000; 15979d3b5030SFabien DESSENNE d8[3] = alen & 0x00FF0000; 15989d3b5030SFabien DESSENNE 15999d3b5030SFabien DESSENNE stm32_cryp_write(cryp, CRYP_DIN, *(u32 *)d8); 16009d3b5030SFabien DESSENNE i++; 16019d3b5030SFabien DESSENNE 16029d3b5030SFabien DESSENNE d8[0] = alen & 0x0000FF00; 16039d3b5030SFabien DESSENNE d8[1] = alen & 0x000000FF; 16049d3b5030SFabien DESSENNE d8[2] = *((u8 *)src); 16059d3b5030SFabien DESSENNE src = stm32_cryp_next_in(cryp, src, 1); 16069d3b5030SFabien DESSENNE d8[3] = *((u8 *)src); 16079d3b5030SFabien DESSENNE src = stm32_cryp_next_in(cryp, src, 1); 16089d3b5030SFabien DESSENNE 16099d3b5030SFabien DESSENNE stm32_cryp_write(cryp, CRYP_DIN, *(u32 *)d8); 16109d3b5030SFabien DESSENNE i++; 16119d3b5030SFabien DESSENNE 16129d3b5030SFabien DESSENNE cryp->total_in -= min_t(size_t, 2, cryp->total_in); 16139d3b5030SFabien DESSENNE } 16149d3b5030SFabien DESSENNE } 16159d3b5030SFabien DESSENNE 16169d3b5030SFabien DESSENNE /* Write next u32 */ 16179d3b5030SFabien DESSENNE for (; i < AES_BLOCK_32; i++) { 16189d3b5030SFabien DESSENNE /* Build an u32 */ 16199d3b5030SFabien DESSENNE memset(d8, 0, sizeof(u32)); 16209d3b5030SFabien DESSENNE for (k = 0; k < sizeof(u32); k++) { 16219d3b5030SFabien DESSENNE d8[k] = *((u8 *)src); 16229d3b5030SFabien DESSENNE src = stm32_cryp_next_in(cryp, src, 1); 16239d3b5030SFabien DESSENNE 16249d3b5030SFabien DESSENNE cryp->total_in -= min_t(size_t, 1, cryp->total_in); 16259d3b5030SFabien DESSENNE if ((cryp->total_in_save - cryp->total_in) == alen) 16269d3b5030SFabien DESSENNE break; 16279d3b5030SFabien DESSENNE } 16289d3b5030SFabien DESSENNE 16299d3b5030SFabien DESSENNE stm32_cryp_write(cryp, CRYP_DIN, *(u32 *)d8); 16309d3b5030SFabien DESSENNE 16319d3b5030SFabien DESSENNE if ((cryp->total_in_save - cryp->total_in) == alen) { 16329d3b5030SFabien DESSENNE /* Write padding if needed */ 16339d3b5030SFabien DESSENNE for (j = i + 1; j < AES_BLOCK_32; j++) 16349d3b5030SFabien DESSENNE stm32_cryp_write(cryp, CRYP_DIN, 0); 16359d3b5030SFabien DESSENNE 16369d3b5030SFabien DESSENNE /* Wait for completion */ 16379d3b5030SFabien DESSENNE err = stm32_cryp_wait_busy(cryp); 16389d3b5030SFabien DESSENNE if (err) { 16399d3b5030SFabien DESSENNE dev_err(cryp->dev, "Timeout (ccm header)\n"); 16409d3b5030SFabien DESSENNE return stm32_cryp_finish_req(cryp, err); 16419d3b5030SFabien DESSENNE } 16429d3b5030SFabien DESSENNE 16439d3b5030SFabien DESSENNE if (stm32_cryp_get_input_text_len(cryp)) { 16449d3b5030SFabien DESSENNE /* Phase 3 : payload */ 16459d3b5030SFabien DESSENNE cfg = stm32_cryp_read(cryp, CRYP_CR); 16469d3b5030SFabien DESSENNE cfg &= ~CR_CRYPEN; 16479d3b5030SFabien DESSENNE stm32_cryp_write(cryp, CRYP_CR, cfg); 16489d3b5030SFabien DESSENNE 16499d3b5030SFabien DESSENNE cfg &= ~CR_PH_MASK; 16509d3b5030SFabien DESSENNE cfg |= CR_PH_PAYLOAD; 16519d3b5030SFabien DESSENNE cfg |= CR_CRYPEN; 16529d3b5030SFabien DESSENNE stm32_cryp_write(cryp, CRYP_CR, cfg); 16539d3b5030SFabien DESSENNE } else { 16549d3b5030SFabien DESSENNE /* Phase 4 : tag */ 16559d3b5030SFabien DESSENNE stm32_cryp_write(cryp, CRYP_IMSCR, 0); 16569d3b5030SFabien DESSENNE stm32_cryp_finish_req(cryp, 0); 16579d3b5030SFabien DESSENNE } 16589d3b5030SFabien DESSENNE 16599d3b5030SFabien DESSENNE break; 16609d3b5030SFabien DESSENNE } 16619d3b5030SFabien DESSENNE } 16629d3b5030SFabien DESSENNE } 16639d3b5030SFabien DESSENNE 16649e054ec2SFabien DESSENNE static irqreturn_t stm32_cryp_irq_thread(int irq, void *arg) 16659e054ec2SFabien DESSENNE { 16669e054ec2SFabien DESSENNE struct stm32_cryp *cryp = arg; 16679d3b5030SFabien DESSENNE u32 ph; 16689e054ec2SFabien DESSENNE 16699e054ec2SFabien DESSENNE if (cryp->irq_status & MISR_OUT) 16709e054ec2SFabien DESSENNE /* Output FIFO IRQ: read data */ 16719e054ec2SFabien DESSENNE if (unlikely(stm32_cryp_irq_read_data(cryp))) { 16729e054ec2SFabien DESSENNE /* All bytes processed, finish */ 16739e054ec2SFabien DESSENNE stm32_cryp_write(cryp, CRYP_IMSCR, 0); 16749d3b5030SFabien DESSENNE stm32_cryp_finish_req(cryp, 0); 16759e054ec2SFabien DESSENNE return IRQ_HANDLED; 16769e054ec2SFabien DESSENNE } 16779e054ec2SFabien DESSENNE 16789e054ec2SFabien DESSENNE if (cryp->irq_status & MISR_IN) { 16799d3b5030SFabien DESSENNE if (is_gcm(cryp)) { 16809d3b5030SFabien DESSENNE ph = stm32_cryp_read(cryp, CRYP_CR) & CR_PH_MASK; 16819d3b5030SFabien DESSENNE if (unlikely(ph == CR_PH_HEADER)) 16829d3b5030SFabien DESSENNE /* Write Header */ 16839d3b5030SFabien DESSENNE stm32_cryp_irq_write_gcm_header(cryp); 16849d3b5030SFabien DESSENNE else 16859e054ec2SFabien DESSENNE /* Input FIFO IRQ: write data */ 16869e054ec2SFabien DESSENNE stm32_cryp_irq_write_data(cryp); 16879d3b5030SFabien DESSENNE cryp->gcm_ctr++; 16889d3b5030SFabien DESSENNE } else if (is_ccm(cryp)) { 16899d3b5030SFabien DESSENNE ph = stm32_cryp_read(cryp, CRYP_CR) & CR_PH_MASK; 16909d3b5030SFabien DESSENNE if (unlikely(ph == CR_PH_HEADER)) 16919d3b5030SFabien DESSENNE /* Write Header */ 16929d3b5030SFabien DESSENNE stm32_cryp_irq_write_ccm_header(cryp); 16939d3b5030SFabien DESSENNE else 16949d3b5030SFabien DESSENNE /* Input FIFO IRQ: write data */ 16959d3b5030SFabien DESSENNE stm32_cryp_irq_write_data(cryp); 16969d3b5030SFabien DESSENNE } else { 16979d3b5030SFabien DESSENNE /* Input FIFO IRQ: write data */ 16989d3b5030SFabien DESSENNE stm32_cryp_irq_write_data(cryp); 16999d3b5030SFabien DESSENNE } 17009e054ec2SFabien DESSENNE } 17019e054ec2SFabien DESSENNE 17029e054ec2SFabien DESSENNE return IRQ_HANDLED; 17039e054ec2SFabien DESSENNE } 17049e054ec2SFabien DESSENNE 17059e054ec2SFabien DESSENNE static irqreturn_t stm32_cryp_irq(int irq, void *arg) 17069e054ec2SFabien DESSENNE { 17079e054ec2SFabien DESSENNE struct stm32_cryp *cryp = arg; 17089e054ec2SFabien DESSENNE 17099e054ec2SFabien DESSENNE cryp->irq_status = stm32_cryp_read(cryp, CRYP_MISR); 17109e054ec2SFabien DESSENNE 17119e054ec2SFabien DESSENNE return IRQ_WAKE_THREAD; 17129e054ec2SFabien DESSENNE } 17139e054ec2SFabien DESSENNE 17149e054ec2SFabien DESSENNE static struct crypto_alg crypto_algs[] = { 17159e054ec2SFabien DESSENNE { 17169e054ec2SFabien DESSENNE .cra_name = "ecb(aes)", 17179e054ec2SFabien DESSENNE .cra_driver_name = "stm32-ecb-aes", 17189e054ec2SFabien DESSENNE .cra_priority = 200, 17199e054ec2SFabien DESSENNE .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | 17209e054ec2SFabien DESSENNE CRYPTO_ALG_ASYNC, 17219e054ec2SFabien DESSENNE .cra_blocksize = AES_BLOCK_SIZE, 17229e054ec2SFabien DESSENNE .cra_ctxsize = sizeof(struct stm32_cryp_ctx), 17239e054ec2SFabien DESSENNE .cra_alignmask = 0xf, 17249e054ec2SFabien DESSENNE .cra_type = &crypto_ablkcipher_type, 17259e054ec2SFabien DESSENNE .cra_module = THIS_MODULE, 17269e054ec2SFabien DESSENNE .cra_init = stm32_cryp_cra_init, 17279e054ec2SFabien DESSENNE .cra_ablkcipher = { 17289e054ec2SFabien DESSENNE .min_keysize = AES_MIN_KEY_SIZE, 17299e054ec2SFabien DESSENNE .max_keysize = AES_MAX_KEY_SIZE, 17309e054ec2SFabien DESSENNE .setkey = stm32_cryp_aes_setkey, 17319e054ec2SFabien DESSENNE .encrypt = stm32_cryp_aes_ecb_encrypt, 17329e054ec2SFabien DESSENNE .decrypt = stm32_cryp_aes_ecb_decrypt, 17339e054ec2SFabien DESSENNE } 17349e054ec2SFabien DESSENNE }, 17359e054ec2SFabien DESSENNE { 17369e054ec2SFabien DESSENNE .cra_name = "cbc(aes)", 17379e054ec2SFabien DESSENNE .cra_driver_name = "stm32-cbc-aes", 17389e054ec2SFabien DESSENNE .cra_priority = 200, 17399e054ec2SFabien DESSENNE .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | 17409e054ec2SFabien DESSENNE CRYPTO_ALG_ASYNC, 17419e054ec2SFabien DESSENNE .cra_blocksize = AES_BLOCK_SIZE, 17429e054ec2SFabien DESSENNE .cra_ctxsize = sizeof(struct stm32_cryp_ctx), 17439e054ec2SFabien DESSENNE .cra_alignmask = 0xf, 17449e054ec2SFabien DESSENNE .cra_type = &crypto_ablkcipher_type, 17459e054ec2SFabien DESSENNE .cra_module = THIS_MODULE, 17469e054ec2SFabien DESSENNE .cra_init = stm32_cryp_cra_init, 17479e054ec2SFabien DESSENNE .cra_ablkcipher = { 17489e054ec2SFabien DESSENNE .min_keysize = AES_MIN_KEY_SIZE, 17499e054ec2SFabien DESSENNE .max_keysize = AES_MAX_KEY_SIZE, 17509e054ec2SFabien DESSENNE .ivsize = AES_BLOCK_SIZE, 17519e054ec2SFabien DESSENNE .setkey = stm32_cryp_aes_setkey, 17529e054ec2SFabien DESSENNE .encrypt = stm32_cryp_aes_cbc_encrypt, 17539e054ec2SFabien DESSENNE .decrypt = stm32_cryp_aes_cbc_decrypt, 17549e054ec2SFabien DESSENNE } 17559e054ec2SFabien DESSENNE }, 17569e054ec2SFabien DESSENNE { 17579e054ec2SFabien DESSENNE .cra_name = "ctr(aes)", 17589e054ec2SFabien DESSENNE .cra_driver_name = "stm32-ctr-aes", 17599e054ec2SFabien DESSENNE .cra_priority = 200, 17609e054ec2SFabien DESSENNE .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | 17619e054ec2SFabien DESSENNE CRYPTO_ALG_ASYNC, 17629e054ec2SFabien DESSENNE .cra_blocksize = 1, 17639e054ec2SFabien DESSENNE .cra_ctxsize = sizeof(struct stm32_cryp_ctx), 17649e054ec2SFabien DESSENNE .cra_alignmask = 0xf, 17659e054ec2SFabien DESSENNE .cra_type = &crypto_ablkcipher_type, 17669e054ec2SFabien DESSENNE .cra_module = THIS_MODULE, 17679e054ec2SFabien DESSENNE .cra_init = stm32_cryp_cra_init, 17689e054ec2SFabien DESSENNE .cra_ablkcipher = { 17699e054ec2SFabien DESSENNE .min_keysize = AES_MIN_KEY_SIZE, 17709e054ec2SFabien DESSENNE .max_keysize = AES_MAX_KEY_SIZE, 17719e054ec2SFabien DESSENNE .ivsize = AES_BLOCK_SIZE, 17729e054ec2SFabien DESSENNE .setkey = stm32_cryp_aes_setkey, 17739e054ec2SFabien DESSENNE .encrypt = stm32_cryp_aes_ctr_encrypt, 17749e054ec2SFabien DESSENNE .decrypt = stm32_cryp_aes_ctr_decrypt, 17759e054ec2SFabien DESSENNE } 17769e054ec2SFabien DESSENNE }, 17779e054ec2SFabien DESSENNE { 17789e054ec2SFabien DESSENNE .cra_name = "ecb(des)", 17799e054ec2SFabien DESSENNE .cra_driver_name = "stm32-ecb-des", 17809e054ec2SFabien DESSENNE .cra_priority = 200, 17819e054ec2SFabien DESSENNE .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | 17829e054ec2SFabien DESSENNE CRYPTO_ALG_ASYNC, 17839e054ec2SFabien DESSENNE .cra_blocksize = DES_BLOCK_SIZE, 17849e054ec2SFabien DESSENNE .cra_ctxsize = sizeof(struct stm32_cryp_ctx), 17859e054ec2SFabien DESSENNE .cra_alignmask = 0xf, 17869e054ec2SFabien DESSENNE .cra_type = &crypto_ablkcipher_type, 17879e054ec2SFabien DESSENNE .cra_module = THIS_MODULE, 17889e054ec2SFabien DESSENNE .cra_init = stm32_cryp_cra_init, 17899e054ec2SFabien DESSENNE .cra_ablkcipher = { 17909e054ec2SFabien DESSENNE .min_keysize = DES_BLOCK_SIZE, 17919e054ec2SFabien DESSENNE .max_keysize = DES_BLOCK_SIZE, 17929e054ec2SFabien DESSENNE .setkey = stm32_cryp_des_setkey, 17939e054ec2SFabien DESSENNE .encrypt = stm32_cryp_des_ecb_encrypt, 17949e054ec2SFabien DESSENNE .decrypt = stm32_cryp_des_ecb_decrypt, 17959e054ec2SFabien DESSENNE } 17969e054ec2SFabien DESSENNE }, 17979e054ec2SFabien DESSENNE { 17989e054ec2SFabien DESSENNE .cra_name = "cbc(des)", 17999e054ec2SFabien DESSENNE .cra_driver_name = "stm32-cbc-des", 18009e054ec2SFabien DESSENNE .cra_priority = 200, 18019e054ec2SFabien DESSENNE .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | 18029e054ec2SFabien DESSENNE CRYPTO_ALG_ASYNC, 18039e054ec2SFabien DESSENNE .cra_blocksize = DES_BLOCK_SIZE, 18049e054ec2SFabien DESSENNE .cra_ctxsize = sizeof(struct stm32_cryp_ctx), 18059e054ec2SFabien DESSENNE .cra_alignmask = 0xf, 18069e054ec2SFabien DESSENNE .cra_type = &crypto_ablkcipher_type, 18079e054ec2SFabien DESSENNE .cra_module = THIS_MODULE, 18089e054ec2SFabien DESSENNE .cra_init = stm32_cryp_cra_init, 18099e054ec2SFabien DESSENNE .cra_ablkcipher = { 18109e054ec2SFabien DESSENNE .min_keysize = DES_BLOCK_SIZE, 18119e054ec2SFabien DESSENNE .max_keysize = DES_BLOCK_SIZE, 18129e054ec2SFabien DESSENNE .ivsize = DES_BLOCK_SIZE, 18139e054ec2SFabien DESSENNE .setkey = stm32_cryp_des_setkey, 18149e054ec2SFabien DESSENNE .encrypt = stm32_cryp_des_cbc_encrypt, 18159e054ec2SFabien DESSENNE .decrypt = stm32_cryp_des_cbc_decrypt, 18169e054ec2SFabien DESSENNE } 18179e054ec2SFabien DESSENNE }, 18189e054ec2SFabien DESSENNE { 18199e054ec2SFabien DESSENNE .cra_name = "ecb(des3_ede)", 18209e054ec2SFabien DESSENNE .cra_driver_name = "stm32-ecb-des3", 18219e054ec2SFabien DESSENNE .cra_priority = 200, 18229e054ec2SFabien DESSENNE .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | 18239e054ec2SFabien DESSENNE CRYPTO_ALG_ASYNC, 18249e054ec2SFabien DESSENNE .cra_blocksize = DES_BLOCK_SIZE, 18259e054ec2SFabien DESSENNE .cra_ctxsize = sizeof(struct stm32_cryp_ctx), 18269e054ec2SFabien DESSENNE .cra_alignmask = 0xf, 18279e054ec2SFabien DESSENNE .cra_type = &crypto_ablkcipher_type, 18289e054ec2SFabien DESSENNE .cra_module = THIS_MODULE, 18299e054ec2SFabien DESSENNE .cra_init = stm32_cryp_cra_init, 18309e054ec2SFabien DESSENNE .cra_ablkcipher = { 18319e054ec2SFabien DESSENNE .min_keysize = 3 * DES_BLOCK_SIZE, 18329e054ec2SFabien DESSENNE .max_keysize = 3 * DES_BLOCK_SIZE, 18339e054ec2SFabien DESSENNE .setkey = stm32_cryp_tdes_setkey, 18349e054ec2SFabien DESSENNE .encrypt = stm32_cryp_tdes_ecb_encrypt, 18359e054ec2SFabien DESSENNE .decrypt = stm32_cryp_tdes_ecb_decrypt, 18369e054ec2SFabien DESSENNE } 18379e054ec2SFabien DESSENNE }, 18389e054ec2SFabien DESSENNE { 18399e054ec2SFabien DESSENNE .cra_name = "cbc(des3_ede)", 18409e054ec2SFabien DESSENNE .cra_driver_name = "stm32-cbc-des3", 18419e054ec2SFabien DESSENNE .cra_priority = 200, 18429e054ec2SFabien DESSENNE .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | 18439e054ec2SFabien DESSENNE CRYPTO_ALG_ASYNC, 18449e054ec2SFabien DESSENNE .cra_blocksize = DES_BLOCK_SIZE, 18459e054ec2SFabien DESSENNE .cra_ctxsize = sizeof(struct stm32_cryp_ctx), 18469e054ec2SFabien DESSENNE .cra_alignmask = 0xf, 18479e054ec2SFabien DESSENNE .cra_type = &crypto_ablkcipher_type, 18489e054ec2SFabien DESSENNE .cra_module = THIS_MODULE, 18499e054ec2SFabien DESSENNE .cra_init = stm32_cryp_cra_init, 18509e054ec2SFabien DESSENNE .cra_ablkcipher = { 18519e054ec2SFabien DESSENNE .min_keysize = 3 * DES_BLOCK_SIZE, 18529e054ec2SFabien DESSENNE .max_keysize = 3 * DES_BLOCK_SIZE, 18539e054ec2SFabien DESSENNE .ivsize = DES_BLOCK_SIZE, 18549e054ec2SFabien DESSENNE .setkey = stm32_cryp_tdes_setkey, 18559e054ec2SFabien DESSENNE .encrypt = stm32_cryp_tdes_cbc_encrypt, 18569e054ec2SFabien DESSENNE .decrypt = stm32_cryp_tdes_cbc_decrypt, 18579e054ec2SFabien DESSENNE } 18589e054ec2SFabien DESSENNE }, 18599e054ec2SFabien DESSENNE }; 18609e054ec2SFabien DESSENNE 18619d3b5030SFabien DESSENNE static struct aead_alg aead_algs[] = { 18629d3b5030SFabien DESSENNE { 18639d3b5030SFabien DESSENNE .setkey = stm32_cryp_aes_aead_setkey, 18649d3b5030SFabien DESSENNE .setauthsize = stm32_cryp_aes_gcm_setauthsize, 18659d3b5030SFabien DESSENNE .encrypt = stm32_cryp_aes_gcm_encrypt, 18669d3b5030SFabien DESSENNE .decrypt = stm32_cryp_aes_gcm_decrypt, 18679d3b5030SFabien DESSENNE .init = stm32_cryp_aes_aead_init, 18689d3b5030SFabien DESSENNE .ivsize = 12, 18699d3b5030SFabien DESSENNE .maxauthsize = AES_BLOCK_SIZE, 18709d3b5030SFabien DESSENNE 18719d3b5030SFabien DESSENNE .base = { 18729d3b5030SFabien DESSENNE .cra_name = "gcm(aes)", 18739d3b5030SFabien DESSENNE .cra_driver_name = "stm32-gcm-aes", 18749d3b5030SFabien DESSENNE .cra_priority = 200, 18759d3b5030SFabien DESSENNE .cra_flags = CRYPTO_ALG_ASYNC, 18769d3b5030SFabien DESSENNE .cra_blocksize = 1, 18779d3b5030SFabien DESSENNE .cra_ctxsize = sizeof(struct stm32_cryp_ctx), 18789d3b5030SFabien DESSENNE .cra_alignmask = 0xf, 18799d3b5030SFabien DESSENNE .cra_module = THIS_MODULE, 18809d3b5030SFabien DESSENNE }, 18819d3b5030SFabien DESSENNE }, 18829d3b5030SFabien DESSENNE { 18839d3b5030SFabien DESSENNE .setkey = stm32_cryp_aes_aead_setkey, 18849d3b5030SFabien DESSENNE .setauthsize = stm32_cryp_aes_ccm_setauthsize, 18859d3b5030SFabien DESSENNE .encrypt = stm32_cryp_aes_ccm_encrypt, 18869d3b5030SFabien DESSENNE .decrypt = stm32_cryp_aes_ccm_decrypt, 18879d3b5030SFabien DESSENNE .init = stm32_cryp_aes_aead_init, 18889d3b5030SFabien DESSENNE .ivsize = AES_BLOCK_SIZE, 18899d3b5030SFabien DESSENNE .maxauthsize = AES_BLOCK_SIZE, 18909d3b5030SFabien DESSENNE 18919d3b5030SFabien DESSENNE .base = { 18929d3b5030SFabien DESSENNE .cra_name = "ccm(aes)", 18939d3b5030SFabien DESSENNE .cra_driver_name = "stm32-ccm-aes", 18949d3b5030SFabien DESSENNE .cra_priority = 200, 18959d3b5030SFabien DESSENNE .cra_flags = CRYPTO_ALG_ASYNC, 18969d3b5030SFabien DESSENNE .cra_blocksize = 1, 18979d3b5030SFabien DESSENNE .cra_ctxsize = sizeof(struct stm32_cryp_ctx), 18989d3b5030SFabien DESSENNE .cra_alignmask = 0xf, 18999d3b5030SFabien DESSENNE .cra_module = THIS_MODULE, 19009d3b5030SFabien DESSENNE }, 19019d3b5030SFabien DESSENNE }, 19029d3b5030SFabien DESSENNE }; 19039d3b5030SFabien DESSENNE 19049d3b5030SFabien DESSENNE static const struct stm32_cryp_caps f7_data = { 19059d3b5030SFabien DESSENNE .swap_final = true, 19069d3b5030SFabien DESSENNE .padding_wa = true, 19079d3b5030SFabien DESSENNE }; 19089d3b5030SFabien DESSENNE 1909*a43a3484SFabien DESSENNE static const struct stm32_cryp_caps mp1_data = { 1910*a43a3484SFabien DESSENNE .swap_final = false, 1911*a43a3484SFabien DESSENNE .padding_wa = false, 1912*a43a3484SFabien DESSENNE }; 1913*a43a3484SFabien DESSENNE 19149e054ec2SFabien DESSENNE static const struct of_device_id stm32_dt_ids[] = { 19159d3b5030SFabien DESSENNE { .compatible = "st,stm32f756-cryp", .data = &f7_data}, 1916*a43a3484SFabien DESSENNE { .compatible = "st,stm32mp1-cryp", .data = &mp1_data}, 19179e054ec2SFabien DESSENNE {}, 19189e054ec2SFabien DESSENNE }; 1919761a6982SCorentin LABBE MODULE_DEVICE_TABLE(of, stm32_dt_ids); 19209e054ec2SFabien DESSENNE 19219e054ec2SFabien DESSENNE static int stm32_cryp_probe(struct platform_device *pdev) 19229e054ec2SFabien DESSENNE { 19239e054ec2SFabien DESSENNE struct device *dev = &pdev->dev; 19249e054ec2SFabien DESSENNE struct stm32_cryp *cryp; 19259e054ec2SFabien DESSENNE struct resource *res; 19269e054ec2SFabien DESSENNE struct reset_control *rst; 19279e054ec2SFabien DESSENNE int irq, ret; 19289e054ec2SFabien DESSENNE 19299e054ec2SFabien DESSENNE cryp = devm_kzalloc(dev, sizeof(*cryp), GFP_KERNEL); 19309e054ec2SFabien DESSENNE if (!cryp) 19319e054ec2SFabien DESSENNE return -ENOMEM; 19329e054ec2SFabien DESSENNE 19339d3b5030SFabien DESSENNE cryp->caps = of_device_get_match_data(dev); 19349d3b5030SFabien DESSENNE if (!cryp->caps) 19359d3b5030SFabien DESSENNE return -ENODEV; 19369d3b5030SFabien DESSENNE 19379e054ec2SFabien DESSENNE cryp->dev = dev; 19389e054ec2SFabien DESSENNE 19399e054ec2SFabien DESSENNE mutex_init(&cryp->lock); 19409e054ec2SFabien DESSENNE 19419e054ec2SFabien DESSENNE res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 19429e054ec2SFabien DESSENNE cryp->regs = devm_ioremap_resource(dev, res); 194360bcf265Sweiyongjun \(A\) if (IS_ERR(cryp->regs)) 19449e054ec2SFabien DESSENNE return PTR_ERR(cryp->regs); 19459e054ec2SFabien DESSENNE 19469e054ec2SFabien DESSENNE irq = platform_get_irq(pdev, 0); 19479e054ec2SFabien DESSENNE if (irq < 0) { 19489e054ec2SFabien DESSENNE dev_err(dev, "Cannot get IRQ resource\n"); 19499e054ec2SFabien DESSENNE return irq; 19509e054ec2SFabien DESSENNE } 19519e054ec2SFabien DESSENNE 19529e054ec2SFabien DESSENNE ret = devm_request_threaded_irq(dev, irq, stm32_cryp_irq, 19539e054ec2SFabien DESSENNE stm32_cryp_irq_thread, IRQF_ONESHOT, 19549e054ec2SFabien DESSENNE dev_name(dev), cryp); 19559e054ec2SFabien DESSENNE if (ret) { 19569e054ec2SFabien DESSENNE dev_err(dev, "Cannot grab IRQ\n"); 19579e054ec2SFabien DESSENNE return ret; 19589e054ec2SFabien DESSENNE } 19599e054ec2SFabien DESSENNE 19609e054ec2SFabien DESSENNE cryp->clk = devm_clk_get(dev, NULL); 19619e054ec2SFabien DESSENNE if (IS_ERR(cryp->clk)) { 19629e054ec2SFabien DESSENNE dev_err(dev, "Could not get clock\n"); 19639e054ec2SFabien DESSENNE return PTR_ERR(cryp->clk); 19649e054ec2SFabien DESSENNE } 19659e054ec2SFabien DESSENNE 19669e054ec2SFabien DESSENNE ret = clk_prepare_enable(cryp->clk); 19679e054ec2SFabien DESSENNE if (ret) { 19689e054ec2SFabien DESSENNE dev_err(cryp->dev, "Failed to enable clock\n"); 19699e054ec2SFabien DESSENNE return ret; 19709e054ec2SFabien DESSENNE } 19719e054ec2SFabien DESSENNE 19729e054ec2SFabien DESSENNE rst = devm_reset_control_get(dev, NULL); 19739e054ec2SFabien DESSENNE if (!IS_ERR(rst)) { 19749e054ec2SFabien DESSENNE reset_control_assert(rst); 19759e054ec2SFabien DESSENNE udelay(2); 19769e054ec2SFabien DESSENNE reset_control_deassert(rst); 19779e054ec2SFabien DESSENNE } 19789e054ec2SFabien DESSENNE 19799e054ec2SFabien DESSENNE platform_set_drvdata(pdev, cryp); 19809e054ec2SFabien DESSENNE 19819e054ec2SFabien DESSENNE spin_lock(&cryp_list.lock); 19829e054ec2SFabien DESSENNE list_add(&cryp->list, &cryp_list.dev_list); 19839e054ec2SFabien DESSENNE spin_unlock(&cryp_list.lock); 19849e054ec2SFabien DESSENNE 19859e054ec2SFabien DESSENNE /* Initialize crypto engine */ 19869e054ec2SFabien DESSENNE cryp->engine = crypto_engine_alloc_init(dev, 1); 19879e054ec2SFabien DESSENNE if (!cryp->engine) { 19889e054ec2SFabien DESSENNE dev_err(dev, "Could not init crypto engine\n"); 19899e054ec2SFabien DESSENNE ret = -ENOMEM; 19909e054ec2SFabien DESSENNE goto err_engine1; 19919e054ec2SFabien DESSENNE } 19929e054ec2SFabien DESSENNE 19939e054ec2SFabien DESSENNE ret = crypto_engine_start(cryp->engine); 19949e054ec2SFabien DESSENNE if (ret) { 19959e054ec2SFabien DESSENNE dev_err(dev, "Could not start crypto engine\n"); 19969e054ec2SFabien DESSENNE goto err_engine2; 19979e054ec2SFabien DESSENNE } 19989e054ec2SFabien DESSENNE 19999e054ec2SFabien DESSENNE ret = crypto_register_algs(crypto_algs, ARRAY_SIZE(crypto_algs)); 20009e054ec2SFabien DESSENNE if (ret) { 20019e054ec2SFabien DESSENNE dev_err(dev, "Could not register algs\n"); 20029e054ec2SFabien DESSENNE goto err_algs; 20039e054ec2SFabien DESSENNE } 20049e054ec2SFabien DESSENNE 20059d3b5030SFabien DESSENNE ret = crypto_register_aeads(aead_algs, ARRAY_SIZE(aead_algs)); 20069d3b5030SFabien DESSENNE if (ret) 20079d3b5030SFabien DESSENNE goto err_aead_algs; 20089d3b5030SFabien DESSENNE 20099e054ec2SFabien DESSENNE dev_info(dev, "Initialized\n"); 20109e054ec2SFabien DESSENNE 20119e054ec2SFabien DESSENNE return 0; 20129e054ec2SFabien DESSENNE 20139d3b5030SFabien DESSENNE err_aead_algs: 20149d3b5030SFabien DESSENNE crypto_unregister_algs(crypto_algs, ARRAY_SIZE(crypto_algs)); 20159e054ec2SFabien DESSENNE err_algs: 20169e054ec2SFabien DESSENNE err_engine2: 20179e054ec2SFabien DESSENNE crypto_engine_exit(cryp->engine); 20189e054ec2SFabien DESSENNE err_engine1: 20199e054ec2SFabien DESSENNE spin_lock(&cryp_list.lock); 20209e054ec2SFabien DESSENNE list_del(&cryp->list); 20219e054ec2SFabien DESSENNE spin_unlock(&cryp_list.lock); 20229e054ec2SFabien DESSENNE 20239e054ec2SFabien DESSENNE clk_disable_unprepare(cryp->clk); 20249e054ec2SFabien DESSENNE 20259e054ec2SFabien DESSENNE return ret; 20269e054ec2SFabien DESSENNE } 20279e054ec2SFabien DESSENNE 20289e054ec2SFabien DESSENNE static int stm32_cryp_remove(struct platform_device *pdev) 20299e054ec2SFabien DESSENNE { 20309e054ec2SFabien DESSENNE struct stm32_cryp *cryp = platform_get_drvdata(pdev); 20319e054ec2SFabien DESSENNE 20329e054ec2SFabien DESSENNE if (!cryp) 20339e054ec2SFabien DESSENNE return -ENODEV; 20349e054ec2SFabien DESSENNE 20359d3b5030SFabien DESSENNE crypto_unregister_aeads(aead_algs, ARRAY_SIZE(aead_algs)); 20369e054ec2SFabien DESSENNE crypto_unregister_algs(crypto_algs, ARRAY_SIZE(crypto_algs)); 20379e054ec2SFabien DESSENNE 20389e054ec2SFabien DESSENNE crypto_engine_exit(cryp->engine); 20399e054ec2SFabien DESSENNE 20409e054ec2SFabien DESSENNE spin_lock(&cryp_list.lock); 20419e054ec2SFabien DESSENNE list_del(&cryp->list); 20429e054ec2SFabien DESSENNE spin_unlock(&cryp_list.lock); 20439e054ec2SFabien DESSENNE 20449e054ec2SFabien DESSENNE clk_disable_unprepare(cryp->clk); 20459e054ec2SFabien DESSENNE 20469e054ec2SFabien DESSENNE return 0; 20479e054ec2SFabien DESSENNE } 20489e054ec2SFabien DESSENNE 20499e054ec2SFabien DESSENNE static struct platform_driver stm32_cryp_driver = { 20509e054ec2SFabien DESSENNE .probe = stm32_cryp_probe, 20519e054ec2SFabien DESSENNE .remove = stm32_cryp_remove, 20529e054ec2SFabien DESSENNE .driver = { 20539e054ec2SFabien DESSENNE .name = DRIVER_NAME, 20549e054ec2SFabien DESSENNE .of_match_table = stm32_dt_ids, 20559e054ec2SFabien DESSENNE }, 20569e054ec2SFabien DESSENNE }; 20579e054ec2SFabien DESSENNE 20589e054ec2SFabien DESSENNE module_platform_driver(stm32_cryp_driver); 20599e054ec2SFabien DESSENNE 20609e054ec2SFabien DESSENNE MODULE_AUTHOR("Fabien Dessenne <fabien.dessenne@st.com>"); 20619e054ec2SFabien DESSENNE MODULE_DESCRIPTION("STMicrolectronics STM32 CRYP hardware driver"); 20629e054ec2SFabien DESSENNE MODULE_LICENSE("GPL"); 2063