blob: 307d534a0f2ffcaae4f036f138528c7aabf00061 [file] [log] [blame]
Kim Phillips9c4a7962008-06-23 19:50:15 +08001/*
2 * talitos - Freescale Integrated Security Engine (SEC) device driver
3 *
Kim Phillips5228f0f2011-07-15 11:21:38 +08004 * Copyright (c) 2008-2011 Freescale Semiconductor, Inc.
Kim Phillips9c4a7962008-06-23 19:50:15 +08005 *
6 * Scatterlist Crypto API glue code copied from files with the following:
7 * Copyright (c) 2006-2007 Herbert Xu <herbert@gondor.apana.org.au>
8 *
9 * Crypto algorithm registration code copied from hifn driver:
10 * 2007+ Copyright (c) Evgeniy Polyakov <johnpol@2ka.mipt.ru>
11 * All rights reserved.
12 *
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2 of the License, or
16 * (at your option) any later version.
17 *
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
22 *
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, write to the Free Software
25 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
26 */
27
28#include <linux/kernel.h>
29#include <linux/module.h>
30#include <linux/mod_devicetable.h>
31#include <linux/device.h>
32#include <linux/interrupt.h>
33#include <linux/crypto.h>
34#include <linux/hw_random.h>
Rob Herring5af50732013-09-17 14:28:33 -050035#include <linux/of_address.h>
36#include <linux/of_irq.h>
Kim Phillips9c4a7962008-06-23 19:50:15 +080037#include <linux/of_platform.h>
38#include <linux/dma-mapping.h>
39#include <linux/io.h>
40#include <linux/spinlock.h>
41#include <linux/rtnetlink.h>
Tejun Heo5a0e3ad2010-03-24 17:04:11 +090042#include <linux/slab.h>
Kim Phillips9c4a7962008-06-23 19:50:15 +080043
44#include <crypto/algapi.h>
45#include <crypto/aes.h>
Lee Nipper3952f172008-07-10 18:29:18 +080046#include <crypto/des.h>
Kim Phillips9c4a7962008-06-23 19:50:15 +080047#include <crypto/sha.h>
Lee Nipper497f2e62010-05-19 19:20:36 +100048#include <crypto/md5.h>
Herbert Xue98014a2015-05-11 17:47:48 +080049#include <crypto/internal/aead.h>
Kim Phillips9c4a7962008-06-23 19:50:15 +080050#include <crypto/authenc.h>
Lee Nipper4de9d0b2009-03-29 15:52:32 +080051#include <crypto/skcipher.h>
Lee Nipperacbf7c622010-05-19 19:19:33 +100052#include <crypto/hash.h>
53#include <crypto/internal/hash.h>
Lee Nipper4de9d0b2009-03-29 15:52:32 +080054#include <crypto/scatterwalk.h>
Kim Phillips9c4a7962008-06-23 19:50:15 +080055
56#include "talitos.h"
57
LEROY Christophe922f9dc2015-04-17 16:32:07 +020058static void to_talitos_ptr(struct talitos_ptr *ptr, dma_addr_t dma_addr,
LEROY Christopheda9de142017-10-06 15:04:57 +020059 unsigned int len, bool is_sec1)
Kim Phillips81eb0242009-08-13 11:51:51 +100060{
LEROY Christopheedc6bd62015-04-17 16:31:53 +020061 ptr->ptr = cpu_to_be32(lower_32_bits(dma_addr));
LEROY Christopheda9de142017-10-06 15:04:57 +020062 if (is_sec1) {
63 ptr->len1 = cpu_to_be16(len);
64 } else {
65 ptr->len = cpu_to_be16(len);
LEROY Christophe922f9dc2015-04-17 16:32:07 +020066 ptr->eptr = upper_32_bits(dma_addr);
LEROY Christopheda9de142017-10-06 15:04:57 +020067 }
Kim Phillips81eb0242009-08-13 11:51:51 +100068}
69
Horia Geant?340ff602016-04-19 20:33:48 +030070static void copy_talitos_ptr(struct talitos_ptr *dst_ptr,
71 struct talitos_ptr *src_ptr, bool is_sec1)
72{
73 dst_ptr->ptr = src_ptr->ptr;
LEROY Christophe922f9dc2015-04-17 16:32:07 +020074 if (is_sec1) {
LEROY Christopheda9de142017-10-06 15:04:57 +020075 dst_ptr->len1 = src_ptr->len1;
LEROY Christophe922f9dc2015-04-17 16:32:07 +020076 } else {
LEROY Christopheda9de142017-10-06 15:04:57 +020077 dst_ptr->len = src_ptr->len;
78 dst_ptr->eptr = src_ptr->eptr;
LEROY Christophe922f9dc2015-04-17 16:32:07 +020079 }
LEROY Christophe538caf82015-04-17 16:31:59 +020080}
81
LEROY Christophe922f9dc2015-04-17 16:32:07 +020082static unsigned short from_talitos_ptr_len(struct talitos_ptr *ptr,
83 bool is_sec1)
LEROY Christophe538caf82015-04-17 16:31:59 +020084{
LEROY Christophe922f9dc2015-04-17 16:32:07 +020085 if (is_sec1)
86 return be16_to_cpu(ptr->len1);
87 else
88 return be16_to_cpu(ptr->len);
LEROY Christophe538caf82015-04-17 16:31:59 +020089}
90
LEROY Christopheb096b542016-06-06 13:20:34 +020091static void to_talitos_ptr_ext_set(struct talitos_ptr *ptr, u8 val,
92 bool is_sec1)
LEROY Christophe185eb792015-04-17 16:31:55 +020093{
LEROY Christophe922f9dc2015-04-17 16:32:07 +020094 if (!is_sec1)
LEROY Christopheb096b542016-06-06 13:20:34 +020095 ptr->j_extent = val;
96}
97
98static void to_talitos_ptr_ext_or(struct talitos_ptr *ptr, u8 val, bool is_sec1)
99{
100 if (!is_sec1)
101 ptr->j_extent |= val;
LEROY Christophe185eb792015-04-17 16:31:55 +0200102}
103
Kim Phillips9c4a7962008-06-23 19:50:15 +0800104/*
105 * map virtual single (contiguous) pointer to h/w descriptor pointer
106 */
107static void map_single_talitos_ptr(struct device *dev,
LEROY Christopheedc6bd62015-04-17 16:31:53 +0200108 struct talitos_ptr *ptr,
Horia Geant?42e8b0d2015-05-11 20:04:56 +0300109 unsigned int len, void *data,
Kim Phillips9c4a7962008-06-23 19:50:15 +0800110 enum dma_data_direction dir)
111{
Kim Phillips81eb0242009-08-13 11:51:51 +1000112 dma_addr_t dma_addr = dma_map_single(dev, data, len, dir);
LEROY Christophe922f9dc2015-04-17 16:32:07 +0200113 struct talitos_private *priv = dev_get_drvdata(dev);
114 bool is_sec1 = has_ftr_sec1(priv);
Kim Phillips81eb0242009-08-13 11:51:51 +1000115
LEROY Christopheda9de142017-10-06 15:04:57 +0200116 to_talitos_ptr(ptr, dma_addr, len, is_sec1);
Kim Phillips9c4a7962008-06-23 19:50:15 +0800117}
118
119/*
120 * unmap bus single (contiguous) h/w descriptor pointer
121 */
122static void unmap_single_talitos_ptr(struct device *dev,
LEROY Christopheedc6bd62015-04-17 16:31:53 +0200123 struct talitos_ptr *ptr,
Kim Phillips9c4a7962008-06-23 19:50:15 +0800124 enum dma_data_direction dir)
125{
LEROY Christophe922f9dc2015-04-17 16:32:07 +0200126 struct talitos_private *priv = dev_get_drvdata(dev);
127 bool is_sec1 = has_ftr_sec1(priv);
128
LEROY Christopheedc6bd62015-04-17 16:31:53 +0200129 dma_unmap_single(dev, be32_to_cpu(ptr->ptr),
LEROY Christophe922f9dc2015-04-17 16:32:07 +0200130 from_talitos_ptr_len(ptr, is_sec1), dir);
Kim Phillips9c4a7962008-06-23 19:50:15 +0800131}
132
133static int reset_channel(struct device *dev, int ch)
134{
135 struct talitos_private *priv = dev_get_drvdata(dev);
136 unsigned int timeout = TALITOS_TIMEOUT;
LEROY Christophedd3c0982015-04-17 16:32:13 +0200137 bool is_sec1 = has_ftr_sec1(priv);
Kim Phillips9c4a7962008-06-23 19:50:15 +0800138
LEROY Christophedd3c0982015-04-17 16:32:13 +0200139 if (is_sec1) {
140 setbits32(priv->chan[ch].reg + TALITOS_CCCR_LO,
141 TALITOS1_CCCR_LO_RESET);
Kim Phillips9c4a7962008-06-23 19:50:15 +0800142
LEROY Christophedd3c0982015-04-17 16:32:13 +0200143 while ((in_be32(priv->chan[ch].reg + TALITOS_CCCR_LO) &
144 TALITOS1_CCCR_LO_RESET) && --timeout)
145 cpu_relax();
146 } else {
147 setbits32(priv->chan[ch].reg + TALITOS_CCCR,
148 TALITOS2_CCCR_RESET);
149
150 while ((in_be32(priv->chan[ch].reg + TALITOS_CCCR) &
151 TALITOS2_CCCR_RESET) && --timeout)
152 cpu_relax();
153 }
Kim Phillips9c4a7962008-06-23 19:50:15 +0800154
155 if (timeout == 0) {
156 dev_err(dev, "failed to reset channel %d\n", ch);
157 return -EIO;
158 }
159
Kim Phillips81eb0242009-08-13 11:51:51 +1000160 /* set 36-bit addressing, done writeback enable and done IRQ enable */
Kim Phillipsad42d5f2011-11-21 16:13:27 +0800161 setbits32(priv->chan[ch].reg + TALITOS_CCCR_LO, TALITOS_CCCR_LO_EAE |
Kim Phillips81eb0242009-08-13 11:51:51 +1000162 TALITOS_CCCR_LO_CDWE | TALITOS_CCCR_LO_CDIE);
Kim Phillips9c4a7962008-06-23 19:50:15 +0800163
Kim Phillipsfe5720e2008-10-12 20:33:14 +0800164 /* and ICCR writeback, if available */
165 if (priv->features & TALITOS_FTR_HW_AUTH_CHECK)
Kim Phillipsad42d5f2011-11-21 16:13:27 +0800166 setbits32(priv->chan[ch].reg + TALITOS_CCCR_LO,
Kim Phillipsfe5720e2008-10-12 20:33:14 +0800167 TALITOS_CCCR_LO_IWSE);
168
Kim Phillips9c4a7962008-06-23 19:50:15 +0800169 return 0;
170}
171
172static int reset_device(struct device *dev)
173{
174 struct talitos_private *priv = dev_get_drvdata(dev);
175 unsigned int timeout = TALITOS_TIMEOUT;
LEROY Christophedd3c0982015-04-17 16:32:13 +0200176 bool is_sec1 = has_ftr_sec1(priv);
177 u32 mcr = is_sec1 ? TALITOS1_MCR_SWR : TALITOS2_MCR_SWR;
Kim Phillips9c4a7962008-06-23 19:50:15 +0800178
Kim Phillipsc3e337f2011-11-21 16:13:27 +0800179 setbits32(priv->reg + TALITOS_MCR, mcr);
Kim Phillips9c4a7962008-06-23 19:50:15 +0800180
LEROY Christophedd3c0982015-04-17 16:32:13 +0200181 while ((in_be32(priv->reg + TALITOS_MCR) & mcr)
Kim Phillips9c4a7962008-06-23 19:50:15 +0800182 && --timeout)
183 cpu_relax();
184
Kim Phillips2cdba3c2011-12-12 14:59:11 -0600185 if (priv->irq[1]) {
Kim Phillipsc3e337f2011-11-21 16:13:27 +0800186 mcr = TALITOS_MCR_RCA1 | TALITOS_MCR_RCA3;
187 setbits32(priv->reg + TALITOS_MCR, mcr);
188 }
189
Kim Phillips9c4a7962008-06-23 19:50:15 +0800190 if (timeout == 0) {
191 dev_err(dev, "failed to reset device\n");
192 return -EIO;
193 }
194
195 return 0;
196}
197
198/*
199 * Reset and initialize the device
200 */
201static int init_device(struct device *dev)
202{
203 struct talitos_private *priv = dev_get_drvdata(dev);
204 int ch, err;
LEROY Christophedd3c0982015-04-17 16:32:13 +0200205 bool is_sec1 = has_ftr_sec1(priv);
Kim Phillips9c4a7962008-06-23 19:50:15 +0800206
207 /*
208 * Master reset
209 * errata documentation: warning: certain SEC interrupts
210 * are not fully cleared by writing the MCR:SWR bit,
211 * set bit twice to completely reset
212 */
213 err = reset_device(dev);
214 if (err)
215 return err;
216
217 err = reset_device(dev);
218 if (err)
219 return err;
220
221 /* reset channels */
222 for (ch = 0; ch < priv->num_channels; ch++) {
223 err = reset_channel(dev, ch);
224 if (err)
225 return err;
226 }
227
228 /* enable channel done and error interrupts */
LEROY Christophedd3c0982015-04-17 16:32:13 +0200229 if (is_sec1) {
230 clrbits32(priv->reg + TALITOS_IMR, TALITOS1_IMR_INIT);
231 clrbits32(priv->reg + TALITOS_IMR_LO, TALITOS1_IMR_LO_INIT);
232 /* disable parity error check in DEU (erroneous? test vect.) */
233 setbits32(priv->reg_deu + TALITOS_EUICR, TALITOS1_DEUICR_KPE);
234 } else {
235 setbits32(priv->reg + TALITOS_IMR, TALITOS2_IMR_INIT);
236 setbits32(priv->reg + TALITOS_IMR_LO, TALITOS2_IMR_LO_INIT);
237 }
Kim Phillips9c4a7962008-06-23 19:50:15 +0800238
Kim Phillipsfe5720e2008-10-12 20:33:14 +0800239 /* disable integrity check error interrupts (use writeback instead) */
240 if (priv->features & TALITOS_FTR_HW_AUTH_CHECK)
LEROY Christophe5fa7fa12015-04-17 16:32:11 +0200241 setbits32(priv->reg_mdeu + TALITOS_EUICR_LO,
Kim Phillipsfe5720e2008-10-12 20:33:14 +0800242 TALITOS_MDEUICR_LO_ICE);
243
Kim Phillips9c4a7962008-06-23 19:50:15 +0800244 return 0;
245}
246
247/**
248 * talitos_submit - submits a descriptor to the device for processing
249 * @dev: the SEC device to be used
Kim Phillips5228f0f2011-07-15 11:21:38 +0800250 * @ch: the SEC device channel to be used
Kim Phillips9c4a7962008-06-23 19:50:15 +0800251 * @desc: the descriptor to be processed by the device
252 * @callback: whom to call when processing is complete
253 * @context: a handle for use by caller (optional)
254 *
255 * desc must contain valid dma-mapped (bus physical) address pointers.
256 * callback must check err and feedback in descriptor header
257 * for device processing status.
258 */
Horia Geanta865d5062012-07-03 19:16:52 +0300259int talitos_submit(struct device *dev, int ch, struct talitos_desc *desc,
260 void (*callback)(struct device *dev,
261 struct talitos_desc *desc,
262 void *context, int error),
263 void *context)
Kim Phillips9c4a7962008-06-23 19:50:15 +0800264{
265 struct talitos_private *priv = dev_get_drvdata(dev);
266 struct talitos_request *request;
Kim Phillips5228f0f2011-07-15 11:21:38 +0800267 unsigned long flags;
Kim Phillips9c4a7962008-06-23 19:50:15 +0800268 int head;
LEROY Christophe7d607c6a2015-04-17 16:32:09 +0200269 bool is_sec1 = has_ftr_sec1(priv);
Kim Phillips9c4a7962008-06-23 19:50:15 +0800270
Kim Phillips4b9926282009-08-13 11:50:38 +1000271 spin_lock_irqsave(&priv->chan[ch].head_lock, flags);
Kim Phillips9c4a7962008-06-23 19:50:15 +0800272
Kim Phillips4b9926282009-08-13 11:50:38 +1000273 if (!atomic_inc_not_zero(&priv->chan[ch].submit_count)) {
Kim Phillipsec6644d2008-07-17 20:16:40 +0800274 /* h/w fifo is full */
Kim Phillips4b9926282009-08-13 11:50:38 +1000275 spin_unlock_irqrestore(&priv->chan[ch].head_lock, flags);
Kim Phillips9c4a7962008-06-23 19:50:15 +0800276 return -EAGAIN;
277 }
278
Kim Phillips4b9926282009-08-13 11:50:38 +1000279 head = priv->chan[ch].head;
280 request = &priv->chan[ch].fifo[head];
Kim Phillipsec6644d2008-07-17 20:16:40 +0800281
Kim Phillips9c4a7962008-06-23 19:50:15 +0800282 /* map descriptor and save caller data */
LEROY Christophe7d607c6a2015-04-17 16:32:09 +0200283 if (is_sec1) {
284 desc->hdr1 = desc->hdr;
LEROY Christophe7d607c6a2015-04-17 16:32:09 +0200285 request->dma_desc = dma_map_single(dev, &desc->hdr1,
286 TALITOS_DESC_SIZE,
287 DMA_BIDIRECTIONAL);
288 } else {
289 request->dma_desc = dma_map_single(dev, desc,
290 TALITOS_DESC_SIZE,
291 DMA_BIDIRECTIONAL);
292 }
Kim Phillips9c4a7962008-06-23 19:50:15 +0800293 request->callback = callback;
294 request->context = context;
295
296 /* increment fifo head */
Kim Phillips4b9926282009-08-13 11:50:38 +1000297 priv->chan[ch].head = (priv->chan[ch].head + 1) & (priv->fifo_len - 1);
Kim Phillips9c4a7962008-06-23 19:50:15 +0800298
299 smp_wmb();
300 request->desc = desc;
301
302 /* GO! */
303 wmb();
Kim Phillipsad42d5f2011-11-21 16:13:27 +0800304 out_be32(priv->chan[ch].reg + TALITOS_FF,
305 upper_32_bits(request->dma_desc));
306 out_be32(priv->chan[ch].reg + TALITOS_FF_LO,
Kim Phillipsa7524472010-09-23 15:56:38 +0800307 lower_32_bits(request->dma_desc));
Kim Phillips9c4a7962008-06-23 19:50:15 +0800308
Kim Phillips4b9926282009-08-13 11:50:38 +1000309 spin_unlock_irqrestore(&priv->chan[ch].head_lock, flags);
Kim Phillips9c4a7962008-06-23 19:50:15 +0800310
311 return -EINPROGRESS;
312}
Horia Geanta865d5062012-07-03 19:16:52 +0300313EXPORT_SYMBOL(talitos_submit);
Kim Phillips9c4a7962008-06-23 19:50:15 +0800314
315/*
316 * process what was done, notify callback of error if not
317 */
318static void flush_channel(struct device *dev, int ch, int error, int reset_ch)
319{
320 struct talitos_private *priv = dev_get_drvdata(dev);
321 struct talitos_request *request, saved_req;
322 unsigned long flags;
323 int tail, status;
LEROY Christophe7d607c6a2015-04-17 16:32:09 +0200324 bool is_sec1 = has_ftr_sec1(priv);
Kim Phillips9c4a7962008-06-23 19:50:15 +0800325
Kim Phillips4b9926282009-08-13 11:50:38 +1000326 spin_lock_irqsave(&priv->chan[ch].tail_lock, flags);
Kim Phillips9c4a7962008-06-23 19:50:15 +0800327
Kim Phillips4b9926282009-08-13 11:50:38 +1000328 tail = priv->chan[ch].tail;
329 while (priv->chan[ch].fifo[tail].desc) {
LEROY Christophe7d607c6a2015-04-17 16:32:09 +0200330 __be32 hdr;
331
Kim Phillips4b9926282009-08-13 11:50:38 +1000332 request = &priv->chan[ch].fifo[tail];
Kim Phillips9c4a7962008-06-23 19:50:15 +0800333
334 /* descriptors with their done bits set don't get the error */
335 rmb();
LEROY Christophe7d607c6a2015-04-17 16:32:09 +0200336 hdr = is_sec1 ? request->desc->hdr1 : request->desc->hdr;
337
338 if ((hdr & DESC_HDR_DONE) == DESC_HDR_DONE)
Kim Phillips9c4a7962008-06-23 19:50:15 +0800339 status = 0;
Lee Nipperca38a812008-12-20 17:09:25 +1100340 else
Kim Phillips9c4a7962008-06-23 19:50:15 +0800341 if (!error)
342 break;
343 else
344 status = error;
345
346 dma_unmap_single(dev, request->dma_desc,
LEROY Christophe7d607c6a2015-04-17 16:32:09 +0200347 TALITOS_DESC_SIZE,
Kim Phillipse938e462009-03-29 15:53:23 +0800348 DMA_BIDIRECTIONAL);
Kim Phillips9c4a7962008-06-23 19:50:15 +0800349
350 /* copy entries so we can call callback outside lock */
351 saved_req.desc = request->desc;
352 saved_req.callback = request->callback;
353 saved_req.context = request->context;
354
355 /* release request entry in fifo */
356 smp_wmb();
357 request->desc = NULL;
358
359 /* increment fifo tail */
Kim Phillips4b9926282009-08-13 11:50:38 +1000360 priv->chan[ch].tail = (tail + 1) & (priv->fifo_len - 1);
Kim Phillips9c4a7962008-06-23 19:50:15 +0800361
Kim Phillips4b9926282009-08-13 11:50:38 +1000362 spin_unlock_irqrestore(&priv->chan[ch].tail_lock, flags);
Kim Phillipsec6644d2008-07-17 20:16:40 +0800363
Kim Phillips4b9926282009-08-13 11:50:38 +1000364 atomic_dec(&priv->chan[ch].submit_count);
Kim Phillipsec6644d2008-07-17 20:16:40 +0800365
Kim Phillips9c4a7962008-06-23 19:50:15 +0800366 saved_req.callback(dev, saved_req.desc, saved_req.context,
367 status);
368 /* channel may resume processing in single desc error case */
369 if (error && !reset_ch && status == error)
370 return;
Kim Phillips4b9926282009-08-13 11:50:38 +1000371 spin_lock_irqsave(&priv->chan[ch].tail_lock, flags);
372 tail = priv->chan[ch].tail;
Kim Phillips9c4a7962008-06-23 19:50:15 +0800373 }
374
Kim Phillips4b9926282009-08-13 11:50:38 +1000375 spin_unlock_irqrestore(&priv->chan[ch].tail_lock, flags);
Kim Phillips9c4a7962008-06-23 19:50:15 +0800376}
377
378/*
379 * process completed requests for channels that have done status
380 */
LEROY Christophedd3c0982015-04-17 16:32:13 +0200381#define DEF_TALITOS1_DONE(name, ch_done_mask) \
382static void talitos1_done_##name(unsigned long data) \
383{ \
384 struct device *dev = (struct device *)data; \
385 struct talitos_private *priv = dev_get_drvdata(dev); \
386 unsigned long flags; \
387 \
388 if (ch_done_mask & 0x10000000) \
389 flush_channel(dev, 0, 0, 0); \
LEROY Christophedd3c0982015-04-17 16:32:13 +0200390 if (ch_done_mask & 0x40000000) \
391 flush_channel(dev, 1, 0, 0); \
392 if (ch_done_mask & 0x00010000) \
393 flush_channel(dev, 2, 0, 0); \
394 if (ch_done_mask & 0x00040000) \
395 flush_channel(dev, 3, 0, 0); \
396 \
LEROY Christophedd3c0982015-04-17 16:32:13 +0200397 /* At this point, all completed channels have been processed */ \
398 /* Unmask done interrupts for channels completed later on. */ \
399 spin_lock_irqsave(&priv->reg_lock, flags); \
400 clrbits32(priv->reg + TALITOS_IMR, ch_done_mask); \
401 clrbits32(priv->reg + TALITOS_IMR_LO, TALITOS1_IMR_LO_INIT); \
402 spin_unlock_irqrestore(&priv->reg_lock, flags); \
403}
404
405DEF_TALITOS1_DONE(4ch, TALITOS1_ISR_4CHDONE)
LEROY Christophe9c02e282017-10-06 15:04:55 +0200406DEF_TALITOS1_DONE(ch0, TALITOS1_ISR_CH_0_DONE)
LEROY Christophedd3c0982015-04-17 16:32:13 +0200407
408#define DEF_TALITOS2_DONE(name, ch_done_mask) \
409static void talitos2_done_##name(unsigned long data) \
Kim Phillipsc3e337f2011-11-21 16:13:27 +0800410{ \
411 struct device *dev = (struct device *)data; \
412 struct talitos_private *priv = dev_get_drvdata(dev); \
Horia Geanta511d63c2012-03-30 17:49:53 +0300413 unsigned long flags; \
Kim Phillipsc3e337f2011-11-21 16:13:27 +0800414 \
415 if (ch_done_mask & 1) \
416 flush_channel(dev, 0, 0, 0); \
Kim Phillipsc3e337f2011-11-21 16:13:27 +0800417 if (ch_done_mask & (1 << 2)) \
418 flush_channel(dev, 1, 0, 0); \
419 if (ch_done_mask & (1 << 4)) \
420 flush_channel(dev, 2, 0, 0); \
421 if (ch_done_mask & (1 << 6)) \
422 flush_channel(dev, 3, 0, 0); \
423 \
Kim Phillipsc3e337f2011-11-21 16:13:27 +0800424 /* At this point, all completed channels have been processed */ \
425 /* Unmask done interrupts for channels completed later on. */ \
Horia Geanta511d63c2012-03-30 17:49:53 +0300426 spin_lock_irqsave(&priv->reg_lock, flags); \
Kim Phillipsc3e337f2011-11-21 16:13:27 +0800427 setbits32(priv->reg + TALITOS_IMR, ch_done_mask); \
LEROY Christophedd3c0982015-04-17 16:32:13 +0200428 setbits32(priv->reg + TALITOS_IMR_LO, TALITOS2_IMR_LO_INIT); \
Horia Geanta511d63c2012-03-30 17:49:53 +0300429 spin_unlock_irqrestore(&priv->reg_lock, flags); \
Kim Phillips9c4a7962008-06-23 19:50:15 +0800430}
LEROY Christophedd3c0982015-04-17 16:32:13 +0200431
432DEF_TALITOS2_DONE(4ch, TALITOS2_ISR_4CHDONE)
LEROY Christophe9c02e282017-10-06 15:04:55 +0200433DEF_TALITOS2_DONE(ch0, TALITOS2_ISR_CH_0_DONE)
LEROY Christophedd3c0982015-04-17 16:32:13 +0200434DEF_TALITOS2_DONE(ch0_2, TALITOS2_ISR_CH_0_2_DONE)
435DEF_TALITOS2_DONE(ch1_3, TALITOS2_ISR_CH_1_3_DONE)
Kim Phillips9c4a7962008-06-23 19:50:15 +0800436
437/*
438 * locate current (offending) descriptor
439 */
Kim Phillips3e721ae2011-10-21 15:20:28 +0200440static u32 current_desc_hdr(struct device *dev, int ch)
Kim Phillips9c4a7962008-06-23 19:50:15 +0800441{
442 struct talitos_private *priv = dev_get_drvdata(dev);
Horia Geantab62ffd82013-11-13 12:20:37 +0200443 int tail, iter;
Kim Phillips9c4a7962008-06-23 19:50:15 +0800444 dma_addr_t cur_desc;
445
Horia Geantab62ffd82013-11-13 12:20:37 +0200446 cur_desc = ((u64)in_be32(priv->chan[ch].reg + TALITOS_CDPR)) << 32;
447 cur_desc |= in_be32(priv->chan[ch].reg + TALITOS_CDPR_LO);
Kim Phillips9c4a7962008-06-23 19:50:15 +0800448
Horia Geantab62ffd82013-11-13 12:20:37 +0200449 if (!cur_desc) {
450 dev_err(dev, "CDPR is NULL, giving up search for offending descriptor\n");
451 return 0;
452 }
453
454 tail = priv->chan[ch].tail;
455
456 iter = tail;
457 while (priv->chan[ch].fifo[iter].dma_desc != cur_desc) {
458 iter = (iter + 1) & (priv->fifo_len - 1);
459 if (iter == tail) {
Kim Phillips9c4a7962008-06-23 19:50:15 +0800460 dev_err(dev, "couldn't locate current descriptor\n");
Kim Phillips3e721ae2011-10-21 15:20:28 +0200461 return 0;
Kim Phillips9c4a7962008-06-23 19:50:15 +0800462 }
463 }
464
Horia Geantab62ffd82013-11-13 12:20:37 +0200465 return priv->chan[ch].fifo[iter].desc->hdr;
Kim Phillips9c4a7962008-06-23 19:50:15 +0800466}
467
468/*
469 * user diagnostics; report root cause of error based on execution unit status
470 */
Kim Phillips3e721ae2011-10-21 15:20:28 +0200471static void report_eu_error(struct device *dev, int ch, u32 desc_hdr)
Kim Phillips9c4a7962008-06-23 19:50:15 +0800472{
473 struct talitos_private *priv = dev_get_drvdata(dev);
474 int i;
475
Kim Phillips3e721ae2011-10-21 15:20:28 +0200476 if (!desc_hdr)
Kim Phillipsad42d5f2011-11-21 16:13:27 +0800477 desc_hdr = in_be32(priv->chan[ch].reg + TALITOS_DESCBUF);
Kim Phillips3e721ae2011-10-21 15:20:28 +0200478
479 switch (desc_hdr & DESC_HDR_SEL0_MASK) {
Kim Phillips9c4a7962008-06-23 19:50:15 +0800480 case DESC_HDR_SEL0_AFEU:
481 dev_err(dev, "AFEUISR 0x%08x_%08x\n",
LEROY Christophe5fa7fa12015-04-17 16:32:11 +0200482 in_be32(priv->reg_afeu + TALITOS_EUISR),
483 in_be32(priv->reg_afeu + TALITOS_EUISR_LO));
Kim Phillips9c4a7962008-06-23 19:50:15 +0800484 break;
485 case DESC_HDR_SEL0_DEU:
486 dev_err(dev, "DEUISR 0x%08x_%08x\n",
LEROY Christophe5fa7fa12015-04-17 16:32:11 +0200487 in_be32(priv->reg_deu + TALITOS_EUISR),
488 in_be32(priv->reg_deu + TALITOS_EUISR_LO));
Kim Phillips9c4a7962008-06-23 19:50:15 +0800489 break;
490 case DESC_HDR_SEL0_MDEUA:
491 case DESC_HDR_SEL0_MDEUB:
492 dev_err(dev, "MDEUISR 0x%08x_%08x\n",
LEROY Christophe5fa7fa12015-04-17 16:32:11 +0200493 in_be32(priv->reg_mdeu + TALITOS_EUISR),
494 in_be32(priv->reg_mdeu + TALITOS_EUISR_LO));
Kim Phillips9c4a7962008-06-23 19:50:15 +0800495 break;
496 case DESC_HDR_SEL0_RNG:
497 dev_err(dev, "RNGUISR 0x%08x_%08x\n",
LEROY Christophe5fa7fa12015-04-17 16:32:11 +0200498 in_be32(priv->reg_rngu + TALITOS_ISR),
499 in_be32(priv->reg_rngu + TALITOS_ISR_LO));
Kim Phillips9c4a7962008-06-23 19:50:15 +0800500 break;
501 case DESC_HDR_SEL0_PKEU:
502 dev_err(dev, "PKEUISR 0x%08x_%08x\n",
LEROY Christophe5fa7fa12015-04-17 16:32:11 +0200503 in_be32(priv->reg_pkeu + TALITOS_EUISR),
504 in_be32(priv->reg_pkeu + TALITOS_EUISR_LO));
Kim Phillips9c4a7962008-06-23 19:50:15 +0800505 break;
506 case DESC_HDR_SEL0_AESU:
507 dev_err(dev, "AESUISR 0x%08x_%08x\n",
LEROY Christophe5fa7fa12015-04-17 16:32:11 +0200508 in_be32(priv->reg_aesu + TALITOS_EUISR),
509 in_be32(priv->reg_aesu + TALITOS_EUISR_LO));
Kim Phillips9c4a7962008-06-23 19:50:15 +0800510 break;
511 case DESC_HDR_SEL0_CRCU:
512 dev_err(dev, "CRCUISR 0x%08x_%08x\n",
LEROY Christophe5fa7fa12015-04-17 16:32:11 +0200513 in_be32(priv->reg_crcu + TALITOS_EUISR),
514 in_be32(priv->reg_crcu + TALITOS_EUISR_LO));
Kim Phillips9c4a7962008-06-23 19:50:15 +0800515 break;
516 case DESC_HDR_SEL0_KEU:
517 dev_err(dev, "KEUISR 0x%08x_%08x\n",
LEROY Christophe5fa7fa12015-04-17 16:32:11 +0200518 in_be32(priv->reg_pkeu + TALITOS_EUISR),
519 in_be32(priv->reg_pkeu + TALITOS_EUISR_LO));
Kim Phillips9c4a7962008-06-23 19:50:15 +0800520 break;
521 }
522
Kim Phillips3e721ae2011-10-21 15:20:28 +0200523 switch (desc_hdr & DESC_HDR_SEL1_MASK) {
Kim Phillips9c4a7962008-06-23 19:50:15 +0800524 case DESC_HDR_SEL1_MDEUA:
525 case DESC_HDR_SEL1_MDEUB:
526 dev_err(dev, "MDEUISR 0x%08x_%08x\n",
LEROY Christophe5fa7fa12015-04-17 16:32:11 +0200527 in_be32(priv->reg_mdeu + TALITOS_EUISR),
528 in_be32(priv->reg_mdeu + TALITOS_EUISR_LO));
Kim Phillips9c4a7962008-06-23 19:50:15 +0800529 break;
530 case DESC_HDR_SEL1_CRCU:
531 dev_err(dev, "CRCUISR 0x%08x_%08x\n",
LEROY Christophe5fa7fa12015-04-17 16:32:11 +0200532 in_be32(priv->reg_crcu + TALITOS_EUISR),
533 in_be32(priv->reg_crcu + TALITOS_EUISR_LO));
Kim Phillips9c4a7962008-06-23 19:50:15 +0800534 break;
535 }
536
537 for (i = 0; i < 8; i++)
538 dev_err(dev, "DESCBUF 0x%08x_%08x\n",
Kim Phillipsad42d5f2011-11-21 16:13:27 +0800539 in_be32(priv->chan[ch].reg + TALITOS_DESCBUF + 8*i),
540 in_be32(priv->chan[ch].reg + TALITOS_DESCBUF_LO + 8*i));
Kim Phillips9c4a7962008-06-23 19:50:15 +0800541}
542
543/*
544 * recover from error interrupts
545 */
Kim Phillips5e718a02011-12-12 14:59:12 -0600546static void talitos_error(struct device *dev, u32 isr, u32 isr_lo)
Kim Phillips9c4a7962008-06-23 19:50:15 +0800547{
Kim Phillips9c4a7962008-06-23 19:50:15 +0800548 struct talitos_private *priv = dev_get_drvdata(dev);
549 unsigned int timeout = TALITOS_TIMEOUT;
LEROY Christophedd3c0982015-04-17 16:32:13 +0200550 int ch, error, reset_dev = 0;
Horia Geant?42e8b0d2015-05-11 20:04:56 +0300551 u32 v_lo;
LEROY Christophedd3c0982015-04-17 16:32:13 +0200552 bool is_sec1 = has_ftr_sec1(priv);
553 int reset_ch = is_sec1 ? 1 : 0; /* only SEC2 supports continuation */
Kim Phillips9c4a7962008-06-23 19:50:15 +0800554
555 for (ch = 0; ch < priv->num_channels; ch++) {
556 /* skip channels without errors */
LEROY Christophedd3c0982015-04-17 16:32:13 +0200557 if (is_sec1) {
558 /* bits 29, 31, 17, 19 */
559 if (!(isr & (1 << (29 + (ch & 1) * 2 - (ch & 2) * 6))))
560 continue;
561 } else {
562 if (!(isr & (1 << (ch * 2 + 1))))
563 continue;
564 }
Kim Phillips9c4a7962008-06-23 19:50:15 +0800565
566 error = -EINVAL;
567
Kim Phillipsad42d5f2011-11-21 16:13:27 +0800568 v_lo = in_be32(priv->chan[ch].reg + TALITOS_CCPSR_LO);
Kim Phillips9c4a7962008-06-23 19:50:15 +0800569
570 if (v_lo & TALITOS_CCPSR_LO_DOF) {
571 dev_err(dev, "double fetch fifo overflow error\n");
572 error = -EAGAIN;
573 reset_ch = 1;
574 }
575 if (v_lo & TALITOS_CCPSR_LO_SOF) {
576 /* h/w dropped descriptor */
577 dev_err(dev, "single fetch fifo overflow error\n");
578 error = -EAGAIN;
579 }
580 if (v_lo & TALITOS_CCPSR_LO_MDTE)
581 dev_err(dev, "master data transfer error\n");
582 if (v_lo & TALITOS_CCPSR_LO_SGDLZ)
Colin Ian King4d9b3a52016-11-01 20:14:04 -0600583 dev_err(dev, is_sec1 ? "pointer not complete error\n"
LEROY Christophedd3c0982015-04-17 16:32:13 +0200584 : "s/g data length zero error\n");
Kim Phillips9c4a7962008-06-23 19:50:15 +0800585 if (v_lo & TALITOS_CCPSR_LO_FPZ)
LEROY Christophedd3c0982015-04-17 16:32:13 +0200586 dev_err(dev, is_sec1 ? "parity error\n"
587 : "fetch pointer zero error\n");
Kim Phillips9c4a7962008-06-23 19:50:15 +0800588 if (v_lo & TALITOS_CCPSR_LO_IDH)
589 dev_err(dev, "illegal descriptor header error\n");
590 if (v_lo & TALITOS_CCPSR_LO_IEU)
LEROY Christophedd3c0982015-04-17 16:32:13 +0200591 dev_err(dev, is_sec1 ? "static assignment error\n"
592 : "invalid exec unit error\n");
Kim Phillips9c4a7962008-06-23 19:50:15 +0800593 if (v_lo & TALITOS_CCPSR_LO_EU)
Kim Phillips3e721ae2011-10-21 15:20:28 +0200594 report_eu_error(dev, ch, current_desc_hdr(dev, ch));
LEROY Christophedd3c0982015-04-17 16:32:13 +0200595 if (!is_sec1) {
596 if (v_lo & TALITOS_CCPSR_LO_GB)
597 dev_err(dev, "gather boundary error\n");
598 if (v_lo & TALITOS_CCPSR_LO_GRL)
599 dev_err(dev, "gather return/length error\n");
600 if (v_lo & TALITOS_CCPSR_LO_SB)
601 dev_err(dev, "scatter boundary error\n");
602 if (v_lo & TALITOS_CCPSR_LO_SRL)
603 dev_err(dev, "scatter return/length error\n");
604 }
Kim Phillips9c4a7962008-06-23 19:50:15 +0800605
606 flush_channel(dev, ch, error, reset_ch);
607
608 if (reset_ch) {
609 reset_channel(dev, ch);
610 } else {
Kim Phillipsad42d5f2011-11-21 16:13:27 +0800611 setbits32(priv->chan[ch].reg + TALITOS_CCCR,
LEROY Christophedd3c0982015-04-17 16:32:13 +0200612 TALITOS2_CCCR_CONT);
Kim Phillipsad42d5f2011-11-21 16:13:27 +0800613 setbits32(priv->chan[ch].reg + TALITOS_CCCR_LO, 0);
614 while ((in_be32(priv->chan[ch].reg + TALITOS_CCCR) &
LEROY Christophedd3c0982015-04-17 16:32:13 +0200615 TALITOS2_CCCR_CONT) && --timeout)
Kim Phillips9c4a7962008-06-23 19:50:15 +0800616 cpu_relax();
617 if (timeout == 0) {
618 dev_err(dev, "failed to restart channel %d\n",
619 ch);
620 reset_dev = 1;
621 }
622 }
623 }
LEROY Christophedd3c0982015-04-17 16:32:13 +0200624 if (reset_dev || (is_sec1 && isr & ~TALITOS1_ISR_4CHERR) ||
625 (!is_sec1 && isr & ~TALITOS2_ISR_4CHERR) || isr_lo) {
626 if (is_sec1 && (isr_lo & TALITOS1_ISR_TEA_ERR))
627 dev_err(dev, "TEA error: ISR 0x%08x_%08x\n",
628 isr, isr_lo);
629 else
630 dev_err(dev, "done overflow, internal time out, or "
631 "rngu error: ISR 0x%08x_%08x\n", isr, isr_lo);
Kim Phillips9c4a7962008-06-23 19:50:15 +0800632
633 /* purge request queues */
634 for (ch = 0; ch < priv->num_channels; ch++)
635 flush_channel(dev, ch, -EIO, 1);
636
637 /* reset and reinitialize the device */
638 init_device(dev);
639 }
640}
641
LEROY Christophedd3c0982015-04-17 16:32:13 +0200642#define DEF_TALITOS1_INTERRUPT(name, ch_done_mask, ch_err_mask, tlet) \
643static irqreturn_t talitos1_interrupt_##name(int irq, void *data) \
644{ \
645 struct device *dev = data; \
646 struct talitos_private *priv = dev_get_drvdata(dev); \
647 u32 isr, isr_lo; \
648 unsigned long flags; \
649 \
650 spin_lock_irqsave(&priv->reg_lock, flags); \
651 isr = in_be32(priv->reg + TALITOS_ISR); \
652 isr_lo = in_be32(priv->reg + TALITOS_ISR_LO); \
653 /* Acknowledge interrupt */ \
654 out_be32(priv->reg + TALITOS_ICR, isr & (ch_done_mask | ch_err_mask)); \
655 out_be32(priv->reg + TALITOS_ICR_LO, isr_lo); \
656 \
657 if (unlikely(isr & ch_err_mask || isr_lo & TALITOS1_IMR_LO_INIT)) { \
658 spin_unlock_irqrestore(&priv->reg_lock, flags); \
659 talitos_error(dev, isr & ch_err_mask, isr_lo); \
660 } \
661 else { \
662 if (likely(isr & ch_done_mask)) { \
663 /* mask further done interrupts. */ \
664 setbits32(priv->reg + TALITOS_IMR, ch_done_mask); \
665 /* done_task will unmask done interrupts at exit */ \
666 tasklet_schedule(&priv->done_task[tlet]); \
667 } \
668 spin_unlock_irqrestore(&priv->reg_lock, flags); \
669 } \
670 \
671 return (isr & (ch_done_mask | ch_err_mask) || isr_lo) ? IRQ_HANDLED : \
672 IRQ_NONE; \
673}
674
675DEF_TALITOS1_INTERRUPT(4ch, TALITOS1_ISR_4CHDONE, TALITOS1_ISR_4CHERR, 0)
676
677#define DEF_TALITOS2_INTERRUPT(name, ch_done_mask, ch_err_mask, tlet) \
678static irqreturn_t talitos2_interrupt_##name(int irq, void *data) \
Kim Phillipsc3e337f2011-11-21 16:13:27 +0800679{ \
680 struct device *dev = data; \
681 struct talitos_private *priv = dev_get_drvdata(dev); \
682 u32 isr, isr_lo; \
Horia Geanta511d63c2012-03-30 17:49:53 +0300683 unsigned long flags; \
Kim Phillipsc3e337f2011-11-21 16:13:27 +0800684 \
Horia Geanta511d63c2012-03-30 17:49:53 +0300685 spin_lock_irqsave(&priv->reg_lock, flags); \
Kim Phillipsc3e337f2011-11-21 16:13:27 +0800686 isr = in_be32(priv->reg + TALITOS_ISR); \
687 isr_lo = in_be32(priv->reg + TALITOS_ISR_LO); \
688 /* Acknowledge interrupt */ \
689 out_be32(priv->reg + TALITOS_ICR, isr & (ch_done_mask | ch_err_mask)); \
690 out_be32(priv->reg + TALITOS_ICR_LO, isr_lo); \
691 \
Horia Geanta511d63c2012-03-30 17:49:53 +0300692 if (unlikely(isr & ch_err_mask || isr_lo)) { \
693 spin_unlock_irqrestore(&priv->reg_lock, flags); \
694 talitos_error(dev, isr & ch_err_mask, isr_lo); \
695 } \
696 else { \
Kim Phillipsc3e337f2011-11-21 16:13:27 +0800697 if (likely(isr & ch_done_mask)) { \
698 /* mask further done interrupts. */ \
699 clrbits32(priv->reg + TALITOS_IMR, ch_done_mask); \
700 /* done_task will unmask done interrupts at exit */ \
701 tasklet_schedule(&priv->done_task[tlet]); \
702 } \
Horia Geanta511d63c2012-03-30 17:49:53 +0300703 spin_unlock_irqrestore(&priv->reg_lock, flags); \
704 } \
Kim Phillipsc3e337f2011-11-21 16:13:27 +0800705 \
706 return (isr & (ch_done_mask | ch_err_mask) || isr_lo) ? IRQ_HANDLED : \
707 IRQ_NONE; \
Kim Phillips9c4a7962008-06-23 19:50:15 +0800708}
LEROY Christophedd3c0982015-04-17 16:32:13 +0200709
710DEF_TALITOS2_INTERRUPT(4ch, TALITOS2_ISR_4CHDONE, TALITOS2_ISR_4CHERR, 0)
711DEF_TALITOS2_INTERRUPT(ch0_2, TALITOS2_ISR_CH_0_2_DONE, TALITOS2_ISR_CH_0_2_ERR,
712 0)
713DEF_TALITOS2_INTERRUPT(ch1_3, TALITOS2_ISR_CH_1_3_DONE, TALITOS2_ISR_CH_1_3_ERR,
714 1)
Kim Phillips9c4a7962008-06-23 19:50:15 +0800715
716/*
717 * hwrng
718 */
719static int talitos_rng_data_present(struct hwrng *rng, int wait)
720{
721 struct device *dev = (struct device *)rng->priv;
722 struct talitos_private *priv = dev_get_drvdata(dev);
723 u32 ofl;
724 int i;
725
726 for (i = 0; i < 20; i++) {
LEROY Christophe5fa7fa12015-04-17 16:32:11 +0200727 ofl = in_be32(priv->reg_rngu + TALITOS_EUSR_LO) &
Kim Phillips9c4a7962008-06-23 19:50:15 +0800728 TALITOS_RNGUSR_LO_OFL;
729 if (ofl || !wait)
730 break;
731 udelay(10);
732 }
733
734 return !!ofl;
735}
736
737static int talitos_rng_data_read(struct hwrng *rng, u32 *data)
738{
739 struct device *dev = (struct device *)rng->priv;
740 struct talitos_private *priv = dev_get_drvdata(dev);
741
742 /* rng fifo requires 64-bit accesses */
LEROY Christophe5fa7fa12015-04-17 16:32:11 +0200743 *data = in_be32(priv->reg_rngu + TALITOS_EU_FIFO);
744 *data = in_be32(priv->reg_rngu + TALITOS_EU_FIFO_LO);
Kim Phillips9c4a7962008-06-23 19:50:15 +0800745
746 return sizeof(u32);
747}
748
749static int talitos_rng_init(struct hwrng *rng)
750{
751 struct device *dev = (struct device *)rng->priv;
752 struct talitos_private *priv = dev_get_drvdata(dev);
753 unsigned int timeout = TALITOS_TIMEOUT;
754
LEROY Christophe5fa7fa12015-04-17 16:32:11 +0200755 setbits32(priv->reg_rngu + TALITOS_EURCR_LO, TALITOS_RNGURCR_LO_SR);
756 while (!(in_be32(priv->reg_rngu + TALITOS_EUSR_LO)
757 & TALITOS_RNGUSR_LO_RD)
Kim Phillips9c4a7962008-06-23 19:50:15 +0800758 && --timeout)
759 cpu_relax();
760 if (timeout == 0) {
761 dev_err(dev, "failed to reset rng hw\n");
762 return -ENODEV;
763 }
764
765 /* start generating */
LEROY Christophe5fa7fa12015-04-17 16:32:11 +0200766 setbits32(priv->reg_rngu + TALITOS_EUDSR_LO, 0);
Kim Phillips9c4a7962008-06-23 19:50:15 +0800767
768 return 0;
769}
770
771static int talitos_register_rng(struct device *dev)
772{
773 struct talitos_private *priv = dev_get_drvdata(dev);
Aaron Sierra35a3bb32015-08-05 16:52:08 -0500774 int err;
Kim Phillips9c4a7962008-06-23 19:50:15 +0800775
776 priv->rng.name = dev_driver_string(dev),
777 priv->rng.init = talitos_rng_init,
778 priv->rng.data_present = talitos_rng_data_present,
779 priv->rng.data_read = talitos_rng_data_read,
780 priv->rng.priv = (unsigned long)dev;
781
Aaron Sierra35a3bb32015-08-05 16:52:08 -0500782 err = hwrng_register(&priv->rng);
783 if (!err)
784 priv->rng_registered = true;
785
786 return err;
Kim Phillips9c4a7962008-06-23 19:50:15 +0800787}
788
789static void talitos_unregister_rng(struct device *dev)
790{
791 struct talitos_private *priv = dev_get_drvdata(dev);
792
Aaron Sierra35a3bb32015-08-05 16:52:08 -0500793 if (!priv->rng_registered)
794 return;
795
Kim Phillips9c4a7962008-06-23 19:50:15 +0800796 hwrng_unregister(&priv->rng);
Aaron Sierra35a3bb32015-08-05 16:52:08 -0500797 priv->rng_registered = false;
Kim Phillips9c4a7962008-06-23 19:50:15 +0800798}
799
800/*
801 * crypto alg
802 */
803#define TALITOS_CRA_PRIORITY 3000
LEROY Christophe7405c8d2016-06-06 13:20:46 +0200804/*
805 * Defines a priority for doing AEAD with descriptors type
806 * HMAC_SNOOP_NO_AFEA (HSNA) instead of type IPSEC_ESP
807 */
808#define TALITOS_CRA_PRIORITY_AEAD_HSNA (TALITOS_CRA_PRIORITY - 1)
Martin Hicks03d2c512017-05-02 09:38:35 -0400809#define TALITOS_MAX_KEY_SIZE (AES_MAX_KEY_SIZE + SHA512_BLOCK_SIZE)
Lee Nipper3952f172008-07-10 18:29:18 +0800810#define TALITOS_MAX_IV_LENGTH 16 /* max of AES_BLOCK_SIZE, DES3_EDE_BLOCK_SIZE */
Lee Nipper70bcaca2008-07-03 19:08:46 +0800811
Kim Phillips9c4a7962008-06-23 19:50:15 +0800812struct talitos_ctx {
813 struct device *dev;
Kim Phillips5228f0f2011-07-15 11:21:38 +0800814 int ch;
Kim Phillips9c4a7962008-06-23 19:50:15 +0800815 __be32 desc_hdr_template;
816 u8 key[TALITOS_MAX_KEY_SIZE];
Lee Nipper70bcaca2008-07-03 19:08:46 +0800817 u8 iv[TALITOS_MAX_IV_LENGTH];
Kim Phillips9c4a7962008-06-23 19:50:15 +0800818 unsigned int keylen;
819 unsigned int enckeylen;
820 unsigned int authkeylen;
Kim Phillips9c4a7962008-06-23 19:50:15 +0800821};
822
Lee Nipper497f2e62010-05-19 19:20:36 +1000823#define HASH_MAX_BLOCK_SIZE SHA512_BLOCK_SIZE
824#define TALITOS_MDEU_MAX_CONTEXT_SIZE TALITOS_MDEU_CONTEXT_SIZE_SHA384_SHA512
825
826struct talitos_ahash_req_ctx {
Kim Phillips60f208d2010-05-19 19:21:53 +1000827 u32 hw_context[TALITOS_MDEU_MAX_CONTEXT_SIZE / sizeof(u32)];
Lee Nipper497f2e62010-05-19 19:20:36 +1000828 unsigned int hw_context_size;
829 u8 buf[HASH_MAX_BLOCK_SIZE];
830 u8 bufnext[HASH_MAX_BLOCK_SIZE];
Kim Phillips60f208d2010-05-19 19:21:53 +1000831 unsigned int swinit;
Lee Nipper497f2e62010-05-19 19:20:36 +1000832 unsigned int first;
833 unsigned int last;
834 unsigned int to_hash_later;
Horia Geant?42e8b0d2015-05-11 20:04:56 +0300835 unsigned int nbuf;
Lee Nipper497f2e62010-05-19 19:20:36 +1000836 struct scatterlist bufsl[2];
837 struct scatterlist *psrc;
838};
839
Horia Geant?3639ca82016-04-21 19:24:55 +0300840struct talitos_export_state {
841 u32 hw_context[TALITOS_MDEU_MAX_CONTEXT_SIZE / sizeof(u32)];
842 u8 buf[HASH_MAX_BLOCK_SIZE];
843 unsigned int swinit;
844 unsigned int first;
845 unsigned int last;
846 unsigned int to_hash_later;
847 unsigned int nbuf;
848};
849
Lee Nipper56af8cd2009-03-29 15:50:50 +0800850static int aead_setkey(struct crypto_aead *authenc,
851 const u8 *key, unsigned int keylen)
Kim Phillips9c4a7962008-06-23 19:50:15 +0800852{
853 struct talitos_ctx *ctx = crypto_aead_ctx(authenc);
Mathias Krausec306a982013-10-15 13:49:34 +0200854 struct crypto_authenc_keys keys;
Kim Phillips9c4a7962008-06-23 19:50:15 +0800855
Mathias Krausec306a982013-10-15 13:49:34 +0200856 if (crypto_authenc_extractkeys(&keys, key, keylen) != 0)
Kim Phillips9c4a7962008-06-23 19:50:15 +0800857 goto badkey;
858
Mathias Krausec306a982013-10-15 13:49:34 +0200859 if (keys.authkeylen + keys.enckeylen > TALITOS_MAX_KEY_SIZE)
Kim Phillips9c4a7962008-06-23 19:50:15 +0800860 goto badkey;
861
Mathias Krausec306a982013-10-15 13:49:34 +0200862 memcpy(ctx->key, keys.authkey, keys.authkeylen);
863 memcpy(&ctx->key[keys.authkeylen], keys.enckey, keys.enckeylen);
Kim Phillips9c4a7962008-06-23 19:50:15 +0800864
Mathias Krausec306a982013-10-15 13:49:34 +0200865 ctx->keylen = keys.authkeylen + keys.enckeylen;
866 ctx->enckeylen = keys.enckeylen;
867 ctx->authkeylen = keys.authkeylen;
Kim Phillips9c4a7962008-06-23 19:50:15 +0800868
869 return 0;
870
871badkey:
872 crypto_aead_set_flags(authenc, CRYPTO_TFM_RES_BAD_KEY_LEN);
873 return -EINVAL;
874}
875
876/*
Lee Nipper56af8cd2009-03-29 15:50:50 +0800877 * talitos_edesc - s/w-extended descriptor
Kim Phillips9c4a7962008-06-23 19:50:15 +0800878 * @src_nents: number of segments in input scatterlist
879 * @dst_nents: number of segments in output scatterlist
Herbert Xuaeb4c132015-07-30 17:53:22 +0800880 * @icv_ool: whether ICV is out-of-line
Horia Geanta79fd31d2012-08-02 17:16:40 +0300881 * @iv_dma: dma address of iv for checking continuity and link table
Kim Phillips9c4a7962008-06-23 19:50:15 +0800882 * @dma_len: length of dma mapped link_tbl space
LEROY Christophe6f65f6a2015-04-17 16:32:15 +0200883 * @dma_link_tbl: bus physical address of link_tbl/buf
Kim Phillips9c4a7962008-06-23 19:50:15 +0800884 * @desc: h/w descriptor
LEROY Christophe6f65f6a2015-04-17 16:32:15 +0200885 * @link_tbl: input and output h/w link tables (if {src,dst}_nents > 1) (SEC2)
886 * @buf: input and output buffeur (if {src,dst}_nents > 1) (SEC1)
Kim Phillips9c4a7962008-06-23 19:50:15 +0800887 *
888 * if decrypting (with authcheck), or either one of src_nents or dst_nents
889 * is greater than 1, an integrity check value is concatenated to the end
890 * of link_tbl data
891 */
Lee Nipper56af8cd2009-03-29 15:50:50 +0800892struct talitos_edesc {
Kim Phillips9c4a7962008-06-23 19:50:15 +0800893 int src_nents;
894 int dst_nents;
Herbert Xuaeb4c132015-07-30 17:53:22 +0800895 bool icv_ool;
Horia Geanta79fd31d2012-08-02 17:16:40 +0300896 dma_addr_t iv_dma;
Kim Phillips9c4a7962008-06-23 19:50:15 +0800897 int dma_len;
898 dma_addr_t dma_link_tbl;
899 struct talitos_desc desc;
LEROY Christophe6f65f6a2015-04-17 16:32:15 +0200900 union {
901 struct talitos_ptr link_tbl[0];
902 u8 buf[0];
903 };
Kim Phillips9c4a7962008-06-23 19:50:15 +0800904};
905
Lee Nipper4de9d0b2009-03-29 15:52:32 +0800906static void talitos_sg_unmap(struct device *dev,
907 struct talitos_edesc *edesc,
908 struct scatterlist *src,
LEROY Christophe6a1e8d12016-06-06 13:20:38 +0200909 struct scatterlist *dst,
910 unsigned int len, unsigned int offset)
LEROY Christophe246a87c2016-06-06 13:20:36 +0200911{
912 struct talitos_private *priv = dev_get_drvdata(dev);
913 bool is_sec1 = has_ftr_sec1(priv);
LEROY Christophe6a1e8d12016-06-06 13:20:38 +0200914 unsigned int src_nents = edesc->src_nents ? : 1;
915 unsigned int dst_nents = edesc->dst_nents ? : 1;
LEROY Christophe246a87c2016-06-06 13:20:36 +0200916
LEROY Christophe6a1e8d12016-06-06 13:20:38 +0200917 if (is_sec1 && dst && dst_nents > 1) {
918 dma_sync_single_for_device(dev, edesc->dma_link_tbl + offset,
919 len, DMA_FROM_DEVICE);
920 sg_pcopy_from_buffer(dst, dst_nents, edesc->buf + offset, len,
921 offset);
922 }
923 if (src != dst) {
924 if (src_nents == 1 || !is_sec1)
925 dma_unmap_sg(dev, src, src_nents, DMA_TO_DEVICE);
926
927 if (dst && (dst_nents == 1 || !is_sec1))
928 dma_unmap_sg(dev, dst, dst_nents, DMA_FROM_DEVICE);
929 } else if (src_nents == 1 || !is_sec1) {
930 dma_unmap_sg(dev, src, src_nents, DMA_BIDIRECTIONAL);
LEROY Christophe246a87c2016-06-06 13:20:36 +0200931 }
932}
933
Kim Phillips9c4a7962008-06-23 19:50:15 +0800934static void ipsec_esp_unmap(struct device *dev,
Lee Nipper56af8cd2009-03-29 15:50:50 +0800935 struct talitos_edesc *edesc,
Kim Phillips9c4a7962008-06-23 19:50:15 +0800936 struct aead_request *areq)
937{
LEROY Christophe549bd8b2016-06-06 13:20:40 +0200938 struct crypto_aead *aead = crypto_aead_reqtfm(areq);
939 struct talitos_ctx *ctx = crypto_aead_ctx(aead);
940 unsigned int ivsize = crypto_aead_ivsize(aead);
LEROY Christophe9a655602017-10-06 15:04:59 +0200941 bool is_ipsec_esp = edesc->desc.hdr & DESC_HDR_TYPE_IPSEC_ESP;
942 struct talitos_ptr *civ_ptr = &edesc->desc.ptr[is_ipsec_esp ? 2 : 3];
943 struct talitos_ptr *ckey_ptr = &edesc->desc.ptr[is_ipsec_esp ? 3 : 2];
LEROY Christophe549bd8b2016-06-06 13:20:40 +0200944
LEROY Christophe9a655602017-10-06 15:04:59 +0200945 if (is_ipsec_esp)
LEROY Christophe549bd8b2016-06-06 13:20:40 +0200946 unmap_single_talitos_ptr(dev, &edesc->desc.ptr[6],
947 DMA_FROM_DEVICE);
LEROY Christophe9a655602017-10-06 15:04:59 +0200948 unmap_single_talitos_ptr(dev, ckey_ptr, DMA_TO_DEVICE);
949 unmap_single_talitos_ptr(dev, civ_ptr, DMA_TO_DEVICE);
Kim Phillips9c4a7962008-06-23 19:50:15 +0800950 unmap_single_talitos_ptr(dev, &edesc->desc.ptr[0], DMA_TO_DEVICE);
951
LEROY Christophe6a1e8d12016-06-06 13:20:38 +0200952 talitos_sg_unmap(dev, edesc, areq->src, areq->dst, areq->cryptlen,
953 areq->assoclen);
Kim Phillips9c4a7962008-06-23 19:50:15 +0800954
955 if (edesc->dma_len)
956 dma_unmap_single(dev, edesc->dma_link_tbl, edesc->dma_len,
957 DMA_BIDIRECTIONAL);
LEROY Christophe549bd8b2016-06-06 13:20:40 +0200958
LEROY Christophe9a655602017-10-06 15:04:59 +0200959 if (!is_ipsec_esp) {
LEROY Christophe549bd8b2016-06-06 13:20:40 +0200960 unsigned int dst_nents = edesc->dst_nents ? : 1;
961
962 sg_pcopy_to_buffer(areq->dst, dst_nents, ctx->iv, ivsize,
963 areq->assoclen + areq->cryptlen - ivsize);
964 }
Kim Phillips9c4a7962008-06-23 19:50:15 +0800965}
966
967/*
968 * ipsec_esp descriptor callbacks
969 */
970static void ipsec_esp_encrypt_done(struct device *dev,
971 struct talitos_desc *desc, void *context,
972 int err)
973{
LEROY Christophe549bd8b2016-06-06 13:20:40 +0200974 struct talitos_private *priv = dev_get_drvdata(dev);
975 bool is_sec1 = has_ftr_sec1(priv);
Kim Phillips9c4a7962008-06-23 19:50:15 +0800976 struct aead_request *areq = context;
Kim Phillips9c4a7962008-06-23 19:50:15 +0800977 struct crypto_aead *authenc = crypto_aead_reqtfm(areq);
Herbert Xuaeb4c132015-07-30 17:53:22 +0800978 unsigned int authsize = crypto_aead_authsize(authenc);
Kim Phillips19bbbc62009-03-29 15:53:59 +0800979 struct talitos_edesc *edesc;
Kim Phillips9c4a7962008-06-23 19:50:15 +0800980 struct scatterlist *sg;
981 void *icvdata;
982
Kim Phillips19bbbc62009-03-29 15:53:59 +0800983 edesc = container_of(desc, struct talitos_edesc, desc);
984
Kim Phillips9c4a7962008-06-23 19:50:15 +0800985 ipsec_esp_unmap(dev, edesc, areq);
986
987 /* copy the generated ICV to dst */
Herbert Xuaeb4c132015-07-30 17:53:22 +0800988 if (edesc->icv_ool) {
LEROY Christophe549bd8b2016-06-06 13:20:40 +0200989 if (is_sec1)
990 icvdata = edesc->buf + areq->assoclen + areq->cryptlen;
991 else
992 icvdata = &edesc->link_tbl[edesc->src_nents +
993 edesc->dst_nents + 2];
Kim Phillips9c4a7962008-06-23 19:50:15 +0800994 sg = sg_last(areq->dst, edesc->dst_nents);
Herbert Xuaeb4c132015-07-30 17:53:22 +0800995 memcpy((char *)sg_virt(sg) + sg->length - authsize,
996 icvdata, authsize);
Kim Phillips9c4a7962008-06-23 19:50:15 +0800997 }
998
999 kfree(edesc);
1000
1001 aead_request_complete(areq, err);
1002}
1003
Kim Phillipsfe5720e2008-10-12 20:33:14 +08001004static void ipsec_esp_decrypt_swauth_done(struct device *dev,
Kim Phillipse938e462009-03-29 15:53:23 +08001005 struct talitos_desc *desc,
1006 void *context, int err)
Kim Phillips9c4a7962008-06-23 19:50:15 +08001007{
1008 struct aead_request *req = context;
Kim Phillips9c4a7962008-06-23 19:50:15 +08001009 struct crypto_aead *authenc = crypto_aead_reqtfm(req);
Herbert Xuaeb4c132015-07-30 17:53:22 +08001010 unsigned int authsize = crypto_aead_authsize(authenc);
Kim Phillips19bbbc62009-03-29 15:53:59 +08001011 struct talitos_edesc *edesc;
Kim Phillips9c4a7962008-06-23 19:50:15 +08001012 struct scatterlist *sg;
Herbert Xuaeb4c132015-07-30 17:53:22 +08001013 char *oicv, *icv;
LEROY Christophe549bd8b2016-06-06 13:20:40 +02001014 struct talitos_private *priv = dev_get_drvdata(dev);
1015 bool is_sec1 = has_ftr_sec1(priv);
Kim Phillips9c4a7962008-06-23 19:50:15 +08001016
Kim Phillips19bbbc62009-03-29 15:53:59 +08001017 edesc = container_of(desc, struct talitos_edesc, desc);
1018
Kim Phillips9c4a7962008-06-23 19:50:15 +08001019 ipsec_esp_unmap(dev, edesc, req);
1020
1021 if (!err) {
1022 /* auth check */
Kim Phillips9c4a7962008-06-23 19:50:15 +08001023 sg = sg_last(req->dst, edesc->dst_nents ? : 1);
Herbert Xuaeb4c132015-07-30 17:53:22 +08001024 icv = (char *)sg_virt(sg) + sg->length - authsize;
1025
1026 if (edesc->dma_len) {
LEROY Christophe549bd8b2016-06-06 13:20:40 +02001027 if (is_sec1)
1028 oicv = (char *)&edesc->dma_link_tbl +
1029 req->assoclen + req->cryptlen;
1030 else
1031 oicv = (char *)
1032 &edesc->link_tbl[edesc->src_nents +
Herbert Xuaeb4c132015-07-30 17:53:22 +08001033 edesc->dst_nents + 2];
1034 if (edesc->icv_ool)
1035 icv = oicv + authsize;
1036 } else
1037 oicv = (char *)&edesc->link_tbl[0];
1038
David Gstir79960942015-11-15 17:14:42 +01001039 err = crypto_memneq(oicv, icv, authsize) ? -EBADMSG : 0;
Kim Phillips9c4a7962008-06-23 19:50:15 +08001040 }
1041
1042 kfree(edesc);
1043
1044 aead_request_complete(req, err);
1045}
1046
Kim Phillipsfe5720e2008-10-12 20:33:14 +08001047static void ipsec_esp_decrypt_hwauth_done(struct device *dev,
Kim Phillipse938e462009-03-29 15:53:23 +08001048 struct talitos_desc *desc,
1049 void *context, int err)
Kim Phillipsfe5720e2008-10-12 20:33:14 +08001050{
1051 struct aead_request *req = context;
Kim Phillips19bbbc62009-03-29 15:53:59 +08001052 struct talitos_edesc *edesc;
1053
1054 edesc = container_of(desc, struct talitos_edesc, desc);
Kim Phillipsfe5720e2008-10-12 20:33:14 +08001055
1056 ipsec_esp_unmap(dev, edesc, req);
1057
1058 /* check ICV auth status */
Kim Phillipse938e462009-03-29 15:53:23 +08001059 if (!err && ((desc->hdr_lo & DESC_HDR_LO_ICCR1_MASK) !=
1060 DESC_HDR_LO_ICCR1_PASS))
1061 err = -EBADMSG;
Kim Phillipsfe5720e2008-10-12 20:33:14 +08001062
1063 kfree(edesc);
1064
1065 aead_request_complete(req, err);
1066}
1067
Kim Phillips9c4a7962008-06-23 19:50:15 +08001068/*
1069 * convert scatterlist to SEC h/w link table format
1070 * stop at cryptlen bytes
1071 */
Herbert Xuaeb4c132015-07-30 17:53:22 +08001072static int sg_to_link_tbl_offset(struct scatterlist *sg, int sg_count,
1073 unsigned int offset, int cryptlen,
1074 struct talitos_ptr *link_tbl_ptr)
Kim Phillips9c4a7962008-06-23 19:50:15 +08001075{
Lee Nipper70bcaca2008-07-03 19:08:46 +08001076 int n_sg = sg_count;
Herbert Xuaeb4c132015-07-30 17:53:22 +08001077 int count = 0;
Lee Nipper70bcaca2008-07-03 19:08:46 +08001078
Herbert Xuaeb4c132015-07-30 17:53:22 +08001079 while (cryptlen && sg && n_sg--) {
1080 unsigned int len = sg_dma_len(sg);
1081
1082 if (offset >= len) {
1083 offset -= len;
1084 goto next;
1085 }
1086
1087 len -= offset;
1088
1089 if (len > cryptlen)
1090 len = cryptlen;
1091
1092 to_talitos_ptr(link_tbl_ptr + count,
LEROY Christopheda9de142017-10-06 15:04:57 +02001093 sg_dma_address(sg) + offset, len, 0);
LEROY Christopheb096b542016-06-06 13:20:34 +02001094 to_talitos_ptr_ext_set(link_tbl_ptr + count, 0, 0);
Herbert Xuaeb4c132015-07-30 17:53:22 +08001095 count++;
1096 cryptlen -= len;
1097 offset = 0;
1098
1099next:
Cristian Stoica5be4d4c2015-01-20 10:06:16 +02001100 sg = sg_next(sg);
Kim Phillips9c4a7962008-06-23 19:50:15 +08001101 }
1102
Kim Phillips9c4a7962008-06-23 19:50:15 +08001103 /* tag end of link table */
Herbert Xuaeb4c132015-07-30 17:53:22 +08001104 if (count > 0)
LEROY Christopheb096b542016-06-06 13:20:34 +02001105 to_talitos_ptr_ext_set(link_tbl_ptr + count - 1,
1106 DESC_PTR_LNKTBL_RETURN, 0);
Lee Nipper70bcaca2008-07-03 19:08:46 +08001107
Herbert Xuaeb4c132015-07-30 17:53:22 +08001108 return count;
1109}
1110
LEROY Christophe5b2cf262017-10-06 15:04:47 +02001111static int talitos_sg_map(struct device *dev, struct scatterlist *src,
LEROY Christophe6a1e8d12016-06-06 13:20:38 +02001112 unsigned int len, struct talitos_edesc *edesc,
1113 struct talitos_ptr *ptr,
1114 int sg_count, unsigned int offset, int tbl_off)
LEROY Christophe246a87c2016-06-06 13:20:36 +02001115{
LEROY Christophe246a87c2016-06-06 13:20:36 +02001116 struct talitos_private *priv = dev_get_drvdata(dev);
1117 bool is_sec1 = has_ftr_sec1(priv);
1118
LEROY Christophe6a1e8d12016-06-06 13:20:38 +02001119 if (sg_count == 1) {
LEROY Christopheda9de142017-10-06 15:04:57 +02001120 to_talitos_ptr(ptr, sg_dma_address(src) + offset, len, is_sec1);
LEROY Christophe6a1e8d12016-06-06 13:20:38 +02001121 return sg_count;
LEROY Christophe246a87c2016-06-06 13:20:36 +02001122 }
LEROY Christophe6a1e8d12016-06-06 13:20:38 +02001123 if (is_sec1) {
LEROY Christopheda9de142017-10-06 15:04:57 +02001124 to_talitos_ptr(ptr, edesc->dma_link_tbl + offset, len, is_sec1);
LEROY Christophe6a1e8d12016-06-06 13:20:38 +02001125 return sg_count;
1126 }
1127 sg_count = sg_to_link_tbl_offset(src, sg_count, offset, len,
1128 &edesc->link_tbl[tbl_off]);
1129 if (sg_count == 1) {
1130 /* Only one segment now, so no link tbl needed*/
1131 copy_talitos_ptr(ptr, &edesc->link_tbl[tbl_off], is_sec1);
1132 return sg_count;
1133 }
1134 to_talitos_ptr(ptr, edesc->dma_link_tbl +
LEROY Christopheda9de142017-10-06 15:04:57 +02001135 tbl_off * sizeof(struct talitos_ptr), len, is_sec1);
LEROY Christophe6a1e8d12016-06-06 13:20:38 +02001136 to_talitos_ptr_ext_or(ptr, DESC_PTR_LNKTBL_JUMP, is_sec1);
1137
LEROY Christophe246a87c2016-06-06 13:20:36 +02001138 return sg_count;
1139}
1140
Kim Phillips9c4a7962008-06-23 19:50:15 +08001141/*
1142 * fill in and submit ipsec_esp descriptor
1143 */
Lee Nipper56af8cd2009-03-29 15:50:50 +08001144static int ipsec_esp(struct talitos_edesc *edesc, struct aead_request *areq,
Herbert Xuaeb4c132015-07-30 17:53:22 +08001145 void (*callback)(struct device *dev,
1146 struct talitos_desc *desc,
1147 void *context, int error))
Kim Phillips9c4a7962008-06-23 19:50:15 +08001148{
1149 struct crypto_aead *aead = crypto_aead_reqtfm(areq);
Herbert Xuaeb4c132015-07-30 17:53:22 +08001150 unsigned int authsize = crypto_aead_authsize(aead);
Kim Phillips9c4a7962008-06-23 19:50:15 +08001151 struct talitos_ctx *ctx = crypto_aead_ctx(aead);
1152 struct device *dev = ctx->dev;
1153 struct talitos_desc *desc = &edesc->desc;
1154 unsigned int cryptlen = areq->cryptlen;
Kim Phillipse41256f2009-08-13 11:49:06 +10001155 unsigned int ivsize = crypto_aead_ivsize(aead);
Herbert Xuaeb4c132015-07-30 17:53:22 +08001156 int tbl_off = 0;
Kim Phillipsfa86a262008-07-17 20:20:06 +08001157 int sg_count, ret;
Kim Phillipsfe5720e2008-10-12 20:33:14 +08001158 int sg_link_tbl_len;
LEROY Christophe549bd8b2016-06-06 13:20:40 +02001159 bool sync_needed = false;
1160 struct talitos_private *priv = dev_get_drvdata(dev);
1161 bool is_sec1 = has_ftr_sec1(priv);
LEROY Christophe9a655602017-10-06 15:04:59 +02001162 bool is_ipsec_esp = desc->hdr & DESC_HDR_TYPE_IPSEC_ESP;
1163 struct talitos_ptr *civ_ptr = &desc->ptr[is_ipsec_esp ? 2 : 3];
1164 struct talitos_ptr *ckey_ptr = &desc->ptr[is_ipsec_esp ? 3 : 2];
Kim Phillips9c4a7962008-06-23 19:50:15 +08001165
1166 /* hmac key */
1167 map_single_talitos_ptr(dev, &desc->ptr[0], ctx->authkeylen, &ctx->key,
LEROY Christophea2b35aa2015-04-17 16:31:57 +02001168 DMA_TO_DEVICE);
Horia Geanta79fd31d2012-08-02 17:16:40 +03001169
LEROY Christophe549bd8b2016-06-06 13:20:40 +02001170 sg_count = edesc->src_nents ?: 1;
1171 if (is_sec1 && sg_count > 1)
1172 sg_copy_to_buffer(areq->src, sg_count, edesc->buf,
1173 areq->assoclen + cryptlen);
1174 else
1175 sg_count = dma_map_sg(dev, areq->src, sg_count,
1176 (areq->src == areq->dst) ?
1177 DMA_BIDIRECTIONAL : DMA_TO_DEVICE);
1178
Kim Phillips9c4a7962008-06-23 19:50:15 +08001179 /* hmac data */
LEROY Christophe549bd8b2016-06-06 13:20:40 +02001180 ret = talitos_sg_map(dev, areq->src, areq->assoclen, edesc,
1181 &desc->ptr[1], sg_count, 0, tbl_off);
Horia Geanta79fd31d2012-08-02 17:16:40 +03001182
LEROY Christophe549bd8b2016-06-06 13:20:40 +02001183 if (ret > 1) {
Horia Geant?340ff602016-04-19 20:33:48 +03001184 tbl_off += ret;
LEROY Christophe549bd8b2016-06-06 13:20:40 +02001185 sync_needed = true;
Horia Geanta79fd31d2012-08-02 17:16:40 +03001186 }
1187
Kim Phillips9c4a7962008-06-23 19:50:15 +08001188 /* cipher iv */
LEROY Christophe9a655602017-10-06 15:04:59 +02001189 to_talitos_ptr(civ_ptr, edesc->iv_dma, ivsize, is_sec1);
Kim Phillips9c4a7962008-06-23 19:50:15 +08001190
1191 /* cipher key */
LEROY Christophe9a655602017-10-06 15:04:59 +02001192 map_single_talitos_ptr(dev, ckey_ptr, ctx->enckeylen,
1193 (char *)&ctx->key + ctx->authkeylen,
1194 DMA_TO_DEVICE);
Kim Phillips9c4a7962008-06-23 19:50:15 +08001195
1196 /*
1197 * cipher in
1198 * map and adjust cipher len to aead request cryptlen.
1199 * extent is bytes of HMAC postpended to ciphertext,
1200 * typically 12 for ipsec
1201 */
Herbert Xuaeb4c132015-07-30 17:53:22 +08001202 sg_link_tbl_len = cryptlen;
Kim Phillips9c4a7962008-06-23 19:50:15 +08001203
LEROY Christophe9a655602017-10-06 15:04:59 +02001204 if (is_ipsec_esp) {
LEROY Christophe549bd8b2016-06-06 13:20:40 +02001205 to_talitos_ptr_ext_set(&desc->ptr[4], authsize, is_sec1);
1206
LEROY Christophe9a655602017-10-06 15:04:59 +02001207 if (desc->hdr & DESC_HDR_MODE1_MDEU_CICV)
LEROY Christophe549bd8b2016-06-06 13:20:40 +02001208 sg_link_tbl_len += authsize;
1209 }
1210
LEROY Christophefbb22132017-10-06 15:04:41 +02001211 ret = talitos_sg_map(dev, areq->src, sg_link_tbl_len, edesc,
1212 &desc->ptr[4], sg_count, areq->assoclen, tbl_off);
LEROY Christophe549bd8b2016-06-06 13:20:40 +02001213
LEROY Christopheec8c7d12017-10-06 15:04:33 +02001214 if (ret > 1) {
1215 tbl_off += ret;
LEROY Christophe549bd8b2016-06-06 13:20:40 +02001216 sync_needed = true;
Horia Geant?340ff602016-04-19 20:33:48 +03001217 }
Kim Phillips9c4a7962008-06-23 19:50:15 +08001218
1219 /* cipher out */
LEROY Christophe549bd8b2016-06-06 13:20:40 +02001220 if (areq->src != areq->dst) {
1221 sg_count = edesc->dst_nents ? : 1;
1222 if (!is_sec1 || sg_count == 1)
1223 dma_map_sg(dev, areq->dst, sg_count, DMA_FROM_DEVICE);
1224 }
Kim Phillips9c4a7962008-06-23 19:50:15 +08001225
LEROY Christophee04a61b2017-10-06 15:04:35 +02001226 ret = talitos_sg_map(dev, areq->dst, cryptlen, edesc, &desc->ptr[5],
1227 sg_count, areq->assoclen, tbl_off);
Kim Phillips9c4a7962008-06-23 19:50:15 +08001228
LEROY Christophe9a655602017-10-06 15:04:59 +02001229 if (is_ipsec_esp)
LEROY Christophe549bd8b2016-06-06 13:20:40 +02001230 to_talitos_ptr_ext_or(&desc->ptr[5], authsize, is_sec1);
Herbert Xuaeb4c132015-07-30 17:53:22 +08001231
LEROY Christophee04a61b2017-10-06 15:04:35 +02001232 /* ICV data */
1233 if (ret > 1) {
1234 tbl_off += ret;
Herbert Xuaeb4c132015-07-30 17:53:22 +08001235 edesc->icv_ool = true;
LEROY Christophe549bd8b2016-06-06 13:20:40 +02001236 sync_needed = true;
1237
LEROY Christophe9a655602017-10-06 15:04:59 +02001238 if (is_ipsec_esp) {
LEROY Christophe549bd8b2016-06-06 13:20:40 +02001239 struct talitos_ptr *tbl_ptr = &edesc->link_tbl[tbl_off];
1240 int offset = (edesc->src_nents + edesc->dst_nents + 2) *
1241 sizeof(struct talitos_ptr) + authsize;
1242
1243 /* Add an entry to the link table for ICV data */
LEROY Christophee04a61b2017-10-06 15:04:35 +02001244 to_talitos_ptr_ext_set(tbl_ptr - 1, 0, is_sec1);
LEROY Christophe549bd8b2016-06-06 13:20:40 +02001245 to_talitos_ptr_ext_set(tbl_ptr, DESC_PTR_LNKTBL_RETURN,
1246 is_sec1);
LEROY Christophe549bd8b2016-06-06 13:20:40 +02001247
1248 /* icv data follows link tables */
1249 to_talitos_ptr(tbl_ptr, edesc->dma_link_tbl + offset,
LEROY Christopheda9de142017-10-06 15:04:57 +02001250 authsize, is_sec1);
LEROY Christophee04a61b2017-10-06 15:04:35 +02001251 } else {
1252 dma_addr_t addr = edesc->dma_link_tbl;
1253
1254 if (is_sec1)
1255 addr += areq->assoclen + cryptlen;
1256 else
1257 addr += sizeof(struct talitos_ptr) * tbl_off;
1258
LEROY Christopheda9de142017-10-06 15:04:57 +02001259 to_talitos_ptr(&desc->ptr[6], addr, authsize, is_sec1);
LEROY Christophee04a61b2017-10-06 15:04:35 +02001260 }
LEROY Christophe9a655602017-10-06 15:04:59 +02001261 } else if (!is_ipsec_esp) {
LEROY Christophee04a61b2017-10-06 15:04:35 +02001262 ret = talitos_sg_map(dev, areq->dst, authsize, edesc,
1263 &desc->ptr[6], sg_count, areq->assoclen +
1264 cryptlen,
1265 tbl_off);
1266 if (ret > 1) {
1267 tbl_off += ret;
1268 edesc->icv_ool = true;
1269 sync_needed = true;
1270 } else {
1271 edesc->icv_ool = false;
LEROY Christophe549bd8b2016-06-06 13:20:40 +02001272 }
Horia Geant?340ff602016-04-19 20:33:48 +03001273 } else {
LEROY Christophe549bd8b2016-06-06 13:20:40 +02001274 edesc->icv_ool = false;
1275 }
1276
Kim Phillips9c4a7962008-06-23 19:50:15 +08001277 /* iv out */
LEROY Christophe9a655602017-10-06 15:04:59 +02001278 if (is_ipsec_esp)
LEROY Christophe549bd8b2016-06-06 13:20:40 +02001279 map_single_talitos_ptr(dev, &desc->ptr[6], ivsize, ctx->iv,
1280 DMA_FROM_DEVICE);
1281
1282 if (sync_needed)
1283 dma_sync_single_for_device(dev, edesc->dma_link_tbl,
1284 edesc->dma_len,
1285 DMA_BIDIRECTIONAL);
Kim Phillips9c4a7962008-06-23 19:50:15 +08001286
Kim Phillips5228f0f2011-07-15 11:21:38 +08001287 ret = talitos_submit(dev, ctx->ch, desc, callback, areq);
Kim Phillipsfa86a262008-07-17 20:20:06 +08001288 if (ret != -EINPROGRESS) {
1289 ipsec_esp_unmap(dev, edesc, areq);
1290 kfree(edesc);
1291 }
1292 return ret;
Kim Phillips9c4a7962008-06-23 19:50:15 +08001293}
1294
Kim Phillips9c4a7962008-06-23 19:50:15 +08001295/*
Lee Nipper56af8cd2009-03-29 15:50:50 +08001296 * allocate and map the extended descriptor
Kim Phillips9c4a7962008-06-23 19:50:15 +08001297 */
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001298static struct talitos_edesc *talitos_edesc_alloc(struct device *dev,
1299 struct scatterlist *src,
1300 struct scatterlist *dst,
Horia Geanta79fd31d2012-08-02 17:16:40 +03001301 u8 *iv,
1302 unsigned int assoclen,
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001303 unsigned int cryptlen,
1304 unsigned int authsize,
Horia Geanta79fd31d2012-08-02 17:16:40 +03001305 unsigned int ivsize,
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001306 int icv_stashing,
Horia Geanta62293a32013-11-28 15:11:17 +02001307 u32 cryptoflags,
1308 bool encrypt)
Kim Phillips9c4a7962008-06-23 19:50:15 +08001309{
Lee Nipper56af8cd2009-03-29 15:50:50 +08001310 struct talitos_edesc *edesc;
LEROY Christophe6a1e8d12016-06-06 13:20:38 +02001311 int src_nents, dst_nents, alloc_len, dma_len, src_len, dst_len;
Horia Geanta79fd31d2012-08-02 17:16:40 +03001312 dma_addr_t iv_dma = 0;
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001313 gfp_t flags = cryptoflags & CRYPTO_TFM_REQ_MAY_SLEEP ? GFP_KERNEL :
Kim Phillips586725f2008-07-17 20:19:18 +08001314 GFP_ATOMIC;
LEROY Christophe6f65f6a2015-04-17 16:32:15 +02001315 struct talitos_private *priv = dev_get_drvdata(dev);
1316 bool is_sec1 = has_ftr_sec1(priv);
1317 int max_len = is_sec1 ? TALITOS1_MAX_DATA_LEN : TALITOS2_MAX_DATA_LEN;
LABBE Corentin8e409fe2015-11-04 21:13:34 +01001318 void *err;
Kim Phillips9c4a7962008-06-23 19:50:15 +08001319
LEROY Christophe6f65f6a2015-04-17 16:32:15 +02001320 if (cryptlen + authsize > max_len) {
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001321 dev_err(dev, "length exceeds h/w max limit\n");
Kim Phillips9c4a7962008-06-23 19:50:15 +08001322 return ERR_PTR(-EINVAL);
1323 }
1324
Horia Geanta935e99a2013-11-19 14:57:49 +02001325 if (ivsize)
Horia Geanta79fd31d2012-08-02 17:16:40 +03001326 iv_dma = dma_map_single(dev, iv, ivsize, DMA_TO_DEVICE);
1327
Horia Geanta62293a32013-11-28 15:11:17 +02001328 if (!dst || dst == src) {
LEROY Christophe6a1e8d12016-06-06 13:20:38 +02001329 src_len = assoclen + cryptlen + authsize;
1330 src_nents = sg_nents_for_len(src, src_len);
LABBE Corentin8e409fe2015-11-04 21:13:34 +01001331 if (src_nents < 0) {
1332 dev_err(dev, "Invalid number of src SG.\n");
1333 err = ERR_PTR(-EINVAL);
1334 goto error_sg;
1335 }
Horia Geanta62293a32013-11-28 15:11:17 +02001336 src_nents = (src_nents == 1) ? 0 : src_nents;
1337 dst_nents = dst ? src_nents : 0;
LEROY Christophe6a1e8d12016-06-06 13:20:38 +02001338 dst_len = 0;
Horia Geanta62293a32013-11-28 15:11:17 +02001339 } else { /* dst && dst != src*/
LEROY Christophe6a1e8d12016-06-06 13:20:38 +02001340 src_len = assoclen + cryptlen + (encrypt ? 0 : authsize);
1341 src_nents = sg_nents_for_len(src, src_len);
LABBE Corentin8e409fe2015-11-04 21:13:34 +01001342 if (src_nents < 0) {
1343 dev_err(dev, "Invalid number of src SG.\n");
1344 err = ERR_PTR(-EINVAL);
1345 goto error_sg;
1346 }
Horia Geanta62293a32013-11-28 15:11:17 +02001347 src_nents = (src_nents == 1) ? 0 : src_nents;
LEROY Christophe6a1e8d12016-06-06 13:20:38 +02001348 dst_len = assoclen + cryptlen + (encrypt ? authsize : 0);
1349 dst_nents = sg_nents_for_len(dst, dst_len);
LABBE Corentin8e409fe2015-11-04 21:13:34 +01001350 if (dst_nents < 0) {
1351 dev_err(dev, "Invalid number of dst SG.\n");
1352 err = ERR_PTR(-EINVAL);
1353 goto error_sg;
1354 }
Horia Geanta62293a32013-11-28 15:11:17 +02001355 dst_nents = (dst_nents == 1) ? 0 : dst_nents;
Kim Phillips9c4a7962008-06-23 19:50:15 +08001356 }
1357
1358 /*
1359 * allocate space for base edesc plus the link tables,
Herbert Xuaeb4c132015-07-30 17:53:22 +08001360 * allowing for two separate entries for AD and generated ICV (+ 2),
1361 * and space for two sets of ICVs (stashed and generated)
Kim Phillips9c4a7962008-06-23 19:50:15 +08001362 */
Lee Nipper56af8cd2009-03-29 15:50:50 +08001363 alloc_len = sizeof(struct talitos_edesc);
Herbert Xuaeb4c132015-07-30 17:53:22 +08001364 if (src_nents || dst_nents) {
LEROY Christophe6f65f6a2015-04-17 16:32:15 +02001365 if (is_sec1)
LEROY Christophe6a1e8d12016-06-06 13:20:38 +02001366 dma_len = (src_nents ? src_len : 0) +
1367 (dst_nents ? dst_len : 0);
LEROY Christophe6f65f6a2015-04-17 16:32:15 +02001368 else
Herbert Xuaeb4c132015-07-30 17:53:22 +08001369 dma_len = (src_nents + dst_nents + 2) *
1370 sizeof(struct talitos_ptr) + authsize * 2;
Kim Phillips9c4a7962008-06-23 19:50:15 +08001371 alloc_len += dma_len;
1372 } else {
1373 dma_len = 0;
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001374 alloc_len += icv_stashing ? authsize : 0;
Kim Phillips9c4a7962008-06-23 19:50:15 +08001375 }
1376
Kim Phillips586725f2008-07-17 20:19:18 +08001377 edesc = kmalloc(alloc_len, GFP_DMA | flags);
Kim Phillips9c4a7962008-06-23 19:50:15 +08001378 if (!edesc) {
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001379 dev_err(dev, "could not allocate edescriptor\n");
LABBE Corentin8e409fe2015-11-04 21:13:34 +01001380 err = ERR_PTR(-ENOMEM);
1381 goto error_sg;
Kim Phillips9c4a7962008-06-23 19:50:15 +08001382 }
LEROY Christophee4a647c2017-10-06 15:04:45 +02001383 memset(&edesc->desc, 0, sizeof(edesc->desc));
Kim Phillips9c4a7962008-06-23 19:50:15 +08001384
1385 edesc->src_nents = src_nents;
1386 edesc->dst_nents = dst_nents;
Horia Geanta79fd31d2012-08-02 17:16:40 +03001387 edesc->iv_dma = iv_dma;
Kim Phillips9c4a7962008-06-23 19:50:15 +08001388 edesc->dma_len = dma_len;
Lee Nipper497f2e62010-05-19 19:20:36 +10001389 if (dma_len)
1390 edesc->dma_link_tbl = dma_map_single(dev, &edesc->link_tbl[0],
1391 edesc->dma_len,
1392 DMA_BIDIRECTIONAL);
Kim Phillips9c4a7962008-06-23 19:50:15 +08001393
1394 return edesc;
LABBE Corentin8e409fe2015-11-04 21:13:34 +01001395error_sg:
1396 if (iv_dma)
1397 dma_unmap_single(dev, iv_dma, ivsize, DMA_TO_DEVICE);
1398 return err;
Kim Phillips9c4a7962008-06-23 19:50:15 +08001399}
1400
Horia Geanta79fd31d2012-08-02 17:16:40 +03001401static struct talitos_edesc *aead_edesc_alloc(struct aead_request *areq, u8 *iv,
Horia Geanta62293a32013-11-28 15:11:17 +02001402 int icv_stashing, bool encrypt)
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001403{
1404 struct crypto_aead *authenc = crypto_aead_reqtfm(areq);
Herbert Xuaeb4c132015-07-30 17:53:22 +08001405 unsigned int authsize = crypto_aead_authsize(authenc);
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001406 struct talitos_ctx *ctx = crypto_aead_ctx(authenc);
Horia Geanta79fd31d2012-08-02 17:16:40 +03001407 unsigned int ivsize = crypto_aead_ivsize(authenc);
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001408
Herbert Xuaeb4c132015-07-30 17:53:22 +08001409 return talitos_edesc_alloc(ctx->dev, areq->src, areq->dst,
Horia Geanta79fd31d2012-08-02 17:16:40 +03001410 iv, areq->assoclen, areq->cryptlen,
Herbert Xuaeb4c132015-07-30 17:53:22 +08001411 authsize, ivsize, icv_stashing,
Horia Geanta62293a32013-11-28 15:11:17 +02001412 areq->base.flags, encrypt);
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001413}
1414
Lee Nipper56af8cd2009-03-29 15:50:50 +08001415static int aead_encrypt(struct aead_request *req)
Kim Phillips9c4a7962008-06-23 19:50:15 +08001416{
1417 struct crypto_aead *authenc = crypto_aead_reqtfm(req);
1418 struct talitos_ctx *ctx = crypto_aead_ctx(authenc);
Lee Nipper56af8cd2009-03-29 15:50:50 +08001419 struct talitos_edesc *edesc;
Kim Phillips9c4a7962008-06-23 19:50:15 +08001420
1421 /* allocate extended descriptor */
Horia Geanta62293a32013-11-28 15:11:17 +02001422 edesc = aead_edesc_alloc(req, req->iv, 0, true);
Kim Phillips9c4a7962008-06-23 19:50:15 +08001423 if (IS_ERR(edesc))
1424 return PTR_ERR(edesc);
1425
1426 /* set encrypt */
Lee Nipper70bcaca2008-07-03 19:08:46 +08001427 edesc->desc.hdr = ctx->desc_hdr_template | DESC_HDR_MODE0_ENCRYPT;
Kim Phillips9c4a7962008-06-23 19:50:15 +08001428
Herbert Xuaeb4c132015-07-30 17:53:22 +08001429 return ipsec_esp(edesc, req, ipsec_esp_encrypt_done);
Kim Phillips9c4a7962008-06-23 19:50:15 +08001430}
1431
Lee Nipper56af8cd2009-03-29 15:50:50 +08001432static int aead_decrypt(struct aead_request *req)
Kim Phillips9c4a7962008-06-23 19:50:15 +08001433{
1434 struct crypto_aead *authenc = crypto_aead_reqtfm(req);
Herbert Xuaeb4c132015-07-30 17:53:22 +08001435 unsigned int authsize = crypto_aead_authsize(authenc);
Kim Phillips9c4a7962008-06-23 19:50:15 +08001436 struct talitos_ctx *ctx = crypto_aead_ctx(authenc);
Kim Phillipsfe5720e2008-10-12 20:33:14 +08001437 struct talitos_private *priv = dev_get_drvdata(ctx->dev);
Lee Nipper56af8cd2009-03-29 15:50:50 +08001438 struct talitos_edesc *edesc;
Kim Phillips9c4a7962008-06-23 19:50:15 +08001439 struct scatterlist *sg;
1440 void *icvdata;
1441
1442 req->cryptlen -= authsize;
1443
1444 /* allocate extended descriptor */
Horia Geanta62293a32013-11-28 15:11:17 +02001445 edesc = aead_edesc_alloc(req, req->iv, 1, false);
Kim Phillips9c4a7962008-06-23 19:50:15 +08001446 if (IS_ERR(edesc))
1447 return PTR_ERR(edesc);
1448
Kim Phillipsfe5720e2008-10-12 20:33:14 +08001449 if ((priv->features & TALITOS_FTR_HW_AUTH_CHECK) &&
Kim Phillipse938e462009-03-29 15:53:23 +08001450 ((!edesc->src_nents && !edesc->dst_nents) ||
1451 priv->features & TALITOS_FTR_SRC_LINK_TBL_LEN_INCLUDES_EXTENT)) {
Kim Phillips9c4a7962008-06-23 19:50:15 +08001452
Kim Phillipsfe5720e2008-10-12 20:33:14 +08001453 /* decrypt and check the ICV */
Kim Phillipse938e462009-03-29 15:53:23 +08001454 edesc->desc.hdr = ctx->desc_hdr_template |
1455 DESC_HDR_DIR_INBOUND |
Kim Phillipsfe5720e2008-10-12 20:33:14 +08001456 DESC_HDR_MODE1_MDEU_CICV;
Kim Phillips9c4a7962008-06-23 19:50:15 +08001457
Kim Phillipsfe5720e2008-10-12 20:33:14 +08001458 /* reset integrity check result bits */
Kim Phillips9c4a7962008-06-23 19:50:15 +08001459
Herbert Xuaeb4c132015-07-30 17:53:22 +08001460 return ipsec_esp(edesc, req, ipsec_esp_decrypt_hwauth_done);
Kim Phillipsfe5720e2008-10-12 20:33:14 +08001461 }
Kim Phillipse938e462009-03-29 15:53:23 +08001462
1463 /* Have to check the ICV with software */
1464 edesc->desc.hdr = ctx->desc_hdr_template | DESC_HDR_DIR_INBOUND;
1465
1466 /* stash incoming ICV for later cmp with ICV generated by the h/w */
1467 if (edesc->dma_len)
Herbert Xuaeb4c132015-07-30 17:53:22 +08001468 icvdata = (char *)&edesc->link_tbl[edesc->src_nents +
1469 edesc->dst_nents + 2];
Kim Phillipse938e462009-03-29 15:53:23 +08001470 else
1471 icvdata = &edesc->link_tbl[0];
1472
1473 sg = sg_last(req->src, edesc->src_nents ? : 1);
1474
Herbert Xuaeb4c132015-07-30 17:53:22 +08001475 memcpy(icvdata, (char *)sg_virt(sg) + sg->length - authsize, authsize);
Kim Phillipse938e462009-03-29 15:53:23 +08001476
Herbert Xuaeb4c132015-07-30 17:53:22 +08001477 return ipsec_esp(edesc, req, ipsec_esp_decrypt_swauth_done);
Kim Phillips9c4a7962008-06-23 19:50:15 +08001478}
1479
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001480static int ablkcipher_setkey(struct crypto_ablkcipher *cipher,
1481 const u8 *key, unsigned int keylen)
1482{
1483 struct talitos_ctx *ctx = crypto_ablkcipher_ctx(cipher);
LEROY Christophef384cdc2017-10-06 15:04:37 +02001484 u32 tmp[DES_EXPKEY_WORDS];
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001485
Martin Hicks03d2c512017-05-02 09:38:35 -04001486 if (keylen > TALITOS_MAX_KEY_SIZE) {
1487 crypto_ablkcipher_set_flags(cipher, CRYPTO_TFM_RES_BAD_KEY_LEN);
1488 return -EINVAL;
1489 }
1490
LEROY Christophef384cdc2017-10-06 15:04:37 +02001491 if (unlikely(crypto_ablkcipher_get_flags(cipher) &
1492 CRYPTO_TFM_REQ_WEAK_KEY) &&
1493 !des_ekey(tmp, key)) {
1494 crypto_ablkcipher_set_flags(cipher, CRYPTO_TFM_RES_WEAK_KEY);
1495 return -EINVAL;
1496 }
1497
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001498 memcpy(&ctx->key, key, keylen);
1499 ctx->keylen = keylen;
1500
1501 return 0;
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001502}
1503
1504static void common_nonsnoop_unmap(struct device *dev,
1505 struct talitos_edesc *edesc,
1506 struct ablkcipher_request *areq)
1507{
1508 unmap_single_talitos_ptr(dev, &edesc->desc.ptr[5], DMA_FROM_DEVICE);
LEROY Christophe032d1972015-04-17 16:31:51 +02001509
LEROY Christophe6a1e8d12016-06-06 13:20:38 +02001510 talitos_sg_unmap(dev, edesc, areq->src, areq->dst, areq->nbytes, 0);
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001511 unmap_single_talitos_ptr(dev, &edesc->desc.ptr[2], DMA_TO_DEVICE);
1512 unmap_single_talitos_ptr(dev, &edesc->desc.ptr[1], DMA_TO_DEVICE);
1513
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001514 if (edesc->dma_len)
1515 dma_unmap_single(dev, edesc->dma_link_tbl, edesc->dma_len,
1516 DMA_BIDIRECTIONAL);
1517}
1518
1519static void ablkcipher_done(struct device *dev,
1520 struct talitos_desc *desc, void *context,
1521 int err)
1522{
1523 struct ablkcipher_request *areq = context;
Kim Phillips19bbbc62009-03-29 15:53:59 +08001524 struct talitos_edesc *edesc;
1525
1526 edesc = container_of(desc, struct talitos_edesc, desc);
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001527
1528 common_nonsnoop_unmap(dev, edesc, areq);
1529
1530 kfree(edesc);
1531
1532 areq->base.complete(&areq->base, err);
1533}
1534
1535static int common_nonsnoop(struct talitos_edesc *edesc,
1536 struct ablkcipher_request *areq,
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001537 void (*callback) (struct device *dev,
1538 struct talitos_desc *desc,
1539 void *context, int error))
1540{
1541 struct crypto_ablkcipher *cipher = crypto_ablkcipher_reqtfm(areq);
1542 struct talitos_ctx *ctx = crypto_ablkcipher_ctx(cipher);
1543 struct device *dev = ctx->dev;
1544 struct talitos_desc *desc = &edesc->desc;
1545 unsigned int cryptlen = areq->nbytes;
Horia Geanta79fd31d2012-08-02 17:16:40 +03001546 unsigned int ivsize = crypto_ablkcipher_ivsize(cipher);
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001547 int sg_count, ret;
LEROY Christophe6a1e8d12016-06-06 13:20:38 +02001548 bool sync_needed = false;
LEROY Christophe922f9dc2015-04-17 16:32:07 +02001549 struct talitos_private *priv = dev_get_drvdata(dev);
1550 bool is_sec1 = has_ftr_sec1(priv);
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001551
1552 /* first DWORD empty */
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001553
1554 /* cipher iv */
LEROY Christopheda9de142017-10-06 15:04:57 +02001555 to_talitos_ptr(&desc->ptr[1], edesc->iv_dma, ivsize, is_sec1);
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001556
1557 /* cipher key */
1558 map_single_talitos_ptr(dev, &desc->ptr[2], ctx->keylen,
LEROY Christophea2b35aa2015-04-17 16:31:57 +02001559 (char *)&ctx->key, DMA_TO_DEVICE);
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001560
LEROY Christophe6a1e8d12016-06-06 13:20:38 +02001561 sg_count = edesc->src_nents ?: 1;
1562 if (is_sec1 && sg_count > 1)
1563 sg_copy_to_buffer(areq->src, sg_count, edesc->buf,
1564 cryptlen);
1565 else
1566 sg_count = dma_map_sg(dev, areq->src, sg_count,
1567 (areq->src == areq->dst) ?
1568 DMA_BIDIRECTIONAL : DMA_TO_DEVICE);
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001569 /*
1570 * cipher in
1571 */
LEROY Christophe6a1e8d12016-06-06 13:20:38 +02001572 sg_count = talitos_sg_map(dev, areq->src, cryptlen, edesc,
1573 &desc->ptr[3], sg_count, 0, 0);
1574 if (sg_count > 1)
1575 sync_needed = true;
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001576
1577 /* cipher out */
LEROY Christophe6a1e8d12016-06-06 13:20:38 +02001578 if (areq->src != areq->dst) {
1579 sg_count = edesc->dst_nents ? : 1;
1580 if (!is_sec1 || sg_count == 1)
1581 dma_map_sg(dev, areq->dst, sg_count, DMA_FROM_DEVICE);
1582 }
1583
1584 ret = talitos_sg_map(dev, areq->dst, cryptlen, edesc, &desc->ptr[4],
1585 sg_count, 0, (edesc->src_nents + 1));
1586 if (ret > 1)
1587 sync_needed = true;
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001588
1589 /* iv out */
LEROY Christophea2b35aa2015-04-17 16:31:57 +02001590 map_single_talitos_ptr(dev, &desc->ptr[5], ivsize, ctx->iv,
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001591 DMA_FROM_DEVICE);
1592
1593 /* last DWORD empty */
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001594
LEROY Christophe6a1e8d12016-06-06 13:20:38 +02001595 if (sync_needed)
1596 dma_sync_single_for_device(dev, edesc->dma_link_tbl,
1597 edesc->dma_len, DMA_BIDIRECTIONAL);
1598
Kim Phillips5228f0f2011-07-15 11:21:38 +08001599 ret = talitos_submit(dev, ctx->ch, desc, callback, areq);
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001600 if (ret != -EINPROGRESS) {
1601 common_nonsnoop_unmap(dev, edesc, areq);
1602 kfree(edesc);
1603 }
1604 return ret;
1605}
1606
Kim Phillipse938e462009-03-29 15:53:23 +08001607static struct talitos_edesc *ablkcipher_edesc_alloc(struct ablkcipher_request *
Horia Geanta62293a32013-11-28 15:11:17 +02001608 areq, bool encrypt)
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001609{
1610 struct crypto_ablkcipher *cipher = crypto_ablkcipher_reqtfm(areq);
1611 struct talitos_ctx *ctx = crypto_ablkcipher_ctx(cipher);
Horia Geanta79fd31d2012-08-02 17:16:40 +03001612 unsigned int ivsize = crypto_ablkcipher_ivsize(cipher);
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001613
Herbert Xuaeb4c132015-07-30 17:53:22 +08001614 return talitos_edesc_alloc(ctx->dev, areq->src, areq->dst,
Horia Geanta79fd31d2012-08-02 17:16:40 +03001615 areq->info, 0, areq->nbytes, 0, ivsize, 0,
Horia Geanta62293a32013-11-28 15:11:17 +02001616 areq->base.flags, encrypt);
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001617}
1618
1619static int ablkcipher_encrypt(struct ablkcipher_request *areq)
1620{
1621 struct crypto_ablkcipher *cipher = crypto_ablkcipher_reqtfm(areq);
1622 struct talitos_ctx *ctx = crypto_ablkcipher_ctx(cipher);
1623 struct talitos_edesc *edesc;
1624
1625 /* allocate extended descriptor */
Horia Geanta62293a32013-11-28 15:11:17 +02001626 edesc = ablkcipher_edesc_alloc(areq, true);
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001627 if (IS_ERR(edesc))
1628 return PTR_ERR(edesc);
1629
1630 /* set encrypt */
1631 edesc->desc.hdr = ctx->desc_hdr_template | DESC_HDR_MODE0_ENCRYPT;
1632
Kim Phillipsfebec542011-07-15 11:21:39 +08001633 return common_nonsnoop(edesc, areq, ablkcipher_done);
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001634}
1635
1636static int ablkcipher_decrypt(struct ablkcipher_request *areq)
1637{
1638 struct crypto_ablkcipher *cipher = crypto_ablkcipher_reqtfm(areq);
1639 struct talitos_ctx *ctx = crypto_ablkcipher_ctx(cipher);
1640 struct talitos_edesc *edesc;
1641
1642 /* allocate extended descriptor */
Horia Geanta62293a32013-11-28 15:11:17 +02001643 edesc = ablkcipher_edesc_alloc(areq, false);
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001644 if (IS_ERR(edesc))
1645 return PTR_ERR(edesc);
1646
1647 edesc->desc.hdr = ctx->desc_hdr_template | DESC_HDR_DIR_INBOUND;
1648
Kim Phillipsfebec542011-07-15 11:21:39 +08001649 return common_nonsnoop(edesc, areq, ablkcipher_done);
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001650}
1651
Lee Nipper497f2e62010-05-19 19:20:36 +10001652static void common_nonsnoop_hash_unmap(struct device *dev,
1653 struct talitos_edesc *edesc,
1654 struct ahash_request *areq)
1655{
1656 struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
LEROY Christophe922f9dc2015-04-17 16:32:07 +02001657 struct talitos_private *priv = dev_get_drvdata(dev);
1658 bool is_sec1 = has_ftr_sec1(priv);
Lee Nipper497f2e62010-05-19 19:20:36 +10001659
1660 unmap_single_talitos_ptr(dev, &edesc->desc.ptr[5], DMA_FROM_DEVICE);
1661
LEROY Christophe6a1e8d12016-06-06 13:20:38 +02001662 talitos_sg_unmap(dev, edesc, req_ctx->psrc, NULL, 0, 0);
LEROY Christophe032d1972015-04-17 16:31:51 +02001663
Lee Nipper497f2e62010-05-19 19:20:36 +10001664 /* When using hashctx-in, must unmap it. */
LEROY Christophe922f9dc2015-04-17 16:32:07 +02001665 if (from_talitos_ptr_len(&edesc->desc.ptr[1], is_sec1))
Lee Nipper497f2e62010-05-19 19:20:36 +10001666 unmap_single_talitos_ptr(dev, &edesc->desc.ptr[1],
1667 DMA_TO_DEVICE);
1668
LEROY Christophe922f9dc2015-04-17 16:32:07 +02001669 if (from_talitos_ptr_len(&edesc->desc.ptr[2], is_sec1))
Lee Nipper497f2e62010-05-19 19:20:36 +10001670 unmap_single_talitos_ptr(dev, &edesc->desc.ptr[2],
1671 DMA_TO_DEVICE);
1672
Lee Nipper497f2e62010-05-19 19:20:36 +10001673 if (edesc->dma_len)
1674 dma_unmap_single(dev, edesc->dma_link_tbl, edesc->dma_len,
1675 DMA_BIDIRECTIONAL);
1676
1677}
1678
1679static void ahash_done(struct device *dev,
1680 struct talitos_desc *desc, void *context,
1681 int err)
1682{
1683 struct ahash_request *areq = context;
1684 struct talitos_edesc *edesc =
1685 container_of(desc, struct talitos_edesc, desc);
1686 struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
1687
1688 if (!req_ctx->last && req_ctx->to_hash_later) {
1689 /* Position any partial block for next update/final/finup */
1690 memcpy(req_ctx->buf, req_ctx->bufnext, req_ctx->to_hash_later);
Lee Nipper5e833bc2010-06-16 15:29:15 +10001691 req_ctx->nbuf = req_ctx->to_hash_later;
Lee Nipper497f2e62010-05-19 19:20:36 +10001692 }
1693 common_nonsnoop_hash_unmap(dev, edesc, areq);
1694
1695 kfree(edesc);
1696
1697 areq->base.complete(&areq->base, err);
1698}
1699
LEROY Christophe2d029052015-04-17 16:32:18 +02001700/*
1701 * SEC1 doesn't like hashing of 0 sized message, so we do the padding
1702 * ourself and submit a padded block
1703 */
LEROY Christophe5b2cf262017-10-06 15:04:47 +02001704static void talitos_handle_buggy_hash(struct talitos_ctx *ctx,
LEROY Christophe2d029052015-04-17 16:32:18 +02001705 struct talitos_edesc *edesc,
1706 struct talitos_ptr *ptr)
1707{
1708 static u8 padded_hash[64] = {
1709 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1710 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1711 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1712 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1713 };
1714
1715 pr_err_once("Bug in SEC1, padding ourself\n");
1716 edesc->desc.hdr &= ~DESC_HDR_MODE0_MDEU_PAD;
1717 map_single_talitos_ptr(ctx->dev, ptr, sizeof(padded_hash),
1718 (char *)padded_hash, DMA_TO_DEVICE);
1719}
1720
Lee Nipper497f2e62010-05-19 19:20:36 +10001721static int common_nonsnoop_hash(struct talitos_edesc *edesc,
1722 struct ahash_request *areq, unsigned int length,
1723 void (*callback) (struct device *dev,
1724 struct talitos_desc *desc,
1725 void *context, int error))
1726{
1727 struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq);
1728 struct talitos_ctx *ctx = crypto_ahash_ctx(tfm);
1729 struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
1730 struct device *dev = ctx->dev;
1731 struct talitos_desc *desc = &edesc->desc;
LEROY Christophe032d1972015-04-17 16:31:51 +02001732 int ret;
LEROY Christophe6a1e8d12016-06-06 13:20:38 +02001733 bool sync_needed = false;
LEROY Christophe922f9dc2015-04-17 16:32:07 +02001734 struct talitos_private *priv = dev_get_drvdata(dev);
1735 bool is_sec1 = has_ftr_sec1(priv);
LEROY Christophe6a1e8d12016-06-06 13:20:38 +02001736 int sg_count;
Lee Nipper497f2e62010-05-19 19:20:36 +10001737
1738 /* first DWORD empty */
Lee Nipper497f2e62010-05-19 19:20:36 +10001739
Kim Phillips60f208d2010-05-19 19:21:53 +10001740 /* hash context in */
1741 if (!req_ctx->first || req_ctx->swinit) {
Lee Nipper497f2e62010-05-19 19:20:36 +10001742 map_single_talitos_ptr(dev, &desc->ptr[1],
1743 req_ctx->hw_context_size,
LEROY Christophea2b35aa2015-04-17 16:31:57 +02001744 (char *)req_ctx->hw_context,
Lee Nipper497f2e62010-05-19 19:20:36 +10001745 DMA_TO_DEVICE);
Kim Phillips60f208d2010-05-19 19:21:53 +10001746 req_ctx->swinit = 0;
Lee Nipper497f2e62010-05-19 19:20:36 +10001747 }
LEROY Christopheafd62fa2017-09-13 12:44:51 +02001748 /* Indicate next op is not the first. */
1749 req_ctx->first = 0;
Lee Nipper497f2e62010-05-19 19:20:36 +10001750
1751 /* HMAC key */
1752 if (ctx->keylen)
1753 map_single_talitos_ptr(dev, &desc->ptr[2], ctx->keylen,
LEROY Christophea2b35aa2015-04-17 16:31:57 +02001754 (char *)&ctx->key, DMA_TO_DEVICE);
Lee Nipper497f2e62010-05-19 19:20:36 +10001755
LEROY Christophe6a1e8d12016-06-06 13:20:38 +02001756 sg_count = edesc->src_nents ?: 1;
1757 if (is_sec1 && sg_count > 1)
LEROY Christophe886a27c2017-09-13 12:44:57 +02001758 sg_copy_to_buffer(req_ctx->psrc, sg_count, edesc->buf, length);
LEROY Christophe6a1e8d12016-06-06 13:20:38 +02001759 else
1760 sg_count = dma_map_sg(dev, req_ctx->psrc, sg_count,
1761 DMA_TO_DEVICE);
Lee Nipper497f2e62010-05-19 19:20:36 +10001762 /*
1763 * data in
1764 */
LEROY Christophe6a1e8d12016-06-06 13:20:38 +02001765 sg_count = talitos_sg_map(dev, req_ctx->psrc, length, edesc,
1766 &desc->ptr[3], sg_count, 0, 0);
1767 if (sg_count > 1)
1768 sync_needed = true;
Lee Nipper497f2e62010-05-19 19:20:36 +10001769
1770 /* fifth DWORD empty */
Lee Nipper497f2e62010-05-19 19:20:36 +10001771
1772 /* hash/HMAC out -or- hash context out */
1773 if (req_ctx->last)
1774 map_single_talitos_ptr(dev, &desc->ptr[5],
1775 crypto_ahash_digestsize(tfm),
LEROY Christophea2b35aa2015-04-17 16:31:57 +02001776 areq->result, DMA_FROM_DEVICE);
Lee Nipper497f2e62010-05-19 19:20:36 +10001777 else
1778 map_single_talitos_ptr(dev, &desc->ptr[5],
1779 req_ctx->hw_context_size,
LEROY Christophea2b35aa2015-04-17 16:31:57 +02001780 req_ctx->hw_context, DMA_FROM_DEVICE);
Lee Nipper497f2e62010-05-19 19:20:36 +10001781
1782 /* last DWORD empty */
Lee Nipper497f2e62010-05-19 19:20:36 +10001783
LEROY Christophe2d029052015-04-17 16:32:18 +02001784 if (is_sec1 && from_talitos_ptr_len(&desc->ptr[3], true) == 0)
1785 talitos_handle_buggy_hash(ctx, edesc, &desc->ptr[3]);
1786
LEROY Christophe6a1e8d12016-06-06 13:20:38 +02001787 if (sync_needed)
1788 dma_sync_single_for_device(dev, edesc->dma_link_tbl,
1789 edesc->dma_len, DMA_BIDIRECTIONAL);
1790
Kim Phillips5228f0f2011-07-15 11:21:38 +08001791 ret = talitos_submit(dev, ctx->ch, desc, callback, areq);
Lee Nipper497f2e62010-05-19 19:20:36 +10001792 if (ret != -EINPROGRESS) {
1793 common_nonsnoop_hash_unmap(dev, edesc, areq);
1794 kfree(edesc);
1795 }
1796 return ret;
1797}
1798
1799static struct talitos_edesc *ahash_edesc_alloc(struct ahash_request *areq,
1800 unsigned int nbytes)
1801{
1802 struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq);
1803 struct talitos_ctx *ctx = crypto_ahash_ctx(tfm);
1804 struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
1805
Herbert Xuaeb4c132015-07-30 17:53:22 +08001806 return talitos_edesc_alloc(ctx->dev, req_ctx->psrc, NULL, NULL, 0,
Horia Geanta62293a32013-11-28 15:11:17 +02001807 nbytes, 0, 0, 0, areq->base.flags, false);
Lee Nipper497f2e62010-05-19 19:20:36 +10001808}
1809
1810static int ahash_init(struct ahash_request *areq)
1811{
1812 struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq);
1813 struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
1814
1815 /* Initialize the context */
Lee Nipper5e833bc2010-06-16 15:29:15 +10001816 req_ctx->nbuf = 0;
Kim Phillips60f208d2010-05-19 19:21:53 +10001817 req_ctx->first = 1; /* first indicates h/w must init its context */
1818 req_ctx->swinit = 0; /* assume h/w init of context */
Lee Nipper497f2e62010-05-19 19:20:36 +10001819 req_ctx->hw_context_size =
1820 (crypto_ahash_digestsize(tfm) <= SHA256_DIGEST_SIZE)
1821 ? TALITOS_MDEU_CONTEXT_SIZE_MD5_SHA1_SHA256
1822 : TALITOS_MDEU_CONTEXT_SIZE_SHA384_SHA512;
1823
1824 return 0;
1825}
1826
Kim Phillips60f208d2010-05-19 19:21:53 +10001827/*
1828 * on h/w without explicit sha224 support, we initialize h/w context
1829 * manually with sha224 constants, and tell it to run sha256.
1830 */
1831static int ahash_init_sha224_swinit(struct ahash_request *areq)
1832{
1833 struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
1834
1835 ahash_init(areq);
1836 req_ctx->swinit = 1;/* prevent h/w initting context with sha256 values*/
1837
Kim Phillipsa7524472010-09-23 15:56:38 +08001838 req_ctx->hw_context[0] = SHA224_H0;
1839 req_ctx->hw_context[1] = SHA224_H1;
1840 req_ctx->hw_context[2] = SHA224_H2;
1841 req_ctx->hw_context[3] = SHA224_H3;
1842 req_ctx->hw_context[4] = SHA224_H4;
1843 req_ctx->hw_context[5] = SHA224_H5;
1844 req_ctx->hw_context[6] = SHA224_H6;
1845 req_ctx->hw_context[7] = SHA224_H7;
Kim Phillips60f208d2010-05-19 19:21:53 +10001846
1847 /* init 64-bit count */
1848 req_ctx->hw_context[8] = 0;
1849 req_ctx->hw_context[9] = 0;
1850
1851 return 0;
1852}
1853
Lee Nipper497f2e62010-05-19 19:20:36 +10001854static int ahash_process_req(struct ahash_request *areq, unsigned int nbytes)
1855{
1856 struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq);
1857 struct talitos_ctx *ctx = crypto_ahash_ctx(tfm);
1858 struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
1859 struct talitos_edesc *edesc;
1860 unsigned int blocksize =
1861 crypto_tfm_alg_blocksize(crypto_ahash_tfm(tfm));
1862 unsigned int nbytes_to_hash;
1863 unsigned int to_hash_later;
Lee Nipper5e833bc2010-06-16 15:29:15 +10001864 unsigned int nsg;
LABBE Corentin8e409fe2015-11-04 21:13:34 +01001865 int nents;
Lee Nipper497f2e62010-05-19 19:20:36 +10001866
Lee Nipper5e833bc2010-06-16 15:29:15 +10001867 if (!req_ctx->last && (nbytes + req_ctx->nbuf <= blocksize)) {
1868 /* Buffer up to one whole block */
LABBE Corentin8e409fe2015-11-04 21:13:34 +01001869 nents = sg_nents_for_len(areq->src, nbytes);
1870 if (nents < 0) {
1871 dev_err(ctx->dev, "Invalid number of src SG.\n");
1872 return nents;
1873 }
1874 sg_copy_to_buffer(areq->src, nents,
Lee Nipper5e833bc2010-06-16 15:29:15 +10001875 req_ctx->buf + req_ctx->nbuf, nbytes);
1876 req_ctx->nbuf += nbytes;
Lee Nipper497f2e62010-05-19 19:20:36 +10001877 return 0;
1878 }
1879
Lee Nipper5e833bc2010-06-16 15:29:15 +10001880 /* At least (blocksize + 1) bytes are available to hash */
1881 nbytes_to_hash = nbytes + req_ctx->nbuf;
1882 to_hash_later = nbytes_to_hash & (blocksize - 1);
1883
1884 if (req_ctx->last)
1885 to_hash_later = 0;
1886 else if (to_hash_later)
1887 /* There is a partial block. Hash the full block(s) now */
1888 nbytes_to_hash -= to_hash_later;
1889 else {
1890 /* Keep one block buffered */
1891 nbytes_to_hash -= blocksize;
1892 to_hash_later = blocksize;
1893 }
1894
1895 /* Chain in any previously buffered data */
1896 if (req_ctx->nbuf) {
1897 nsg = (req_ctx->nbuf < nbytes_to_hash) ? 2 : 1;
1898 sg_init_table(req_ctx->bufsl, nsg);
1899 sg_set_buf(req_ctx->bufsl, req_ctx->buf, req_ctx->nbuf);
1900 if (nsg > 1)
Dan Williamsc56f6d12015-08-07 18:15:13 +02001901 sg_chain(req_ctx->bufsl, 2, areq->src);
Lee Nipper497f2e62010-05-19 19:20:36 +10001902 req_ctx->psrc = req_ctx->bufsl;
Lee Nipper5e833bc2010-06-16 15:29:15 +10001903 } else
Lee Nipper497f2e62010-05-19 19:20:36 +10001904 req_ctx->psrc = areq->src;
Lee Nipper497f2e62010-05-19 19:20:36 +10001905
Lee Nipper5e833bc2010-06-16 15:29:15 +10001906 if (to_hash_later) {
LABBE Corentin8e409fe2015-11-04 21:13:34 +01001907 nents = sg_nents_for_len(areq->src, nbytes);
1908 if (nents < 0) {
1909 dev_err(ctx->dev, "Invalid number of src SG.\n");
1910 return nents;
1911 }
Akinobu Mitad0525722013-07-08 16:01:55 -07001912 sg_pcopy_to_buffer(areq->src, nents,
Lee Nipper5e833bc2010-06-16 15:29:15 +10001913 req_ctx->bufnext,
1914 to_hash_later,
1915 nbytes - to_hash_later);
Lee Nipper497f2e62010-05-19 19:20:36 +10001916 }
Lee Nipper5e833bc2010-06-16 15:29:15 +10001917 req_ctx->to_hash_later = to_hash_later;
Lee Nipper497f2e62010-05-19 19:20:36 +10001918
Lee Nipper5e833bc2010-06-16 15:29:15 +10001919 /* Allocate extended descriptor */
Lee Nipper497f2e62010-05-19 19:20:36 +10001920 edesc = ahash_edesc_alloc(areq, nbytes_to_hash);
1921 if (IS_ERR(edesc))
1922 return PTR_ERR(edesc);
1923
1924 edesc->desc.hdr = ctx->desc_hdr_template;
1925
1926 /* On last one, request SEC to pad; otherwise continue */
1927 if (req_ctx->last)
1928 edesc->desc.hdr |= DESC_HDR_MODE0_MDEU_PAD;
1929 else
1930 edesc->desc.hdr |= DESC_HDR_MODE0_MDEU_CONT;
1931
Kim Phillips60f208d2010-05-19 19:21:53 +10001932 /* request SEC to INIT hash. */
1933 if (req_ctx->first && !req_ctx->swinit)
Lee Nipper497f2e62010-05-19 19:20:36 +10001934 edesc->desc.hdr |= DESC_HDR_MODE0_MDEU_INIT;
1935
1936 /* When the tfm context has a keylen, it's an HMAC.
1937 * A first or last (ie. not middle) descriptor must request HMAC.
1938 */
1939 if (ctx->keylen && (req_ctx->first || req_ctx->last))
1940 edesc->desc.hdr |= DESC_HDR_MODE0_MDEU_HMAC;
1941
1942 return common_nonsnoop_hash(edesc, areq, nbytes_to_hash,
1943 ahash_done);
1944}
1945
1946static int ahash_update(struct ahash_request *areq)
1947{
1948 struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
1949
1950 req_ctx->last = 0;
1951
1952 return ahash_process_req(areq, areq->nbytes);
1953}
1954
1955static int ahash_final(struct ahash_request *areq)
1956{
1957 struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
1958
1959 req_ctx->last = 1;
1960
1961 return ahash_process_req(areq, 0);
1962}
1963
1964static int ahash_finup(struct ahash_request *areq)
1965{
1966 struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
1967
1968 req_ctx->last = 1;
1969
1970 return ahash_process_req(areq, areq->nbytes);
1971}
1972
1973static int ahash_digest(struct ahash_request *areq)
1974{
1975 struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
Kim Phillips60f208d2010-05-19 19:21:53 +10001976 struct crypto_ahash *ahash = crypto_ahash_reqtfm(areq);
Lee Nipper497f2e62010-05-19 19:20:36 +10001977
Kim Phillips60f208d2010-05-19 19:21:53 +10001978 ahash->init(areq);
Lee Nipper497f2e62010-05-19 19:20:36 +10001979 req_ctx->last = 1;
1980
1981 return ahash_process_req(areq, areq->nbytes);
1982}
1983
Horia Geant?3639ca82016-04-21 19:24:55 +03001984static int ahash_export(struct ahash_request *areq, void *out)
1985{
1986 struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
1987 struct talitos_export_state *export = out;
1988
1989 memcpy(export->hw_context, req_ctx->hw_context,
1990 req_ctx->hw_context_size);
1991 memcpy(export->buf, req_ctx->buf, req_ctx->nbuf);
1992 export->swinit = req_ctx->swinit;
1993 export->first = req_ctx->first;
1994 export->last = req_ctx->last;
1995 export->to_hash_later = req_ctx->to_hash_later;
1996 export->nbuf = req_ctx->nbuf;
1997
1998 return 0;
1999}
2000
2001static int ahash_import(struct ahash_request *areq, const void *in)
2002{
2003 struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
2004 struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq);
2005 const struct talitos_export_state *export = in;
2006
2007 memset(req_ctx, 0, sizeof(*req_ctx));
2008 req_ctx->hw_context_size =
2009 (crypto_ahash_digestsize(tfm) <= SHA256_DIGEST_SIZE)
2010 ? TALITOS_MDEU_CONTEXT_SIZE_MD5_SHA1_SHA256
2011 : TALITOS_MDEU_CONTEXT_SIZE_SHA384_SHA512;
2012 memcpy(req_ctx->hw_context, export->hw_context,
2013 req_ctx->hw_context_size);
2014 memcpy(req_ctx->buf, export->buf, export->nbuf);
2015 req_ctx->swinit = export->swinit;
2016 req_ctx->first = export->first;
2017 req_ctx->last = export->last;
2018 req_ctx->to_hash_later = export->to_hash_later;
2019 req_ctx->nbuf = export->nbuf;
2020
2021 return 0;
2022}
2023
Lee Nipper79b3a412011-11-21 16:13:25 +08002024struct keyhash_result {
2025 struct completion completion;
2026 int err;
2027};
2028
2029static void keyhash_complete(struct crypto_async_request *req, int err)
2030{
2031 struct keyhash_result *res = req->data;
2032
2033 if (err == -EINPROGRESS)
2034 return;
2035
2036 res->err = err;
2037 complete(&res->completion);
2038}
2039
2040static int keyhash(struct crypto_ahash *tfm, const u8 *key, unsigned int keylen,
2041 u8 *hash)
2042{
2043 struct talitos_ctx *ctx = crypto_tfm_ctx(crypto_ahash_tfm(tfm));
2044
2045 struct scatterlist sg[1];
2046 struct ahash_request *req;
2047 struct keyhash_result hresult;
2048 int ret;
2049
2050 init_completion(&hresult.completion);
2051
2052 req = ahash_request_alloc(tfm, GFP_KERNEL);
2053 if (!req)
2054 return -ENOMEM;
2055
2056 /* Keep tfm keylen == 0 during hash of the long key */
2057 ctx->keylen = 0;
2058 ahash_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
2059 keyhash_complete, &hresult);
2060
2061 sg_init_one(&sg[0], key, keylen);
2062
2063 ahash_request_set_crypt(req, sg, hash, keylen);
2064 ret = crypto_ahash_digest(req);
2065 switch (ret) {
2066 case 0:
2067 break;
2068 case -EINPROGRESS:
2069 case -EBUSY:
2070 ret = wait_for_completion_interruptible(
2071 &hresult.completion);
2072 if (!ret)
2073 ret = hresult.err;
2074 break;
2075 default:
2076 break;
2077 }
2078 ahash_request_free(req);
2079
2080 return ret;
2081}
2082
2083static int ahash_setkey(struct crypto_ahash *tfm, const u8 *key,
2084 unsigned int keylen)
2085{
2086 struct talitos_ctx *ctx = crypto_tfm_ctx(crypto_ahash_tfm(tfm));
2087 unsigned int blocksize =
2088 crypto_tfm_alg_blocksize(crypto_ahash_tfm(tfm));
2089 unsigned int digestsize = crypto_ahash_digestsize(tfm);
2090 unsigned int keysize = keylen;
2091 u8 hash[SHA512_DIGEST_SIZE];
2092 int ret;
2093
2094 if (keylen <= blocksize)
2095 memcpy(ctx->key, key, keysize);
2096 else {
2097 /* Must get the hash of the long key */
2098 ret = keyhash(tfm, key, keylen, hash);
2099
2100 if (ret) {
2101 crypto_ahash_set_flags(tfm, CRYPTO_TFM_RES_BAD_KEY_LEN);
2102 return -EINVAL;
2103 }
2104
2105 keysize = digestsize;
2106 memcpy(ctx->key, hash, digestsize);
2107 }
2108
2109 ctx->keylen = keysize;
2110
2111 return 0;
2112}
2113
2114
Kim Phillips9c4a7962008-06-23 19:50:15 +08002115struct talitos_alg_template {
Lee Nipperd5e4aae2010-05-19 19:18:38 +10002116 u32 type;
LEROY Christopheb0057762016-06-06 13:20:44 +02002117 u32 priority;
Lee Nipperd5e4aae2010-05-19 19:18:38 +10002118 union {
2119 struct crypto_alg crypto;
Lee Nipperacbf7c622010-05-19 19:19:33 +10002120 struct ahash_alg hash;
Herbert Xuaeb4c132015-07-30 17:53:22 +08002121 struct aead_alg aead;
Lee Nipperd5e4aae2010-05-19 19:18:38 +10002122 } alg;
Kim Phillips9c4a7962008-06-23 19:50:15 +08002123 __be32 desc_hdr_template;
2124};
2125
2126static struct talitos_alg_template driver_algs[] = {
Horia Geanta991155b2013-03-20 16:31:38 +02002127 /* AEAD algorithms. These use a single-pass ipsec_esp descriptor */
Lee Nipperd5e4aae2010-05-19 19:18:38 +10002128 { .type = CRYPTO_ALG_TYPE_AEAD,
Herbert Xuaeb4c132015-07-30 17:53:22 +08002129 .alg.aead = {
2130 .base = {
2131 .cra_name = "authenc(hmac(sha1),cbc(aes))",
2132 .cra_driver_name = "authenc-hmac-sha1-"
2133 "cbc-aes-talitos",
2134 .cra_blocksize = AES_BLOCK_SIZE,
2135 .cra_flags = CRYPTO_ALG_ASYNC,
2136 },
2137 .ivsize = AES_BLOCK_SIZE,
2138 .maxauthsize = SHA1_DIGEST_SIZE,
Lee Nipper56af8cd2009-03-29 15:50:50 +08002139 },
Kim Phillips9c4a7962008-06-23 19:50:15 +08002140 .desc_hdr_template = DESC_HDR_TYPE_IPSEC_ESP |
2141 DESC_HDR_SEL0_AESU |
2142 DESC_HDR_MODE0_AESU_CBC |
2143 DESC_HDR_SEL1_MDEUA |
2144 DESC_HDR_MODE1_MDEU_INIT |
2145 DESC_HDR_MODE1_MDEU_PAD |
2146 DESC_HDR_MODE1_MDEU_SHA1_HMAC,
Lee Nipper70bcaca2008-07-03 19:08:46 +08002147 },
Lee Nipperd5e4aae2010-05-19 19:18:38 +10002148 { .type = CRYPTO_ALG_TYPE_AEAD,
LEROY Christophe7405c8d2016-06-06 13:20:46 +02002149 .priority = TALITOS_CRA_PRIORITY_AEAD_HSNA,
2150 .alg.aead = {
2151 .base = {
2152 .cra_name = "authenc(hmac(sha1),cbc(aes))",
2153 .cra_driver_name = "authenc-hmac-sha1-"
2154 "cbc-aes-talitos",
2155 .cra_blocksize = AES_BLOCK_SIZE,
2156 .cra_flags = CRYPTO_ALG_ASYNC,
2157 },
2158 .ivsize = AES_BLOCK_SIZE,
2159 .maxauthsize = SHA1_DIGEST_SIZE,
2160 },
2161 .desc_hdr_template = DESC_HDR_TYPE_HMAC_SNOOP_NO_AFEU |
2162 DESC_HDR_SEL0_AESU |
2163 DESC_HDR_MODE0_AESU_CBC |
2164 DESC_HDR_SEL1_MDEUA |
2165 DESC_HDR_MODE1_MDEU_INIT |
2166 DESC_HDR_MODE1_MDEU_PAD |
2167 DESC_HDR_MODE1_MDEU_SHA1_HMAC,
2168 },
2169 { .type = CRYPTO_ALG_TYPE_AEAD,
Herbert Xuaeb4c132015-07-30 17:53:22 +08002170 .alg.aead = {
2171 .base = {
2172 .cra_name = "authenc(hmac(sha1),"
2173 "cbc(des3_ede))",
2174 .cra_driver_name = "authenc-hmac-sha1-"
2175 "cbc-3des-talitos",
2176 .cra_blocksize = DES3_EDE_BLOCK_SIZE,
2177 .cra_flags = CRYPTO_ALG_ASYNC,
2178 },
2179 .ivsize = DES3_EDE_BLOCK_SIZE,
2180 .maxauthsize = SHA1_DIGEST_SIZE,
Lee Nipper56af8cd2009-03-29 15:50:50 +08002181 },
Lee Nipper70bcaca2008-07-03 19:08:46 +08002182 .desc_hdr_template = DESC_HDR_TYPE_IPSEC_ESP |
2183 DESC_HDR_SEL0_DEU |
2184 DESC_HDR_MODE0_DEU_CBC |
2185 DESC_HDR_MODE0_DEU_3DES |
2186 DESC_HDR_SEL1_MDEUA |
2187 DESC_HDR_MODE1_MDEU_INIT |
2188 DESC_HDR_MODE1_MDEU_PAD |
2189 DESC_HDR_MODE1_MDEU_SHA1_HMAC,
Lee Nipper3952f172008-07-10 18:29:18 +08002190 },
LEROY Christophe7405c8d2016-06-06 13:20:46 +02002191 { .type = CRYPTO_ALG_TYPE_AEAD,
2192 .priority = TALITOS_CRA_PRIORITY_AEAD_HSNA,
2193 .alg.aead = {
2194 .base = {
2195 .cra_name = "authenc(hmac(sha1),"
2196 "cbc(des3_ede))",
2197 .cra_driver_name = "authenc-hmac-sha1-"
2198 "cbc-3des-talitos",
2199 .cra_blocksize = DES3_EDE_BLOCK_SIZE,
2200 .cra_flags = CRYPTO_ALG_ASYNC,
2201 },
2202 .ivsize = DES3_EDE_BLOCK_SIZE,
2203 .maxauthsize = SHA1_DIGEST_SIZE,
2204 },
2205 .desc_hdr_template = DESC_HDR_TYPE_HMAC_SNOOP_NO_AFEU |
2206 DESC_HDR_SEL0_DEU |
2207 DESC_HDR_MODE0_DEU_CBC |
2208 DESC_HDR_MODE0_DEU_3DES |
2209 DESC_HDR_SEL1_MDEUA |
2210 DESC_HDR_MODE1_MDEU_INIT |
2211 DESC_HDR_MODE1_MDEU_PAD |
2212 DESC_HDR_MODE1_MDEU_SHA1_HMAC,
2213 },
Horia Geanta357fb602012-07-03 19:16:53 +03002214 { .type = CRYPTO_ALG_TYPE_AEAD,
Herbert Xuaeb4c132015-07-30 17:53:22 +08002215 .alg.aead = {
2216 .base = {
2217 .cra_name = "authenc(hmac(sha224),cbc(aes))",
2218 .cra_driver_name = "authenc-hmac-sha224-"
2219 "cbc-aes-talitos",
2220 .cra_blocksize = AES_BLOCK_SIZE,
2221 .cra_flags = CRYPTO_ALG_ASYNC,
2222 },
2223 .ivsize = AES_BLOCK_SIZE,
2224 .maxauthsize = SHA224_DIGEST_SIZE,
Horia Geanta357fb602012-07-03 19:16:53 +03002225 },
2226 .desc_hdr_template = DESC_HDR_TYPE_IPSEC_ESP |
2227 DESC_HDR_SEL0_AESU |
2228 DESC_HDR_MODE0_AESU_CBC |
2229 DESC_HDR_SEL1_MDEUA |
2230 DESC_HDR_MODE1_MDEU_INIT |
2231 DESC_HDR_MODE1_MDEU_PAD |
2232 DESC_HDR_MODE1_MDEU_SHA224_HMAC,
2233 },
LEROY Christophe7405c8d2016-06-06 13:20:46 +02002234 { .type = CRYPTO_ALG_TYPE_AEAD,
2235 .priority = TALITOS_CRA_PRIORITY_AEAD_HSNA,
2236 .alg.aead = {
2237 .base = {
2238 .cra_name = "authenc(hmac(sha224),cbc(aes))",
2239 .cra_driver_name = "authenc-hmac-sha224-"
2240 "cbc-aes-talitos",
2241 .cra_blocksize = AES_BLOCK_SIZE,
2242 .cra_flags = CRYPTO_ALG_ASYNC,
2243 },
2244 .ivsize = AES_BLOCK_SIZE,
2245 .maxauthsize = SHA224_DIGEST_SIZE,
2246 },
2247 .desc_hdr_template = DESC_HDR_TYPE_HMAC_SNOOP_NO_AFEU |
2248 DESC_HDR_SEL0_AESU |
2249 DESC_HDR_MODE0_AESU_CBC |
2250 DESC_HDR_SEL1_MDEUA |
2251 DESC_HDR_MODE1_MDEU_INIT |
2252 DESC_HDR_MODE1_MDEU_PAD |
2253 DESC_HDR_MODE1_MDEU_SHA224_HMAC,
2254 },
Horia Geanta357fb602012-07-03 19:16:53 +03002255 { .type = CRYPTO_ALG_TYPE_AEAD,
Herbert Xuaeb4c132015-07-30 17:53:22 +08002256 .alg.aead = {
2257 .base = {
2258 .cra_name = "authenc(hmac(sha224),"
2259 "cbc(des3_ede))",
2260 .cra_driver_name = "authenc-hmac-sha224-"
2261 "cbc-3des-talitos",
2262 .cra_blocksize = DES3_EDE_BLOCK_SIZE,
2263 .cra_flags = CRYPTO_ALG_ASYNC,
2264 },
2265 .ivsize = DES3_EDE_BLOCK_SIZE,
2266 .maxauthsize = SHA224_DIGEST_SIZE,
Horia Geanta357fb602012-07-03 19:16:53 +03002267 },
2268 .desc_hdr_template = DESC_HDR_TYPE_IPSEC_ESP |
2269 DESC_HDR_SEL0_DEU |
2270 DESC_HDR_MODE0_DEU_CBC |
2271 DESC_HDR_MODE0_DEU_3DES |
2272 DESC_HDR_SEL1_MDEUA |
2273 DESC_HDR_MODE1_MDEU_INIT |
2274 DESC_HDR_MODE1_MDEU_PAD |
2275 DESC_HDR_MODE1_MDEU_SHA224_HMAC,
2276 },
Lee Nipperd5e4aae2010-05-19 19:18:38 +10002277 { .type = CRYPTO_ALG_TYPE_AEAD,
LEROY Christophe7405c8d2016-06-06 13:20:46 +02002278 .priority = TALITOS_CRA_PRIORITY_AEAD_HSNA,
2279 .alg.aead = {
2280 .base = {
2281 .cra_name = "authenc(hmac(sha224),"
2282 "cbc(des3_ede))",
2283 .cra_driver_name = "authenc-hmac-sha224-"
2284 "cbc-3des-talitos",
2285 .cra_blocksize = DES3_EDE_BLOCK_SIZE,
2286 .cra_flags = CRYPTO_ALG_ASYNC,
2287 },
2288 .ivsize = DES3_EDE_BLOCK_SIZE,
2289 .maxauthsize = SHA224_DIGEST_SIZE,
2290 },
2291 .desc_hdr_template = DESC_HDR_TYPE_HMAC_SNOOP_NO_AFEU |
2292 DESC_HDR_SEL0_DEU |
2293 DESC_HDR_MODE0_DEU_CBC |
2294 DESC_HDR_MODE0_DEU_3DES |
2295 DESC_HDR_SEL1_MDEUA |
2296 DESC_HDR_MODE1_MDEU_INIT |
2297 DESC_HDR_MODE1_MDEU_PAD |
2298 DESC_HDR_MODE1_MDEU_SHA224_HMAC,
2299 },
2300 { .type = CRYPTO_ALG_TYPE_AEAD,
Herbert Xuaeb4c132015-07-30 17:53:22 +08002301 .alg.aead = {
2302 .base = {
2303 .cra_name = "authenc(hmac(sha256),cbc(aes))",
2304 .cra_driver_name = "authenc-hmac-sha256-"
2305 "cbc-aes-talitos",
2306 .cra_blocksize = AES_BLOCK_SIZE,
2307 .cra_flags = CRYPTO_ALG_ASYNC,
2308 },
2309 .ivsize = AES_BLOCK_SIZE,
2310 .maxauthsize = SHA256_DIGEST_SIZE,
Lee Nipper56af8cd2009-03-29 15:50:50 +08002311 },
Lee Nipper3952f172008-07-10 18:29:18 +08002312 .desc_hdr_template = DESC_HDR_TYPE_IPSEC_ESP |
2313 DESC_HDR_SEL0_AESU |
2314 DESC_HDR_MODE0_AESU_CBC |
2315 DESC_HDR_SEL1_MDEUA |
2316 DESC_HDR_MODE1_MDEU_INIT |
2317 DESC_HDR_MODE1_MDEU_PAD |
2318 DESC_HDR_MODE1_MDEU_SHA256_HMAC,
2319 },
Lee Nipperd5e4aae2010-05-19 19:18:38 +10002320 { .type = CRYPTO_ALG_TYPE_AEAD,
LEROY Christophe7405c8d2016-06-06 13:20:46 +02002321 .priority = TALITOS_CRA_PRIORITY_AEAD_HSNA,
2322 .alg.aead = {
2323 .base = {
2324 .cra_name = "authenc(hmac(sha256),cbc(aes))",
2325 .cra_driver_name = "authenc-hmac-sha256-"
2326 "cbc-aes-talitos",
2327 .cra_blocksize = AES_BLOCK_SIZE,
2328 .cra_flags = CRYPTO_ALG_ASYNC,
2329 },
2330 .ivsize = AES_BLOCK_SIZE,
2331 .maxauthsize = SHA256_DIGEST_SIZE,
2332 },
2333 .desc_hdr_template = DESC_HDR_TYPE_HMAC_SNOOP_NO_AFEU |
2334 DESC_HDR_SEL0_AESU |
2335 DESC_HDR_MODE0_AESU_CBC |
2336 DESC_HDR_SEL1_MDEUA |
2337 DESC_HDR_MODE1_MDEU_INIT |
2338 DESC_HDR_MODE1_MDEU_PAD |
2339 DESC_HDR_MODE1_MDEU_SHA256_HMAC,
2340 },
2341 { .type = CRYPTO_ALG_TYPE_AEAD,
Herbert Xuaeb4c132015-07-30 17:53:22 +08002342 .alg.aead = {
2343 .base = {
2344 .cra_name = "authenc(hmac(sha256),"
2345 "cbc(des3_ede))",
2346 .cra_driver_name = "authenc-hmac-sha256-"
2347 "cbc-3des-talitos",
2348 .cra_blocksize = DES3_EDE_BLOCK_SIZE,
2349 .cra_flags = CRYPTO_ALG_ASYNC,
2350 },
2351 .ivsize = DES3_EDE_BLOCK_SIZE,
2352 .maxauthsize = SHA256_DIGEST_SIZE,
Lee Nipper56af8cd2009-03-29 15:50:50 +08002353 },
Lee Nipper3952f172008-07-10 18:29:18 +08002354 .desc_hdr_template = DESC_HDR_TYPE_IPSEC_ESP |
2355 DESC_HDR_SEL0_DEU |
2356 DESC_HDR_MODE0_DEU_CBC |
2357 DESC_HDR_MODE0_DEU_3DES |
2358 DESC_HDR_SEL1_MDEUA |
2359 DESC_HDR_MODE1_MDEU_INIT |
2360 DESC_HDR_MODE1_MDEU_PAD |
2361 DESC_HDR_MODE1_MDEU_SHA256_HMAC,
2362 },
Lee Nipperd5e4aae2010-05-19 19:18:38 +10002363 { .type = CRYPTO_ALG_TYPE_AEAD,
LEROY Christophe7405c8d2016-06-06 13:20:46 +02002364 .priority = TALITOS_CRA_PRIORITY_AEAD_HSNA,
2365 .alg.aead = {
2366 .base = {
2367 .cra_name = "authenc(hmac(sha256),"
2368 "cbc(des3_ede))",
2369 .cra_driver_name = "authenc-hmac-sha256-"
2370 "cbc-3des-talitos",
2371 .cra_blocksize = DES3_EDE_BLOCK_SIZE,
2372 .cra_flags = CRYPTO_ALG_ASYNC,
2373 },
2374 .ivsize = DES3_EDE_BLOCK_SIZE,
2375 .maxauthsize = SHA256_DIGEST_SIZE,
2376 },
2377 .desc_hdr_template = DESC_HDR_TYPE_HMAC_SNOOP_NO_AFEU |
2378 DESC_HDR_SEL0_DEU |
2379 DESC_HDR_MODE0_DEU_CBC |
2380 DESC_HDR_MODE0_DEU_3DES |
2381 DESC_HDR_SEL1_MDEUA |
2382 DESC_HDR_MODE1_MDEU_INIT |
2383 DESC_HDR_MODE1_MDEU_PAD |
2384 DESC_HDR_MODE1_MDEU_SHA256_HMAC,
2385 },
2386 { .type = CRYPTO_ALG_TYPE_AEAD,
Herbert Xuaeb4c132015-07-30 17:53:22 +08002387 .alg.aead = {
2388 .base = {
2389 .cra_name = "authenc(hmac(sha384),cbc(aes))",
2390 .cra_driver_name = "authenc-hmac-sha384-"
2391 "cbc-aes-talitos",
2392 .cra_blocksize = AES_BLOCK_SIZE,
2393 .cra_flags = CRYPTO_ALG_ASYNC,
2394 },
2395 .ivsize = AES_BLOCK_SIZE,
2396 .maxauthsize = SHA384_DIGEST_SIZE,
Horia Geanta357fb602012-07-03 19:16:53 +03002397 },
2398 .desc_hdr_template = DESC_HDR_TYPE_IPSEC_ESP |
2399 DESC_HDR_SEL0_AESU |
2400 DESC_HDR_MODE0_AESU_CBC |
2401 DESC_HDR_SEL1_MDEUB |
2402 DESC_HDR_MODE1_MDEU_INIT |
2403 DESC_HDR_MODE1_MDEU_PAD |
2404 DESC_HDR_MODE1_MDEUB_SHA384_HMAC,
2405 },
2406 { .type = CRYPTO_ALG_TYPE_AEAD,
Herbert Xuaeb4c132015-07-30 17:53:22 +08002407 .alg.aead = {
2408 .base = {
2409 .cra_name = "authenc(hmac(sha384),"
2410 "cbc(des3_ede))",
2411 .cra_driver_name = "authenc-hmac-sha384-"
2412 "cbc-3des-talitos",
2413 .cra_blocksize = DES3_EDE_BLOCK_SIZE,
2414 .cra_flags = CRYPTO_ALG_ASYNC,
2415 },
2416 .ivsize = DES3_EDE_BLOCK_SIZE,
2417 .maxauthsize = SHA384_DIGEST_SIZE,
Horia Geanta357fb602012-07-03 19:16:53 +03002418 },
2419 .desc_hdr_template = DESC_HDR_TYPE_IPSEC_ESP |
2420 DESC_HDR_SEL0_DEU |
2421 DESC_HDR_MODE0_DEU_CBC |
2422 DESC_HDR_MODE0_DEU_3DES |
2423 DESC_HDR_SEL1_MDEUB |
2424 DESC_HDR_MODE1_MDEU_INIT |
2425 DESC_HDR_MODE1_MDEU_PAD |
2426 DESC_HDR_MODE1_MDEUB_SHA384_HMAC,
2427 },
2428 { .type = CRYPTO_ALG_TYPE_AEAD,
Herbert Xuaeb4c132015-07-30 17:53:22 +08002429 .alg.aead = {
2430 .base = {
2431 .cra_name = "authenc(hmac(sha512),cbc(aes))",
2432 .cra_driver_name = "authenc-hmac-sha512-"
2433 "cbc-aes-talitos",
2434 .cra_blocksize = AES_BLOCK_SIZE,
2435 .cra_flags = CRYPTO_ALG_ASYNC,
2436 },
2437 .ivsize = AES_BLOCK_SIZE,
2438 .maxauthsize = SHA512_DIGEST_SIZE,
Horia Geanta357fb602012-07-03 19:16:53 +03002439 },
2440 .desc_hdr_template = DESC_HDR_TYPE_IPSEC_ESP |
2441 DESC_HDR_SEL0_AESU |
2442 DESC_HDR_MODE0_AESU_CBC |
2443 DESC_HDR_SEL1_MDEUB |
2444 DESC_HDR_MODE1_MDEU_INIT |
2445 DESC_HDR_MODE1_MDEU_PAD |
2446 DESC_HDR_MODE1_MDEUB_SHA512_HMAC,
2447 },
2448 { .type = CRYPTO_ALG_TYPE_AEAD,
Herbert Xuaeb4c132015-07-30 17:53:22 +08002449 .alg.aead = {
2450 .base = {
2451 .cra_name = "authenc(hmac(sha512),"
2452 "cbc(des3_ede))",
2453 .cra_driver_name = "authenc-hmac-sha512-"
2454 "cbc-3des-talitos",
2455 .cra_blocksize = DES3_EDE_BLOCK_SIZE,
2456 .cra_flags = CRYPTO_ALG_ASYNC,
2457 },
2458 .ivsize = DES3_EDE_BLOCK_SIZE,
2459 .maxauthsize = SHA512_DIGEST_SIZE,
Horia Geanta357fb602012-07-03 19:16:53 +03002460 },
2461 .desc_hdr_template = DESC_HDR_TYPE_IPSEC_ESP |
2462 DESC_HDR_SEL0_DEU |
2463 DESC_HDR_MODE0_DEU_CBC |
2464 DESC_HDR_MODE0_DEU_3DES |
2465 DESC_HDR_SEL1_MDEUB |
2466 DESC_HDR_MODE1_MDEU_INIT |
2467 DESC_HDR_MODE1_MDEU_PAD |
2468 DESC_HDR_MODE1_MDEUB_SHA512_HMAC,
2469 },
2470 { .type = CRYPTO_ALG_TYPE_AEAD,
Herbert Xuaeb4c132015-07-30 17:53:22 +08002471 .alg.aead = {
2472 .base = {
2473 .cra_name = "authenc(hmac(md5),cbc(aes))",
2474 .cra_driver_name = "authenc-hmac-md5-"
2475 "cbc-aes-talitos",
2476 .cra_blocksize = AES_BLOCK_SIZE,
2477 .cra_flags = CRYPTO_ALG_ASYNC,
2478 },
2479 .ivsize = AES_BLOCK_SIZE,
2480 .maxauthsize = MD5_DIGEST_SIZE,
Lee Nipper56af8cd2009-03-29 15:50:50 +08002481 },
Lee Nipper3952f172008-07-10 18:29:18 +08002482 .desc_hdr_template = DESC_HDR_TYPE_IPSEC_ESP |
2483 DESC_HDR_SEL0_AESU |
2484 DESC_HDR_MODE0_AESU_CBC |
2485 DESC_HDR_SEL1_MDEUA |
2486 DESC_HDR_MODE1_MDEU_INIT |
2487 DESC_HDR_MODE1_MDEU_PAD |
2488 DESC_HDR_MODE1_MDEU_MD5_HMAC,
2489 },
Lee Nipperd5e4aae2010-05-19 19:18:38 +10002490 { .type = CRYPTO_ALG_TYPE_AEAD,
LEROY Christophe7405c8d2016-06-06 13:20:46 +02002491 .priority = TALITOS_CRA_PRIORITY_AEAD_HSNA,
2492 .alg.aead = {
2493 .base = {
2494 .cra_name = "authenc(hmac(md5),cbc(aes))",
2495 .cra_driver_name = "authenc-hmac-md5-"
2496 "cbc-aes-talitos",
2497 .cra_blocksize = AES_BLOCK_SIZE,
2498 .cra_flags = CRYPTO_ALG_ASYNC,
2499 },
2500 .ivsize = AES_BLOCK_SIZE,
2501 .maxauthsize = MD5_DIGEST_SIZE,
2502 },
2503 .desc_hdr_template = DESC_HDR_TYPE_HMAC_SNOOP_NO_AFEU |
2504 DESC_HDR_SEL0_AESU |
2505 DESC_HDR_MODE0_AESU_CBC |
2506 DESC_HDR_SEL1_MDEUA |
2507 DESC_HDR_MODE1_MDEU_INIT |
2508 DESC_HDR_MODE1_MDEU_PAD |
2509 DESC_HDR_MODE1_MDEU_MD5_HMAC,
2510 },
2511 { .type = CRYPTO_ALG_TYPE_AEAD,
Herbert Xuaeb4c132015-07-30 17:53:22 +08002512 .alg.aead = {
2513 .base = {
2514 .cra_name = "authenc(hmac(md5),cbc(des3_ede))",
2515 .cra_driver_name = "authenc-hmac-md5-"
2516 "cbc-3des-talitos",
2517 .cra_blocksize = DES3_EDE_BLOCK_SIZE,
2518 .cra_flags = CRYPTO_ALG_ASYNC,
2519 },
2520 .ivsize = DES3_EDE_BLOCK_SIZE,
2521 .maxauthsize = MD5_DIGEST_SIZE,
Lee Nipper56af8cd2009-03-29 15:50:50 +08002522 },
Lee Nipper3952f172008-07-10 18:29:18 +08002523 .desc_hdr_template = DESC_HDR_TYPE_IPSEC_ESP |
2524 DESC_HDR_SEL0_DEU |
2525 DESC_HDR_MODE0_DEU_CBC |
2526 DESC_HDR_MODE0_DEU_3DES |
2527 DESC_HDR_SEL1_MDEUA |
2528 DESC_HDR_MODE1_MDEU_INIT |
2529 DESC_HDR_MODE1_MDEU_PAD |
2530 DESC_HDR_MODE1_MDEU_MD5_HMAC,
Lee Nipper4de9d0b2009-03-29 15:52:32 +08002531 },
LEROY Christophe7405c8d2016-06-06 13:20:46 +02002532 { .type = CRYPTO_ALG_TYPE_AEAD,
2533 .priority = TALITOS_CRA_PRIORITY_AEAD_HSNA,
2534 .alg.aead = {
2535 .base = {
2536 .cra_name = "authenc(hmac(md5),cbc(des3_ede))",
2537 .cra_driver_name = "authenc-hmac-md5-"
2538 "cbc-3des-talitos",
2539 .cra_blocksize = DES3_EDE_BLOCK_SIZE,
2540 .cra_flags = CRYPTO_ALG_ASYNC,
2541 },
2542 .ivsize = DES3_EDE_BLOCK_SIZE,
2543 .maxauthsize = MD5_DIGEST_SIZE,
2544 },
2545 .desc_hdr_template = DESC_HDR_TYPE_HMAC_SNOOP_NO_AFEU |
2546 DESC_HDR_SEL0_DEU |
2547 DESC_HDR_MODE0_DEU_CBC |
2548 DESC_HDR_MODE0_DEU_3DES |
2549 DESC_HDR_SEL1_MDEUA |
2550 DESC_HDR_MODE1_MDEU_INIT |
2551 DESC_HDR_MODE1_MDEU_PAD |
2552 DESC_HDR_MODE1_MDEU_MD5_HMAC,
2553 },
Lee Nipper4de9d0b2009-03-29 15:52:32 +08002554 /* ABLKCIPHER algorithms. */
Lee Nipperd5e4aae2010-05-19 19:18:38 +10002555 { .type = CRYPTO_ALG_TYPE_ABLKCIPHER,
2556 .alg.crypto = {
LEROY Christophe5e75ae12015-12-01 12:44:15 +01002557 .cra_name = "ecb(aes)",
2558 .cra_driver_name = "ecb-aes-talitos",
2559 .cra_blocksize = AES_BLOCK_SIZE,
2560 .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER |
2561 CRYPTO_ALG_ASYNC,
2562 .cra_ablkcipher = {
2563 .min_keysize = AES_MIN_KEY_SIZE,
2564 .max_keysize = AES_MAX_KEY_SIZE,
2565 .ivsize = AES_BLOCK_SIZE,
2566 }
2567 },
2568 .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
2569 DESC_HDR_SEL0_AESU,
2570 },
2571 { .type = CRYPTO_ALG_TYPE_ABLKCIPHER,
2572 .alg.crypto = {
Lee Nipper4de9d0b2009-03-29 15:52:32 +08002573 .cra_name = "cbc(aes)",
2574 .cra_driver_name = "cbc-aes-talitos",
2575 .cra_blocksize = AES_BLOCK_SIZE,
2576 .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER |
2577 CRYPTO_ALG_ASYNC,
Lee Nipper4de9d0b2009-03-29 15:52:32 +08002578 .cra_ablkcipher = {
Lee Nipper4de9d0b2009-03-29 15:52:32 +08002579 .min_keysize = AES_MIN_KEY_SIZE,
2580 .max_keysize = AES_MAX_KEY_SIZE,
2581 .ivsize = AES_BLOCK_SIZE,
2582 }
2583 },
2584 .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
2585 DESC_HDR_SEL0_AESU |
2586 DESC_HDR_MODE0_AESU_CBC,
2587 },
Lee Nipperd5e4aae2010-05-19 19:18:38 +10002588 { .type = CRYPTO_ALG_TYPE_ABLKCIPHER,
2589 .alg.crypto = {
LEROY Christophe5e75ae12015-12-01 12:44:15 +01002590 .cra_name = "ctr(aes)",
2591 .cra_driver_name = "ctr-aes-talitos",
2592 .cra_blocksize = AES_BLOCK_SIZE,
2593 .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER |
2594 CRYPTO_ALG_ASYNC,
2595 .cra_ablkcipher = {
2596 .min_keysize = AES_MIN_KEY_SIZE,
2597 .max_keysize = AES_MAX_KEY_SIZE,
2598 .ivsize = AES_BLOCK_SIZE,
2599 }
2600 },
LEROY Christophe70d355c2017-10-06 15:04:43 +02002601 .desc_hdr_template = DESC_HDR_TYPE_AESU_CTR_NONSNOOP |
LEROY Christophe5e75ae12015-12-01 12:44:15 +01002602 DESC_HDR_SEL0_AESU |
2603 DESC_HDR_MODE0_AESU_CTR,
2604 },
2605 { .type = CRYPTO_ALG_TYPE_ABLKCIPHER,
2606 .alg.crypto = {
2607 .cra_name = "ecb(des)",
2608 .cra_driver_name = "ecb-des-talitos",
2609 .cra_blocksize = DES_BLOCK_SIZE,
2610 .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER |
2611 CRYPTO_ALG_ASYNC,
2612 .cra_ablkcipher = {
2613 .min_keysize = DES_KEY_SIZE,
2614 .max_keysize = DES_KEY_SIZE,
2615 .ivsize = DES_BLOCK_SIZE,
2616 }
2617 },
2618 .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
2619 DESC_HDR_SEL0_DEU,
2620 },
2621 { .type = CRYPTO_ALG_TYPE_ABLKCIPHER,
2622 .alg.crypto = {
2623 .cra_name = "cbc(des)",
2624 .cra_driver_name = "cbc-des-talitos",
2625 .cra_blocksize = DES_BLOCK_SIZE,
2626 .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER |
2627 CRYPTO_ALG_ASYNC,
2628 .cra_ablkcipher = {
2629 .min_keysize = DES_KEY_SIZE,
2630 .max_keysize = DES_KEY_SIZE,
2631 .ivsize = DES_BLOCK_SIZE,
2632 }
2633 },
2634 .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
2635 DESC_HDR_SEL0_DEU |
2636 DESC_HDR_MODE0_DEU_CBC,
2637 },
2638 { .type = CRYPTO_ALG_TYPE_ABLKCIPHER,
2639 .alg.crypto = {
2640 .cra_name = "ecb(des3_ede)",
2641 .cra_driver_name = "ecb-3des-talitos",
2642 .cra_blocksize = DES3_EDE_BLOCK_SIZE,
2643 .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER |
2644 CRYPTO_ALG_ASYNC,
2645 .cra_ablkcipher = {
2646 .min_keysize = DES3_EDE_KEY_SIZE,
2647 .max_keysize = DES3_EDE_KEY_SIZE,
2648 .ivsize = DES3_EDE_BLOCK_SIZE,
2649 }
2650 },
2651 .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
2652 DESC_HDR_SEL0_DEU |
2653 DESC_HDR_MODE0_DEU_3DES,
2654 },
2655 { .type = CRYPTO_ALG_TYPE_ABLKCIPHER,
2656 .alg.crypto = {
Lee Nipper4de9d0b2009-03-29 15:52:32 +08002657 .cra_name = "cbc(des3_ede)",
2658 .cra_driver_name = "cbc-3des-talitos",
2659 .cra_blocksize = DES3_EDE_BLOCK_SIZE,
2660 .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER |
2661 CRYPTO_ALG_ASYNC,
Lee Nipper4de9d0b2009-03-29 15:52:32 +08002662 .cra_ablkcipher = {
Lee Nipper4de9d0b2009-03-29 15:52:32 +08002663 .min_keysize = DES3_EDE_KEY_SIZE,
2664 .max_keysize = DES3_EDE_KEY_SIZE,
2665 .ivsize = DES3_EDE_BLOCK_SIZE,
2666 }
2667 },
2668 .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
2669 DESC_HDR_SEL0_DEU |
2670 DESC_HDR_MODE0_DEU_CBC |
2671 DESC_HDR_MODE0_DEU_3DES,
Lee Nipper497f2e62010-05-19 19:20:36 +10002672 },
2673 /* AHASH algorithms. */
2674 { .type = CRYPTO_ALG_TYPE_AHASH,
2675 .alg.hash = {
Lee Nipper497f2e62010-05-19 19:20:36 +10002676 .halg.digestsize = MD5_DIGEST_SIZE,
Horia Geant?3639ca82016-04-21 19:24:55 +03002677 .halg.statesize = sizeof(struct talitos_export_state),
Lee Nipper497f2e62010-05-19 19:20:36 +10002678 .halg.base = {
2679 .cra_name = "md5",
2680 .cra_driver_name = "md5-talitos",
Martin Hicksb3988612015-03-03 08:21:34 -05002681 .cra_blocksize = MD5_HMAC_BLOCK_SIZE,
Lee Nipper497f2e62010-05-19 19:20:36 +10002682 .cra_flags = CRYPTO_ALG_TYPE_AHASH |
2683 CRYPTO_ALG_ASYNC,
Lee Nipper497f2e62010-05-19 19:20:36 +10002684 }
2685 },
2686 .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
2687 DESC_HDR_SEL0_MDEUA |
2688 DESC_HDR_MODE0_MDEU_MD5,
2689 },
2690 { .type = CRYPTO_ALG_TYPE_AHASH,
2691 .alg.hash = {
Lee Nipper497f2e62010-05-19 19:20:36 +10002692 .halg.digestsize = SHA1_DIGEST_SIZE,
Horia Geant?3639ca82016-04-21 19:24:55 +03002693 .halg.statesize = sizeof(struct talitos_export_state),
Lee Nipper497f2e62010-05-19 19:20:36 +10002694 .halg.base = {
2695 .cra_name = "sha1",
2696 .cra_driver_name = "sha1-talitos",
2697 .cra_blocksize = SHA1_BLOCK_SIZE,
2698 .cra_flags = CRYPTO_ALG_TYPE_AHASH |
2699 CRYPTO_ALG_ASYNC,
Lee Nipper497f2e62010-05-19 19:20:36 +10002700 }
2701 },
2702 .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
2703 DESC_HDR_SEL0_MDEUA |
2704 DESC_HDR_MODE0_MDEU_SHA1,
2705 },
2706 { .type = CRYPTO_ALG_TYPE_AHASH,
2707 .alg.hash = {
Kim Phillips60f208d2010-05-19 19:21:53 +10002708 .halg.digestsize = SHA224_DIGEST_SIZE,
Horia Geant?3639ca82016-04-21 19:24:55 +03002709 .halg.statesize = sizeof(struct talitos_export_state),
Kim Phillips60f208d2010-05-19 19:21:53 +10002710 .halg.base = {
2711 .cra_name = "sha224",
2712 .cra_driver_name = "sha224-talitos",
2713 .cra_blocksize = SHA224_BLOCK_SIZE,
2714 .cra_flags = CRYPTO_ALG_TYPE_AHASH |
2715 CRYPTO_ALG_ASYNC,
Kim Phillips60f208d2010-05-19 19:21:53 +10002716 }
2717 },
2718 .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
2719 DESC_HDR_SEL0_MDEUA |
2720 DESC_HDR_MODE0_MDEU_SHA224,
2721 },
2722 { .type = CRYPTO_ALG_TYPE_AHASH,
2723 .alg.hash = {
Lee Nipper497f2e62010-05-19 19:20:36 +10002724 .halg.digestsize = SHA256_DIGEST_SIZE,
Horia Geant?3639ca82016-04-21 19:24:55 +03002725 .halg.statesize = sizeof(struct talitos_export_state),
Lee Nipper497f2e62010-05-19 19:20:36 +10002726 .halg.base = {
2727 .cra_name = "sha256",
2728 .cra_driver_name = "sha256-talitos",
2729 .cra_blocksize = SHA256_BLOCK_SIZE,
2730 .cra_flags = CRYPTO_ALG_TYPE_AHASH |
2731 CRYPTO_ALG_ASYNC,
Lee Nipper497f2e62010-05-19 19:20:36 +10002732 }
2733 },
2734 .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
2735 DESC_HDR_SEL0_MDEUA |
2736 DESC_HDR_MODE0_MDEU_SHA256,
2737 },
2738 { .type = CRYPTO_ALG_TYPE_AHASH,
2739 .alg.hash = {
Lee Nipper497f2e62010-05-19 19:20:36 +10002740 .halg.digestsize = SHA384_DIGEST_SIZE,
Horia Geant?3639ca82016-04-21 19:24:55 +03002741 .halg.statesize = sizeof(struct talitos_export_state),
Lee Nipper497f2e62010-05-19 19:20:36 +10002742 .halg.base = {
2743 .cra_name = "sha384",
2744 .cra_driver_name = "sha384-talitos",
2745 .cra_blocksize = SHA384_BLOCK_SIZE,
2746 .cra_flags = CRYPTO_ALG_TYPE_AHASH |
2747 CRYPTO_ALG_ASYNC,
Lee Nipper497f2e62010-05-19 19:20:36 +10002748 }
2749 },
2750 .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
2751 DESC_HDR_SEL0_MDEUB |
2752 DESC_HDR_MODE0_MDEUB_SHA384,
2753 },
2754 { .type = CRYPTO_ALG_TYPE_AHASH,
2755 .alg.hash = {
Lee Nipper497f2e62010-05-19 19:20:36 +10002756 .halg.digestsize = SHA512_DIGEST_SIZE,
Horia Geant?3639ca82016-04-21 19:24:55 +03002757 .halg.statesize = sizeof(struct talitos_export_state),
Lee Nipper497f2e62010-05-19 19:20:36 +10002758 .halg.base = {
2759 .cra_name = "sha512",
2760 .cra_driver_name = "sha512-talitos",
2761 .cra_blocksize = SHA512_BLOCK_SIZE,
2762 .cra_flags = CRYPTO_ALG_TYPE_AHASH |
2763 CRYPTO_ALG_ASYNC,
Lee Nipper497f2e62010-05-19 19:20:36 +10002764 }
2765 },
2766 .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
2767 DESC_HDR_SEL0_MDEUB |
2768 DESC_HDR_MODE0_MDEUB_SHA512,
2769 },
Lee Nipper79b3a412011-11-21 16:13:25 +08002770 { .type = CRYPTO_ALG_TYPE_AHASH,
2771 .alg.hash = {
Lee Nipper79b3a412011-11-21 16:13:25 +08002772 .halg.digestsize = MD5_DIGEST_SIZE,
Horia Geant?3639ca82016-04-21 19:24:55 +03002773 .halg.statesize = sizeof(struct talitos_export_state),
Lee Nipper79b3a412011-11-21 16:13:25 +08002774 .halg.base = {
2775 .cra_name = "hmac(md5)",
2776 .cra_driver_name = "hmac-md5-talitos",
Martin Hicksb3988612015-03-03 08:21:34 -05002777 .cra_blocksize = MD5_HMAC_BLOCK_SIZE,
Lee Nipper79b3a412011-11-21 16:13:25 +08002778 .cra_flags = CRYPTO_ALG_TYPE_AHASH |
2779 CRYPTO_ALG_ASYNC,
Lee Nipper79b3a412011-11-21 16:13:25 +08002780 }
2781 },
2782 .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
2783 DESC_HDR_SEL0_MDEUA |
2784 DESC_HDR_MODE0_MDEU_MD5,
2785 },
2786 { .type = CRYPTO_ALG_TYPE_AHASH,
2787 .alg.hash = {
Lee Nipper79b3a412011-11-21 16:13:25 +08002788 .halg.digestsize = SHA1_DIGEST_SIZE,
Horia Geant?3639ca82016-04-21 19:24:55 +03002789 .halg.statesize = sizeof(struct talitos_export_state),
Lee Nipper79b3a412011-11-21 16:13:25 +08002790 .halg.base = {
2791 .cra_name = "hmac(sha1)",
2792 .cra_driver_name = "hmac-sha1-talitos",
2793 .cra_blocksize = SHA1_BLOCK_SIZE,
2794 .cra_flags = CRYPTO_ALG_TYPE_AHASH |
2795 CRYPTO_ALG_ASYNC,
Lee Nipper79b3a412011-11-21 16:13:25 +08002796 }
2797 },
2798 .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
2799 DESC_HDR_SEL0_MDEUA |
2800 DESC_HDR_MODE0_MDEU_SHA1,
2801 },
2802 { .type = CRYPTO_ALG_TYPE_AHASH,
2803 .alg.hash = {
Lee Nipper79b3a412011-11-21 16:13:25 +08002804 .halg.digestsize = SHA224_DIGEST_SIZE,
Horia Geant?3639ca82016-04-21 19:24:55 +03002805 .halg.statesize = sizeof(struct talitos_export_state),
Lee Nipper79b3a412011-11-21 16:13:25 +08002806 .halg.base = {
2807 .cra_name = "hmac(sha224)",
2808 .cra_driver_name = "hmac-sha224-talitos",
2809 .cra_blocksize = SHA224_BLOCK_SIZE,
2810 .cra_flags = CRYPTO_ALG_TYPE_AHASH |
2811 CRYPTO_ALG_ASYNC,
Lee Nipper79b3a412011-11-21 16:13:25 +08002812 }
2813 },
2814 .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
2815 DESC_HDR_SEL0_MDEUA |
2816 DESC_HDR_MODE0_MDEU_SHA224,
2817 },
2818 { .type = CRYPTO_ALG_TYPE_AHASH,
2819 .alg.hash = {
Lee Nipper79b3a412011-11-21 16:13:25 +08002820 .halg.digestsize = SHA256_DIGEST_SIZE,
Horia Geant?3639ca82016-04-21 19:24:55 +03002821 .halg.statesize = sizeof(struct talitos_export_state),
Lee Nipper79b3a412011-11-21 16:13:25 +08002822 .halg.base = {
2823 .cra_name = "hmac(sha256)",
2824 .cra_driver_name = "hmac-sha256-talitos",
2825 .cra_blocksize = SHA256_BLOCK_SIZE,
2826 .cra_flags = CRYPTO_ALG_TYPE_AHASH |
2827 CRYPTO_ALG_ASYNC,
Lee Nipper79b3a412011-11-21 16:13:25 +08002828 }
2829 },
2830 .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
2831 DESC_HDR_SEL0_MDEUA |
2832 DESC_HDR_MODE0_MDEU_SHA256,
2833 },
2834 { .type = CRYPTO_ALG_TYPE_AHASH,
2835 .alg.hash = {
Lee Nipper79b3a412011-11-21 16:13:25 +08002836 .halg.digestsize = SHA384_DIGEST_SIZE,
Horia Geant?3639ca82016-04-21 19:24:55 +03002837 .halg.statesize = sizeof(struct talitos_export_state),
Lee Nipper79b3a412011-11-21 16:13:25 +08002838 .halg.base = {
2839 .cra_name = "hmac(sha384)",
2840 .cra_driver_name = "hmac-sha384-talitos",
2841 .cra_blocksize = SHA384_BLOCK_SIZE,
2842 .cra_flags = CRYPTO_ALG_TYPE_AHASH |
2843 CRYPTO_ALG_ASYNC,
Lee Nipper79b3a412011-11-21 16:13:25 +08002844 }
2845 },
2846 .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
2847 DESC_HDR_SEL0_MDEUB |
2848 DESC_HDR_MODE0_MDEUB_SHA384,
2849 },
2850 { .type = CRYPTO_ALG_TYPE_AHASH,
2851 .alg.hash = {
Lee Nipper79b3a412011-11-21 16:13:25 +08002852 .halg.digestsize = SHA512_DIGEST_SIZE,
Horia Geant?3639ca82016-04-21 19:24:55 +03002853 .halg.statesize = sizeof(struct talitos_export_state),
Lee Nipper79b3a412011-11-21 16:13:25 +08002854 .halg.base = {
2855 .cra_name = "hmac(sha512)",
2856 .cra_driver_name = "hmac-sha512-talitos",
2857 .cra_blocksize = SHA512_BLOCK_SIZE,
2858 .cra_flags = CRYPTO_ALG_TYPE_AHASH |
2859 CRYPTO_ALG_ASYNC,
Lee Nipper79b3a412011-11-21 16:13:25 +08002860 }
2861 },
2862 .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
2863 DESC_HDR_SEL0_MDEUB |
2864 DESC_HDR_MODE0_MDEUB_SHA512,
2865 }
Kim Phillips9c4a7962008-06-23 19:50:15 +08002866};
2867
2868struct talitos_crypto_alg {
2869 struct list_head entry;
2870 struct device *dev;
Lee Nipperacbf7c622010-05-19 19:19:33 +10002871 struct talitos_alg_template algt;
Kim Phillips9c4a7962008-06-23 19:50:15 +08002872};
2873
Jonas Eymann89d124c2016-04-19 20:33:47 +03002874static int talitos_init_common(struct talitos_ctx *ctx,
2875 struct talitos_crypto_alg *talitos_alg)
Kim Phillips9c4a7962008-06-23 19:50:15 +08002876{
Kim Phillips5228f0f2011-07-15 11:21:38 +08002877 struct talitos_private *priv;
Kim Phillips9c4a7962008-06-23 19:50:15 +08002878
2879 /* update context with ptr to dev */
2880 ctx->dev = talitos_alg->dev;
Kim Phillips19bbbc62009-03-29 15:53:59 +08002881
Kim Phillips5228f0f2011-07-15 11:21:38 +08002882 /* assign SEC channel to tfm in round-robin fashion */
2883 priv = dev_get_drvdata(ctx->dev);
2884 ctx->ch = atomic_inc_return(&priv->last_chan) &
2885 (priv->num_channels - 1);
2886
Kim Phillips9c4a7962008-06-23 19:50:15 +08002887 /* copy descriptor header template value */
Lee Nipperacbf7c622010-05-19 19:19:33 +10002888 ctx->desc_hdr_template = talitos_alg->algt.desc_hdr_template;
Kim Phillips9c4a7962008-06-23 19:50:15 +08002889
Kim Phillips602dba52011-07-15 11:21:39 +08002890 /* select done notification */
2891 ctx->desc_hdr_template |= DESC_HDR_DONE_NOTIFY;
2892
Lee Nipper497f2e62010-05-19 19:20:36 +10002893 return 0;
2894}
2895
Jonas Eymann89d124c2016-04-19 20:33:47 +03002896static int talitos_cra_init(struct crypto_tfm *tfm)
2897{
2898 struct crypto_alg *alg = tfm->__crt_alg;
2899 struct talitos_crypto_alg *talitos_alg;
2900 struct talitos_ctx *ctx = crypto_tfm_ctx(tfm);
2901
2902 if ((alg->cra_flags & CRYPTO_ALG_TYPE_MASK) == CRYPTO_ALG_TYPE_AHASH)
2903 talitos_alg = container_of(__crypto_ahash_alg(alg),
2904 struct talitos_crypto_alg,
2905 algt.alg.hash);
2906 else
2907 talitos_alg = container_of(alg, struct talitos_crypto_alg,
2908 algt.alg.crypto);
2909
2910 return talitos_init_common(ctx, talitos_alg);
2911}
2912
Herbert Xuaeb4c132015-07-30 17:53:22 +08002913static int talitos_cra_init_aead(struct crypto_aead *tfm)
Lee Nipper497f2e62010-05-19 19:20:36 +10002914{
Jonas Eymann89d124c2016-04-19 20:33:47 +03002915 struct aead_alg *alg = crypto_aead_alg(tfm);
2916 struct talitos_crypto_alg *talitos_alg;
2917 struct talitos_ctx *ctx = crypto_aead_ctx(tfm);
2918
2919 talitos_alg = container_of(alg, struct talitos_crypto_alg,
2920 algt.alg.aead);
2921
2922 return talitos_init_common(ctx, talitos_alg);
Kim Phillips9c4a7962008-06-23 19:50:15 +08002923}
2924
Lee Nipper497f2e62010-05-19 19:20:36 +10002925static int talitos_cra_init_ahash(struct crypto_tfm *tfm)
2926{
2927 struct talitos_ctx *ctx = crypto_tfm_ctx(tfm);
2928
2929 talitos_cra_init(tfm);
2930
2931 ctx->keylen = 0;
2932 crypto_ahash_set_reqsize(__crypto_ahash_cast(tfm),
2933 sizeof(struct talitos_ahash_req_ctx));
2934
2935 return 0;
2936}
2937
Kim Phillips9c4a7962008-06-23 19:50:15 +08002938/*
2939 * given the alg's descriptor header template, determine whether descriptor
2940 * type and primary/secondary execution units required match the hw
2941 * capabilities description provided in the device tree node.
2942 */
2943static int hw_supports(struct device *dev, __be32 desc_hdr_template)
2944{
2945 struct talitos_private *priv = dev_get_drvdata(dev);
2946 int ret;
2947
2948 ret = (1 << DESC_TYPE(desc_hdr_template) & priv->desc_types) &&
2949 (1 << PRIMARY_EU(desc_hdr_template) & priv->exec_units);
2950
2951 if (SECONDARY_EU(desc_hdr_template))
2952 ret = ret && (1 << SECONDARY_EU(desc_hdr_template)
2953 & priv->exec_units);
2954
2955 return ret;
2956}
2957
Grant Likely2dc11582010-08-06 09:25:50 -06002958static int talitos_remove(struct platform_device *ofdev)
Kim Phillips9c4a7962008-06-23 19:50:15 +08002959{
2960 struct device *dev = &ofdev->dev;
2961 struct talitos_private *priv = dev_get_drvdata(dev);
2962 struct talitos_crypto_alg *t_alg, *n;
2963 int i;
2964
2965 list_for_each_entry_safe(t_alg, n, &priv->alg_list, entry) {
Lee Nipperacbf7c622010-05-19 19:19:33 +10002966 switch (t_alg->algt.type) {
2967 case CRYPTO_ALG_TYPE_ABLKCIPHER:
Lee Nipperacbf7c622010-05-19 19:19:33 +10002968 break;
Herbert Xuaeb4c132015-07-30 17:53:22 +08002969 case CRYPTO_ALG_TYPE_AEAD:
2970 crypto_unregister_aead(&t_alg->algt.alg.aead);
Lee Nipperacbf7c622010-05-19 19:19:33 +10002971 case CRYPTO_ALG_TYPE_AHASH:
2972 crypto_unregister_ahash(&t_alg->algt.alg.hash);
2973 break;
2974 }
Kim Phillips9c4a7962008-06-23 19:50:15 +08002975 list_del(&t_alg->entry);
Kim Phillips9c4a7962008-06-23 19:50:15 +08002976 }
2977
2978 if (hw_supports(dev, DESC_HDR_SEL0_RNG))
2979 talitos_unregister_rng(dev);
2980
Kim Phillipsc3e337f2011-11-21 16:13:27 +08002981 for (i = 0; i < 2; i++)
Kim Phillips2cdba3c2011-12-12 14:59:11 -06002982 if (priv->irq[i]) {
Kim Phillipsc3e337f2011-11-21 16:13:27 +08002983 free_irq(priv->irq[i], dev);
2984 irq_dispose_mapping(priv->irq[i]);
2985 }
Kim Phillips9c4a7962008-06-23 19:50:15 +08002986
Kim Phillipsc3e337f2011-11-21 16:13:27 +08002987 tasklet_kill(&priv->done_task[0]);
Kim Phillips2cdba3c2011-12-12 14:59:11 -06002988 if (priv->irq[1])
Kim Phillipsc3e337f2011-11-21 16:13:27 +08002989 tasklet_kill(&priv->done_task[1]);
Kim Phillips9c4a7962008-06-23 19:50:15 +08002990
Kim Phillips9c4a7962008-06-23 19:50:15 +08002991 return 0;
2992}
2993
2994static struct talitos_crypto_alg *talitos_alg_alloc(struct device *dev,
2995 struct talitos_alg_template
2996 *template)
2997{
Kim Phillips60f208d2010-05-19 19:21:53 +10002998 struct talitos_private *priv = dev_get_drvdata(dev);
Kim Phillips9c4a7962008-06-23 19:50:15 +08002999 struct talitos_crypto_alg *t_alg;
3000 struct crypto_alg *alg;
3001
LEROY Christophe24b92ff2017-10-06 15:04:49 +02003002 t_alg = devm_kzalloc(dev, sizeof(struct talitos_crypto_alg),
3003 GFP_KERNEL);
Kim Phillips9c4a7962008-06-23 19:50:15 +08003004 if (!t_alg)
3005 return ERR_PTR(-ENOMEM);
3006
Lee Nipperacbf7c622010-05-19 19:19:33 +10003007 t_alg->algt = *template;
3008
3009 switch (t_alg->algt.type) {
3010 case CRYPTO_ALG_TYPE_ABLKCIPHER:
Lee Nipper497f2e62010-05-19 19:20:36 +10003011 alg = &t_alg->algt.alg.crypto;
3012 alg->cra_init = talitos_cra_init;
Kim Phillipsd4cd3282012-08-08 20:32:00 -05003013 alg->cra_type = &crypto_ablkcipher_type;
Kim Phillipsb286e002012-08-08 20:33:34 -05003014 alg->cra_ablkcipher.setkey = ablkcipher_setkey;
3015 alg->cra_ablkcipher.encrypt = ablkcipher_encrypt;
3016 alg->cra_ablkcipher.decrypt = ablkcipher_decrypt;
3017 alg->cra_ablkcipher.geniv = "eseqiv";
Lee Nipper497f2e62010-05-19 19:20:36 +10003018 break;
Lee Nipperacbf7c622010-05-19 19:19:33 +10003019 case CRYPTO_ALG_TYPE_AEAD:
Herbert Xuaeb4c132015-07-30 17:53:22 +08003020 alg = &t_alg->algt.alg.aead.base;
Herbert Xuaeb4c132015-07-30 17:53:22 +08003021 t_alg->algt.alg.aead.init = talitos_cra_init_aead;
3022 t_alg->algt.alg.aead.setkey = aead_setkey;
3023 t_alg->algt.alg.aead.encrypt = aead_encrypt;
3024 t_alg->algt.alg.aead.decrypt = aead_decrypt;
LEROY Christophe6cda0752017-10-06 15:04:39 +02003025 if (!(priv->features & TALITOS_FTR_SHA224_HWINIT) &&
3026 !strncmp(alg->cra_name, "authenc(hmac(sha224)", 20)) {
LEROY Christophe24b92ff2017-10-06 15:04:49 +02003027 devm_kfree(dev, t_alg);
LEROY Christophe6cda0752017-10-06 15:04:39 +02003028 return ERR_PTR(-ENOTSUPP);
3029 }
Lee Nipperacbf7c622010-05-19 19:19:33 +10003030 break;
3031 case CRYPTO_ALG_TYPE_AHASH:
3032 alg = &t_alg->algt.alg.hash.halg.base;
Lee Nipper497f2e62010-05-19 19:20:36 +10003033 alg->cra_init = talitos_cra_init_ahash;
Kim Phillipsd4cd3282012-08-08 20:32:00 -05003034 alg->cra_type = &crypto_ahash_type;
Kim Phillipsb286e002012-08-08 20:33:34 -05003035 t_alg->algt.alg.hash.init = ahash_init;
3036 t_alg->algt.alg.hash.update = ahash_update;
3037 t_alg->algt.alg.hash.final = ahash_final;
3038 t_alg->algt.alg.hash.finup = ahash_finup;
3039 t_alg->algt.alg.hash.digest = ahash_digest;
LEROY Christophe56136632017-09-12 11:03:39 +02003040 if (!strncmp(alg->cra_name, "hmac", 4))
3041 t_alg->algt.alg.hash.setkey = ahash_setkey;
Horia Geant?3639ca82016-04-21 19:24:55 +03003042 t_alg->algt.alg.hash.import = ahash_import;
3043 t_alg->algt.alg.hash.export = ahash_export;
Kim Phillipsb286e002012-08-08 20:33:34 -05003044
Lee Nipper79b3a412011-11-21 16:13:25 +08003045 if (!(priv->features & TALITOS_FTR_HMAC_OK) &&
Kim Phillips0b2730d2011-12-12 14:59:10 -06003046 !strncmp(alg->cra_name, "hmac", 4)) {
LEROY Christophe24b92ff2017-10-06 15:04:49 +02003047 devm_kfree(dev, t_alg);
Lee Nipper79b3a412011-11-21 16:13:25 +08003048 return ERR_PTR(-ENOTSUPP);
Kim Phillips0b2730d2011-12-12 14:59:10 -06003049 }
Kim Phillips60f208d2010-05-19 19:21:53 +10003050 if (!(priv->features & TALITOS_FTR_SHA224_HWINIT) &&
Lee Nipper79b3a412011-11-21 16:13:25 +08003051 (!strcmp(alg->cra_name, "sha224") ||
3052 !strcmp(alg->cra_name, "hmac(sha224)"))) {
Kim Phillips60f208d2010-05-19 19:21:53 +10003053 t_alg->algt.alg.hash.init = ahash_init_sha224_swinit;
3054 t_alg->algt.desc_hdr_template =
3055 DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
3056 DESC_HDR_SEL0_MDEUA |
3057 DESC_HDR_MODE0_MDEU_SHA256;
3058 }
Lee Nipper497f2e62010-05-19 19:20:36 +10003059 break;
Kim Phillips1d119112010-09-23 15:55:27 +08003060 default:
3061 dev_err(dev, "unknown algorithm type %d\n", t_alg->algt.type);
LEROY Christophe24b92ff2017-10-06 15:04:49 +02003062 devm_kfree(dev, t_alg);
Kim Phillips1d119112010-09-23 15:55:27 +08003063 return ERR_PTR(-EINVAL);
Lee Nipperacbf7c622010-05-19 19:19:33 +10003064 }
Kim Phillips9c4a7962008-06-23 19:50:15 +08003065
Kim Phillips9c4a7962008-06-23 19:50:15 +08003066 alg->cra_module = THIS_MODULE;
LEROY Christopheb0057762016-06-06 13:20:44 +02003067 if (t_alg->algt.priority)
3068 alg->cra_priority = t_alg->algt.priority;
3069 else
3070 alg->cra_priority = TALITOS_CRA_PRIORITY;
Kim Phillips9c4a7962008-06-23 19:50:15 +08003071 alg->cra_alignmask = 0;
Kim Phillips9c4a7962008-06-23 19:50:15 +08003072 alg->cra_ctxsize = sizeof(struct talitos_ctx);
Nikos Mavrogiannopoulosd912bb72011-11-01 13:39:56 +01003073 alg->cra_flags |= CRYPTO_ALG_KERN_DRIVER_ONLY;
Kim Phillips9c4a7962008-06-23 19:50:15 +08003074
Kim Phillips9c4a7962008-06-23 19:50:15 +08003075 t_alg->dev = dev;
3076
3077 return t_alg;
3078}
3079
Kim Phillipsc3e337f2011-11-21 16:13:27 +08003080static int talitos_probe_irq(struct platform_device *ofdev)
3081{
3082 struct device *dev = &ofdev->dev;
3083 struct device_node *np = ofdev->dev.of_node;
3084 struct talitos_private *priv = dev_get_drvdata(dev);
3085 int err;
LEROY Christophedd3c0982015-04-17 16:32:13 +02003086 bool is_sec1 = has_ftr_sec1(priv);
Kim Phillipsc3e337f2011-11-21 16:13:27 +08003087
3088 priv->irq[0] = irq_of_parse_and_map(np, 0);
Kim Phillips2cdba3c2011-12-12 14:59:11 -06003089 if (!priv->irq[0]) {
Kim Phillipsc3e337f2011-11-21 16:13:27 +08003090 dev_err(dev, "failed to map irq\n");
3091 return -EINVAL;
3092 }
LEROY Christophedd3c0982015-04-17 16:32:13 +02003093 if (is_sec1) {
3094 err = request_irq(priv->irq[0], talitos1_interrupt_4ch, 0,
3095 dev_driver_string(dev), dev);
3096 goto primary_out;
3097 }
Kim Phillipsc3e337f2011-11-21 16:13:27 +08003098
3099 priv->irq[1] = irq_of_parse_and_map(np, 1);
3100
3101 /* get the primary irq line */
Kim Phillips2cdba3c2011-12-12 14:59:11 -06003102 if (!priv->irq[1]) {
LEROY Christophedd3c0982015-04-17 16:32:13 +02003103 err = request_irq(priv->irq[0], talitos2_interrupt_4ch, 0,
Kim Phillipsc3e337f2011-11-21 16:13:27 +08003104 dev_driver_string(dev), dev);
3105 goto primary_out;
3106 }
3107
LEROY Christophedd3c0982015-04-17 16:32:13 +02003108 err = request_irq(priv->irq[0], talitos2_interrupt_ch0_2, 0,
Kim Phillipsc3e337f2011-11-21 16:13:27 +08003109 dev_driver_string(dev), dev);
3110 if (err)
3111 goto primary_out;
3112
3113 /* get the secondary irq line */
LEROY Christophedd3c0982015-04-17 16:32:13 +02003114 err = request_irq(priv->irq[1], talitos2_interrupt_ch1_3, 0,
Kim Phillipsc3e337f2011-11-21 16:13:27 +08003115 dev_driver_string(dev), dev);
3116 if (err) {
3117 dev_err(dev, "failed to request secondary irq\n");
3118 irq_dispose_mapping(priv->irq[1]);
Kim Phillips2cdba3c2011-12-12 14:59:11 -06003119 priv->irq[1] = 0;
Kim Phillipsc3e337f2011-11-21 16:13:27 +08003120 }
3121
3122 return err;
3123
3124primary_out:
3125 if (err) {
3126 dev_err(dev, "failed to request primary irq\n");
3127 irq_dispose_mapping(priv->irq[0]);
Kim Phillips2cdba3c2011-12-12 14:59:11 -06003128 priv->irq[0] = 0;
Kim Phillipsc3e337f2011-11-21 16:13:27 +08003129 }
3130
3131 return err;
3132}
3133
Grant Likely1c48a5c2011-02-17 02:43:24 -07003134static int talitos_probe(struct platform_device *ofdev)
Kim Phillips9c4a7962008-06-23 19:50:15 +08003135{
3136 struct device *dev = &ofdev->dev;
Grant Likely61c7a082010-04-13 16:12:29 -07003137 struct device_node *np = ofdev->dev.of_node;
Kim Phillips9c4a7962008-06-23 19:50:15 +08003138 struct talitos_private *priv;
Kim Phillips9c4a7962008-06-23 19:50:15 +08003139 int i, err;
LEROY Christophe5fa7fa12015-04-17 16:32:11 +02003140 int stride;
LEROY Christophefd5ea7f2017-10-06 15:04:53 +02003141 struct resource *res;
Kim Phillips9c4a7962008-06-23 19:50:15 +08003142
LEROY Christophe24b92ff2017-10-06 15:04:49 +02003143 priv = devm_kzalloc(dev, sizeof(struct talitos_private), GFP_KERNEL);
Kim Phillips9c4a7962008-06-23 19:50:15 +08003144 if (!priv)
3145 return -ENOMEM;
3146
Kevin Haof3de9cb2014-01-28 20:17:23 +08003147 INIT_LIST_HEAD(&priv->alg_list);
3148
Kim Phillips9c4a7962008-06-23 19:50:15 +08003149 dev_set_drvdata(dev, priv);
3150
3151 priv->ofdev = ofdev;
3152
Horia Geanta511d63c2012-03-30 17:49:53 +03003153 spin_lock_init(&priv->reg_lock);
3154
LEROY Christophefd5ea7f2017-10-06 15:04:53 +02003155 res = platform_get_resource(ofdev, IORESOURCE_MEM, 0);
3156 if (!res)
3157 return -ENXIO;
3158 priv->reg = devm_ioremap(dev, res->start, resource_size(res));
Kim Phillips9c4a7962008-06-23 19:50:15 +08003159 if (!priv->reg) {
3160 dev_err(dev, "failed to of_iomap\n");
3161 err = -ENOMEM;
3162 goto err_out;
3163 }
3164
3165 /* get SEC version capabilities from device tree */
LEROY Christophefa14c6c2017-10-06 15:04:51 +02003166 of_property_read_u32(np, "fsl,num-channels", &priv->num_channels);
3167 of_property_read_u32(np, "fsl,channel-fifo-len", &priv->chfifo_len);
3168 of_property_read_u32(np, "fsl,exec-units-mask", &priv->exec_units);
3169 of_property_read_u32(np, "fsl,descriptor-types-mask",
3170 &priv->desc_types);
Kim Phillips9c4a7962008-06-23 19:50:15 +08003171
3172 if (!is_power_of_2(priv->num_channels) || !priv->chfifo_len ||
3173 !priv->exec_units || !priv->desc_types) {
3174 dev_err(dev, "invalid property data in device tree node\n");
3175 err = -EINVAL;
3176 goto err_out;
3177 }
3178
Lee Nipperf3c85bc2008-07-30 16:26:57 +08003179 if (of_device_is_compatible(np, "fsl,sec3.0"))
3180 priv->features |= TALITOS_FTR_SRC_LINK_TBL_LEN_INCLUDES_EXTENT;
3181
Kim Phillipsfe5720e2008-10-12 20:33:14 +08003182 if (of_device_is_compatible(np, "fsl,sec2.1"))
Kim Phillips60f208d2010-05-19 19:21:53 +10003183 priv->features |= TALITOS_FTR_HW_AUTH_CHECK |
Lee Nipper79b3a412011-11-21 16:13:25 +08003184 TALITOS_FTR_SHA224_HWINIT |
3185 TALITOS_FTR_HMAC_OK;
Kim Phillipsfe5720e2008-10-12 20:33:14 +08003186
LEROY Christophe21590882015-04-17 16:32:05 +02003187 if (of_device_is_compatible(np, "fsl,sec1.0"))
3188 priv->features |= TALITOS_FTR_SEC1;
3189
LEROY Christophe5fa7fa12015-04-17 16:32:11 +02003190 if (of_device_is_compatible(np, "fsl,sec1.2")) {
3191 priv->reg_deu = priv->reg + TALITOS12_DEU;
3192 priv->reg_aesu = priv->reg + TALITOS12_AESU;
3193 priv->reg_mdeu = priv->reg + TALITOS12_MDEU;
3194 stride = TALITOS1_CH_STRIDE;
3195 } else if (of_device_is_compatible(np, "fsl,sec1.0")) {
3196 priv->reg_deu = priv->reg + TALITOS10_DEU;
3197 priv->reg_aesu = priv->reg + TALITOS10_AESU;
3198 priv->reg_mdeu = priv->reg + TALITOS10_MDEU;
3199 priv->reg_afeu = priv->reg + TALITOS10_AFEU;
3200 priv->reg_rngu = priv->reg + TALITOS10_RNGU;
3201 priv->reg_pkeu = priv->reg + TALITOS10_PKEU;
3202 stride = TALITOS1_CH_STRIDE;
3203 } else {
3204 priv->reg_deu = priv->reg + TALITOS2_DEU;
3205 priv->reg_aesu = priv->reg + TALITOS2_AESU;
3206 priv->reg_mdeu = priv->reg + TALITOS2_MDEU;
3207 priv->reg_afeu = priv->reg + TALITOS2_AFEU;
3208 priv->reg_rngu = priv->reg + TALITOS2_RNGU;
3209 priv->reg_pkeu = priv->reg + TALITOS2_PKEU;
3210 priv->reg_keu = priv->reg + TALITOS2_KEU;
3211 priv->reg_crcu = priv->reg + TALITOS2_CRCU;
3212 stride = TALITOS2_CH_STRIDE;
3213 }
3214
LEROY Christophedd3c0982015-04-17 16:32:13 +02003215 err = talitos_probe_irq(ofdev);
3216 if (err)
3217 goto err_out;
3218
3219 if (of_device_is_compatible(np, "fsl,sec1.0")) {
LEROY Christophe9c02e282017-10-06 15:04:55 +02003220 if (priv->num_channels == 1)
3221 tasklet_init(&priv->done_task[0], talitos1_done_ch0,
LEROY Christophedd3c0982015-04-17 16:32:13 +02003222 (unsigned long)dev);
LEROY Christophe9c02e282017-10-06 15:04:55 +02003223 else
3224 tasklet_init(&priv->done_task[0], talitos1_done_4ch,
3225 (unsigned long)dev);
3226 } else {
3227 if (priv->irq[1]) {
LEROY Christophedd3c0982015-04-17 16:32:13 +02003228 tasklet_init(&priv->done_task[0], talitos2_done_ch0_2,
3229 (unsigned long)dev);
3230 tasklet_init(&priv->done_task[1], talitos2_done_ch1_3,
3231 (unsigned long)dev);
LEROY Christophe9c02e282017-10-06 15:04:55 +02003232 } else if (priv->num_channels == 1) {
3233 tasklet_init(&priv->done_task[0], talitos2_done_ch0,
3234 (unsigned long)dev);
3235 } else {
3236 tasklet_init(&priv->done_task[0], talitos2_done_4ch,
3237 (unsigned long)dev);
LEROY Christophedd3c0982015-04-17 16:32:13 +02003238 }
3239 }
3240
LEROY Christophe24b92ff2017-10-06 15:04:49 +02003241 priv->chan = devm_kzalloc(dev, sizeof(struct talitos_channel) *
3242 priv->num_channels, GFP_KERNEL);
Kim Phillips4b9926282009-08-13 11:50:38 +10003243 if (!priv->chan) {
3244 dev_err(dev, "failed to allocate channel management space\n");
Kim Phillips9c4a7962008-06-23 19:50:15 +08003245 err = -ENOMEM;
3246 goto err_out;
3247 }
3248
Martin Hicksf641ddd2015-03-03 08:21:33 -05003249 priv->fifo_len = roundup_pow_of_two(priv->chfifo_len);
3250
Kim Phillipsc3e337f2011-11-21 16:13:27 +08003251 for (i = 0; i < priv->num_channels; i++) {
LEROY Christophe5fa7fa12015-04-17 16:32:11 +02003252 priv->chan[i].reg = priv->reg + stride * (i + 1);
Kim Phillips2cdba3c2011-12-12 14:59:11 -06003253 if (!priv->irq[1] || !(i & 1))
Kim Phillipsc3e337f2011-11-21 16:13:27 +08003254 priv->chan[i].reg += TALITOS_CH_BASE_OFFSET;
Kim Phillipsad42d5f2011-11-21 16:13:27 +08003255
Kim Phillips4b9926282009-08-13 11:50:38 +10003256 spin_lock_init(&priv->chan[i].head_lock);
3257 spin_lock_init(&priv->chan[i].tail_lock);
Kim Phillips9c4a7962008-06-23 19:50:15 +08003258
LEROY Christophe24b92ff2017-10-06 15:04:49 +02003259 priv->chan[i].fifo = devm_kzalloc(dev,
3260 sizeof(struct talitos_request) *
3261 priv->fifo_len, GFP_KERNEL);
Kim Phillips4b9926282009-08-13 11:50:38 +10003262 if (!priv->chan[i].fifo) {
Kim Phillips9c4a7962008-06-23 19:50:15 +08003263 dev_err(dev, "failed to allocate request fifo %d\n", i);
3264 err = -ENOMEM;
3265 goto err_out;
3266 }
Kim Phillips9c4a7962008-06-23 19:50:15 +08003267
Kim Phillips4b9926282009-08-13 11:50:38 +10003268 atomic_set(&priv->chan[i].submit_count,
3269 -(priv->chfifo_len - 1));
Martin Hicksf641ddd2015-03-03 08:21:33 -05003270 }
Kim Phillips9c4a7962008-06-23 19:50:15 +08003271
Kim Phillips81eb0242009-08-13 11:51:51 +10003272 dma_set_mask(dev, DMA_BIT_MASK(36));
3273
Kim Phillips9c4a7962008-06-23 19:50:15 +08003274 /* reset and initialize the h/w */
3275 err = init_device(dev);
3276 if (err) {
3277 dev_err(dev, "failed to initialize device\n");
3278 goto err_out;
3279 }
3280
3281 /* register the RNG, if available */
3282 if (hw_supports(dev, DESC_HDR_SEL0_RNG)) {
3283 err = talitos_register_rng(dev);
3284 if (err) {
3285 dev_err(dev, "failed to register hwrng: %d\n", err);
3286 goto err_out;
3287 } else
3288 dev_info(dev, "hwrng\n");
3289 }
3290
3291 /* register crypto algorithms the device supports */
Kim Phillips9c4a7962008-06-23 19:50:15 +08003292 for (i = 0; i < ARRAY_SIZE(driver_algs); i++) {
3293 if (hw_supports(dev, driver_algs[i].desc_hdr_template)) {
3294 struct talitos_crypto_alg *t_alg;
Herbert Xuaeb4c132015-07-30 17:53:22 +08003295 struct crypto_alg *alg = NULL;
Kim Phillips9c4a7962008-06-23 19:50:15 +08003296
3297 t_alg = talitos_alg_alloc(dev, &driver_algs[i]);
3298 if (IS_ERR(t_alg)) {
3299 err = PTR_ERR(t_alg);
Kim Phillips0b2730d2011-12-12 14:59:10 -06003300 if (err == -ENOTSUPP)
Lee Nipper79b3a412011-11-21 16:13:25 +08003301 continue;
Kim Phillips9c4a7962008-06-23 19:50:15 +08003302 goto err_out;
3303 }
3304
Lee Nipperacbf7c622010-05-19 19:19:33 +10003305 switch (t_alg->algt.type) {
3306 case CRYPTO_ALG_TYPE_ABLKCIPHER:
Lee Nipperacbf7c622010-05-19 19:19:33 +10003307 err = crypto_register_alg(
3308 &t_alg->algt.alg.crypto);
Herbert Xuaeb4c132015-07-30 17:53:22 +08003309 alg = &t_alg->algt.alg.crypto;
Lee Nipperacbf7c622010-05-19 19:19:33 +10003310 break;
Herbert Xuaeb4c132015-07-30 17:53:22 +08003311
3312 case CRYPTO_ALG_TYPE_AEAD:
3313 err = crypto_register_aead(
3314 &t_alg->algt.alg.aead);
3315 alg = &t_alg->algt.alg.aead.base;
3316 break;
3317
Lee Nipperacbf7c622010-05-19 19:19:33 +10003318 case CRYPTO_ALG_TYPE_AHASH:
3319 err = crypto_register_ahash(
3320 &t_alg->algt.alg.hash);
Herbert Xuaeb4c132015-07-30 17:53:22 +08003321 alg = &t_alg->algt.alg.hash.halg.base;
Lee Nipperacbf7c622010-05-19 19:19:33 +10003322 break;
3323 }
Kim Phillips9c4a7962008-06-23 19:50:15 +08003324 if (err) {
3325 dev_err(dev, "%s alg registration failed\n",
Herbert Xuaeb4c132015-07-30 17:53:22 +08003326 alg->cra_driver_name);
LEROY Christophe24b92ff2017-10-06 15:04:49 +02003327 devm_kfree(dev, t_alg);
Horia Geanta991155b2013-03-20 16:31:38 +02003328 } else
Kim Phillips9c4a7962008-06-23 19:50:15 +08003329 list_add_tail(&t_alg->entry, &priv->alg_list);
Kim Phillips9c4a7962008-06-23 19:50:15 +08003330 }
3331 }
Kim Phillips5b859b6e2011-11-21 16:13:26 +08003332 if (!list_empty(&priv->alg_list))
3333 dev_info(dev, "%s algorithms registered in /proc/crypto\n",
3334 (char *)of_get_property(np, "compatible", NULL));
Kim Phillips9c4a7962008-06-23 19:50:15 +08003335
3336 return 0;
3337
3338err_out:
3339 talitos_remove(ofdev);
Kim Phillips9c4a7962008-06-23 19:50:15 +08003340
3341 return err;
3342}
3343
Márton Németh6c3f9752010-01-17 21:54:01 +11003344static const struct of_device_id talitos_match[] = {
LEROY Christophe0635b7db2015-04-17 16:32:20 +02003345#ifdef CONFIG_CRYPTO_DEV_TALITOS1
3346 {
3347 .compatible = "fsl,sec1.0",
3348 },
3349#endif
3350#ifdef CONFIG_CRYPTO_DEV_TALITOS2
Kim Phillips9c4a7962008-06-23 19:50:15 +08003351 {
3352 .compatible = "fsl,sec2.0",
3353 },
LEROY Christophe0635b7db2015-04-17 16:32:20 +02003354#endif
Kim Phillips9c4a7962008-06-23 19:50:15 +08003355 {},
3356};
3357MODULE_DEVICE_TABLE(of, talitos_match);
3358
Grant Likely1c48a5c2011-02-17 02:43:24 -07003359static struct platform_driver talitos_driver = {
Grant Likely40182942010-04-13 16:13:02 -07003360 .driver = {
3361 .name = "talitos",
Grant Likely40182942010-04-13 16:13:02 -07003362 .of_match_table = talitos_match,
3363 },
Kim Phillips9c4a7962008-06-23 19:50:15 +08003364 .probe = talitos_probe,
Al Viro596f1032008-11-22 17:34:24 +00003365 .remove = talitos_remove,
Kim Phillips9c4a7962008-06-23 19:50:15 +08003366};
3367
Axel Lin741e8c22011-11-26 21:26:19 +08003368module_platform_driver(talitos_driver);
Kim Phillips9c4a7962008-06-23 19:50:15 +08003369
3370MODULE_LICENSE("GPL");
3371MODULE_AUTHOR("Kim Phillips <kim.phillips@freescale.com>");
3372MODULE_DESCRIPTION("Freescale integrated security engine (SEC) driver");