blob: bb44df1c1f2d3f3846a08f51630c4f8b9a59c551 [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);
LEROY Christophe37b5e882017-10-06 15:05:06 +0200163 /* enable chaining descriptors */
164 if (is_sec1)
165 setbits32(priv->chan[ch].reg + TALITOS_CCCR_LO,
166 TALITOS_CCCR_LO_NE);
Kim Phillips9c4a7962008-06-23 19:50:15 +0800167
Kim Phillipsfe5720e2008-10-12 20:33:14 +0800168 /* and ICCR writeback, if available */
169 if (priv->features & TALITOS_FTR_HW_AUTH_CHECK)
Kim Phillipsad42d5f2011-11-21 16:13:27 +0800170 setbits32(priv->chan[ch].reg + TALITOS_CCCR_LO,
Kim Phillipsfe5720e2008-10-12 20:33:14 +0800171 TALITOS_CCCR_LO_IWSE);
172
Kim Phillips9c4a7962008-06-23 19:50:15 +0800173 return 0;
174}
175
176static int reset_device(struct device *dev)
177{
178 struct talitos_private *priv = dev_get_drvdata(dev);
179 unsigned int timeout = TALITOS_TIMEOUT;
LEROY Christophedd3c0982015-04-17 16:32:13 +0200180 bool is_sec1 = has_ftr_sec1(priv);
181 u32 mcr = is_sec1 ? TALITOS1_MCR_SWR : TALITOS2_MCR_SWR;
Kim Phillips9c4a7962008-06-23 19:50:15 +0800182
Kim Phillipsc3e337f2011-11-21 16:13:27 +0800183 setbits32(priv->reg + TALITOS_MCR, mcr);
Kim Phillips9c4a7962008-06-23 19:50:15 +0800184
LEROY Christophedd3c0982015-04-17 16:32:13 +0200185 while ((in_be32(priv->reg + TALITOS_MCR) & mcr)
Kim Phillips9c4a7962008-06-23 19:50:15 +0800186 && --timeout)
187 cpu_relax();
188
Kim Phillips2cdba3c2011-12-12 14:59:11 -0600189 if (priv->irq[1]) {
Kim Phillipsc3e337f2011-11-21 16:13:27 +0800190 mcr = TALITOS_MCR_RCA1 | TALITOS_MCR_RCA3;
191 setbits32(priv->reg + TALITOS_MCR, mcr);
192 }
193
Kim Phillips9c4a7962008-06-23 19:50:15 +0800194 if (timeout == 0) {
195 dev_err(dev, "failed to reset device\n");
196 return -EIO;
197 }
198
199 return 0;
200}
201
202/*
203 * Reset and initialize the device
204 */
205static int init_device(struct device *dev)
206{
207 struct talitos_private *priv = dev_get_drvdata(dev);
208 int ch, err;
LEROY Christophedd3c0982015-04-17 16:32:13 +0200209 bool is_sec1 = has_ftr_sec1(priv);
Kim Phillips9c4a7962008-06-23 19:50:15 +0800210
211 /*
212 * Master reset
213 * errata documentation: warning: certain SEC interrupts
214 * are not fully cleared by writing the MCR:SWR bit,
215 * set bit twice to completely reset
216 */
217 err = reset_device(dev);
218 if (err)
219 return err;
220
221 err = reset_device(dev);
222 if (err)
223 return err;
224
225 /* reset channels */
226 for (ch = 0; ch < priv->num_channels; ch++) {
227 err = reset_channel(dev, ch);
228 if (err)
229 return err;
230 }
231
232 /* enable channel done and error interrupts */
LEROY Christophedd3c0982015-04-17 16:32:13 +0200233 if (is_sec1) {
234 clrbits32(priv->reg + TALITOS_IMR, TALITOS1_IMR_INIT);
235 clrbits32(priv->reg + TALITOS_IMR_LO, TALITOS1_IMR_LO_INIT);
236 /* disable parity error check in DEU (erroneous? test vect.) */
237 setbits32(priv->reg_deu + TALITOS_EUICR, TALITOS1_DEUICR_KPE);
238 } else {
239 setbits32(priv->reg + TALITOS_IMR, TALITOS2_IMR_INIT);
240 setbits32(priv->reg + TALITOS_IMR_LO, TALITOS2_IMR_LO_INIT);
241 }
Kim Phillips9c4a7962008-06-23 19:50:15 +0800242
Kim Phillipsfe5720e2008-10-12 20:33:14 +0800243 /* disable integrity check error interrupts (use writeback instead) */
244 if (priv->features & TALITOS_FTR_HW_AUTH_CHECK)
LEROY Christophe5fa7fa12015-04-17 16:32:11 +0200245 setbits32(priv->reg_mdeu + TALITOS_EUICR_LO,
Kim Phillipsfe5720e2008-10-12 20:33:14 +0800246 TALITOS_MDEUICR_LO_ICE);
247
Kim Phillips9c4a7962008-06-23 19:50:15 +0800248 return 0;
249}
250
251/**
252 * talitos_submit - submits a descriptor to the device for processing
253 * @dev: the SEC device to be used
Kim Phillips5228f0f2011-07-15 11:21:38 +0800254 * @ch: the SEC device channel to be used
Kim Phillips9c4a7962008-06-23 19:50:15 +0800255 * @desc: the descriptor to be processed by the device
256 * @callback: whom to call when processing is complete
257 * @context: a handle for use by caller (optional)
258 *
259 * desc must contain valid dma-mapped (bus physical) address pointers.
260 * callback must check err and feedback in descriptor header
261 * for device processing status.
262 */
Horia Geanta865d5062012-07-03 19:16:52 +0300263int talitos_submit(struct device *dev, int ch, struct talitos_desc *desc,
264 void (*callback)(struct device *dev,
265 struct talitos_desc *desc,
266 void *context, int error),
267 void *context)
Kim Phillips9c4a7962008-06-23 19:50:15 +0800268{
269 struct talitos_private *priv = dev_get_drvdata(dev);
270 struct talitos_request *request;
Kim Phillips5228f0f2011-07-15 11:21:38 +0800271 unsigned long flags;
Kim Phillips9c4a7962008-06-23 19:50:15 +0800272 int head;
LEROY Christophe7d607c6a2015-04-17 16:32:09 +0200273 bool is_sec1 = has_ftr_sec1(priv);
Kim Phillips9c4a7962008-06-23 19:50:15 +0800274
Kim Phillips4b9926282009-08-13 11:50:38 +1000275 spin_lock_irqsave(&priv->chan[ch].head_lock, flags);
Kim Phillips9c4a7962008-06-23 19:50:15 +0800276
Kim Phillips4b9926282009-08-13 11:50:38 +1000277 if (!atomic_inc_not_zero(&priv->chan[ch].submit_count)) {
Kim Phillipsec6644d2008-07-17 20:16:40 +0800278 /* h/w fifo is full */
Kim Phillips4b9926282009-08-13 11:50:38 +1000279 spin_unlock_irqrestore(&priv->chan[ch].head_lock, flags);
Kim Phillips9c4a7962008-06-23 19:50:15 +0800280 return -EAGAIN;
281 }
282
Kim Phillips4b9926282009-08-13 11:50:38 +1000283 head = priv->chan[ch].head;
284 request = &priv->chan[ch].fifo[head];
Kim Phillipsec6644d2008-07-17 20:16:40 +0800285
Kim Phillips9c4a7962008-06-23 19:50:15 +0800286 /* map descriptor and save caller data */
LEROY Christophe7d607c6a2015-04-17 16:32:09 +0200287 if (is_sec1) {
288 desc->hdr1 = desc->hdr;
LEROY Christophe7d607c6a2015-04-17 16:32:09 +0200289 request->dma_desc = dma_map_single(dev, &desc->hdr1,
290 TALITOS_DESC_SIZE,
291 DMA_BIDIRECTIONAL);
292 } else {
293 request->dma_desc = dma_map_single(dev, desc,
294 TALITOS_DESC_SIZE,
295 DMA_BIDIRECTIONAL);
296 }
Kim Phillips9c4a7962008-06-23 19:50:15 +0800297 request->callback = callback;
298 request->context = context;
299
300 /* increment fifo head */
Kim Phillips4b9926282009-08-13 11:50:38 +1000301 priv->chan[ch].head = (priv->chan[ch].head + 1) & (priv->fifo_len - 1);
Kim Phillips9c4a7962008-06-23 19:50:15 +0800302
303 smp_wmb();
304 request->desc = desc;
305
306 /* GO! */
307 wmb();
Kim Phillipsad42d5f2011-11-21 16:13:27 +0800308 out_be32(priv->chan[ch].reg + TALITOS_FF,
309 upper_32_bits(request->dma_desc));
310 out_be32(priv->chan[ch].reg + TALITOS_FF_LO,
Kim Phillipsa7524472010-09-23 15:56:38 +0800311 lower_32_bits(request->dma_desc));
Kim Phillips9c4a7962008-06-23 19:50:15 +0800312
Kim Phillips4b9926282009-08-13 11:50:38 +1000313 spin_unlock_irqrestore(&priv->chan[ch].head_lock, flags);
Kim Phillips9c4a7962008-06-23 19:50:15 +0800314
315 return -EINPROGRESS;
316}
Horia Geanta865d5062012-07-03 19:16:52 +0300317EXPORT_SYMBOL(talitos_submit);
Kim Phillips9c4a7962008-06-23 19:50:15 +0800318
319/*
320 * process what was done, notify callback of error if not
321 */
322static void flush_channel(struct device *dev, int ch, int error, int reset_ch)
323{
324 struct talitos_private *priv = dev_get_drvdata(dev);
325 struct talitos_request *request, saved_req;
326 unsigned long flags;
327 int tail, status;
LEROY Christophe7d607c6a2015-04-17 16:32:09 +0200328 bool is_sec1 = has_ftr_sec1(priv);
Kim Phillips9c4a7962008-06-23 19:50:15 +0800329
Kim Phillips4b9926282009-08-13 11:50:38 +1000330 spin_lock_irqsave(&priv->chan[ch].tail_lock, flags);
Kim Phillips9c4a7962008-06-23 19:50:15 +0800331
Kim Phillips4b9926282009-08-13 11:50:38 +1000332 tail = priv->chan[ch].tail;
333 while (priv->chan[ch].fifo[tail].desc) {
LEROY Christophe7d607c6a2015-04-17 16:32:09 +0200334 __be32 hdr;
335
Kim Phillips4b9926282009-08-13 11:50:38 +1000336 request = &priv->chan[ch].fifo[tail];
Kim Phillips9c4a7962008-06-23 19:50:15 +0800337
338 /* descriptors with their done bits set don't get the error */
339 rmb();
LEROY Christophe37b5e882017-10-06 15:05:06 +0200340 if (!is_sec1)
341 hdr = request->desc->hdr;
342 else if (request->desc->next_desc)
343 hdr = (request->desc + 1)->hdr1;
344 else
345 hdr = request->desc->hdr1;
LEROY Christophe7d607c6a2015-04-17 16:32:09 +0200346
347 if ((hdr & DESC_HDR_DONE) == DESC_HDR_DONE)
Kim Phillips9c4a7962008-06-23 19:50:15 +0800348 status = 0;
Lee Nipperca38a812008-12-20 17:09:25 +1100349 else
Kim Phillips9c4a7962008-06-23 19:50:15 +0800350 if (!error)
351 break;
352 else
353 status = error;
354
355 dma_unmap_single(dev, request->dma_desc,
LEROY Christophe7d607c6a2015-04-17 16:32:09 +0200356 TALITOS_DESC_SIZE,
Kim Phillipse938e462009-03-29 15:53:23 +0800357 DMA_BIDIRECTIONAL);
Kim Phillips9c4a7962008-06-23 19:50:15 +0800358
359 /* copy entries so we can call callback outside lock */
360 saved_req.desc = request->desc;
361 saved_req.callback = request->callback;
362 saved_req.context = request->context;
363
364 /* release request entry in fifo */
365 smp_wmb();
366 request->desc = NULL;
367
368 /* increment fifo tail */
Kim Phillips4b9926282009-08-13 11:50:38 +1000369 priv->chan[ch].tail = (tail + 1) & (priv->fifo_len - 1);
Kim Phillips9c4a7962008-06-23 19:50:15 +0800370
Kim Phillips4b9926282009-08-13 11:50:38 +1000371 spin_unlock_irqrestore(&priv->chan[ch].tail_lock, flags);
Kim Phillipsec6644d2008-07-17 20:16:40 +0800372
Kim Phillips4b9926282009-08-13 11:50:38 +1000373 atomic_dec(&priv->chan[ch].submit_count);
Kim Phillipsec6644d2008-07-17 20:16:40 +0800374
Kim Phillips9c4a7962008-06-23 19:50:15 +0800375 saved_req.callback(dev, saved_req.desc, saved_req.context,
376 status);
377 /* channel may resume processing in single desc error case */
378 if (error && !reset_ch && status == error)
379 return;
Kim Phillips4b9926282009-08-13 11:50:38 +1000380 spin_lock_irqsave(&priv->chan[ch].tail_lock, flags);
381 tail = priv->chan[ch].tail;
Kim Phillips9c4a7962008-06-23 19:50:15 +0800382 }
383
Kim Phillips4b9926282009-08-13 11:50:38 +1000384 spin_unlock_irqrestore(&priv->chan[ch].tail_lock, flags);
Kim Phillips9c4a7962008-06-23 19:50:15 +0800385}
386
387/*
388 * process completed requests for channels that have done status
389 */
LEROY Christophedd3c0982015-04-17 16:32:13 +0200390#define DEF_TALITOS1_DONE(name, ch_done_mask) \
391static void talitos1_done_##name(unsigned long data) \
392{ \
393 struct device *dev = (struct device *)data; \
394 struct talitos_private *priv = dev_get_drvdata(dev); \
395 unsigned long flags; \
396 \
397 if (ch_done_mask & 0x10000000) \
398 flush_channel(dev, 0, 0, 0); \
LEROY Christophedd3c0982015-04-17 16:32:13 +0200399 if (ch_done_mask & 0x40000000) \
400 flush_channel(dev, 1, 0, 0); \
401 if (ch_done_mask & 0x00010000) \
402 flush_channel(dev, 2, 0, 0); \
403 if (ch_done_mask & 0x00040000) \
404 flush_channel(dev, 3, 0, 0); \
405 \
LEROY Christophedd3c0982015-04-17 16:32:13 +0200406 /* At this point, all completed channels have been processed */ \
407 /* Unmask done interrupts for channels completed later on. */ \
408 spin_lock_irqsave(&priv->reg_lock, flags); \
409 clrbits32(priv->reg + TALITOS_IMR, ch_done_mask); \
410 clrbits32(priv->reg + TALITOS_IMR_LO, TALITOS1_IMR_LO_INIT); \
411 spin_unlock_irqrestore(&priv->reg_lock, flags); \
412}
413
414DEF_TALITOS1_DONE(4ch, TALITOS1_ISR_4CHDONE)
LEROY Christophe9c02e282017-10-06 15:04:55 +0200415DEF_TALITOS1_DONE(ch0, TALITOS1_ISR_CH_0_DONE)
LEROY Christophedd3c0982015-04-17 16:32:13 +0200416
417#define DEF_TALITOS2_DONE(name, ch_done_mask) \
418static void talitos2_done_##name(unsigned long data) \
Kim Phillipsc3e337f2011-11-21 16:13:27 +0800419{ \
420 struct device *dev = (struct device *)data; \
421 struct talitos_private *priv = dev_get_drvdata(dev); \
Horia Geanta511d63c2012-03-30 17:49:53 +0300422 unsigned long flags; \
Kim Phillipsc3e337f2011-11-21 16:13:27 +0800423 \
424 if (ch_done_mask & 1) \
425 flush_channel(dev, 0, 0, 0); \
Kim Phillipsc3e337f2011-11-21 16:13:27 +0800426 if (ch_done_mask & (1 << 2)) \
427 flush_channel(dev, 1, 0, 0); \
428 if (ch_done_mask & (1 << 4)) \
429 flush_channel(dev, 2, 0, 0); \
430 if (ch_done_mask & (1 << 6)) \
431 flush_channel(dev, 3, 0, 0); \
432 \
Kim Phillipsc3e337f2011-11-21 16:13:27 +0800433 /* At this point, all completed channels have been processed */ \
434 /* Unmask done interrupts for channels completed later on. */ \
Horia Geanta511d63c2012-03-30 17:49:53 +0300435 spin_lock_irqsave(&priv->reg_lock, flags); \
Kim Phillipsc3e337f2011-11-21 16:13:27 +0800436 setbits32(priv->reg + TALITOS_IMR, ch_done_mask); \
LEROY Christophedd3c0982015-04-17 16:32:13 +0200437 setbits32(priv->reg + TALITOS_IMR_LO, TALITOS2_IMR_LO_INIT); \
Horia Geanta511d63c2012-03-30 17:49:53 +0300438 spin_unlock_irqrestore(&priv->reg_lock, flags); \
Kim Phillips9c4a7962008-06-23 19:50:15 +0800439}
LEROY Christophedd3c0982015-04-17 16:32:13 +0200440
441DEF_TALITOS2_DONE(4ch, TALITOS2_ISR_4CHDONE)
LEROY Christophe9c02e282017-10-06 15:04:55 +0200442DEF_TALITOS2_DONE(ch0, TALITOS2_ISR_CH_0_DONE)
LEROY Christophedd3c0982015-04-17 16:32:13 +0200443DEF_TALITOS2_DONE(ch0_2, TALITOS2_ISR_CH_0_2_DONE)
444DEF_TALITOS2_DONE(ch1_3, TALITOS2_ISR_CH_1_3_DONE)
Kim Phillips9c4a7962008-06-23 19:50:15 +0800445
446/*
447 * locate current (offending) descriptor
448 */
Kim Phillips3e721ae2011-10-21 15:20:28 +0200449static u32 current_desc_hdr(struct device *dev, int ch)
Kim Phillips9c4a7962008-06-23 19:50:15 +0800450{
451 struct talitos_private *priv = dev_get_drvdata(dev);
Horia Geantab62ffd82013-11-13 12:20:37 +0200452 int tail, iter;
Kim Phillips9c4a7962008-06-23 19:50:15 +0800453 dma_addr_t cur_desc;
454
Horia Geantab62ffd82013-11-13 12:20:37 +0200455 cur_desc = ((u64)in_be32(priv->chan[ch].reg + TALITOS_CDPR)) << 32;
456 cur_desc |= in_be32(priv->chan[ch].reg + TALITOS_CDPR_LO);
Kim Phillips9c4a7962008-06-23 19:50:15 +0800457
Horia Geantab62ffd82013-11-13 12:20:37 +0200458 if (!cur_desc) {
459 dev_err(dev, "CDPR is NULL, giving up search for offending descriptor\n");
460 return 0;
461 }
462
463 tail = priv->chan[ch].tail;
464
465 iter = tail;
LEROY Christophe37b5e882017-10-06 15:05:06 +0200466 while (priv->chan[ch].fifo[iter].dma_desc != cur_desc &&
467 priv->chan[ch].fifo[iter].desc->next_desc != cur_desc) {
Horia Geantab62ffd82013-11-13 12:20:37 +0200468 iter = (iter + 1) & (priv->fifo_len - 1);
469 if (iter == tail) {
Kim Phillips9c4a7962008-06-23 19:50:15 +0800470 dev_err(dev, "couldn't locate current descriptor\n");
Kim Phillips3e721ae2011-10-21 15:20:28 +0200471 return 0;
Kim Phillips9c4a7962008-06-23 19:50:15 +0800472 }
473 }
474
LEROY Christophe37b5e882017-10-06 15:05:06 +0200475 if (priv->chan[ch].fifo[iter].desc->next_desc == cur_desc)
476 return (priv->chan[ch].fifo[iter].desc + 1)->hdr;
477
Horia Geantab62ffd82013-11-13 12:20:37 +0200478 return priv->chan[ch].fifo[iter].desc->hdr;
Kim Phillips9c4a7962008-06-23 19:50:15 +0800479}
480
481/*
482 * user diagnostics; report root cause of error based on execution unit status
483 */
Kim Phillips3e721ae2011-10-21 15:20:28 +0200484static void report_eu_error(struct device *dev, int ch, u32 desc_hdr)
Kim Phillips9c4a7962008-06-23 19:50:15 +0800485{
486 struct talitos_private *priv = dev_get_drvdata(dev);
487 int i;
488
Kim Phillips3e721ae2011-10-21 15:20:28 +0200489 if (!desc_hdr)
Kim Phillipsad42d5f2011-11-21 16:13:27 +0800490 desc_hdr = in_be32(priv->chan[ch].reg + TALITOS_DESCBUF);
Kim Phillips3e721ae2011-10-21 15:20:28 +0200491
492 switch (desc_hdr & DESC_HDR_SEL0_MASK) {
Kim Phillips9c4a7962008-06-23 19:50:15 +0800493 case DESC_HDR_SEL0_AFEU:
494 dev_err(dev, "AFEUISR 0x%08x_%08x\n",
LEROY Christophe5fa7fa12015-04-17 16:32:11 +0200495 in_be32(priv->reg_afeu + TALITOS_EUISR),
496 in_be32(priv->reg_afeu + TALITOS_EUISR_LO));
Kim Phillips9c4a7962008-06-23 19:50:15 +0800497 break;
498 case DESC_HDR_SEL0_DEU:
499 dev_err(dev, "DEUISR 0x%08x_%08x\n",
LEROY Christophe5fa7fa12015-04-17 16:32:11 +0200500 in_be32(priv->reg_deu + TALITOS_EUISR),
501 in_be32(priv->reg_deu + TALITOS_EUISR_LO));
Kim Phillips9c4a7962008-06-23 19:50:15 +0800502 break;
503 case DESC_HDR_SEL0_MDEUA:
504 case DESC_HDR_SEL0_MDEUB:
505 dev_err(dev, "MDEUISR 0x%08x_%08x\n",
LEROY Christophe5fa7fa12015-04-17 16:32:11 +0200506 in_be32(priv->reg_mdeu + TALITOS_EUISR),
507 in_be32(priv->reg_mdeu + TALITOS_EUISR_LO));
Kim Phillips9c4a7962008-06-23 19:50:15 +0800508 break;
509 case DESC_HDR_SEL0_RNG:
510 dev_err(dev, "RNGUISR 0x%08x_%08x\n",
LEROY Christophe5fa7fa12015-04-17 16:32:11 +0200511 in_be32(priv->reg_rngu + TALITOS_ISR),
512 in_be32(priv->reg_rngu + TALITOS_ISR_LO));
Kim Phillips9c4a7962008-06-23 19:50:15 +0800513 break;
514 case DESC_HDR_SEL0_PKEU:
515 dev_err(dev, "PKEUISR 0x%08x_%08x\n",
LEROY Christophe5fa7fa12015-04-17 16:32:11 +0200516 in_be32(priv->reg_pkeu + TALITOS_EUISR),
517 in_be32(priv->reg_pkeu + TALITOS_EUISR_LO));
Kim Phillips9c4a7962008-06-23 19:50:15 +0800518 break;
519 case DESC_HDR_SEL0_AESU:
520 dev_err(dev, "AESUISR 0x%08x_%08x\n",
LEROY Christophe5fa7fa12015-04-17 16:32:11 +0200521 in_be32(priv->reg_aesu + TALITOS_EUISR),
522 in_be32(priv->reg_aesu + TALITOS_EUISR_LO));
Kim Phillips9c4a7962008-06-23 19:50:15 +0800523 break;
524 case DESC_HDR_SEL0_CRCU:
525 dev_err(dev, "CRCUISR 0x%08x_%08x\n",
LEROY Christophe5fa7fa12015-04-17 16:32:11 +0200526 in_be32(priv->reg_crcu + TALITOS_EUISR),
527 in_be32(priv->reg_crcu + TALITOS_EUISR_LO));
Kim Phillips9c4a7962008-06-23 19:50:15 +0800528 break;
529 case DESC_HDR_SEL0_KEU:
530 dev_err(dev, "KEUISR 0x%08x_%08x\n",
LEROY Christophe5fa7fa12015-04-17 16:32:11 +0200531 in_be32(priv->reg_pkeu + TALITOS_EUISR),
532 in_be32(priv->reg_pkeu + TALITOS_EUISR_LO));
Kim Phillips9c4a7962008-06-23 19:50:15 +0800533 break;
534 }
535
Kim Phillips3e721ae2011-10-21 15:20:28 +0200536 switch (desc_hdr & DESC_HDR_SEL1_MASK) {
Kim Phillips9c4a7962008-06-23 19:50:15 +0800537 case DESC_HDR_SEL1_MDEUA:
538 case DESC_HDR_SEL1_MDEUB:
539 dev_err(dev, "MDEUISR 0x%08x_%08x\n",
LEROY Christophe5fa7fa12015-04-17 16:32:11 +0200540 in_be32(priv->reg_mdeu + TALITOS_EUISR),
541 in_be32(priv->reg_mdeu + TALITOS_EUISR_LO));
Kim Phillips9c4a7962008-06-23 19:50:15 +0800542 break;
543 case DESC_HDR_SEL1_CRCU:
544 dev_err(dev, "CRCUISR 0x%08x_%08x\n",
LEROY Christophe5fa7fa12015-04-17 16:32:11 +0200545 in_be32(priv->reg_crcu + TALITOS_EUISR),
546 in_be32(priv->reg_crcu + TALITOS_EUISR_LO));
Kim Phillips9c4a7962008-06-23 19:50:15 +0800547 break;
548 }
549
550 for (i = 0; i < 8; i++)
551 dev_err(dev, "DESCBUF 0x%08x_%08x\n",
Kim Phillipsad42d5f2011-11-21 16:13:27 +0800552 in_be32(priv->chan[ch].reg + TALITOS_DESCBUF + 8*i),
553 in_be32(priv->chan[ch].reg + TALITOS_DESCBUF_LO + 8*i));
Kim Phillips9c4a7962008-06-23 19:50:15 +0800554}
555
556/*
557 * recover from error interrupts
558 */
Kim Phillips5e718a02011-12-12 14:59:12 -0600559static void talitos_error(struct device *dev, u32 isr, u32 isr_lo)
Kim Phillips9c4a7962008-06-23 19:50:15 +0800560{
Kim Phillips9c4a7962008-06-23 19:50:15 +0800561 struct talitos_private *priv = dev_get_drvdata(dev);
562 unsigned int timeout = TALITOS_TIMEOUT;
LEROY Christophedd3c0982015-04-17 16:32:13 +0200563 int ch, error, reset_dev = 0;
Horia Geant?42e8b0d2015-05-11 20:04:56 +0300564 u32 v_lo;
LEROY Christophedd3c0982015-04-17 16:32:13 +0200565 bool is_sec1 = has_ftr_sec1(priv);
566 int reset_ch = is_sec1 ? 1 : 0; /* only SEC2 supports continuation */
Kim Phillips9c4a7962008-06-23 19:50:15 +0800567
568 for (ch = 0; ch < priv->num_channels; ch++) {
569 /* skip channels without errors */
LEROY Christophedd3c0982015-04-17 16:32:13 +0200570 if (is_sec1) {
571 /* bits 29, 31, 17, 19 */
572 if (!(isr & (1 << (29 + (ch & 1) * 2 - (ch & 2) * 6))))
573 continue;
574 } else {
575 if (!(isr & (1 << (ch * 2 + 1))))
576 continue;
577 }
Kim Phillips9c4a7962008-06-23 19:50:15 +0800578
579 error = -EINVAL;
580
Kim Phillipsad42d5f2011-11-21 16:13:27 +0800581 v_lo = in_be32(priv->chan[ch].reg + TALITOS_CCPSR_LO);
Kim Phillips9c4a7962008-06-23 19:50:15 +0800582
583 if (v_lo & TALITOS_CCPSR_LO_DOF) {
584 dev_err(dev, "double fetch fifo overflow error\n");
585 error = -EAGAIN;
586 reset_ch = 1;
587 }
588 if (v_lo & TALITOS_CCPSR_LO_SOF) {
589 /* h/w dropped descriptor */
590 dev_err(dev, "single fetch fifo overflow error\n");
591 error = -EAGAIN;
592 }
593 if (v_lo & TALITOS_CCPSR_LO_MDTE)
594 dev_err(dev, "master data transfer error\n");
595 if (v_lo & TALITOS_CCPSR_LO_SGDLZ)
Colin Ian King4d9b3a52016-11-01 20:14:04 -0600596 dev_err(dev, is_sec1 ? "pointer not complete error\n"
LEROY Christophedd3c0982015-04-17 16:32:13 +0200597 : "s/g data length zero error\n");
Kim Phillips9c4a7962008-06-23 19:50:15 +0800598 if (v_lo & TALITOS_CCPSR_LO_FPZ)
LEROY Christophedd3c0982015-04-17 16:32:13 +0200599 dev_err(dev, is_sec1 ? "parity error\n"
600 : "fetch pointer zero error\n");
Kim Phillips9c4a7962008-06-23 19:50:15 +0800601 if (v_lo & TALITOS_CCPSR_LO_IDH)
602 dev_err(dev, "illegal descriptor header error\n");
603 if (v_lo & TALITOS_CCPSR_LO_IEU)
LEROY Christophedd3c0982015-04-17 16:32:13 +0200604 dev_err(dev, is_sec1 ? "static assignment error\n"
605 : "invalid exec unit error\n");
Kim Phillips9c4a7962008-06-23 19:50:15 +0800606 if (v_lo & TALITOS_CCPSR_LO_EU)
Kim Phillips3e721ae2011-10-21 15:20:28 +0200607 report_eu_error(dev, ch, current_desc_hdr(dev, ch));
LEROY Christophedd3c0982015-04-17 16:32:13 +0200608 if (!is_sec1) {
609 if (v_lo & TALITOS_CCPSR_LO_GB)
610 dev_err(dev, "gather boundary error\n");
611 if (v_lo & TALITOS_CCPSR_LO_GRL)
612 dev_err(dev, "gather return/length error\n");
613 if (v_lo & TALITOS_CCPSR_LO_SB)
614 dev_err(dev, "scatter boundary error\n");
615 if (v_lo & TALITOS_CCPSR_LO_SRL)
616 dev_err(dev, "scatter return/length error\n");
617 }
Kim Phillips9c4a7962008-06-23 19:50:15 +0800618
619 flush_channel(dev, ch, error, reset_ch);
620
621 if (reset_ch) {
622 reset_channel(dev, ch);
623 } else {
Kim Phillipsad42d5f2011-11-21 16:13:27 +0800624 setbits32(priv->chan[ch].reg + TALITOS_CCCR,
LEROY Christophedd3c0982015-04-17 16:32:13 +0200625 TALITOS2_CCCR_CONT);
Kim Phillipsad42d5f2011-11-21 16:13:27 +0800626 setbits32(priv->chan[ch].reg + TALITOS_CCCR_LO, 0);
627 while ((in_be32(priv->chan[ch].reg + TALITOS_CCCR) &
LEROY Christophedd3c0982015-04-17 16:32:13 +0200628 TALITOS2_CCCR_CONT) && --timeout)
Kim Phillips9c4a7962008-06-23 19:50:15 +0800629 cpu_relax();
630 if (timeout == 0) {
631 dev_err(dev, "failed to restart channel %d\n",
632 ch);
633 reset_dev = 1;
634 }
635 }
636 }
LEROY Christophedd3c0982015-04-17 16:32:13 +0200637 if (reset_dev || (is_sec1 && isr & ~TALITOS1_ISR_4CHERR) ||
638 (!is_sec1 && isr & ~TALITOS2_ISR_4CHERR) || isr_lo) {
639 if (is_sec1 && (isr_lo & TALITOS1_ISR_TEA_ERR))
640 dev_err(dev, "TEA error: ISR 0x%08x_%08x\n",
641 isr, isr_lo);
642 else
643 dev_err(dev, "done overflow, internal time out, or "
644 "rngu error: ISR 0x%08x_%08x\n", isr, isr_lo);
Kim Phillips9c4a7962008-06-23 19:50:15 +0800645
646 /* purge request queues */
647 for (ch = 0; ch < priv->num_channels; ch++)
648 flush_channel(dev, ch, -EIO, 1);
649
650 /* reset and reinitialize the device */
651 init_device(dev);
652 }
653}
654
LEROY Christophedd3c0982015-04-17 16:32:13 +0200655#define DEF_TALITOS1_INTERRUPT(name, ch_done_mask, ch_err_mask, tlet) \
656static irqreturn_t talitos1_interrupt_##name(int irq, void *data) \
657{ \
658 struct device *dev = data; \
659 struct talitos_private *priv = dev_get_drvdata(dev); \
660 u32 isr, isr_lo; \
661 unsigned long flags; \
662 \
663 spin_lock_irqsave(&priv->reg_lock, flags); \
664 isr = in_be32(priv->reg + TALITOS_ISR); \
665 isr_lo = in_be32(priv->reg + TALITOS_ISR_LO); \
666 /* Acknowledge interrupt */ \
667 out_be32(priv->reg + TALITOS_ICR, isr & (ch_done_mask | ch_err_mask)); \
668 out_be32(priv->reg + TALITOS_ICR_LO, isr_lo); \
669 \
670 if (unlikely(isr & ch_err_mask || isr_lo & TALITOS1_IMR_LO_INIT)) { \
671 spin_unlock_irqrestore(&priv->reg_lock, flags); \
672 talitos_error(dev, isr & ch_err_mask, isr_lo); \
673 } \
674 else { \
675 if (likely(isr & ch_done_mask)) { \
676 /* mask further done interrupts. */ \
677 setbits32(priv->reg + TALITOS_IMR, ch_done_mask); \
678 /* done_task will unmask done interrupts at exit */ \
679 tasklet_schedule(&priv->done_task[tlet]); \
680 } \
681 spin_unlock_irqrestore(&priv->reg_lock, flags); \
682 } \
683 \
684 return (isr & (ch_done_mask | ch_err_mask) || isr_lo) ? IRQ_HANDLED : \
685 IRQ_NONE; \
686}
687
688DEF_TALITOS1_INTERRUPT(4ch, TALITOS1_ISR_4CHDONE, TALITOS1_ISR_4CHERR, 0)
689
690#define DEF_TALITOS2_INTERRUPT(name, ch_done_mask, ch_err_mask, tlet) \
691static irqreturn_t talitos2_interrupt_##name(int irq, void *data) \
Kim Phillipsc3e337f2011-11-21 16:13:27 +0800692{ \
693 struct device *dev = data; \
694 struct talitos_private *priv = dev_get_drvdata(dev); \
695 u32 isr, isr_lo; \
Horia Geanta511d63c2012-03-30 17:49:53 +0300696 unsigned long flags; \
Kim Phillipsc3e337f2011-11-21 16:13:27 +0800697 \
Horia Geanta511d63c2012-03-30 17:49:53 +0300698 spin_lock_irqsave(&priv->reg_lock, flags); \
Kim Phillipsc3e337f2011-11-21 16:13:27 +0800699 isr = in_be32(priv->reg + TALITOS_ISR); \
700 isr_lo = in_be32(priv->reg + TALITOS_ISR_LO); \
701 /* Acknowledge interrupt */ \
702 out_be32(priv->reg + TALITOS_ICR, isr & (ch_done_mask | ch_err_mask)); \
703 out_be32(priv->reg + TALITOS_ICR_LO, isr_lo); \
704 \
Horia Geanta511d63c2012-03-30 17:49:53 +0300705 if (unlikely(isr & ch_err_mask || isr_lo)) { \
706 spin_unlock_irqrestore(&priv->reg_lock, flags); \
707 talitos_error(dev, isr & ch_err_mask, isr_lo); \
708 } \
709 else { \
Kim Phillipsc3e337f2011-11-21 16:13:27 +0800710 if (likely(isr & ch_done_mask)) { \
711 /* mask further done interrupts. */ \
712 clrbits32(priv->reg + TALITOS_IMR, ch_done_mask); \
713 /* done_task will unmask done interrupts at exit */ \
714 tasklet_schedule(&priv->done_task[tlet]); \
715 } \
Horia Geanta511d63c2012-03-30 17:49:53 +0300716 spin_unlock_irqrestore(&priv->reg_lock, flags); \
717 } \
Kim Phillipsc3e337f2011-11-21 16:13:27 +0800718 \
719 return (isr & (ch_done_mask | ch_err_mask) || isr_lo) ? IRQ_HANDLED : \
720 IRQ_NONE; \
Kim Phillips9c4a7962008-06-23 19:50:15 +0800721}
LEROY Christophedd3c0982015-04-17 16:32:13 +0200722
723DEF_TALITOS2_INTERRUPT(4ch, TALITOS2_ISR_4CHDONE, TALITOS2_ISR_4CHERR, 0)
724DEF_TALITOS2_INTERRUPT(ch0_2, TALITOS2_ISR_CH_0_2_DONE, TALITOS2_ISR_CH_0_2_ERR,
725 0)
726DEF_TALITOS2_INTERRUPT(ch1_3, TALITOS2_ISR_CH_1_3_DONE, TALITOS2_ISR_CH_1_3_ERR,
727 1)
Kim Phillips9c4a7962008-06-23 19:50:15 +0800728
729/*
730 * hwrng
731 */
732static int talitos_rng_data_present(struct hwrng *rng, int wait)
733{
734 struct device *dev = (struct device *)rng->priv;
735 struct talitos_private *priv = dev_get_drvdata(dev);
736 u32 ofl;
737 int i;
738
739 for (i = 0; i < 20; i++) {
LEROY Christophe5fa7fa12015-04-17 16:32:11 +0200740 ofl = in_be32(priv->reg_rngu + TALITOS_EUSR_LO) &
Kim Phillips9c4a7962008-06-23 19:50:15 +0800741 TALITOS_RNGUSR_LO_OFL;
742 if (ofl || !wait)
743 break;
744 udelay(10);
745 }
746
747 return !!ofl;
748}
749
750static int talitos_rng_data_read(struct hwrng *rng, u32 *data)
751{
752 struct device *dev = (struct device *)rng->priv;
753 struct talitos_private *priv = dev_get_drvdata(dev);
754
755 /* rng fifo requires 64-bit accesses */
LEROY Christophe5fa7fa12015-04-17 16:32:11 +0200756 *data = in_be32(priv->reg_rngu + TALITOS_EU_FIFO);
757 *data = in_be32(priv->reg_rngu + TALITOS_EU_FIFO_LO);
Kim Phillips9c4a7962008-06-23 19:50:15 +0800758
759 return sizeof(u32);
760}
761
762static int talitos_rng_init(struct hwrng *rng)
763{
764 struct device *dev = (struct device *)rng->priv;
765 struct talitos_private *priv = dev_get_drvdata(dev);
766 unsigned int timeout = TALITOS_TIMEOUT;
767
LEROY Christophe5fa7fa12015-04-17 16:32:11 +0200768 setbits32(priv->reg_rngu + TALITOS_EURCR_LO, TALITOS_RNGURCR_LO_SR);
769 while (!(in_be32(priv->reg_rngu + TALITOS_EUSR_LO)
770 & TALITOS_RNGUSR_LO_RD)
Kim Phillips9c4a7962008-06-23 19:50:15 +0800771 && --timeout)
772 cpu_relax();
773 if (timeout == 0) {
774 dev_err(dev, "failed to reset rng hw\n");
775 return -ENODEV;
776 }
777
778 /* start generating */
LEROY Christophe5fa7fa12015-04-17 16:32:11 +0200779 setbits32(priv->reg_rngu + TALITOS_EUDSR_LO, 0);
Kim Phillips9c4a7962008-06-23 19:50:15 +0800780
781 return 0;
782}
783
784static int talitos_register_rng(struct device *dev)
785{
786 struct talitos_private *priv = dev_get_drvdata(dev);
Aaron Sierra35a3bb32015-08-05 16:52:08 -0500787 int err;
Kim Phillips9c4a7962008-06-23 19:50:15 +0800788
789 priv->rng.name = dev_driver_string(dev),
790 priv->rng.init = talitos_rng_init,
791 priv->rng.data_present = talitos_rng_data_present,
792 priv->rng.data_read = talitos_rng_data_read,
793 priv->rng.priv = (unsigned long)dev;
794
Aaron Sierra35a3bb32015-08-05 16:52:08 -0500795 err = hwrng_register(&priv->rng);
796 if (!err)
797 priv->rng_registered = true;
798
799 return err;
Kim Phillips9c4a7962008-06-23 19:50:15 +0800800}
801
802static void talitos_unregister_rng(struct device *dev)
803{
804 struct talitos_private *priv = dev_get_drvdata(dev);
805
Aaron Sierra35a3bb32015-08-05 16:52:08 -0500806 if (!priv->rng_registered)
807 return;
808
Kim Phillips9c4a7962008-06-23 19:50:15 +0800809 hwrng_unregister(&priv->rng);
Aaron Sierra35a3bb32015-08-05 16:52:08 -0500810 priv->rng_registered = false;
Kim Phillips9c4a7962008-06-23 19:50:15 +0800811}
812
813/*
814 * crypto alg
815 */
816#define TALITOS_CRA_PRIORITY 3000
LEROY Christophe7405c8d2016-06-06 13:20:46 +0200817/*
818 * Defines a priority for doing AEAD with descriptors type
819 * HMAC_SNOOP_NO_AFEA (HSNA) instead of type IPSEC_ESP
820 */
821#define TALITOS_CRA_PRIORITY_AEAD_HSNA (TALITOS_CRA_PRIORITY - 1)
Martin Hicks03d2c512017-05-02 09:38:35 -0400822#define TALITOS_MAX_KEY_SIZE (AES_MAX_KEY_SIZE + SHA512_BLOCK_SIZE)
Lee Nipper3952f172008-07-10 18:29:18 +0800823#define TALITOS_MAX_IV_LENGTH 16 /* max of AES_BLOCK_SIZE, DES3_EDE_BLOCK_SIZE */
Lee Nipper70bcaca2008-07-03 19:08:46 +0800824
Kim Phillips9c4a7962008-06-23 19:50:15 +0800825struct talitos_ctx {
826 struct device *dev;
Kim Phillips5228f0f2011-07-15 11:21:38 +0800827 int ch;
Kim Phillips9c4a7962008-06-23 19:50:15 +0800828 __be32 desc_hdr_template;
829 u8 key[TALITOS_MAX_KEY_SIZE];
Lee Nipper70bcaca2008-07-03 19:08:46 +0800830 u8 iv[TALITOS_MAX_IV_LENGTH];
LEROY Christophe2e13ce02017-10-06 15:05:02 +0200831 dma_addr_t dma_key;
Kim Phillips9c4a7962008-06-23 19:50:15 +0800832 unsigned int keylen;
833 unsigned int enckeylen;
834 unsigned int authkeylen;
Kim Phillips9c4a7962008-06-23 19:50:15 +0800835};
836
Lee Nipper497f2e62010-05-19 19:20:36 +1000837#define HASH_MAX_BLOCK_SIZE SHA512_BLOCK_SIZE
838#define TALITOS_MDEU_MAX_CONTEXT_SIZE TALITOS_MDEU_CONTEXT_SIZE_SHA384_SHA512
839
840struct talitos_ahash_req_ctx {
Kim Phillips60f208d2010-05-19 19:21:53 +1000841 u32 hw_context[TALITOS_MDEU_MAX_CONTEXT_SIZE / sizeof(u32)];
Lee Nipper497f2e62010-05-19 19:20:36 +1000842 unsigned int hw_context_size;
LEROY Christophe3c0dd192017-10-06 15:05:08 +0200843 u8 buf[2][HASH_MAX_BLOCK_SIZE];
844 int buf_idx;
Kim Phillips60f208d2010-05-19 19:21:53 +1000845 unsigned int swinit;
Lee Nipper497f2e62010-05-19 19:20:36 +1000846 unsigned int first;
847 unsigned int last;
848 unsigned int to_hash_later;
Horia Geant?42e8b0d2015-05-11 20:04:56 +0300849 unsigned int nbuf;
Lee Nipper497f2e62010-05-19 19:20:36 +1000850 struct scatterlist bufsl[2];
851 struct scatterlist *psrc;
852};
853
Horia Geant?3639ca82016-04-21 19:24:55 +0300854struct talitos_export_state {
855 u32 hw_context[TALITOS_MDEU_MAX_CONTEXT_SIZE / sizeof(u32)];
856 u8 buf[HASH_MAX_BLOCK_SIZE];
857 unsigned int swinit;
858 unsigned int first;
859 unsigned int last;
860 unsigned int to_hash_later;
861 unsigned int nbuf;
862};
863
Lee Nipper56af8cd2009-03-29 15:50:50 +0800864static int aead_setkey(struct crypto_aead *authenc,
865 const u8 *key, unsigned int keylen)
Kim Phillips9c4a7962008-06-23 19:50:15 +0800866{
867 struct talitos_ctx *ctx = crypto_aead_ctx(authenc);
LEROY Christophe2e13ce02017-10-06 15:05:02 +0200868 struct device *dev = ctx->dev;
Mathias Krausec306a982013-10-15 13:49:34 +0200869 struct crypto_authenc_keys keys;
Kim Phillips9c4a7962008-06-23 19:50:15 +0800870
Mathias Krausec306a982013-10-15 13:49:34 +0200871 if (crypto_authenc_extractkeys(&keys, key, keylen) != 0)
Kim Phillips9c4a7962008-06-23 19:50:15 +0800872 goto badkey;
873
Mathias Krausec306a982013-10-15 13:49:34 +0200874 if (keys.authkeylen + keys.enckeylen > TALITOS_MAX_KEY_SIZE)
Kim Phillips9c4a7962008-06-23 19:50:15 +0800875 goto badkey;
876
LEROY Christophe2e13ce02017-10-06 15:05:02 +0200877 if (ctx->keylen)
878 dma_unmap_single(dev, ctx->dma_key, ctx->keylen, DMA_TO_DEVICE);
879
Mathias Krausec306a982013-10-15 13:49:34 +0200880 memcpy(ctx->key, keys.authkey, keys.authkeylen);
881 memcpy(&ctx->key[keys.authkeylen], keys.enckey, keys.enckeylen);
Kim Phillips9c4a7962008-06-23 19:50:15 +0800882
Mathias Krausec306a982013-10-15 13:49:34 +0200883 ctx->keylen = keys.authkeylen + keys.enckeylen;
884 ctx->enckeylen = keys.enckeylen;
885 ctx->authkeylen = keys.authkeylen;
LEROY Christophe2e13ce02017-10-06 15:05:02 +0200886 ctx->dma_key = dma_map_single(dev, ctx->key, ctx->keylen,
887 DMA_TO_DEVICE);
Kim Phillips9c4a7962008-06-23 19:50:15 +0800888
889 return 0;
890
891badkey:
892 crypto_aead_set_flags(authenc, CRYPTO_TFM_RES_BAD_KEY_LEN);
893 return -EINVAL;
894}
895
896/*
Lee Nipper56af8cd2009-03-29 15:50:50 +0800897 * talitos_edesc - s/w-extended descriptor
Kim Phillips9c4a7962008-06-23 19:50:15 +0800898 * @src_nents: number of segments in input scatterlist
899 * @dst_nents: number of segments in output scatterlist
Herbert Xuaeb4c132015-07-30 17:53:22 +0800900 * @icv_ool: whether ICV is out-of-line
Horia Geanta79fd31d2012-08-02 17:16:40 +0300901 * @iv_dma: dma address of iv for checking continuity and link table
Kim Phillips9c4a7962008-06-23 19:50:15 +0800902 * @dma_len: length of dma mapped link_tbl space
LEROY Christophe6f65f6a2015-04-17 16:32:15 +0200903 * @dma_link_tbl: bus physical address of link_tbl/buf
Kim Phillips9c4a7962008-06-23 19:50:15 +0800904 * @desc: h/w descriptor
LEROY Christophe6f65f6a2015-04-17 16:32:15 +0200905 * @link_tbl: input and output h/w link tables (if {src,dst}_nents > 1) (SEC2)
906 * @buf: input and output buffeur (if {src,dst}_nents > 1) (SEC1)
Kim Phillips9c4a7962008-06-23 19:50:15 +0800907 *
908 * if decrypting (with authcheck), or either one of src_nents or dst_nents
909 * is greater than 1, an integrity check value is concatenated to the end
910 * of link_tbl data
911 */
Lee Nipper56af8cd2009-03-29 15:50:50 +0800912struct talitos_edesc {
Kim Phillips9c4a7962008-06-23 19:50:15 +0800913 int src_nents;
914 int dst_nents;
Herbert Xuaeb4c132015-07-30 17:53:22 +0800915 bool icv_ool;
Horia Geanta79fd31d2012-08-02 17:16:40 +0300916 dma_addr_t iv_dma;
Kim Phillips9c4a7962008-06-23 19:50:15 +0800917 int dma_len;
918 dma_addr_t dma_link_tbl;
919 struct talitos_desc desc;
LEROY Christophe6f65f6a2015-04-17 16:32:15 +0200920 union {
921 struct talitos_ptr link_tbl[0];
922 u8 buf[0];
923 };
Kim Phillips9c4a7962008-06-23 19:50:15 +0800924};
925
Lee Nipper4de9d0b2009-03-29 15:52:32 +0800926static void talitos_sg_unmap(struct device *dev,
927 struct talitos_edesc *edesc,
928 struct scatterlist *src,
LEROY Christophe6a1e8d12016-06-06 13:20:38 +0200929 struct scatterlist *dst,
930 unsigned int len, unsigned int offset)
LEROY Christophe246a87c2016-06-06 13:20:36 +0200931{
932 struct talitos_private *priv = dev_get_drvdata(dev);
933 bool is_sec1 = has_ftr_sec1(priv);
LEROY Christophe6a1e8d12016-06-06 13:20:38 +0200934 unsigned int src_nents = edesc->src_nents ? : 1;
935 unsigned int dst_nents = edesc->dst_nents ? : 1;
LEROY Christophe246a87c2016-06-06 13:20:36 +0200936
LEROY Christophe6a1e8d12016-06-06 13:20:38 +0200937 if (is_sec1 && dst && dst_nents > 1) {
938 dma_sync_single_for_device(dev, edesc->dma_link_tbl + offset,
939 len, DMA_FROM_DEVICE);
940 sg_pcopy_from_buffer(dst, dst_nents, edesc->buf + offset, len,
941 offset);
942 }
943 if (src != dst) {
944 if (src_nents == 1 || !is_sec1)
945 dma_unmap_sg(dev, src, src_nents, DMA_TO_DEVICE);
946
947 if (dst && (dst_nents == 1 || !is_sec1))
948 dma_unmap_sg(dev, dst, dst_nents, DMA_FROM_DEVICE);
949 } else if (src_nents == 1 || !is_sec1) {
950 dma_unmap_sg(dev, src, src_nents, DMA_BIDIRECTIONAL);
LEROY Christophe246a87c2016-06-06 13:20:36 +0200951 }
952}
953
Kim Phillips9c4a7962008-06-23 19:50:15 +0800954static void ipsec_esp_unmap(struct device *dev,
Lee Nipper56af8cd2009-03-29 15:50:50 +0800955 struct talitos_edesc *edesc,
Kim Phillips9c4a7962008-06-23 19:50:15 +0800956 struct aead_request *areq)
957{
LEROY Christophe549bd8b2016-06-06 13:20:40 +0200958 struct crypto_aead *aead = crypto_aead_reqtfm(areq);
959 struct talitos_ctx *ctx = crypto_aead_ctx(aead);
960 unsigned int ivsize = crypto_aead_ivsize(aead);
LEROY Christophe9a655602017-10-06 15:04:59 +0200961 bool is_ipsec_esp = edesc->desc.hdr & DESC_HDR_TYPE_IPSEC_ESP;
962 struct talitos_ptr *civ_ptr = &edesc->desc.ptr[is_ipsec_esp ? 2 : 3];
LEROY Christophe549bd8b2016-06-06 13:20:40 +0200963
LEROY Christophe9a655602017-10-06 15:04:59 +0200964 if (is_ipsec_esp)
LEROY Christophe549bd8b2016-06-06 13:20:40 +0200965 unmap_single_talitos_ptr(dev, &edesc->desc.ptr[6],
966 DMA_FROM_DEVICE);
LEROY Christophe9a655602017-10-06 15:04:59 +0200967 unmap_single_talitos_ptr(dev, civ_ptr, DMA_TO_DEVICE);
Kim Phillips9c4a7962008-06-23 19:50:15 +0800968
LEROY Christophe6a1e8d12016-06-06 13:20:38 +0200969 talitos_sg_unmap(dev, edesc, areq->src, areq->dst, areq->cryptlen,
970 areq->assoclen);
Kim Phillips9c4a7962008-06-23 19:50:15 +0800971
972 if (edesc->dma_len)
973 dma_unmap_single(dev, edesc->dma_link_tbl, edesc->dma_len,
974 DMA_BIDIRECTIONAL);
LEROY Christophe549bd8b2016-06-06 13:20:40 +0200975
LEROY Christophe9a655602017-10-06 15:04:59 +0200976 if (!is_ipsec_esp) {
LEROY Christophe549bd8b2016-06-06 13:20:40 +0200977 unsigned int dst_nents = edesc->dst_nents ? : 1;
978
979 sg_pcopy_to_buffer(areq->dst, dst_nents, ctx->iv, ivsize,
980 areq->assoclen + areq->cryptlen - ivsize);
981 }
Kim Phillips9c4a7962008-06-23 19:50:15 +0800982}
983
984/*
985 * ipsec_esp descriptor callbacks
986 */
987static void ipsec_esp_encrypt_done(struct device *dev,
988 struct talitos_desc *desc, void *context,
989 int err)
990{
LEROY Christophe549bd8b2016-06-06 13:20:40 +0200991 struct talitos_private *priv = dev_get_drvdata(dev);
992 bool is_sec1 = has_ftr_sec1(priv);
Kim Phillips9c4a7962008-06-23 19:50:15 +0800993 struct aead_request *areq = context;
Kim Phillips9c4a7962008-06-23 19:50:15 +0800994 struct crypto_aead *authenc = crypto_aead_reqtfm(areq);
Herbert Xuaeb4c132015-07-30 17:53:22 +0800995 unsigned int authsize = crypto_aead_authsize(authenc);
LEROY Christophe2e13ce02017-10-06 15:05:02 +0200996 unsigned int ivsize = crypto_aead_ivsize(authenc);
Kim Phillips19bbbc62009-03-29 15:53:59 +0800997 struct talitos_edesc *edesc;
Kim Phillips9c4a7962008-06-23 19:50:15 +0800998 struct scatterlist *sg;
999 void *icvdata;
1000
Kim Phillips19bbbc62009-03-29 15:53:59 +08001001 edesc = container_of(desc, struct talitos_edesc, desc);
1002
Kim Phillips9c4a7962008-06-23 19:50:15 +08001003 ipsec_esp_unmap(dev, edesc, areq);
1004
1005 /* copy the generated ICV to dst */
Herbert Xuaeb4c132015-07-30 17:53:22 +08001006 if (edesc->icv_ool) {
LEROY Christophe549bd8b2016-06-06 13:20:40 +02001007 if (is_sec1)
1008 icvdata = edesc->buf + areq->assoclen + areq->cryptlen;
1009 else
1010 icvdata = &edesc->link_tbl[edesc->src_nents +
1011 edesc->dst_nents + 2];
Kim Phillips9c4a7962008-06-23 19:50:15 +08001012 sg = sg_last(areq->dst, edesc->dst_nents);
Herbert Xuaeb4c132015-07-30 17:53:22 +08001013 memcpy((char *)sg_virt(sg) + sg->length - authsize,
1014 icvdata, authsize);
Kim Phillips9c4a7962008-06-23 19:50:15 +08001015 }
1016
LEROY Christophe2e13ce02017-10-06 15:05:02 +02001017 dma_unmap_single(dev, edesc->iv_dma, ivsize, DMA_TO_DEVICE);
1018
Kim Phillips9c4a7962008-06-23 19:50:15 +08001019 kfree(edesc);
1020
1021 aead_request_complete(areq, err);
1022}
1023
Kim Phillipsfe5720e2008-10-12 20:33:14 +08001024static void ipsec_esp_decrypt_swauth_done(struct device *dev,
Kim Phillipse938e462009-03-29 15:53:23 +08001025 struct talitos_desc *desc,
1026 void *context, int err)
Kim Phillips9c4a7962008-06-23 19:50:15 +08001027{
1028 struct aead_request *req = context;
Kim Phillips9c4a7962008-06-23 19:50:15 +08001029 struct crypto_aead *authenc = crypto_aead_reqtfm(req);
Herbert Xuaeb4c132015-07-30 17:53:22 +08001030 unsigned int authsize = crypto_aead_authsize(authenc);
Kim Phillips19bbbc62009-03-29 15:53:59 +08001031 struct talitos_edesc *edesc;
Kim Phillips9c4a7962008-06-23 19:50:15 +08001032 struct scatterlist *sg;
Herbert Xuaeb4c132015-07-30 17:53:22 +08001033 char *oicv, *icv;
LEROY Christophe549bd8b2016-06-06 13:20:40 +02001034 struct talitos_private *priv = dev_get_drvdata(dev);
1035 bool is_sec1 = has_ftr_sec1(priv);
Kim Phillips9c4a7962008-06-23 19:50:15 +08001036
Kim Phillips19bbbc62009-03-29 15:53:59 +08001037 edesc = container_of(desc, struct talitos_edesc, desc);
1038
Kim Phillips9c4a7962008-06-23 19:50:15 +08001039 ipsec_esp_unmap(dev, edesc, req);
1040
1041 if (!err) {
1042 /* auth check */
Kim Phillips9c4a7962008-06-23 19:50:15 +08001043 sg = sg_last(req->dst, edesc->dst_nents ? : 1);
Herbert Xuaeb4c132015-07-30 17:53:22 +08001044 icv = (char *)sg_virt(sg) + sg->length - authsize;
1045
1046 if (edesc->dma_len) {
LEROY Christophe549bd8b2016-06-06 13:20:40 +02001047 if (is_sec1)
1048 oicv = (char *)&edesc->dma_link_tbl +
1049 req->assoclen + req->cryptlen;
1050 else
1051 oicv = (char *)
1052 &edesc->link_tbl[edesc->src_nents +
Herbert Xuaeb4c132015-07-30 17:53:22 +08001053 edesc->dst_nents + 2];
1054 if (edesc->icv_ool)
1055 icv = oicv + authsize;
1056 } else
1057 oicv = (char *)&edesc->link_tbl[0];
1058
David Gstir79960942015-11-15 17:14:42 +01001059 err = crypto_memneq(oicv, icv, authsize) ? -EBADMSG : 0;
Kim Phillips9c4a7962008-06-23 19:50:15 +08001060 }
1061
1062 kfree(edesc);
1063
1064 aead_request_complete(req, err);
1065}
1066
Kim Phillipsfe5720e2008-10-12 20:33:14 +08001067static void ipsec_esp_decrypt_hwauth_done(struct device *dev,
Kim Phillipse938e462009-03-29 15:53:23 +08001068 struct talitos_desc *desc,
1069 void *context, int err)
Kim Phillipsfe5720e2008-10-12 20:33:14 +08001070{
1071 struct aead_request *req = context;
Kim Phillips19bbbc62009-03-29 15:53:59 +08001072 struct talitos_edesc *edesc;
1073
1074 edesc = container_of(desc, struct talitos_edesc, desc);
Kim Phillipsfe5720e2008-10-12 20:33:14 +08001075
1076 ipsec_esp_unmap(dev, edesc, req);
1077
1078 /* check ICV auth status */
Kim Phillipse938e462009-03-29 15:53:23 +08001079 if (!err && ((desc->hdr_lo & DESC_HDR_LO_ICCR1_MASK) !=
1080 DESC_HDR_LO_ICCR1_PASS))
1081 err = -EBADMSG;
Kim Phillipsfe5720e2008-10-12 20:33:14 +08001082
1083 kfree(edesc);
1084
1085 aead_request_complete(req, err);
1086}
1087
Kim Phillips9c4a7962008-06-23 19:50:15 +08001088/*
1089 * convert scatterlist to SEC h/w link table format
1090 * stop at cryptlen bytes
1091 */
Herbert Xuaeb4c132015-07-30 17:53:22 +08001092static int sg_to_link_tbl_offset(struct scatterlist *sg, int sg_count,
1093 unsigned int offset, int cryptlen,
1094 struct talitos_ptr *link_tbl_ptr)
Kim Phillips9c4a7962008-06-23 19:50:15 +08001095{
Lee Nipper70bcaca2008-07-03 19:08:46 +08001096 int n_sg = sg_count;
Herbert Xuaeb4c132015-07-30 17:53:22 +08001097 int count = 0;
Lee Nipper70bcaca2008-07-03 19:08:46 +08001098
Herbert Xuaeb4c132015-07-30 17:53:22 +08001099 while (cryptlen && sg && n_sg--) {
1100 unsigned int len = sg_dma_len(sg);
1101
1102 if (offset >= len) {
1103 offset -= len;
1104 goto next;
1105 }
1106
1107 len -= offset;
1108
1109 if (len > cryptlen)
1110 len = cryptlen;
1111
1112 to_talitos_ptr(link_tbl_ptr + count,
LEROY Christopheda9de142017-10-06 15:04:57 +02001113 sg_dma_address(sg) + offset, len, 0);
LEROY Christopheb096b542016-06-06 13:20:34 +02001114 to_talitos_ptr_ext_set(link_tbl_ptr + count, 0, 0);
Herbert Xuaeb4c132015-07-30 17:53:22 +08001115 count++;
1116 cryptlen -= len;
1117 offset = 0;
1118
1119next:
Cristian Stoica5be4d4c2015-01-20 10:06:16 +02001120 sg = sg_next(sg);
Kim Phillips9c4a7962008-06-23 19:50:15 +08001121 }
1122
Kim Phillips9c4a7962008-06-23 19:50:15 +08001123 /* tag end of link table */
Herbert Xuaeb4c132015-07-30 17:53:22 +08001124 if (count > 0)
LEROY Christopheb096b542016-06-06 13:20:34 +02001125 to_talitos_ptr_ext_set(link_tbl_ptr + count - 1,
1126 DESC_PTR_LNKTBL_RETURN, 0);
Lee Nipper70bcaca2008-07-03 19:08:46 +08001127
Herbert Xuaeb4c132015-07-30 17:53:22 +08001128 return count;
1129}
1130
LEROY Christophe5b2cf262017-10-06 15:04:47 +02001131static int talitos_sg_map(struct device *dev, struct scatterlist *src,
LEROY Christophe6a1e8d12016-06-06 13:20:38 +02001132 unsigned int len, struct talitos_edesc *edesc,
1133 struct talitos_ptr *ptr,
1134 int sg_count, unsigned int offset, int tbl_off)
LEROY Christophe246a87c2016-06-06 13:20:36 +02001135{
LEROY Christophe246a87c2016-06-06 13:20:36 +02001136 struct talitos_private *priv = dev_get_drvdata(dev);
1137 bool is_sec1 = has_ftr_sec1(priv);
1138
LEROY Christophe87a81dc2018-01-26 17:09:59 +01001139 if (!src) {
1140 to_talitos_ptr(ptr, 0, 0, is_sec1);
1141 return 1;
1142 }
LEROY Christophe6a1e8d12016-06-06 13:20:38 +02001143 if (sg_count == 1) {
LEROY Christopheda9de142017-10-06 15:04:57 +02001144 to_talitos_ptr(ptr, sg_dma_address(src) + offset, len, is_sec1);
LEROY Christophe6a1e8d12016-06-06 13:20:38 +02001145 return sg_count;
LEROY Christophe246a87c2016-06-06 13:20:36 +02001146 }
LEROY Christophe6a1e8d12016-06-06 13:20:38 +02001147 if (is_sec1) {
LEROY Christopheda9de142017-10-06 15:04:57 +02001148 to_talitos_ptr(ptr, edesc->dma_link_tbl + offset, len, is_sec1);
LEROY Christophe6a1e8d12016-06-06 13:20:38 +02001149 return sg_count;
1150 }
1151 sg_count = sg_to_link_tbl_offset(src, sg_count, offset, len,
1152 &edesc->link_tbl[tbl_off]);
1153 if (sg_count == 1) {
1154 /* Only one segment now, so no link tbl needed*/
1155 copy_talitos_ptr(ptr, &edesc->link_tbl[tbl_off], is_sec1);
1156 return sg_count;
1157 }
1158 to_talitos_ptr(ptr, edesc->dma_link_tbl +
LEROY Christopheda9de142017-10-06 15:04:57 +02001159 tbl_off * sizeof(struct talitos_ptr), len, is_sec1);
LEROY Christophe6a1e8d12016-06-06 13:20:38 +02001160 to_talitos_ptr_ext_or(ptr, DESC_PTR_LNKTBL_JUMP, is_sec1);
1161
LEROY Christophe246a87c2016-06-06 13:20:36 +02001162 return sg_count;
1163}
1164
Kim Phillips9c4a7962008-06-23 19:50:15 +08001165/*
1166 * fill in and submit ipsec_esp descriptor
1167 */
Lee Nipper56af8cd2009-03-29 15:50:50 +08001168static int ipsec_esp(struct talitos_edesc *edesc, struct aead_request *areq,
Herbert Xuaeb4c132015-07-30 17:53:22 +08001169 void (*callback)(struct device *dev,
1170 struct talitos_desc *desc,
1171 void *context, int error))
Kim Phillips9c4a7962008-06-23 19:50:15 +08001172{
1173 struct crypto_aead *aead = crypto_aead_reqtfm(areq);
Herbert Xuaeb4c132015-07-30 17:53:22 +08001174 unsigned int authsize = crypto_aead_authsize(aead);
Kim Phillips9c4a7962008-06-23 19:50:15 +08001175 struct talitos_ctx *ctx = crypto_aead_ctx(aead);
1176 struct device *dev = ctx->dev;
1177 struct talitos_desc *desc = &edesc->desc;
1178 unsigned int cryptlen = areq->cryptlen;
Kim Phillipse41256f2009-08-13 11:49:06 +10001179 unsigned int ivsize = crypto_aead_ivsize(aead);
Herbert Xuaeb4c132015-07-30 17:53:22 +08001180 int tbl_off = 0;
Kim Phillipsfa86a262008-07-17 20:20:06 +08001181 int sg_count, ret;
Kim Phillipsfe5720e2008-10-12 20:33:14 +08001182 int sg_link_tbl_len;
LEROY Christophe549bd8b2016-06-06 13:20:40 +02001183 bool sync_needed = false;
1184 struct talitos_private *priv = dev_get_drvdata(dev);
1185 bool is_sec1 = has_ftr_sec1(priv);
LEROY Christophe9a655602017-10-06 15:04:59 +02001186 bool is_ipsec_esp = desc->hdr & DESC_HDR_TYPE_IPSEC_ESP;
1187 struct talitos_ptr *civ_ptr = &desc->ptr[is_ipsec_esp ? 2 : 3];
1188 struct talitos_ptr *ckey_ptr = &desc->ptr[is_ipsec_esp ? 3 : 2];
Kim Phillips9c4a7962008-06-23 19:50:15 +08001189
1190 /* hmac key */
LEROY Christophe2e13ce02017-10-06 15:05:02 +02001191 to_talitos_ptr(&desc->ptr[0], ctx->dma_key, ctx->authkeylen, is_sec1);
Horia Geanta79fd31d2012-08-02 17:16:40 +03001192
LEROY Christophe549bd8b2016-06-06 13:20:40 +02001193 sg_count = edesc->src_nents ?: 1;
1194 if (is_sec1 && sg_count > 1)
1195 sg_copy_to_buffer(areq->src, sg_count, edesc->buf,
1196 areq->assoclen + cryptlen);
1197 else
1198 sg_count = dma_map_sg(dev, areq->src, sg_count,
1199 (areq->src == areq->dst) ?
1200 DMA_BIDIRECTIONAL : DMA_TO_DEVICE);
1201
Kim Phillips9c4a7962008-06-23 19:50:15 +08001202 /* hmac data */
LEROY Christophe549bd8b2016-06-06 13:20:40 +02001203 ret = talitos_sg_map(dev, areq->src, areq->assoclen, edesc,
1204 &desc->ptr[1], sg_count, 0, tbl_off);
Horia Geanta79fd31d2012-08-02 17:16:40 +03001205
LEROY Christophe549bd8b2016-06-06 13:20:40 +02001206 if (ret > 1) {
Horia Geant?340ff602016-04-19 20:33:48 +03001207 tbl_off += ret;
LEROY Christophe549bd8b2016-06-06 13:20:40 +02001208 sync_needed = true;
Horia Geanta79fd31d2012-08-02 17:16:40 +03001209 }
1210
Kim Phillips9c4a7962008-06-23 19:50:15 +08001211 /* cipher iv */
LEROY Christophe9a655602017-10-06 15:04:59 +02001212 to_talitos_ptr(civ_ptr, edesc->iv_dma, ivsize, is_sec1);
Kim Phillips9c4a7962008-06-23 19:50:15 +08001213
1214 /* cipher key */
LEROY Christophe2e13ce02017-10-06 15:05:02 +02001215 to_talitos_ptr(ckey_ptr, ctx->dma_key + ctx->authkeylen,
1216 ctx->enckeylen, is_sec1);
Kim Phillips9c4a7962008-06-23 19:50:15 +08001217
1218 /*
1219 * cipher in
1220 * map and adjust cipher len to aead request cryptlen.
1221 * extent is bytes of HMAC postpended to ciphertext,
1222 * typically 12 for ipsec
1223 */
Herbert Xuaeb4c132015-07-30 17:53:22 +08001224 sg_link_tbl_len = cryptlen;
Kim Phillips9c4a7962008-06-23 19:50:15 +08001225
LEROY Christophe9a655602017-10-06 15:04:59 +02001226 if (is_ipsec_esp) {
LEROY Christophe549bd8b2016-06-06 13:20:40 +02001227 to_talitos_ptr_ext_set(&desc->ptr[4], authsize, is_sec1);
1228
LEROY Christophe9a655602017-10-06 15:04:59 +02001229 if (desc->hdr & DESC_HDR_MODE1_MDEU_CICV)
LEROY Christophe549bd8b2016-06-06 13:20:40 +02001230 sg_link_tbl_len += authsize;
1231 }
1232
LEROY Christophefbb22132017-10-06 15:04:41 +02001233 ret = talitos_sg_map(dev, areq->src, sg_link_tbl_len, edesc,
1234 &desc->ptr[4], sg_count, areq->assoclen, tbl_off);
LEROY Christophe549bd8b2016-06-06 13:20:40 +02001235
LEROY Christopheec8c7d12017-10-06 15:04:33 +02001236 if (ret > 1) {
1237 tbl_off += ret;
LEROY Christophe549bd8b2016-06-06 13:20:40 +02001238 sync_needed = true;
Horia Geant?340ff602016-04-19 20:33:48 +03001239 }
Kim Phillips9c4a7962008-06-23 19:50:15 +08001240
1241 /* cipher out */
LEROY Christophe549bd8b2016-06-06 13:20:40 +02001242 if (areq->src != areq->dst) {
1243 sg_count = edesc->dst_nents ? : 1;
1244 if (!is_sec1 || sg_count == 1)
1245 dma_map_sg(dev, areq->dst, sg_count, DMA_FROM_DEVICE);
1246 }
Kim Phillips9c4a7962008-06-23 19:50:15 +08001247
LEROY Christophee04a61b2017-10-06 15:04:35 +02001248 ret = talitos_sg_map(dev, areq->dst, cryptlen, edesc, &desc->ptr[5],
1249 sg_count, areq->assoclen, tbl_off);
Kim Phillips9c4a7962008-06-23 19:50:15 +08001250
LEROY Christophe9a655602017-10-06 15:04:59 +02001251 if (is_ipsec_esp)
LEROY Christophe549bd8b2016-06-06 13:20:40 +02001252 to_talitos_ptr_ext_or(&desc->ptr[5], authsize, is_sec1);
Herbert Xuaeb4c132015-07-30 17:53:22 +08001253
LEROY Christophee04a61b2017-10-06 15:04:35 +02001254 /* ICV data */
1255 if (ret > 1) {
1256 tbl_off += ret;
Herbert Xuaeb4c132015-07-30 17:53:22 +08001257 edesc->icv_ool = true;
LEROY Christophe549bd8b2016-06-06 13:20:40 +02001258 sync_needed = true;
1259
LEROY Christophe9a655602017-10-06 15:04:59 +02001260 if (is_ipsec_esp) {
LEROY Christophe549bd8b2016-06-06 13:20:40 +02001261 struct talitos_ptr *tbl_ptr = &edesc->link_tbl[tbl_off];
1262 int offset = (edesc->src_nents + edesc->dst_nents + 2) *
1263 sizeof(struct talitos_ptr) + authsize;
1264
1265 /* Add an entry to the link table for ICV data */
LEROY Christophee04a61b2017-10-06 15:04:35 +02001266 to_talitos_ptr_ext_set(tbl_ptr - 1, 0, is_sec1);
LEROY Christophe549bd8b2016-06-06 13:20:40 +02001267 to_talitos_ptr_ext_set(tbl_ptr, DESC_PTR_LNKTBL_RETURN,
1268 is_sec1);
LEROY Christophe549bd8b2016-06-06 13:20:40 +02001269
1270 /* icv data follows link tables */
1271 to_talitos_ptr(tbl_ptr, edesc->dma_link_tbl + offset,
LEROY Christopheda9de142017-10-06 15:04:57 +02001272 authsize, is_sec1);
LEROY Christophee04a61b2017-10-06 15:04:35 +02001273 } else {
1274 dma_addr_t addr = edesc->dma_link_tbl;
1275
1276 if (is_sec1)
1277 addr += areq->assoclen + cryptlen;
1278 else
1279 addr += sizeof(struct talitos_ptr) * tbl_off;
1280
LEROY Christopheda9de142017-10-06 15:04:57 +02001281 to_talitos_ptr(&desc->ptr[6], addr, authsize, is_sec1);
LEROY Christophee04a61b2017-10-06 15:04:35 +02001282 }
LEROY Christophe9a655602017-10-06 15:04:59 +02001283 } else if (!is_ipsec_esp) {
LEROY Christophee04a61b2017-10-06 15:04:35 +02001284 ret = talitos_sg_map(dev, areq->dst, authsize, edesc,
1285 &desc->ptr[6], sg_count, areq->assoclen +
1286 cryptlen,
1287 tbl_off);
1288 if (ret > 1) {
1289 tbl_off += ret;
1290 edesc->icv_ool = true;
1291 sync_needed = true;
1292 } else {
1293 edesc->icv_ool = false;
LEROY Christophe549bd8b2016-06-06 13:20:40 +02001294 }
Horia Geant?340ff602016-04-19 20:33:48 +03001295 } else {
LEROY Christophe549bd8b2016-06-06 13:20:40 +02001296 edesc->icv_ool = false;
1297 }
1298
Kim Phillips9c4a7962008-06-23 19:50:15 +08001299 /* iv out */
LEROY Christophe9a655602017-10-06 15:04:59 +02001300 if (is_ipsec_esp)
LEROY Christophe549bd8b2016-06-06 13:20:40 +02001301 map_single_talitos_ptr(dev, &desc->ptr[6], ivsize, ctx->iv,
1302 DMA_FROM_DEVICE);
1303
1304 if (sync_needed)
1305 dma_sync_single_for_device(dev, edesc->dma_link_tbl,
1306 edesc->dma_len,
1307 DMA_BIDIRECTIONAL);
Kim Phillips9c4a7962008-06-23 19:50:15 +08001308
Kim Phillips5228f0f2011-07-15 11:21:38 +08001309 ret = talitos_submit(dev, ctx->ch, desc, callback, areq);
Kim Phillipsfa86a262008-07-17 20:20:06 +08001310 if (ret != -EINPROGRESS) {
1311 ipsec_esp_unmap(dev, edesc, areq);
1312 kfree(edesc);
1313 }
1314 return ret;
Kim Phillips9c4a7962008-06-23 19:50:15 +08001315}
1316
Kim Phillips9c4a7962008-06-23 19:50:15 +08001317/*
Lee Nipper56af8cd2009-03-29 15:50:50 +08001318 * allocate and map the extended descriptor
Kim Phillips9c4a7962008-06-23 19:50:15 +08001319 */
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001320static struct talitos_edesc *talitos_edesc_alloc(struct device *dev,
1321 struct scatterlist *src,
1322 struct scatterlist *dst,
Horia Geanta79fd31d2012-08-02 17:16:40 +03001323 u8 *iv,
1324 unsigned int assoclen,
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001325 unsigned int cryptlen,
1326 unsigned int authsize,
Horia Geanta79fd31d2012-08-02 17:16:40 +03001327 unsigned int ivsize,
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001328 int icv_stashing,
Horia Geanta62293a32013-11-28 15:11:17 +02001329 u32 cryptoflags,
1330 bool encrypt)
Kim Phillips9c4a7962008-06-23 19:50:15 +08001331{
Lee Nipper56af8cd2009-03-29 15:50:50 +08001332 struct talitos_edesc *edesc;
LEROY Christophe6a1e8d12016-06-06 13:20:38 +02001333 int src_nents, dst_nents, alloc_len, dma_len, src_len, dst_len;
Horia Geanta79fd31d2012-08-02 17:16:40 +03001334 dma_addr_t iv_dma = 0;
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001335 gfp_t flags = cryptoflags & CRYPTO_TFM_REQ_MAY_SLEEP ? GFP_KERNEL :
Kim Phillips586725f2008-07-17 20:19:18 +08001336 GFP_ATOMIC;
LEROY Christophe6f65f6a2015-04-17 16:32:15 +02001337 struct talitos_private *priv = dev_get_drvdata(dev);
1338 bool is_sec1 = has_ftr_sec1(priv);
1339 int max_len = is_sec1 ? TALITOS1_MAX_DATA_LEN : TALITOS2_MAX_DATA_LEN;
LABBE Corentin8e409fe2015-11-04 21:13:34 +01001340 void *err;
Kim Phillips9c4a7962008-06-23 19:50:15 +08001341
LEROY Christophe6f65f6a2015-04-17 16:32:15 +02001342 if (cryptlen + authsize > max_len) {
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001343 dev_err(dev, "length exceeds h/w max limit\n");
Kim Phillips9c4a7962008-06-23 19:50:15 +08001344 return ERR_PTR(-EINVAL);
1345 }
1346
Horia Geanta935e99a2013-11-19 14:57:49 +02001347 if (ivsize)
Horia Geanta79fd31d2012-08-02 17:16:40 +03001348 iv_dma = dma_map_single(dev, iv, ivsize, DMA_TO_DEVICE);
1349
Horia Geanta62293a32013-11-28 15:11:17 +02001350 if (!dst || dst == src) {
LEROY Christophe6a1e8d12016-06-06 13:20:38 +02001351 src_len = assoclen + cryptlen + authsize;
1352 src_nents = sg_nents_for_len(src, src_len);
LABBE Corentin8e409fe2015-11-04 21:13:34 +01001353 if (src_nents < 0) {
1354 dev_err(dev, "Invalid number of src SG.\n");
1355 err = ERR_PTR(-EINVAL);
1356 goto error_sg;
1357 }
Horia Geanta62293a32013-11-28 15:11:17 +02001358 src_nents = (src_nents == 1) ? 0 : src_nents;
1359 dst_nents = dst ? src_nents : 0;
LEROY Christophe6a1e8d12016-06-06 13:20:38 +02001360 dst_len = 0;
Horia Geanta62293a32013-11-28 15:11:17 +02001361 } else { /* dst && dst != src*/
LEROY Christophe6a1e8d12016-06-06 13:20:38 +02001362 src_len = assoclen + cryptlen + (encrypt ? 0 : authsize);
1363 src_nents = sg_nents_for_len(src, src_len);
LABBE Corentin8e409fe2015-11-04 21:13:34 +01001364 if (src_nents < 0) {
1365 dev_err(dev, "Invalid number of src SG.\n");
1366 err = ERR_PTR(-EINVAL);
1367 goto error_sg;
1368 }
Horia Geanta62293a32013-11-28 15:11:17 +02001369 src_nents = (src_nents == 1) ? 0 : src_nents;
LEROY Christophe6a1e8d12016-06-06 13:20:38 +02001370 dst_len = assoclen + cryptlen + (encrypt ? authsize : 0);
1371 dst_nents = sg_nents_for_len(dst, dst_len);
LABBE Corentin8e409fe2015-11-04 21:13:34 +01001372 if (dst_nents < 0) {
1373 dev_err(dev, "Invalid number of dst SG.\n");
1374 err = ERR_PTR(-EINVAL);
1375 goto error_sg;
1376 }
Horia Geanta62293a32013-11-28 15:11:17 +02001377 dst_nents = (dst_nents == 1) ? 0 : dst_nents;
Kim Phillips9c4a7962008-06-23 19:50:15 +08001378 }
1379
1380 /*
1381 * allocate space for base edesc plus the link tables,
Herbert Xuaeb4c132015-07-30 17:53:22 +08001382 * allowing for two separate entries for AD and generated ICV (+ 2),
1383 * and space for two sets of ICVs (stashed and generated)
Kim Phillips9c4a7962008-06-23 19:50:15 +08001384 */
Lee Nipper56af8cd2009-03-29 15:50:50 +08001385 alloc_len = sizeof(struct talitos_edesc);
Herbert Xuaeb4c132015-07-30 17:53:22 +08001386 if (src_nents || dst_nents) {
LEROY Christophe6f65f6a2015-04-17 16:32:15 +02001387 if (is_sec1)
LEROY Christophe6a1e8d12016-06-06 13:20:38 +02001388 dma_len = (src_nents ? src_len : 0) +
1389 (dst_nents ? dst_len : 0);
LEROY Christophe6f65f6a2015-04-17 16:32:15 +02001390 else
Herbert Xuaeb4c132015-07-30 17:53:22 +08001391 dma_len = (src_nents + dst_nents + 2) *
1392 sizeof(struct talitos_ptr) + authsize * 2;
Kim Phillips9c4a7962008-06-23 19:50:15 +08001393 alloc_len += dma_len;
1394 } else {
1395 dma_len = 0;
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001396 alloc_len += icv_stashing ? authsize : 0;
Kim Phillips9c4a7962008-06-23 19:50:15 +08001397 }
1398
LEROY Christophe37b5e882017-10-06 15:05:06 +02001399 /* if its a ahash, add space for a second desc next to the first one */
1400 if (is_sec1 && !dst)
1401 alloc_len += sizeof(struct talitos_desc);
1402
Kim Phillips586725f2008-07-17 20:19:18 +08001403 edesc = kmalloc(alloc_len, GFP_DMA | flags);
Kim Phillips9c4a7962008-06-23 19:50:15 +08001404 if (!edesc) {
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001405 dev_err(dev, "could not allocate edescriptor\n");
LABBE Corentin8e409fe2015-11-04 21:13:34 +01001406 err = ERR_PTR(-ENOMEM);
1407 goto error_sg;
Kim Phillips9c4a7962008-06-23 19:50:15 +08001408 }
LEROY Christophee4a647c2017-10-06 15:04:45 +02001409 memset(&edesc->desc, 0, sizeof(edesc->desc));
Kim Phillips9c4a7962008-06-23 19:50:15 +08001410
1411 edesc->src_nents = src_nents;
1412 edesc->dst_nents = dst_nents;
Horia Geanta79fd31d2012-08-02 17:16:40 +03001413 edesc->iv_dma = iv_dma;
Kim Phillips9c4a7962008-06-23 19:50:15 +08001414 edesc->dma_len = dma_len;
LEROY Christophe37b5e882017-10-06 15:05:06 +02001415 if (dma_len) {
1416 void *addr = &edesc->link_tbl[0];
1417
1418 if (is_sec1 && !dst)
1419 addr += sizeof(struct talitos_desc);
1420 edesc->dma_link_tbl = dma_map_single(dev, addr,
Lee Nipper497f2e62010-05-19 19:20:36 +10001421 edesc->dma_len,
1422 DMA_BIDIRECTIONAL);
LEROY Christophe37b5e882017-10-06 15:05:06 +02001423 }
Kim Phillips9c4a7962008-06-23 19:50:15 +08001424 return edesc;
LABBE Corentin8e409fe2015-11-04 21:13:34 +01001425error_sg:
1426 if (iv_dma)
1427 dma_unmap_single(dev, iv_dma, ivsize, DMA_TO_DEVICE);
1428 return err;
Kim Phillips9c4a7962008-06-23 19:50:15 +08001429}
1430
Horia Geanta79fd31d2012-08-02 17:16:40 +03001431static struct talitos_edesc *aead_edesc_alloc(struct aead_request *areq, u8 *iv,
Horia Geanta62293a32013-11-28 15:11:17 +02001432 int icv_stashing, bool encrypt)
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001433{
1434 struct crypto_aead *authenc = crypto_aead_reqtfm(areq);
Herbert Xuaeb4c132015-07-30 17:53:22 +08001435 unsigned int authsize = crypto_aead_authsize(authenc);
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001436 struct talitos_ctx *ctx = crypto_aead_ctx(authenc);
Horia Geanta79fd31d2012-08-02 17:16:40 +03001437 unsigned int ivsize = crypto_aead_ivsize(authenc);
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001438
Herbert Xuaeb4c132015-07-30 17:53:22 +08001439 return talitos_edesc_alloc(ctx->dev, areq->src, areq->dst,
Horia Geanta79fd31d2012-08-02 17:16:40 +03001440 iv, areq->assoclen, areq->cryptlen,
Herbert Xuaeb4c132015-07-30 17:53:22 +08001441 authsize, ivsize, icv_stashing,
Horia Geanta62293a32013-11-28 15:11:17 +02001442 areq->base.flags, encrypt);
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001443}
1444
Lee Nipper56af8cd2009-03-29 15:50:50 +08001445static int aead_encrypt(struct aead_request *req)
Kim Phillips9c4a7962008-06-23 19:50:15 +08001446{
1447 struct crypto_aead *authenc = crypto_aead_reqtfm(req);
1448 struct talitos_ctx *ctx = crypto_aead_ctx(authenc);
Lee Nipper56af8cd2009-03-29 15:50:50 +08001449 struct talitos_edesc *edesc;
Kim Phillips9c4a7962008-06-23 19:50:15 +08001450
1451 /* allocate extended descriptor */
Horia Geanta62293a32013-11-28 15:11:17 +02001452 edesc = aead_edesc_alloc(req, req->iv, 0, true);
Kim Phillips9c4a7962008-06-23 19:50:15 +08001453 if (IS_ERR(edesc))
1454 return PTR_ERR(edesc);
1455
1456 /* set encrypt */
Lee Nipper70bcaca2008-07-03 19:08:46 +08001457 edesc->desc.hdr = ctx->desc_hdr_template | DESC_HDR_MODE0_ENCRYPT;
Kim Phillips9c4a7962008-06-23 19:50:15 +08001458
Herbert Xuaeb4c132015-07-30 17:53:22 +08001459 return ipsec_esp(edesc, req, ipsec_esp_encrypt_done);
Kim Phillips9c4a7962008-06-23 19:50:15 +08001460}
1461
Lee Nipper56af8cd2009-03-29 15:50:50 +08001462static int aead_decrypt(struct aead_request *req)
Kim Phillips9c4a7962008-06-23 19:50:15 +08001463{
1464 struct crypto_aead *authenc = crypto_aead_reqtfm(req);
Herbert Xuaeb4c132015-07-30 17:53:22 +08001465 unsigned int authsize = crypto_aead_authsize(authenc);
Kim Phillips9c4a7962008-06-23 19:50:15 +08001466 struct talitos_ctx *ctx = crypto_aead_ctx(authenc);
Kim Phillipsfe5720e2008-10-12 20:33:14 +08001467 struct talitos_private *priv = dev_get_drvdata(ctx->dev);
Lee Nipper56af8cd2009-03-29 15:50:50 +08001468 struct talitos_edesc *edesc;
Kim Phillips9c4a7962008-06-23 19:50:15 +08001469 struct scatterlist *sg;
1470 void *icvdata;
1471
1472 req->cryptlen -= authsize;
1473
1474 /* allocate extended descriptor */
Horia Geanta62293a32013-11-28 15:11:17 +02001475 edesc = aead_edesc_alloc(req, req->iv, 1, false);
Kim Phillips9c4a7962008-06-23 19:50:15 +08001476 if (IS_ERR(edesc))
1477 return PTR_ERR(edesc);
1478
Kim Phillipsfe5720e2008-10-12 20:33:14 +08001479 if ((priv->features & TALITOS_FTR_HW_AUTH_CHECK) &&
Kim Phillipse938e462009-03-29 15:53:23 +08001480 ((!edesc->src_nents && !edesc->dst_nents) ||
1481 priv->features & TALITOS_FTR_SRC_LINK_TBL_LEN_INCLUDES_EXTENT)) {
Kim Phillips9c4a7962008-06-23 19:50:15 +08001482
Kim Phillipsfe5720e2008-10-12 20:33:14 +08001483 /* decrypt and check the ICV */
Kim Phillipse938e462009-03-29 15:53:23 +08001484 edesc->desc.hdr = ctx->desc_hdr_template |
1485 DESC_HDR_DIR_INBOUND |
Kim Phillipsfe5720e2008-10-12 20:33:14 +08001486 DESC_HDR_MODE1_MDEU_CICV;
Kim Phillips9c4a7962008-06-23 19:50:15 +08001487
Kim Phillipsfe5720e2008-10-12 20:33:14 +08001488 /* reset integrity check result bits */
Kim Phillips9c4a7962008-06-23 19:50:15 +08001489
Herbert Xuaeb4c132015-07-30 17:53:22 +08001490 return ipsec_esp(edesc, req, ipsec_esp_decrypt_hwauth_done);
Kim Phillipsfe5720e2008-10-12 20:33:14 +08001491 }
Kim Phillipse938e462009-03-29 15:53:23 +08001492
1493 /* Have to check the ICV with software */
1494 edesc->desc.hdr = ctx->desc_hdr_template | DESC_HDR_DIR_INBOUND;
1495
1496 /* stash incoming ICV for later cmp with ICV generated by the h/w */
1497 if (edesc->dma_len)
Herbert Xuaeb4c132015-07-30 17:53:22 +08001498 icvdata = (char *)&edesc->link_tbl[edesc->src_nents +
1499 edesc->dst_nents + 2];
Kim Phillipse938e462009-03-29 15:53:23 +08001500 else
1501 icvdata = &edesc->link_tbl[0];
1502
1503 sg = sg_last(req->src, edesc->src_nents ? : 1);
1504
Herbert Xuaeb4c132015-07-30 17:53:22 +08001505 memcpy(icvdata, (char *)sg_virt(sg) + sg->length - authsize, authsize);
Kim Phillipse938e462009-03-29 15:53:23 +08001506
Herbert Xuaeb4c132015-07-30 17:53:22 +08001507 return ipsec_esp(edesc, req, ipsec_esp_decrypt_swauth_done);
Kim Phillips9c4a7962008-06-23 19:50:15 +08001508}
1509
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001510static int ablkcipher_setkey(struct crypto_ablkcipher *cipher,
1511 const u8 *key, unsigned int keylen)
1512{
1513 struct talitos_ctx *ctx = crypto_ablkcipher_ctx(cipher);
LEROY Christophe2e13ce02017-10-06 15:05:02 +02001514 struct device *dev = ctx->dev;
LEROY Christophef384cdc2017-10-06 15:04:37 +02001515 u32 tmp[DES_EXPKEY_WORDS];
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001516
Martin Hicks03d2c512017-05-02 09:38:35 -04001517 if (keylen > TALITOS_MAX_KEY_SIZE) {
1518 crypto_ablkcipher_set_flags(cipher, CRYPTO_TFM_RES_BAD_KEY_LEN);
1519 return -EINVAL;
1520 }
1521
LEROY Christophef384cdc2017-10-06 15:04:37 +02001522 if (unlikely(crypto_ablkcipher_get_flags(cipher) &
1523 CRYPTO_TFM_REQ_WEAK_KEY) &&
1524 !des_ekey(tmp, key)) {
1525 crypto_ablkcipher_set_flags(cipher, CRYPTO_TFM_RES_WEAK_KEY);
1526 return -EINVAL;
1527 }
1528
LEROY Christophe2e13ce02017-10-06 15:05:02 +02001529 if (ctx->keylen)
1530 dma_unmap_single(dev, ctx->dma_key, ctx->keylen, DMA_TO_DEVICE);
1531
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001532 memcpy(&ctx->key, key, keylen);
1533 ctx->keylen = keylen;
1534
LEROY Christophe2e13ce02017-10-06 15:05:02 +02001535 ctx->dma_key = dma_map_single(dev, ctx->key, keylen, DMA_TO_DEVICE);
1536
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001537 return 0;
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001538}
1539
1540static void common_nonsnoop_unmap(struct device *dev,
1541 struct talitos_edesc *edesc,
1542 struct ablkcipher_request *areq)
1543{
1544 unmap_single_talitos_ptr(dev, &edesc->desc.ptr[5], DMA_FROM_DEVICE);
LEROY Christophe032d1972015-04-17 16:31:51 +02001545
LEROY Christophe6a1e8d12016-06-06 13:20:38 +02001546 talitos_sg_unmap(dev, edesc, areq->src, areq->dst, areq->nbytes, 0);
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001547 unmap_single_talitos_ptr(dev, &edesc->desc.ptr[1], DMA_TO_DEVICE);
1548
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001549 if (edesc->dma_len)
1550 dma_unmap_single(dev, edesc->dma_link_tbl, edesc->dma_len,
1551 DMA_BIDIRECTIONAL);
1552}
1553
1554static void ablkcipher_done(struct device *dev,
1555 struct talitos_desc *desc, void *context,
1556 int err)
1557{
1558 struct ablkcipher_request *areq = context;
Kim Phillips19bbbc62009-03-29 15:53:59 +08001559 struct talitos_edesc *edesc;
1560
1561 edesc = container_of(desc, struct talitos_edesc, desc);
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001562
1563 common_nonsnoop_unmap(dev, edesc, areq);
1564
1565 kfree(edesc);
1566
1567 areq->base.complete(&areq->base, err);
1568}
1569
1570static int common_nonsnoop(struct talitos_edesc *edesc,
1571 struct ablkcipher_request *areq,
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001572 void (*callback) (struct device *dev,
1573 struct talitos_desc *desc,
1574 void *context, int error))
1575{
1576 struct crypto_ablkcipher *cipher = crypto_ablkcipher_reqtfm(areq);
1577 struct talitos_ctx *ctx = crypto_ablkcipher_ctx(cipher);
1578 struct device *dev = ctx->dev;
1579 struct talitos_desc *desc = &edesc->desc;
1580 unsigned int cryptlen = areq->nbytes;
Horia Geanta79fd31d2012-08-02 17:16:40 +03001581 unsigned int ivsize = crypto_ablkcipher_ivsize(cipher);
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001582 int sg_count, ret;
LEROY Christophe6a1e8d12016-06-06 13:20:38 +02001583 bool sync_needed = false;
LEROY Christophe922f9dc2015-04-17 16:32:07 +02001584 struct talitos_private *priv = dev_get_drvdata(dev);
1585 bool is_sec1 = has_ftr_sec1(priv);
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001586
1587 /* first DWORD empty */
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001588
1589 /* cipher iv */
LEROY Christopheda9de142017-10-06 15:04:57 +02001590 to_talitos_ptr(&desc->ptr[1], edesc->iv_dma, ivsize, is_sec1);
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001591
1592 /* cipher key */
LEROY Christophe2e13ce02017-10-06 15:05:02 +02001593 to_talitos_ptr(&desc->ptr[2], ctx->dma_key, ctx->keylen, is_sec1);
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001594
LEROY Christophe6a1e8d12016-06-06 13:20:38 +02001595 sg_count = edesc->src_nents ?: 1;
1596 if (is_sec1 && sg_count > 1)
1597 sg_copy_to_buffer(areq->src, sg_count, edesc->buf,
1598 cryptlen);
1599 else
1600 sg_count = dma_map_sg(dev, areq->src, sg_count,
1601 (areq->src == areq->dst) ?
1602 DMA_BIDIRECTIONAL : DMA_TO_DEVICE);
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001603 /*
1604 * cipher in
1605 */
LEROY Christophe6a1e8d12016-06-06 13:20:38 +02001606 sg_count = talitos_sg_map(dev, areq->src, cryptlen, edesc,
1607 &desc->ptr[3], sg_count, 0, 0);
1608 if (sg_count > 1)
1609 sync_needed = true;
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001610
1611 /* cipher out */
LEROY Christophe6a1e8d12016-06-06 13:20:38 +02001612 if (areq->src != areq->dst) {
1613 sg_count = edesc->dst_nents ? : 1;
1614 if (!is_sec1 || sg_count == 1)
1615 dma_map_sg(dev, areq->dst, sg_count, DMA_FROM_DEVICE);
1616 }
1617
1618 ret = talitos_sg_map(dev, areq->dst, cryptlen, edesc, &desc->ptr[4],
1619 sg_count, 0, (edesc->src_nents + 1));
1620 if (ret > 1)
1621 sync_needed = true;
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001622
1623 /* iv out */
LEROY Christophea2b35aa2015-04-17 16:31:57 +02001624 map_single_talitos_ptr(dev, &desc->ptr[5], ivsize, ctx->iv,
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001625 DMA_FROM_DEVICE);
1626
1627 /* last DWORD empty */
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001628
LEROY Christophe6a1e8d12016-06-06 13:20:38 +02001629 if (sync_needed)
1630 dma_sync_single_for_device(dev, edesc->dma_link_tbl,
1631 edesc->dma_len, DMA_BIDIRECTIONAL);
1632
Kim Phillips5228f0f2011-07-15 11:21:38 +08001633 ret = talitos_submit(dev, ctx->ch, desc, callback, areq);
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001634 if (ret != -EINPROGRESS) {
1635 common_nonsnoop_unmap(dev, edesc, areq);
1636 kfree(edesc);
1637 }
1638 return ret;
1639}
1640
Kim Phillipse938e462009-03-29 15:53:23 +08001641static struct talitos_edesc *ablkcipher_edesc_alloc(struct ablkcipher_request *
Horia Geanta62293a32013-11-28 15:11:17 +02001642 areq, bool encrypt)
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001643{
1644 struct crypto_ablkcipher *cipher = crypto_ablkcipher_reqtfm(areq);
1645 struct talitos_ctx *ctx = crypto_ablkcipher_ctx(cipher);
Horia Geanta79fd31d2012-08-02 17:16:40 +03001646 unsigned int ivsize = crypto_ablkcipher_ivsize(cipher);
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001647
Herbert Xuaeb4c132015-07-30 17:53:22 +08001648 return talitos_edesc_alloc(ctx->dev, areq->src, areq->dst,
Horia Geanta79fd31d2012-08-02 17:16:40 +03001649 areq->info, 0, areq->nbytes, 0, ivsize, 0,
Horia Geanta62293a32013-11-28 15:11:17 +02001650 areq->base.flags, encrypt);
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001651}
1652
1653static int ablkcipher_encrypt(struct ablkcipher_request *areq)
1654{
1655 struct crypto_ablkcipher *cipher = crypto_ablkcipher_reqtfm(areq);
1656 struct talitos_ctx *ctx = crypto_ablkcipher_ctx(cipher);
1657 struct talitos_edesc *edesc;
1658
1659 /* allocate extended descriptor */
Horia Geanta62293a32013-11-28 15:11:17 +02001660 edesc = ablkcipher_edesc_alloc(areq, true);
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001661 if (IS_ERR(edesc))
1662 return PTR_ERR(edesc);
1663
1664 /* set encrypt */
1665 edesc->desc.hdr = ctx->desc_hdr_template | DESC_HDR_MODE0_ENCRYPT;
1666
Kim Phillipsfebec542011-07-15 11:21:39 +08001667 return common_nonsnoop(edesc, areq, ablkcipher_done);
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001668}
1669
1670static int ablkcipher_decrypt(struct ablkcipher_request *areq)
1671{
1672 struct crypto_ablkcipher *cipher = crypto_ablkcipher_reqtfm(areq);
1673 struct talitos_ctx *ctx = crypto_ablkcipher_ctx(cipher);
1674 struct talitos_edesc *edesc;
1675
1676 /* allocate extended descriptor */
Horia Geanta62293a32013-11-28 15:11:17 +02001677 edesc = ablkcipher_edesc_alloc(areq, false);
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001678 if (IS_ERR(edesc))
1679 return PTR_ERR(edesc);
1680
1681 edesc->desc.hdr = ctx->desc_hdr_template | DESC_HDR_DIR_INBOUND;
1682
Kim Phillipsfebec542011-07-15 11:21:39 +08001683 return common_nonsnoop(edesc, areq, ablkcipher_done);
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001684}
1685
Lee Nipper497f2e62010-05-19 19:20:36 +10001686static void common_nonsnoop_hash_unmap(struct device *dev,
1687 struct talitos_edesc *edesc,
1688 struct ahash_request *areq)
1689{
1690 struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
LEROY Christophead4cd512018-02-26 17:40:04 +01001691 struct talitos_private *priv = dev_get_drvdata(dev);
1692 bool is_sec1 = has_ftr_sec1(priv);
1693 struct talitos_desc *desc = &edesc->desc;
1694 struct talitos_desc *desc2 = desc + 1;
1695
1696 unmap_single_talitos_ptr(dev, &edesc->desc.ptr[5], DMA_FROM_DEVICE);
1697 if (desc->next_desc &&
1698 desc->ptr[5].ptr != desc2->ptr[5].ptr)
1699 unmap_single_talitos_ptr(dev, &desc2->ptr[5], DMA_FROM_DEVICE);
Lee Nipper497f2e62010-05-19 19:20:36 +10001700
LEROY Christophe6a1e8d12016-06-06 13:20:38 +02001701 talitos_sg_unmap(dev, edesc, req_ctx->psrc, NULL, 0, 0);
LEROY Christophe032d1972015-04-17 16:31:51 +02001702
LEROY Christophead4cd512018-02-26 17:40:04 +01001703 /* When using hashctx-in, must unmap it. */
1704 if (from_talitos_ptr_len(&edesc->desc.ptr[1], is_sec1))
1705 unmap_single_talitos_ptr(dev, &edesc->desc.ptr[1],
1706 DMA_TO_DEVICE);
1707 else if (desc->next_desc)
1708 unmap_single_talitos_ptr(dev, &desc2->ptr[1],
1709 DMA_TO_DEVICE);
1710
1711 if (is_sec1 && req_ctx->nbuf)
1712 unmap_single_talitos_ptr(dev, &desc->ptr[3],
1713 DMA_TO_DEVICE);
1714
Lee Nipper497f2e62010-05-19 19:20:36 +10001715 if (edesc->dma_len)
1716 dma_unmap_single(dev, edesc->dma_link_tbl, edesc->dma_len,
1717 DMA_BIDIRECTIONAL);
1718
LEROY Christophe37b5e882017-10-06 15:05:06 +02001719 if (edesc->desc.next_desc)
1720 dma_unmap_single(dev, be32_to_cpu(edesc->desc.next_desc),
1721 TALITOS_DESC_SIZE, DMA_BIDIRECTIONAL);
Lee Nipper497f2e62010-05-19 19:20:36 +10001722}
1723
1724static void ahash_done(struct device *dev,
1725 struct talitos_desc *desc, void *context,
1726 int err)
1727{
1728 struct ahash_request *areq = context;
1729 struct talitos_edesc *edesc =
1730 container_of(desc, struct talitos_edesc, desc);
1731 struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
1732
1733 if (!req_ctx->last && req_ctx->to_hash_later) {
1734 /* Position any partial block for next update/final/finup */
LEROY Christophe3c0dd192017-10-06 15:05:08 +02001735 req_ctx->buf_idx = (req_ctx->buf_idx + 1) & 1;
Lee Nipper5e833bc2010-06-16 15:29:15 +10001736 req_ctx->nbuf = req_ctx->to_hash_later;
Lee Nipper497f2e62010-05-19 19:20:36 +10001737 }
1738 common_nonsnoop_hash_unmap(dev, edesc, areq);
1739
1740 kfree(edesc);
1741
1742 areq->base.complete(&areq->base, err);
1743}
1744
LEROY Christophe2d029052015-04-17 16:32:18 +02001745/*
1746 * SEC1 doesn't like hashing of 0 sized message, so we do the padding
1747 * ourself and submit a padded block
1748 */
LEROY Christophe5b2cf262017-10-06 15:04:47 +02001749static void talitos_handle_buggy_hash(struct talitos_ctx *ctx,
LEROY Christophe2d029052015-04-17 16:32:18 +02001750 struct talitos_edesc *edesc,
1751 struct talitos_ptr *ptr)
1752{
1753 static u8 padded_hash[64] = {
1754 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1755 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1756 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1757 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1758 };
1759
1760 pr_err_once("Bug in SEC1, padding ourself\n");
1761 edesc->desc.hdr &= ~DESC_HDR_MODE0_MDEU_PAD;
1762 map_single_talitos_ptr(ctx->dev, ptr, sizeof(padded_hash),
1763 (char *)padded_hash, DMA_TO_DEVICE);
1764}
1765
Lee Nipper497f2e62010-05-19 19:20:36 +10001766static int common_nonsnoop_hash(struct talitos_edesc *edesc,
1767 struct ahash_request *areq, unsigned int length,
LEROY Christophe37b5e882017-10-06 15:05:06 +02001768 unsigned int offset,
Lee Nipper497f2e62010-05-19 19:20:36 +10001769 void (*callback) (struct device *dev,
1770 struct talitos_desc *desc,
1771 void *context, int error))
1772{
1773 struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq);
1774 struct talitos_ctx *ctx = crypto_ahash_ctx(tfm);
1775 struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
1776 struct device *dev = ctx->dev;
1777 struct talitos_desc *desc = &edesc->desc;
LEROY Christophe032d1972015-04-17 16:31:51 +02001778 int ret;
LEROY Christophe6a1e8d12016-06-06 13:20:38 +02001779 bool sync_needed = false;
LEROY Christophe922f9dc2015-04-17 16:32:07 +02001780 struct talitos_private *priv = dev_get_drvdata(dev);
1781 bool is_sec1 = has_ftr_sec1(priv);
LEROY Christophe6a1e8d12016-06-06 13:20:38 +02001782 int sg_count;
Lee Nipper497f2e62010-05-19 19:20:36 +10001783
1784 /* first DWORD empty */
Lee Nipper497f2e62010-05-19 19:20:36 +10001785
Kim Phillips60f208d2010-05-19 19:21:53 +10001786 /* hash context in */
1787 if (!req_ctx->first || req_ctx->swinit) {
LEROY Christophead4cd512018-02-26 17:40:04 +01001788 map_single_talitos_ptr(dev, &desc->ptr[1],
1789 req_ctx->hw_context_size,
1790 (char *)req_ctx->hw_context,
1791 DMA_TO_DEVICE);
Kim Phillips60f208d2010-05-19 19:21:53 +10001792 req_ctx->swinit = 0;
Lee Nipper497f2e62010-05-19 19:20:36 +10001793 }
LEROY Christopheafd62fa2017-09-13 12:44:51 +02001794 /* Indicate next op is not the first. */
1795 req_ctx->first = 0;
Lee Nipper497f2e62010-05-19 19:20:36 +10001796
1797 /* HMAC key */
1798 if (ctx->keylen)
LEROY Christophe2e13ce02017-10-06 15:05:02 +02001799 to_talitos_ptr(&desc->ptr[2], ctx->dma_key, ctx->keylen,
1800 is_sec1);
Lee Nipper497f2e62010-05-19 19:20:36 +10001801
LEROY Christophe37b5e882017-10-06 15:05:06 +02001802 if (is_sec1 && req_ctx->nbuf)
1803 length -= req_ctx->nbuf;
1804
LEROY Christophe6a1e8d12016-06-06 13:20:38 +02001805 sg_count = edesc->src_nents ?: 1;
1806 if (is_sec1 && sg_count > 1)
LEROY Christophe37b5e882017-10-06 15:05:06 +02001807 sg_pcopy_to_buffer(req_ctx->psrc, sg_count,
1808 edesc->buf + sizeof(struct talitos_desc),
1809 length, req_ctx->nbuf);
1810 else if (length)
LEROY Christophe6a1e8d12016-06-06 13:20:38 +02001811 sg_count = dma_map_sg(dev, req_ctx->psrc, sg_count,
1812 DMA_TO_DEVICE);
Lee Nipper497f2e62010-05-19 19:20:36 +10001813 /*
1814 * data in
1815 */
LEROY Christophe37b5e882017-10-06 15:05:06 +02001816 if (is_sec1 && req_ctx->nbuf) {
LEROY Christophead4cd512018-02-26 17:40:04 +01001817 map_single_talitos_ptr(dev, &desc->ptr[3], req_ctx->nbuf,
1818 req_ctx->buf[req_ctx->buf_idx],
1819 DMA_TO_DEVICE);
LEROY Christophe37b5e882017-10-06 15:05:06 +02001820 } else {
1821 sg_count = talitos_sg_map(dev, req_ctx->psrc, length, edesc,
1822 &desc->ptr[3], sg_count, offset, 0);
1823 if (sg_count > 1)
1824 sync_needed = true;
1825 }
Lee Nipper497f2e62010-05-19 19:20:36 +10001826
1827 /* fifth DWORD empty */
Lee Nipper497f2e62010-05-19 19:20:36 +10001828
1829 /* hash/HMAC out -or- hash context out */
1830 if (req_ctx->last)
1831 map_single_talitos_ptr(dev, &desc->ptr[5],
1832 crypto_ahash_digestsize(tfm),
LEROY Christophea2b35aa2015-04-17 16:31:57 +02001833 areq->result, DMA_FROM_DEVICE);
Lee Nipper497f2e62010-05-19 19:20:36 +10001834 else
LEROY Christophead4cd512018-02-26 17:40:04 +01001835 map_single_talitos_ptr(dev, &desc->ptr[5],
1836 req_ctx->hw_context_size,
1837 req_ctx->hw_context, DMA_FROM_DEVICE);
Lee Nipper497f2e62010-05-19 19:20:36 +10001838
1839 /* last DWORD empty */
Lee Nipper497f2e62010-05-19 19:20:36 +10001840
LEROY Christophe2d029052015-04-17 16:32:18 +02001841 if (is_sec1 && from_talitos_ptr_len(&desc->ptr[3], true) == 0)
1842 talitos_handle_buggy_hash(ctx, edesc, &desc->ptr[3]);
1843
LEROY Christophe37b5e882017-10-06 15:05:06 +02001844 if (is_sec1 && req_ctx->nbuf && length) {
1845 struct talitos_desc *desc2 = desc + 1;
1846 dma_addr_t next_desc;
1847
1848 memset(desc2, 0, sizeof(*desc2));
1849 desc2->hdr = desc->hdr;
1850 desc2->hdr &= ~DESC_HDR_MODE0_MDEU_INIT;
1851 desc2->hdr1 = desc2->hdr;
1852 desc->hdr &= ~DESC_HDR_MODE0_MDEU_PAD;
1853 desc->hdr |= DESC_HDR_MODE0_MDEU_CONT;
1854 desc->hdr &= ~DESC_HDR_DONE_NOTIFY;
1855
LEROY Christophead4cd512018-02-26 17:40:04 +01001856 if (desc->ptr[1].ptr)
1857 copy_talitos_ptr(&desc2->ptr[1], &desc->ptr[1],
1858 is_sec1);
1859 else
1860 map_single_talitos_ptr(dev, &desc2->ptr[1],
1861 req_ctx->hw_context_size,
1862 req_ctx->hw_context,
1863 DMA_TO_DEVICE);
LEROY Christophe37b5e882017-10-06 15:05:06 +02001864 copy_talitos_ptr(&desc2->ptr[2], &desc->ptr[2], is_sec1);
1865 sg_count = talitos_sg_map(dev, req_ctx->psrc, length, edesc,
1866 &desc2->ptr[3], sg_count, offset, 0);
1867 if (sg_count > 1)
1868 sync_needed = true;
1869 copy_talitos_ptr(&desc2->ptr[5], &desc->ptr[5], is_sec1);
1870 if (req_ctx->last)
LEROY Christophead4cd512018-02-26 17:40:04 +01001871 map_single_talitos_ptr(dev, &desc->ptr[5],
1872 req_ctx->hw_context_size,
1873 req_ctx->hw_context,
1874 DMA_FROM_DEVICE);
LEROY Christophe37b5e882017-10-06 15:05:06 +02001875
1876 next_desc = dma_map_single(dev, &desc2->hdr1, TALITOS_DESC_SIZE,
1877 DMA_BIDIRECTIONAL);
1878 desc->next_desc = cpu_to_be32(next_desc);
1879 }
1880
LEROY Christophe6a1e8d12016-06-06 13:20:38 +02001881 if (sync_needed)
1882 dma_sync_single_for_device(dev, edesc->dma_link_tbl,
1883 edesc->dma_len, DMA_BIDIRECTIONAL);
1884
Kim Phillips5228f0f2011-07-15 11:21:38 +08001885 ret = talitos_submit(dev, ctx->ch, desc, callback, areq);
Lee Nipper497f2e62010-05-19 19:20:36 +10001886 if (ret != -EINPROGRESS) {
1887 common_nonsnoop_hash_unmap(dev, edesc, areq);
1888 kfree(edesc);
1889 }
1890 return ret;
1891}
1892
1893static struct talitos_edesc *ahash_edesc_alloc(struct ahash_request *areq,
1894 unsigned int nbytes)
1895{
1896 struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq);
1897 struct talitos_ctx *ctx = crypto_ahash_ctx(tfm);
1898 struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
LEROY Christophe37b5e882017-10-06 15:05:06 +02001899 struct talitos_private *priv = dev_get_drvdata(ctx->dev);
1900 bool is_sec1 = has_ftr_sec1(priv);
1901
1902 if (is_sec1)
1903 nbytes -= req_ctx->nbuf;
Lee Nipper497f2e62010-05-19 19:20:36 +10001904
Herbert Xuaeb4c132015-07-30 17:53:22 +08001905 return talitos_edesc_alloc(ctx->dev, req_ctx->psrc, NULL, NULL, 0,
Horia Geanta62293a32013-11-28 15:11:17 +02001906 nbytes, 0, 0, 0, areq->base.flags, false);
Lee Nipper497f2e62010-05-19 19:20:36 +10001907}
1908
1909static int ahash_init(struct ahash_request *areq)
1910{
1911 struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq);
1912 struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
LEROY Christophe49f97832017-10-06 15:05:04 +02001913 unsigned int size;
Lee Nipper497f2e62010-05-19 19:20:36 +10001914
1915 /* Initialize the context */
LEROY Christophe3c0dd192017-10-06 15:05:08 +02001916 req_ctx->buf_idx = 0;
Lee Nipper5e833bc2010-06-16 15:29:15 +10001917 req_ctx->nbuf = 0;
Kim Phillips60f208d2010-05-19 19:21:53 +10001918 req_ctx->first = 1; /* first indicates h/w must init its context */
1919 req_ctx->swinit = 0; /* assume h/w init of context */
LEROY Christophe49f97832017-10-06 15:05:04 +02001920 size = (crypto_ahash_digestsize(tfm) <= SHA256_DIGEST_SIZE)
Lee Nipper497f2e62010-05-19 19:20:36 +10001921 ? TALITOS_MDEU_CONTEXT_SIZE_MD5_SHA1_SHA256
1922 : TALITOS_MDEU_CONTEXT_SIZE_SHA384_SHA512;
LEROY Christophe49f97832017-10-06 15:05:04 +02001923 req_ctx->hw_context_size = size;
Lee Nipper497f2e62010-05-19 19:20:36 +10001924
1925 return 0;
1926}
1927
Kim Phillips60f208d2010-05-19 19:21:53 +10001928/*
1929 * on h/w without explicit sha224 support, we initialize h/w context
1930 * manually with sha224 constants, and tell it to run sha256.
1931 */
1932static int ahash_init_sha224_swinit(struct ahash_request *areq)
1933{
1934 struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
1935
1936 ahash_init(areq);
1937 req_ctx->swinit = 1;/* prevent h/w initting context with sha256 values*/
1938
Kim Phillipsa7524472010-09-23 15:56:38 +08001939 req_ctx->hw_context[0] = SHA224_H0;
1940 req_ctx->hw_context[1] = SHA224_H1;
1941 req_ctx->hw_context[2] = SHA224_H2;
1942 req_ctx->hw_context[3] = SHA224_H3;
1943 req_ctx->hw_context[4] = SHA224_H4;
1944 req_ctx->hw_context[5] = SHA224_H5;
1945 req_ctx->hw_context[6] = SHA224_H6;
1946 req_ctx->hw_context[7] = SHA224_H7;
Kim Phillips60f208d2010-05-19 19:21:53 +10001947
1948 /* init 64-bit count */
1949 req_ctx->hw_context[8] = 0;
1950 req_ctx->hw_context[9] = 0;
1951
1952 return 0;
1953}
1954
Lee Nipper497f2e62010-05-19 19:20:36 +10001955static int ahash_process_req(struct ahash_request *areq, unsigned int nbytes)
1956{
1957 struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq);
1958 struct talitos_ctx *ctx = crypto_ahash_ctx(tfm);
1959 struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
1960 struct talitos_edesc *edesc;
1961 unsigned int blocksize =
1962 crypto_tfm_alg_blocksize(crypto_ahash_tfm(tfm));
1963 unsigned int nbytes_to_hash;
1964 unsigned int to_hash_later;
Lee Nipper5e833bc2010-06-16 15:29:15 +10001965 unsigned int nsg;
LABBE Corentin8e409fe2015-11-04 21:13:34 +01001966 int nents;
LEROY Christophe37b5e882017-10-06 15:05:06 +02001967 struct device *dev = ctx->dev;
1968 struct talitos_private *priv = dev_get_drvdata(dev);
1969 bool is_sec1 = has_ftr_sec1(priv);
1970 int offset = 0;
LEROY Christophe3c0dd192017-10-06 15:05:08 +02001971 u8 *ctx_buf = req_ctx->buf[req_ctx->buf_idx];
Lee Nipper497f2e62010-05-19 19:20:36 +10001972
Lee Nipper5e833bc2010-06-16 15:29:15 +10001973 if (!req_ctx->last && (nbytes + req_ctx->nbuf <= blocksize)) {
1974 /* Buffer up to one whole block */
LABBE Corentin8e409fe2015-11-04 21:13:34 +01001975 nents = sg_nents_for_len(areq->src, nbytes);
1976 if (nents < 0) {
1977 dev_err(ctx->dev, "Invalid number of src SG.\n");
1978 return nents;
1979 }
1980 sg_copy_to_buffer(areq->src, nents,
LEROY Christophe3c0dd192017-10-06 15:05:08 +02001981 ctx_buf + req_ctx->nbuf, nbytes);
Lee Nipper5e833bc2010-06-16 15:29:15 +10001982 req_ctx->nbuf += nbytes;
Lee Nipper497f2e62010-05-19 19:20:36 +10001983 return 0;
1984 }
1985
Lee Nipper5e833bc2010-06-16 15:29:15 +10001986 /* At least (blocksize + 1) bytes are available to hash */
1987 nbytes_to_hash = nbytes + req_ctx->nbuf;
1988 to_hash_later = nbytes_to_hash & (blocksize - 1);
1989
1990 if (req_ctx->last)
1991 to_hash_later = 0;
1992 else if (to_hash_later)
1993 /* There is a partial block. Hash the full block(s) now */
1994 nbytes_to_hash -= to_hash_later;
1995 else {
1996 /* Keep one block buffered */
1997 nbytes_to_hash -= blocksize;
1998 to_hash_later = blocksize;
1999 }
2000
2001 /* Chain in any previously buffered data */
LEROY Christophe37b5e882017-10-06 15:05:06 +02002002 if (!is_sec1 && req_ctx->nbuf) {
Lee Nipper5e833bc2010-06-16 15:29:15 +10002003 nsg = (req_ctx->nbuf < nbytes_to_hash) ? 2 : 1;
2004 sg_init_table(req_ctx->bufsl, nsg);
LEROY Christophe3c0dd192017-10-06 15:05:08 +02002005 sg_set_buf(req_ctx->bufsl, ctx_buf, req_ctx->nbuf);
Lee Nipper5e833bc2010-06-16 15:29:15 +10002006 if (nsg > 1)
Dan Williamsc56f6d12015-08-07 18:15:13 +02002007 sg_chain(req_ctx->bufsl, 2, areq->src);
Lee Nipper497f2e62010-05-19 19:20:36 +10002008 req_ctx->psrc = req_ctx->bufsl;
LEROY Christophe37b5e882017-10-06 15:05:06 +02002009 } else if (is_sec1 && req_ctx->nbuf && req_ctx->nbuf < blocksize) {
2010 if (nbytes_to_hash > blocksize)
2011 offset = blocksize - req_ctx->nbuf;
2012 else
2013 offset = nbytes_to_hash - req_ctx->nbuf;
2014 nents = sg_nents_for_len(areq->src, offset);
2015 if (nents < 0) {
2016 dev_err(ctx->dev, "Invalid number of src SG.\n");
2017 return nents;
2018 }
2019 sg_copy_to_buffer(areq->src, nents,
LEROY Christophe3c0dd192017-10-06 15:05:08 +02002020 ctx_buf + req_ctx->nbuf, offset);
LEROY Christophe37b5e882017-10-06 15:05:06 +02002021 req_ctx->nbuf += offset;
2022 req_ctx->psrc = areq->src;
Lee Nipper5e833bc2010-06-16 15:29:15 +10002023 } else
Lee Nipper497f2e62010-05-19 19:20:36 +10002024 req_ctx->psrc = areq->src;
Lee Nipper497f2e62010-05-19 19:20:36 +10002025
Lee Nipper5e833bc2010-06-16 15:29:15 +10002026 if (to_hash_later) {
LABBE Corentin8e409fe2015-11-04 21:13:34 +01002027 nents = sg_nents_for_len(areq->src, nbytes);
2028 if (nents < 0) {
2029 dev_err(ctx->dev, "Invalid number of src SG.\n");
2030 return nents;
2031 }
Akinobu Mitad0525722013-07-08 16:01:55 -07002032 sg_pcopy_to_buffer(areq->src, nents,
LEROY Christophe3c0dd192017-10-06 15:05:08 +02002033 req_ctx->buf[(req_ctx->buf_idx + 1) & 1],
Lee Nipper5e833bc2010-06-16 15:29:15 +10002034 to_hash_later,
2035 nbytes - to_hash_later);
Lee Nipper497f2e62010-05-19 19:20:36 +10002036 }
Lee Nipper5e833bc2010-06-16 15:29:15 +10002037 req_ctx->to_hash_later = to_hash_later;
Lee Nipper497f2e62010-05-19 19:20:36 +10002038
Lee Nipper5e833bc2010-06-16 15:29:15 +10002039 /* Allocate extended descriptor */
Lee Nipper497f2e62010-05-19 19:20:36 +10002040 edesc = ahash_edesc_alloc(areq, nbytes_to_hash);
2041 if (IS_ERR(edesc))
2042 return PTR_ERR(edesc);
2043
2044 edesc->desc.hdr = ctx->desc_hdr_template;
2045
2046 /* On last one, request SEC to pad; otherwise continue */
2047 if (req_ctx->last)
2048 edesc->desc.hdr |= DESC_HDR_MODE0_MDEU_PAD;
2049 else
2050 edesc->desc.hdr |= DESC_HDR_MODE0_MDEU_CONT;
2051
Kim Phillips60f208d2010-05-19 19:21:53 +10002052 /* request SEC to INIT hash. */
2053 if (req_ctx->first && !req_ctx->swinit)
Lee Nipper497f2e62010-05-19 19:20:36 +10002054 edesc->desc.hdr |= DESC_HDR_MODE0_MDEU_INIT;
2055
2056 /* When the tfm context has a keylen, it's an HMAC.
2057 * A first or last (ie. not middle) descriptor must request HMAC.
2058 */
2059 if (ctx->keylen && (req_ctx->first || req_ctx->last))
2060 edesc->desc.hdr |= DESC_HDR_MODE0_MDEU_HMAC;
2061
LEROY Christophe37b5e882017-10-06 15:05:06 +02002062 return common_nonsnoop_hash(edesc, areq, nbytes_to_hash, offset,
Lee Nipper497f2e62010-05-19 19:20:36 +10002063 ahash_done);
2064}
2065
2066static int ahash_update(struct ahash_request *areq)
2067{
2068 struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
2069
2070 req_ctx->last = 0;
2071
2072 return ahash_process_req(areq, areq->nbytes);
2073}
2074
2075static int ahash_final(struct ahash_request *areq)
2076{
2077 struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
2078
2079 req_ctx->last = 1;
2080
2081 return ahash_process_req(areq, 0);
2082}
2083
2084static int ahash_finup(struct ahash_request *areq)
2085{
2086 struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
2087
2088 req_ctx->last = 1;
2089
2090 return ahash_process_req(areq, areq->nbytes);
2091}
2092
2093static int ahash_digest(struct ahash_request *areq)
2094{
2095 struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
Kim Phillips60f208d2010-05-19 19:21:53 +10002096 struct crypto_ahash *ahash = crypto_ahash_reqtfm(areq);
Lee Nipper497f2e62010-05-19 19:20:36 +10002097
Kim Phillips60f208d2010-05-19 19:21:53 +10002098 ahash->init(areq);
Lee Nipper497f2e62010-05-19 19:20:36 +10002099 req_ctx->last = 1;
2100
2101 return ahash_process_req(areq, areq->nbytes);
2102}
2103
Horia Geant?3639ca82016-04-21 19:24:55 +03002104static int ahash_export(struct ahash_request *areq, void *out)
2105{
2106 struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
2107 struct talitos_export_state *export = out;
2108
2109 memcpy(export->hw_context, req_ctx->hw_context,
2110 req_ctx->hw_context_size);
LEROY Christophe3c0dd192017-10-06 15:05:08 +02002111 memcpy(export->buf, req_ctx->buf[req_ctx->buf_idx], req_ctx->nbuf);
Horia Geant?3639ca82016-04-21 19:24:55 +03002112 export->swinit = req_ctx->swinit;
2113 export->first = req_ctx->first;
2114 export->last = req_ctx->last;
2115 export->to_hash_later = req_ctx->to_hash_later;
2116 export->nbuf = req_ctx->nbuf;
2117
2118 return 0;
2119}
2120
2121static int ahash_import(struct ahash_request *areq, const void *in)
2122{
2123 struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
2124 struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq);
2125 const struct talitos_export_state *export = in;
LEROY Christophe49f97832017-10-06 15:05:04 +02002126 unsigned int size;
Horia Geant?3639ca82016-04-21 19:24:55 +03002127
2128 memset(req_ctx, 0, sizeof(*req_ctx));
LEROY Christophe49f97832017-10-06 15:05:04 +02002129 size = (crypto_ahash_digestsize(tfm) <= SHA256_DIGEST_SIZE)
Horia Geant?3639ca82016-04-21 19:24:55 +03002130 ? TALITOS_MDEU_CONTEXT_SIZE_MD5_SHA1_SHA256
2131 : TALITOS_MDEU_CONTEXT_SIZE_SHA384_SHA512;
LEROY Christophe49f97832017-10-06 15:05:04 +02002132 req_ctx->hw_context_size = size;
LEROY Christophe49f97832017-10-06 15:05:04 +02002133 memcpy(req_ctx->hw_context, export->hw_context, size);
LEROY Christophe3c0dd192017-10-06 15:05:08 +02002134 memcpy(req_ctx->buf[0], export->buf, export->nbuf);
Horia Geant?3639ca82016-04-21 19:24:55 +03002135 req_ctx->swinit = export->swinit;
2136 req_ctx->first = export->first;
2137 req_ctx->last = export->last;
2138 req_ctx->to_hash_later = export->to_hash_later;
2139 req_ctx->nbuf = export->nbuf;
2140
2141 return 0;
2142}
2143
Lee Nipper79b3a412011-11-21 16:13:25 +08002144static int keyhash(struct crypto_ahash *tfm, const u8 *key, unsigned int keylen,
2145 u8 *hash)
2146{
2147 struct talitos_ctx *ctx = crypto_tfm_ctx(crypto_ahash_tfm(tfm));
2148
2149 struct scatterlist sg[1];
2150 struct ahash_request *req;
Gilad Ben-Yosseff1c90ac32017-10-18 08:00:49 +01002151 struct crypto_wait wait;
Lee Nipper79b3a412011-11-21 16:13:25 +08002152 int ret;
2153
Gilad Ben-Yosseff1c90ac32017-10-18 08:00:49 +01002154 crypto_init_wait(&wait);
Lee Nipper79b3a412011-11-21 16:13:25 +08002155
2156 req = ahash_request_alloc(tfm, GFP_KERNEL);
2157 if (!req)
2158 return -ENOMEM;
2159
2160 /* Keep tfm keylen == 0 during hash of the long key */
2161 ctx->keylen = 0;
2162 ahash_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
Gilad Ben-Yosseff1c90ac32017-10-18 08:00:49 +01002163 crypto_req_done, &wait);
Lee Nipper79b3a412011-11-21 16:13:25 +08002164
2165 sg_init_one(&sg[0], key, keylen);
2166
2167 ahash_request_set_crypt(req, sg, hash, keylen);
Gilad Ben-Yosseff1c90ac32017-10-18 08:00:49 +01002168 ret = crypto_wait_req(crypto_ahash_digest(req), &wait);
2169
Lee Nipper79b3a412011-11-21 16:13:25 +08002170 ahash_request_free(req);
2171
2172 return ret;
2173}
2174
2175static int ahash_setkey(struct crypto_ahash *tfm, const u8 *key,
2176 unsigned int keylen)
2177{
2178 struct talitos_ctx *ctx = crypto_tfm_ctx(crypto_ahash_tfm(tfm));
LEROY Christophe2e13ce02017-10-06 15:05:02 +02002179 struct device *dev = ctx->dev;
Lee Nipper79b3a412011-11-21 16:13:25 +08002180 unsigned int blocksize =
2181 crypto_tfm_alg_blocksize(crypto_ahash_tfm(tfm));
2182 unsigned int digestsize = crypto_ahash_digestsize(tfm);
2183 unsigned int keysize = keylen;
2184 u8 hash[SHA512_DIGEST_SIZE];
2185 int ret;
2186
2187 if (keylen <= blocksize)
2188 memcpy(ctx->key, key, keysize);
2189 else {
2190 /* Must get the hash of the long key */
2191 ret = keyhash(tfm, key, keylen, hash);
2192
2193 if (ret) {
2194 crypto_ahash_set_flags(tfm, CRYPTO_TFM_RES_BAD_KEY_LEN);
2195 return -EINVAL;
2196 }
2197
2198 keysize = digestsize;
2199 memcpy(ctx->key, hash, digestsize);
2200 }
2201
LEROY Christophe2e13ce02017-10-06 15:05:02 +02002202 if (ctx->keylen)
2203 dma_unmap_single(dev, ctx->dma_key, ctx->keylen, DMA_TO_DEVICE);
2204
Lee Nipper79b3a412011-11-21 16:13:25 +08002205 ctx->keylen = keysize;
LEROY Christophe2e13ce02017-10-06 15:05:02 +02002206 ctx->dma_key = dma_map_single(dev, ctx->key, keysize, DMA_TO_DEVICE);
Lee Nipper79b3a412011-11-21 16:13:25 +08002207
2208 return 0;
2209}
2210
2211
Kim Phillips9c4a7962008-06-23 19:50:15 +08002212struct talitos_alg_template {
Lee Nipperd5e4aae2010-05-19 19:18:38 +10002213 u32 type;
LEROY Christopheb0057762016-06-06 13:20:44 +02002214 u32 priority;
Lee Nipperd5e4aae2010-05-19 19:18:38 +10002215 union {
2216 struct crypto_alg crypto;
Lee Nipperacbf7c622010-05-19 19:19:33 +10002217 struct ahash_alg hash;
Herbert Xuaeb4c132015-07-30 17:53:22 +08002218 struct aead_alg aead;
Lee Nipperd5e4aae2010-05-19 19:18:38 +10002219 } alg;
Kim Phillips9c4a7962008-06-23 19:50:15 +08002220 __be32 desc_hdr_template;
2221};
2222
2223static struct talitos_alg_template driver_algs[] = {
Horia Geanta991155b2013-03-20 16:31:38 +02002224 /* AEAD algorithms. These use a single-pass ipsec_esp descriptor */
Lee Nipperd5e4aae2010-05-19 19:18:38 +10002225 { .type = CRYPTO_ALG_TYPE_AEAD,
Herbert Xuaeb4c132015-07-30 17:53:22 +08002226 .alg.aead = {
2227 .base = {
2228 .cra_name = "authenc(hmac(sha1),cbc(aes))",
2229 .cra_driver_name = "authenc-hmac-sha1-"
2230 "cbc-aes-talitos",
2231 .cra_blocksize = AES_BLOCK_SIZE,
2232 .cra_flags = CRYPTO_ALG_ASYNC,
2233 },
2234 .ivsize = AES_BLOCK_SIZE,
2235 .maxauthsize = SHA1_DIGEST_SIZE,
Lee Nipper56af8cd2009-03-29 15:50:50 +08002236 },
Kim Phillips9c4a7962008-06-23 19:50:15 +08002237 .desc_hdr_template = DESC_HDR_TYPE_IPSEC_ESP |
2238 DESC_HDR_SEL0_AESU |
2239 DESC_HDR_MODE0_AESU_CBC |
2240 DESC_HDR_SEL1_MDEUA |
2241 DESC_HDR_MODE1_MDEU_INIT |
2242 DESC_HDR_MODE1_MDEU_PAD |
2243 DESC_HDR_MODE1_MDEU_SHA1_HMAC,
Lee Nipper70bcaca2008-07-03 19:08:46 +08002244 },
Lee Nipperd5e4aae2010-05-19 19:18:38 +10002245 { .type = CRYPTO_ALG_TYPE_AEAD,
LEROY Christophe7405c8d2016-06-06 13:20:46 +02002246 .priority = TALITOS_CRA_PRIORITY_AEAD_HSNA,
2247 .alg.aead = {
2248 .base = {
2249 .cra_name = "authenc(hmac(sha1),cbc(aes))",
2250 .cra_driver_name = "authenc-hmac-sha1-"
2251 "cbc-aes-talitos",
2252 .cra_blocksize = AES_BLOCK_SIZE,
2253 .cra_flags = CRYPTO_ALG_ASYNC,
2254 },
2255 .ivsize = AES_BLOCK_SIZE,
2256 .maxauthsize = SHA1_DIGEST_SIZE,
2257 },
2258 .desc_hdr_template = DESC_HDR_TYPE_HMAC_SNOOP_NO_AFEU |
2259 DESC_HDR_SEL0_AESU |
2260 DESC_HDR_MODE0_AESU_CBC |
2261 DESC_HDR_SEL1_MDEUA |
2262 DESC_HDR_MODE1_MDEU_INIT |
2263 DESC_HDR_MODE1_MDEU_PAD |
2264 DESC_HDR_MODE1_MDEU_SHA1_HMAC,
2265 },
2266 { .type = CRYPTO_ALG_TYPE_AEAD,
Herbert Xuaeb4c132015-07-30 17:53:22 +08002267 .alg.aead = {
2268 .base = {
2269 .cra_name = "authenc(hmac(sha1),"
2270 "cbc(des3_ede))",
2271 .cra_driver_name = "authenc-hmac-sha1-"
2272 "cbc-3des-talitos",
2273 .cra_blocksize = DES3_EDE_BLOCK_SIZE,
2274 .cra_flags = CRYPTO_ALG_ASYNC,
2275 },
2276 .ivsize = DES3_EDE_BLOCK_SIZE,
2277 .maxauthsize = SHA1_DIGEST_SIZE,
Lee Nipper56af8cd2009-03-29 15:50:50 +08002278 },
Lee Nipper70bcaca2008-07-03 19:08:46 +08002279 .desc_hdr_template = DESC_HDR_TYPE_IPSEC_ESP |
2280 DESC_HDR_SEL0_DEU |
2281 DESC_HDR_MODE0_DEU_CBC |
2282 DESC_HDR_MODE0_DEU_3DES |
2283 DESC_HDR_SEL1_MDEUA |
2284 DESC_HDR_MODE1_MDEU_INIT |
2285 DESC_HDR_MODE1_MDEU_PAD |
2286 DESC_HDR_MODE1_MDEU_SHA1_HMAC,
Lee Nipper3952f172008-07-10 18:29:18 +08002287 },
LEROY Christophe7405c8d2016-06-06 13:20:46 +02002288 { .type = CRYPTO_ALG_TYPE_AEAD,
2289 .priority = TALITOS_CRA_PRIORITY_AEAD_HSNA,
2290 .alg.aead = {
2291 .base = {
2292 .cra_name = "authenc(hmac(sha1),"
2293 "cbc(des3_ede))",
2294 .cra_driver_name = "authenc-hmac-sha1-"
2295 "cbc-3des-talitos",
2296 .cra_blocksize = DES3_EDE_BLOCK_SIZE,
2297 .cra_flags = CRYPTO_ALG_ASYNC,
2298 },
2299 .ivsize = DES3_EDE_BLOCK_SIZE,
2300 .maxauthsize = SHA1_DIGEST_SIZE,
2301 },
2302 .desc_hdr_template = DESC_HDR_TYPE_HMAC_SNOOP_NO_AFEU |
2303 DESC_HDR_SEL0_DEU |
2304 DESC_HDR_MODE0_DEU_CBC |
2305 DESC_HDR_MODE0_DEU_3DES |
2306 DESC_HDR_SEL1_MDEUA |
2307 DESC_HDR_MODE1_MDEU_INIT |
2308 DESC_HDR_MODE1_MDEU_PAD |
2309 DESC_HDR_MODE1_MDEU_SHA1_HMAC,
2310 },
Horia Geanta357fb602012-07-03 19:16:53 +03002311 { .type = CRYPTO_ALG_TYPE_AEAD,
Herbert Xuaeb4c132015-07-30 17:53:22 +08002312 .alg.aead = {
2313 .base = {
2314 .cra_name = "authenc(hmac(sha224),cbc(aes))",
2315 .cra_driver_name = "authenc-hmac-sha224-"
2316 "cbc-aes-talitos",
2317 .cra_blocksize = AES_BLOCK_SIZE,
2318 .cra_flags = CRYPTO_ALG_ASYNC,
2319 },
2320 .ivsize = AES_BLOCK_SIZE,
2321 .maxauthsize = SHA224_DIGEST_SIZE,
Horia Geanta357fb602012-07-03 19:16:53 +03002322 },
2323 .desc_hdr_template = DESC_HDR_TYPE_IPSEC_ESP |
2324 DESC_HDR_SEL0_AESU |
2325 DESC_HDR_MODE0_AESU_CBC |
2326 DESC_HDR_SEL1_MDEUA |
2327 DESC_HDR_MODE1_MDEU_INIT |
2328 DESC_HDR_MODE1_MDEU_PAD |
2329 DESC_HDR_MODE1_MDEU_SHA224_HMAC,
2330 },
LEROY Christophe7405c8d2016-06-06 13:20:46 +02002331 { .type = CRYPTO_ALG_TYPE_AEAD,
2332 .priority = TALITOS_CRA_PRIORITY_AEAD_HSNA,
2333 .alg.aead = {
2334 .base = {
2335 .cra_name = "authenc(hmac(sha224),cbc(aes))",
2336 .cra_driver_name = "authenc-hmac-sha224-"
2337 "cbc-aes-talitos",
2338 .cra_blocksize = AES_BLOCK_SIZE,
2339 .cra_flags = CRYPTO_ALG_ASYNC,
2340 },
2341 .ivsize = AES_BLOCK_SIZE,
2342 .maxauthsize = SHA224_DIGEST_SIZE,
2343 },
2344 .desc_hdr_template = DESC_HDR_TYPE_HMAC_SNOOP_NO_AFEU |
2345 DESC_HDR_SEL0_AESU |
2346 DESC_HDR_MODE0_AESU_CBC |
2347 DESC_HDR_SEL1_MDEUA |
2348 DESC_HDR_MODE1_MDEU_INIT |
2349 DESC_HDR_MODE1_MDEU_PAD |
2350 DESC_HDR_MODE1_MDEU_SHA224_HMAC,
2351 },
Horia Geanta357fb602012-07-03 19:16:53 +03002352 { .type = CRYPTO_ALG_TYPE_AEAD,
Herbert Xuaeb4c132015-07-30 17:53:22 +08002353 .alg.aead = {
2354 .base = {
2355 .cra_name = "authenc(hmac(sha224),"
2356 "cbc(des3_ede))",
2357 .cra_driver_name = "authenc-hmac-sha224-"
2358 "cbc-3des-talitos",
2359 .cra_blocksize = DES3_EDE_BLOCK_SIZE,
2360 .cra_flags = CRYPTO_ALG_ASYNC,
2361 },
2362 .ivsize = DES3_EDE_BLOCK_SIZE,
2363 .maxauthsize = SHA224_DIGEST_SIZE,
Horia Geanta357fb602012-07-03 19:16:53 +03002364 },
2365 .desc_hdr_template = DESC_HDR_TYPE_IPSEC_ESP |
2366 DESC_HDR_SEL0_DEU |
2367 DESC_HDR_MODE0_DEU_CBC |
2368 DESC_HDR_MODE0_DEU_3DES |
2369 DESC_HDR_SEL1_MDEUA |
2370 DESC_HDR_MODE1_MDEU_INIT |
2371 DESC_HDR_MODE1_MDEU_PAD |
2372 DESC_HDR_MODE1_MDEU_SHA224_HMAC,
2373 },
Lee Nipperd5e4aae2010-05-19 19:18:38 +10002374 { .type = CRYPTO_ALG_TYPE_AEAD,
LEROY Christophe7405c8d2016-06-06 13:20:46 +02002375 .priority = TALITOS_CRA_PRIORITY_AEAD_HSNA,
2376 .alg.aead = {
2377 .base = {
2378 .cra_name = "authenc(hmac(sha224),"
2379 "cbc(des3_ede))",
2380 .cra_driver_name = "authenc-hmac-sha224-"
2381 "cbc-3des-talitos",
2382 .cra_blocksize = DES3_EDE_BLOCK_SIZE,
2383 .cra_flags = CRYPTO_ALG_ASYNC,
2384 },
2385 .ivsize = DES3_EDE_BLOCK_SIZE,
2386 .maxauthsize = SHA224_DIGEST_SIZE,
2387 },
2388 .desc_hdr_template = DESC_HDR_TYPE_HMAC_SNOOP_NO_AFEU |
2389 DESC_HDR_SEL0_DEU |
2390 DESC_HDR_MODE0_DEU_CBC |
2391 DESC_HDR_MODE0_DEU_3DES |
2392 DESC_HDR_SEL1_MDEUA |
2393 DESC_HDR_MODE1_MDEU_INIT |
2394 DESC_HDR_MODE1_MDEU_PAD |
2395 DESC_HDR_MODE1_MDEU_SHA224_HMAC,
2396 },
2397 { .type = CRYPTO_ALG_TYPE_AEAD,
Herbert Xuaeb4c132015-07-30 17:53:22 +08002398 .alg.aead = {
2399 .base = {
2400 .cra_name = "authenc(hmac(sha256),cbc(aes))",
2401 .cra_driver_name = "authenc-hmac-sha256-"
2402 "cbc-aes-talitos",
2403 .cra_blocksize = AES_BLOCK_SIZE,
2404 .cra_flags = CRYPTO_ALG_ASYNC,
2405 },
2406 .ivsize = AES_BLOCK_SIZE,
2407 .maxauthsize = SHA256_DIGEST_SIZE,
Lee Nipper56af8cd2009-03-29 15:50:50 +08002408 },
Lee Nipper3952f172008-07-10 18:29:18 +08002409 .desc_hdr_template = DESC_HDR_TYPE_IPSEC_ESP |
2410 DESC_HDR_SEL0_AESU |
2411 DESC_HDR_MODE0_AESU_CBC |
2412 DESC_HDR_SEL1_MDEUA |
2413 DESC_HDR_MODE1_MDEU_INIT |
2414 DESC_HDR_MODE1_MDEU_PAD |
2415 DESC_HDR_MODE1_MDEU_SHA256_HMAC,
2416 },
Lee Nipperd5e4aae2010-05-19 19:18:38 +10002417 { .type = CRYPTO_ALG_TYPE_AEAD,
LEROY Christophe7405c8d2016-06-06 13:20:46 +02002418 .priority = TALITOS_CRA_PRIORITY_AEAD_HSNA,
2419 .alg.aead = {
2420 .base = {
2421 .cra_name = "authenc(hmac(sha256),cbc(aes))",
2422 .cra_driver_name = "authenc-hmac-sha256-"
2423 "cbc-aes-talitos",
2424 .cra_blocksize = AES_BLOCK_SIZE,
2425 .cra_flags = CRYPTO_ALG_ASYNC,
2426 },
2427 .ivsize = AES_BLOCK_SIZE,
2428 .maxauthsize = SHA256_DIGEST_SIZE,
2429 },
2430 .desc_hdr_template = DESC_HDR_TYPE_HMAC_SNOOP_NO_AFEU |
2431 DESC_HDR_SEL0_AESU |
2432 DESC_HDR_MODE0_AESU_CBC |
2433 DESC_HDR_SEL1_MDEUA |
2434 DESC_HDR_MODE1_MDEU_INIT |
2435 DESC_HDR_MODE1_MDEU_PAD |
2436 DESC_HDR_MODE1_MDEU_SHA256_HMAC,
2437 },
2438 { .type = CRYPTO_ALG_TYPE_AEAD,
Herbert Xuaeb4c132015-07-30 17:53:22 +08002439 .alg.aead = {
2440 .base = {
2441 .cra_name = "authenc(hmac(sha256),"
2442 "cbc(des3_ede))",
2443 .cra_driver_name = "authenc-hmac-sha256-"
2444 "cbc-3des-talitos",
2445 .cra_blocksize = DES3_EDE_BLOCK_SIZE,
2446 .cra_flags = CRYPTO_ALG_ASYNC,
2447 },
2448 .ivsize = DES3_EDE_BLOCK_SIZE,
2449 .maxauthsize = SHA256_DIGEST_SIZE,
Lee Nipper56af8cd2009-03-29 15:50:50 +08002450 },
Lee Nipper3952f172008-07-10 18:29:18 +08002451 .desc_hdr_template = DESC_HDR_TYPE_IPSEC_ESP |
2452 DESC_HDR_SEL0_DEU |
2453 DESC_HDR_MODE0_DEU_CBC |
2454 DESC_HDR_MODE0_DEU_3DES |
2455 DESC_HDR_SEL1_MDEUA |
2456 DESC_HDR_MODE1_MDEU_INIT |
2457 DESC_HDR_MODE1_MDEU_PAD |
2458 DESC_HDR_MODE1_MDEU_SHA256_HMAC,
2459 },
Lee Nipperd5e4aae2010-05-19 19:18:38 +10002460 { .type = CRYPTO_ALG_TYPE_AEAD,
LEROY Christophe7405c8d2016-06-06 13:20:46 +02002461 .priority = TALITOS_CRA_PRIORITY_AEAD_HSNA,
2462 .alg.aead = {
2463 .base = {
2464 .cra_name = "authenc(hmac(sha256),"
2465 "cbc(des3_ede))",
2466 .cra_driver_name = "authenc-hmac-sha256-"
2467 "cbc-3des-talitos",
2468 .cra_blocksize = DES3_EDE_BLOCK_SIZE,
2469 .cra_flags = CRYPTO_ALG_ASYNC,
2470 },
2471 .ivsize = DES3_EDE_BLOCK_SIZE,
2472 .maxauthsize = SHA256_DIGEST_SIZE,
2473 },
2474 .desc_hdr_template = DESC_HDR_TYPE_HMAC_SNOOP_NO_AFEU |
2475 DESC_HDR_SEL0_DEU |
2476 DESC_HDR_MODE0_DEU_CBC |
2477 DESC_HDR_MODE0_DEU_3DES |
2478 DESC_HDR_SEL1_MDEUA |
2479 DESC_HDR_MODE1_MDEU_INIT |
2480 DESC_HDR_MODE1_MDEU_PAD |
2481 DESC_HDR_MODE1_MDEU_SHA256_HMAC,
2482 },
2483 { .type = CRYPTO_ALG_TYPE_AEAD,
Herbert Xuaeb4c132015-07-30 17:53:22 +08002484 .alg.aead = {
2485 .base = {
2486 .cra_name = "authenc(hmac(sha384),cbc(aes))",
2487 .cra_driver_name = "authenc-hmac-sha384-"
2488 "cbc-aes-talitos",
2489 .cra_blocksize = AES_BLOCK_SIZE,
2490 .cra_flags = CRYPTO_ALG_ASYNC,
2491 },
2492 .ivsize = AES_BLOCK_SIZE,
2493 .maxauthsize = SHA384_DIGEST_SIZE,
Horia Geanta357fb602012-07-03 19:16:53 +03002494 },
2495 .desc_hdr_template = DESC_HDR_TYPE_IPSEC_ESP |
2496 DESC_HDR_SEL0_AESU |
2497 DESC_HDR_MODE0_AESU_CBC |
2498 DESC_HDR_SEL1_MDEUB |
2499 DESC_HDR_MODE1_MDEU_INIT |
2500 DESC_HDR_MODE1_MDEU_PAD |
2501 DESC_HDR_MODE1_MDEUB_SHA384_HMAC,
2502 },
2503 { .type = CRYPTO_ALG_TYPE_AEAD,
Herbert Xuaeb4c132015-07-30 17:53:22 +08002504 .alg.aead = {
2505 .base = {
2506 .cra_name = "authenc(hmac(sha384),"
2507 "cbc(des3_ede))",
2508 .cra_driver_name = "authenc-hmac-sha384-"
2509 "cbc-3des-talitos",
2510 .cra_blocksize = DES3_EDE_BLOCK_SIZE,
2511 .cra_flags = CRYPTO_ALG_ASYNC,
2512 },
2513 .ivsize = DES3_EDE_BLOCK_SIZE,
2514 .maxauthsize = SHA384_DIGEST_SIZE,
Horia Geanta357fb602012-07-03 19:16:53 +03002515 },
2516 .desc_hdr_template = DESC_HDR_TYPE_IPSEC_ESP |
2517 DESC_HDR_SEL0_DEU |
2518 DESC_HDR_MODE0_DEU_CBC |
2519 DESC_HDR_MODE0_DEU_3DES |
2520 DESC_HDR_SEL1_MDEUB |
2521 DESC_HDR_MODE1_MDEU_INIT |
2522 DESC_HDR_MODE1_MDEU_PAD |
2523 DESC_HDR_MODE1_MDEUB_SHA384_HMAC,
2524 },
2525 { .type = CRYPTO_ALG_TYPE_AEAD,
Herbert Xuaeb4c132015-07-30 17:53:22 +08002526 .alg.aead = {
2527 .base = {
2528 .cra_name = "authenc(hmac(sha512),cbc(aes))",
2529 .cra_driver_name = "authenc-hmac-sha512-"
2530 "cbc-aes-talitos",
2531 .cra_blocksize = AES_BLOCK_SIZE,
2532 .cra_flags = CRYPTO_ALG_ASYNC,
2533 },
2534 .ivsize = AES_BLOCK_SIZE,
2535 .maxauthsize = SHA512_DIGEST_SIZE,
Horia Geanta357fb602012-07-03 19:16:53 +03002536 },
2537 .desc_hdr_template = DESC_HDR_TYPE_IPSEC_ESP |
2538 DESC_HDR_SEL0_AESU |
2539 DESC_HDR_MODE0_AESU_CBC |
2540 DESC_HDR_SEL1_MDEUB |
2541 DESC_HDR_MODE1_MDEU_INIT |
2542 DESC_HDR_MODE1_MDEU_PAD |
2543 DESC_HDR_MODE1_MDEUB_SHA512_HMAC,
2544 },
2545 { .type = CRYPTO_ALG_TYPE_AEAD,
Herbert Xuaeb4c132015-07-30 17:53:22 +08002546 .alg.aead = {
2547 .base = {
2548 .cra_name = "authenc(hmac(sha512),"
2549 "cbc(des3_ede))",
2550 .cra_driver_name = "authenc-hmac-sha512-"
2551 "cbc-3des-talitos",
2552 .cra_blocksize = DES3_EDE_BLOCK_SIZE,
2553 .cra_flags = CRYPTO_ALG_ASYNC,
2554 },
2555 .ivsize = DES3_EDE_BLOCK_SIZE,
2556 .maxauthsize = SHA512_DIGEST_SIZE,
Horia Geanta357fb602012-07-03 19:16:53 +03002557 },
2558 .desc_hdr_template = DESC_HDR_TYPE_IPSEC_ESP |
2559 DESC_HDR_SEL0_DEU |
2560 DESC_HDR_MODE0_DEU_CBC |
2561 DESC_HDR_MODE0_DEU_3DES |
2562 DESC_HDR_SEL1_MDEUB |
2563 DESC_HDR_MODE1_MDEU_INIT |
2564 DESC_HDR_MODE1_MDEU_PAD |
2565 DESC_HDR_MODE1_MDEUB_SHA512_HMAC,
2566 },
2567 { .type = CRYPTO_ALG_TYPE_AEAD,
Herbert Xuaeb4c132015-07-30 17:53:22 +08002568 .alg.aead = {
2569 .base = {
2570 .cra_name = "authenc(hmac(md5),cbc(aes))",
2571 .cra_driver_name = "authenc-hmac-md5-"
2572 "cbc-aes-talitos",
2573 .cra_blocksize = AES_BLOCK_SIZE,
2574 .cra_flags = CRYPTO_ALG_ASYNC,
2575 },
2576 .ivsize = AES_BLOCK_SIZE,
2577 .maxauthsize = MD5_DIGEST_SIZE,
Lee Nipper56af8cd2009-03-29 15:50:50 +08002578 },
Lee Nipper3952f172008-07-10 18:29:18 +08002579 .desc_hdr_template = DESC_HDR_TYPE_IPSEC_ESP |
2580 DESC_HDR_SEL0_AESU |
2581 DESC_HDR_MODE0_AESU_CBC |
2582 DESC_HDR_SEL1_MDEUA |
2583 DESC_HDR_MODE1_MDEU_INIT |
2584 DESC_HDR_MODE1_MDEU_PAD |
2585 DESC_HDR_MODE1_MDEU_MD5_HMAC,
2586 },
Lee Nipperd5e4aae2010-05-19 19:18:38 +10002587 { .type = CRYPTO_ALG_TYPE_AEAD,
LEROY Christophe7405c8d2016-06-06 13:20:46 +02002588 .priority = TALITOS_CRA_PRIORITY_AEAD_HSNA,
2589 .alg.aead = {
2590 .base = {
2591 .cra_name = "authenc(hmac(md5),cbc(aes))",
2592 .cra_driver_name = "authenc-hmac-md5-"
2593 "cbc-aes-talitos",
2594 .cra_blocksize = AES_BLOCK_SIZE,
2595 .cra_flags = CRYPTO_ALG_ASYNC,
2596 },
2597 .ivsize = AES_BLOCK_SIZE,
2598 .maxauthsize = MD5_DIGEST_SIZE,
2599 },
2600 .desc_hdr_template = DESC_HDR_TYPE_HMAC_SNOOP_NO_AFEU |
2601 DESC_HDR_SEL0_AESU |
2602 DESC_HDR_MODE0_AESU_CBC |
2603 DESC_HDR_SEL1_MDEUA |
2604 DESC_HDR_MODE1_MDEU_INIT |
2605 DESC_HDR_MODE1_MDEU_PAD |
2606 DESC_HDR_MODE1_MDEU_MD5_HMAC,
2607 },
2608 { .type = CRYPTO_ALG_TYPE_AEAD,
Herbert Xuaeb4c132015-07-30 17:53:22 +08002609 .alg.aead = {
2610 .base = {
2611 .cra_name = "authenc(hmac(md5),cbc(des3_ede))",
2612 .cra_driver_name = "authenc-hmac-md5-"
2613 "cbc-3des-talitos",
2614 .cra_blocksize = DES3_EDE_BLOCK_SIZE,
2615 .cra_flags = CRYPTO_ALG_ASYNC,
2616 },
2617 .ivsize = DES3_EDE_BLOCK_SIZE,
2618 .maxauthsize = MD5_DIGEST_SIZE,
Lee Nipper56af8cd2009-03-29 15:50:50 +08002619 },
Lee Nipper3952f172008-07-10 18:29:18 +08002620 .desc_hdr_template = DESC_HDR_TYPE_IPSEC_ESP |
2621 DESC_HDR_SEL0_DEU |
2622 DESC_HDR_MODE0_DEU_CBC |
2623 DESC_HDR_MODE0_DEU_3DES |
2624 DESC_HDR_SEL1_MDEUA |
2625 DESC_HDR_MODE1_MDEU_INIT |
2626 DESC_HDR_MODE1_MDEU_PAD |
2627 DESC_HDR_MODE1_MDEU_MD5_HMAC,
Lee Nipper4de9d0b2009-03-29 15:52:32 +08002628 },
LEROY Christophe7405c8d2016-06-06 13:20:46 +02002629 { .type = CRYPTO_ALG_TYPE_AEAD,
2630 .priority = TALITOS_CRA_PRIORITY_AEAD_HSNA,
2631 .alg.aead = {
2632 .base = {
2633 .cra_name = "authenc(hmac(md5),cbc(des3_ede))",
2634 .cra_driver_name = "authenc-hmac-md5-"
2635 "cbc-3des-talitos",
2636 .cra_blocksize = DES3_EDE_BLOCK_SIZE,
2637 .cra_flags = CRYPTO_ALG_ASYNC,
2638 },
2639 .ivsize = DES3_EDE_BLOCK_SIZE,
2640 .maxauthsize = MD5_DIGEST_SIZE,
2641 },
2642 .desc_hdr_template = DESC_HDR_TYPE_HMAC_SNOOP_NO_AFEU |
2643 DESC_HDR_SEL0_DEU |
2644 DESC_HDR_MODE0_DEU_CBC |
2645 DESC_HDR_MODE0_DEU_3DES |
2646 DESC_HDR_SEL1_MDEUA |
2647 DESC_HDR_MODE1_MDEU_INIT |
2648 DESC_HDR_MODE1_MDEU_PAD |
2649 DESC_HDR_MODE1_MDEU_MD5_HMAC,
2650 },
Lee Nipper4de9d0b2009-03-29 15:52:32 +08002651 /* ABLKCIPHER algorithms. */
Lee Nipperd5e4aae2010-05-19 19:18:38 +10002652 { .type = CRYPTO_ALG_TYPE_ABLKCIPHER,
2653 .alg.crypto = {
LEROY Christophe5e75ae12015-12-01 12:44:15 +01002654 .cra_name = "ecb(aes)",
2655 .cra_driver_name = "ecb-aes-talitos",
2656 .cra_blocksize = AES_BLOCK_SIZE,
2657 .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER |
2658 CRYPTO_ALG_ASYNC,
2659 .cra_ablkcipher = {
2660 .min_keysize = AES_MIN_KEY_SIZE,
2661 .max_keysize = AES_MAX_KEY_SIZE,
2662 .ivsize = AES_BLOCK_SIZE,
2663 }
2664 },
2665 .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
2666 DESC_HDR_SEL0_AESU,
2667 },
2668 { .type = CRYPTO_ALG_TYPE_ABLKCIPHER,
2669 .alg.crypto = {
Lee Nipper4de9d0b2009-03-29 15:52:32 +08002670 .cra_name = "cbc(aes)",
2671 .cra_driver_name = "cbc-aes-talitos",
2672 .cra_blocksize = AES_BLOCK_SIZE,
2673 .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER |
2674 CRYPTO_ALG_ASYNC,
Lee Nipper4de9d0b2009-03-29 15:52:32 +08002675 .cra_ablkcipher = {
Lee Nipper4de9d0b2009-03-29 15:52:32 +08002676 .min_keysize = AES_MIN_KEY_SIZE,
2677 .max_keysize = AES_MAX_KEY_SIZE,
2678 .ivsize = AES_BLOCK_SIZE,
2679 }
2680 },
2681 .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
2682 DESC_HDR_SEL0_AESU |
2683 DESC_HDR_MODE0_AESU_CBC,
2684 },
Lee Nipperd5e4aae2010-05-19 19:18:38 +10002685 { .type = CRYPTO_ALG_TYPE_ABLKCIPHER,
2686 .alg.crypto = {
LEROY Christophe5e75ae12015-12-01 12:44:15 +01002687 .cra_name = "ctr(aes)",
2688 .cra_driver_name = "ctr-aes-talitos",
2689 .cra_blocksize = AES_BLOCK_SIZE,
2690 .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER |
2691 CRYPTO_ALG_ASYNC,
2692 .cra_ablkcipher = {
2693 .min_keysize = AES_MIN_KEY_SIZE,
2694 .max_keysize = AES_MAX_KEY_SIZE,
2695 .ivsize = AES_BLOCK_SIZE,
2696 }
2697 },
LEROY Christophe70d355c2017-10-06 15:04:43 +02002698 .desc_hdr_template = DESC_HDR_TYPE_AESU_CTR_NONSNOOP |
LEROY Christophe5e75ae12015-12-01 12:44:15 +01002699 DESC_HDR_SEL0_AESU |
2700 DESC_HDR_MODE0_AESU_CTR,
2701 },
2702 { .type = CRYPTO_ALG_TYPE_ABLKCIPHER,
2703 .alg.crypto = {
2704 .cra_name = "ecb(des)",
2705 .cra_driver_name = "ecb-des-talitos",
2706 .cra_blocksize = DES_BLOCK_SIZE,
2707 .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER |
2708 CRYPTO_ALG_ASYNC,
2709 .cra_ablkcipher = {
2710 .min_keysize = DES_KEY_SIZE,
2711 .max_keysize = DES_KEY_SIZE,
2712 .ivsize = DES_BLOCK_SIZE,
2713 }
2714 },
2715 .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
2716 DESC_HDR_SEL0_DEU,
2717 },
2718 { .type = CRYPTO_ALG_TYPE_ABLKCIPHER,
2719 .alg.crypto = {
2720 .cra_name = "cbc(des)",
2721 .cra_driver_name = "cbc-des-talitos",
2722 .cra_blocksize = DES_BLOCK_SIZE,
2723 .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER |
2724 CRYPTO_ALG_ASYNC,
2725 .cra_ablkcipher = {
2726 .min_keysize = DES_KEY_SIZE,
2727 .max_keysize = DES_KEY_SIZE,
2728 .ivsize = DES_BLOCK_SIZE,
2729 }
2730 },
2731 .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
2732 DESC_HDR_SEL0_DEU |
2733 DESC_HDR_MODE0_DEU_CBC,
2734 },
2735 { .type = CRYPTO_ALG_TYPE_ABLKCIPHER,
2736 .alg.crypto = {
2737 .cra_name = "ecb(des3_ede)",
2738 .cra_driver_name = "ecb-3des-talitos",
2739 .cra_blocksize = DES3_EDE_BLOCK_SIZE,
2740 .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER |
2741 CRYPTO_ALG_ASYNC,
2742 .cra_ablkcipher = {
2743 .min_keysize = DES3_EDE_KEY_SIZE,
2744 .max_keysize = DES3_EDE_KEY_SIZE,
2745 .ivsize = DES3_EDE_BLOCK_SIZE,
2746 }
2747 },
2748 .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
2749 DESC_HDR_SEL0_DEU |
2750 DESC_HDR_MODE0_DEU_3DES,
2751 },
2752 { .type = CRYPTO_ALG_TYPE_ABLKCIPHER,
2753 .alg.crypto = {
Lee Nipper4de9d0b2009-03-29 15:52:32 +08002754 .cra_name = "cbc(des3_ede)",
2755 .cra_driver_name = "cbc-3des-talitos",
2756 .cra_blocksize = DES3_EDE_BLOCK_SIZE,
2757 .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER |
2758 CRYPTO_ALG_ASYNC,
Lee Nipper4de9d0b2009-03-29 15:52:32 +08002759 .cra_ablkcipher = {
Lee Nipper4de9d0b2009-03-29 15:52:32 +08002760 .min_keysize = DES3_EDE_KEY_SIZE,
2761 .max_keysize = DES3_EDE_KEY_SIZE,
2762 .ivsize = DES3_EDE_BLOCK_SIZE,
2763 }
2764 },
2765 .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
2766 DESC_HDR_SEL0_DEU |
2767 DESC_HDR_MODE0_DEU_CBC |
2768 DESC_HDR_MODE0_DEU_3DES,
Lee Nipper497f2e62010-05-19 19:20:36 +10002769 },
2770 /* AHASH algorithms. */
2771 { .type = CRYPTO_ALG_TYPE_AHASH,
2772 .alg.hash = {
Lee Nipper497f2e62010-05-19 19:20:36 +10002773 .halg.digestsize = MD5_DIGEST_SIZE,
Horia Geant?3639ca82016-04-21 19:24:55 +03002774 .halg.statesize = sizeof(struct talitos_export_state),
Lee Nipper497f2e62010-05-19 19:20:36 +10002775 .halg.base = {
2776 .cra_name = "md5",
2777 .cra_driver_name = "md5-talitos",
Martin Hicksb3988612015-03-03 08:21:34 -05002778 .cra_blocksize = MD5_HMAC_BLOCK_SIZE,
Lee Nipper497f2e62010-05-19 19:20:36 +10002779 .cra_flags = CRYPTO_ALG_TYPE_AHASH |
2780 CRYPTO_ALG_ASYNC,
Lee Nipper497f2e62010-05-19 19:20:36 +10002781 }
2782 },
2783 .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
2784 DESC_HDR_SEL0_MDEUA |
2785 DESC_HDR_MODE0_MDEU_MD5,
2786 },
2787 { .type = CRYPTO_ALG_TYPE_AHASH,
2788 .alg.hash = {
Lee Nipper497f2e62010-05-19 19:20:36 +10002789 .halg.digestsize = SHA1_DIGEST_SIZE,
Horia Geant?3639ca82016-04-21 19:24:55 +03002790 .halg.statesize = sizeof(struct talitos_export_state),
Lee Nipper497f2e62010-05-19 19:20:36 +10002791 .halg.base = {
2792 .cra_name = "sha1",
2793 .cra_driver_name = "sha1-talitos",
2794 .cra_blocksize = SHA1_BLOCK_SIZE,
2795 .cra_flags = CRYPTO_ALG_TYPE_AHASH |
2796 CRYPTO_ALG_ASYNC,
Lee Nipper497f2e62010-05-19 19:20:36 +10002797 }
2798 },
2799 .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
2800 DESC_HDR_SEL0_MDEUA |
2801 DESC_HDR_MODE0_MDEU_SHA1,
2802 },
2803 { .type = CRYPTO_ALG_TYPE_AHASH,
2804 .alg.hash = {
Kim Phillips60f208d2010-05-19 19:21:53 +10002805 .halg.digestsize = SHA224_DIGEST_SIZE,
Horia Geant?3639ca82016-04-21 19:24:55 +03002806 .halg.statesize = sizeof(struct talitos_export_state),
Kim Phillips60f208d2010-05-19 19:21:53 +10002807 .halg.base = {
2808 .cra_name = "sha224",
2809 .cra_driver_name = "sha224-talitos",
2810 .cra_blocksize = SHA224_BLOCK_SIZE,
2811 .cra_flags = CRYPTO_ALG_TYPE_AHASH |
2812 CRYPTO_ALG_ASYNC,
Kim Phillips60f208d2010-05-19 19:21:53 +10002813 }
2814 },
2815 .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
2816 DESC_HDR_SEL0_MDEUA |
2817 DESC_HDR_MODE0_MDEU_SHA224,
2818 },
2819 { .type = CRYPTO_ALG_TYPE_AHASH,
2820 .alg.hash = {
Lee Nipper497f2e62010-05-19 19:20:36 +10002821 .halg.digestsize = SHA256_DIGEST_SIZE,
Horia Geant?3639ca82016-04-21 19:24:55 +03002822 .halg.statesize = sizeof(struct talitos_export_state),
Lee Nipper497f2e62010-05-19 19:20:36 +10002823 .halg.base = {
2824 .cra_name = "sha256",
2825 .cra_driver_name = "sha256-talitos",
2826 .cra_blocksize = SHA256_BLOCK_SIZE,
2827 .cra_flags = CRYPTO_ALG_TYPE_AHASH |
2828 CRYPTO_ALG_ASYNC,
Lee Nipper497f2e62010-05-19 19:20:36 +10002829 }
2830 },
2831 .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
2832 DESC_HDR_SEL0_MDEUA |
2833 DESC_HDR_MODE0_MDEU_SHA256,
2834 },
2835 { .type = CRYPTO_ALG_TYPE_AHASH,
2836 .alg.hash = {
Lee Nipper497f2e62010-05-19 19:20:36 +10002837 .halg.digestsize = SHA384_DIGEST_SIZE,
Horia Geant?3639ca82016-04-21 19:24:55 +03002838 .halg.statesize = sizeof(struct talitos_export_state),
Lee Nipper497f2e62010-05-19 19:20:36 +10002839 .halg.base = {
2840 .cra_name = "sha384",
2841 .cra_driver_name = "sha384-talitos",
2842 .cra_blocksize = SHA384_BLOCK_SIZE,
2843 .cra_flags = CRYPTO_ALG_TYPE_AHASH |
2844 CRYPTO_ALG_ASYNC,
Lee Nipper497f2e62010-05-19 19:20:36 +10002845 }
2846 },
2847 .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
2848 DESC_HDR_SEL0_MDEUB |
2849 DESC_HDR_MODE0_MDEUB_SHA384,
2850 },
2851 { .type = CRYPTO_ALG_TYPE_AHASH,
2852 .alg.hash = {
Lee Nipper497f2e62010-05-19 19:20:36 +10002853 .halg.digestsize = SHA512_DIGEST_SIZE,
Horia Geant?3639ca82016-04-21 19:24:55 +03002854 .halg.statesize = sizeof(struct talitos_export_state),
Lee Nipper497f2e62010-05-19 19:20:36 +10002855 .halg.base = {
2856 .cra_name = "sha512",
2857 .cra_driver_name = "sha512-talitos",
2858 .cra_blocksize = SHA512_BLOCK_SIZE,
2859 .cra_flags = CRYPTO_ALG_TYPE_AHASH |
2860 CRYPTO_ALG_ASYNC,
Lee Nipper497f2e62010-05-19 19:20:36 +10002861 }
2862 },
2863 .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
2864 DESC_HDR_SEL0_MDEUB |
2865 DESC_HDR_MODE0_MDEUB_SHA512,
2866 },
Lee Nipper79b3a412011-11-21 16:13:25 +08002867 { .type = CRYPTO_ALG_TYPE_AHASH,
2868 .alg.hash = {
Lee Nipper79b3a412011-11-21 16:13:25 +08002869 .halg.digestsize = MD5_DIGEST_SIZE,
Horia Geant?3639ca82016-04-21 19:24:55 +03002870 .halg.statesize = sizeof(struct talitos_export_state),
Lee Nipper79b3a412011-11-21 16:13:25 +08002871 .halg.base = {
2872 .cra_name = "hmac(md5)",
2873 .cra_driver_name = "hmac-md5-talitos",
Martin Hicksb3988612015-03-03 08:21:34 -05002874 .cra_blocksize = MD5_HMAC_BLOCK_SIZE,
Lee Nipper79b3a412011-11-21 16:13:25 +08002875 .cra_flags = CRYPTO_ALG_TYPE_AHASH |
2876 CRYPTO_ALG_ASYNC,
Lee Nipper79b3a412011-11-21 16:13:25 +08002877 }
2878 },
2879 .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
2880 DESC_HDR_SEL0_MDEUA |
2881 DESC_HDR_MODE0_MDEU_MD5,
2882 },
2883 { .type = CRYPTO_ALG_TYPE_AHASH,
2884 .alg.hash = {
Lee Nipper79b3a412011-11-21 16:13:25 +08002885 .halg.digestsize = SHA1_DIGEST_SIZE,
Horia Geant?3639ca82016-04-21 19:24:55 +03002886 .halg.statesize = sizeof(struct talitos_export_state),
Lee Nipper79b3a412011-11-21 16:13:25 +08002887 .halg.base = {
2888 .cra_name = "hmac(sha1)",
2889 .cra_driver_name = "hmac-sha1-talitos",
2890 .cra_blocksize = SHA1_BLOCK_SIZE,
2891 .cra_flags = CRYPTO_ALG_TYPE_AHASH |
2892 CRYPTO_ALG_ASYNC,
Lee Nipper79b3a412011-11-21 16:13:25 +08002893 }
2894 },
2895 .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
2896 DESC_HDR_SEL0_MDEUA |
2897 DESC_HDR_MODE0_MDEU_SHA1,
2898 },
2899 { .type = CRYPTO_ALG_TYPE_AHASH,
2900 .alg.hash = {
Lee Nipper79b3a412011-11-21 16:13:25 +08002901 .halg.digestsize = SHA224_DIGEST_SIZE,
Horia Geant?3639ca82016-04-21 19:24:55 +03002902 .halg.statesize = sizeof(struct talitos_export_state),
Lee Nipper79b3a412011-11-21 16:13:25 +08002903 .halg.base = {
2904 .cra_name = "hmac(sha224)",
2905 .cra_driver_name = "hmac-sha224-talitos",
2906 .cra_blocksize = SHA224_BLOCK_SIZE,
2907 .cra_flags = CRYPTO_ALG_TYPE_AHASH |
2908 CRYPTO_ALG_ASYNC,
Lee Nipper79b3a412011-11-21 16:13:25 +08002909 }
2910 },
2911 .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
2912 DESC_HDR_SEL0_MDEUA |
2913 DESC_HDR_MODE0_MDEU_SHA224,
2914 },
2915 { .type = CRYPTO_ALG_TYPE_AHASH,
2916 .alg.hash = {
Lee Nipper79b3a412011-11-21 16:13:25 +08002917 .halg.digestsize = SHA256_DIGEST_SIZE,
Horia Geant?3639ca82016-04-21 19:24:55 +03002918 .halg.statesize = sizeof(struct talitos_export_state),
Lee Nipper79b3a412011-11-21 16:13:25 +08002919 .halg.base = {
2920 .cra_name = "hmac(sha256)",
2921 .cra_driver_name = "hmac-sha256-talitos",
2922 .cra_blocksize = SHA256_BLOCK_SIZE,
2923 .cra_flags = CRYPTO_ALG_TYPE_AHASH |
2924 CRYPTO_ALG_ASYNC,
Lee Nipper79b3a412011-11-21 16:13:25 +08002925 }
2926 },
2927 .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
2928 DESC_HDR_SEL0_MDEUA |
2929 DESC_HDR_MODE0_MDEU_SHA256,
2930 },
2931 { .type = CRYPTO_ALG_TYPE_AHASH,
2932 .alg.hash = {
Lee Nipper79b3a412011-11-21 16:13:25 +08002933 .halg.digestsize = SHA384_DIGEST_SIZE,
Horia Geant?3639ca82016-04-21 19:24:55 +03002934 .halg.statesize = sizeof(struct talitos_export_state),
Lee Nipper79b3a412011-11-21 16:13:25 +08002935 .halg.base = {
2936 .cra_name = "hmac(sha384)",
2937 .cra_driver_name = "hmac-sha384-talitos",
2938 .cra_blocksize = SHA384_BLOCK_SIZE,
2939 .cra_flags = CRYPTO_ALG_TYPE_AHASH |
2940 CRYPTO_ALG_ASYNC,
Lee Nipper79b3a412011-11-21 16:13:25 +08002941 }
2942 },
2943 .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
2944 DESC_HDR_SEL0_MDEUB |
2945 DESC_HDR_MODE0_MDEUB_SHA384,
2946 },
2947 { .type = CRYPTO_ALG_TYPE_AHASH,
2948 .alg.hash = {
Lee Nipper79b3a412011-11-21 16:13:25 +08002949 .halg.digestsize = SHA512_DIGEST_SIZE,
Horia Geant?3639ca82016-04-21 19:24:55 +03002950 .halg.statesize = sizeof(struct talitos_export_state),
Lee Nipper79b3a412011-11-21 16:13:25 +08002951 .halg.base = {
2952 .cra_name = "hmac(sha512)",
2953 .cra_driver_name = "hmac-sha512-talitos",
2954 .cra_blocksize = SHA512_BLOCK_SIZE,
2955 .cra_flags = CRYPTO_ALG_TYPE_AHASH |
2956 CRYPTO_ALG_ASYNC,
Lee Nipper79b3a412011-11-21 16:13:25 +08002957 }
2958 },
2959 .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
2960 DESC_HDR_SEL0_MDEUB |
2961 DESC_HDR_MODE0_MDEUB_SHA512,
2962 }
Kim Phillips9c4a7962008-06-23 19:50:15 +08002963};
2964
2965struct talitos_crypto_alg {
2966 struct list_head entry;
2967 struct device *dev;
Lee Nipperacbf7c622010-05-19 19:19:33 +10002968 struct talitos_alg_template algt;
Kim Phillips9c4a7962008-06-23 19:50:15 +08002969};
2970
Jonas Eymann89d124c2016-04-19 20:33:47 +03002971static int talitos_init_common(struct talitos_ctx *ctx,
2972 struct talitos_crypto_alg *talitos_alg)
Kim Phillips9c4a7962008-06-23 19:50:15 +08002973{
Kim Phillips5228f0f2011-07-15 11:21:38 +08002974 struct talitos_private *priv;
Kim Phillips9c4a7962008-06-23 19:50:15 +08002975
2976 /* update context with ptr to dev */
2977 ctx->dev = talitos_alg->dev;
Kim Phillips19bbbc62009-03-29 15:53:59 +08002978
Kim Phillips5228f0f2011-07-15 11:21:38 +08002979 /* assign SEC channel to tfm in round-robin fashion */
2980 priv = dev_get_drvdata(ctx->dev);
2981 ctx->ch = atomic_inc_return(&priv->last_chan) &
2982 (priv->num_channels - 1);
2983
Kim Phillips9c4a7962008-06-23 19:50:15 +08002984 /* copy descriptor header template value */
Lee Nipperacbf7c622010-05-19 19:19:33 +10002985 ctx->desc_hdr_template = talitos_alg->algt.desc_hdr_template;
Kim Phillips9c4a7962008-06-23 19:50:15 +08002986
Kim Phillips602dba52011-07-15 11:21:39 +08002987 /* select done notification */
2988 ctx->desc_hdr_template |= DESC_HDR_DONE_NOTIFY;
2989
Lee Nipper497f2e62010-05-19 19:20:36 +10002990 return 0;
2991}
2992
Jonas Eymann89d124c2016-04-19 20:33:47 +03002993static int talitos_cra_init(struct crypto_tfm *tfm)
2994{
2995 struct crypto_alg *alg = tfm->__crt_alg;
2996 struct talitos_crypto_alg *talitos_alg;
2997 struct talitos_ctx *ctx = crypto_tfm_ctx(tfm);
2998
2999 if ((alg->cra_flags & CRYPTO_ALG_TYPE_MASK) == CRYPTO_ALG_TYPE_AHASH)
3000 talitos_alg = container_of(__crypto_ahash_alg(alg),
3001 struct talitos_crypto_alg,
3002 algt.alg.hash);
3003 else
3004 talitos_alg = container_of(alg, struct talitos_crypto_alg,
3005 algt.alg.crypto);
3006
3007 return talitos_init_common(ctx, talitos_alg);
3008}
3009
Herbert Xuaeb4c132015-07-30 17:53:22 +08003010static int talitos_cra_init_aead(struct crypto_aead *tfm)
Lee Nipper497f2e62010-05-19 19:20:36 +10003011{
Jonas Eymann89d124c2016-04-19 20:33:47 +03003012 struct aead_alg *alg = crypto_aead_alg(tfm);
3013 struct talitos_crypto_alg *talitos_alg;
3014 struct talitos_ctx *ctx = crypto_aead_ctx(tfm);
3015
3016 talitos_alg = container_of(alg, struct talitos_crypto_alg,
3017 algt.alg.aead);
3018
3019 return talitos_init_common(ctx, talitos_alg);
Kim Phillips9c4a7962008-06-23 19:50:15 +08003020}
3021
Lee Nipper497f2e62010-05-19 19:20:36 +10003022static int talitos_cra_init_ahash(struct crypto_tfm *tfm)
3023{
3024 struct talitos_ctx *ctx = crypto_tfm_ctx(tfm);
3025
3026 talitos_cra_init(tfm);
3027
3028 ctx->keylen = 0;
3029 crypto_ahash_set_reqsize(__crypto_ahash_cast(tfm),
3030 sizeof(struct talitos_ahash_req_ctx));
3031
3032 return 0;
3033}
3034
LEROY Christophe2e13ce02017-10-06 15:05:02 +02003035static void talitos_cra_exit(struct crypto_tfm *tfm)
3036{
3037 struct talitos_ctx *ctx = crypto_tfm_ctx(tfm);
3038 struct device *dev = ctx->dev;
3039
3040 if (ctx->keylen)
3041 dma_unmap_single(dev, ctx->dma_key, ctx->keylen, DMA_TO_DEVICE);
3042}
3043
Kim Phillips9c4a7962008-06-23 19:50:15 +08003044/*
3045 * given the alg's descriptor header template, determine whether descriptor
3046 * type and primary/secondary execution units required match the hw
3047 * capabilities description provided in the device tree node.
3048 */
3049static int hw_supports(struct device *dev, __be32 desc_hdr_template)
3050{
3051 struct talitos_private *priv = dev_get_drvdata(dev);
3052 int ret;
3053
3054 ret = (1 << DESC_TYPE(desc_hdr_template) & priv->desc_types) &&
3055 (1 << PRIMARY_EU(desc_hdr_template) & priv->exec_units);
3056
3057 if (SECONDARY_EU(desc_hdr_template))
3058 ret = ret && (1 << SECONDARY_EU(desc_hdr_template)
3059 & priv->exec_units);
3060
3061 return ret;
3062}
3063
Grant Likely2dc11582010-08-06 09:25:50 -06003064static int talitos_remove(struct platform_device *ofdev)
Kim Phillips9c4a7962008-06-23 19:50:15 +08003065{
3066 struct device *dev = &ofdev->dev;
3067 struct talitos_private *priv = dev_get_drvdata(dev);
3068 struct talitos_crypto_alg *t_alg, *n;
3069 int i;
3070
3071 list_for_each_entry_safe(t_alg, n, &priv->alg_list, entry) {
Lee Nipperacbf7c622010-05-19 19:19:33 +10003072 switch (t_alg->algt.type) {
3073 case CRYPTO_ALG_TYPE_ABLKCIPHER:
Lee Nipperacbf7c622010-05-19 19:19:33 +10003074 break;
Herbert Xuaeb4c132015-07-30 17:53:22 +08003075 case CRYPTO_ALG_TYPE_AEAD:
3076 crypto_unregister_aead(&t_alg->algt.alg.aead);
Lee Nipperacbf7c622010-05-19 19:19:33 +10003077 case CRYPTO_ALG_TYPE_AHASH:
3078 crypto_unregister_ahash(&t_alg->algt.alg.hash);
3079 break;
3080 }
Kim Phillips9c4a7962008-06-23 19:50:15 +08003081 list_del(&t_alg->entry);
Kim Phillips9c4a7962008-06-23 19:50:15 +08003082 }
3083
3084 if (hw_supports(dev, DESC_HDR_SEL0_RNG))
3085 talitos_unregister_rng(dev);
3086
Kim Phillipsc3e337f2011-11-21 16:13:27 +08003087 for (i = 0; i < 2; i++)
Kim Phillips2cdba3c2011-12-12 14:59:11 -06003088 if (priv->irq[i]) {
Kim Phillipsc3e337f2011-11-21 16:13:27 +08003089 free_irq(priv->irq[i], dev);
3090 irq_dispose_mapping(priv->irq[i]);
3091 }
Kim Phillips9c4a7962008-06-23 19:50:15 +08003092
Kim Phillipsc3e337f2011-11-21 16:13:27 +08003093 tasklet_kill(&priv->done_task[0]);
Kim Phillips2cdba3c2011-12-12 14:59:11 -06003094 if (priv->irq[1])
Kim Phillipsc3e337f2011-11-21 16:13:27 +08003095 tasklet_kill(&priv->done_task[1]);
Kim Phillips9c4a7962008-06-23 19:50:15 +08003096
Kim Phillips9c4a7962008-06-23 19:50:15 +08003097 return 0;
3098}
3099
3100static struct talitos_crypto_alg *talitos_alg_alloc(struct device *dev,
3101 struct talitos_alg_template
3102 *template)
3103{
Kim Phillips60f208d2010-05-19 19:21:53 +10003104 struct talitos_private *priv = dev_get_drvdata(dev);
Kim Phillips9c4a7962008-06-23 19:50:15 +08003105 struct talitos_crypto_alg *t_alg;
3106 struct crypto_alg *alg;
3107
LEROY Christophe24b92ff2017-10-06 15:04:49 +02003108 t_alg = devm_kzalloc(dev, sizeof(struct talitos_crypto_alg),
3109 GFP_KERNEL);
Kim Phillips9c4a7962008-06-23 19:50:15 +08003110 if (!t_alg)
3111 return ERR_PTR(-ENOMEM);
3112
Lee Nipperacbf7c622010-05-19 19:19:33 +10003113 t_alg->algt = *template;
3114
3115 switch (t_alg->algt.type) {
3116 case CRYPTO_ALG_TYPE_ABLKCIPHER:
Lee Nipper497f2e62010-05-19 19:20:36 +10003117 alg = &t_alg->algt.alg.crypto;
3118 alg->cra_init = talitos_cra_init;
LEROY Christophe2e13ce02017-10-06 15:05:02 +02003119 alg->cra_exit = talitos_cra_exit;
Kim Phillipsd4cd3282012-08-08 20:32:00 -05003120 alg->cra_type = &crypto_ablkcipher_type;
Kim Phillipsb286e002012-08-08 20:33:34 -05003121 alg->cra_ablkcipher.setkey = ablkcipher_setkey;
3122 alg->cra_ablkcipher.encrypt = ablkcipher_encrypt;
3123 alg->cra_ablkcipher.decrypt = ablkcipher_decrypt;
3124 alg->cra_ablkcipher.geniv = "eseqiv";
Lee Nipper497f2e62010-05-19 19:20:36 +10003125 break;
Lee Nipperacbf7c622010-05-19 19:19:33 +10003126 case CRYPTO_ALG_TYPE_AEAD:
Herbert Xuaeb4c132015-07-30 17:53:22 +08003127 alg = &t_alg->algt.alg.aead.base;
LEROY Christophe2e13ce02017-10-06 15:05:02 +02003128 alg->cra_exit = talitos_cra_exit;
Herbert Xuaeb4c132015-07-30 17:53:22 +08003129 t_alg->algt.alg.aead.init = talitos_cra_init_aead;
3130 t_alg->algt.alg.aead.setkey = aead_setkey;
3131 t_alg->algt.alg.aead.encrypt = aead_encrypt;
3132 t_alg->algt.alg.aead.decrypt = aead_decrypt;
LEROY Christophe6cda0752017-10-06 15:04:39 +02003133 if (!(priv->features & TALITOS_FTR_SHA224_HWINIT) &&
3134 !strncmp(alg->cra_name, "authenc(hmac(sha224)", 20)) {
LEROY Christophe24b92ff2017-10-06 15:04:49 +02003135 devm_kfree(dev, t_alg);
LEROY Christophe6cda0752017-10-06 15:04:39 +02003136 return ERR_PTR(-ENOTSUPP);
3137 }
Lee Nipperacbf7c622010-05-19 19:19:33 +10003138 break;
3139 case CRYPTO_ALG_TYPE_AHASH:
3140 alg = &t_alg->algt.alg.hash.halg.base;
Lee Nipper497f2e62010-05-19 19:20:36 +10003141 alg->cra_init = talitos_cra_init_ahash;
LEROY Christophead4cd512018-02-26 17:40:04 +01003142 alg->cra_exit = talitos_cra_exit;
Kim Phillipsd4cd3282012-08-08 20:32:00 -05003143 alg->cra_type = &crypto_ahash_type;
Kim Phillipsb286e002012-08-08 20:33:34 -05003144 t_alg->algt.alg.hash.init = ahash_init;
3145 t_alg->algt.alg.hash.update = ahash_update;
3146 t_alg->algt.alg.hash.final = ahash_final;
3147 t_alg->algt.alg.hash.finup = ahash_finup;
3148 t_alg->algt.alg.hash.digest = ahash_digest;
LEROY Christophe56136632017-09-12 11:03:39 +02003149 if (!strncmp(alg->cra_name, "hmac", 4))
3150 t_alg->algt.alg.hash.setkey = ahash_setkey;
Horia Geant?3639ca82016-04-21 19:24:55 +03003151 t_alg->algt.alg.hash.import = ahash_import;
3152 t_alg->algt.alg.hash.export = ahash_export;
Kim Phillipsb286e002012-08-08 20:33:34 -05003153
Lee Nipper79b3a412011-11-21 16:13:25 +08003154 if (!(priv->features & TALITOS_FTR_HMAC_OK) &&
Kim Phillips0b2730d2011-12-12 14:59:10 -06003155 !strncmp(alg->cra_name, "hmac", 4)) {
LEROY Christophe24b92ff2017-10-06 15:04:49 +02003156 devm_kfree(dev, t_alg);
Lee Nipper79b3a412011-11-21 16:13:25 +08003157 return ERR_PTR(-ENOTSUPP);
Kim Phillips0b2730d2011-12-12 14:59:10 -06003158 }
Kim Phillips60f208d2010-05-19 19:21:53 +10003159 if (!(priv->features & TALITOS_FTR_SHA224_HWINIT) &&
Lee Nipper79b3a412011-11-21 16:13:25 +08003160 (!strcmp(alg->cra_name, "sha224") ||
3161 !strcmp(alg->cra_name, "hmac(sha224)"))) {
Kim Phillips60f208d2010-05-19 19:21:53 +10003162 t_alg->algt.alg.hash.init = ahash_init_sha224_swinit;
3163 t_alg->algt.desc_hdr_template =
3164 DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
3165 DESC_HDR_SEL0_MDEUA |
3166 DESC_HDR_MODE0_MDEU_SHA256;
3167 }
Lee Nipper497f2e62010-05-19 19:20:36 +10003168 break;
Kim Phillips1d119112010-09-23 15:55:27 +08003169 default:
3170 dev_err(dev, "unknown algorithm type %d\n", t_alg->algt.type);
LEROY Christophe24b92ff2017-10-06 15:04:49 +02003171 devm_kfree(dev, t_alg);
Kim Phillips1d119112010-09-23 15:55:27 +08003172 return ERR_PTR(-EINVAL);
Lee Nipperacbf7c622010-05-19 19:19:33 +10003173 }
Kim Phillips9c4a7962008-06-23 19:50:15 +08003174
Kim Phillips9c4a7962008-06-23 19:50:15 +08003175 alg->cra_module = THIS_MODULE;
LEROY Christopheb0057762016-06-06 13:20:44 +02003176 if (t_alg->algt.priority)
3177 alg->cra_priority = t_alg->algt.priority;
3178 else
3179 alg->cra_priority = TALITOS_CRA_PRIORITY;
Kim Phillips9c4a7962008-06-23 19:50:15 +08003180 alg->cra_alignmask = 0;
Kim Phillips9c4a7962008-06-23 19:50:15 +08003181 alg->cra_ctxsize = sizeof(struct talitos_ctx);
Nikos Mavrogiannopoulosd912bb72011-11-01 13:39:56 +01003182 alg->cra_flags |= CRYPTO_ALG_KERN_DRIVER_ONLY;
Kim Phillips9c4a7962008-06-23 19:50:15 +08003183
Kim Phillips9c4a7962008-06-23 19:50:15 +08003184 t_alg->dev = dev;
3185
3186 return t_alg;
3187}
3188
Kim Phillipsc3e337f2011-11-21 16:13:27 +08003189static int talitos_probe_irq(struct platform_device *ofdev)
3190{
3191 struct device *dev = &ofdev->dev;
3192 struct device_node *np = ofdev->dev.of_node;
3193 struct talitos_private *priv = dev_get_drvdata(dev);
3194 int err;
LEROY Christophedd3c0982015-04-17 16:32:13 +02003195 bool is_sec1 = has_ftr_sec1(priv);
Kim Phillipsc3e337f2011-11-21 16:13:27 +08003196
3197 priv->irq[0] = irq_of_parse_and_map(np, 0);
Kim Phillips2cdba3c2011-12-12 14:59:11 -06003198 if (!priv->irq[0]) {
Kim Phillipsc3e337f2011-11-21 16:13:27 +08003199 dev_err(dev, "failed to map irq\n");
3200 return -EINVAL;
3201 }
LEROY Christophedd3c0982015-04-17 16:32:13 +02003202 if (is_sec1) {
3203 err = request_irq(priv->irq[0], talitos1_interrupt_4ch, 0,
3204 dev_driver_string(dev), dev);
3205 goto primary_out;
3206 }
Kim Phillipsc3e337f2011-11-21 16:13:27 +08003207
3208 priv->irq[1] = irq_of_parse_and_map(np, 1);
3209
3210 /* get the primary irq line */
Kim Phillips2cdba3c2011-12-12 14:59:11 -06003211 if (!priv->irq[1]) {
LEROY Christophedd3c0982015-04-17 16:32:13 +02003212 err = request_irq(priv->irq[0], talitos2_interrupt_4ch, 0,
Kim Phillipsc3e337f2011-11-21 16:13:27 +08003213 dev_driver_string(dev), dev);
3214 goto primary_out;
3215 }
3216
LEROY Christophedd3c0982015-04-17 16:32:13 +02003217 err = request_irq(priv->irq[0], talitos2_interrupt_ch0_2, 0,
Kim Phillipsc3e337f2011-11-21 16:13:27 +08003218 dev_driver_string(dev), dev);
3219 if (err)
3220 goto primary_out;
3221
3222 /* get the secondary irq line */
LEROY Christophedd3c0982015-04-17 16:32:13 +02003223 err = request_irq(priv->irq[1], talitos2_interrupt_ch1_3, 0,
Kim Phillipsc3e337f2011-11-21 16:13:27 +08003224 dev_driver_string(dev), dev);
3225 if (err) {
3226 dev_err(dev, "failed to request secondary irq\n");
3227 irq_dispose_mapping(priv->irq[1]);
Kim Phillips2cdba3c2011-12-12 14:59:11 -06003228 priv->irq[1] = 0;
Kim Phillipsc3e337f2011-11-21 16:13:27 +08003229 }
3230
3231 return err;
3232
3233primary_out:
3234 if (err) {
3235 dev_err(dev, "failed to request primary irq\n");
3236 irq_dispose_mapping(priv->irq[0]);
Kim Phillips2cdba3c2011-12-12 14:59:11 -06003237 priv->irq[0] = 0;
Kim Phillipsc3e337f2011-11-21 16:13:27 +08003238 }
3239
3240 return err;
3241}
3242
Grant Likely1c48a5c2011-02-17 02:43:24 -07003243static int talitos_probe(struct platform_device *ofdev)
Kim Phillips9c4a7962008-06-23 19:50:15 +08003244{
3245 struct device *dev = &ofdev->dev;
Grant Likely61c7a082010-04-13 16:12:29 -07003246 struct device_node *np = ofdev->dev.of_node;
Kim Phillips9c4a7962008-06-23 19:50:15 +08003247 struct talitos_private *priv;
Kim Phillips9c4a7962008-06-23 19:50:15 +08003248 int i, err;
LEROY Christophe5fa7fa12015-04-17 16:32:11 +02003249 int stride;
LEROY Christophefd5ea7f2017-10-06 15:04:53 +02003250 struct resource *res;
Kim Phillips9c4a7962008-06-23 19:50:15 +08003251
LEROY Christophe24b92ff2017-10-06 15:04:49 +02003252 priv = devm_kzalloc(dev, sizeof(struct talitos_private), GFP_KERNEL);
Kim Phillips9c4a7962008-06-23 19:50:15 +08003253 if (!priv)
3254 return -ENOMEM;
3255
Kevin Haof3de9cb2014-01-28 20:17:23 +08003256 INIT_LIST_HEAD(&priv->alg_list);
3257
Kim Phillips9c4a7962008-06-23 19:50:15 +08003258 dev_set_drvdata(dev, priv);
3259
3260 priv->ofdev = ofdev;
3261
Horia Geanta511d63c2012-03-30 17:49:53 +03003262 spin_lock_init(&priv->reg_lock);
3263
LEROY Christophefd5ea7f2017-10-06 15:04:53 +02003264 res = platform_get_resource(ofdev, IORESOURCE_MEM, 0);
3265 if (!res)
3266 return -ENXIO;
3267 priv->reg = devm_ioremap(dev, res->start, resource_size(res));
Kim Phillips9c4a7962008-06-23 19:50:15 +08003268 if (!priv->reg) {
3269 dev_err(dev, "failed to of_iomap\n");
3270 err = -ENOMEM;
3271 goto err_out;
3272 }
3273
3274 /* get SEC version capabilities from device tree */
LEROY Christophefa14c6c2017-10-06 15:04:51 +02003275 of_property_read_u32(np, "fsl,num-channels", &priv->num_channels);
3276 of_property_read_u32(np, "fsl,channel-fifo-len", &priv->chfifo_len);
3277 of_property_read_u32(np, "fsl,exec-units-mask", &priv->exec_units);
3278 of_property_read_u32(np, "fsl,descriptor-types-mask",
3279 &priv->desc_types);
Kim Phillips9c4a7962008-06-23 19:50:15 +08003280
3281 if (!is_power_of_2(priv->num_channels) || !priv->chfifo_len ||
3282 !priv->exec_units || !priv->desc_types) {
3283 dev_err(dev, "invalid property data in device tree node\n");
3284 err = -EINVAL;
3285 goto err_out;
3286 }
3287
Lee Nipperf3c85bc2008-07-30 16:26:57 +08003288 if (of_device_is_compatible(np, "fsl,sec3.0"))
3289 priv->features |= TALITOS_FTR_SRC_LINK_TBL_LEN_INCLUDES_EXTENT;
3290
Kim Phillipsfe5720e2008-10-12 20:33:14 +08003291 if (of_device_is_compatible(np, "fsl,sec2.1"))
Kim Phillips60f208d2010-05-19 19:21:53 +10003292 priv->features |= TALITOS_FTR_HW_AUTH_CHECK |
Lee Nipper79b3a412011-11-21 16:13:25 +08003293 TALITOS_FTR_SHA224_HWINIT |
3294 TALITOS_FTR_HMAC_OK;
Kim Phillipsfe5720e2008-10-12 20:33:14 +08003295
LEROY Christophe21590882015-04-17 16:32:05 +02003296 if (of_device_is_compatible(np, "fsl,sec1.0"))
3297 priv->features |= TALITOS_FTR_SEC1;
3298
LEROY Christophe5fa7fa12015-04-17 16:32:11 +02003299 if (of_device_is_compatible(np, "fsl,sec1.2")) {
3300 priv->reg_deu = priv->reg + TALITOS12_DEU;
3301 priv->reg_aesu = priv->reg + TALITOS12_AESU;
3302 priv->reg_mdeu = priv->reg + TALITOS12_MDEU;
3303 stride = TALITOS1_CH_STRIDE;
3304 } else if (of_device_is_compatible(np, "fsl,sec1.0")) {
3305 priv->reg_deu = priv->reg + TALITOS10_DEU;
3306 priv->reg_aesu = priv->reg + TALITOS10_AESU;
3307 priv->reg_mdeu = priv->reg + TALITOS10_MDEU;
3308 priv->reg_afeu = priv->reg + TALITOS10_AFEU;
3309 priv->reg_rngu = priv->reg + TALITOS10_RNGU;
3310 priv->reg_pkeu = priv->reg + TALITOS10_PKEU;
3311 stride = TALITOS1_CH_STRIDE;
3312 } else {
3313 priv->reg_deu = priv->reg + TALITOS2_DEU;
3314 priv->reg_aesu = priv->reg + TALITOS2_AESU;
3315 priv->reg_mdeu = priv->reg + TALITOS2_MDEU;
3316 priv->reg_afeu = priv->reg + TALITOS2_AFEU;
3317 priv->reg_rngu = priv->reg + TALITOS2_RNGU;
3318 priv->reg_pkeu = priv->reg + TALITOS2_PKEU;
3319 priv->reg_keu = priv->reg + TALITOS2_KEU;
3320 priv->reg_crcu = priv->reg + TALITOS2_CRCU;
3321 stride = TALITOS2_CH_STRIDE;
3322 }
3323
LEROY Christophedd3c0982015-04-17 16:32:13 +02003324 err = talitos_probe_irq(ofdev);
3325 if (err)
3326 goto err_out;
3327
3328 if (of_device_is_compatible(np, "fsl,sec1.0")) {
LEROY Christophe9c02e282017-10-06 15:04:55 +02003329 if (priv->num_channels == 1)
3330 tasklet_init(&priv->done_task[0], talitos1_done_ch0,
LEROY Christophedd3c0982015-04-17 16:32:13 +02003331 (unsigned long)dev);
LEROY Christophe9c02e282017-10-06 15:04:55 +02003332 else
3333 tasklet_init(&priv->done_task[0], talitos1_done_4ch,
3334 (unsigned long)dev);
3335 } else {
3336 if (priv->irq[1]) {
LEROY Christophedd3c0982015-04-17 16:32:13 +02003337 tasklet_init(&priv->done_task[0], talitos2_done_ch0_2,
3338 (unsigned long)dev);
3339 tasklet_init(&priv->done_task[1], talitos2_done_ch1_3,
3340 (unsigned long)dev);
LEROY Christophe9c02e282017-10-06 15:04:55 +02003341 } else if (priv->num_channels == 1) {
3342 tasklet_init(&priv->done_task[0], talitos2_done_ch0,
3343 (unsigned long)dev);
3344 } else {
3345 tasklet_init(&priv->done_task[0], talitos2_done_4ch,
3346 (unsigned long)dev);
LEROY Christophedd3c0982015-04-17 16:32:13 +02003347 }
3348 }
3349
LEROY Christophe24b92ff2017-10-06 15:04:49 +02003350 priv->chan = devm_kzalloc(dev, sizeof(struct talitos_channel) *
3351 priv->num_channels, GFP_KERNEL);
Kim Phillips4b9926282009-08-13 11:50:38 +10003352 if (!priv->chan) {
3353 dev_err(dev, "failed to allocate channel management space\n");
Kim Phillips9c4a7962008-06-23 19:50:15 +08003354 err = -ENOMEM;
3355 goto err_out;
3356 }
3357
Martin Hicksf641ddd2015-03-03 08:21:33 -05003358 priv->fifo_len = roundup_pow_of_two(priv->chfifo_len);
3359
Kim Phillipsc3e337f2011-11-21 16:13:27 +08003360 for (i = 0; i < priv->num_channels; i++) {
LEROY Christophe5fa7fa12015-04-17 16:32:11 +02003361 priv->chan[i].reg = priv->reg + stride * (i + 1);
Kim Phillips2cdba3c2011-12-12 14:59:11 -06003362 if (!priv->irq[1] || !(i & 1))
Kim Phillipsc3e337f2011-11-21 16:13:27 +08003363 priv->chan[i].reg += TALITOS_CH_BASE_OFFSET;
Kim Phillipsad42d5f2011-11-21 16:13:27 +08003364
Kim Phillips4b9926282009-08-13 11:50:38 +10003365 spin_lock_init(&priv->chan[i].head_lock);
3366 spin_lock_init(&priv->chan[i].tail_lock);
Kim Phillips9c4a7962008-06-23 19:50:15 +08003367
LEROY Christophe24b92ff2017-10-06 15:04:49 +02003368 priv->chan[i].fifo = devm_kzalloc(dev,
3369 sizeof(struct talitos_request) *
3370 priv->fifo_len, GFP_KERNEL);
Kim Phillips4b9926282009-08-13 11:50:38 +10003371 if (!priv->chan[i].fifo) {
Kim Phillips9c4a7962008-06-23 19:50:15 +08003372 dev_err(dev, "failed to allocate request fifo %d\n", i);
3373 err = -ENOMEM;
3374 goto err_out;
3375 }
Kim Phillips9c4a7962008-06-23 19:50:15 +08003376
Kim Phillips4b9926282009-08-13 11:50:38 +10003377 atomic_set(&priv->chan[i].submit_count,
3378 -(priv->chfifo_len - 1));
Martin Hicksf641ddd2015-03-03 08:21:33 -05003379 }
Kim Phillips9c4a7962008-06-23 19:50:15 +08003380
Kim Phillips81eb0242009-08-13 11:51:51 +10003381 dma_set_mask(dev, DMA_BIT_MASK(36));
3382
Kim Phillips9c4a7962008-06-23 19:50:15 +08003383 /* reset and initialize the h/w */
3384 err = init_device(dev);
3385 if (err) {
3386 dev_err(dev, "failed to initialize device\n");
3387 goto err_out;
3388 }
3389
3390 /* register the RNG, if available */
3391 if (hw_supports(dev, DESC_HDR_SEL0_RNG)) {
3392 err = talitos_register_rng(dev);
3393 if (err) {
3394 dev_err(dev, "failed to register hwrng: %d\n", err);
3395 goto err_out;
3396 } else
3397 dev_info(dev, "hwrng\n");
3398 }
3399
3400 /* register crypto algorithms the device supports */
Kim Phillips9c4a7962008-06-23 19:50:15 +08003401 for (i = 0; i < ARRAY_SIZE(driver_algs); i++) {
3402 if (hw_supports(dev, driver_algs[i].desc_hdr_template)) {
3403 struct talitos_crypto_alg *t_alg;
Herbert Xuaeb4c132015-07-30 17:53:22 +08003404 struct crypto_alg *alg = NULL;
Kim Phillips9c4a7962008-06-23 19:50:15 +08003405
3406 t_alg = talitos_alg_alloc(dev, &driver_algs[i]);
3407 if (IS_ERR(t_alg)) {
3408 err = PTR_ERR(t_alg);
Kim Phillips0b2730d2011-12-12 14:59:10 -06003409 if (err == -ENOTSUPP)
Lee Nipper79b3a412011-11-21 16:13:25 +08003410 continue;
Kim Phillips9c4a7962008-06-23 19:50:15 +08003411 goto err_out;
3412 }
3413
Lee Nipperacbf7c622010-05-19 19:19:33 +10003414 switch (t_alg->algt.type) {
3415 case CRYPTO_ALG_TYPE_ABLKCIPHER:
Lee Nipperacbf7c622010-05-19 19:19:33 +10003416 err = crypto_register_alg(
3417 &t_alg->algt.alg.crypto);
Herbert Xuaeb4c132015-07-30 17:53:22 +08003418 alg = &t_alg->algt.alg.crypto;
Lee Nipperacbf7c622010-05-19 19:19:33 +10003419 break;
Herbert Xuaeb4c132015-07-30 17:53:22 +08003420
3421 case CRYPTO_ALG_TYPE_AEAD:
3422 err = crypto_register_aead(
3423 &t_alg->algt.alg.aead);
3424 alg = &t_alg->algt.alg.aead.base;
3425 break;
3426
Lee Nipperacbf7c622010-05-19 19:19:33 +10003427 case CRYPTO_ALG_TYPE_AHASH:
3428 err = crypto_register_ahash(
3429 &t_alg->algt.alg.hash);
Herbert Xuaeb4c132015-07-30 17:53:22 +08003430 alg = &t_alg->algt.alg.hash.halg.base;
Lee Nipperacbf7c622010-05-19 19:19:33 +10003431 break;
3432 }
Kim Phillips9c4a7962008-06-23 19:50:15 +08003433 if (err) {
3434 dev_err(dev, "%s alg registration failed\n",
Herbert Xuaeb4c132015-07-30 17:53:22 +08003435 alg->cra_driver_name);
LEROY Christophe24b92ff2017-10-06 15:04:49 +02003436 devm_kfree(dev, t_alg);
Horia Geanta991155b2013-03-20 16:31:38 +02003437 } else
Kim Phillips9c4a7962008-06-23 19:50:15 +08003438 list_add_tail(&t_alg->entry, &priv->alg_list);
Kim Phillips9c4a7962008-06-23 19:50:15 +08003439 }
3440 }
Kim Phillips5b859b6e2011-11-21 16:13:26 +08003441 if (!list_empty(&priv->alg_list))
3442 dev_info(dev, "%s algorithms registered in /proc/crypto\n",
3443 (char *)of_get_property(np, "compatible", NULL));
Kim Phillips9c4a7962008-06-23 19:50:15 +08003444
3445 return 0;
3446
3447err_out:
3448 talitos_remove(ofdev);
Kim Phillips9c4a7962008-06-23 19:50:15 +08003449
3450 return err;
3451}
3452
Márton Németh6c3f9752010-01-17 21:54:01 +11003453static const struct of_device_id talitos_match[] = {
LEROY Christophe0635b7db2015-04-17 16:32:20 +02003454#ifdef CONFIG_CRYPTO_DEV_TALITOS1
3455 {
3456 .compatible = "fsl,sec1.0",
3457 },
3458#endif
3459#ifdef CONFIG_CRYPTO_DEV_TALITOS2
Kim Phillips9c4a7962008-06-23 19:50:15 +08003460 {
3461 .compatible = "fsl,sec2.0",
3462 },
LEROY Christophe0635b7db2015-04-17 16:32:20 +02003463#endif
Kim Phillips9c4a7962008-06-23 19:50:15 +08003464 {},
3465};
3466MODULE_DEVICE_TABLE(of, talitos_match);
3467
Grant Likely1c48a5c2011-02-17 02:43:24 -07003468static struct platform_driver talitos_driver = {
Grant Likely40182942010-04-13 16:13:02 -07003469 .driver = {
3470 .name = "talitos",
Grant Likely40182942010-04-13 16:13:02 -07003471 .of_match_table = talitos_match,
3472 },
Kim Phillips9c4a7962008-06-23 19:50:15 +08003473 .probe = talitos_probe,
Al Viro596f1032008-11-22 17:34:24 +00003474 .remove = talitos_remove,
Kim Phillips9c4a7962008-06-23 19:50:15 +08003475};
3476
Axel Lin741e8c22011-11-26 21:26:19 +08003477module_platform_driver(talitos_driver);
Kim Phillips9c4a7962008-06-23 19:50:15 +08003478
3479MODULE_LICENSE("GPL");
3480MODULE_AUTHOR("Kim Phillips <kim.phillips@freescale.com>");
3481MODULE_DESCRIPTION("Freescale integrated security engine (SEC) driver");