11a59d1b8SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-or-later 29c4a7965SKim Phillips /* 39c4a7965SKim Phillips * talitos - Freescale Integrated Security Engine (SEC) device driver 49c4a7965SKim Phillips * 55228f0f7SKim Phillips * Copyright (c) 2008-2011 Freescale Semiconductor, Inc. 69c4a7965SKim Phillips * 79c4a7965SKim Phillips * Scatterlist Crypto API glue code copied from files with the following: 89c4a7965SKim Phillips * Copyright (c) 2006-2007 Herbert Xu <herbert@gondor.apana.org.au> 99c4a7965SKim Phillips * 109c4a7965SKim Phillips * Crypto algorithm registration code copied from hifn driver: 119c4a7965SKim Phillips * 2007+ Copyright (c) Evgeniy Polyakov <johnpol@2ka.mipt.ru> 129c4a7965SKim Phillips * All rights reserved. 139c4a7965SKim Phillips */ 149c4a7965SKim Phillips 159c4a7965SKim Phillips #include <linux/kernel.h> 169c4a7965SKim Phillips #include <linux/module.h> 179c4a7965SKim Phillips #include <linux/mod_devicetable.h> 189c4a7965SKim Phillips #include <linux/device.h> 199c4a7965SKim Phillips #include <linux/interrupt.h> 209c4a7965SKim Phillips #include <linux/crypto.h> 219c4a7965SKim Phillips #include <linux/hw_random.h> 225af50730SRob Herring #include <linux/of_address.h> 235af50730SRob Herring #include <linux/of_irq.h> 249c4a7965SKim Phillips #include <linux/of_platform.h> 259c4a7965SKim Phillips #include <linux/dma-mapping.h> 269c4a7965SKim Phillips #include <linux/io.h> 279c4a7965SKim Phillips #include <linux/spinlock.h> 289c4a7965SKim Phillips #include <linux/rtnetlink.h> 295a0e3ad6STejun Heo #include <linux/slab.h> 309c4a7965SKim Phillips 319c4a7965SKim Phillips #include <crypto/algapi.h> 329c4a7965SKim Phillips #include <crypto/aes.h> 33*9d574ae8SArd Biesheuvel #include <crypto/internal/des.h> 349c4a7965SKim Phillips #include <crypto/sha.h> 35497f2e6bSLee Nipper #include <crypto/md5.h> 36e98014abSHerbert Xu #include <crypto/internal/aead.h> 379c4a7965SKim Phillips #include <crypto/authenc.h> 384de9d0b5SLee Nipper #include <crypto/skcipher.h> 39acbf7c62SLee Nipper #include <crypto/hash.h> 40acbf7c62SLee Nipper #include <crypto/internal/hash.h> 414de9d0b5SLee Nipper #include <crypto/scatterwalk.h> 429c4a7965SKim Phillips 439c4a7965SKim Phillips #include "talitos.h" 449c4a7965SKim Phillips 45922f9dc8SLEROY Christophe static void to_talitos_ptr(struct talitos_ptr *ptr, dma_addr_t dma_addr, 46da9de146SLEROY Christophe unsigned int len, bool is_sec1) 4781eb024cSKim Phillips { 48edc6bd69SLEROY Christophe ptr->ptr = cpu_to_be32(lower_32_bits(dma_addr)); 49da9de146SLEROY Christophe if (is_sec1) { 50da9de146SLEROY Christophe ptr->len1 = cpu_to_be16(len); 51da9de146SLEROY Christophe } else { 52da9de146SLEROY Christophe ptr->len = cpu_to_be16(len); 53edc6bd69SLEROY Christophe ptr->eptr = upper_32_bits(dma_addr); 5481eb024cSKim Phillips } 55da9de146SLEROY Christophe } 5681eb024cSKim Phillips 57340ff60aSHoria Geant? static void copy_talitos_ptr(struct talitos_ptr *dst_ptr, 58340ff60aSHoria Geant? struct talitos_ptr *src_ptr, bool is_sec1) 59340ff60aSHoria Geant? { 60340ff60aSHoria Geant? dst_ptr->ptr = src_ptr->ptr; 61922f9dc8SLEROY Christophe if (is_sec1) { 62da9de146SLEROY Christophe dst_ptr->len1 = src_ptr->len1; 63922f9dc8SLEROY Christophe } else { 64da9de146SLEROY Christophe dst_ptr->len = src_ptr->len; 65da9de146SLEROY Christophe dst_ptr->eptr = src_ptr->eptr; 66538caf83SLEROY Christophe } 67922f9dc8SLEROY Christophe } 68538caf83SLEROY Christophe 69922f9dc8SLEROY Christophe static unsigned short from_talitos_ptr_len(struct talitos_ptr *ptr, 70922f9dc8SLEROY Christophe bool is_sec1) 71538caf83SLEROY Christophe { 72922f9dc8SLEROY Christophe if (is_sec1) 73922f9dc8SLEROY Christophe return be16_to_cpu(ptr->len1); 74922f9dc8SLEROY Christophe else 75538caf83SLEROY Christophe return be16_to_cpu(ptr->len); 76538caf83SLEROY Christophe } 77538caf83SLEROY Christophe 78b096b544SLEROY Christophe static void to_talitos_ptr_ext_set(struct talitos_ptr *ptr, u8 val, 79b096b544SLEROY Christophe bool is_sec1) 80185eb79fSLEROY Christophe { 81922f9dc8SLEROY Christophe if (!is_sec1) 82b096b544SLEROY Christophe ptr->j_extent = val; 83b096b544SLEROY Christophe } 84b096b544SLEROY Christophe 85b096b544SLEROY Christophe static void to_talitos_ptr_ext_or(struct talitos_ptr *ptr, u8 val, bool is_sec1) 86b096b544SLEROY Christophe { 87b096b544SLEROY Christophe if (!is_sec1) 88b096b544SLEROY Christophe ptr->j_extent |= val; 89185eb79fSLEROY Christophe } 90185eb79fSLEROY Christophe 919c4a7965SKim Phillips /* 929c4a7965SKim Phillips * map virtual single (contiguous) pointer to h/w descriptor pointer 939c4a7965SKim Phillips */ 946a4967c3SLEROY Christophe static void __map_single_talitos_ptr(struct device *dev, 956a4967c3SLEROY Christophe struct talitos_ptr *ptr, 966a4967c3SLEROY Christophe unsigned int len, void *data, 976a4967c3SLEROY Christophe enum dma_data_direction dir, 986a4967c3SLEROY Christophe unsigned long attrs) 996a4967c3SLEROY Christophe { 1006a4967c3SLEROY Christophe dma_addr_t dma_addr = dma_map_single_attrs(dev, data, len, dir, attrs); 1016a4967c3SLEROY Christophe struct talitos_private *priv = dev_get_drvdata(dev); 1026a4967c3SLEROY Christophe bool is_sec1 = has_ftr_sec1(priv); 1036a4967c3SLEROY Christophe 1046a4967c3SLEROY Christophe to_talitos_ptr(ptr, dma_addr, len, is_sec1); 1056a4967c3SLEROY Christophe } 1066a4967c3SLEROY Christophe 1079c4a7965SKim Phillips static void map_single_talitos_ptr(struct device *dev, 108edc6bd69SLEROY Christophe struct talitos_ptr *ptr, 10942e8b0d7SHoria Geant? unsigned int len, void *data, 1109c4a7965SKim Phillips enum dma_data_direction dir) 1119c4a7965SKim Phillips { 1126a4967c3SLEROY Christophe __map_single_talitos_ptr(dev, ptr, len, data, dir, 0); 1136a4967c3SLEROY Christophe } 11481eb024cSKim Phillips 1156a4967c3SLEROY Christophe static void map_single_talitos_ptr_nosync(struct device *dev, 1166a4967c3SLEROY Christophe struct talitos_ptr *ptr, 1176a4967c3SLEROY Christophe unsigned int len, void *data, 1186a4967c3SLEROY Christophe enum dma_data_direction dir) 1196a4967c3SLEROY Christophe { 1206a4967c3SLEROY Christophe __map_single_talitos_ptr(dev, ptr, len, data, dir, 1216a4967c3SLEROY Christophe DMA_ATTR_SKIP_CPU_SYNC); 1229c4a7965SKim Phillips } 1239c4a7965SKim Phillips 1249c4a7965SKim Phillips /* 1259c4a7965SKim Phillips * unmap bus single (contiguous) h/w descriptor pointer 1269c4a7965SKim Phillips */ 1279c4a7965SKim Phillips static void unmap_single_talitos_ptr(struct device *dev, 128edc6bd69SLEROY Christophe struct talitos_ptr *ptr, 1299c4a7965SKim Phillips enum dma_data_direction dir) 1309c4a7965SKim Phillips { 131922f9dc8SLEROY Christophe struct talitos_private *priv = dev_get_drvdata(dev); 132922f9dc8SLEROY Christophe bool is_sec1 = has_ftr_sec1(priv); 133922f9dc8SLEROY Christophe 134edc6bd69SLEROY Christophe dma_unmap_single(dev, be32_to_cpu(ptr->ptr), 135922f9dc8SLEROY Christophe from_talitos_ptr_len(ptr, is_sec1), dir); 1369c4a7965SKim Phillips } 1379c4a7965SKim Phillips 1389c4a7965SKim Phillips static int reset_channel(struct device *dev, int ch) 1399c4a7965SKim Phillips { 1409c4a7965SKim Phillips struct talitos_private *priv = dev_get_drvdata(dev); 1419c4a7965SKim Phillips unsigned int timeout = TALITOS_TIMEOUT; 142dd3c0987SLEROY Christophe bool is_sec1 = has_ftr_sec1(priv); 1439c4a7965SKim Phillips 144dd3c0987SLEROY Christophe if (is_sec1) { 145dd3c0987SLEROY Christophe setbits32(priv->chan[ch].reg + TALITOS_CCCR_LO, 146dd3c0987SLEROY Christophe TALITOS1_CCCR_LO_RESET); 1479c4a7965SKim Phillips 148dd3c0987SLEROY Christophe while ((in_be32(priv->chan[ch].reg + TALITOS_CCCR_LO) & 149dd3c0987SLEROY Christophe TALITOS1_CCCR_LO_RESET) && --timeout) 1509c4a7965SKim Phillips cpu_relax(); 151dd3c0987SLEROY Christophe } else { 152dd3c0987SLEROY Christophe setbits32(priv->chan[ch].reg + TALITOS_CCCR, 153dd3c0987SLEROY Christophe TALITOS2_CCCR_RESET); 154dd3c0987SLEROY Christophe 155dd3c0987SLEROY Christophe while ((in_be32(priv->chan[ch].reg + TALITOS_CCCR) & 156dd3c0987SLEROY Christophe TALITOS2_CCCR_RESET) && --timeout) 157dd3c0987SLEROY Christophe cpu_relax(); 158dd3c0987SLEROY Christophe } 1599c4a7965SKim Phillips 1609c4a7965SKim Phillips if (timeout == 0) { 1619c4a7965SKim Phillips dev_err(dev, "failed to reset channel %d\n", ch); 1629c4a7965SKim Phillips return -EIO; 1639c4a7965SKim Phillips } 1649c4a7965SKim Phillips 16581eb024cSKim Phillips /* set 36-bit addressing, done writeback enable and done IRQ enable */ 166ad42d5fcSKim Phillips setbits32(priv->chan[ch].reg + TALITOS_CCCR_LO, TALITOS_CCCR_LO_EAE | 16781eb024cSKim Phillips TALITOS_CCCR_LO_CDWE | TALITOS_CCCR_LO_CDIE); 16837b5e889SLEROY Christophe /* enable chaining descriptors */ 16937b5e889SLEROY Christophe if (is_sec1) 17037b5e889SLEROY Christophe setbits32(priv->chan[ch].reg + TALITOS_CCCR_LO, 17137b5e889SLEROY Christophe TALITOS_CCCR_LO_NE); 1729c4a7965SKim Phillips 173fe5720e2SKim Phillips /* and ICCR writeback, if available */ 174fe5720e2SKim Phillips if (priv->features & TALITOS_FTR_HW_AUTH_CHECK) 175ad42d5fcSKim Phillips setbits32(priv->chan[ch].reg + TALITOS_CCCR_LO, 176fe5720e2SKim Phillips TALITOS_CCCR_LO_IWSE); 177fe5720e2SKim Phillips 1789c4a7965SKim Phillips return 0; 1799c4a7965SKim Phillips } 1809c4a7965SKim Phillips 1819c4a7965SKim Phillips static int reset_device(struct device *dev) 1829c4a7965SKim Phillips { 1839c4a7965SKim Phillips struct talitos_private *priv = dev_get_drvdata(dev); 1849c4a7965SKim Phillips unsigned int timeout = TALITOS_TIMEOUT; 185dd3c0987SLEROY Christophe bool is_sec1 = has_ftr_sec1(priv); 186dd3c0987SLEROY Christophe u32 mcr = is_sec1 ? TALITOS1_MCR_SWR : TALITOS2_MCR_SWR; 1879c4a7965SKim Phillips 188c3e337f8SKim Phillips setbits32(priv->reg + TALITOS_MCR, mcr); 1899c4a7965SKim Phillips 190dd3c0987SLEROY Christophe while ((in_be32(priv->reg + TALITOS_MCR) & mcr) 1919c4a7965SKim Phillips && --timeout) 1929c4a7965SKim Phillips cpu_relax(); 1939c4a7965SKim Phillips 1942cdba3cfSKim Phillips if (priv->irq[1]) { 195c3e337f8SKim Phillips mcr = TALITOS_MCR_RCA1 | TALITOS_MCR_RCA3; 196c3e337f8SKim Phillips setbits32(priv->reg + TALITOS_MCR, mcr); 197c3e337f8SKim Phillips } 198c3e337f8SKim Phillips 1999c4a7965SKim Phillips if (timeout == 0) { 2009c4a7965SKim Phillips dev_err(dev, "failed to reset device\n"); 2019c4a7965SKim Phillips return -EIO; 2029c4a7965SKim Phillips } 2039c4a7965SKim Phillips 2049c4a7965SKim Phillips return 0; 2059c4a7965SKim Phillips } 2069c4a7965SKim Phillips 2079c4a7965SKim Phillips /* 2089c4a7965SKim Phillips * Reset and initialize the device 2099c4a7965SKim Phillips */ 2109c4a7965SKim Phillips static int init_device(struct device *dev) 2119c4a7965SKim Phillips { 2129c4a7965SKim Phillips struct talitos_private *priv = dev_get_drvdata(dev); 2139c4a7965SKim Phillips int ch, err; 214dd3c0987SLEROY Christophe bool is_sec1 = has_ftr_sec1(priv); 2159c4a7965SKim Phillips 2169c4a7965SKim Phillips /* 2179c4a7965SKim Phillips * Master reset 2189c4a7965SKim Phillips * errata documentation: warning: certain SEC interrupts 2199c4a7965SKim Phillips * are not fully cleared by writing the MCR:SWR bit, 2209c4a7965SKim Phillips * set bit twice to completely reset 2219c4a7965SKim Phillips */ 2229c4a7965SKim Phillips err = reset_device(dev); 2239c4a7965SKim Phillips if (err) 2249c4a7965SKim Phillips return err; 2259c4a7965SKim Phillips 2269c4a7965SKim Phillips err = reset_device(dev); 2279c4a7965SKim Phillips if (err) 2289c4a7965SKim Phillips return err; 2299c4a7965SKim Phillips 2309c4a7965SKim Phillips /* reset channels */ 2319c4a7965SKim Phillips for (ch = 0; ch < priv->num_channels; ch++) { 2329c4a7965SKim Phillips err = reset_channel(dev, ch); 2339c4a7965SKim Phillips if (err) 2349c4a7965SKim Phillips return err; 2359c4a7965SKim Phillips } 2369c4a7965SKim Phillips 2379c4a7965SKim Phillips /* enable channel done and error interrupts */ 238dd3c0987SLEROY Christophe if (is_sec1) { 239dd3c0987SLEROY Christophe clrbits32(priv->reg + TALITOS_IMR, TALITOS1_IMR_INIT); 240dd3c0987SLEROY Christophe clrbits32(priv->reg + TALITOS_IMR_LO, TALITOS1_IMR_LO_INIT); 241dd3c0987SLEROY Christophe /* disable parity error check in DEU (erroneous? test vect.) */ 242dd3c0987SLEROY Christophe setbits32(priv->reg_deu + TALITOS_EUICR, TALITOS1_DEUICR_KPE); 243dd3c0987SLEROY Christophe } else { 244dd3c0987SLEROY Christophe setbits32(priv->reg + TALITOS_IMR, TALITOS2_IMR_INIT); 245dd3c0987SLEROY Christophe setbits32(priv->reg + TALITOS_IMR_LO, TALITOS2_IMR_LO_INIT); 246dd3c0987SLEROY Christophe } 2479c4a7965SKim Phillips 248fe5720e2SKim Phillips /* disable integrity check error interrupts (use writeback instead) */ 249fe5720e2SKim Phillips if (priv->features & TALITOS_FTR_HW_AUTH_CHECK) 2505fa7fa14SLEROY Christophe setbits32(priv->reg_mdeu + TALITOS_EUICR_LO, 251fe5720e2SKim Phillips TALITOS_MDEUICR_LO_ICE); 252fe5720e2SKim Phillips 2539c4a7965SKim Phillips return 0; 2549c4a7965SKim Phillips } 2559c4a7965SKim Phillips 2569c4a7965SKim Phillips /** 2579c4a7965SKim Phillips * talitos_submit - submits a descriptor to the device for processing 2589c4a7965SKim Phillips * @dev: the SEC device to be used 2595228f0f7SKim Phillips * @ch: the SEC device channel to be used 2609c4a7965SKim Phillips * @desc: the descriptor to be processed by the device 2619c4a7965SKim Phillips * @callback: whom to call when processing is complete 2629c4a7965SKim Phillips * @context: a handle for use by caller (optional) 2639c4a7965SKim Phillips * 2649c4a7965SKim Phillips * desc must contain valid dma-mapped (bus physical) address pointers. 2659c4a7965SKim Phillips * callback must check err and feedback in descriptor header 2669c4a7965SKim Phillips * for device processing status. 2679c4a7965SKim Phillips */ 268fbb8d46eSChristophe Leroy static int talitos_submit(struct device *dev, int ch, struct talitos_desc *desc, 2699c4a7965SKim Phillips void (*callback)(struct device *dev, 2709c4a7965SKim Phillips struct talitos_desc *desc, 2719c4a7965SKim Phillips void *context, int error), 2729c4a7965SKim Phillips void *context) 2739c4a7965SKim Phillips { 2749c4a7965SKim Phillips struct talitos_private *priv = dev_get_drvdata(dev); 2759c4a7965SKim Phillips struct talitos_request *request; 2765228f0f7SKim Phillips unsigned long flags; 2779c4a7965SKim Phillips int head; 2787d607c6aSLEROY Christophe bool is_sec1 = has_ftr_sec1(priv); 2799c4a7965SKim Phillips 2804b992628SKim Phillips spin_lock_irqsave(&priv->chan[ch].head_lock, flags); 2819c4a7965SKim Phillips 2824b992628SKim Phillips if (!atomic_inc_not_zero(&priv->chan[ch].submit_count)) { 283ec6644d6SKim Phillips /* h/w fifo is full */ 2844b992628SKim Phillips spin_unlock_irqrestore(&priv->chan[ch].head_lock, flags); 2859c4a7965SKim Phillips return -EAGAIN; 2869c4a7965SKim Phillips } 2879c4a7965SKim Phillips 2884b992628SKim Phillips head = priv->chan[ch].head; 2894b992628SKim Phillips request = &priv->chan[ch].fifo[head]; 290ec6644d6SKim Phillips 2919c4a7965SKim Phillips /* map descriptor and save caller data */ 2927d607c6aSLEROY Christophe if (is_sec1) { 2937d607c6aSLEROY Christophe desc->hdr1 = desc->hdr; 2947d607c6aSLEROY Christophe request->dma_desc = dma_map_single(dev, &desc->hdr1, 2957d607c6aSLEROY Christophe TALITOS_DESC_SIZE, 2969c4a7965SKim Phillips DMA_BIDIRECTIONAL); 2977d607c6aSLEROY Christophe } else { 2987d607c6aSLEROY Christophe request->dma_desc = dma_map_single(dev, desc, 2997d607c6aSLEROY Christophe TALITOS_DESC_SIZE, 3007d607c6aSLEROY Christophe DMA_BIDIRECTIONAL); 3017d607c6aSLEROY Christophe } 3029c4a7965SKim Phillips request->callback = callback; 3039c4a7965SKim Phillips request->context = context; 3049c4a7965SKim Phillips 3059c4a7965SKim Phillips /* increment fifo head */ 3064b992628SKim Phillips priv->chan[ch].head = (priv->chan[ch].head + 1) & (priv->fifo_len - 1); 3079c4a7965SKim Phillips 3089c4a7965SKim Phillips smp_wmb(); 3099c4a7965SKim Phillips request->desc = desc; 3109c4a7965SKim Phillips 3119c4a7965SKim Phillips /* GO! */ 3129c4a7965SKim Phillips wmb(); 313ad42d5fcSKim Phillips out_be32(priv->chan[ch].reg + TALITOS_FF, 314ad42d5fcSKim Phillips upper_32_bits(request->dma_desc)); 315ad42d5fcSKim Phillips out_be32(priv->chan[ch].reg + TALITOS_FF_LO, 316a752447aSKim Phillips lower_32_bits(request->dma_desc)); 3179c4a7965SKim Phillips 3184b992628SKim Phillips spin_unlock_irqrestore(&priv->chan[ch].head_lock, flags); 3199c4a7965SKim Phillips 3209c4a7965SKim Phillips return -EINPROGRESS; 3219c4a7965SKim Phillips } 3229c4a7965SKim Phillips 32358cdbc6dSChristophe Leroy static __be32 get_request_hdr(struct talitos_request *request, bool is_sec1) 32458cdbc6dSChristophe Leroy { 32558cdbc6dSChristophe Leroy struct talitos_edesc *edesc; 32658cdbc6dSChristophe Leroy 32758cdbc6dSChristophe Leroy if (!is_sec1) 32858cdbc6dSChristophe Leroy return request->desc->hdr; 32958cdbc6dSChristophe Leroy 33058cdbc6dSChristophe Leroy if (!request->desc->next_desc) 33158cdbc6dSChristophe Leroy return request->desc->hdr1; 33258cdbc6dSChristophe Leroy 33358cdbc6dSChristophe Leroy edesc = container_of(request->desc, struct talitos_edesc, desc); 33458cdbc6dSChristophe Leroy 33558cdbc6dSChristophe Leroy return ((struct talitos_desc *)(edesc->buf + edesc->dma_len))->hdr1; 33658cdbc6dSChristophe Leroy } 3379c4a7965SKim Phillips 3389c4a7965SKim Phillips /* 3399c4a7965SKim Phillips * process what was done, notify callback of error if not 3409c4a7965SKim Phillips */ 3419c4a7965SKim Phillips static void flush_channel(struct device *dev, int ch, int error, int reset_ch) 3429c4a7965SKim Phillips { 3439c4a7965SKim Phillips struct talitos_private *priv = dev_get_drvdata(dev); 3449c4a7965SKim Phillips struct talitos_request *request, saved_req; 3459c4a7965SKim Phillips unsigned long flags; 3469c4a7965SKim Phillips int tail, status; 3477d607c6aSLEROY Christophe bool is_sec1 = has_ftr_sec1(priv); 3489c4a7965SKim Phillips 3494b992628SKim Phillips spin_lock_irqsave(&priv->chan[ch].tail_lock, flags); 3509c4a7965SKim Phillips 3514b992628SKim Phillips tail = priv->chan[ch].tail; 3524b992628SKim Phillips while (priv->chan[ch].fifo[tail].desc) { 3537d607c6aSLEROY Christophe __be32 hdr; 3547d607c6aSLEROY Christophe 3554b992628SKim Phillips request = &priv->chan[ch].fifo[tail]; 3569c4a7965SKim Phillips 3579c4a7965SKim Phillips /* descriptors with their done bits set don't get the error */ 3589c4a7965SKim Phillips rmb(); 35958cdbc6dSChristophe Leroy hdr = get_request_hdr(request, is_sec1); 3607d607c6aSLEROY Christophe 3617d607c6aSLEROY Christophe if ((hdr & DESC_HDR_DONE) == DESC_HDR_DONE) 3629c4a7965SKim Phillips status = 0; 363ca38a814SLee Nipper else 3649c4a7965SKim Phillips if (!error) 3659c4a7965SKim Phillips break; 3669c4a7965SKim Phillips else 3679c4a7965SKim Phillips status = error; 3689c4a7965SKim Phillips 3699c4a7965SKim Phillips dma_unmap_single(dev, request->dma_desc, 3707d607c6aSLEROY Christophe TALITOS_DESC_SIZE, 371e938e465SKim Phillips DMA_BIDIRECTIONAL); 3729c4a7965SKim Phillips 3739c4a7965SKim Phillips /* copy entries so we can call callback outside lock */ 3749c4a7965SKim Phillips saved_req.desc = request->desc; 3759c4a7965SKim Phillips saved_req.callback = request->callback; 3769c4a7965SKim Phillips saved_req.context = request->context; 3779c4a7965SKim Phillips 3789c4a7965SKim Phillips /* release request entry in fifo */ 3799c4a7965SKim Phillips smp_wmb(); 3809c4a7965SKim Phillips request->desc = NULL; 3819c4a7965SKim Phillips 3829c4a7965SKim Phillips /* increment fifo tail */ 3834b992628SKim Phillips priv->chan[ch].tail = (tail + 1) & (priv->fifo_len - 1); 3849c4a7965SKim Phillips 3854b992628SKim Phillips spin_unlock_irqrestore(&priv->chan[ch].tail_lock, flags); 386ec6644d6SKim Phillips 3874b992628SKim Phillips atomic_dec(&priv->chan[ch].submit_count); 388ec6644d6SKim Phillips 3899c4a7965SKim Phillips saved_req.callback(dev, saved_req.desc, saved_req.context, 3909c4a7965SKim Phillips status); 3919c4a7965SKim Phillips /* channel may resume processing in single desc error case */ 3929c4a7965SKim Phillips if (error && !reset_ch && status == error) 3939c4a7965SKim Phillips return; 3944b992628SKim Phillips spin_lock_irqsave(&priv->chan[ch].tail_lock, flags); 3954b992628SKim Phillips tail = priv->chan[ch].tail; 3969c4a7965SKim Phillips } 3979c4a7965SKim Phillips 3984b992628SKim Phillips spin_unlock_irqrestore(&priv->chan[ch].tail_lock, flags); 3999c4a7965SKim Phillips } 4009c4a7965SKim Phillips 4019c4a7965SKim Phillips /* 4029c4a7965SKim Phillips * process completed requests for channels that have done status 4039c4a7965SKim Phillips */ 404dd3c0987SLEROY Christophe #define DEF_TALITOS1_DONE(name, ch_done_mask) \ 405dd3c0987SLEROY Christophe static void talitos1_done_##name(unsigned long data) \ 406dd3c0987SLEROY Christophe { \ 407dd3c0987SLEROY Christophe struct device *dev = (struct device *)data; \ 408dd3c0987SLEROY Christophe struct talitos_private *priv = dev_get_drvdata(dev); \ 409dd3c0987SLEROY Christophe unsigned long flags; \ 410dd3c0987SLEROY Christophe \ 411dd3c0987SLEROY Christophe if (ch_done_mask & 0x10000000) \ 412dd3c0987SLEROY Christophe flush_channel(dev, 0, 0, 0); \ 413dd3c0987SLEROY Christophe if (ch_done_mask & 0x40000000) \ 414dd3c0987SLEROY Christophe flush_channel(dev, 1, 0, 0); \ 415dd3c0987SLEROY Christophe if (ch_done_mask & 0x00010000) \ 416dd3c0987SLEROY Christophe flush_channel(dev, 2, 0, 0); \ 417dd3c0987SLEROY Christophe if (ch_done_mask & 0x00040000) \ 418dd3c0987SLEROY Christophe flush_channel(dev, 3, 0, 0); \ 419dd3c0987SLEROY Christophe \ 420dd3c0987SLEROY Christophe /* At this point, all completed channels have been processed */ \ 421dd3c0987SLEROY Christophe /* Unmask done interrupts for channels completed later on. */ \ 422dd3c0987SLEROY Christophe spin_lock_irqsave(&priv->reg_lock, flags); \ 423dd3c0987SLEROY Christophe clrbits32(priv->reg + TALITOS_IMR, ch_done_mask); \ 424dd3c0987SLEROY Christophe clrbits32(priv->reg + TALITOS_IMR_LO, TALITOS1_IMR_LO_INIT); \ 425dd3c0987SLEROY Christophe spin_unlock_irqrestore(&priv->reg_lock, flags); \ 426dd3c0987SLEROY Christophe } 427dd3c0987SLEROY Christophe 428dd3c0987SLEROY Christophe DEF_TALITOS1_DONE(4ch, TALITOS1_ISR_4CHDONE) 4299c02e285SLEROY Christophe DEF_TALITOS1_DONE(ch0, TALITOS1_ISR_CH_0_DONE) 430dd3c0987SLEROY Christophe 431dd3c0987SLEROY Christophe #define DEF_TALITOS2_DONE(name, ch_done_mask) \ 432dd3c0987SLEROY Christophe static void talitos2_done_##name(unsigned long data) \ 433c3e337f8SKim Phillips { \ 434c3e337f8SKim Phillips struct device *dev = (struct device *)data; \ 435c3e337f8SKim Phillips struct talitos_private *priv = dev_get_drvdata(dev); \ 436511d63cbSHoria Geanta unsigned long flags; \ 437c3e337f8SKim Phillips \ 438c3e337f8SKim Phillips if (ch_done_mask & 1) \ 439c3e337f8SKim Phillips flush_channel(dev, 0, 0, 0); \ 440c3e337f8SKim Phillips if (ch_done_mask & (1 << 2)) \ 441c3e337f8SKim Phillips flush_channel(dev, 1, 0, 0); \ 442c3e337f8SKim Phillips if (ch_done_mask & (1 << 4)) \ 443c3e337f8SKim Phillips flush_channel(dev, 2, 0, 0); \ 444c3e337f8SKim Phillips if (ch_done_mask & (1 << 6)) \ 445c3e337f8SKim Phillips flush_channel(dev, 3, 0, 0); \ 446c3e337f8SKim Phillips \ 447c3e337f8SKim Phillips /* At this point, all completed channels have been processed */ \ 448c3e337f8SKim Phillips /* Unmask done interrupts for channels completed later on. */ \ 449511d63cbSHoria Geanta spin_lock_irqsave(&priv->reg_lock, flags); \ 450c3e337f8SKim Phillips setbits32(priv->reg + TALITOS_IMR, ch_done_mask); \ 451dd3c0987SLEROY Christophe setbits32(priv->reg + TALITOS_IMR_LO, TALITOS2_IMR_LO_INIT); \ 452511d63cbSHoria Geanta spin_unlock_irqrestore(&priv->reg_lock, flags); \ 4539c4a7965SKim Phillips } 454dd3c0987SLEROY Christophe 455dd3c0987SLEROY Christophe DEF_TALITOS2_DONE(4ch, TALITOS2_ISR_4CHDONE) 4569c02e285SLEROY Christophe DEF_TALITOS2_DONE(ch0, TALITOS2_ISR_CH_0_DONE) 457dd3c0987SLEROY Christophe DEF_TALITOS2_DONE(ch0_2, TALITOS2_ISR_CH_0_2_DONE) 458dd3c0987SLEROY Christophe DEF_TALITOS2_DONE(ch1_3, TALITOS2_ISR_CH_1_3_DONE) 4599c4a7965SKim Phillips 4609c4a7965SKim Phillips /* 4619c4a7965SKim Phillips * locate current (offending) descriptor 4629c4a7965SKim Phillips */ 4633e721aebSKim Phillips static u32 current_desc_hdr(struct device *dev, int ch) 4649c4a7965SKim Phillips { 4659c4a7965SKim Phillips struct talitos_private *priv = dev_get_drvdata(dev); 466b62ffd8cSHoria Geanta int tail, iter; 4679c4a7965SKim Phillips dma_addr_t cur_desc; 4689c4a7965SKim Phillips 469b62ffd8cSHoria Geanta cur_desc = ((u64)in_be32(priv->chan[ch].reg + TALITOS_CDPR)) << 32; 470b62ffd8cSHoria Geanta cur_desc |= in_be32(priv->chan[ch].reg + TALITOS_CDPR_LO); 4719c4a7965SKim Phillips 472b62ffd8cSHoria Geanta if (!cur_desc) { 473b62ffd8cSHoria Geanta dev_err(dev, "CDPR is NULL, giving up search for offending descriptor\n"); 474b62ffd8cSHoria Geanta return 0; 475b62ffd8cSHoria Geanta } 476b62ffd8cSHoria Geanta 477b62ffd8cSHoria Geanta tail = priv->chan[ch].tail; 478b62ffd8cSHoria Geanta 479b62ffd8cSHoria Geanta iter = tail; 48037b5e889SLEROY Christophe while (priv->chan[ch].fifo[iter].dma_desc != cur_desc && 48137b5e889SLEROY Christophe priv->chan[ch].fifo[iter].desc->next_desc != cur_desc) { 482b62ffd8cSHoria Geanta iter = (iter + 1) & (priv->fifo_len - 1); 483b62ffd8cSHoria Geanta if (iter == tail) { 4849c4a7965SKim Phillips dev_err(dev, "couldn't locate current descriptor\n"); 4853e721aebSKim Phillips return 0; 4869c4a7965SKim Phillips } 4879c4a7965SKim Phillips } 4889c4a7965SKim Phillips 48958cdbc6dSChristophe Leroy if (priv->chan[ch].fifo[iter].desc->next_desc == cur_desc) { 49058cdbc6dSChristophe Leroy struct talitos_edesc *edesc; 49158cdbc6dSChristophe Leroy 49258cdbc6dSChristophe Leroy edesc = container_of(priv->chan[ch].fifo[iter].desc, 49358cdbc6dSChristophe Leroy struct talitos_edesc, desc); 49458cdbc6dSChristophe Leroy return ((struct talitos_desc *) 49558cdbc6dSChristophe Leroy (edesc->buf + edesc->dma_len))->hdr; 49658cdbc6dSChristophe Leroy } 49737b5e889SLEROY Christophe 498b62ffd8cSHoria Geanta return priv->chan[ch].fifo[iter].desc->hdr; 4999c4a7965SKim Phillips } 5009c4a7965SKim Phillips 5019c4a7965SKim Phillips /* 5029c4a7965SKim Phillips * user diagnostics; report root cause of error based on execution unit status 5039c4a7965SKim Phillips */ 5043e721aebSKim Phillips static void report_eu_error(struct device *dev, int ch, u32 desc_hdr) 5059c4a7965SKim Phillips { 5069c4a7965SKim Phillips struct talitos_private *priv = dev_get_drvdata(dev); 5079c4a7965SKim Phillips int i; 5089c4a7965SKim Phillips 5093e721aebSKim Phillips if (!desc_hdr) 510ad42d5fcSKim Phillips desc_hdr = in_be32(priv->chan[ch].reg + TALITOS_DESCBUF); 5113e721aebSKim Phillips 5123e721aebSKim Phillips switch (desc_hdr & DESC_HDR_SEL0_MASK) { 5139c4a7965SKim Phillips case DESC_HDR_SEL0_AFEU: 5149c4a7965SKim Phillips dev_err(dev, "AFEUISR 0x%08x_%08x\n", 5155fa7fa14SLEROY Christophe in_be32(priv->reg_afeu + TALITOS_EUISR), 5165fa7fa14SLEROY Christophe in_be32(priv->reg_afeu + TALITOS_EUISR_LO)); 5179c4a7965SKim Phillips break; 5189c4a7965SKim Phillips case DESC_HDR_SEL0_DEU: 5199c4a7965SKim Phillips dev_err(dev, "DEUISR 0x%08x_%08x\n", 5205fa7fa14SLEROY Christophe in_be32(priv->reg_deu + TALITOS_EUISR), 5215fa7fa14SLEROY Christophe in_be32(priv->reg_deu + TALITOS_EUISR_LO)); 5229c4a7965SKim Phillips break; 5239c4a7965SKim Phillips case DESC_HDR_SEL0_MDEUA: 5249c4a7965SKim Phillips case DESC_HDR_SEL0_MDEUB: 5259c4a7965SKim Phillips dev_err(dev, "MDEUISR 0x%08x_%08x\n", 5265fa7fa14SLEROY Christophe in_be32(priv->reg_mdeu + TALITOS_EUISR), 5275fa7fa14SLEROY Christophe in_be32(priv->reg_mdeu + TALITOS_EUISR_LO)); 5289c4a7965SKim Phillips break; 5299c4a7965SKim Phillips case DESC_HDR_SEL0_RNG: 5309c4a7965SKim Phillips dev_err(dev, "RNGUISR 0x%08x_%08x\n", 5315fa7fa14SLEROY Christophe in_be32(priv->reg_rngu + TALITOS_ISR), 5325fa7fa14SLEROY Christophe in_be32(priv->reg_rngu + TALITOS_ISR_LO)); 5339c4a7965SKim Phillips break; 5349c4a7965SKim Phillips case DESC_HDR_SEL0_PKEU: 5359c4a7965SKim Phillips dev_err(dev, "PKEUISR 0x%08x_%08x\n", 5365fa7fa14SLEROY Christophe in_be32(priv->reg_pkeu + TALITOS_EUISR), 5375fa7fa14SLEROY Christophe in_be32(priv->reg_pkeu + TALITOS_EUISR_LO)); 5389c4a7965SKim Phillips break; 5399c4a7965SKim Phillips case DESC_HDR_SEL0_AESU: 5409c4a7965SKim Phillips dev_err(dev, "AESUISR 0x%08x_%08x\n", 5415fa7fa14SLEROY Christophe in_be32(priv->reg_aesu + TALITOS_EUISR), 5425fa7fa14SLEROY Christophe in_be32(priv->reg_aesu + TALITOS_EUISR_LO)); 5439c4a7965SKim Phillips break; 5449c4a7965SKim Phillips case DESC_HDR_SEL0_CRCU: 5459c4a7965SKim Phillips dev_err(dev, "CRCUISR 0x%08x_%08x\n", 5465fa7fa14SLEROY Christophe in_be32(priv->reg_crcu + TALITOS_EUISR), 5475fa7fa14SLEROY Christophe in_be32(priv->reg_crcu + TALITOS_EUISR_LO)); 5489c4a7965SKim Phillips break; 5499c4a7965SKim Phillips case DESC_HDR_SEL0_KEU: 5509c4a7965SKim Phillips dev_err(dev, "KEUISR 0x%08x_%08x\n", 5515fa7fa14SLEROY Christophe in_be32(priv->reg_pkeu + TALITOS_EUISR), 5525fa7fa14SLEROY Christophe in_be32(priv->reg_pkeu + TALITOS_EUISR_LO)); 5539c4a7965SKim Phillips break; 5549c4a7965SKim Phillips } 5559c4a7965SKim Phillips 5563e721aebSKim Phillips switch (desc_hdr & DESC_HDR_SEL1_MASK) { 5579c4a7965SKim Phillips case DESC_HDR_SEL1_MDEUA: 5589c4a7965SKim Phillips case DESC_HDR_SEL1_MDEUB: 5599c4a7965SKim Phillips dev_err(dev, "MDEUISR 0x%08x_%08x\n", 5605fa7fa14SLEROY Christophe in_be32(priv->reg_mdeu + TALITOS_EUISR), 5615fa7fa14SLEROY Christophe in_be32(priv->reg_mdeu + TALITOS_EUISR_LO)); 5629c4a7965SKim Phillips break; 5639c4a7965SKim Phillips case DESC_HDR_SEL1_CRCU: 5649c4a7965SKim Phillips dev_err(dev, "CRCUISR 0x%08x_%08x\n", 5655fa7fa14SLEROY Christophe in_be32(priv->reg_crcu + TALITOS_EUISR), 5665fa7fa14SLEROY Christophe in_be32(priv->reg_crcu + TALITOS_EUISR_LO)); 5679c4a7965SKim Phillips break; 5689c4a7965SKim Phillips } 5699c4a7965SKim Phillips 5709c4a7965SKim Phillips for (i = 0; i < 8; i++) 5719c4a7965SKim Phillips dev_err(dev, "DESCBUF 0x%08x_%08x\n", 572ad42d5fcSKim Phillips in_be32(priv->chan[ch].reg + TALITOS_DESCBUF + 8*i), 573ad42d5fcSKim Phillips in_be32(priv->chan[ch].reg + TALITOS_DESCBUF_LO + 8*i)); 5749c4a7965SKim Phillips } 5759c4a7965SKim Phillips 5769c4a7965SKim Phillips /* 5779c4a7965SKim Phillips * recover from error interrupts 5789c4a7965SKim Phillips */ 5795e718a09SKim Phillips static void talitos_error(struct device *dev, u32 isr, u32 isr_lo) 5809c4a7965SKim Phillips { 5819c4a7965SKim Phillips struct talitos_private *priv = dev_get_drvdata(dev); 5829c4a7965SKim Phillips unsigned int timeout = TALITOS_TIMEOUT; 583dd3c0987SLEROY Christophe int ch, error, reset_dev = 0; 58442e8b0d7SHoria Geant? u32 v_lo; 585dd3c0987SLEROY Christophe bool is_sec1 = has_ftr_sec1(priv); 586dd3c0987SLEROY Christophe int reset_ch = is_sec1 ? 1 : 0; /* only SEC2 supports continuation */ 5879c4a7965SKim Phillips 5889c4a7965SKim Phillips for (ch = 0; ch < priv->num_channels; ch++) { 5899c4a7965SKim Phillips /* skip channels without errors */ 590dd3c0987SLEROY Christophe if (is_sec1) { 591dd3c0987SLEROY Christophe /* bits 29, 31, 17, 19 */ 592dd3c0987SLEROY Christophe if (!(isr & (1 << (29 + (ch & 1) * 2 - (ch & 2) * 6)))) 593dd3c0987SLEROY Christophe continue; 594dd3c0987SLEROY Christophe } else { 5959c4a7965SKim Phillips if (!(isr & (1 << (ch * 2 + 1)))) 5969c4a7965SKim Phillips continue; 597dd3c0987SLEROY Christophe } 5989c4a7965SKim Phillips 5999c4a7965SKim Phillips error = -EINVAL; 6009c4a7965SKim Phillips 601ad42d5fcSKim Phillips v_lo = in_be32(priv->chan[ch].reg + TALITOS_CCPSR_LO); 6029c4a7965SKim Phillips 6039c4a7965SKim Phillips if (v_lo & TALITOS_CCPSR_LO_DOF) { 6049c4a7965SKim Phillips dev_err(dev, "double fetch fifo overflow error\n"); 6059c4a7965SKim Phillips error = -EAGAIN; 6069c4a7965SKim Phillips reset_ch = 1; 6079c4a7965SKim Phillips } 6089c4a7965SKim Phillips if (v_lo & TALITOS_CCPSR_LO_SOF) { 6099c4a7965SKim Phillips /* h/w dropped descriptor */ 6109c4a7965SKim Phillips dev_err(dev, "single fetch fifo overflow error\n"); 6119c4a7965SKim Phillips error = -EAGAIN; 6129c4a7965SKim Phillips } 6139c4a7965SKim Phillips if (v_lo & TALITOS_CCPSR_LO_MDTE) 6149c4a7965SKim Phillips dev_err(dev, "master data transfer error\n"); 6159c4a7965SKim Phillips if (v_lo & TALITOS_CCPSR_LO_SGDLZ) 6164d9b3a5bSColin Ian King dev_err(dev, is_sec1 ? "pointer not complete error\n" 617dd3c0987SLEROY Christophe : "s/g data length zero error\n"); 6189c4a7965SKim Phillips if (v_lo & TALITOS_CCPSR_LO_FPZ) 619dd3c0987SLEROY Christophe dev_err(dev, is_sec1 ? "parity error\n" 620dd3c0987SLEROY Christophe : "fetch pointer zero error\n"); 6219c4a7965SKim Phillips if (v_lo & TALITOS_CCPSR_LO_IDH) 6229c4a7965SKim Phillips dev_err(dev, "illegal descriptor header error\n"); 6239c4a7965SKim Phillips if (v_lo & TALITOS_CCPSR_LO_IEU) 624dd3c0987SLEROY Christophe dev_err(dev, is_sec1 ? "static assignment error\n" 625dd3c0987SLEROY Christophe : "invalid exec unit error\n"); 6269c4a7965SKim Phillips if (v_lo & TALITOS_CCPSR_LO_EU) 6273e721aebSKim Phillips report_eu_error(dev, ch, current_desc_hdr(dev, ch)); 628dd3c0987SLEROY Christophe if (!is_sec1) { 6299c4a7965SKim Phillips if (v_lo & TALITOS_CCPSR_LO_GB) 6309c4a7965SKim Phillips dev_err(dev, "gather boundary error\n"); 6319c4a7965SKim Phillips if (v_lo & TALITOS_CCPSR_LO_GRL) 6329c4a7965SKim Phillips dev_err(dev, "gather return/length error\n"); 6339c4a7965SKim Phillips if (v_lo & TALITOS_CCPSR_LO_SB) 6349c4a7965SKim Phillips dev_err(dev, "scatter boundary error\n"); 6359c4a7965SKim Phillips if (v_lo & TALITOS_CCPSR_LO_SRL) 6369c4a7965SKim Phillips dev_err(dev, "scatter return/length error\n"); 637dd3c0987SLEROY Christophe } 6389c4a7965SKim Phillips 6399c4a7965SKim Phillips flush_channel(dev, ch, error, reset_ch); 6409c4a7965SKim Phillips 6419c4a7965SKim Phillips if (reset_ch) { 6429c4a7965SKim Phillips reset_channel(dev, ch); 6439c4a7965SKim Phillips } else { 644ad42d5fcSKim Phillips setbits32(priv->chan[ch].reg + TALITOS_CCCR, 645dd3c0987SLEROY Christophe TALITOS2_CCCR_CONT); 646ad42d5fcSKim Phillips setbits32(priv->chan[ch].reg + TALITOS_CCCR_LO, 0); 647ad42d5fcSKim Phillips while ((in_be32(priv->chan[ch].reg + TALITOS_CCCR) & 648dd3c0987SLEROY Christophe TALITOS2_CCCR_CONT) && --timeout) 6499c4a7965SKim Phillips cpu_relax(); 6509c4a7965SKim Phillips if (timeout == 0) { 6519c4a7965SKim Phillips dev_err(dev, "failed to restart channel %d\n", 6529c4a7965SKim Phillips ch); 6539c4a7965SKim Phillips reset_dev = 1; 6549c4a7965SKim Phillips } 6559c4a7965SKim Phillips } 6569c4a7965SKim Phillips } 657dd3c0987SLEROY Christophe if (reset_dev || (is_sec1 && isr & ~TALITOS1_ISR_4CHERR) || 658dd3c0987SLEROY Christophe (!is_sec1 && isr & ~TALITOS2_ISR_4CHERR) || isr_lo) { 659dd3c0987SLEROY Christophe if (is_sec1 && (isr_lo & TALITOS1_ISR_TEA_ERR)) 660dd3c0987SLEROY Christophe dev_err(dev, "TEA error: ISR 0x%08x_%08x\n", 661dd3c0987SLEROY Christophe isr, isr_lo); 662dd3c0987SLEROY Christophe else 663dd3c0987SLEROY Christophe dev_err(dev, "done overflow, internal time out, or " 664dd3c0987SLEROY Christophe "rngu error: ISR 0x%08x_%08x\n", isr, isr_lo); 6659c4a7965SKim Phillips 6669c4a7965SKim Phillips /* purge request queues */ 6679c4a7965SKim Phillips for (ch = 0; ch < priv->num_channels; ch++) 6689c4a7965SKim Phillips flush_channel(dev, ch, -EIO, 1); 6699c4a7965SKim Phillips 6709c4a7965SKim Phillips /* reset and reinitialize the device */ 6719c4a7965SKim Phillips init_device(dev); 6729c4a7965SKim Phillips } 6739c4a7965SKim Phillips } 6749c4a7965SKim Phillips 675dd3c0987SLEROY Christophe #define DEF_TALITOS1_INTERRUPT(name, ch_done_mask, ch_err_mask, tlet) \ 676dd3c0987SLEROY Christophe static irqreturn_t talitos1_interrupt_##name(int irq, void *data) \ 677dd3c0987SLEROY Christophe { \ 678dd3c0987SLEROY Christophe struct device *dev = data; \ 679dd3c0987SLEROY Christophe struct talitos_private *priv = dev_get_drvdata(dev); \ 680dd3c0987SLEROY Christophe u32 isr, isr_lo; \ 681dd3c0987SLEROY Christophe unsigned long flags; \ 682dd3c0987SLEROY Christophe \ 683dd3c0987SLEROY Christophe spin_lock_irqsave(&priv->reg_lock, flags); \ 684dd3c0987SLEROY Christophe isr = in_be32(priv->reg + TALITOS_ISR); \ 685dd3c0987SLEROY Christophe isr_lo = in_be32(priv->reg + TALITOS_ISR_LO); \ 686dd3c0987SLEROY Christophe /* Acknowledge interrupt */ \ 687dd3c0987SLEROY Christophe out_be32(priv->reg + TALITOS_ICR, isr & (ch_done_mask | ch_err_mask)); \ 688dd3c0987SLEROY Christophe out_be32(priv->reg + TALITOS_ICR_LO, isr_lo); \ 689dd3c0987SLEROY Christophe \ 690dd3c0987SLEROY Christophe if (unlikely(isr & ch_err_mask || isr_lo & TALITOS1_IMR_LO_INIT)) { \ 691dd3c0987SLEROY Christophe spin_unlock_irqrestore(&priv->reg_lock, flags); \ 692dd3c0987SLEROY Christophe talitos_error(dev, isr & ch_err_mask, isr_lo); \ 693dd3c0987SLEROY Christophe } \ 694dd3c0987SLEROY Christophe else { \ 695dd3c0987SLEROY Christophe if (likely(isr & ch_done_mask)) { \ 696dd3c0987SLEROY Christophe /* mask further done interrupts. */ \ 697dd3c0987SLEROY Christophe setbits32(priv->reg + TALITOS_IMR, ch_done_mask); \ 698dd3c0987SLEROY Christophe /* done_task will unmask done interrupts at exit */ \ 699dd3c0987SLEROY Christophe tasklet_schedule(&priv->done_task[tlet]); \ 700dd3c0987SLEROY Christophe } \ 701dd3c0987SLEROY Christophe spin_unlock_irqrestore(&priv->reg_lock, flags); \ 702dd3c0987SLEROY Christophe } \ 703dd3c0987SLEROY Christophe \ 704dd3c0987SLEROY Christophe return (isr & (ch_done_mask | ch_err_mask) || isr_lo) ? IRQ_HANDLED : \ 705dd3c0987SLEROY Christophe IRQ_NONE; \ 706dd3c0987SLEROY Christophe } 707dd3c0987SLEROY Christophe 708dd3c0987SLEROY Christophe DEF_TALITOS1_INTERRUPT(4ch, TALITOS1_ISR_4CHDONE, TALITOS1_ISR_4CHERR, 0) 709dd3c0987SLEROY Christophe 710dd3c0987SLEROY Christophe #define DEF_TALITOS2_INTERRUPT(name, ch_done_mask, ch_err_mask, tlet) \ 711dd3c0987SLEROY Christophe static irqreturn_t talitos2_interrupt_##name(int irq, void *data) \ 712c3e337f8SKim Phillips { \ 713c3e337f8SKim Phillips struct device *dev = data; \ 714c3e337f8SKim Phillips struct talitos_private *priv = dev_get_drvdata(dev); \ 715c3e337f8SKim Phillips u32 isr, isr_lo; \ 716511d63cbSHoria Geanta unsigned long flags; \ 717c3e337f8SKim Phillips \ 718511d63cbSHoria Geanta spin_lock_irqsave(&priv->reg_lock, flags); \ 719c3e337f8SKim Phillips isr = in_be32(priv->reg + TALITOS_ISR); \ 720c3e337f8SKim Phillips isr_lo = in_be32(priv->reg + TALITOS_ISR_LO); \ 721c3e337f8SKim Phillips /* Acknowledge interrupt */ \ 722c3e337f8SKim Phillips out_be32(priv->reg + TALITOS_ICR, isr & (ch_done_mask | ch_err_mask)); \ 723c3e337f8SKim Phillips out_be32(priv->reg + TALITOS_ICR_LO, isr_lo); \ 724c3e337f8SKim Phillips \ 725511d63cbSHoria Geanta if (unlikely(isr & ch_err_mask || isr_lo)) { \ 726511d63cbSHoria Geanta spin_unlock_irqrestore(&priv->reg_lock, flags); \ 727511d63cbSHoria Geanta talitos_error(dev, isr & ch_err_mask, isr_lo); \ 728511d63cbSHoria Geanta } \ 729511d63cbSHoria Geanta else { \ 730c3e337f8SKim Phillips if (likely(isr & ch_done_mask)) { \ 731c3e337f8SKim Phillips /* mask further done interrupts. */ \ 732c3e337f8SKim Phillips clrbits32(priv->reg + TALITOS_IMR, ch_done_mask); \ 733c3e337f8SKim Phillips /* done_task will unmask done interrupts at exit */ \ 734c3e337f8SKim Phillips tasklet_schedule(&priv->done_task[tlet]); \ 735c3e337f8SKim Phillips } \ 736511d63cbSHoria Geanta spin_unlock_irqrestore(&priv->reg_lock, flags); \ 737511d63cbSHoria Geanta } \ 738c3e337f8SKim Phillips \ 739c3e337f8SKim Phillips return (isr & (ch_done_mask | ch_err_mask) || isr_lo) ? IRQ_HANDLED : \ 740c3e337f8SKim Phillips IRQ_NONE; \ 7411c2e8811SLee Nipper } 742dd3c0987SLEROY Christophe 743dd3c0987SLEROY Christophe DEF_TALITOS2_INTERRUPT(4ch, TALITOS2_ISR_4CHDONE, TALITOS2_ISR_4CHERR, 0) 744dd3c0987SLEROY Christophe DEF_TALITOS2_INTERRUPT(ch0_2, TALITOS2_ISR_CH_0_2_DONE, TALITOS2_ISR_CH_0_2_ERR, 745dd3c0987SLEROY Christophe 0) 746dd3c0987SLEROY Christophe DEF_TALITOS2_INTERRUPT(ch1_3, TALITOS2_ISR_CH_1_3_DONE, TALITOS2_ISR_CH_1_3_ERR, 747dd3c0987SLEROY Christophe 1) 7489c4a7965SKim Phillips 7499c4a7965SKim Phillips /* 7509c4a7965SKim Phillips * hwrng 7519c4a7965SKim Phillips */ 7529c4a7965SKim Phillips static int talitos_rng_data_present(struct hwrng *rng, int wait) 7539c4a7965SKim Phillips { 7549c4a7965SKim Phillips struct device *dev = (struct device *)rng->priv; 7559c4a7965SKim Phillips struct talitos_private *priv = dev_get_drvdata(dev); 7569c4a7965SKim Phillips u32 ofl; 7579c4a7965SKim Phillips int i; 7589c4a7965SKim Phillips 7599c4a7965SKim Phillips for (i = 0; i < 20; i++) { 7605fa7fa14SLEROY Christophe ofl = in_be32(priv->reg_rngu + TALITOS_EUSR_LO) & 7619c4a7965SKim Phillips TALITOS_RNGUSR_LO_OFL; 7629c4a7965SKim Phillips if (ofl || !wait) 7639c4a7965SKim Phillips break; 7649c4a7965SKim Phillips udelay(10); 7659c4a7965SKim Phillips } 7669c4a7965SKim Phillips 7679c4a7965SKim Phillips return !!ofl; 7689c4a7965SKim Phillips } 7699c4a7965SKim Phillips 7709c4a7965SKim Phillips static int talitos_rng_data_read(struct hwrng *rng, u32 *data) 7719c4a7965SKim Phillips { 7729c4a7965SKim Phillips struct device *dev = (struct device *)rng->priv; 7739c4a7965SKim Phillips struct talitos_private *priv = dev_get_drvdata(dev); 7749c4a7965SKim Phillips 7759c4a7965SKim Phillips /* rng fifo requires 64-bit accesses */ 7765fa7fa14SLEROY Christophe *data = in_be32(priv->reg_rngu + TALITOS_EU_FIFO); 7775fa7fa14SLEROY Christophe *data = in_be32(priv->reg_rngu + TALITOS_EU_FIFO_LO); 7789c4a7965SKim Phillips 7799c4a7965SKim Phillips return sizeof(u32); 7809c4a7965SKim Phillips } 7819c4a7965SKim Phillips 7829c4a7965SKim Phillips static int talitos_rng_init(struct hwrng *rng) 7839c4a7965SKim Phillips { 7849c4a7965SKim Phillips struct device *dev = (struct device *)rng->priv; 7859c4a7965SKim Phillips struct talitos_private *priv = dev_get_drvdata(dev); 7869c4a7965SKim Phillips unsigned int timeout = TALITOS_TIMEOUT; 7879c4a7965SKim Phillips 7885fa7fa14SLEROY Christophe setbits32(priv->reg_rngu + TALITOS_EURCR_LO, TALITOS_RNGURCR_LO_SR); 7895fa7fa14SLEROY Christophe while (!(in_be32(priv->reg_rngu + TALITOS_EUSR_LO) 7905fa7fa14SLEROY Christophe & TALITOS_RNGUSR_LO_RD) 7919c4a7965SKim Phillips && --timeout) 7929c4a7965SKim Phillips cpu_relax(); 7939c4a7965SKim Phillips if (timeout == 0) { 7949c4a7965SKim Phillips dev_err(dev, "failed to reset rng hw\n"); 7959c4a7965SKim Phillips return -ENODEV; 7969c4a7965SKim Phillips } 7979c4a7965SKim Phillips 7989c4a7965SKim Phillips /* start generating */ 7995fa7fa14SLEROY Christophe setbits32(priv->reg_rngu + TALITOS_EUDSR_LO, 0); 8009c4a7965SKim Phillips 8019c4a7965SKim Phillips return 0; 8029c4a7965SKim Phillips } 8039c4a7965SKim Phillips 8049c4a7965SKim Phillips static int talitos_register_rng(struct device *dev) 8059c4a7965SKim Phillips { 8069c4a7965SKim Phillips struct talitos_private *priv = dev_get_drvdata(dev); 80735a3bb3dSAaron Sierra int err; 8089c4a7965SKim Phillips 8099c4a7965SKim Phillips priv->rng.name = dev_driver_string(dev), 8109c4a7965SKim Phillips priv->rng.init = talitos_rng_init, 8119c4a7965SKim Phillips priv->rng.data_present = talitos_rng_data_present, 8129c4a7965SKim Phillips priv->rng.data_read = talitos_rng_data_read, 8139c4a7965SKim Phillips priv->rng.priv = (unsigned long)dev; 8149c4a7965SKim Phillips 81535a3bb3dSAaron Sierra err = hwrng_register(&priv->rng); 81635a3bb3dSAaron Sierra if (!err) 81735a3bb3dSAaron Sierra priv->rng_registered = true; 81835a3bb3dSAaron Sierra 81935a3bb3dSAaron Sierra return err; 8209c4a7965SKim Phillips } 8219c4a7965SKim Phillips 8229c4a7965SKim Phillips static void talitos_unregister_rng(struct device *dev) 8239c4a7965SKim Phillips { 8249c4a7965SKim Phillips struct talitos_private *priv = dev_get_drvdata(dev); 8259c4a7965SKim Phillips 82635a3bb3dSAaron Sierra if (!priv->rng_registered) 82735a3bb3dSAaron Sierra return; 82835a3bb3dSAaron Sierra 8299c4a7965SKim Phillips hwrng_unregister(&priv->rng); 83035a3bb3dSAaron Sierra priv->rng_registered = false; 8319c4a7965SKim Phillips } 8329c4a7965SKim Phillips 8339c4a7965SKim Phillips /* 8349c4a7965SKim Phillips * crypto alg 8359c4a7965SKim Phillips */ 8369c4a7965SKim Phillips #define TALITOS_CRA_PRIORITY 3000 8377405c8d7SLEROY Christophe /* 8387405c8d7SLEROY Christophe * Defines a priority for doing AEAD with descriptors type 8397405c8d7SLEROY Christophe * HMAC_SNOOP_NO_AFEA (HSNA) instead of type IPSEC_ESP 8407405c8d7SLEROY Christophe */ 8417405c8d7SLEROY Christophe #define TALITOS_CRA_PRIORITY_AEAD_HSNA (TALITOS_CRA_PRIORITY - 1) 842192125edSChristophe Leroy #ifdef CONFIG_CRYPTO_DEV_TALITOS2 84303d2c511SMartin Hicks #define TALITOS_MAX_KEY_SIZE (AES_MAX_KEY_SIZE + SHA512_BLOCK_SIZE) 844b8fbdc2bSChristophe Leroy #else 845b8fbdc2bSChristophe Leroy #define TALITOS_MAX_KEY_SIZE (AES_MAX_KEY_SIZE + SHA256_BLOCK_SIZE) 846b8fbdc2bSChristophe Leroy #endif 8473952f17eSLee Nipper #define TALITOS_MAX_IV_LENGTH 16 /* max of AES_BLOCK_SIZE, DES3_EDE_BLOCK_SIZE */ 84870bcaca7SLee Nipper 8499c4a7965SKim Phillips struct talitos_ctx { 8509c4a7965SKim Phillips struct device *dev; 8515228f0f7SKim Phillips int ch; 8529c4a7965SKim Phillips __be32 desc_hdr_template; 8539c4a7965SKim Phillips u8 key[TALITOS_MAX_KEY_SIZE]; 85470bcaca7SLee Nipper u8 iv[TALITOS_MAX_IV_LENGTH]; 8552e13ce08SLEROY Christophe dma_addr_t dma_key; 8569c4a7965SKim Phillips unsigned int keylen; 8579c4a7965SKim Phillips unsigned int enckeylen; 8589c4a7965SKim Phillips unsigned int authkeylen; 8599c4a7965SKim Phillips }; 8609c4a7965SKim Phillips 861497f2e6bSLee Nipper #define HASH_MAX_BLOCK_SIZE SHA512_BLOCK_SIZE 862497f2e6bSLee Nipper #define TALITOS_MDEU_MAX_CONTEXT_SIZE TALITOS_MDEU_CONTEXT_SIZE_SHA384_SHA512 863497f2e6bSLee Nipper 864497f2e6bSLee Nipper struct talitos_ahash_req_ctx { 86560f208d7SKim Phillips u32 hw_context[TALITOS_MDEU_MAX_CONTEXT_SIZE / sizeof(u32)]; 866497f2e6bSLee Nipper unsigned int hw_context_size; 8673c0dd190SLEROY Christophe u8 buf[2][HASH_MAX_BLOCK_SIZE]; 8683c0dd190SLEROY Christophe int buf_idx; 86960f208d7SKim Phillips unsigned int swinit; 870497f2e6bSLee Nipper unsigned int first; 871497f2e6bSLee Nipper unsigned int last; 872497f2e6bSLee Nipper unsigned int to_hash_later; 87342e8b0d7SHoria Geant? unsigned int nbuf; 874497f2e6bSLee Nipper struct scatterlist bufsl[2]; 875497f2e6bSLee Nipper struct scatterlist *psrc; 876497f2e6bSLee Nipper }; 877497f2e6bSLee Nipper 8783639ca84SHoria Geant? struct talitos_export_state { 8793639ca84SHoria Geant? u32 hw_context[TALITOS_MDEU_MAX_CONTEXT_SIZE / sizeof(u32)]; 8803639ca84SHoria Geant? u8 buf[HASH_MAX_BLOCK_SIZE]; 8813639ca84SHoria Geant? unsigned int swinit; 8823639ca84SHoria Geant? unsigned int first; 8833639ca84SHoria Geant? unsigned int last; 8843639ca84SHoria Geant? unsigned int to_hash_later; 8853639ca84SHoria Geant? unsigned int nbuf; 8863639ca84SHoria Geant? }; 8873639ca84SHoria Geant? 88856af8cd4SLee Nipper static int aead_setkey(struct crypto_aead *authenc, 8899c4a7965SKim Phillips const u8 *key, unsigned int keylen) 8909c4a7965SKim Phillips { 8919c4a7965SKim Phillips struct talitos_ctx *ctx = crypto_aead_ctx(authenc); 8922e13ce08SLEROY Christophe struct device *dev = ctx->dev; 893c306a98dSMathias Krause struct crypto_authenc_keys keys; 8949c4a7965SKim Phillips 895c306a98dSMathias Krause if (crypto_authenc_extractkeys(&keys, key, keylen) != 0) 8969c4a7965SKim Phillips goto badkey; 8979c4a7965SKim Phillips 898c306a98dSMathias Krause if (keys.authkeylen + keys.enckeylen > TALITOS_MAX_KEY_SIZE) 8999c4a7965SKim Phillips goto badkey; 9009c4a7965SKim Phillips 9012e13ce08SLEROY Christophe if (ctx->keylen) 9022e13ce08SLEROY Christophe dma_unmap_single(dev, ctx->dma_key, ctx->keylen, DMA_TO_DEVICE); 9032e13ce08SLEROY Christophe 904c306a98dSMathias Krause memcpy(ctx->key, keys.authkey, keys.authkeylen); 905c306a98dSMathias Krause memcpy(&ctx->key[keys.authkeylen], keys.enckey, keys.enckeylen); 9069c4a7965SKim Phillips 907c306a98dSMathias Krause ctx->keylen = keys.authkeylen + keys.enckeylen; 908c306a98dSMathias Krause ctx->enckeylen = keys.enckeylen; 909c306a98dSMathias Krause ctx->authkeylen = keys.authkeylen; 9102e13ce08SLEROY Christophe ctx->dma_key = dma_map_single(dev, ctx->key, ctx->keylen, 9112e13ce08SLEROY Christophe DMA_TO_DEVICE); 9129c4a7965SKim Phillips 9138f0691fcSTudor-Dan Ambarus memzero_explicit(&keys, sizeof(keys)); 9149c4a7965SKim Phillips return 0; 9159c4a7965SKim Phillips 9169c4a7965SKim Phillips badkey: 9179c4a7965SKim Phillips crypto_aead_set_flags(authenc, CRYPTO_TFM_RES_BAD_KEY_LEN); 9188f0691fcSTudor-Dan Ambarus memzero_explicit(&keys, sizeof(keys)); 9199c4a7965SKim Phillips return -EINVAL; 9209c4a7965SKim Phillips } 9219c4a7965SKim Phillips 922ef7c5c85SHerbert Xu static int aead_des3_setkey(struct crypto_aead *authenc, 923ef7c5c85SHerbert Xu const u8 *key, unsigned int keylen) 924ef7c5c85SHerbert Xu { 925ef7c5c85SHerbert Xu struct talitos_ctx *ctx = crypto_aead_ctx(authenc); 926ef7c5c85SHerbert Xu struct device *dev = ctx->dev; 927ef7c5c85SHerbert Xu struct crypto_authenc_keys keys; 928ef7c5c85SHerbert Xu u32 flags; 929ef7c5c85SHerbert Xu int err; 930ef7c5c85SHerbert Xu 931ef7c5c85SHerbert Xu err = crypto_authenc_extractkeys(&keys, key, keylen); 932ef7c5c85SHerbert Xu if (unlikely(err)) 933ef7c5c85SHerbert Xu goto badkey; 934ef7c5c85SHerbert Xu 935ef7c5c85SHerbert Xu err = -EINVAL; 936ef7c5c85SHerbert Xu if (keys.authkeylen + keys.enckeylen > TALITOS_MAX_KEY_SIZE) 937ef7c5c85SHerbert Xu goto badkey; 938ef7c5c85SHerbert Xu 939*9d574ae8SArd Biesheuvel err = verify_aead_des3_key(authenc, keys.enckey, keys.enckeylen); 940*9d574ae8SArd Biesheuvel if (err) 941ef7c5c85SHerbert Xu goto out; 942ef7c5c85SHerbert Xu 943ef7c5c85SHerbert Xu if (ctx->keylen) 944ef7c5c85SHerbert Xu dma_unmap_single(dev, ctx->dma_key, ctx->keylen, DMA_TO_DEVICE); 945ef7c5c85SHerbert Xu 946ef7c5c85SHerbert Xu memcpy(ctx->key, keys.authkey, keys.authkeylen); 947ef7c5c85SHerbert Xu memcpy(&ctx->key[keys.authkeylen], keys.enckey, keys.enckeylen); 948ef7c5c85SHerbert Xu 949ef7c5c85SHerbert Xu ctx->keylen = keys.authkeylen + keys.enckeylen; 950ef7c5c85SHerbert Xu ctx->enckeylen = keys.enckeylen; 951ef7c5c85SHerbert Xu ctx->authkeylen = keys.authkeylen; 952ef7c5c85SHerbert Xu ctx->dma_key = dma_map_single(dev, ctx->key, ctx->keylen, 953ef7c5c85SHerbert Xu DMA_TO_DEVICE); 954ef7c5c85SHerbert Xu 955ef7c5c85SHerbert Xu out: 956ef7c5c85SHerbert Xu memzero_explicit(&keys, sizeof(keys)); 957ef7c5c85SHerbert Xu return err; 958ef7c5c85SHerbert Xu 959ef7c5c85SHerbert Xu badkey: 960ef7c5c85SHerbert Xu crypto_aead_set_flags(authenc, CRYPTO_TFM_RES_BAD_KEY_LEN); 961ef7c5c85SHerbert Xu goto out; 962ef7c5c85SHerbert Xu } 963ef7c5c85SHerbert Xu 9644de9d0b5SLee Nipper static void talitos_sg_unmap(struct device *dev, 9654de9d0b5SLee Nipper struct talitos_edesc *edesc, 9664de9d0b5SLee Nipper struct scatterlist *src, 9676a1e8d14SLEROY Christophe struct scatterlist *dst, 9686a1e8d14SLEROY Christophe unsigned int len, unsigned int offset) 969246a87cdSLEROY Christophe { 970246a87cdSLEROY Christophe struct talitos_private *priv = dev_get_drvdata(dev); 971246a87cdSLEROY Christophe bool is_sec1 = has_ftr_sec1(priv); 9726a1e8d14SLEROY Christophe unsigned int src_nents = edesc->src_nents ? : 1; 9736a1e8d14SLEROY Christophe unsigned int dst_nents = edesc->dst_nents ? : 1; 974246a87cdSLEROY Christophe 9756a1e8d14SLEROY Christophe if (is_sec1 && dst && dst_nents > 1) { 9766a1e8d14SLEROY Christophe dma_sync_single_for_device(dev, edesc->dma_link_tbl + offset, 977246a87cdSLEROY Christophe len, DMA_FROM_DEVICE); 9786a1e8d14SLEROY Christophe sg_pcopy_from_buffer(dst, dst_nents, edesc->buf + offset, len, 9796a1e8d14SLEROY Christophe offset); 980246a87cdSLEROY Christophe } 9816a1e8d14SLEROY Christophe if (src != dst) { 9826a1e8d14SLEROY Christophe if (src_nents == 1 || !is_sec1) 9836a1e8d14SLEROY Christophe dma_unmap_sg(dev, src, src_nents, DMA_TO_DEVICE); 9846a1e8d14SLEROY Christophe 9856a1e8d14SLEROY Christophe if (dst && (dst_nents == 1 || !is_sec1)) 9866a1e8d14SLEROY Christophe dma_unmap_sg(dev, dst, dst_nents, DMA_FROM_DEVICE); 9876a1e8d14SLEROY Christophe } else if (src_nents == 1 || !is_sec1) { 9886a1e8d14SLEROY Christophe dma_unmap_sg(dev, src, src_nents, DMA_BIDIRECTIONAL); 989246a87cdSLEROY Christophe } 990246a87cdSLEROY Christophe } 991246a87cdSLEROY Christophe 9929c4a7965SKim Phillips static void ipsec_esp_unmap(struct device *dev, 99356af8cd4SLee Nipper struct talitos_edesc *edesc, 9947ede4c36SChristophe Leroy struct aead_request *areq, bool encrypt) 9959c4a7965SKim Phillips { 996549bd8bcSLEROY Christophe struct crypto_aead *aead = crypto_aead_reqtfm(areq); 997549bd8bcSLEROY Christophe struct talitos_ctx *ctx = crypto_aead_ctx(aead); 998549bd8bcSLEROY Christophe unsigned int ivsize = crypto_aead_ivsize(aead); 9997ede4c36SChristophe Leroy unsigned int authsize = crypto_aead_authsize(aead); 10007ede4c36SChristophe Leroy unsigned int cryptlen = areq->cryptlen - (encrypt ? 0 : authsize); 10019a655608SLEROY Christophe bool is_ipsec_esp = edesc->desc.hdr & DESC_HDR_TYPE_IPSEC_ESP; 10029a655608SLEROY Christophe struct talitos_ptr *civ_ptr = &edesc->desc.ptr[is_ipsec_esp ? 2 : 3]; 1003549bd8bcSLEROY Christophe 10049a655608SLEROY Christophe if (is_ipsec_esp) 1005549bd8bcSLEROY Christophe unmap_single_talitos_ptr(dev, &edesc->desc.ptr[6], 1006549bd8bcSLEROY Christophe DMA_FROM_DEVICE); 10079a655608SLEROY Christophe unmap_single_talitos_ptr(dev, civ_ptr, DMA_TO_DEVICE); 10089c4a7965SKim Phillips 1009e345177dSChristophe Leroy talitos_sg_unmap(dev, edesc, areq->src, areq->dst, 1010e345177dSChristophe Leroy cryptlen + authsize, areq->assoclen); 10119c4a7965SKim Phillips 10129c4a7965SKim Phillips if (edesc->dma_len) 10139c4a7965SKim Phillips dma_unmap_single(dev, edesc->dma_link_tbl, edesc->dma_len, 10149c4a7965SKim Phillips DMA_BIDIRECTIONAL); 1015549bd8bcSLEROY Christophe 10169a655608SLEROY Christophe if (!is_ipsec_esp) { 1017549bd8bcSLEROY Christophe unsigned int dst_nents = edesc->dst_nents ? : 1; 1018549bd8bcSLEROY Christophe 1019549bd8bcSLEROY Christophe sg_pcopy_to_buffer(areq->dst, dst_nents, ctx->iv, ivsize, 10207ede4c36SChristophe Leroy areq->assoclen + cryptlen - ivsize); 1021549bd8bcSLEROY Christophe } 10229c4a7965SKim Phillips } 10239c4a7965SKim Phillips 10249c4a7965SKim Phillips /* 10259c4a7965SKim Phillips * ipsec_esp descriptor callbacks 10269c4a7965SKim Phillips */ 10279c4a7965SKim Phillips static void ipsec_esp_encrypt_done(struct device *dev, 10289c4a7965SKim Phillips struct talitos_desc *desc, void *context, 10299c4a7965SKim Phillips int err) 10309c4a7965SKim Phillips { 10319c4a7965SKim Phillips struct aead_request *areq = context; 10329c4a7965SKim Phillips struct crypto_aead *authenc = crypto_aead_reqtfm(areq); 10332e13ce08SLEROY Christophe unsigned int ivsize = crypto_aead_ivsize(authenc); 103419bbbc63SKim Phillips struct talitos_edesc *edesc; 10359c4a7965SKim Phillips 103619bbbc63SKim Phillips edesc = container_of(desc, struct talitos_edesc, desc); 103719bbbc63SKim Phillips 10387ede4c36SChristophe Leroy ipsec_esp_unmap(dev, edesc, areq, true); 10399c4a7965SKim Phillips 10402e13ce08SLEROY Christophe dma_unmap_single(dev, edesc->iv_dma, ivsize, DMA_TO_DEVICE); 10412e13ce08SLEROY Christophe 10429c4a7965SKim Phillips kfree(edesc); 10439c4a7965SKim Phillips 10449c4a7965SKim Phillips aead_request_complete(areq, err); 10459c4a7965SKim Phillips } 10469c4a7965SKim Phillips 1047fe5720e2SKim Phillips static void ipsec_esp_decrypt_swauth_done(struct device *dev, 1048e938e465SKim Phillips struct talitos_desc *desc, 1049e938e465SKim Phillips void *context, int err) 10509c4a7965SKim Phillips { 10519c4a7965SKim Phillips struct aead_request *req = context; 10529c4a7965SKim Phillips struct crypto_aead *authenc = crypto_aead_reqtfm(req); 1053aeb4c132SHerbert Xu unsigned int authsize = crypto_aead_authsize(authenc); 105419bbbc63SKim Phillips struct talitos_edesc *edesc; 1055aeb4c132SHerbert Xu char *oicv, *icv; 10569c4a7965SKim Phillips 105719bbbc63SKim Phillips edesc = container_of(desc, struct talitos_edesc, desc); 105819bbbc63SKim Phillips 10597ede4c36SChristophe Leroy ipsec_esp_unmap(dev, edesc, req, false); 10609c4a7965SKim Phillips 10619c4a7965SKim Phillips if (!err) { 10629c4a7965SKim Phillips /* auth check */ 1063e345177dSChristophe Leroy oicv = edesc->buf + edesc->dma_len; 1064e345177dSChristophe Leroy icv = oicv - authsize; 1065aeb4c132SHerbert Xu 106679960943SDavid Gstir err = crypto_memneq(oicv, icv, authsize) ? -EBADMSG : 0; 10679c4a7965SKim Phillips } 10689c4a7965SKim Phillips 10699c4a7965SKim Phillips kfree(edesc); 10709c4a7965SKim Phillips 10719c4a7965SKim Phillips aead_request_complete(req, err); 10729c4a7965SKim Phillips } 10739c4a7965SKim Phillips 1074fe5720e2SKim Phillips static void ipsec_esp_decrypt_hwauth_done(struct device *dev, 1075e938e465SKim Phillips struct talitos_desc *desc, 1076e938e465SKim Phillips void *context, int err) 1077fe5720e2SKim Phillips { 1078fe5720e2SKim Phillips struct aead_request *req = context; 107919bbbc63SKim Phillips struct talitos_edesc *edesc; 108019bbbc63SKim Phillips 108119bbbc63SKim Phillips edesc = container_of(desc, struct talitos_edesc, desc); 1082fe5720e2SKim Phillips 10837ede4c36SChristophe Leroy ipsec_esp_unmap(dev, edesc, req, false); 1084fe5720e2SKim Phillips 1085fe5720e2SKim Phillips /* check ICV auth status */ 1086e938e465SKim Phillips if (!err && ((desc->hdr_lo & DESC_HDR_LO_ICCR1_MASK) != 1087e938e465SKim Phillips DESC_HDR_LO_ICCR1_PASS)) 1088fe5720e2SKim Phillips err = -EBADMSG; 1089fe5720e2SKim Phillips 1090fe5720e2SKim Phillips kfree(edesc); 1091fe5720e2SKim Phillips 1092fe5720e2SKim Phillips aead_request_complete(req, err); 1093fe5720e2SKim Phillips } 1094fe5720e2SKim Phillips 10959c4a7965SKim Phillips /* 10969c4a7965SKim Phillips * convert scatterlist to SEC h/w link table format 10979c4a7965SKim Phillips * stop at cryptlen bytes 10989c4a7965SKim Phillips */ 1099aeb4c132SHerbert Xu static int sg_to_link_tbl_offset(struct scatterlist *sg, int sg_count, 1100e345177dSChristophe Leroy unsigned int offset, int datalen, int elen, 1101aeb4c132SHerbert Xu struct talitos_ptr *link_tbl_ptr) 11029c4a7965SKim Phillips { 1103e345177dSChristophe Leroy int n_sg = elen ? sg_count + 1 : sg_count; 1104aeb4c132SHerbert Xu int count = 0; 1105e345177dSChristophe Leroy int cryptlen = datalen + elen; 110670bcaca7SLee Nipper 1107aeb4c132SHerbert Xu while (cryptlen && sg && n_sg--) { 1108aeb4c132SHerbert Xu unsigned int len = sg_dma_len(sg); 1109aeb4c132SHerbert Xu 1110aeb4c132SHerbert Xu if (offset >= len) { 1111aeb4c132SHerbert Xu offset -= len; 1112aeb4c132SHerbert Xu goto next; 1113aeb4c132SHerbert Xu } 1114aeb4c132SHerbert Xu 1115aeb4c132SHerbert Xu len -= offset; 1116aeb4c132SHerbert Xu 1117aeb4c132SHerbert Xu if (len > cryptlen) 1118aeb4c132SHerbert Xu len = cryptlen; 1119aeb4c132SHerbert Xu 1120e345177dSChristophe Leroy if (datalen > 0 && len > datalen) { 1121e345177dSChristophe Leroy to_talitos_ptr(link_tbl_ptr + count, 1122e345177dSChristophe Leroy sg_dma_address(sg) + offset, datalen, 0); 1123e345177dSChristophe Leroy to_talitos_ptr_ext_set(link_tbl_ptr + count, 0, 0); 1124e345177dSChristophe Leroy count++; 1125e345177dSChristophe Leroy len -= datalen; 1126e345177dSChristophe Leroy offset += datalen; 1127e345177dSChristophe Leroy } 1128aeb4c132SHerbert Xu to_talitos_ptr(link_tbl_ptr + count, 1129da9de146SLEROY Christophe sg_dma_address(sg) + offset, len, 0); 1130b096b544SLEROY Christophe to_talitos_ptr_ext_set(link_tbl_ptr + count, 0, 0); 1131aeb4c132SHerbert Xu count++; 1132aeb4c132SHerbert Xu cryptlen -= len; 1133e345177dSChristophe Leroy datalen -= len; 1134aeb4c132SHerbert Xu offset = 0; 1135aeb4c132SHerbert Xu 1136aeb4c132SHerbert Xu next: 11375be4d4c9SCristian Stoica sg = sg_next(sg); 11389c4a7965SKim Phillips } 11399c4a7965SKim Phillips 11409c4a7965SKim Phillips /* tag end of link table */ 1141aeb4c132SHerbert Xu if (count > 0) 1142b096b544SLEROY Christophe to_talitos_ptr_ext_set(link_tbl_ptr + count - 1, 1143e345177dSChristophe Leroy DESC_PTR_LNKTBL_RET, 0); 114470bcaca7SLee Nipper 1145aeb4c132SHerbert Xu return count; 1146aeb4c132SHerbert Xu } 1147aeb4c132SHerbert Xu 11482b122730SLEROY Christophe static int talitos_sg_map_ext(struct device *dev, struct scatterlist *src, 1149246a87cdSLEROY Christophe unsigned int len, struct talitos_edesc *edesc, 11502b122730SLEROY Christophe struct talitos_ptr *ptr, int sg_count, 1151e345177dSChristophe Leroy unsigned int offset, int tbl_off, int elen, 1152e345177dSChristophe Leroy bool force) 1153246a87cdSLEROY Christophe { 1154246a87cdSLEROY Christophe struct talitos_private *priv = dev_get_drvdata(dev); 1155246a87cdSLEROY Christophe bool is_sec1 = has_ftr_sec1(priv); 1156246a87cdSLEROY Christophe 115787a81dceSLEROY Christophe if (!src) { 115887a81dceSLEROY Christophe to_talitos_ptr(ptr, 0, 0, is_sec1); 115987a81dceSLEROY Christophe return 1; 116087a81dceSLEROY Christophe } 11612b122730SLEROY Christophe to_talitos_ptr_ext_set(ptr, elen, is_sec1); 1162e345177dSChristophe Leroy if (sg_count == 1 && !force) { 1163da9de146SLEROY Christophe to_talitos_ptr(ptr, sg_dma_address(src) + offset, len, is_sec1); 1164246a87cdSLEROY Christophe return sg_count; 1165246a87cdSLEROY Christophe } 1166246a87cdSLEROY Christophe if (is_sec1) { 1167da9de146SLEROY Christophe to_talitos_ptr(ptr, edesc->dma_link_tbl + offset, len, is_sec1); 11686a1e8d14SLEROY Christophe return sg_count; 1169246a87cdSLEROY Christophe } 1170e345177dSChristophe Leroy sg_count = sg_to_link_tbl_offset(src, sg_count, offset, len, elen, 11716a1e8d14SLEROY Christophe &edesc->link_tbl[tbl_off]); 1172e345177dSChristophe Leroy if (sg_count == 1 && !force) { 11736a1e8d14SLEROY Christophe /* Only one segment now, so no link tbl needed*/ 11746a1e8d14SLEROY Christophe copy_talitos_ptr(ptr, &edesc->link_tbl[tbl_off], is_sec1); 11756a1e8d14SLEROY Christophe return sg_count; 11766a1e8d14SLEROY Christophe } 1177246a87cdSLEROY Christophe to_talitos_ptr(ptr, edesc->dma_link_tbl + 1178da9de146SLEROY Christophe tbl_off * sizeof(struct talitos_ptr), len, is_sec1); 11796a1e8d14SLEROY Christophe to_talitos_ptr_ext_or(ptr, DESC_PTR_LNKTBL_JUMP, is_sec1); 11806a1e8d14SLEROY Christophe 11816a1e8d14SLEROY Christophe return sg_count; 1182246a87cdSLEROY Christophe } 1183246a87cdSLEROY Christophe 11842b122730SLEROY Christophe static int talitos_sg_map(struct device *dev, struct scatterlist *src, 11852b122730SLEROY Christophe unsigned int len, struct talitos_edesc *edesc, 11862b122730SLEROY Christophe struct talitos_ptr *ptr, int sg_count, 11872b122730SLEROY Christophe unsigned int offset, int tbl_off) 11882b122730SLEROY Christophe { 11892b122730SLEROY Christophe return talitos_sg_map_ext(dev, src, len, edesc, ptr, sg_count, offset, 1190e345177dSChristophe Leroy tbl_off, 0, false); 11912b122730SLEROY Christophe } 11922b122730SLEROY Christophe 11939c4a7965SKim Phillips /* 11949c4a7965SKim Phillips * fill in and submit ipsec_esp descriptor 11959c4a7965SKim Phillips */ 119656af8cd4SLee Nipper static int ipsec_esp(struct talitos_edesc *edesc, struct aead_request *areq, 11977ede4c36SChristophe Leroy bool encrypt, 1198aeb4c132SHerbert Xu void (*callback)(struct device *dev, 11999c4a7965SKim Phillips struct talitos_desc *desc, 12009c4a7965SKim Phillips void *context, int error)) 12019c4a7965SKim Phillips { 12029c4a7965SKim Phillips struct crypto_aead *aead = crypto_aead_reqtfm(areq); 1203aeb4c132SHerbert Xu unsigned int authsize = crypto_aead_authsize(aead); 12049c4a7965SKim Phillips struct talitos_ctx *ctx = crypto_aead_ctx(aead); 12059c4a7965SKim Phillips struct device *dev = ctx->dev; 12069c4a7965SKim Phillips struct talitos_desc *desc = &edesc->desc; 12077ede4c36SChristophe Leroy unsigned int cryptlen = areq->cryptlen - (encrypt ? 0 : authsize); 1208e41256f1SKim Phillips unsigned int ivsize = crypto_aead_ivsize(aead); 1209aeb4c132SHerbert Xu int tbl_off = 0; 1210fa86a267SKim Phillips int sg_count, ret; 12112b122730SLEROY Christophe int elen = 0; 1212549bd8bcSLEROY Christophe bool sync_needed = false; 1213549bd8bcSLEROY Christophe struct talitos_private *priv = dev_get_drvdata(dev); 1214549bd8bcSLEROY Christophe bool is_sec1 = has_ftr_sec1(priv); 12159a655608SLEROY Christophe bool is_ipsec_esp = desc->hdr & DESC_HDR_TYPE_IPSEC_ESP; 12169a655608SLEROY Christophe struct talitos_ptr *civ_ptr = &desc->ptr[is_ipsec_esp ? 2 : 3]; 12179a655608SLEROY Christophe struct talitos_ptr *ckey_ptr = &desc->ptr[is_ipsec_esp ? 3 : 2]; 1218e345177dSChristophe Leroy dma_addr_t dma_icv = edesc->dma_link_tbl + edesc->dma_len - authsize; 12199c4a7965SKim Phillips 12209c4a7965SKim Phillips /* hmac key */ 12212e13ce08SLEROY Christophe to_talitos_ptr(&desc->ptr[0], ctx->dma_key, ctx->authkeylen, is_sec1); 122279fd31d3SHoria Geanta 1223549bd8bcSLEROY Christophe sg_count = edesc->src_nents ?: 1; 1224549bd8bcSLEROY Christophe if (is_sec1 && sg_count > 1) 1225549bd8bcSLEROY Christophe sg_copy_to_buffer(areq->src, sg_count, edesc->buf, 1226549bd8bcSLEROY Christophe areq->assoclen + cryptlen); 1227549bd8bcSLEROY Christophe else 1228549bd8bcSLEROY Christophe sg_count = dma_map_sg(dev, areq->src, sg_count, 1229549bd8bcSLEROY Christophe (areq->src == areq->dst) ? 1230549bd8bcSLEROY Christophe DMA_BIDIRECTIONAL : DMA_TO_DEVICE); 1231549bd8bcSLEROY Christophe 12329c4a7965SKim Phillips /* hmac data */ 1233549bd8bcSLEROY Christophe ret = talitos_sg_map(dev, areq->src, areq->assoclen, edesc, 1234549bd8bcSLEROY Christophe &desc->ptr[1], sg_count, 0, tbl_off); 123579fd31d3SHoria Geanta 1236549bd8bcSLEROY Christophe if (ret > 1) { 1237340ff60aSHoria Geant? tbl_off += ret; 1238549bd8bcSLEROY Christophe sync_needed = true; 123979fd31d3SHoria Geanta } 124079fd31d3SHoria Geanta 12419c4a7965SKim Phillips /* cipher iv */ 12429a655608SLEROY Christophe to_talitos_ptr(civ_ptr, edesc->iv_dma, ivsize, is_sec1); 12439c4a7965SKim Phillips 12449c4a7965SKim Phillips /* cipher key */ 12452e13ce08SLEROY Christophe to_talitos_ptr(ckey_ptr, ctx->dma_key + ctx->authkeylen, 12462e13ce08SLEROY Christophe ctx->enckeylen, is_sec1); 12479c4a7965SKim Phillips 12489c4a7965SKim Phillips /* 12499c4a7965SKim Phillips * cipher in 12509c4a7965SKim Phillips * map and adjust cipher len to aead request cryptlen. 12519c4a7965SKim Phillips * extent is bytes of HMAC postpended to ciphertext, 12529c4a7965SKim Phillips * typically 12 for ipsec 12539c4a7965SKim Phillips */ 12542b122730SLEROY Christophe if (is_ipsec_esp && (desc->hdr & DESC_HDR_MODE1_MDEU_CICV)) 12552b122730SLEROY Christophe elen = authsize; 1256549bd8bcSLEROY Christophe 12572b122730SLEROY Christophe ret = talitos_sg_map_ext(dev, areq->src, cryptlen, edesc, &desc->ptr[4], 1258e345177dSChristophe Leroy sg_count, areq->assoclen, tbl_off, elen, 1259e345177dSChristophe Leroy false); 1260549bd8bcSLEROY Christophe 1261ec8c7d14SLEROY Christophe if (ret > 1) { 1262ec8c7d14SLEROY Christophe tbl_off += ret; 1263549bd8bcSLEROY Christophe sync_needed = true; 1264340ff60aSHoria Geant? } 12659c4a7965SKim Phillips 12669c4a7965SKim Phillips /* cipher out */ 1267549bd8bcSLEROY Christophe if (areq->src != areq->dst) { 1268549bd8bcSLEROY Christophe sg_count = edesc->dst_nents ? : 1; 1269549bd8bcSLEROY Christophe if (!is_sec1 || sg_count == 1) 1270549bd8bcSLEROY Christophe dma_map_sg(dev, areq->dst, sg_count, DMA_FROM_DEVICE); 1271549bd8bcSLEROY Christophe } 12729c4a7965SKim Phillips 1273e345177dSChristophe Leroy if (is_ipsec_esp && encrypt) 1274e345177dSChristophe Leroy elen = authsize; 1275e345177dSChristophe Leroy else 1276e345177dSChristophe Leroy elen = 0; 1277e345177dSChristophe Leroy ret = talitos_sg_map_ext(dev, areq->dst, cryptlen, edesc, &desc->ptr[5], 1278e345177dSChristophe Leroy sg_count, areq->assoclen, tbl_off, elen, 1279e345177dSChristophe Leroy is_ipsec_esp && !encrypt); 1280e04a61beSLEROY Christophe tbl_off += ret; 1281549bd8bcSLEROY Christophe 1282e345177dSChristophe Leroy if (!encrypt && is_ipsec_esp) { 128379fd31d3SHoria Geanta struct talitos_ptr *tbl_ptr = &edesc->link_tbl[tbl_off]; 1284fe5720e2SKim Phillips 1285f3c85bc1SLee Nipper /* Add an entry to the link table for ICV data */ 1286e04a61beSLEROY Christophe to_talitos_ptr_ext_set(tbl_ptr - 1, 0, is_sec1); 1287e345177dSChristophe Leroy to_talitos_ptr_ext_set(tbl_ptr, DESC_PTR_LNKTBL_RET, is_sec1); 12889c4a7965SKim Phillips 12899c4a7965SKim Phillips /* icv data follows link tables */ 1290e345177dSChristophe Leroy to_talitos_ptr(tbl_ptr, dma_icv, authsize, is_sec1); 1291e345177dSChristophe Leroy to_talitos_ptr_ext_or(&desc->ptr[5], authsize, is_sec1); 1292e04a61beSLEROY Christophe sync_needed = true; 1293e345177dSChristophe Leroy } else if (!encrypt) { 1294e345177dSChristophe Leroy to_talitos_ptr(&desc->ptr[6], dma_icv, authsize, is_sec1); 1295e345177dSChristophe Leroy sync_needed = true; 1296e345177dSChristophe Leroy } else if (!is_ipsec_esp) { 1297e345177dSChristophe Leroy talitos_sg_map(dev, areq->dst, authsize, edesc, &desc->ptr[6], 1298e345177dSChristophe Leroy sg_count, areq->assoclen + cryptlen, tbl_off); 1299340ff60aSHoria Geant? } 13009c4a7965SKim Phillips 13019c4a7965SKim Phillips /* iv out */ 13029a655608SLEROY Christophe if (is_ipsec_esp) 1303a2b35aa8SLEROY Christophe map_single_talitos_ptr(dev, &desc->ptr[6], ivsize, ctx->iv, 13049c4a7965SKim Phillips DMA_FROM_DEVICE); 13059c4a7965SKim Phillips 1306549bd8bcSLEROY Christophe if (sync_needed) 1307549bd8bcSLEROY Christophe dma_sync_single_for_device(dev, edesc->dma_link_tbl, 1308549bd8bcSLEROY Christophe edesc->dma_len, 1309549bd8bcSLEROY Christophe DMA_BIDIRECTIONAL); 1310549bd8bcSLEROY Christophe 13115228f0f7SKim Phillips ret = talitos_submit(dev, ctx->ch, desc, callback, areq); 1312fa86a267SKim Phillips if (ret != -EINPROGRESS) { 13137ede4c36SChristophe Leroy ipsec_esp_unmap(dev, edesc, areq, encrypt); 1314fa86a267SKim Phillips kfree(edesc); 1315fa86a267SKim Phillips } 1316fa86a267SKim Phillips return ret; 13179c4a7965SKim Phillips } 13189c4a7965SKim Phillips 13199c4a7965SKim Phillips /* 132056af8cd4SLee Nipper * allocate and map the extended descriptor 13219c4a7965SKim Phillips */ 13224de9d0b5SLee Nipper static struct talitos_edesc *talitos_edesc_alloc(struct device *dev, 13234de9d0b5SLee Nipper struct scatterlist *src, 13244de9d0b5SLee Nipper struct scatterlist *dst, 132579fd31d3SHoria Geanta u8 *iv, 132679fd31d3SHoria Geanta unsigned int assoclen, 13274de9d0b5SLee Nipper unsigned int cryptlen, 13284de9d0b5SLee Nipper unsigned int authsize, 132979fd31d3SHoria Geanta unsigned int ivsize, 13304de9d0b5SLee Nipper int icv_stashing, 133162293a37SHoria Geanta u32 cryptoflags, 133262293a37SHoria Geanta bool encrypt) 13339c4a7965SKim Phillips { 133456af8cd4SLee Nipper struct talitos_edesc *edesc; 13356a1e8d14SLEROY Christophe int src_nents, dst_nents, alloc_len, dma_len, src_len, dst_len; 133679fd31d3SHoria Geanta dma_addr_t iv_dma = 0; 13374de9d0b5SLee Nipper gfp_t flags = cryptoflags & CRYPTO_TFM_REQ_MAY_SLEEP ? GFP_KERNEL : 1338586725f8SKim Phillips GFP_ATOMIC; 13396f65f6acSLEROY Christophe struct talitos_private *priv = dev_get_drvdata(dev); 13406f65f6acSLEROY Christophe bool is_sec1 = has_ftr_sec1(priv); 13416f65f6acSLEROY Christophe int max_len = is_sec1 ? TALITOS1_MAX_DATA_LEN : TALITOS2_MAX_DATA_LEN; 13429c4a7965SKim Phillips 13436f65f6acSLEROY Christophe if (cryptlen + authsize > max_len) { 13444de9d0b5SLee Nipper dev_err(dev, "length exceeds h/w max limit\n"); 13459c4a7965SKim Phillips return ERR_PTR(-EINVAL); 13469c4a7965SKim Phillips } 13479c4a7965SKim Phillips 134862293a37SHoria Geanta if (!dst || dst == src) { 13496a1e8d14SLEROY Christophe src_len = assoclen + cryptlen + authsize; 13506a1e8d14SLEROY Christophe src_nents = sg_nents_for_len(src, src_len); 13518e409fe1SLABBE Corentin if (src_nents < 0) { 13528e409fe1SLABBE Corentin dev_err(dev, "Invalid number of src SG.\n"); 1353c56c2e17SChristophe Leroy return ERR_PTR(-EINVAL); 13548e409fe1SLABBE Corentin } 13559c4a7965SKim Phillips src_nents = (src_nents == 1) ? 0 : src_nents; 135662293a37SHoria Geanta dst_nents = dst ? src_nents : 0; 13576a1e8d14SLEROY Christophe dst_len = 0; 135862293a37SHoria Geanta } else { /* dst && dst != src*/ 13596a1e8d14SLEROY Christophe src_len = assoclen + cryptlen + (encrypt ? 0 : authsize); 13606a1e8d14SLEROY Christophe src_nents = sg_nents_for_len(src, src_len); 13618e409fe1SLABBE Corentin if (src_nents < 0) { 13628e409fe1SLABBE Corentin dev_err(dev, "Invalid number of src SG.\n"); 1363c56c2e17SChristophe Leroy return ERR_PTR(-EINVAL); 13648e409fe1SLABBE Corentin } 136562293a37SHoria Geanta src_nents = (src_nents == 1) ? 0 : src_nents; 13666a1e8d14SLEROY Christophe dst_len = assoclen + cryptlen + (encrypt ? authsize : 0); 13676a1e8d14SLEROY Christophe dst_nents = sg_nents_for_len(dst, dst_len); 13688e409fe1SLABBE Corentin if (dst_nents < 0) { 13698e409fe1SLABBE Corentin dev_err(dev, "Invalid number of dst SG.\n"); 1370c56c2e17SChristophe Leroy return ERR_PTR(-EINVAL); 13718e409fe1SLABBE Corentin } 1372695ad589SLee Nipper dst_nents = (dst_nents == 1) ? 0 : dst_nents; 13739c4a7965SKim Phillips } 13749c4a7965SKim Phillips 13759c4a7965SKim Phillips /* 13769c4a7965SKim Phillips * allocate space for base edesc plus the link tables, 1377aeb4c132SHerbert Xu * allowing for two separate entries for AD and generated ICV (+ 2), 1378aeb4c132SHerbert Xu * and space for two sets of ICVs (stashed and generated) 13799c4a7965SKim Phillips */ 138056af8cd4SLee Nipper alloc_len = sizeof(struct talitos_edesc); 1381e345177dSChristophe Leroy if (src_nents || dst_nents || !encrypt) { 13826f65f6acSLEROY Christophe if (is_sec1) 13836a1e8d14SLEROY Christophe dma_len = (src_nents ? src_len : 0) + 1384e345177dSChristophe Leroy (dst_nents ? dst_len : 0) + authsize; 13856f65f6acSLEROY Christophe else 1386aeb4c132SHerbert Xu dma_len = (src_nents + dst_nents + 2) * 1387e345177dSChristophe Leroy sizeof(struct talitos_ptr) + authsize; 13889c4a7965SKim Phillips alloc_len += dma_len; 13899c4a7965SKim Phillips } else { 13909c4a7965SKim Phillips dma_len = 0; 13919c4a7965SKim Phillips } 1392e345177dSChristophe Leroy alloc_len += icv_stashing ? authsize : 0; 13939c4a7965SKim Phillips 139437b5e889SLEROY Christophe /* if its a ahash, add space for a second desc next to the first one */ 139537b5e889SLEROY Christophe if (is_sec1 && !dst) 139637b5e889SLEROY Christophe alloc_len += sizeof(struct talitos_desc); 13971bea445bSChristophe Leroy alloc_len += ivsize; 139837b5e889SLEROY Christophe 1399586725f8SKim Phillips edesc = kmalloc(alloc_len, GFP_DMA | flags); 1400c56c2e17SChristophe Leroy if (!edesc) 1401c56c2e17SChristophe Leroy return ERR_PTR(-ENOMEM); 14021bea445bSChristophe Leroy if (ivsize) { 14031bea445bSChristophe Leroy iv = memcpy(((u8 *)edesc) + alloc_len - ivsize, iv, ivsize); 1404c56c2e17SChristophe Leroy iv_dma = dma_map_single(dev, iv, ivsize, DMA_TO_DEVICE); 14051bea445bSChristophe Leroy } 1406e4a647c4SLEROY Christophe memset(&edesc->desc, 0, sizeof(edesc->desc)); 14079c4a7965SKim Phillips 14089c4a7965SKim Phillips edesc->src_nents = src_nents; 14099c4a7965SKim Phillips edesc->dst_nents = dst_nents; 141079fd31d3SHoria Geanta edesc->iv_dma = iv_dma; 14119c4a7965SKim Phillips edesc->dma_len = dma_len; 141258cdbc6dSChristophe Leroy if (dma_len) 141358cdbc6dSChristophe Leroy edesc->dma_link_tbl = dma_map_single(dev, &edesc->link_tbl[0], 1414497f2e6bSLee Nipper edesc->dma_len, 1415497f2e6bSLee Nipper DMA_BIDIRECTIONAL); 141658cdbc6dSChristophe Leroy 14179c4a7965SKim Phillips return edesc; 14189c4a7965SKim Phillips } 14199c4a7965SKim Phillips 142079fd31d3SHoria Geanta static struct talitos_edesc *aead_edesc_alloc(struct aead_request *areq, u8 *iv, 142162293a37SHoria Geanta int icv_stashing, bool encrypt) 14224de9d0b5SLee Nipper { 14234de9d0b5SLee Nipper struct crypto_aead *authenc = crypto_aead_reqtfm(areq); 1424aeb4c132SHerbert Xu unsigned int authsize = crypto_aead_authsize(authenc); 14254de9d0b5SLee Nipper struct talitos_ctx *ctx = crypto_aead_ctx(authenc); 142679fd31d3SHoria Geanta unsigned int ivsize = crypto_aead_ivsize(authenc); 14277ede4c36SChristophe Leroy unsigned int cryptlen = areq->cryptlen - (encrypt ? 0 : authsize); 14284de9d0b5SLee Nipper 1429aeb4c132SHerbert Xu return talitos_edesc_alloc(ctx->dev, areq->src, areq->dst, 14307ede4c36SChristophe Leroy iv, areq->assoclen, cryptlen, 1431aeb4c132SHerbert Xu authsize, ivsize, icv_stashing, 143262293a37SHoria Geanta areq->base.flags, encrypt); 14334de9d0b5SLee Nipper } 14344de9d0b5SLee Nipper 143556af8cd4SLee Nipper static int aead_encrypt(struct aead_request *req) 14369c4a7965SKim Phillips { 14379c4a7965SKim Phillips struct crypto_aead *authenc = crypto_aead_reqtfm(req); 14389c4a7965SKim Phillips struct talitos_ctx *ctx = crypto_aead_ctx(authenc); 143956af8cd4SLee Nipper struct talitos_edesc *edesc; 14409c4a7965SKim Phillips 14419c4a7965SKim Phillips /* allocate extended descriptor */ 144262293a37SHoria Geanta edesc = aead_edesc_alloc(req, req->iv, 0, true); 14439c4a7965SKim Phillips if (IS_ERR(edesc)) 14449c4a7965SKim Phillips return PTR_ERR(edesc); 14459c4a7965SKim Phillips 14469c4a7965SKim Phillips /* set encrypt */ 144770bcaca7SLee Nipper edesc->desc.hdr = ctx->desc_hdr_template | DESC_HDR_MODE0_ENCRYPT; 14489c4a7965SKim Phillips 14497ede4c36SChristophe Leroy return ipsec_esp(edesc, req, true, ipsec_esp_encrypt_done); 14509c4a7965SKim Phillips } 14519c4a7965SKim Phillips 145256af8cd4SLee Nipper static int aead_decrypt(struct aead_request *req) 14539c4a7965SKim Phillips { 14549c4a7965SKim Phillips struct crypto_aead *authenc = crypto_aead_reqtfm(req); 1455aeb4c132SHerbert Xu unsigned int authsize = crypto_aead_authsize(authenc); 14569c4a7965SKim Phillips struct talitos_ctx *ctx = crypto_aead_ctx(authenc); 1457fe5720e2SKim Phillips struct talitos_private *priv = dev_get_drvdata(ctx->dev); 145856af8cd4SLee Nipper struct talitos_edesc *edesc; 14599c4a7965SKim Phillips void *icvdata; 14609c4a7965SKim Phillips 14619c4a7965SKim Phillips /* allocate extended descriptor */ 146262293a37SHoria Geanta edesc = aead_edesc_alloc(req, req->iv, 1, false); 14639c4a7965SKim Phillips if (IS_ERR(edesc)) 14649c4a7965SKim Phillips return PTR_ERR(edesc); 14659c4a7965SKim Phillips 14664bbfb839SChristophe Leroy if ((edesc->desc.hdr & DESC_HDR_TYPE_IPSEC_ESP) && 14674bbfb839SChristophe Leroy (priv->features & TALITOS_FTR_HW_AUTH_CHECK) && 1468e938e465SKim Phillips ((!edesc->src_nents && !edesc->dst_nents) || 1469e938e465SKim Phillips priv->features & TALITOS_FTR_SRC_LINK_TBL_LEN_INCLUDES_EXTENT)) { 1470fe5720e2SKim Phillips 1471fe5720e2SKim Phillips /* decrypt and check the ICV */ 1472e938e465SKim Phillips edesc->desc.hdr = ctx->desc_hdr_template | 1473e938e465SKim Phillips DESC_HDR_DIR_INBOUND | 1474fe5720e2SKim Phillips DESC_HDR_MODE1_MDEU_CICV; 1475fe5720e2SKim Phillips 1476fe5720e2SKim Phillips /* reset integrity check result bits */ 1477fe5720e2SKim Phillips 14787ede4c36SChristophe Leroy return ipsec_esp(edesc, req, false, 14797ede4c36SChristophe Leroy ipsec_esp_decrypt_hwauth_done); 1480e938e465SKim Phillips } 1481fe5720e2SKim Phillips 1482fe5720e2SKim Phillips /* Have to check the ICV with software */ 1483fe5720e2SKim Phillips edesc->desc.hdr = ctx->desc_hdr_template | DESC_HDR_DIR_INBOUND; 1484fe5720e2SKim Phillips 14859c4a7965SKim Phillips /* stash incoming ICV for later cmp with ICV generated by the h/w */ 1486e345177dSChristophe Leroy icvdata = edesc->buf + edesc->dma_len; 14879c4a7965SKim Phillips 1488eae55a58SChristophe Leroy sg_pcopy_to_buffer(req->src, edesc->src_nents ? : 1, icvdata, authsize, 1489eae55a58SChristophe Leroy req->assoclen + req->cryptlen - authsize); 14909c4a7965SKim Phillips 14917ede4c36SChristophe Leroy return ipsec_esp(edesc, req, false, ipsec_esp_decrypt_swauth_done); 14929c4a7965SKim Phillips } 14939c4a7965SKim Phillips 14944de9d0b5SLee Nipper static int ablkcipher_setkey(struct crypto_ablkcipher *cipher, 14954de9d0b5SLee Nipper const u8 *key, unsigned int keylen) 14964de9d0b5SLee Nipper { 14974de9d0b5SLee Nipper struct talitos_ctx *ctx = crypto_ablkcipher_ctx(cipher); 14982e13ce08SLEROY Christophe struct device *dev = ctx->dev; 1499f384cdc4SLEROY Christophe 15002e13ce08SLEROY Christophe if (ctx->keylen) 15012e13ce08SLEROY Christophe dma_unmap_single(dev, ctx->dma_key, ctx->keylen, DMA_TO_DEVICE); 15022e13ce08SLEROY Christophe 15034de9d0b5SLee Nipper memcpy(&ctx->key, key, keylen); 15044de9d0b5SLee Nipper ctx->keylen = keylen; 15054de9d0b5SLee Nipper 15062e13ce08SLEROY Christophe ctx->dma_key = dma_map_single(dev, ctx->key, keylen, DMA_TO_DEVICE); 15072e13ce08SLEROY Christophe 15084de9d0b5SLee Nipper return 0; 15094de9d0b5SLee Nipper } 15104de9d0b5SLee Nipper 1511ef7c5c85SHerbert Xu static int ablkcipher_des_setkey(struct crypto_ablkcipher *cipher, 1512ef7c5c85SHerbert Xu const u8 *key, unsigned int keylen) 1513ef7c5c85SHerbert Xu { 1514*9d574ae8SArd Biesheuvel return verify_ablkcipher_des_key(cipher, key) ?: 1515*9d574ae8SArd Biesheuvel ablkcipher_setkey(cipher, key, keylen); 1516ef7c5c85SHerbert Xu } 1517ef7c5c85SHerbert Xu 1518ef7c5c85SHerbert Xu static int ablkcipher_des3_setkey(struct crypto_ablkcipher *cipher, 1519ef7c5c85SHerbert Xu const u8 *key, unsigned int keylen) 1520ef7c5c85SHerbert Xu { 1521*9d574ae8SArd Biesheuvel return verify_ablkcipher_des3_key(cipher, key) ?: 1522*9d574ae8SArd Biesheuvel ablkcipher_setkey(cipher, key, keylen); 1523ef7c5c85SHerbert Xu } 1524ef7c5c85SHerbert Xu 15251ba34e71SChristophe Leroy static int ablkcipher_aes_setkey(struct crypto_ablkcipher *cipher, 15261ba34e71SChristophe Leroy const u8 *key, unsigned int keylen) 15271ba34e71SChristophe Leroy { 15281ba34e71SChristophe Leroy if (keylen == AES_KEYSIZE_128 || keylen == AES_KEYSIZE_192 || 15291ba34e71SChristophe Leroy keylen == AES_KEYSIZE_256) 15301ba34e71SChristophe Leroy return ablkcipher_setkey(cipher, key, keylen); 15311ba34e71SChristophe Leroy 15321ba34e71SChristophe Leroy crypto_ablkcipher_set_flags(cipher, CRYPTO_TFM_RES_BAD_KEY_LEN); 15331ba34e71SChristophe Leroy 15341ba34e71SChristophe Leroy return -EINVAL; 15351ba34e71SChristophe Leroy } 15361ba34e71SChristophe Leroy 15374de9d0b5SLee Nipper static void common_nonsnoop_unmap(struct device *dev, 15384de9d0b5SLee Nipper struct talitos_edesc *edesc, 15394de9d0b5SLee Nipper struct ablkcipher_request *areq) 15404de9d0b5SLee Nipper { 15414de9d0b5SLee Nipper unmap_single_talitos_ptr(dev, &edesc->desc.ptr[5], DMA_FROM_DEVICE); 1542032d197eSLEROY Christophe 15436a1e8d14SLEROY Christophe talitos_sg_unmap(dev, edesc, areq->src, areq->dst, areq->nbytes, 0); 15444de9d0b5SLee Nipper unmap_single_talitos_ptr(dev, &edesc->desc.ptr[1], DMA_TO_DEVICE); 15454de9d0b5SLee Nipper 15464de9d0b5SLee Nipper if (edesc->dma_len) 15474de9d0b5SLee Nipper dma_unmap_single(dev, edesc->dma_link_tbl, edesc->dma_len, 15484de9d0b5SLee Nipper DMA_BIDIRECTIONAL); 15494de9d0b5SLee Nipper } 15504de9d0b5SLee Nipper 15514de9d0b5SLee Nipper static void ablkcipher_done(struct device *dev, 15524de9d0b5SLee Nipper struct talitos_desc *desc, void *context, 15534de9d0b5SLee Nipper int err) 15544de9d0b5SLee Nipper { 15554de9d0b5SLee Nipper struct ablkcipher_request *areq = context; 15563e03e792SChristophe Leroy struct crypto_ablkcipher *cipher = crypto_ablkcipher_reqtfm(areq); 15573e03e792SChristophe Leroy struct talitos_ctx *ctx = crypto_ablkcipher_ctx(cipher); 15583e03e792SChristophe Leroy unsigned int ivsize = crypto_ablkcipher_ivsize(cipher); 155919bbbc63SKim Phillips struct talitos_edesc *edesc; 156019bbbc63SKim Phillips 156119bbbc63SKim Phillips edesc = container_of(desc, struct talitos_edesc, desc); 15624de9d0b5SLee Nipper 15634de9d0b5SLee Nipper common_nonsnoop_unmap(dev, edesc, areq); 15643e03e792SChristophe Leroy memcpy(areq->info, ctx->iv, ivsize); 15654de9d0b5SLee Nipper 15664de9d0b5SLee Nipper kfree(edesc); 15674de9d0b5SLee Nipper 15684de9d0b5SLee Nipper areq->base.complete(&areq->base, err); 15694de9d0b5SLee Nipper } 15704de9d0b5SLee Nipper 15714de9d0b5SLee Nipper static int common_nonsnoop(struct talitos_edesc *edesc, 15724de9d0b5SLee Nipper struct ablkcipher_request *areq, 15734de9d0b5SLee Nipper void (*callback) (struct device *dev, 15744de9d0b5SLee Nipper struct talitos_desc *desc, 15754de9d0b5SLee Nipper void *context, int error)) 15764de9d0b5SLee Nipper { 15774de9d0b5SLee Nipper struct crypto_ablkcipher *cipher = crypto_ablkcipher_reqtfm(areq); 15784de9d0b5SLee Nipper struct talitos_ctx *ctx = crypto_ablkcipher_ctx(cipher); 15794de9d0b5SLee Nipper struct device *dev = ctx->dev; 15804de9d0b5SLee Nipper struct talitos_desc *desc = &edesc->desc; 15814de9d0b5SLee Nipper unsigned int cryptlen = areq->nbytes; 158279fd31d3SHoria Geanta unsigned int ivsize = crypto_ablkcipher_ivsize(cipher); 15834de9d0b5SLee Nipper int sg_count, ret; 15846a1e8d14SLEROY Christophe bool sync_needed = false; 1585922f9dc8SLEROY Christophe struct talitos_private *priv = dev_get_drvdata(dev); 1586922f9dc8SLEROY Christophe bool is_sec1 = has_ftr_sec1(priv); 15874de9d0b5SLee Nipper 15884de9d0b5SLee Nipper /* first DWORD empty */ 15894de9d0b5SLee Nipper 15904de9d0b5SLee Nipper /* cipher iv */ 1591da9de146SLEROY Christophe to_talitos_ptr(&desc->ptr[1], edesc->iv_dma, ivsize, is_sec1); 15924de9d0b5SLee Nipper 15934de9d0b5SLee Nipper /* cipher key */ 15942e13ce08SLEROY Christophe to_talitos_ptr(&desc->ptr[2], ctx->dma_key, ctx->keylen, is_sec1); 15954de9d0b5SLee Nipper 15966a1e8d14SLEROY Christophe sg_count = edesc->src_nents ?: 1; 15976a1e8d14SLEROY Christophe if (is_sec1 && sg_count > 1) 15986a1e8d14SLEROY Christophe sg_copy_to_buffer(areq->src, sg_count, edesc->buf, 15996a1e8d14SLEROY Christophe cryptlen); 16006a1e8d14SLEROY Christophe else 16016a1e8d14SLEROY Christophe sg_count = dma_map_sg(dev, areq->src, sg_count, 16026a1e8d14SLEROY Christophe (areq->src == areq->dst) ? 16036a1e8d14SLEROY Christophe DMA_BIDIRECTIONAL : DMA_TO_DEVICE); 16044de9d0b5SLee Nipper /* 16054de9d0b5SLee Nipper * cipher in 16064de9d0b5SLee Nipper */ 16076a1e8d14SLEROY Christophe sg_count = talitos_sg_map(dev, areq->src, cryptlen, edesc, 16086a1e8d14SLEROY Christophe &desc->ptr[3], sg_count, 0, 0); 16096a1e8d14SLEROY Christophe if (sg_count > 1) 16106a1e8d14SLEROY Christophe sync_needed = true; 16114de9d0b5SLee Nipper 16124de9d0b5SLee Nipper /* cipher out */ 16136a1e8d14SLEROY Christophe if (areq->src != areq->dst) { 16146a1e8d14SLEROY Christophe sg_count = edesc->dst_nents ? : 1; 16156a1e8d14SLEROY Christophe if (!is_sec1 || sg_count == 1) 16166a1e8d14SLEROY Christophe dma_map_sg(dev, areq->dst, sg_count, DMA_FROM_DEVICE); 16176a1e8d14SLEROY Christophe } 16186a1e8d14SLEROY Christophe 16196a1e8d14SLEROY Christophe ret = talitos_sg_map(dev, areq->dst, cryptlen, edesc, &desc->ptr[4], 16206a1e8d14SLEROY Christophe sg_count, 0, (edesc->src_nents + 1)); 16216a1e8d14SLEROY Christophe if (ret > 1) 16226a1e8d14SLEROY Christophe sync_needed = true; 16234de9d0b5SLee Nipper 16244de9d0b5SLee Nipper /* iv out */ 1625a2b35aa8SLEROY Christophe map_single_talitos_ptr(dev, &desc->ptr[5], ivsize, ctx->iv, 16264de9d0b5SLee Nipper DMA_FROM_DEVICE); 16274de9d0b5SLee Nipper 16284de9d0b5SLee Nipper /* last DWORD empty */ 16294de9d0b5SLee Nipper 16306a1e8d14SLEROY Christophe if (sync_needed) 16316a1e8d14SLEROY Christophe dma_sync_single_for_device(dev, edesc->dma_link_tbl, 16326a1e8d14SLEROY Christophe edesc->dma_len, DMA_BIDIRECTIONAL); 16336a1e8d14SLEROY Christophe 16345228f0f7SKim Phillips ret = talitos_submit(dev, ctx->ch, desc, callback, areq); 16354de9d0b5SLee Nipper if (ret != -EINPROGRESS) { 16364de9d0b5SLee Nipper common_nonsnoop_unmap(dev, edesc, areq); 16374de9d0b5SLee Nipper kfree(edesc); 16384de9d0b5SLee Nipper } 16394de9d0b5SLee Nipper return ret; 16404de9d0b5SLee Nipper } 16414de9d0b5SLee Nipper 1642e938e465SKim Phillips static struct talitos_edesc *ablkcipher_edesc_alloc(struct ablkcipher_request * 164362293a37SHoria Geanta areq, bool encrypt) 16444de9d0b5SLee Nipper { 16454de9d0b5SLee Nipper struct crypto_ablkcipher *cipher = crypto_ablkcipher_reqtfm(areq); 16464de9d0b5SLee Nipper struct talitos_ctx *ctx = crypto_ablkcipher_ctx(cipher); 164779fd31d3SHoria Geanta unsigned int ivsize = crypto_ablkcipher_ivsize(cipher); 16484de9d0b5SLee Nipper 1649aeb4c132SHerbert Xu return talitos_edesc_alloc(ctx->dev, areq->src, areq->dst, 165079fd31d3SHoria Geanta areq->info, 0, areq->nbytes, 0, ivsize, 0, 165162293a37SHoria Geanta areq->base.flags, encrypt); 16524de9d0b5SLee Nipper } 16534de9d0b5SLee Nipper 16544de9d0b5SLee Nipper static int ablkcipher_encrypt(struct ablkcipher_request *areq) 16554de9d0b5SLee Nipper { 16564de9d0b5SLee Nipper struct crypto_ablkcipher *cipher = crypto_ablkcipher_reqtfm(areq); 16574de9d0b5SLee Nipper struct talitos_ctx *ctx = crypto_ablkcipher_ctx(cipher); 16584de9d0b5SLee Nipper struct talitos_edesc *edesc; 1659ee483d32SChristophe Leroy unsigned int blocksize = 1660ee483d32SChristophe Leroy crypto_tfm_alg_blocksize(crypto_ablkcipher_tfm(cipher)); 1661ee483d32SChristophe Leroy 1662ee483d32SChristophe Leroy if (!areq->nbytes) 1663ee483d32SChristophe Leroy return 0; 1664ee483d32SChristophe Leroy 1665ee483d32SChristophe Leroy if (areq->nbytes % blocksize) 1666ee483d32SChristophe Leroy return -EINVAL; 16674de9d0b5SLee Nipper 16684de9d0b5SLee Nipper /* allocate extended descriptor */ 166962293a37SHoria Geanta edesc = ablkcipher_edesc_alloc(areq, true); 16704de9d0b5SLee Nipper if (IS_ERR(edesc)) 16714de9d0b5SLee Nipper return PTR_ERR(edesc); 16724de9d0b5SLee Nipper 16734de9d0b5SLee Nipper /* set encrypt */ 16744de9d0b5SLee Nipper edesc->desc.hdr = ctx->desc_hdr_template | DESC_HDR_MODE0_ENCRYPT; 16754de9d0b5SLee Nipper 1676febec542SKim Phillips return common_nonsnoop(edesc, areq, ablkcipher_done); 16774de9d0b5SLee Nipper } 16784de9d0b5SLee Nipper 16794de9d0b5SLee Nipper static int ablkcipher_decrypt(struct ablkcipher_request *areq) 16804de9d0b5SLee Nipper { 16814de9d0b5SLee Nipper struct crypto_ablkcipher *cipher = crypto_ablkcipher_reqtfm(areq); 16824de9d0b5SLee Nipper struct talitos_ctx *ctx = crypto_ablkcipher_ctx(cipher); 16834de9d0b5SLee Nipper struct talitos_edesc *edesc; 1684ee483d32SChristophe Leroy unsigned int blocksize = 1685ee483d32SChristophe Leroy crypto_tfm_alg_blocksize(crypto_ablkcipher_tfm(cipher)); 1686ee483d32SChristophe Leroy 1687ee483d32SChristophe Leroy if (!areq->nbytes) 1688ee483d32SChristophe Leroy return 0; 1689ee483d32SChristophe Leroy 1690ee483d32SChristophe Leroy if (areq->nbytes % blocksize) 1691ee483d32SChristophe Leroy return -EINVAL; 16924de9d0b5SLee Nipper 16934de9d0b5SLee Nipper /* allocate extended descriptor */ 169462293a37SHoria Geanta edesc = ablkcipher_edesc_alloc(areq, false); 16954de9d0b5SLee Nipper if (IS_ERR(edesc)) 16964de9d0b5SLee Nipper return PTR_ERR(edesc); 16974de9d0b5SLee Nipper 16984de9d0b5SLee Nipper edesc->desc.hdr = ctx->desc_hdr_template | DESC_HDR_DIR_INBOUND; 16994de9d0b5SLee Nipper 1700febec542SKim Phillips return common_nonsnoop(edesc, areq, ablkcipher_done); 17014de9d0b5SLee Nipper } 17024de9d0b5SLee Nipper 1703497f2e6bSLee Nipper static void common_nonsnoop_hash_unmap(struct device *dev, 1704497f2e6bSLee Nipper struct talitos_edesc *edesc, 1705497f2e6bSLee Nipper struct ahash_request *areq) 1706497f2e6bSLee Nipper { 1707497f2e6bSLee Nipper struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq); 1708ad4cd51fSLEROY Christophe struct talitos_private *priv = dev_get_drvdata(dev); 1709ad4cd51fSLEROY Christophe bool is_sec1 = has_ftr_sec1(priv); 1710ad4cd51fSLEROY Christophe struct talitos_desc *desc = &edesc->desc; 171158cdbc6dSChristophe Leroy struct talitos_desc *desc2 = (struct talitos_desc *) 171258cdbc6dSChristophe Leroy (edesc->buf + edesc->dma_len); 1713ad4cd51fSLEROY Christophe 1714ad4cd51fSLEROY Christophe unmap_single_talitos_ptr(dev, &edesc->desc.ptr[5], DMA_FROM_DEVICE); 1715ad4cd51fSLEROY Christophe if (desc->next_desc && 1716ad4cd51fSLEROY Christophe desc->ptr[5].ptr != desc2->ptr[5].ptr) 1717ad4cd51fSLEROY Christophe unmap_single_talitos_ptr(dev, &desc2->ptr[5], DMA_FROM_DEVICE); 1718497f2e6bSLee Nipper 171958cdbc6dSChristophe Leroy if (req_ctx->psrc) 17206a1e8d14SLEROY Christophe talitos_sg_unmap(dev, edesc, req_ctx->psrc, NULL, 0, 0); 1721032d197eSLEROY Christophe 1722ad4cd51fSLEROY Christophe /* When using hashctx-in, must unmap it. */ 1723ad4cd51fSLEROY Christophe if (from_talitos_ptr_len(&edesc->desc.ptr[1], is_sec1)) 1724ad4cd51fSLEROY Christophe unmap_single_talitos_ptr(dev, &edesc->desc.ptr[1], 1725ad4cd51fSLEROY Christophe DMA_TO_DEVICE); 1726ad4cd51fSLEROY Christophe else if (desc->next_desc) 1727ad4cd51fSLEROY Christophe unmap_single_talitos_ptr(dev, &desc2->ptr[1], 1728ad4cd51fSLEROY Christophe DMA_TO_DEVICE); 1729ad4cd51fSLEROY Christophe 1730ad4cd51fSLEROY Christophe if (is_sec1 && req_ctx->nbuf) 1731ad4cd51fSLEROY Christophe unmap_single_talitos_ptr(dev, &desc->ptr[3], 1732ad4cd51fSLEROY Christophe DMA_TO_DEVICE); 1733ad4cd51fSLEROY Christophe 1734497f2e6bSLee Nipper if (edesc->dma_len) 1735497f2e6bSLee Nipper dma_unmap_single(dev, edesc->dma_link_tbl, edesc->dma_len, 1736497f2e6bSLee Nipper DMA_BIDIRECTIONAL); 1737497f2e6bSLee Nipper 173837b5e889SLEROY Christophe if (edesc->desc.next_desc) 173937b5e889SLEROY Christophe dma_unmap_single(dev, be32_to_cpu(edesc->desc.next_desc), 174037b5e889SLEROY Christophe TALITOS_DESC_SIZE, DMA_BIDIRECTIONAL); 1741497f2e6bSLee Nipper } 1742497f2e6bSLee Nipper 1743497f2e6bSLee Nipper static void ahash_done(struct device *dev, 1744497f2e6bSLee Nipper struct talitos_desc *desc, void *context, 1745497f2e6bSLee Nipper int err) 1746497f2e6bSLee Nipper { 1747497f2e6bSLee Nipper struct ahash_request *areq = context; 1748497f2e6bSLee Nipper struct talitos_edesc *edesc = 1749497f2e6bSLee Nipper container_of(desc, struct talitos_edesc, desc); 1750497f2e6bSLee Nipper struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq); 1751497f2e6bSLee Nipper 1752497f2e6bSLee Nipper if (!req_ctx->last && req_ctx->to_hash_later) { 1753497f2e6bSLee Nipper /* Position any partial block for next update/final/finup */ 17543c0dd190SLEROY Christophe req_ctx->buf_idx = (req_ctx->buf_idx + 1) & 1; 17555e833bc4SLee Nipper req_ctx->nbuf = req_ctx->to_hash_later; 1756497f2e6bSLee Nipper } 1757497f2e6bSLee Nipper common_nonsnoop_hash_unmap(dev, edesc, areq); 1758497f2e6bSLee Nipper 1759497f2e6bSLee Nipper kfree(edesc); 1760497f2e6bSLee Nipper 1761497f2e6bSLee Nipper areq->base.complete(&areq->base, err); 1762497f2e6bSLee Nipper } 1763497f2e6bSLee Nipper 17642d02905eSLEROY Christophe /* 17652d02905eSLEROY Christophe * SEC1 doesn't like hashing of 0 sized message, so we do the padding 17662d02905eSLEROY Christophe * ourself and submit a padded block 17672d02905eSLEROY Christophe */ 17685b2cf268SLEROY Christophe static void talitos_handle_buggy_hash(struct talitos_ctx *ctx, 17692d02905eSLEROY Christophe struct talitos_edesc *edesc, 17702d02905eSLEROY Christophe struct talitos_ptr *ptr) 17712d02905eSLEROY Christophe { 17722d02905eSLEROY Christophe static u8 padded_hash[64] = { 17732d02905eSLEROY Christophe 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17742d02905eSLEROY Christophe 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17752d02905eSLEROY Christophe 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17762d02905eSLEROY Christophe 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17772d02905eSLEROY Christophe }; 17782d02905eSLEROY Christophe 17792d02905eSLEROY Christophe pr_err_once("Bug in SEC1, padding ourself\n"); 17802d02905eSLEROY Christophe edesc->desc.hdr &= ~DESC_HDR_MODE0_MDEU_PAD; 17812d02905eSLEROY Christophe map_single_talitos_ptr(ctx->dev, ptr, sizeof(padded_hash), 17822d02905eSLEROY Christophe (char *)padded_hash, DMA_TO_DEVICE); 17832d02905eSLEROY Christophe } 17842d02905eSLEROY Christophe 1785497f2e6bSLee Nipper static int common_nonsnoop_hash(struct talitos_edesc *edesc, 1786497f2e6bSLee Nipper struct ahash_request *areq, unsigned int length, 1787497f2e6bSLee Nipper void (*callback) (struct device *dev, 1788497f2e6bSLee Nipper struct talitos_desc *desc, 1789497f2e6bSLee Nipper void *context, int error)) 1790497f2e6bSLee Nipper { 1791497f2e6bSLee Nipper struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq); 1792497f2e6bSLee Nipper struct talitos_ctx *ctx = crypto_ahash_ctx(tfm); 1793497f2e6bSLee Nipper struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq); 1794497f2e6bSLee Nipper struct device *dev = ctx->dev; 1795497f2e6bSLee Nipper struct talitos_desc *desc = &edesc->desc; 1796032d197eSLEROY Christophe int ret; 17976a1e8d14SLEROY Christophe bool sync_needed = false; 1798922f9dc8SLEROY Christophe struct talitos_private *priv = dev_get_drvdata(dev); 1799922f9dc8SLEROY Christophe bool is_sec1 = has_ftr_sec1(priv); 18006a1e8d14SLEROY Christophe int sg_count; 1801497f2e6bSLee Nipper 1802497f2e6bSLee Nipper /* first DWORD empty */ 1803497f2e6bSLee Nipper 180460f208d7SKim Phillips /* hash context in */ 180560f208d7SKim Phillips if (!req_ctx->first || req_ctx->swinit) { 18066a4967c3SLEROY Christophe map_single_talitos_ptr_nosync(dev, &desc->ptr[1], 1807ad4cd51fSLEROY Christophe req_ctx->hw_context_size, 18086a4967c3SLEROY Christophe req_ctx->hw_context, 1809ad4cd51fSLEROY Christophe DMA_TO_DEVICE); 181060f208d7SKim Phillips req_ctx->swinit = 0; 1811afd62fa2SLEROY Christophe } 1812497f2e6bSLee Nipper /* Indicate next op is not the first. */ 1813497f2e6bSLee Nipper req_ctx->first = 0; 1814497f2e6bSLee Nipper 1815497f2e6bSLee Nipper /* HMAC key */ 1816497f2e6bSLee Nipper if (ctx->keylen) 18172e13ce08SLEROY Christophe to_talitos_ptr(&desc->ptr[2], ctx->dma_key, ctx->keylen, 18182e13ce08SLEROY Christophe is_sec1); 1819497f2e6bSLee Nipper 182037b5e889SLEROY Christophe if (is_sec1 && req_ctx->nbuf) 182137b5e889SLEROY Christophe length -= req_ctx->nbuf; 182237b5e889SLEROY Christophe 18236a1e8d14SLEROY Christophe sg_count = edesc->src_nents ?: 1; 18246a1e8d14SLEROY Christophe if (is_sec1 && sg_count > 1) 182558cdbc6dSChristophe Leroy sg_copy_to_buffer(req_ctx->psrc, sg_count, edesc->buf, length); 182637b5e889SLEROY Christophe else if (length) 18276a1e8d14SLEROY Christophe sg_count = dma_map_sg(dev, req_ctx->psrc, sg_count, 18286a1e8d14SLEROY Christophe DMA_TO_DEVICE); 1829497f2e6bSLee Nipper /* 1830497f2e6bSLee Nipper * data in 1831497f2e6bSLee Nipper */ 183237b5e889SLEROY Christophe if (is_sec1 && req_ctx->nbuf) { 1833ad4cd51fSLEROY Christophe map_single_talitos_ptr(dev, &desc->ptr[3], req_ctx->nbuf, 1834ad4cd51fSLEROY Christophe req_ctx->buf[req_ctx->buf_idx], 1835ad4cd51fSLEROY Christophe DMA_TO_DEVICE); 183637b5e889SLEROY Christophe } else { 18376a1e8d14SLEROY Christophe sg_count = talitos_sg_map(dev, req_ctx->psrc, length, edesc, 183858cdbc6dSChristophe Leroy &desc->ptr[3], sg_count, 0, 0); 18396a1e8d14SLEROY Christophe if (sg_count > 1) 18406a1e8d14SLEROY Christophe sync_needed = true; 184137b5e889SLEROY Christophe } 1842497f2e6bSLee Nipper 1843497f2e6bSLee Nipper /* fifth DWORD empty */ 1844497f2e6bSLee Nipper 1845497f2e6bSLee Nipper /* hash/HMAC out -or- hash context out */ 1846497f2e6bSLee Nipper if (req_ctx->last) 1847497f2e6bSLee Nipper map_single_talitos_ptr(dev, &desc->ptr[5], 1848497f2e6bSLee Nipper crypto_ahash_digestsize(tfm), 1849a2b35aa8SLEROY Christophe areq->result, DMA_FROM_DEVICE); 1850497f2e6bSLee Nipper else 18516a4967c3SLEROY Christophe map_single_talitos_ptr_nosync(dev, &desc->ptr[5], 1852ad4cd51fSLEROY Christophe req_ctx->hw_context_size, 18536a4967c3SLEROY Christophe req_ctx->hw_context, 18546a4967c3SLEROY Christophe DMA_FROM_DEVICE); 1855497f2e6bSLee Nipper 1856497f2e6bSLee Nipper /* last DWORD empty */ 1857497f2e6bSLee Nipper 18582d02905eSLEROY Christophe if (is_sec1 && from_talitos_ptr_len(&desc->ptr[3], true) == 0) 18592d02905eSLEROY Christophe talitos_handle_buggy_hash(ctx, edesc, &desc->ptr[3]); 18602d02905eSLEROY Christophe 186137b5e889SLEROY Christophe if (is_sec1 && req_ctx->nbuf && length) { 186258cdbc6dSChristophe Leroy struct talitos_desc *desc2 = (struct talitos_desc *) 186358cdbc6dSChristophe Leroy (edesc->buf + edesc->dma_len); 186437b5e889SLEROY Christophe dma_addr_t next_desc; 186537b5e889SLEROY Christophe 186637b5e889SLEROY Christophe memset(desc2, 0, sizeof(*desc2)); 186737b5e889SLEROY Christophe desc2->hdr = desc->hdr; 186837b5e889SLEROY Christophe desc2->hdr &= ~DESC_HDR_MODE0_MDEU_INIT; 186937b5e889SLEROY Christophe desc2->hdr1 = desc2->hdr; 187037b5e889SLEROY Christophe desc->hdr &= ~DESC_HDR_MODE0_MDEU_PAD; 187137b5e889SLEROY Christophe desc->hdr |= DESC_HDR_MODE0_MDEU_CONT; 187237b5e889SLEROY Christophe desc->hdr &= ~DESC_HDR_DONE_NOTIFY; 187337b5e889SLEROY Christophe 1874ad4cd51fSLEROY Christophe if (desc->ptr[1].ptr) 1875ad4cd51fSLEROY Christophe copy_talitos_ptr(&desc2->ptr[1], &desc->ptr[1], 1876ad4cd51fSLEROY Christophe is_sec1); 1877ad4cd51fSLEROY Christophe else 18786a4967c3SLEROY Christophe map_single_talitos_ptr_nosync(dev, &desc2->ptr[1], 1879ad4cd51fSLEROY Christophe req_ctx->hw_context_size, 1880ad4cd51fSLEROY Christophe req_ctx->hw_context, 1881ad4cd51fSLEROY Christophe DMA_TO_DEVICE); 188237b5e889SLEROY Christophe copy_talitos_ptr(&desc2->ptr[2], &desc->ptr[2], is_sec1); 188337b5e889SLEROY Christophe sg_count = talitos_sg_map(dev, req_ctx->psrc, length, edesc, 188458cdbc6dSChristophe Leroy &desc2->ptr[3], sg_count, 0, 0); 188537b5e889SLEROY Christophe if (sg_count > 1) 188637b5e889SLEROY Christophe sync_needed = true; 188737b5e889SLEROY Christophe copy_talitos_ptr(&desc2->ptr[5], &desc->ptr[5], is_sec1); 188837b5e889SLEROY Christophe if (req_ctx->last) 18896a4967c3SLEROY Christophe map_single_talitos_ptr_nosync(dev, &desc->ptr[5], 1890ad4cd51fSLEROY Christophe req_ctx->hw_context_size, 1891ad4cd51fSLEROY Christophe req_ctx->hw_context, 1892ad4cd51fSLEROY Christophe DMA_FROM_DEVICE); 189337b5e889SLEROY Christophe 189437b5e889SLEROY Christophe next_desc = dma_map_single(dev, &desc2->hdr1, TALITOS_DESC_SIZE, 189537b5e889SLEROY Christophe DMA_BIDIRECTIONAL); 189637b5e889SLEROY Christophe desc->next_desc = cpu_to_be32(next_desc); 189737b5e889SLEROY Christophe } 189837b5e889SLEROY Christophe 18996a1e8d14SLEROY Christophe if (sync_needed) 19006a1e8d14SLEROY Christophe dma_sync_single_for_device(dev, edesc->dma_link_tbl, 19016a1e8d14SLEROY Christophe edesc->dma_len, DMA_BIDIRECTIONAL); 19026a1e8d14SLEROY Christophe 19035228f0f7SKim Phillips ret = talitos_submit(dev, ctx->ch, desc, callback, areq); 1904497f2e6bSLee Nipper if (ret != -EINPROGRESS) { 1905497f2e6bSLee Nipper common_nonsnoop_hash_unmap(dev, edesc, areq); 1906497f2e6bSLee Nipper kfree(edesc); 1907497f2e6bSLee Nipper } 1908497f2e6bSLee Nipper return ret; 1909497f2e6bSLee Nipper } 1910497f2e6bSLee Nipper 1911497f2e6bSLee Nipper static struct talitos_edesc *ahash_edesc_alloc(struct ahash_request *areq, 1912497f2e6bSLee Nipper unsigned int nbytes) 1913497f2e6bSLee Nipper { 1914497f2e6bSLee Nipper struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq); 1915497f2e6bSLee Nipper struct talitos_ctx *ctx = crypto_ahash_ctx(tfm); 1916497f2e6bSLee Nipper struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq); 191737b5e889SLEROY Christophe struct talitos_private *priv = dev_get_drvdata(ctx->dev); 191837b5e889SLEROY Christophe bool is_sec1 = has_ftr_sec1(priv); 191937b5e889SLEROY Christophe 192037b5e889SLEROY Christophe if (is_sec1) 192137b5e889SLEROY Christophe nbytes -= req_ctx->nbuf; 1922497f2e6bSLee Nipper 1923aeb4c132SHerbert Xu return talitos_edesc_alloc(ctx->dev, req_ctx->psrc, NULL, NULL, 0, 192462293a37SHoria Geanta nbytes, 0, 0, 0, areq->base.flags, false); 1925497f2e6bSLee Nipper } 1926497f2e6bSLee Nipper 1927497f2e6bSLee Nipper static int ahash_init(struct ahash_request *areq) 1928497f2e6bSLee Nipper { 1929497f2e6bSLee Nipper struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq); 19306a4967c3SLEROY Christophe struct talitos_ctx *ctx = crypto_ahash_ctx(tfm); 19316a4967c3SLEROY Christophe struct device *dev = ctx->dev; 1932497f2e6bSLee Nipper struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq); 193349f9783bSLEROY Christophe unsigned int size; 19346a4967c3SLEROY Christophe dma_addr_t dma; 1935497f2e6bSLee Nipper 1936497f2e6bSLee Nipper /* Initialize the context */ 19373c0dd190SLEROY Christophe req_ctx->buf_idx = 0; 19385e833bc4SLee Nipper req_ctx->nbuf = 0; 193960f208d7SKim Phillips req_ctx->first = 1; /* first indicates h/w must init its context */ 194060f208d7SKim Phillips req_ctx->swinit = 0; /* assume h/w init of context */ 194149f9783bSLEROY Christophe size = (crypto_ahash_digestsize(tfm) <= SHA256_DIGEST_SIZE) 1942497f2e6bSLee Nipper ? TALITOS_MDEU_CONTEXT_SIZE_MD5_SHA1_SHA256 1943497f2e6bSLee Nipper : TALITOS_MDEU_CONTEXT_SIZE_SHA384_SHA512; 194449f9783bSLEROY Christophe req_ctx->hw_context_size = size; 1945497f2e6bSLee Nipper 19466a4967c3SLEROY Christophe dma = dma_map_single(dev, req_ctx->hw_context, req_ctx->hw_context_size, 19476a4967c3SLEROY Christophe DMA_TO_DEVICE); 19486a4967c3SLEROY Christophe dma_unmap_single(dev, dma, req_ctx->hw_context_size, DMA_TO_DEVICE); 19496a4967c3SLEROY Christophe 1950497f2e6bSLee Nipper return 0; 1951497f2e6bSLee Nipper } 1952497f2e6bSLee Nipper 195360f208d7SKim Phillips /* 195460f208d7SKim Phillips * on h/w without explicit sha224 support, we initialize h/w context 195560f208d7SKim Phillips * manually with sha224 constants, and tell it to run sha256. 195660f208d7SKim Phillips */ 195760f208d7SKim Phillips static int ahash_init_sha224_swinit(struct ahash_request *areq) 195860f208d7SKim Phillips { 195960f208d7SKim Phillips struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq); 196060f208d7SKim Phillips 1961a752447aSKim Phillips req_ctx->hw_context[0] = SHA224_H0; 1962a752447aSKim Phillips req_ctx->hw_context[1] = SHA224_H1; 1963a752447aSKim Phillips req_ctx->hw_context[2] = SHA224_H2; 1964a752447aSKim Phillips req_ctx->hw_context[3] = SHA224_H3; 1965a752447aSKim Phillips req_ctx->hw_context[4] = SHA224_H4; 1966a752447aSKim Phillips req_ctx->hw_context[5] = SHA224_H5; 1967a752447aSKim Phillips req_ctx->hw_context[6] = SHA224_H6; 1968a752447aSKim Phillips req_ctx->hw_context[7] = SHA224_H7; 196960f208d7SKim Phillips 197060f208d7SKim Phillips /* init 64-bit count */ 197160f208d7SKim Phillips req_ctx->hw_context[8] = 0; 197260f208d7SKim Phillips req_ctx->hw_context[9] = 0; 197360f208d7SKim Phillips 19746a4967c3SLEROY Christophe ahash_init(areq); 19756a4967c3SLEROY Christophe req_ctx->swinit = 1;/* prevent h/w initting context with sha256 values*/ 19766a4967c3SLEROY Christophe 197760f208d7SKim Phillips return 0; 197860f208d7SKim Phillips } 197960f208d7SKim Phillips 1980497f2e6bSLee Nipper static int ahash_process_req(struct ahash_request *areq, unsigned int nbytes) 1981497f2e6bSLee Nipper { 1982497f2e6bSLee Nipper struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq); 1983497f2e6bSLee Nipper struct talitos_ctx *ctx = crypto_ahash_ctx(tfm); 1984497f2e6bSLee Nipper struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq); 1985497f2e6bSLee Nipper struct talitos_edesc *edesc; 1986497f2e6bSLee Nipper unsigned int blocksize = 1987497f2e6bSLee Nipper crypto_tfm_alg_blocksize(crypto_ahash_tfm(tfm)); 1988497f2e6bSLee Nipper unsigned int nbytes_to_hash; 1989497f2e6bSLee Nipper unsigned int to_hash_later; 19905e833bc4SLee Nipper unsigned int nsg; 19918e409fe1SLABBE Corentin int nents; 199237b5e889SLEROY Christophe struct device *dev = ctx->dev; 199337b5e889SLEROY Christophe struct talitos_private *priv = dev_get_drvdata(dev); 199437b5e889SLEROY Christophe bool is_sec1 = has_ftr_sec1(priv); 19953c0dd190SLEROY Christophe u8 *ctx_buf = req_ctx->buf[req_ctx->buf_idx]; 1996497f2e6bSLee Nipper 19975e833bc4SLee Nipper if (!req_ctx->last && (nbytes + req_ctx->nbuf <= blocksize)) { 19985e833bc4SLee Nipper /* Buffer up to one whole block */ 19998e409fe1SLABBE Corentin nents = sg_nents_for_len(areq->src, nbytes); 20008e409fe1SLABBE Corentin if (nents < 0) { 20018e409fe1SLABBE Corentin dev_err(ctx->dev, "Invalid number of src SG.\n"); 20028e409fe1SLABBE Corentin return nents; 20038e409fe1SLABBE Corentin } 20048e409fe1SLABBE Corentin sg_copy_to_buffer(areq->src, nents, 20053c0dd190SLEROY Christophe ctx_buf + req_ctx->nbuf, nbytes); 20065e833bc4SLee Nipper req_ctx->nbuf += nbytes; 2007497f2e6bSLee Nipper return 0; 2008497f2e6bSLee Nipper } 2009497f2e6bSLee Nipper 20105e833bc4SLee Nipper /* At least (blocksize + 1) bytes are available to hash */ 20115e833bc4SLee Nipper nbytes_to_hash = nbytes + req_ctx->nbuf; 20125e833bc4SLee Nipper to_hash_later = nbytes_to_hash & (blocksize - 1); 20135e833bc4SLee Nipper 20145e833bc4SLee Nipper if (req_ctx->last) 20155e833bc4SLee Nipper to_hash_later = 0; 20165e833bc4SLee Nipper else if (to_hash_later) 20175e833bc4SLee Nipper /* There is a partial block. Hash the full block(s) now */ 20185e833bc4SLee Nipper nbytes_to_hash -= to_hash_later; 20195e833bc4SLee Nipper else { 20205e833bc4SLee Nipper /* Keep one block buffered */ 20215e833bc4SLee Nipper nbytes_to_hash -= blocksize; 20225e833bc4SLee Nipper to_hash_later = blocksize; 2023497f2e6bSLee Nipper } 20245e833bc4SLee Nipper 20255e833bc4SLee Nipper /* Chain in any previously buffered data */ 202637b5e889SLEROY Christophe if (!is_sec1 && req_ctx->nbuf) { 20275e833bc4SLee Nipper nsg = (req_ctx->nbuf < nbytes_to_hash) ? 2 : 1; 20285e833bc4SLee Nipper sg_init_table(req_ctx->bufsl, nsg); 20293c0dd190SLEROY Christophe sg_set_buf(req_ctx->bufsl, ctx_buf, req_ctx->nbuf); 20305e833bc4SLee Nipper if (nsg > 1) 2031c56f6d12SDan Williams sg_chain(req_ctx->bufsl, 2, areq->src); 20325e833bc4SLee Nipper req_ctx->psrc = req_ctx->bufsl; 203337b5e889SLEROY Christophe } else if (is_sec1 && req_ctx->nbuf && req_ctx->nbuf < blocksize) { 203458cdbc6dSChristophe Leroy int offset; 203558cdbc6dSChristophe Leroy 203637b5e889SLEROY Christophe if (nbytes_to_hash > blocksize) 203737b5e889SLEROY Christophe offset = blocksize - req_ctx->nbuf; 203837b5e889SLEROY Christophe else 203937b5e889SLEROY Christophe offset = nbytes_to_hash - req_ctx->nbuf; 204037b5e889SLEROY Christophe nents = sg_nents_for_len(areq->src, offset); 204137b5e889SLEROY Christophe if (nents < 0) { 204237b5e889SLEROY Christophe dev_err(ctx->dev, "Invalid number of src SG.\n"); 204337b5e889SLEROY Christophe return nents; 204437b5e889SLEROY Christophe } 204537b5e889SLEROY Christophe sg_copy_to_buffer(areq->src, nents, 20463c0dd190SLEROY Christophe ctx_buf + req_ctx->nbuf, offset); 204737b5e889SLEROY Christophe req_ctx->nbuf += offset; 204858cdbc6dSChristophe Leroy req_ctx->psrc = scatterwalk_ffwd(req_ctx->bufsl, areq->src, 204958cdbc6dSChristophe Leroy offset); 20505e833bc4SLee Nipper } else 20515e833bc4SLee Nipper req_ctx->psrc = areq->src; 20525e833bc4SLee Nipper 2053497f2e6bSLee Nipper if (to_hash_later) { 20548e409fe1SLABBE Corentin nents = sg_nents_for_len(areq->src, nbytes); 20558e409fe1SLABBE Corentin if (nents < 0) { 20568e409fe1SLABBE Corentin dev_err(ctx->dev, "Invalid number of src SG.\n"); 20578e409fe1SLABBE Corentin return nents; 20588e409fe1SLABBE Corentin } 2059d0525723SAkinobu Mita sg_pcopy_to_buffer(areq->src, nents, 20603c0dd190SLEROY Christophe req_ctx->buf[(req_ctx->buf_idx + 1) & 1], 2061497f2e6bSLee Nipper to_hash_later, 2062497f2e6bSLee Nipper nbytes - to_hash_later); 2063497f2e6bSLee Nipper } 2064497f2e6bSLee Nipper req_ctx->to_hash_later = to_hash_later; 2065497f2e6bSLee Nipper 20665e833bc4SLee Nipper /* Allocate extended descriptor */ 2067497f2e6bSLee Nipper edesc = ahash_edesc_alloc(areq, nbytes_to_hash); 2068497f2e6bSLee Nipper if (IS_ERR(edesc)) 2069497f2e6bSLee Nipper return PTR_ERR(edesc); 2070497f2e6bSLee Nipper 2071497f2e6bSLee Nipper edesc->desc.hdr = ctx->desc_hdr_template; 2072497f2e6bSLee Nipper 2073497f2e6bSLee Nipper /* On last one, request SEC to pad; otherwise continue */ 2074497f2e6bSLee Nipper if (req_ctx->last) 2075497f2e6bSLee Nipper edesc->desc.hdr |= DESC_HDR_MODE0_MDEU_PAD; 2076497f2e6bSLee Nipper else 2077497f2e6bSLee Nipper edesc->desc.hdr |= DESC_HDR_MODE0_MDEU_CONT; 2078497f2e6bSLee Nipper 207960f208d7SKim Phillips /* request SEC to INIT hash. */ 208060f208d7SKim Phillips if (req_ctx->first && !req_ctx->swinit) 2081497f2e6bSLee Nipper edesc->desc.hdr |= DESC_HDR_MODE0_MDEU_INIT; 2082497f2e6bSLee Nipper 2083497f2e6bSLee Nipper /* When the tfm context has a keylen, it's an HMAC. 2084497f2e6bSLee Nipper * A first or last (ie. not middle) descriptor must request HMAC. 2085497f2e6bSLee Nipper */ 2086497f2e6bSLee Nipper if (ctx->keylen && (req_ctx->first || req_ctx->last)) 2087497f2e6bSLee Nipper edesc->desc.hdr |= DESC_HDR_MODE0_MDEU_HMAC; 2088497f2e6bSLee Nipper 208958cdbc6dSChristophe Leroy return common_nonsnoop_hash(edesc, areq, nbytes_to_hash, ahash_done); 2090497f2e6bSLee Nipper } 2091497f2e6bSLee Nipper 2092497f2e6bSLee Nipper static int ahash_update(struct ahash_request *areq) 2093497f2e6bSLee Nipper { 2094497f2e6bSLee Nipper struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq); 2095497f2e6bSLee Nipper 2096497f2e6bSLee Nipper req_ctx->last = 0; 2097497f2e6bSLee Nipper 2098497f2e6bSLee Nipper return ahash_process_req(areq, areq->nbytes); 2099497f2e6bSLee Nipper } 2100497f2e6bSLee Nipper 2101497f2e6bSLee Nipper static int ahash_final(struct ahash_request *areq) 2102497f2e6bSLee Nipper { 2103497f2e6bSLee Nipper struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq); 2104497f2e6bSLee Nipper 2105497f2e6bSLee Nipper req_ctx->last = 1; 2106497f2e6bSLee Nipper 2107497f2e6bSLee Nipper return ahash_process_req(areq, 0); 2108497f2e6bSLee Nipper } 2109497f2e6bSLee Nipper 2110497f2e6bSLee Nipper static int ahash_finup(struct ahash_request *areq) 2111497f2e6bSLee Nipper { 2112497f2e6bSLee Nipper struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq); 2113497f2e6bSLee Nipper 2114497f2e6bSLee Nipper req_ctx->last = 1; 2115497f2e6bSLee Nipper 2116497f2e6bSLee Nipper return ahash_process_req(areq, areq->nbytes); 2117497f2e6bSLee Nipper } 2118497f2e6bSLee Nipper 2119497f2e6bSLee Nipper static int ahash_digest(struct ahash_request *areq) 2120497f2e6bSLee Nipper { 2121497f2e6bSLee Nipper struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq); 212260f208d7SKim Phillips struct crypto_ahash *ahash = crypto_ahash_reqtfm(areq); 2123497f2e6bSLee Nipper 212460f208d7SKim Phillips ahash->init(areq); 2125497f2e6bSLee Nipper req_ctx->last = 1; 2126497f2e6bSLee Nipper 2127497f2e6bSLee Nipper return ahash_process_req(areq, areq->nbytes); 2128497f2e6bSLee Nipper } 2129497f2e6bSLee Nipper 21303639ca84SHoria Geant? static int ahash_export(struct ahash_request *areq, void *out) 21313639ca84SHoria Geant? { 21323639ca84SHoria Geant? struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq); 21333639ca84SHoria Geant? struct talitos_export_state *export = out; 21346a4967c3SLEROY Christophe struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq); 21356a4967c3SLEROY Christophe struct talitos_ctx *ctx = crypto_ahash_ctx(tfm); 21366a4967c3SLEROY Christophe struct device *dev = ctx->dev; 21376a4967c3SLEROY Christophe dma_addr_t dma; 21386a4967c3SLEROY Christophe 21396a4967c3SLEROY Christophe dma = dma_map_single(dev, req_ctx->hw_context, req_ctx->hw_context_size, 21406a4967c3SLEROY Christophe DMA_FROM_DEVICE); 21416a4967c3SLEROY Christophe dma_unmap_single(dev, dma, req_ctx->hw_context_size, DMA_FROM_DEVICE); 21423639ca84SHoria Geant? 21433639ca84SHoria Geant? memcpy(export->hw_context, req_ctx->hw_context, 21443639ca84SHoria Geant? req_ctx->hw_context_size); 21453c0dd190SLEROY Christophe memcpy(export->buf, req_ctx->buf[req_ctx->buf_idx], req_ctx->nbuf); 21463639ca84SHoria Geant? export->swinit = req_ctx->swinit; 21473639ca84SHoria Geant? export->first = req_ctx->first; 21483639ca84SHoria Geant? export->last = req_ctx->last; 21493639ca84SHoria Geant? export->to_hash_later = req_ctx->to_hash_later; 21503639ca84SHoria Geant? export->nbuf = req_ctx->nbuf; 21513639ca84SHoria Geant? 21523639ca84SHoria Geant? return 0; 21533639ca84SHoria Geant? } 21543639ca84SHoria Geant? 21553639ca84SHoria Geant? static int ahash_import(struct ahash_request *areq, const void *in) 21563639ca84SHoria Geant? { 21573639ca84SHoria Geant? struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq); 21583639ca84SHoria Geant? struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq); 21596a4967c3SLEROY Christophe struct talitos_ctx *ctx = crypto_ahash_ctx(tfm); 21606a4967c3SLEROY Christophe struct device *dev = ctx->dev; 21613639ca84SHoria Geant? const struct talitos_export_state *export = in; 216249f9783bSLEROY Christophe unsigned int size; 21636a4967c3SLEROY Christophe dma_addr_t dma; 21643639ca84SHoria Geant? 21653639ca84SHoria Geant? memset(req_ctx, 0, sizeof(*req_ctx)); 216649f9783bSLEROY Christophe size = (crypto_ahash_digestsize(tfm) <= SHA256_DIGEST_SIZE) 21673639ca84SHoria Geant? ? TALITOS_MDEU_CONTEXT_SIZE_MD5_SHA1_SHA256 21683639ca84SHoria Geant? : TALITOS_MDEU_CONTEXT_SIZE_SHA384_SHA512; 216949f9783bSLEROY Christophe req_ctx->hw_context_size = size; 217049f9783bSLEROY Christophe memcpy(req_ctx->hw_context, export->hw_context, size); 21713c0dd190SLEROY Christophe memcpy(req_ctx->buf[0], export->buf, export->nbuf); 21723639ca84SHoria Geant? req_ctx->swinit = export->swinit; 21733639ca84SHoria Geant? req_ctx->first = export->first; 21743639ca84SHoria Geant? req_ctx->last = export->last; 21753639ca84SHoria Geant? req_ctx->to_hash_later = export->to_hash_later; 21763639ca84SHoria Geant? req_ctx->nbuf = export->nbuf; 21773639ca84SHoria Geant? 21786a4967c3SLEROY Christophe dma = dma_map_single(dev, req_ctx->hw_context, req_ctx->hw_context_size, 21796a4967c3SLEROY Christophe DMA_TO_DEVICE); 21806a4967c3SLEROY Christophe dma_unmap_single(dev, dma, req_ctx->hw_context_size, DMA_TO_DEVICE); 21816a4967c3SLEROY Christophe 21823639ca84SHoria Geant? return 0; 21833639ca84SHoria Geant? } 21843639ca84SHoria Geant? 218579b3a418SLee Nipper static int keyhash(struct crypto_ahash *tfm, const u8 *key, unsigned int keylen, 218679b3a418SLee Nipper u8 *hash) 218779b3a418SLee Nipper { 218879b3a418SLee Nipper struct talitos_ctx *ctx = crypto_tfm_ctx(crypto_ahash_tfm(tfm)); 218979b3a418SLee Nipper 219079b3a418SLee Nipper struct scatterlist sg[1]; 219179b3a418SLee Nipper struct ahash_request *req; 2192f1c90ac3SGilad Ben-Yossef struct crypto_wait wait; 219379b3a418SLee Nipper int ret; 219479b3a418SLee Nipper 2195f1c90ac3SGilad Ben-Yossef crypto_init_wait(&wait); 219679b3a418SLee Nipper 219779b3a418SLee Nipper req = ahash_request_alloc(tfm, GFP_KERNEL); 219879b3a418SLee Nipper if (!req) 219979b3a418SLee Nipper return -ENOMEM; 220079b3a418SLee Nipper 220179b3a418SLee Nipper /* Keep tfm keylen == 0 during hash of the long key */ 220279b3a418SLee Nipper ctx->keylen = 0; 220379b3a418SLee Nipper ahash_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG, 2204f1c90ac3SGilad Ben-Yossef crypto_req_done, &wait); 220579b3a418SLee Nipper 220679b3a418SLee Nipper sg_init_one(&sg[0], key, keylen); 220779b3a418SLee Nipper 220879b3a418SLee Nipper ahash_request_set_crypt(req, sg, hash, keylen); 2209f1c90ac3SGilad Ben-Yossef ret = crypto_wait_req(crypto_ahash_digest(req), &wait); 2210f1c90ac3SGilad Ben-Yossef 221179b3a418SLee Nipper ahash_request_free(req); 221279b3a418SLee Nipper 221379b3a418SLee Nipper return ret; 221479b3a418SLee Nipper } 221579b3a418SLee Nipper 221679b3a418SLee Nipper static int ahash_setkey(struct crypto_ahash *tfm, const u8 *key, 221779b3a418SLee Nipper unsigned int keylen) 221879b3a418SLee Nipper { 221979b3a418SLee Nipper struct talitos_ctx *ctx = crypto_tfm_ctx(crypto_ahash_tfm(tfm)); 22202e13ce08SLEROY Christophe struct device *dev = ctx->dev; 222179b3a418SLee Nipper unsigned int blocksize = 222279b3a418SLee Nipper crypto_tfm_alg_blocksize(crypto_ahash_tfm(tfm)); 222379b3a418SLee Nipper unsigned int digestsize = crypto_ahash_digestsize(tfm); 222479b3a418SLee Nipper unsigned int keysize = keylen; 222579b3a418SLee Nipper u8 hash[SHA512_DIGEST_SIZE]; 222679b3a418SLee Nipper int ret; 222779b3a418SLee Nipper 222879b3a418SLee Nipper if (keylen <= blocksize) 222979b3a418SLee Nipper memcpy(ctx->key, key, keysize); 223079b3a418SLee Nipper else { 223179b3a418SLee Nipper /* Must get the hash of the long key */ 223279b3a418SLee Nipper ret = keyhash(tfm, key, keylen, hash); 223379b3a418SLee Nipper 223479b3a418SLee Nipper if (ret) { 223579b3a418SLee Nipper crypto_ahash_set_flags(tfm, CRYPTO_TFM_RES_BAD_KEY_LEN); 223679b3a418SLee Nipper return -EINVAL; 223779b3a418SLee Nipper } 223879b3a418SLee Nipper 223979b3a418SLee Nipper keysize = digestsize; 224079b3a418SLee Nipper memcpy(ctx->key, hash, digestsize); 224179b3a418SLee Nipper } 224279b3a418SLee Nipper 22432e13ce08SLEROY Christophe if (ctx->keylen) 22442e13ce08SLEROY Christophe dma_unmap_single(dev, ctx->dma_key, ctx->keylen, DMA_TO_DEVICE); 22452e13ce08SLEROY Christophe 224679b3a418SLee Nipper ctx->keylen = keysize; 22472e13ce08SLEROY Christophe ctx->dma_key = dma_map_single(dev, ctx->key, keysize, DMA_TO_DEVICE); 224879b3a418SLee Nipper 224979b3a418SLee Nipper return 0; 225079b3a418SLee Nipper } 225179b3a418SLee Nipper 225279b3a418SLee Nipper 22539c4a7965SKim Phillips struct talitos_alg_template { 2254d5e4aaefSLee Nipper u32 type; 2255b0057763SLEROY Christophe u32 priority; 2256d5e4aaefSLee Nipper union { 2257d5e4aaefSLee Nipper struct crypto_alg crypto; 2258acbf7c62SLee Nipper struct ahash_alg hash; 2259aeb4c132SHerbert Xu struct aead_alg aead; 2260d5e4aaefSLee Nipper } alg; 22619c4a7965SKim Phillips __be32 desc_hdr_template; 22629c4a7965SKim Phillips }; 22639c4a7965SKim Phillips 22649c4a7965SKim Phillips static struct talitos_alg_template driver_algs[] = { 2265991155baSHoria Geanta /* AEAD algorithms. These use a single-pass ipsec_esp descriptor */ 2266d5e4aaefSLee Nipper { .type = CRYPTO_ALG_TYPE_AEAD, 2267aeb4c132SHerbert Xu .alg.aead = { 2268aeb4c132SHerbert Xu .base = { 226956af8cd4SLee Nipper .cra_name = "authenc(hmac(sha1),cbc(aes))", 2270aeb4c132SHerbert Xu .cra_driver_name = "authenc-hmac-sha1-" 2271aeb4c132SHerbert Xu "cbc-aes-talitos", 227256af8cd4SLee Nipper .cra_blocksize = AES_BLOCK_SIZE, 2273aeb4c132SHerbert Xu .cra_flags = CRYPTO_ALG_ASYNC, 2274aeb4c132SHerbert Xu }, 22753952f17eSLee Nipper .ivsize = AES_BLOCK_SIZE, 22763952f17eSLee Nipper .maxauthsize = SHA1_DIGEST_SIZE, 22779c4a7965SKim Phillips }, 22789c4a7965SKim Phillips .desc_hdr_template = DESC_HDR_TYPE_IPSEC_ESP | 22799c4a7965SKim Phillips DESC_HDR_SEL0_AESU | 22809c4a7965SKim Phillips DESC_HDR_MODE0_AESU_CBC | 22819c4a7965SKim Phillips DESC_HDR_SEL1_MDEUA | 22829c4a7965SKim Phillips DESC_HDR_MODE1_MDEU_INIT | 22839c4a7965SKim Phillips DESC_HDR_MODE1_MDEU_PAD | 22849c4a7965SKim Phillips DESC_HDR_MODE1_MDEU_SHA1_HMAC, 228570bcaca7SLee Nipper }, 2286d5e4aaefSLee Nipper { .type = CRYPTO_ALG_TYPE_AEAD, 22877405c8d7SLEROY Christophe .priority = TALITOS_CRA_PRIORITY_AEAD_HSNA, 22887405c8d7SLEROY Christophe .alg.aead = { 22897405c8d7SLEROY Christophe .base = { 22907405c8d7SLEROY Christophe .cra_name = "authenc(hmac(sha1),cbc(aes))", 22917405c8d7SLEROY Christophe .cra_driver_name = "authenc-hmac-sha1-" 2292a1a42f84SChristophe Leroy "cbc-aes-talitos-hsna", 22937405c8d7SLEROY Christophe .cra_blocksize = AES_BLOCK_SIZE, 22947405c8d7SLEROY Christophe .cra_flags = CRYPTO_ALG_ASYNC, 22957405c8d7SLEROY Christophe }, 22967405c8d7SLEROY Christophe .ivsize = AES_BLOCK_SIZE, 22977405c8d7SLEROY Christophe .maxauthsize = SHA1_DIGEST_SIZE, 22987405c8d7SLEROY Christophe }, 22997405c8d7SLEROY Christophe .desc_hdr_template = DESC_HDR_TYPE_HMAC_SNOOP_NO_AFEU | 23007405c8d7SLEROY Christophe DESC_HDR_SEL0_AESU | 23017405c8d7SLEROY Christophe DESC_HDR_MODE0_AESU_CBC | 23027405c8d7SLEROY Christophe DESC_HDR_SEL1_MDEUA | 23037405c8d7SLEROY Christophe DESC_HDR_MODE1_MDEU_INIT | 23047405c8d7SLEROY Christophe DESC_HDR_MODE1_MDEU_PAD | 23057405c8d7SLEROY Christophe DESC_HDR_MODE1_MDEU_SHA1_HMAC, 23067405c8d7SLEROY Christophe }, 23077405c8d7SLEROY Christophe { .type = CRYPTO_ALG_TYPE_AEAD, 2308aeb4c132SHerbert Xu .alg.aead = { 2309aeb4c132SHerbert Xu .base = { 2310aeb4c132SHerbert Xu .cra_name = "authenc(hmac(sha1)," 2311aeb4c132SHerbert Xu "cbc(des3_ede))", 2312aeb4c132SHerbert Xu .cra_driver_name = "authenc-hmac-sha1-" 2313aeb4c132SHerbert Xu "cbc-3des-talitos", 231456af8cd4SLee Nipper .cra_blocksize = DES3_EDE_BLOCK_SIZE, 2315aeb4c132SHerbert Xu .cra_flags = CRYPTO_ALG_ASYNC, 2316aeb4c132SHerbert Xu }, 23173952f17eSLee Nipper .ivsize = DES3_EDE_BLOCK_SIZE, 23183952f17eSLee Nipper .maxauthsize = SHA1_DIGEST_SIZE, 2319ef7c5c85SHerbert Xu .setkey = aead_des3_setkey, 232070bcaca7SLee Nipper }, 232170bcaca7SLee Nipper .desc_hdr_template = DESC_HDR_TYPE_IPSEC_ESP | 232270bcaca7SLee Nipper DESC_HDR_SEL0_DEU | 232370bcaca7SLee Nipper DESC_HDR_MODE0_DEU_CBC | 232470bcaca7SLee Nipper DESC_HDR_MODE0_DEU_3DES | 232570bcaca7SLee Nipper DESC_HDR_SEL1_MDEUA | 232670bcaca7SLee Nipper DESC_HDR_MODE1_MDEU_INIT | 232770bcaca7SLee Nipper DESC_HDR_MODE1_MDEU_PAD | 232870bcaca7SLee Nipper DESC_HDR_MODE1_MDEU_SHA1_HMAC, 23293952f17eSLee Nipper }, 2330d5e4aaefSLee Nipper { .type = CRYPTO_ALG_TYPE_AEAD, 23317405c8d7SLEROY Christophe .priority = TALITOS_CRA_PRIORITY_AEAD_HSNA, 23327405c8d7SLEROY Christophe .alg.aead = { 23337405c8d7SLEROY Christophe .base = { 23347405c8d7SLEROY Christophe .cra_name = "authenc(hmac(sha1)," 23357405c8d7SLEROY Christophe "cbc(des3_ede))", 23367405c8d7SLEROY Christophe .cra_driver_name = "authenc-hmac-sha1-" 2337a1a42f84SChristophe Leroy "cbc-3des-talitos-hsna", 23387405c8d7SLEROY Christophe .cra_blocksize = DES3_EDE_BLOCK_SIZE, 23397405c8d7SLEROY Christophe .cra_flags = CRYPTO_ALG_ASYNC, 23407405c8d7SLEROY Christophe }, 23417405c8d7SLEROY Christophe .ivsize = DES3_EDE_BLOCK_SIZE, 23427405c8d7SLEROY Christophe .maxauthsize = SHA1_DIGEST_SIZE, 2343ef7c5c85SHerbert Xu .setkey = aead_des3_setkey, 23447405c8d7SLEROY Christophe }, 23457405c8d7SLEROY Christophe .desc_hdr_template = DESC_HDR_TYPE_HMAC_SNOOP_NO_AFEU | 23467405c8d7SLEROY Christophe DESC_HDR_SEL0_DEU | 23477405c8d7SLEROY Christophe DESC_HDR_MODE0_DEU_CBC | 23487405c8d7SLEROY Christophe DESC_HDR_MODE0_DEU_3DES | 23497405c8d7SLEROY Christophe DESC_HDR_SEL1_MDEUA | 23507405c8d7SLEROY Christophe DESC_HDR_MODE1_MDEU_INIT | 23517405c8d7SLEROY Christophe DESC_HDR_MODE1_MDEU_PAD | 23527405c8d7SLEROY Christophe DESC_HDR_MODE1_MDEU_SHA1_HMAC, 23537405c8d7SLEROY Christophe }, 23547405c8d7SLEROY Christophe { .type = CRYPTO_ALG_TYPE_AEAD, 2355aeb4c132SHerbert Xu .alg.aead = { 2356aeb4c132SHerbert Xu .base = { 2357357fb605SHoria Geanta .cra_name = "authenc(hmac(sha224),cbc(aes))", 2358aeb4c132SHerbert Xu .cra_driver_name = "authenc-hmac-sha224-" 2359aeb4c132SHerbert Xu "cbc-aes-talitos", 2360357fb605SHoria Geanta .cra_blocksize = AES_BLOCK_SIZE, 2361aeb4c132SHerbert Xu .cra_flags = CRYPTO_ALG_ASYNC, 2362aeb4c132SHerbert Xu }, 2363357fb605SHoria Geanta .ivsize = AES_BLOCK_SIZE, 2364357fb605SHoria Geanta .maxauthsize = SHA224_DIGEST_SIZE, 2365357fb605SHoria Geanta }, 2366357fb605SHoria Geanta .desc_hdr_template = DESC_HDR_TYPE_IPSEC_ESP | 2367357fb605SHoria Geanta DESC_HDR_SEL0_AESU | 2368357fb605SHoria Geanta DESC_HDR_MODE0_AESU_CBC | 2369357fb605SHoria Geanta DESC_HDR_SEL1_MDEUA | 2370357fb605SHoria Geanta DESC_HDR_MODE1_MDEU_INIT | 2371357fb605SHoria Geanta DESC_HDR_MODE1_MDEU_PAD | 2372357fb605SHoria Geanta DESC_HDR_MODE1_MDEU_SHA224_HMAC, 2373357fb605SHoria Geanta }, 2374357fb605SHoria Geanta { .type = CRYPTO_ALG_TYPE_AEAD, 23757405c8d7SLEROY Christophe .priority = TALITOS_CRA_PRIORITY_AEAD_HSNA, 23767405c8d7SLEROY Christophe .alg.aead = { 23777405c8d7SLEROY Christophe .base = { 23787405c8d7SLEROY Christophe .cra_name = "authenc(hmac(sha224),cbc(aes))", 23797405c8d7SLEROY Christophe .cra_driver_name = "authenc-hmac-sha224-" 2380a1a42f84SChristophe Leroy "cbc-aes-talitos-hsna", 23817405c8d7SLEROY Christophe .cra_blocksize = AES_BLOCK_SIZE, 23827405c8d7SLEROY Christophe .cra_flags = CRYPTO_ALG_ASYNC, 23837405c8d7SLEROY Christophe }, 23847405c8d7SLEROY Christophe .ivsize = AES_BLOCK_SIZE, 23857405c8d7SLEROY Christophe .maxauthsize = SHA224_DIGEST_SIZE, 23867405c8d7SLEROY Christophe }, 23877405c8d7SLEROY Christophe .desc_hdr_template = DESC_HDR_TYPE_HMAC_SNOOP_NO_AFEU | 23887405c8d7SLEROY Christophe DESC_HDR_SEL0_AESU | 23897405c8d7SLEROY Christophe DESC_HDR_MODE0_AESU_CBC | 23907405c8d7SLEROY Christophe DESC_HDR_SEL1_MDEUA | 23917405c8d7SLEROY Christophe DESC_HDR_MODE1_MDEU_INIT | 23927405c8d7SLEROY Christophe DESC_HDR_MODE1_MDEU_PAD | 23937405c8d7SLEROY Christophe DESC_HDR_MODE1_MDEU_SHA224_HMAC, 23947405c8d7SLEROY Christophe }, 23957405c8d7SLEROY Christophe { .type = CRYPTO_ALG_TYPE_AEAD, 2396aeb4c132SHerbert Xu .alg.aead = { 2397aeb4c132SHerbert Xu .base = { 2398aeb4c132SHerbert Xu .cra_name = "authenc(hmac(sha224)," 2399aeb4c132SHerbert Xu "cbc(des3_ede))", 2400aeb4c132SHerbert Xu .cra_driver_name = "authenc-hmac-sha224-" 2401aeb4c132SHerbert Xu "cbc-3des-talitos", 2402357fb605SHoria Geanta .cra_blocksize = DES3_EDE_BLOCK_SIZE, 2403aeb4c132SHerbert Xu .cra_flags = CRYPTO_ALG_ASYNC, 2404aeb4c132SHerbert Xu }, 2405357fb605SHoria Geanta .ivsize = DES3_EDE_BLOCK_SIZE, 2406357fb605SHoria Geanta .maxauthsize = SHA224_DIGEST_SIZE, 2407ef7c5c85SHerbert Xu .setkey = aead_des3_setkey, 2408357fb605SHoria Geanta }, 2409357fb605SHoria Geanta .desc_hdr_template = DESC_HDR_TYPE_IPSEC_ESP | 2410357fb605SHoria Geanta DESC_HDR_SEL0_DEU | 2411357fb605SHoria Geanta DESC_HDR_MODE0_DEU_CBC | 2412357fb605SHoria Geanta DESC_HDR_MODE0_DEU_3DES | 2413357fb605SHoria Geanta DESC_HDR_SEL1_MDEUA | 2414357fb605SHoria Geanta DESC_HDR_MODE1_MDEU_INIT | 2415357fb605SHoria Geanta DESC_HDR_MODE1_MDEU_PAD | 2416357fb605SHoria Geanta DESC_HDR_MODE1_MDEU_SHA224_HMAC, 2417357fb605SHoria Geanta }, 2418357fb605SHoria Geanta { .type = CRYPTO_ALG_TYPE_AEAD, 24197405c8d7SLEROY Christophe .priority = TALITOS_CRA_PRIORITY_AEAD_HSNA, 24207405c8d7SLEROY Christophe .alg.aead = { 24217405c8d7SLEROY Christophe .base = { 24227405c8d7SLEROY Christophe .cra_name = "authenc(hmac(sha224)," 24237405c8d7SLEROY Christophe "cbc(des3_ede))", 24247405c8d7SLEROY Christophe .cra_driver_name = "authenc-hmac-sha224-" 2425a1a42f84SChristophe Leroy "cbc-3des-talitos-hsna", 24267405c8d7SLEROY Christophe .cra_blocksize = DES3_EDE_BLOCK_SIZE, 24277405c8d7SLEROY Christophe .cra_flags = CRYPTO_ALG_ASYNC, 24287405c8d7SLEROY Christophe }, 24297405c8d7SLEROY Christophe .ivsize = DES3_EDE_BLOCK_SIZE, 24307405c8d7SLEROY Christophe .maxauthsize = SHA224_DIGEST_SIZE, 2431ef7c5c85SHerbert Xu .setkey = aead_des3_setkey, 24327405c8d7SLEROY Christophe }, 24337405c8d7SLEROY Christophe .desc_hdr_template = DESC_HDR_TYPE_HMAC_SNOOP_NO_AFEU | 24347405c8d7SLEROY Christophe DESC_HDR_SEL0_DEU | 24357405c8d7SLEROY Christophe DESC_HDR_MODE0_DEU_CBC | 24367405c8d7SLEROY Christophe DESC_HDR_MODE0_DEU_3DES | 24377405c8d7SLEROY Christophe DESC_HDR_SEL1_MDEUA | 24387405c8d7SLEROY Christophe DESC_HDR_MODE1_MDEU_INIT | 24397405c8d7SLEROY Christophe DESC_HDR_MODE1_MDEU_PAD | 24407405c8d7SLEROY Christophe DESC_HDR_MODE1_MDEU_SHA224_HMAC, 24417405c8d7SLEROY Christophe }, 24427405c8d7SLEROY Christophe { .type = CRYPTO_ALG_TYPE_AEAD, 2443aeb4c132SHerbert Xu .alg.aead = { 2444aeb4c132SHerbert Xu .base = { 244556af8cd4SLee Nipper .cra_name = "authenc(hmac(sha256),cbc(aes))", 2446aeb4c132SHerbert Xu .cra_driver_name = "authenc-hmac-sha256-" 2447aeb4c132SHerbert Xu "cbc-aes-talitos", 244856af8cd4SLee Nipper .cra_blocksize = AES_BLOCK_SIZE, 2449aeb4c132SHerbert Xu .cra_flags = CRYPTO_ALG_ASYNC, 2450aeb4c132SHerbert Xu }, 24513952f17eSLee Nipper .ivsize = AES_BLOCK_SIZE, 24523952f17eSLee Nipper .maxauthsize = SHA256_DIGEST_SIZE, 24533952f17eSLee Nipper }, 24543952f17eSLee Nipper .desc_hdr_template = DESC_HDR_TYPE_IPSEC_ESP | 24553952f17eSLee Nipper DESC_HDR_SEL0_AESU | 24563952f17eSLee Nipper DESC_HDR_MODE0_AESU_CBC | 24573952f17eSLee Nipper DESC_HDR_SEL1_MDEUA | 24583952f17eSLee Nipper DESC_HDR_MODE1_MDEU_INIT | 24593952f17eSLee Nipper DESC_HDR_MODE1_MDEU_PAD | 24603952f17eSLee Nipper DESC_HDR_MODE1_MDEU_SHA256_HMAC, 24613952f17eSLee Nipper }, 2462d5e4aaefSLee Nipper { .type = CRYPTO_ALG_TYPE_AEAD, 24637405c8d7SLEROY Christophe .priority = TALITOS_CRA_PRIORITY_AEAD_HSNA, 24647405c8d7SLEROY Christophe .alg.aead = { 24657405c8d7SLEROY Christophe .base = { 24667405c8d7SLEROY Christophe .cra_name = "authenc(hmac(sha256),cbc(aes))", 24677405c8d7SLEROY Christophe .cra_driver_name = "authenc-hmac-sha256-" 2468a1a42f84SChristophe Leroy "cbc-aes-talitos-hsna", 24697405c8d7SLEROY Christophe .cra_blocksize = AES_BLOCK_SIZE, 24707405c8d7SLEROY Christophe .cra_flags = CRYPTO_ALG_ASYNC, 24717405c8d7SLEROY Christophe }, 24727405c8d7SLEROY Christophe .ivsize = AES_BLOCK_SIZE, 24737405c8d7SLEROY Christophe .maxauthsize = SHA256_DIGEST_SIZE, 24747405c8d7SLEROY Christophe }, 24757405c8d7SLEROY Christophe .desc_hdr_template = DESC_HDR_TYPE_HMAC_SNOOP_NO_AFEU | 24767405c8d7SLEROY Christophe DESC_HDR_SEL0_AESU | 24777405c8d7SLEROY Christophe DESC_HDR_MODE0_AESU_CBC | 24787405c8d7SLEROY Christophe DESC_HDR_SEL1_MDEUA | 24797405c8d7SLEROY Christophe DESC_HDR_MODE1_MDEU_INIT | 24807405c8d7SLEROY Christophe DESC_HDR_MODE1_MDEU_PAD | 24817405c8d7SLEROY Christophe DESC_HDR_MODE1_MDEU_SHA256_HMAC, 24827405c8d7SLEROY Christophe }, 24837405c8d7SLEROY Christophe { .type = CRYPTO_ALG_TYPE_AEAD, 2484aeb4c132SHerbert Xu .alg.aead = { 2485aeb4c132SHerbert Xu .base = { 2486aeb4c132SHerbert Xu .cra_name = "authenc(hmac(sha256)," 2487aeb4c132SHerbert Xu "cbc(des3_ede))", 2488aeb4c132SHerbert Xu .cra_driver_name = "authenc-hmac-sha256-" 2489aeb4c132SHerbert Xu "cbc-3des-talitos", 249056af8cd4SLee Nipper .cra_blocksize = DES3_EDE_BLOCK_SIZE, 2491aeb4c132SHerbert Xu .cra_flags = CRYPTO_ALG_ASYNC, 2492aeb4c132SHerbert Xu }, 24933952f17eSLee Nipper .ivsize = DES3_EDE_BLOCK_SIZE, 24943952f17eSLee Nipper .maxauthsize = SHA256_DIGEST_SIZE, 2495ef7c5c85SHerbert Xu .setkey = aead_des3_setkey, 24963952f17eSLee Nipper }, 24973952f17eSLee Nipper .desc_hdr_template = DESC_HDR_TYPE_IPSEC_ESP | 24983952f17eSLee Nipper DESC_HDR_SEL0_DEU | 24993952f17eSLee Nipper DESC_HDR_MODE0_DEU_CBC | 25003952f17eSLee Nipper DESC_HDR_MODE0_DEU_3DES | 25013952f17eSLee Nipper DESC_HDR_SEL1_MDEUA | 25023952f17eSLee Nipper DESC_HDR_MODE1_MDEU_INIT | 25033952f17eSLee Nipper DESC_HDR_MODE1_MDEU_PAD | 25043952f17eSLee Nipper DESC_HDR_MODE1_MDEU_SHA256_HMAC, 25053952f17eSLee Nipper }, 2506d5e4aaefSLee Nipper { .type = CRYPTO_ALG_TYPE_AEAD, 25077405c8d7SLEROY Christophe .priority = TALITOS_CRA_PRIORITY_AEAD_HSNA, 25087405c8d7SLEROY Christophe .alg.aead = { 25097405c8d7SLEROY Christophe .base = { 25107405c8d7SLEROY Christophe .cra_name = "authenc(hmac(sha256)," 25117405c8d7SLEROY Christophe "cbc(des3_ede))", 25127405c8d7SLEROY Christophe .cra_driver_name = "authenc-hmac-sha256-" 2513a1a42f84SChristophe Leroy "cbc-3des-talitos-hsna", 25147405c8d7SLEROY Christophe .cra_blocksize = DES3_EDE_BLOCK_SIZE, 25157405c8d7SLEROY Christophe .cra_flags = CRYPTO_ALG_ASYNC, 25167405c8d7SLEROY Christophe }, 25177405c8d7SLEROY Christophe .ivsize = DES3_EDE_BLOCK_SIZE, 25187405c8d7SLEROY Christophe .maxauthsize = SHA256_DIGEST_SIZE, 2519ef7c5c85SHerbert Xu .setkey = aead_des3_setkey, 25207405c8d7SLEROY Christophe }, 25217405c8d7SLEROY Christophe .desc_hdr_template = DESC_HDR_TYPE_HMAC_SNOOP_NO_AFEU | 25227405c8d7SLEROY Christophe DESC_HDR_SEL0_DEU | 25237405c8d7SLEROY Christophe DESC_HDR_MODE0_DEU_CBC | 25247405c8d7SLEROY Christophe DESC_HDR_MODE0_DEU_3DES | 25257405c8d7SLEROY Christophe DESC_HDR_SEL1_MDEUA | 25267405c8d7SLEROY Christophe DESC_HDR_MODE1_MDEU_INIT | 25277405c8d7SLEROY Christophe DESC_HDR_MODE1_MDEU_PAD | 25287405c8d7SLEROY Christophe DESC_HDR_MODE1_MDEU_SHA256_HMAC, 25297405c8d7SLEROY Christophe }, 25307405c8d7SLEROY Christophe { .type = CRYPTO_ALG_TYPE_AEAD, 2531aeb4c132SHerbert Xu .alg.aead = { 2532aeb4c132SHerbert Xu .base = { 2533357fb605SHoria Geanta .cra_name = "authenc(hmac(sha384),cbc(aes))", 2534aeb4c132SHerbert Xu .cra_driver_name = "authenc-hmac-sha384-" 2535aeb4c132SHerbert Xu "cbc-aes-talitos", 2536357fb605SHoria Geanta .cra_blocksize = AES_BLOCK_SIZE, 2537aeb4c132SHerbert Xu .cra_flags = CRYPTO_ALG_ASYNC, 2538aeb4c132SHerbert Xu }, 2539357fb605SHoria Geanta .ivsize = AES_BLOCK_SIZE, 2540357fb605SHoria Geanta .maxauthsize = SHA384_DIGEST_SIZE, 2541357fb605SHoria Geanta }, 2542357fb605SHoria Geanta .desc_hdr_template = DESC_HDR_TYPE_IPSEC_ESP | 2543357fb605SHoria Geanta DESC_HDR_SEL0_AESU | 2544357fb605SHoria Geanta DESC_HDR_MODE0_AESU_CBC | 2545357fb605SHoria Geanta DESC_HDR_SEL1_MDEUB | 2546357fb605SHoria Geanta DESC_HDR_MODE1_MDEU_INIT | 2547357fb605SHoria Geanta DESC_HDR_MODE1_MDEU_PAD | 2548357fb605SHoria Geanta DESC_HDR_MODE1_MDEUB_SHA384_HMAC, 2549357fb605SHoria Geanta }, 2550357fb605SHoria Geanta { .type = CRYPTO_ALG_TYPE_AEAD, 2551aeb4c132SHerbert Xu .alg.aead = { 2552aeb4c132SHerbert Xu .base = { 2553aeb4c132SHerbert Xu .cra_name = "authenc(hmac(sha384)," 2554aeb4c132SHerbert Xu "cbc(des3_ede))", 2555aeb4c132SHerbert Xu .cra_driver_name = "authenc-hmac-sha384-" 2556aeb4c132SHerbert Xu "cbc-3des-talitos", 2557357fb605SHoria Geanta .cra_blocksize = DES3_EDE_BLOCK_SIZE, 2558aeb4c132SHerbert Xu .cra_flags = CRYPTO_ALG_ASYNC, 2559aeb4c132SHerbert Xu }, 2560357fb605SHoria Geanta .ivsize = DES3_EDE_BLOCK_SIZE, 2561357fb605SHoria Geanta .maxauthsize = SHA384_DIGEST_SIZE, 2562ef7c5c85SHerbert Xu .setkey = aead_des3_setkey, 2563357fb605SHoria Geanta }, 2564357fb605SHoria Geanta .desc_hdr_template = DESC_HDR_TYPE_IPSEC_ESP | 2565357fb605SHoria Geanta DESC_HDR_SEL0_DEU | 2566357fb605SHoria Geanta DESC_HDR_MODE0_DEU_CBC | 2567357fb605SHoria Geanta DESC_HDR_MODE0_DEU_3DES | 2568357fb605SHoria Geanta DESC_HDR_SEL1_MDEUB | 2569357fb605SHoria Geanta DESC_HDR_MODE1_MDEU_INIT | 2570357fb605SHoria Geanta DESC_HDR_MODE1_MDEU_PAD | 2571357fb605SHoria Geanta DESC_HDR_MODE1_MDEUB_SHA384_HMAC, 2572357fb605SHoria Geanta }, 2573357fb605SHoria Geanta { .type = CRYPTO_ALG_TYPE_AEAD, 2574aeb4c132SHerbert Xu .alg.aead = { 2575aeb4c132SHerbert Xu .base = { 2576357fb605SHoria Geanta .cra_name = "authenc(hmac(sha512),cbc(aes))", 2577aeb4c132SHerbert Xu .cra_driver_name = "authenc-hmac-sha512-" 2578aeb4c132SHerbert Xu "cbc-aes-talitos", 2579357fb605SHoria Geanta .cra_blocksize = AES_BLOCK_SIZE, 2580aeb4c132SHerbert Xu .cra_flags = CRYPTO_ALG_ASYNC, 2581aeb4c132SHerbert Xu }, 2582357fb605SHoria Geanta .ivsize = AES_BLOCK_SIZE, 2583357fb605SHoria Geanta .maxauthsize = SHA512_DIGEST_SIZE, 2584357fb605SHoria Geanta }, 2585357fb605SHoria Geanta .desc_hdr_template = DESC_HDR_TYPE_IPSEC_ESP | 2586357fb605SHoria Geanta DESC_HDR_SEL0_AESU | 2587357fb605SHoria Geanta DESC_HDR_MODE0_AESU_CBC | 2588357fb605SHoria Geanta DESC_HDR_SEL1_MDEUB | 2589357fb605SHoria Geanta DESC_HDR_MODE1_MDEU_INIT | 2590357fb605SHoria Geanta DESC_HDR_MODE1_MDEU_PAD | 2591357fb605SHoria Geanta DESC_HDR_MODE1_MDEUB_SHA512_HMAC, 2592357fb605SHoria Geanta }, 2593357fb605SHoria Geanta { .type = CRYPTO_ALG_TYPE_AEAD, 2594aeb4c132SHerbert Xu .alg.aead = { 2595aeb4c132SHerbert Xu .base = { 2596aeb4c132SHerbert Xu .cra_name = "authenc(hmac(sha512)," 2597aeb4c132SHerbert Xu "cbc(des3_ede))", 2598aeb4c132SHerbert Xu .cra_driver_name = "authenc-hmac-sha512-" 2599aeb4c132SHerbert Xu "cbc-3des-talitos", 2600357fb605SHoria Geanta .cra_blocksize = DES3_EDE_BLOCK_SIZE, 2601aeb4c132SHerbert Xu .cra_flags = CRYPTO_ALG_ASYNC, 2602aeb4c132SHerbert Xu }, 2603357fb605SHoria Geanta .ivsize = DES3_EDE_BLOCK_SIZE, 2604357fb605SHoria Geanta .maxauthsize = SHA512_DIGEST_SIZE, 2605ef7c5c85SHerbert Xu .setkey = aead_des3_setkey, 2606357fb605SHoria Geanta }, 2607357fb605SHoria Geanta .desc_hdr_template = DESC_HDR_TYPE_IPSEC_ESP | 2608357fb605SHoria Geanta DESC_HDR_SEL0_DEU | 2609357fb605SHoria Geanta DESC_HDR_MODE0_DEU_CBC | 2610357fb605SHoria Geanta DESC_HDR_MODE0_DEU_3DES | 2611357fb605SHoria Geanta DESC_HDR_SEL1_MDEUB | 2612357fb605SHoria Geanta DESC_HDR_MODE1_MDEU_INIT | 2613357fb605SHoria Geanta DESC_HDR_MODE1_MDEU_PAD | 2614357fb605SHoria Geanta DESC_HDR_MODE1_MDEUB_SHA512_HMAC, 2615357fb605SHoria Geanta }, 2616357fb605SHoria Geanta { .type = CRYPTO_ALG_TYPE_AEAD, 2617aeb4c132SHerbert Xu .alg.aead = { 2618aeb4c132SHerbert Xu .base = { 261956af8cd4SLee Nipper .cra_name = "authenc(hmac(md5),cbc(aes))", 2620aeb4c132SHerbert Xu .cra_driver_name = "authenc-hmac-md5-" 2621aeb4c132SHerbert Xu "cbc-aes-talitos", 262256af8cd4SLee Nipper .cra_blocksize = AES_BLOCK_SIZE, 2623aeb4c132SHerbert Xu .cra_flags = CRYPTO_ALG_ASYNC, 2624aeb4c132SHerbert Xu }, 26253952f17eSLee Nipper .ivsize = AES_BLOCK_SIZE, 26263952f17eSLee Nipper .maxauthsize = MD5_DIGEST_SIZE, 26273952f17eSLee Nipper }, 26283952f17eSLee Nipper .desc_hdr_template = DESC_HDR_TYPE_IPSEC_ESP | 26293952f17eSLee Nipper DESC_HDR_SEL0_AESU | 26303952f17eSLee Nipper DESC_HDR_MODE0_AESU_CBC | 26313952f17eSLee Nipper DESC_HDR_SEL1_MDEUA | 26323952f17eSLee Nipper DESC_HDR_MODE1_MDEU_INIT | 26333952f17eSLee Nipper DESC_HDR_MODE1_MDEU_PAD | 26343952f17eSLee Nipper DESC_HDR_MODE1_MDEU_MD5_HMAC, 26353952f17eSLee Nipper }, 2636d5e4aaefSLee Nipper { .type = CRYPTO_ALG_TYPE_AEAD, 26377405c8d7SLEROY Christophe .priority = TALITOS_CRA_PRIORITY_AEAD_HSNA, 26387405c8d7SLEROY Christophe .alg.aead = { 26397405c8d7SLEROY Christophe .base = { 26407405c8d7SLEROY Christophe .cra_name = "authenc(hmac(md5),cbc(aes))", 26417405c8d7SLEROY Christophe .cra_driver_name = "authenc-hmac-md5-" 2642a1a42f84SChristophe Leroy "cbc-aes-talitos-hsna", 26437405c8d7SLEROY Christophe .cra_blocksize = AES_BLOCK_SIZE, 26447405c8d7SLEROY Christophe .cra_flags = CRYPTO_ALG_ASYNC, 26457405c8d7SLEROY Christophe }, 26467405c8d7SLEROY Christophe .ivsize = AES_BLOCK_SIZE, 26477405c8d7SLEROY Christophe .maxauthsize = MD5_DIGEST_SIZE, 26487405c8d7SLEROY Christophe }, 26497405c8d7SLEROY Christophe .desc_hdr_template = DESC_HDR_TYPE_HMAC_SNOOP_NO_AFEU | 26507405c8d7SLEROY Christophe DESC_HDR_SEL0_AESU | 26517405c8d7SLEROY Christophe DESC_HDR_MODE0_AESU_CBC | 26527405c8d7SLEROY Christophe DESC_HDR_SEL1_MDEUA | 26537405c8d7SLEROY Christophe DESC_HDR_MODE1_MDEU_INIT | 26547405c8d7SLEROY Christophe DESC_HDR_MODE1_MDEU_PAD | 26557405c8d7SLEROY Christophe DESC_HDR_MODE1_MDEU_MD5_HMAC, 26567405c8d7SLEROY Christophe }, 26577405c8d7SLEROY Christophe { .type = CRYPTO_ALG_TYPE_AEAD, 2658aeb4c132SHerbert Xu .alg.aead = { 2659aeb4c132SHerbert Xu .base = { 266056af8cd4SLee Nipper .cra_name = "authenc(hmac(md5),cbc(des3_ede))", 2661aeb4c132SHerbert Xu .cra_driver_name = "authenc-hmac-md5-" 2662aeb4c132SHerbert Xu "cbc-3des-talitos", 266356af8cd4SLee Nipper .cra_blocksize = DES3_EDE_BLOCK_SIZE, 2664aeb4c132SHerbert Xu .cra_flags = CRYPTO_ALG_ASYNC, 2665aeb4c132SHerbert Xu }, 26663952f17eSLee Nipper .ivsize = DES3_EDE_BLOCK_SIZE, 26673952f17eSLee Nipper .maxauthsize = MD5_DIGEST_SIZE, 2668ef7c5c85SHerbert Xu .setkey = aead_des3_setkey, 26693952f17eSLee Nipper }, 26703952f17eSLee Nipper .desc_hdr_template = DESC_HDR_TYPE_IPSEC_ESP | 26713952f17eSLee Nipper DESC_HDR_SEL0_DEU | 26723952f17eSLee Nipper DESC_HDR_MODE0_DEU_CBC | 26733952f17eSLee Nipper DESC_HDR_MODE0_DEU_3DES | 26743952f17eSLee Nipper DESC_HDR_SEL1_MDEUA | 26753952f17eSLee Nipper DESC_HDR_MODE1_MDEU_INIT | 26763952f17eSLee Nipper DESC_HDR_MODE1_MDEU_PAD | 26773952f17eSLee Nipper DESC_HDR_MODE1_MDEU_MD5_HMAC, 26784de9d0b5SLee Nipper }, 26797405c8d7SLEROY Christophe { .type = CRYPTO_ALG_TYPE_AEAD, 26807405c8d7SLEROY Christophe .priority = TALITOS_CRA_PRIORITY_AEAD_HSNA, 26817405c8d7SLEROY Christophe .alg.aead = { 26827405c8d7SLEROY Christophe .base = { 26837405c8d7SLEROY Christophe .cra_name = "authenc(hmac(md5),cbc(des3_ede))", 26847405c8d7SLEROY Christophe .cra_driver_name = "authenc-hmac-md5-" 2685a1a42f84SChristophe Leroy "cbc-3des-talitos-hsna", 26867405c8d7SLEROY Christophe .cra_blocksize = DES3_EDE_BLOCK_SIZE, 26877405c8d7SLEROY Christophe .cra_flags = CRYPTO_ALG_ASYNC, 26887405c8d7SLEROY Christophe }, 26897405c8d7SLEROY Christophe .ivsize = DES3_EDE_BLOCK_SIZE, 26907405c8d7SLEROY Christophe .maxauthsize = MD5_DIGEST_SIZE, 2691ef7c5c85SHerbert Xu .setkey = aead_des3_setkey, 26927405c8d7SLEROY Christophe }, 26937405c8d7SLEROY Christophe .desc_hdr_template = DESC_HDR_TYPE_HMAC_SNOOP_NO_AFEU | 26947405c8d7SLEROY Christophe DESC_HDR_SEL0_DEU | 26957405c8d7SLEROY Christophe DESC_HDR_MODE0_DEU_CBC | 26967405c8d7SLEROY Christophe DESC_HDR_MODE0_DEU_3DES | 26977405c8d7SLEROY Christophe DESC_HDR_SEL1_MDEUA | 26987405c8d7SLEROY Christophe DESC_HDR_MODE1_MDEU_INIT | 26997405c8d7SLEROY Christophe DESC_HDR_MODE1_MDEU_PAD | 27007405c8d7SLEROY Christophe DESC_HDR_MODE1_MDEU_MD5_HMAC, 27017405c8d7SLEROY Christophe }, 27024de9d0b5SLee Nipper /* ABLKCIPHER algorithms. */ 2703d5e4aaefSLee Nipper { .type = CRYPTO_ALG_TYPE_ABLKCIPHER, 2704d5e4aaefSLee Nipper .alg.crypto = { 27055e75ae1bSLEROY Christophe .cra_name = "ecb(aes)", 27065e75ae1bSLEROY Christophe .cra_driver_name = "ecb-aes-talitos", 27075e75ae1bSLEROY Christophe .cra_blocksize = AES_BLOCK_SIZE, 27085e75ae1bSLEROY Christophe .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | 27095e75ae1bSLEROY Christophe CRYPTO_ALG_ASYNC, 27105e75ae1bSLEROY Christophe .cra_ablkcipher = { 27115e75ae1bSLEROY Christophe .min_keysize = AES_MIN_KEY_SIZE, 27125e75ae1bSLEROY Christophe .max_keysize = AES_MAX_KEY_SIZE, 27131ba34e71SChristophe Leroy .setkey = ablkcipher_aes_setkey, 27145e75ae1bSLEROY Christophe } 27155e75ae1bSLEROY Christophe }, 27165e75ae1bSLEROY Christophe .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU | 27175e75ae1bSLEROY Christophe DESC_HDR_SEL0_AESU, 27185e75ae1bSLEROY Christophe }, 27195e75ae1bSLEROY Christophe { .type = CRYPTO_ALG_TYPE_ABLKCIPHER, 27205e75ae1bSLEROY Christophe .alg.crypto = { 27214de9d0b5SLee Nipper .cra_name = "cbc(aes)", 27224de9d0b5SLee Nipper .cra_driver_name = "cbc-aes-talitos", 27234de9d0b5SLee Nipper .cra_blocksize = AES_BLOCK_SIZE, 27244de9d0b5SLee Nipper .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | 27254de9d0b5SLee Nipper CRYPTO_ALG_ASYNC, 27264de9d0b5SLee Nipper .cra_ablkcipher = { 27274de9d0b5SLee Nipper .min_keysize = AES_MIN_KEY_SIZE, 27284de9d0b5SLee Nipper .max_keysize = AES_MAX_KEY_SIZE, 27294de9d0b5SLee Nipper .ivsize = AES_BLOCK_SIZE, 27301ba34e71SChristophe Leroy .setkey = ablkcipher_aes_setkey, 27314de9d0b5SLee Nipper } 27324de9d0b5SLee Nipper }, 27334de9d0b5SLee Nipper .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU | 27344de9d0b5SLee Nipper DESC_HDR_SEL0_AESU | 27354de9d0b5SLee Nipper DESC_HDR_MODE0_AESU_CBC, 27364de9d0b5SLee Nipper }, 2737d5e4aaefSLee Nipper { .type = CRYPTO_ALG_TYPE_ABLKCIPHER, 2738d5e4aaefSLee Nipper .alg.crypto = { 27395e75ae1bSLEROY Christophe .cra_name = "ctr(aes)", 27405e75ae1bSLEROY Christophe .cra_driver_name = "ctr-aes-talitos", 2741b9a05b60SChristophe Leroy .cra_blocksize = 1, 27425e75ae1bSLEROY Christophe .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | 27435e75ae1bSLEROY Christophe CRYPTO_ALG_ASYNC, 27445e75ae1bSLEROY Christophe .cra_ablkcipher = { 27455e75ae1bSLEROY Christophe .min_keysize = AES_MIN_KEY_SIZE, 27465e75ae1bSLEROY Christophe .max_keysize = AES_MAX_KEY_SIZE, 27475e75ae1bSLEROY Christophe .ivsize = AES_BLOCK_SIZE, 27481ba34e71SChristophe Leroy .setkey = ablkcipher_aes_setkey, 27495e75ae1bSLEROY Christophe } 27505e75ae1bSLEROY Christophe }, 275170d355ccSLEROY Christophe .desc_hdr_template = DESC_HDR_TYPE_AESU_CTR_NONSNOOP | 27525e75ae1bSLEROY Christophe DESC_HDR_SEL0_AESU | 27535e75ae1bSLEROY Christophe DESC_HDR_MODE0_AESU_CTR, 27545e75ae1bSLEROY Christophe }, 27555e75ae1bSLEROY Christophe { .type = CRYPTO_ALG_TYPE_ABLKCIPHER, 27565e75ae1bSLEROY Christophe .alg.crypto = { 27575e75ae1bSLEROY Christophe .cra_name = "ecb(des)", 27585e75ae1bSLEROY Christophe .cra_driver_name = "ecb-des-talitos", 27595e75ae1bSLEROY Christophe .cra_blocksize = DES_BLOCK_SIZE, 27605e75ae1bSLEROY Christophe .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | 27615e75ae1bSLEROY Christophe CRYPTO_ALG_ASYNC, 27625e75ae1bSLEROY Christophe .cra_ablkcipher = { 27635e75ae1bSLEROY Christophe .min_keysize = DES_KEY_SIZE, 27645e75ae1bSLEROY Christophe .max_keysize = DES_KEY_SIZE, 2765ef7c5c85SHerbert Xu .setkey = ablkcipher_des_setkey, 27665e75ae1bSLEROY Christophe } 27675e75ae1bSLEROY Christophe }, 27685e75ae1bSLEROY Christophe .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU | 27695e75ae1bSLEROY Christophe DESC_HDR_SEL0_DEU, 27705e75ae1bSLEROY Christophe }, 27715e75ae1bSLEROY Christophe { .type = CRYPTO_ALG_TYPE_ABLKCIPHER, 27725e75ae1bSLEROY Christophe .alg.crypto = { 27735e75ae1bSLEROY Christophe .cra_name = "cbc(des)", 27745e75ae1bSLEROY Christophe .cra_driver_name = "cbc-des-talitos", 27755e75ae1bSLEROY Christophe .cra_blocksize = DES_BLOCK_SIZE, 27765e75ae1bSLEROY Christophe .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | 27775e75ae1bSLEROY Christophe CRYPTO_ALG_ASYNC, 27785e75ae1bSLEROY Christophe .cra_ablkcipher = { 27795e75ae1bSLEROY Christophe .min_keysize = DES_KEY_SIZE, 27805e75ae1bSLEROY Christophe .max_keysize = DES_KEY_SIZE, 27815e75ae1bSLEROY Christophe .ivsize = DES_BLOCK_SIZE, 2782ef7c5c85SHerbert Xu .setkey = ablkcipher_des_setkey, 27835e75ae1bSLEROY Christophe } 27845e75ae1bSLEROY Christophe }, 27855e75ae1bSLEROY Christophe .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU | 27865e75ae1bSLEROY Christophe DESC_HDR_SEL0_DEU | 27875e75ae1bSLEROY Christophe DESC_HDR_MODE0_DEU_CBC, 27885e75ae1bSLEROY Christophe }, 27895e75ae1bSLEROY Christophe { .type = CRYPTO_ALG_TYPE_ABLKCIPHER, 27905e75ae1bSLEROY Christophe .alg.crypto = { 27915e75ae1bSLEROY Christophe .cra_name = "ecb(des3_ede)", 27925e75ae1bSLEROY Christophe .cra_driver_name = "ecb-3des-talitos", 27935e75ae1bSLEROY Christophe .cra_blocksize = DES3_EDE_BLOCK_SIZE, 27945e75ae1bSLEROY Christophe .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | 27955e75ae1bSLEROY Christophe CRYPTO_ALG_ASYNC, 27965e75ae1bSLEROY Christophe .cra_ablkcipher = { 27975e75ae1bSLEROY Christophe .min_keysize = DES3_EDE_KEY_SIZE, 27985e75ae1bSLEROY Christophe .max_keysize = DES3_EDE_KEY_SIZE, 2799ef7c5c85SHerbert Xu .setkey = ablkcipher_des3_setkey, 28005e75ae1bSLEROY Christophe } 28015e75ae1bSLEROY Christophe }, 28025e75ae1bSLEROY Christophe .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU | 28035e75ae1bSLEROY Christophe DESC_HDR_SEL0_DEU | 28045e75ae1bSLEROY Christophe DESC_HDR_MODE0_DEU_3DES, 28055e75ae1bSLEROY Christophe }, 28065e75ae1bSLEROY Christophe { .type = CRYPTO_ALG_TYPE_ABLKCIPHER, 28075e75ae1bSLEROY Christophe .alg.crypto = { 28084de9d0b5SLee Nipper .cra_name = "cbc(des3_ede)", 28094de9d0b5SLee Nipper .cra_driver_name = "cbc-3des-talitos", 28104de9d0b5SLee Nipper .cra_blocksize = DES3_EDE_BLOCK_SIZE, 28114de9d0b5SLee Nipper .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | 28124de9d0b5SLee Nipper CRYPTO_ALG_ASYNC, 28134de9d0b5SLee Nipper .cra_ablkcipher = { 28144de9d0b5SLee Nipper .min_keysize = DES3_EDE_KEY_SIZE, 28154de9d0b5SLee Nipper .max_keysize = DES3_EDE_KEY_SIZE, 28164de9d0b5SLee Nipper .ivsize = DES3_EDE_BLOCK_SIZE, 2817ef7c5c85SHerbert Xu .setkey = ablkcipher_des3_setkey, 28184de9d0b5SLee Nipper } 28194de9d0b5SLee Nipper }, 28204de9d0b5SLee Nipper .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU | 28214de9d0b5SLee Nipper DESC_HDR_SEL0_DEU | 28224de9d0b5SLee Nipper DESC_HDR_MODE0_DEU_CBC | 28234de9d0b5SLee Nipper DESC_HDR_MODE0_DEU_3DES, 2824497f2e6bSLee Nipper }, 2825497f2e6bSLee Nipper /* AHASH algorithms. */ 2826497f2e6bSLee Nipper { .type = CRYPTO_ALG_TYPE_AHASH, 2827497f2e6bSLee Nipper .alg.hash = { 2828497f2e6bSLee Nipper .halg.digestsize = MD5_DIGEST_SIZE, 28293639ca84SHoria Geant? .halg.statesize = sizeof(struct talitos_export_state), 2830497f2e6bSLee Nipper .halg.base = { 2831497f2e6bSLee Nipper .cra_name = "md5", 2832497f2e6bSLee Nipper .cra_driver_name = "md5-talitos", 2833b3988618SMartin Hicks .cra_blocksize = MD5_HMAC_BLOCK_SIZE, 28346a38f622SEric Biggers .cra_flags = CRYPTO_ALG_ASYNC, 28359c4a7965SKim Phillips } 2836497f2e6bSLee Nipper }, 2837497f2e6bSLee Nipper .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU | 2838497f2e6bSLee Nipper DESC_HDR_SEL0_MDEUA | 2839497f2e6bSLee Nipper DESC_HDR_MODE0_MDEU_MD5, 2840497f2e6bSLee Nipper }, 2841497f2e6bSLee Nipper { .type = CRYPTO_ALG_TYPE_AHASH, 2842497f2e6bSLee Nipper .alg.hash = { 2843497f2e6bSLee Nipper .halg.digestsize = SHA1_DIGEST_SIZE, 28443639ca84SHoria Geant? .halg.statesize = sizeof(struct talitos_export_state), 2845497f2e6bSLee Nipper .halg.base = { 2846497f2e6bSLee Nipper .cra_name = "sha1", 2847497f2e6bSLee Nipper .cra_driver_name = "sha1-talitos", 2848497f2e6bSLee Nipper .cra_blocksize = SHA1_BLOCK_SIZE, 28496a38f622SEric Biggers .cra_flags = CRYPTO_ALG_ASYNC, 2850497f2e6bSLee Nipper } 2851497f2e6bSLee Nipper }, 2852497f2e6bSLee Nipper .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU | 2853497f2e6bSLee Nipper DESC_HDR_SEL0_MDEUA | 2854497f2e6bSLee Nipper DESC_HDR_MODE0_MDEU_SHA1, 2855497f2e6bSLee Nipper }, 2856497f2e6bSLee Nipper { .type = CRYPTO_ALG_TYPE_AHASH, 2857497f2e6bSLee Nipper .alg.hash = { 285860f208d7SKim Phillips .halg.digestsize = SHA224_DIGEST_SIZE, 28593639ca84SHoria Geant? .halg.statesize = sizeof(struct talitos_export_state), 286060f208d7SKim Phillips .halg.base = { 286160f208d7SKim Phillips .cra_name = "sha224", 286260f208d7SKim Phillips .cra_driver_name = "sha224-talitos", 286360f208d7SKim Phillips .cra_blocksize = SHA224_BLOCK_SIZE, 28646a38f622SEric Biggers .cra_flags = CRYPTO_ALG_ASYNC, 286560f208d7SKim Phillips } 286660f208d7SKim Phillips }, 286760f208d7SKim Phillips .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU | 286860f208d7SKim Phillips DESC_HDR_SEL0_MDEUA | 286960f208d7SKim Phillips DESC_HDR_MODE0_MDEU_SHA224, 287060f208d7SKim Phillips }, 287160f208d7SKim Phillips { .type = CRYPTO_ALG_TYPE_AHASH, 287260f208d7SKim Phillips .alg.hash = { 2873497f2e6bSLee Nipper .halg.digestsize = SHA256_DIGEST_SIZE, 28743639ca84SHoria Geant? .halg.statesize = sizeof(struct talitos_export_state), 2875497f2e6bSLee Nipper .halg.base = { 2876497f2e6bSLee Nipper .cra_name = "sha256", 2877497f2e6bSLee Nipper .cra_driver_name = "sha256-talitos", 2878497f2e6bSLee Nipper .cra_blocksize = SHA256_BLOCK_SIZE, 28796a38f622SEric Biggers .cra_flags = CRYPTO_ALG_ASYNC, 2880497f2e6bSLee Nipper } 2881497f2e6bSLee Nipper }, 2882497f2e6bSLee Nipper .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU | 2883497f2e6bSLee Nipper DESC_HDR_SEL0_MDEUA | 2884497f2e6bSLee Nipper DESC_HDR_MODE0_MDEU_SHA256, 2885497f2e6bSLee Nipper }, 2886497f2e6bSLee Nipper { .type = CRYPTO_ALG_TYPE_AHASH, 2887497f2e6bSLee Nipper .alg.hash = { 2888497f2e6bSLee Nipper .halg.digestsize = SHA384_DIGEST_SIZE, 28893639ca84SHoria Geant? .halg.statesize = sizeof(struct talitos_export_state), 2890497f2e6bSLee Nipper .halg.base = { 2891497f2e6bSLee Nipper .cra_name = "sha384", 2892497f2e6bSLee Nipper .cra_driver_name = "sha384-talitos", 2893497f2e6bSLee Nipper .cra_blocksize = SHA384_BLOCK_SIZE, 28946a38f622SEric Biggers .cra_flags = CRYPTO_ALG_ASYNC, 2895497f2e6bSLee Nipper } 2896497f2e6bSLee Nipper }, 2897497f2e6bSLee Nipper .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU | 2898497f2e6bSLee Nipper DESC_HDR_SEL0_MDEUB | 2899497f2e6bSLee Nipper DESC_HDR_MODE0_MDEUB_SHA384, 2900497f2e6bSLee Nipper }, 2901497f2e6bSLee Nipper { .type = CRYPTO_ALG_TYPE_AHASH, 2902497f2e6bSLee Nipper .alg.hash = { 2903497f2e6bSLee Nipper .halg.digestsize = SHA512_DIGEST_SIZE, 29043639ca84SHoria Geant? .halg.statesize = sizeof(struct talitos_export_state), 2905497f2e6bSLee Nipper .halg.base = { 2906497f2e6bSLee Nipper .cra_name = "sha512", 2907497f2e6bSLee Nipper .cra_driver_name = "sha512-talitos", 2908497f2e6bSLee Nipper .cra_blocksize = SHA512_BLOCK_SIZE, 29096a38f622SEric Biggers .cra_flags = CRYPTO_ALG_ASYNC, 2910497f2e6bSLee Nipper } 2911497f2e6bSLee Nipper }, 2912497f2e6bSLee Nipper .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU | 2913497f2e6bSLee Nipper DESC_HDR_SEL0_MDEUB | 2914497f2e6bSLee Nipper DESC_HDR_MODE0_MDEUB_SHA512, 2915497f2e6bSLee Nipper }, 291679b3a418SLee Nipper { .type = CRYPTO_ALG_TYPE_AHASH, 291779b3a418SLee Nipper .alg.hash = { 291879b3a418SLee Nipper .halg.digestsize = MD5_DIGEST_SIZE, 29193639ca84SHoria Geant? .halg.statesize = sizeof(struct talitos_export_state), 292079b3a418SLee Nipper .halg.base = { 292179b3a418SLee Nipper .cra_name = "hmac(md5)", 292279b3a418SLee Nipper .cra_driver_name = "hmac-md5-talitos", 2923b3988618SMartin Hicks .cra_blocksize = MD5_HMAC_BLOCK_SIZE, 29246a38f622SEric Biggers .cra_flags = CRYPTO_ALG_ASYNC, 292579b3a418SLee Nipper } 292679b3a418SLee Nipper }, 292779b3a418SLee Nipper .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU | 292879b3a418SLee Nipper DESC_HDR_SEL0_MDEUA | 292979b3a418SLee Nipper DESC_HDR_MODE0_MDEU_MD5, 293079b3a418SLee Nipper }, 293179b3a418SLee Nipper { .type = CRYPTO_ALG_TYPE_AHASH, 293279b3a418SLee Nipper .alg.hash = { 293379b3a418SLee Nipper .halg.digestsize = SHA1_DIGEST_SIZE, 29343639ca84SHoria Geant? .halg.statesize = sizeof(struct talitos_export_state), 293579b3a418SLee Nipper .halg.base = { 293679b3a418SLee Nipper .cra_name = "hmac(sha1)", 293779b3a418SLee Nipper .cra_driver_name = "hmac-sha1-talitos", 293879b3a418SLee Nipper .cra_blocksize = SHA1_BLOCK_SIZE, 29396a38f622SEric Biggers .cra_flags = CRYPTO_ALG_ASYNC, 294079b3a418SLee Nipper } 294179b3a418SLee Nipper }, 294279b3a418SLee Nipper .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU | 294379b3a418SLee Nipper DESC_HDR_SEL0_MDEUA | 294479b3a418SLee Nipper DESC_HDR_MODE0_MDEU_SHA1, 294579b3a418SLee Nipper }, 294679b3a418SLee Nipper { .type = CRYPTO_ALG_TYPE_AHASH, 294779b3a418SLee Nipper .alg.hash = { 294879b3a418SLee Nipper .halg.digestsize = SHA224_DIGEST_SIZE, 29493639ca84SHoria Geant? .halg.statesize = sizeof(struct talitos_export_state), 295079b3a418SLee Nipper .halg.base = { 295179b3a418SLee Nipper .cra_name = "hmac(sha224)", 295279b3a418SLee Nipper .cra_driver_name = "hmac-sha224-talitos", 295379b3a418SLee Nipper .cra_blocksize = SHA224_BLOCK_SIZE, 29546a38f622SEric Biggers .cra_flags = CRYPTO_ALG_ASYNC, 295579b3a418SLee Nipper } 295679b3a418SLee Nipper }, 295779b3a418SLee Nipper .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU | 295879b3a418SLee Nipper DESC_HDR_SEL0_MDEUA | 295979b3a418SLee Nipper DESC_HDR_MODE0_MDEU_SHA224, 296079b3a418SLee Nipper }, 296179b3a418SLee Nipper { .type = CRYPTO_ALG_TYPE_AHASH, 296279b3a418SLee Nipper .alg.hash = { 296379b3a418SLee Nipper .halg.digestsize = SHA256_DIGEST_SIZE, 29643639ca84SHoria Geant? .halg.statesize = sizeof(struct talitos_export_state), 296579b3a418SLee Nipper .halg.base = { 296679b3a418SLee Nipper .cra_name = "hmac(sha256)", 296779b3a418SLee Nipper .cra_driver_name = "hmac-sha256-talitos", 296879b3a418SLee Nipper .cra_blocksize = SHA256_BLOCK_SIZE, 29696a38f622SEric Biggers .cra_flags = CRYPTO_ALG_ASYNC, 297079b3a418SLee Nipper } 297179b3a418SLee Nipper }, 297279b3a418SLee Nipper .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU | 297379b3a418SLee Nipper DESC_HDR_SEL0_MDEUA | 297479b3a418SLee Nipper DESC_HDR_MODE0_MDEU_SHA256, 297579b3a418SLee Nipper }, 297679b3a418SLee Nipper { .type = CRYPTO_ALG_TYPE_AHASH, 297779b3a418SLee Nipper .alg.hash = { 297879b3a418SLee Nipper .halg.digestsize = SHA384_DIGEST_SIZE, 29793639ca84SHoria Geant? .halg.statesize = sizeof(struct talitos_export_state), 298079b3a418SLee Nipper .halg.base = { 298179b3a418SLee Nipper .cra_name = "hmac(sha384)", 298279b3a418SLee Nipper .cra_driver_name = "hmac-sha384-talitos", 298379b3a418SLee Nipper .cra_blocksize = SHA384_BLOCK_SIZE, 29846a38f622SEric Biggers .cra_flags = CRYPTO_ALG_ASYNC, 298579b3a418SLee Nipper } 298679b3a418SLee Nipper }, 298779b3a418SLee Nipper .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU | 298879b3a418SLee Nipper DESC_HDR_SEL0_MDEUB | 298979b3a418SLee Nipper DESC_HDR_MODE0_MDEUB_SHA384, 299079b3a418SLee Nipper }, 299179b3a418SLee Nipper { .type = CRYPTO_ALG_TYPE_AHASH, 299279b3a418SLee Nipper .alg.hash = { 299379b3a418SLee Nipper .halg.digestsize = SHA512_DIGEST_SIZE, 29943639ca84SHoria Geant? .halg.statesize = sizeof(struct talitos_export_state), 299579b3a418SLee Nipper .halg.base = { 299679b3a418SLee Nipper .cra_name = "hmac(sha512)", 299779b3a418SLee Nipper .cra_driver_name = "hmac-sha512-talitos", 299879b3a418SLee Nipper .cra_blocksize = SHA512_BLOCK_SIZE, 29996a38f622SEric Biggers .cra_flags = CRYPTO_ALG_ASYNC, 300079b3a418SLee Nipper } 300179b3a418SLee Nipper }, 300279b3a418SLee Nipper .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU | 300379b3a418SLee Nipper DESC_HDR_SEL0_MDEUB | 300479b3a418SLee Nipper DESC_HDR_MODE0_MDEUB_SHA512, 300579b3a418SLee Nipper } 30069c4a7965SKim Phillips }; 30079c4a7965SKim Phillips 30089c4a7965SKim Phillips struct talitos_crypto_alg { 30099c4a7965SKim Phillips struct list_head entry; 30109c4a7965SKim Phillips struct device *dev; 3011acbf7c62SLee Nipper struct talitos_alg_template algt; 30129c4a7965SKim Phillips }; 30139c4a7965SKim Phillips 301489d124cbSJonas Eymann static int talitos_init_common(struct talitos_ctx *ctx, 301589d124cbSJonas Eymann struct talitos_crypto_alg *talitos_alg) 30169c4a7965SKim Phillips { 30175228f0f7SKim Phillips struct talitos_private *priv; 30189c4a7965SKim Phillips 30199c4a7965SKim Phillips /* update context with ptr to dev */ 30209c4a7965SKim Phillips ctx->dev = talitos_alg->dev; 302119bbbc63SKim Phillips 30225228f0f7SKim Phillips /* assign SEC channel to tfm in round-robin fashion */ 30235228f0f7SKim Phillips priv = dev_get_drvdata(ctx->dev); 30245228f0f7SKim Phillips ctx->ch = atomic_inc_return(&priv->last_chan) & 30255228f0f7SKim Phillips (priv->num_channels - 1); 30265228f0f7SKim Phillips 30279c4a7965SKim Phillips /* copy descriptor header template value */ 3028acbf7c62SLee Nipper ctx->desc_hdr_template = talitos_alg->algt.desc_hdr_template; 30299c4a7965SKim Phillips 3030602dba5aSKim Phillips /* select done notification */ 3031602dba5aSKim Phillips ctx->desc_hdr_template |= DESC_HDR_DONE_NOTIFY; 3032602dba5aSKim Phillips 3033497f2e6bSLee Nipper return 0; 3034497f2e6bSLee Nipper } 3035497f2e6bSLee Nipper 303689d124cbSJonas Eymann static int talitos_cra_init(struct crypto_tfm *tfm) 303789d124cbSJonas Eymann { 303889d124cbSJonas Eymann struct crypto_alg *alg = tfm->__crt_alg; 303989d124cbSJonas Eymann struct talitos_crypto_alg *talitos_alg; 304089d124cbSJonas Eymann struct talitos_ctx *ctx = crypto_tfm_ctx(tfm); 304189d124cbSJonas Eymann 304289d124cbSJonas Eymann if ((alg->cra_flags & CRYPTO_ALG_TYPE_MASK) == CRYPTO_ALG_TYPE_AHASH) 304389d124cbSJonas Eymann talitos_alg = container_of(__crypto_ahash_alg(alg), 304489d124cbSJonas Eymann struct talitos_crypto_alg, 304589d124cbSJonas Eymann algt.alg.hash); 304689d124cbSJonas Eymann else 304789d124cbSJonas Eymann talitos_alg = container_of(alg, struct talitos_crypto_alg, 304889d124cbSJonas Eymann algt.alg.crypto); 304989d124cbSJonas Eymann 305089d124cbSJonas Eymann return talitos_init_common(ctx, talitos_alg); 305189d124cbSJonas Eymann } 305289d124cbSJonas Eymann 3053aeb4c132SHerbert Xu static int talitos_cra_init_aead(struct crypto_aead *tfm) 3054497f2e6bSLee Nipper { 305589d124cbSJonas Eymann struct aead_alg *alg = crypto_aead_alg(tfm); 305689d124cbSJonas Eymann struct talitos_crypto_alg *talitos_alg; 305789d124cbSJonas Eymann struct talitos_ctx *ctx = crypto_aead_ctx(tfm); 305889d124cbSJonas Eymann 305989d124cbSJonas Eymann talitos_alg = container_of(alg, struct talitos_crypto_alg, 306089d124cbSJonas Eymann algt.alg.aead); 306189d124cbSJonas Eymann 306289d124cbSJonas Eymann return talitos_init_common(ctx, talitos_alg); 30639c4a7965SKim Phillips } 30649c4a7965SKim Phillips 3065497f2e6bSLee Nipper static int talitos_cra_init_ahash(struct crypto_tfm *tfm) 3066497f2e6bSLee Nipper { 3067497f2e6bSLee Nipper struct talitos_ctx *ctx = crypto_tfm_ctx(tfm); 3068497f2e6bSLee Nipper 3069497f2e6bSLee Nipper talitos_cra_init(tfm); 3070497f2e6bSLee Nipper 3071497f2e6bSLee Nipper ctx->keylen = 0; 3072497f2e6bSLee Nipper crypto_ahash_set_reqsize(__crypto_ahash_cast(tfm), 3073497f2e6bSLee Nipper sizeof(struct talitos_ahash_req_ctx)); 3074497f2e6bSLee Nipper 3075497f2e6bSLee Nipper return 0; 3076497f2e6bSLee Nipper } 3077497f2e6bSLee Nipper 30782e13ce08SLEROY Christophe static void talitos_cra_exit(struct crypto_tfm *tfm) 30792e13ce08SLEROY Christophe { 30802e13ce08SLEROY Christophe struct talitos_ctx *ctx = crypto_tfm_ctx(tfm); 30812e13ce08SLEROY Christophe struct device *dev = ctx->dev; 30822e13ce08SLEROY Christophe 30832e13ce08SLEROY Christophe if (ctx->keylen) 30842e13ce08SLEROY Christophe dma_unmap_single(dev, ctx->dma_key, ctx->keylen, DMA_TO_DEVICE); 30852e13ce08SLEROY Christophe } 30862e13ce08SLEROY Christophe 30879c4a7965SKim Phillips /* 30889c4a7965SKim Phillips * given the alg's descriptor header template, determine whether descriptor 30899c4a7965SKim Phillips * type and primary/secondary execution units required match the hw 30909c4a7965SKim Phillips * capabilities description provided in the device tree node. 30919c4a7965SKim Phillips */ 30929c4a7965SKim Phillips static int hw_supports(struct device *dev, __be32 desc_hdr_template) 30939c4a7965SKim Phillips { 30949c4a7965SKim Phillips struct talitos_private *priv = dev_get_drvdata(dev); 30959c4a7965SKim Phillips int ret; 30969c4a7965SKim Phillips 30979c4a7965SKim Phillips ret = (1 << DESC_TYPE(desc_hdr_template) & priv->desc_types) && 30989c4a7965SKim Phillips (1 << PRIMARY_EU(desc_hdr_template) & priv->exec_units); 30999c4a7965SKim Phillips 31009c4a7965SKim Phillips if (SECONDARY_EU(desc_hdr_template)) 31019c4a7965SKim Phillips ret = ret && (1 << SECONDARY_EU(desc_hdr_template) 31029c4a7965SKim Phillips & priv->exec_units); 31039c4a7965SKim Phillips 31049c4a7965SKim Phillips return ret; 31059c4a7965SKim Phillips } 31069c4a7965SKim Phillips 31072dc11581SGrant Likely static int talitos_remove(struct platform_device *ofdev) 31089c4a7965SKim Phillips { 31099c4a7965SKim Phillips struct device *dev = &ofdev->dev; 31109c4a7965SKim Phillips struct talitos_private *priv = dev_get_drvdata(dev); 31119c4a7965SKim Phillips struct talitos_crypto_alg *t_alg, *n; 31129c4a7965SKim Phillips int i; 31139c4a7965SKim Phillips 31149c4a7965SKim Phillips list_for_each_entry_safe(t_alg, n, &priv->alg_list, entry) { 3115acbf7c62SLee Nipper switch (t_alg->algt.type) { 3116acbf7c62SLee Nipper case CRYPTO_ALG_TYPE_ABLKCIPHER: 3117acbf7c62SLee Nipper break; 3118aeb4c132SHerbert Xu case CRYPTO_ALG_TYPE_AEAD: 3119aeb4c132SHerbert Xu crypto_unregister_aead(&t_alg->algt.alg.aead); 3120acbf7c62SLee Nipper case CRYPTO_ALG_TYPE_AHASH: 3121acbf7c62SLee Nipper crypto_unregister_ahash(&t_alg->algt.alg.hash); 3122acbf7c62SLee Nipper break; 3123acbf7c62SLee Nipper } 31249c4a7965SKim Phillips list_del(&t_alg->entry); 31259c4a7965SKim Phillips } 31269c4a7965SKim Phillips 31279c4a7965SKim Phillips if (hw_supports(dev, DESC_HDR_SEL0_RNG)) 31289c4a7965SKim Phillips talitos_unregister_rng(dev); 31299c4a7965SKim Phillips 3130c3e337f8SKim Phillips for (i = 0; i < 2; i++) 31312cdba3cfSKim Phillips if (priv->irq[i]) { 3132c3e337f8SKim Phillips free_irq(priv->irq[i], dev); 3133c3e337f8SKim Phillips irq_dispose_mapping(priv->irq[i]); 31349c4a7965SKim Phillips } 31359c4a7965SKim Phillips 3136c3e337f8SKim Phillips tasklet_kill(&priv->done_task[0]); 31372cdba3cfSKim Phillips if (priv->irq[1]) 3138c3e337f8SKim Phillips tasklet_kill(&priv->done_task[1]); 31399c4a7965SKim Phillips 31409c4a7965SKim Phillips return 0; 31419c4a7965SKim Phillips } 31429c4a7965SKim Phillips 31439c4a7965SKim Phillips static struct talitos_crypto_alg *talitos_alg_alloc(struct device *dev, 31449c4a7965SKim Phillips struct talitos_alg_template 31459c4a7965SKim Phillips *template) 31469c4a7965SKim Phillips { 314760f208d7SKim Phillips struct talitos_private *priv = dev_get_drvdata(dev); 31489c4a7965SKim Phillips struct talitos_crypto_alg *t_alg; 31499c4a7965SKim Phillips struct crypto_alg *alg; 31509c4a7965SKim Phillips 315124b92ff2SLEROY Christophe t_alg = devm_kzalloc(dev, sizeof(struct talitos_crypto_alg), 315224b92ff2SLEROY Christophe GFP_KERNEL); 31539c4a7965SKim Phillips if (!t_alg) 31549c4a7965SKim Phillips return ERR_PTR(-ENOMEM); 31559c4a7965SKim Phillips 3156acbf7c62SLee Nipper t_alg->algt = *template; 3157acbf7c62SLee Nipper 3158acbf7c62SLee Nipper switch (t_alg->algt.type) { 3159acbf7c62SLee Nipper case CRYPTO_ALG_TYPE_ABLKCIPHER: 3160497f2e6bSLee Nipper alg = &t_alg->algt.alg.crypto; 3161497f2e6bSLee Nipper alg->cra_init = talitos_cra_init; 31622e13ce08SLEROY Christophe alg->cra_exit = talitos_cra_exit; 3163d4cd3283SKim Phillips alg->cra_type = &crypto_ablkcipher_type; 3164ef7c5c85SHerbert Xu alg->cra_ablkcipher.setkey = alg->cra_ablkcipher.setkey ?: 3165ef7c5c85SHerbert Xu ablkcipher_setkey; 3166b286e003SKim Phillips alg->cra_ablkcipher.encrypt = ablkcipher_encrypt; 3167b286e003SKim Phillips alg->cra_ablkcipher.decrypt = ablkcipher_decrypt; 3168497f2e6bSLee Nipper break; 3169acbf7c62SLee Nipper case CRYPTO_ALG_TYPE_AEAD: 3170aeb4c132SHerbert Xu alg = &t_alg->algt.alg.aead.base; 31712e13ce08SLEROY Christophe alg->cra_exit = talitos_cra_exit; 3172aeb4c132SHerbert Xu t_alg->algt.alg.aead.init = talitos_cra_init_aead; 3173ef7c5c85SHerbert Xu t_alg->algt.alg.aead.setkey = t_alg->algt.alg.aead.setkey ?: 3174ef7c5c85SHerbert Xu aead_setkey; 3175aeb4c132SHerbert Xu t_alg->algt.alg.aead.encrypt = aead_encrypt; 3176aeb4c132SHerbert Xu t_alg->algt.alg.aead.decrypt = aead_decrypt; 31776cda075aSLEROY Christophe if (!(priv->features & TALITOS_FTR_SHA224_HWINIT) && 31786cda075aSLEROY Christophe !strncmp(alg->cra_name, "authenc(hmac(sha224)", 20)) { 317924b92ff2SLEROY Christophe devm_kfree(dev, t_alg); 31806cda075aSLEROY Christophe return ERR_PTR(-ENOTSUPP); 31816cda075aSLEROY Christophe } 3182acbf7c62SLee Nipper break; 3183acbf7c62SLee Nipper case CRYPTO_ALG_TYPE_AHASH: 3184acbf7c62SLee Nipper alg = &t_alg->algt.alg.hash.halg.base; 3185497f2e6bSLee Nipper alg->cra_init = talitos_cra_init_ahash; 3186ad4cd51fSLEROY Christophe alg->cra_exit = talitos_cra_exit; 3187b286e003SKim Phillips t_alg->algt.alg.hash.init = ahash_init; 3188b286e003SKim Phillips t_alg->algt.alg.hash.update = ahash_update; 3189b286e003SKim Phillips t_alg->algt.alg.hash.final = ahash_final; 3190b286e003SKim Phillips t_alg->algt.alg.hash.finup = ahash_finup; 3191b286e003SKim Phillips t_alg->algt.alg.hash.digest = ahash_digest; 319256136631SLEROY Christophe if (!strncmp(alg->cra_name, "hmac", 4)) 3193b286e003SKim Phillips t_alg->algt.alg.hash.setkey = ahash_setkey; 31943639ca84SHoria Geant? t_alg->algt.alg.hash.import = ahash_import; 31953639ca84SHoria Geant? t_alg->algt.alg.hash.export = ahash_export; 3196b286e003SKim Phillips 319779b3a418SLee Nipper if (!(priv->features & TALITOS_FTR_HMAC_OK) && 31980b2730d8SKim Phillips !strncmp(alg->cra_name, "hmac", 4)) { 319924b92ff2SLEROY Christophe devm_kfree(dev, t_alg); 320079b3a418SLee Nipper return ERR_PTR(-ENOTSUPP); 32010b2730d8SKim Phillips } 320260f208d7SKim Phillips if (!(priv->features & TALITOS_FTR_SHA224_HWINIT) && 320379b3a418SLee Nipper (!strcmp(alg->cra_name, "sha224") || 320479b3a418SLee Nipper !strcmp(alg->cra_name, "hmac(sha224)"))) { 320560f208d7SKim Phillips t_alg->algt.alg.hash.init = ahash_init_sha224_swinit; 320660f208d7SKim Phillips t_alg->algt.desc_hdr_template = 320760f208d7SKim Phillips DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU | 320860f208d7SKim Phillips DESC_HDR_SEL0_MDEUA | 320960f208d7SKim Phillips DESC_HDR_MODE0_MDEU_SHA256; 321060f208d7SKim Phillips } 3211497f2e6bSLee Nipper break; 32121d11911aSKim Phillips default: 32131d11911aSKim Phillips dev_err(dev, "unknown algorithm type %d\n", t_alg->algt.type); 321424b92ff2SLEROY Christophe devm_kfree(dev, t_alg); 32151d11911aSKim Phillips return ERR_PTR(-EINVAL); 3216acbf7c62SLee Nipper } 32179c4a7965SKim Phillips 32189c4a7965SKim Phillips alg->cra_module = THIS_MODULE; 3219b0057763SLEROY Christophe if (t_alg->algt.priority) 3220b0057763SLEROY Christophe alg->cra_priority = t_alg->algt.priority; 3221b0057763SLEROY Christophe else 32229c4a7965SKim Phillips alg->cra_priority = TALITOS_CRA_PRIORITY; 3223c9cca703SChristophe Leroy if (has_ftr_sec1(priv)) 3224c9cca703SChristophe Leroy alg->cra_alignmask = 3; 3225c9cca703SChristophe Leroy else 32269c4a7965SKim Phillips alg->cra_alignmask = 0; 32279c4a7965SKim Phillips alg->cra_ctxsize = sizeof(struct talitos_ctx); 3228d912bb76SNikos Mavrogiannopoulos alg->cra_flags |= CRYPTO_ALG_KERN_DRIVER_ONLY; 32299c4a7965SKim Phillips 32309c4a7965SKim Phillips t_alg->dev = dev; 32319c4a7965SKim Phillips 32329c4a7965SKim Phillips return t_alg; 32339c4a7965SKim Phillips } 32349c4a7965SKim Phillips 3235c3e337f8SKim Phillips static int talitos_probe_irq(struct platform_device *ofdev) 3236c3e337f8SKim Phillips { 3237c3e337f8SKim Phillips struct device *dev = &ofdev->dev; 3238c3e337f8SKim Phillips struct device_node *np = ofdev->dev.of_node; 3239c3e337f8SKim Phillips struct talitos_private *priv = dev_get_drvdata(dev); 3240c3e337f8SKim Phillips int err; 3241dd3c0987SLEROY Christophe bool is_sec1 = has_ftr_sec1(priv); 3242c3e337f8SKim Phillips 3243c3e337f8SKim Phillips priv->irq[0] = irq_of_parse_and_map(np, 0); 32442cdba3cfSKim Phillips if (!priv->irq[0]) { 3245c3e337f8SKim Phillips dev_err(dev, "failed to map irq\n"); 3246c3e337f8SKim Phillips return -EINVAL; 3247c3e337f8SKim Phillips } 3248dd3c0987SLEROY Christophe if (is_sec1) { 3249dd3c0987SLEROY Christophe err = request_irq(priv->irq[0], talitos1_interrupt_4ch, 0, 3250dd3c0987SLEROY Christophe dev_driver_string(dev), dev); 3251dd3c0987SLEROY Christophe goto primary_out; 3252dd3c0987SLEROY Christophe } 3253c3e337f8SKim Phillips 3254c3e337f8SKim Phillips priv->irq[1] = irq_of_parse_and_map(np, 1); 3255c3e337f8SKim Phillips 3256c3e337f8SKim Phillips /* get the primary irq line */ 32572cdba3cfSKim Phillips if (!priv->irq[1]) { 3258dd3c0987SLEROY Christophe err = request_irq(priv->irq[0], talitos2_interrupt_4ch, 0, 3259c3e337f8SKim Phillips dev_driver_string(dev), dev); 3260c3e337f8SKim Phillips goto primary_out; 3261c3e337f8SKim Phillips } 3262c3e337f8SKim Phillips 3263dd3c0987SLEROY Christophe err = request_irq(priv->irq[0], talitos2_interrupt_ch0_2, 0, 3264c3e337f8SKim Phillips dev_driver_string(dev), dev); 3265c3e337f8SKim Phillips if (err) 3266c3e337f8SKim Phillips goto primary_out; 3267c3e337f8SKim Phillips 3268c3e337f8SKim Phillips /* get the secondary irq line */ 3269dd3c0987SLEROY Christophe err = request_irq(priv->irq[1], talitos2_interrupt_ch1_3, 0, 3270c3e337f8SKim Phillips dev_driver_string(dev), dev); 3271c3e337f8SKim Phillips if (err) { 3272c3e337f8SKim Phillips dev_err(dev, "failed to request secondary irq\n"); 3273c3e337f8SKim Phillips irq_dispose_mapping(priv->irq[1]); 32742cdba3cfSKim Phillips priv->irq[1] = 0; 3275c3e337f8SKim Phillips } 3276c3e337f8SKim Phillips 3277c3e337f8SKim Phillips return err; 3278c3e337f8SKim Phillips 3279c3e337f8SKim Phillips primary_out: 3280c3e337f8SKim Phillips if (err) { 3281c3e337f8SKim Phillips dev_err(dev, "failed to request primary irq\n"); 3282c3e337f8SKim Phillips irq_dispose_mapping(priv->irq[0]); 32832cdba3cfSKim Phillips priv->irq[0] = 0; 3284c3e337f8SKim Phillips } 3285c3e337f8SKim Phillips 3286c3e337f8SKim Phillips return err; 3287c3e337f8SKim Phillips } 3288c3e337f8SKim Phillips 32891c48a5c9SGrant Likely static int talitos_probe(struct platform_device *ofdev) 32909c4a7965SKim Phillips { 32919c4a7965SKim Phillips struct device *dev = &ofdev->dev; 329261c7a080SGrant Likely struct device_node *np = ofdev->dev.of_node; 32939c4a7965SKim Phillips struct talitos_private *priv; 32949c4a7965SKim Phillips int i, err; 32955fa7fa14SLEROY Christophe int stride; 3296fd5ea7f0SLEROY Christophe struct resource *res; 32979c4a7965SKim Phillips 329824b92ff2SLEROY Christophe priv = devm_kzalloc(dev, sizeof(struct talitos_private), GFP_KERNEL); 32999c4a7965SKim Phillips if (!priv) 33009c4a7965SKim Phillips return -ENOMEM; 33019c4a7965SKim Phillips 3302f3de9cb1SKevin Hao INIT_LIST_HEAD(&priv->alg_list); 3303f3de9cb1SKevin Hao 33049c4a7965SKim Phillips dev_set_drvdata(dev, priv); 33059c4a7965SKim Phillips 33069c4a7965SKim Phillips priv->ofdev = ofdev; 33079c4a7965SKim Phillips 3308511d63cbSHoria Geanta spin_lock_init(&priv->reg_lock); 3309511d63cbSHoria Geanta 3310fd5ea7f0SLEROY Christophe res = platform_get_resource(ofdev, IORESOURCE_MEM, 0); 3311fd5ea7f0SLEROY Christophe if (!res) 3312fd5ea7f0SLEROY Christophe return -ENXIO; 3313fd5ea7f0SLEROY Christophe priv->reg = devm_ioremap(dev, res->start, resource_size(res)); 33149c4a7965SKim Phillips if (!priv->reg) { 33159c4a7965SKim Phillips dev_err(dev, "failed to of_iomap\n"); 33169c4a7965SKim Phillips err = -ENOMEM; 33179c4a7965SKim Phillips goto err_out; 33189c4a7965SKim Phillips } 33199c4a7965SKim Phillips 33209c4a7965SKim Phillips /* get SEC version capabilities from device tree */ 3321fa14c6cfSLEROY Christophe of_property_read_u32(np, "fsl,num-channels", &priv->num_channels); 3322fa14c6cfSLEROY Christophe of_property_read_u32(np, "fsl,channel-fifo-len", &priv->chfifo_len); 3323fa14c6cfSLEROY Christophe of_property_read_u32(np, "fsl,exec-units-mask", &priv->exec_units); 3324fa14c6cfSLEROY Christophe of_property_read_u32(np, "fsl,descriptor-types-mask", 3325fa14c6cfSLEROY Christophe &priv->desc_types); 33269c4a7965SKim Phillips 33279c4a7965SKim Phillips if (!is_power_of_2(priv->num_channels) || !priv->chfifo_len || 33289c4a7965SKim Phillips !priv->exec_units || !priv->desc_types) { 33299c4a7965SKim Phillips dev_err(dev, "invalid property data in device tree node\n"); 33309c4a7965SKim Phillips err = -EINVAL; 33319c4a7965SKim Phillips goto err_out; 33329c4a7965SKim Phillips } 33339c4a7965SKim Phillips 3334f3c85bc1SLee Nipper if (of_device_is_compatible(np, "fsl,sec3.0")) 3335f3c85bc1SLee Nipper priv->features |= TALITOS_FTR_SRC_LINK_TBL_LEN_INCLUDES_EXTENT; 3336f3c85bc1SLee Nipper 3337fe5720e2SKim Phillips if (of_device_is_compatible(np, "fsl,sec2.1")) 333860f208d7SKim Phillips priv->features |= TALITOS_FTR_HW_AUTH_CHECK | 333979b3a418SLee Nipper TALITOS_FTR_SHA224_HWINIT | 334079b3a418SLee Nipper TALITOS_FTR_HMAC_OK; 3341fe5720e2SKim Phillips 334221590888SLEROY Christophe if (of_device_is_compatible(np, "fsl,sec1.0")) 334321590888SLEROY Christophe priv->features |= TALITOS_FTR_SEC1; 334421590888SLEROY Christophe 33455fa7fa14SLEROY Christophe if (of_device_is_compatible(np, "fsl,sec1.2")) { 33465fa7fa14SLEROY Christophe priv->reg_deu = priv->reg + TALITOS12_DEU; 33475fa7fa14SLEROY Christophe priv->reg_aesu = priv->reg + TALITOS12_AESU; 33485fa7fa14SLEROY Christophe priv->reg_mdeu = priv->reg + TALITOS12_MDEU; 33495fa7fa14SLEROY Christophe stride = TALITOS1_CH_STRIDE; 33505fa7fa14SLEROY Christophe } else if (of_device_is_compatible(np, "fsl,sec1.0")) { 33515fa7fa14SLEROY Christophe priv->reg_deu = priv->reg + TALITOS10_DEU; 33525fa7fa14SLEROY Christophe priv->reg_aesu = priv->reg + TALITOS10_AESU; 33535fa7fa14SLEROY Christophe priv->reg_mdeu = priv->reg + TALITOS10_MDEU; 33545fa7fa14SLEROY Christophe priv->reg_afeu = priv->reg + TALITOS10_AFEU; 33555fa7fa14SLEROY Christophe priv->reg_rngu = priv->reg + TALITOS10_RNGU; 33565fa7fa14SLEROY Christophe priv->reg_pkeu = priv->reg + TALITOS10_PKEU; 33575fa7fa14SLEROY Christophe stride = TALITOS1_CH_STRIDE; 33585fa7fa14SLEROY Christophe } else { 33595fa7fa14SLEROY Christophe priv->reg_deu = priv->reg + TALITOS2_DEU; 33605fa7fa14SLEROY Christophe priv->reg_aesu = priv->reg + TALITOS2_AESU; 33615fa7fa14SLEROY Christophe priv->reg_mdeu = priv->reg + TALITOS2_MDEU; 33625fa7fa14SLEROY Christophe priv->reg_afeu = priv->reg + TALITOS2_AFEU; 33635fa7fa14SLEROY Christophe priv->reg_rngu = priv->reg + TALITOS2_RNGU; 33645fa7fa14SLEROY Christophe priv->reg_pkeu = priv->reg + TALITOS2_PKEU; 33655fa7fa14SLEROY Christophe priv->reg_keu = priv->reg + TALITOS2_KEU; 33665fa7fa14SLEROY Christophe priv->reg_crcu = priv->reg + TALITOS2_CRCU; 33675fa7fa14SLEROY Christophe stride = TALITOS2_CH_STRIDE; 33685fa7fa14SLEROY Christophe } 33695fa7fa14SLEROY Christophe 3370dd3c0987SLEROY Christophe err = talitos_probe_irq(ofdev); 3371dd3c0987SLEROY Christophe if (err) 3372dd3c0987SLEROY Christophe goto err_out; 3373dd3c0987SLEROY Christophe 3374c8c74647SChristophe Leroy if (has_ftr_sec1(priv)) { 33759c02e285SLEROY Christophe if (priv->num_channels == 1) 33769c02e285SLEROY Christophe tasklet_init(&priv->done_task[0], talitos1_done_ch0, 33779c02e285SLEROY Christophe (unsigned long)dev); 33789c02e285SLEROY Christophe else 3379dd3c0987SLEROY Christophe tasklet_init(&priv->done_task[0], talitos1_done_4ch, 3380dd3c0987SLEROY Christophe (unsigned long)dev); 3381dd3c0987SLEROY Christophe } else { 33829c02e285SLEROY Christophe if (priv->irq[1]) { 3383dd3c0987SLEROY Christophe tasklet_init(&priv->done_task[0], talitos2_done_ch0_2, 3384dd3c0987SLEROY Christophe (unsigned long)dev); 3385dd3c0987SLEROY Christophe tasklet_init(&priv->done_task[1], talitos2_done_ch1_3, 3386dd3c0987SLEROY Christophe (unsigned long)dev); 33879c02e285SLEROY Christophe } else if (priv->num_channels == 1) { 33889c02e285SLEROY Christophe tasklet_init(&priv->done_task[0], talitos2_done_ch0, 33899c02e285SLEROY Christophe (unsigned long)dev); 33909c02e285SLEROY Christophe } else { 33919c02e285SLEROY Christophe tasklet_init(&priv->done_task[0], talitos2_done_4ch, 33929c02e285SLEROY Christophe (unsigned long)dev); 3393dd3c0987SLEROY Christophe } 3394dd3c0987SLEROY Christophe } 3395dd3c0987SLEROY Christophe 3396a86854d0SKees Cook priv->chan = devm_kcalloc(dev, 3397a86854d0SKees Cook priv->num_channels, 3398a86854d0SKees Cook sizeof(struct talitos_channel), 3399a86854d0SKees Cook GFP_KERNEL); 34004b992628SKim Phillips if (!priv->chan) { 34014b992628SKim Phillips dev_err(dev, "failed to allocate channel management space\n"); 34029c4a7965SKim Phillips err = -ENOMEM; 34039c4a7965SKim Phillips goto err_out; 34049c4a7965SKim Phillips } 34059c4a7965SKim Phillips 3406f641ddddSMartin Hicks priv->fifo_len = roundup_pow_of_two(priv->chfifo_len); 3407f641ddddSMartin Hicks 3408c3e337f8SKim Phillips for (i = 0; i < priv->num_channels; i++) { 34095fa7fa14SLEROY Christophe priv->chan[i].reg = priv->reg + stride * (i + 1); 34102cdba3cfSKim Phillips if (!priv->irq[1] || !(i & 1)) 3411c3e337f8SKim Phillips priv->chan[i].reg += TALITOS_CH_BASE_OFFSET; 3412ad42d5fcSKim Phillips 34134b992628SKim Phillips spin_lock_init(&priv->chan[i].head_lock); 34144b992628SKim Phillips spin_lock_init(&priv->chan[i].tail_lock); 34159c4a7965SKim Phillips 3416a86854d0SKees Cook priv->chan[i].fifo = devm_kcalloc(dev, 3417a86854d0SKees Cook priv->fifo_len, 3418a86854d0SKees Cook sizeof(struct talitos_request), 3419a86854d0SKees Cook GFP_KERNEL); 34204b992628SKim Phillips if (!priv->chan[i].fifo) { 34219c4a7965SKim Phillips dev_err(dev, "failed to allocate request fifo %d\n", i); 34229c4a7965SKim Phillips err = -ENOMEM; 34239c4a7965SKim Phillips goto err_out; 34249c4a7965SKim Phillips } 34259c4a7965SKim Phillips 34264b992628SKim Phillips atomic_set(&priv->chan[i].submit_count, 34274b992628SKim Phillips -(priv->chfifo_len - 1)); 3428f641ddddSMartin Hicks } 34299c4a7965SKim Phillips 343081eb024cSKim Phillips dma_set_mask(dev, DMA_BIT_MASK(36)); 343181eb024cSKim Phillips 34329c4a7965SKim Phillips /* reset and initialize the h/w */ 34339c4a7965SKim Phillips err = init_device(dev); 34349c4a7965SKim Phillips if (err) { 34359c4a7965SKim Phillips dev_err(dev, "failed to initialize device\n"); 34369c4a7965SKim Phillips goto err_out; 34379c4a7965SKim Phillips } 34389c4a7965SKim Phillips 34399c4a7965SKim Phillips /* register the RNG, if available */ 34409c4a7965SKim Phillips if (hw_supports(dev, DESC_HDR_SEL0_RNG)) { 34419c4a7965SKim Phillips err = talitos_register_rng(dev); 34429c4a7965SKim Phillips if (err) { 34439c4a7965SKim Phillips dev_err(dev, "failed to register hwrng: %d\n", err); 34449c4a7965SKim Phillips goto err_out; 34459c4a7965SKim Phillips } else 34469c4a7965SKim Phillips dev_info(dev, "hwrng\n"); 34479c4a7965SKim Phillips } 34489c4a7965SKim Phillips 34499c4a7965SKim Phillips /* register crypto algorithms the device supports */ 34509c4a7965SKim Phillips for (i = 0; i < ARRAY_SIZE(driver_algs); i++) { 34519c4a7965SKim Phillips if (hw_supports(dev, driver_algs[i].desc_hdr_template)) { 34529c4a7965SKim Phillips struct talitos_crypto_alg *t_alg; 3453aeb4c132SHerbert Xu struct crypto_alg *alg = NULL; 34549c4a7965SKim Phillips 34559c4a7965SKim Phillips t_alg = talitos_alg_alloc(dev, &driver_algs[i]); 34569c4a7965SKim Phillips if (IS_ERR(t_alg)) { 34579c4a7965SKim Phillips err = PTR_ERR(t_alg); 34580b2730d8SKim Phillips if (err == -ENOTSUPP) 345979b3a418SLee Nipper continue; 34609c4a7965SKim Phillips goto err_out; 34619c4a7965SKim Phillips } 34629c4a7965SKim Phillips 3463acbf7c62SLee Nipper switch (t_alg->algt.type) { 3464acbf7c62SLee Nipper case CRYPTO_ALG_TYPE_ABLKCIPHER: 3465acbf7c62SLee Nipper err = crypto_register_alg( 3466acbf7c62SLee Nipper &t_alg->algt.alg.crypto); 3467aeb4c132SHerbert Xu alg = &t_alg->algt.alg.crypto; 3468acbf7c62SLee Nipper break; 3469aeb4c132SHerbert Xu 3470aeb4c132SHerbert Xu case CRYPTO_ALG_TYPE_AEAD: 3471aeb4c132SHerbert Xu err = crypto_register_aead( 3472aeb4c132SHerbert Xu &t_alg->algt.alg.aead); 3473aeb4c132SHerbert Xu alg = &t_alg->algt.alg.aead.base; 3474aeb4c132SHerbert Xu break; 3475aeb4c132SHerbert Xu 3476acbf7c62SLee Nipper case CRYPTO_ALG_TYPE_AHASH: 3477acbf7c62SLee Nipper err = crypto_register_ahash( 3478acbf7c62SLee Nipper &t_alg->algt.alg.hash); 3479aeb4c132SHerbert Xu alg = &t_alg->algt.alg.hash.halg.base; 3480acbf7c62SLee Nipper break; 3481acbf7c62SLee Nipper } 34829c4a7965SKim Phillips if (err) { 34839c4a7965SKim Phillips dev_err(dev, "%s alg registration failed\n", 3484aeb4c132SHerbert Xu alg->cra_driver_name); 348524b92ff2SLEROY Christophe devm_kfree(dev, t_alg); 3486991155baSHoria Geanta } else 34879c4a7965SKim Phillips list_add_tail(&t_alg->entry, &priv->alg_list); 34889c4a7965SKim Phillips } 34899c4a7965SKim Phillips } 34905b859b6eSKim Phillips if (!list_empty(&priv->alg_list)) 34915b859b6eSKim Phillips dev_info(dev, "%s algorithms registered in /proc/crypto\n", 34925b859b6eSKim Phillips (char *)of_get_property(np, "compatible", NULL)); 34939c4a7965SKim Phillips 34949c4a7965SKim Phillips return 0; 34959c4a7965SKim Phillips 34969c4a7965SKim Phillips err_out: 34979c4a7965SKim Phillips talitos_remove(ofdev); 34989c4a7965SKim Phillips 34999c4a7965SKim Phillips return err; 35009c4a7965SKim Phillips } 35019c4a7965SKim Phillips 35026c3f975aSMárton Németh static const struct of_device_id talitos_match[] = { 35030635b7dbSLEROY Christophe #ifdef CONFIG_CRYPTO_DEV_TALITOS1 35040635b7dbSLEROY Christophe { 35050635b7dbSLEROY Christophe .compatible = "fsl,sec1.0", 35060635b7dbSLEROY Christophe }, 35070635b7dbSLEROY Christophe #endif 35080635b7dbSLEROY Christophe #ifdef CONFIG_CRYPTO_DEV_TALITOS2 35099c4a7965SKim Phillips { 35109c4a7965SKim Phillips .compatible = "fsl,sec2.0", 35119c4a7965SKim Phillips }, 35120635b7dbSLEROY Christophe #endif 35139c4a7965SKim Phillips {}, 35149c4a7965SKim Phillips }; 35159c4a7965SKim Phillips MODULE_DEVICE_TABLE(of, talitos_match); 35169c4a7965SKim Phillips 35171c48a5c9SGrant Likely static struct platform_driver talitos_driver = { 35184018294bSGrant Likely .driver = { 35199c4a7965SKim Phillips .name = "talitos", 35204018294bSGrant Likely .of_match_table = talitos_match, 35214018294bSGrant Likely }, 35229c4a7965SKim Phillips .probe = talitos_probe, 3523596f1034SAl Viro .remove = talitos_remove, 35249c4a7965SKim Phillips }; 35259c4a7965SKim Phillips 3526741e8c2dSAxel Lin module_platform_driver(talitos_driver); 35279c4a7965SKim Phillips 35289c4a7965SKim Phillips MODULE_LICENSE("GPL"); 35299c4a7965SKim Phillips MODULE_AUTHOR("Kim Phillips <kim.phillips@freescale.com>"); 35309c4a7965SKim Phillips MODULE_DESCRIPTION("Freescale integrated security engine (SEC) driver"); 3531