blob: fbc7bf9d73807aa062dbf6ff0cf255aa641c9a61 [file] [log] [blame]
Thomas Gleixner1a59d1b82019-05-27 08:55:05 +02001// SPDX-License-Identifier: GPL-2.0-or-later
Kim Phillips9c4a7962008-06-23 19:50:15 +08002/*
3 * talitos - Freescale Integrated Security Engine (SEC) device driver
4 *
Kim Phillips5228f0f2011-07-15 11:21:38 +08005 * Copyright (c) 2008-2011 Freescale Semiconductor, Inc.
Kim Phillips9c4a7962008-06-23 19:50:15 +08006 *
7 * Scatterlist Crypto API glue code copied from files with the following:
8 * Copyright (c) 2006-2007 Herbert Xu <herbert@gondor.apana.org.au>
9 *
10 * Crypto algorithm registration code copied from hifn driver:
11 * 2007+ Copyright (c) Evgeniy Polyakov <johnpol@2ka.mipt.ru>
12 * All rights reserved.
Kim Phillips9c4a7962008-06-23 19:50:15 +080013 */
14
15#include <linux/kernel.h>
16#include <linux/module.h>
17#include <linux/mod_devicetable.h>
18#include <linux/device.h>
19#include <linux/interrupt.h>
20#include <linux/crypto.h>
21#include <linux/hw_random.h>
Rob Herring5af50732013-09-17 14:28:33 -050022#include <linux/of_address.h>
23#include <linux/of_irq.h>
Kim Phillips9c4a7962008-06-23 19:50:15 +080024#include <linux/of_platform.h>
25#include <linux/dma-mapping.h>
26#include <linux/io.h>
27#include <linux/spinlock.h>
28#include <linux/rtnetlink.h>
Tejun Heo5a0e3ad2010-03-24 17:04:11 +090029#include <linux/slab.h>
Kim Phillips9c4a7962008-06-23 19:50:15 +080030
31#include <crypto/algapi.h>
32#include <crypto/aes.h>
Lee Nipper3952f172008-07-10 18:29:18 +080033#include <crypto/des.h>
Kim Phillips9c4a7962008-06-23 19:50:15 +080034#include <crypto/sha.h>
Lee Nipper497f2e62010-05-19 19:20:36 +100035#include <crypto/md5.h>
Herbert Xue98014a2015-05-11 17:47:48 +080036#include <crypto/internal/aead.h>
Kim Phillips9c4a7962008-06-23 19:50:15 +080037#include <crypto/authenc.h>
Lee Nipper4de9d0b2009-03-29 15:52:32 +080038#include <crypto/skcipher.h>
Lee Nipperacbf7c622010-05-19 19:19:33 +100039#include <crypto/hash.h>
40#include <crypto/internal/hash.h>
Lee Nipper4de9d0b2009-03-29 15:52:32 +080041#include <crypto/scatterwalk.h>
Kim Phillips9c4a7962008-06-23 19:50:15 +080042
43#include "talitos.h"
44
LEROY Christophe922f9dc2015-04-17 16:32:07 +020045static void to_talitos_ptr(struct talitos_ptr *ptr, dma_addr_t dma_addr,
LEROY Christopheda9de142017-10-06 15:04:57 +020046 unsigned int len, bool is_sec1)
Kim Phillips81eb0242009-08-13 11:51:51 +100047{
LEROY Christopheedc6bd692015-04-17 16:31:53 +020048 ptr->ptr = cpu_to_be32(lower_32_bits(dma_addr));
LEROY Christopheda9de142017-10-06 15:04:57 +020049 if (is_sec1) {
50 ptr->len1 = cpu_to_be16(len);
51 } else {
52 ptr->len = cpu_to_be16(len);
LEROY Christophe922f9dc2015-04-17 16:32:07 +020053 ptr->eptr = upper_32_bits(dma_addr);
LEROY Christopheda9de142017-10-06 15:04:57 +020054 }
Kim Phillips81eb0242009-08-13 11:51:51 +100055}
56
Horia Geant?340ff602016-04-19 20:33:48 +030057static void copy_talitos_ptr(struct talitos_ptr *dst_ptr,
58 struct talitos_ptr *src_ptr, bool is_sec1)
59{
60 dst_ptr->ptr = src_ptr->ptr;
LEROY Christophe922f9dc2015-04-17 16:32:07 +020061 if (is_sec1) {
LEROY Christopheda9de142017-10-06 15:04:57 +020062 dst_ptr->len1 = src_ptr->len1;
LEROY Christophe922f9dc2015-04-17 16:32:07 +020063 } else {
LEROY Christopheda9de142017-10-06 15:04:57 +020064 dst_ptr->len = src_ptr->len;
65 dst_ptr->eptr = src_ptr->eptr;
LEROY Christophe922f9dc2015-04-17 16:32:07 +020066 }
LEROY Christophe538caf82015-04-17 16:31:59 +020067}
68
LEROY Christophe922f9dc2015-04-17 16:32:07 +020069static unsigned short from_talitos_ptr_len(struct talitos_ptr *ptr,
70 bool is_sec1)
LEROY Christophe538caf82015-04-17 16:31:59 +020071{
LEROY Christophe922f9dc2015-04-17 16:32:07 +020072 if (is_sec1)
73 return be16_to_cpu(ptr->len1);
74 else
75 return be16_to_cpu(ptr->len);
LEROY Christophe538caf82015-04-17 16:31:59 +020076}
77
LEROY Christopheb096b542016-06-06 13:20:34 +020078static void to_talitos_ptr_ext_set(struct talitos_ptr *ptr, u8 val,
79 bool is_sec1)
LEROY Christophe185eb792015-04-17 16:31:55 +020080{
LEROY Christophe922f9dc2015-04-17 16:32:07 +020081 if (!is_sec1)
LEROY Christopheb096b542016-06-06 13:20:34 +020082 ptr->j_extent = val;
83}
84
85static void to_talitos_ptr_ext_or(struct talitos_ptr *ptr, u8 val, bool is_sec1)
86{
87 if (!is_sec1)
88 ptr->j_extent |= val;
LEROY Christophe185eb792015-04-17 16:31:55 +020089}
90
Kim Phillips9c4a7962008-06-23 19:50:15 +080091/*
92 * map virtual single (contiguous) pointer to h/w descriptor pointer
93 */
LEROY Christophe6a4967c2018-02-26 17:40:06 +010094static void __map_single_talitos_ptr(struct device *dev,
95 struct talitos_ptr *ptr,
96 unsigned int len, void *data,
97 enum dma_data_direction dir,
98 unsigned long attrs)
99{
100 dma_addr_t dma_addr = dma_map_single_attrs(dev, data, len, dir, attrs);
101 struct talitos_private *priv = dev_get_drvdata(dev);
102 bool is_sec1 = has_ftr_sec1(priv);
103
104 to_talitos_ptr(ptr, dma_addr, len, is_sec1);
105}
106
Kim Phillips9c4a7962008-06-23 19:50:15 +0800107static void map_single_talitos_ptr(struct device *dev,
LEROY Christopheedc6bd692015-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{
LEROY Christophe6a4967c2018-02-26 17:40:06 +0100112 __map_single_talitos_ptr(dev, ptr, len, data, dir, 0);
113}
Kim Phillips81eb0242009-08-13 11:51:51 +1000114
LEROY Christophe6a4967c2018-02-26 17:40:06 +0100115static void map_single_talitos_ptr_nosync(struct device *dev,
116 struct talitos_ptr *ptr,
117 unsigned int len, void *data,
118 enum dma_data_direction dir)
119{
120 __map_single_talitos_ptr(dev, ptr, len, data, dir,
121 DMA_ATTR_SKIP_CPU_SYNC);
Kim Phillips9c4a7962008-06-23 19:50:15 +0800122}
123
124/*
125 * unmap bus single (contiguous) h/w descriptor pointer
126 */
127static void unmap_single_talitos_ptr(struct device *dev,
LEROY Christopheedc6bd692015-04-17 16:31:53 +0200128 struct talitos_ptr *ptr,
Kim Phillips9c4a7962008-06-23 19:50:15 +0800129 enum dma_data_direction dir)
130{
LEROY Christophe922f9dc2015-04-17 16:32:07 +0200131 struct talitos_private *priv = dev_get_drvdata(dev);
132 bool is_sec1 = has_ftr_sec1(priv);
133
LEROY Christopheedc6bd692015-04-17 16:31:53 +0200134 dma_unmap_single(dev, be32_to_cpu(ptr->ptr),
LEROY Christophe922f9dc2015-04-17 16:32:07 +0200135 from_talitos_ptr_len(ptr, is_sec1), dir);
Kim Phillips9c4a7962008-06-23 19:50:15 +0800136}
137
138static int reset_channel(struct device *dev, int ch)
139{
140 struct talitos_private *priv = dev_get_drvdata(dev);
141 unsigned int timeout = TALITOS_TIMEOUT;
LEROY Christophedd3c0982015-04-17 16:32:13 +0200142 bool is_sec1 = has_ftr_sec1(priv);
Kim Phillips9c4a7962008-06-23 19:50:15 +0800143
LEROY Christophedd3c0982015-04-17 16:32:13 +0200144 if (is_sec1) {
145 setbits32(priv->chan[ch].reg + TALITOS_CCCR_LO,
146 TALITOS1_CCCR_LO_RESET);
Kim Phillips9c4a7962008-06-23 19:50:15 +0800147
LEROY Christophedd3c0982015-04-17 16:32:13 +0200148 while ((in_be32(priv->chan[ch].reg + TALITOS_CCCR_LO) &
149 TALITOS1_CCCR_LO_RESET) && --timeout)
150 cpu_relax();
151 } else {
152 setbits32(priv->chan[ch].reg + TALITOS_CCCR,
153 TALITOS2_CCCR_RESET);
154
155 while ((in_be32(priv->chan[ch].reg + TALITOS_CCCR) &
156 TALITOS2_CCCR_RESET) && --timeout)
157 cpu_relax();
158 }
Kim Phillips9c4a7962008-06-23 19:50:15 +0800159
160 if (timeout == 0) {
161 dev_err(dev, "failed to reset channel %d\n", ch);
162 return -EIO;
163 }
164
Kim Phillips81eb0242009-08-13 11:51:51 +1000165 /* set 36-bit addressing, done writeback enable and done IRQ enable */
Kim Phillipsad42d5f2011-11-21 16:13:27 +0800166 setbits32(priv->chan[ch].reg + TALITOS_CCCR_LO, TALITOS_CCCR_LO_EAE |
Kim Phillips81eb0242009-08-13 11:51:51 +1000167 TALITOS_CCCR_LO_CDWE | TALITOS_CCCR_LO_CDIE);
LEROY Christophe37b5e882017-10-06 15:05:06 +0200168 /* enable chaining descriptors */
169 if (is_sec1)
170 setbits32(priv->chan[ch].reg + TALITOS_CCCR_LO,
171 TALITOS_CCCR_LO_NE);
Kim Phillips9c4a7962008-06-23 19:50:15 +0800172
Kim Phillipsfe5720e2008-10-12 20:33:14 +0800173 /* and ICCR writeback, if available */
174 if (priv->features & TALITOS_FTR_HW_AUTH_CHECK)
Kim Phillipsad42d5f2011-11-21 16:13:27 +0800175 setbits32(priv->chan[ch].reg + TALITOS_CCCR_LO,
Kim Phillipsfe5720e2008-10-12 20:33:14 +0800176 TALITOS_CCCR_LO_IWSE);
177
Kim Phillips9c4a7962008-06-23 19:50:15 +0800178 return 0;
179}
180
181static int reset_device(struct device *dev)
182{
183 struct talitos_private *priv = dev_get_drvdata(dev);
184 unsigned int timeout = TALITOS_TIMEOUT;
LEROY Christophedd3c0982015-04-17 16:32:13 +0200185 bool is_sec1 = has_ftr_sec1(priv);
186 u32 mcr = is_sec1 ? TALITOS1_MCR_SWR : TALITOS2_MCR_SWR;
Kim Phillips9c4a7962008-06-23 19:50:15 +0800187
Kim Phillipsc3e337f2011-11-21 16:13:27 +0800188 setbits32(priv->reg + TALITOS_MCR, mcr);
Kim Phillips9c4a7962008-06-23 19:50:15 +0800189
LEROY Christophedd3c0982015-04-17 16:32:13 +0200190 while ((in_be32(priv->reg + TALITOS_MCR) & mcr)
Kim Phillips9c4a7962008-06-23 19:50:15 +0800191 && --timeout)
192 cpu_relax();
193
Kim Phillips2cdba3c2011-12-12 14:59:11 -0600194 if (priv->irq[1]) {
Kim Phillipsc3e337f2011-11-21 16:13:27 +0800195 mcr = TALITOS_MCR_RCA1 | TALITOS_MCR_RCA3;
196 setbits32(priv->reg + TALITOS_MCR, mcr);
197 }
198
Kim Phillips9c4a7962008-06-23 19:50:15 +0800199 if (timeout == 0) {
200 dev_err(dev, "failed to reset device\n");
201 return -EIO;
202 }
203
204 return 0;
205}
206
207/*
208 * Reset and initialize the device
209 */
210static int init_device(struct device *dev)
211{
212 struct talitos_private *priv = dev_get_drvdata(dev);
213 int ch, err;
LEROY Christophedd3c0982015-04-17 16:32:13 +0200214 bool is_sec1 = has_ftr_sec1(priv);
Kim Phillips9c4a7962008-06-23 19:50:15 +0800215
216 /*
217 * Master reset
218 * errata documentation: warning: certain SEC interrupts
219 * are not fully cleared by writing the MCR:SWR bit,
220 * set bit twice to completely reset
221 */
222 err = reset_device(dev);
223 if (err)
224 return err;
225
226 err = reset_device(dev);
227 if (err)
228 return err;
229
230 /* reset channels */
231 for (ch = 0; ch < priv->num_channels; ch++) {
232 err = reset_channel(dev, ch);
233 if (err)
234 return err;
235 }
236
237 /* enable channel done and error interrupts */
LEROY Christophedd3c0982015-04-17 16:32:13 +0200238 if (is_sec1) {
239 clrbits32(priv->reg + TALITOS_IMR, TALITOS1_IMR_INIT);
240 clrbits32(priv->reg + TALITOS_IMR_LO, TALITOS1_IMR_LO_INIT);
241 /* disable parity error check in DEU (erroneous? test vect.) */
242 setbits32(priv->reg_deu + TALITOS_EUICR, TALITOS1_DEUICR_KPE);
243 } else {
244 setbits32(priv->reg + TALITOS_IMR, TALITOS2_IMR_INIT);
245 setbits32(priv->reg + TALITOS_IMR_LO, TALITOS2_IMR_LO_INIT);
246 }
Kim Phillips9c4a7962008-06-23 19:50:15 +0800247
Kim Phillipsfe5720e2008-10-12 20:33:14 +0800248 /* disable integrity check error interrupts (use writeback instead) */
249 if (priv->features & TALITOS_FTR_HW_AUTH_CHECK)
LEROY Christophe5fa7fa12015-04-17 16:32:11 +0200250 setbits32(priv->reg_mdeu + TALITOS_EUICR_LO,
Kim Phillipsfe5720e2008-10-12 20:33:14 +0800251 TALITOS_MDEUICR_LO_ICE);
252
Kim Phillips9c4a7962008-06-23 19:50:15 +0800253 return 0;
254}
255
256/**
257 * talitos_submit - submits a descriptor to the device for processing
258 * @dev: the SEC device to be used
Kim Phillips5228f0f2011-07-15 11:21:38 +0800259 * @ch: the SEC device channel to be used
Kim Phillips9c4a7962008-06-23 19:50:15 +0800260 * @desc: the descriptor to be processed by the device
261 * @callback: whom to call when processing is complete
262 * @context: a handle for use by caller (optional)
263 *
264 * desc must contain valid dma-mapped (bus physical) address pointers.
265 * callback must check err and feedback in descriptor header
266 * for device processing status.
267 */
Horia Geanta865d5062012-07-03 19:16:52 +0300268int talitos_submit(struct device *dev, int ch, struct talitos_desc *desc,
269 void (*callback)(struct device *dev,
270 struct talitos_desc *desc,
271 void *context, int error),
272 void *context)
Kim Phillips9c4a7962008-06-23 19:50:15 +0800273{
274 struct talitos_private *priv = dev_get_drvdata(dev);
275 struct talitos_request *request;
Kim Phillips5228f0f2011-07-15 11:21:38 +0800276 unsigned long flags;
Kim Phillips9c4a7962008-06-23 19:50:15 +0800277 int head;
LEROY Christophe7d607c6a2015-04-17 16:32:09 +0200278 bool is_sec1 = has_ftr_sec1(priv);
Kim Phillips9c4a7962008-06-23 19:50:15 +0800279
Kim Phillips4b9926282009-08-13 11:50:38 +1000280 spin_lock_irqsave(&priv->chan[ch].head_lock, flags);
Kim Phillips9c4a7962008-06-23 19:50:15 +0800281
Kim Phillips4b9926282009-08-13 11:50:38 +1000282 if (!atomic_inc_not_zero(&priv->chan[ch].submit_count)) {
Kim Phillipsec6644d2008-07-17 20:16:40 +0800283 /* h/w fifo is full */
Kim Phillips4b9926282009-08-13 11:50:38 +1000284 spin_unlock_irqrestore(&priv->chan[ch].head_lock, flags);
Kim Phillips9c4a7962008-06-23 19:50:15 +0800285 return -EAGAIN;
286 }
287
Kim Phillips4b9926282009-08-13 11:50:38 +1000288 head = priv->chan[ch].head;
289 request = &priv->chan[ch].fifo[head];
Kim Phillipsec6644d2008-07-17 20:16:40 +0800290
Kim Phillips9c4a7962008-06-23 19:50:15 +0800291 /* map descriptor and save caller data */
LEROY Christophe7d607c6a2015-04-17 16:32:09 +0200292 if (is_sec1) {
293 desc->hdr1 = desc->hdr;
LEROY Christophe7d607c6a2015-04-17 16:32:09 +0200294 request->dma_desc = dma_map_single(dev, &desc->hdr1,
295 TALITOS_DESC_SIZE,
296 DMA_BIDIRECTIONAL);
297 } else {
298 request->dma_desc = dma_map_single(dev, desc,
299 TALITOS_DESC_SIZE,
300 DMA_BIDIRECTIONAL);
301 }
Kim Phillips9c4a7962008-06-23 19:50:15 +0800302 request->callback = callback;
303 request->context = context;
304
305 /* increment fifo head */
Kim Phillips4b9926282009-08-13 11:50:38 +1000306 priv->chan[ch].head = (priv->chan[ch].head + 1) & (priv->fifo_len - 1);
Kim Phillips9c4a7962008-06-23 19:50:15 +0800307
308 smp_wmb();
309 request->desc = desc;
310
311 /* GO! */
312 wmb();
Kim Phillipsad42d5f2011-11-21 16:13:27 +0800313 out_be32(priv->chan[ch].reg + TALITOS_FF,
314 upper_32_bits(request->dma_desc));
315 out_be32(priv->chan[ch].reg + TALITOS_FF_LO,
Kim Phillipsa7524472010-09-23 15:56:38 +0800316 lower_32_bits(request->dma_desc));
Kim Phillips9c4a7962008-06-23 19:50:15 +0800317
Kim Phillips4b9926282009-08-13 11:50:38 +1000318 spin_unlock_irqrestore(&priv->chan[ch].head_lock, flags);
Kim Phillips9c4a7962008-06-23 19:50:15 +0800319
320 return -EINPROGRESS;
321}
Horia Geanta865d5062012-07-03 19:16:52 +0300322EXPORT_SYMBOL(talitos_submit);
Kim Phillips9c4a7962008-06-23 19:50:15 +0800323
324/*
325 * process what was done, notify callback of error if not
326 */
327static void flush_channel(struct device *dev, int ch, int error, int reset_ch)
328{
329 struct talitos_private *priv = dev_get_drvdata(dev);
330 struct talitos_request *request, saved_req;
331 unsigned long flags;
332 int tail, status;
LEROY Christophe7d607c6a2015-04-17 16:32:09 +0200333 bool is_sec1 = has_ftr_sec1(priv);
Kim Phillips9c4a7962008-06-23 19:50:15 +0800334
Kim Phillips4b9926282009-08-13 11:50:38 +1000335 spin_lock_irqsave(&priv->chan[ch].tail_lock, flags);
Kim Phillips9c4a7962008-06-23 19:50:15 +0800336
Kim Phillips4b9926282009-08-13 11:50:38 +1000337 tail = priv->chan[ch].tail;
338 while (priv->chan[ch].fifo[tail].desc) {
LEROY Christophe7d607c6a2015-04-17 16:32:09 +0200339 __be32 hdr;
340
Kim Phillips4b9926282009-08-13 11:50:38 +1000341 request = &priv->chan[ch].fifo[tail];
Kim Phillips9c4a7962008-06-23 19:50:15 +0800342
343 /* descriptors with their done bits set don't get the error */
344 rmb();
LEROY Christophe37b5e882017-10-06 15:05:06 +0200345 if (!is_sec1)
346 hdr = request->desc->hdr;
347 else if (request->desc->next_desc)
348 hdr = (request->desc + 1)->hdr1;
349 else
350 hdr = request->desc->hdr1;
LEROY Christophe7d607c6a2015-04-17 16:32:09 +0200351
352 if ((hdr & DESC_HDR_DONE) == DESC_HDR_DONE)
Kim Phillips9c4a7962008-06-23 19:50:15 +0800353 status = 0;
Lee Nipperca38a812008-12-20 17:09:25 +1100354 else
Kim Phillips9c4a7962008-06-23 19:50:15 +0800355 if (!error)
356 break;
357 else
358 status = error;
359
360 dma_unmap_single(dev, request->dma_desc,
LEROY Christophe7d607c6a2015-04-17 16:32:09 +0200361 TALITOS_DESC_SIZE,
Kim Phillipse938e462009-03-29 15:53:23 +0800362 DMA_BIDIRECTIONAL);
Kim Phillips9c4a7962008-06-23 19:50:15 +0800363
364 /* copy entries so we can call callback outside lock */
365 saved_req.desc = request->desc;
366 saved_req.callback = request->callback;
367 saved_req.context = request->context;
368
369 /* release request entry in fifo */
370 smp_wmb();
371 request->desc = NULL;
372
373 /* increment fifo tail */
Kim Phillips4b9926282009-08-13 11:50:38 +1000374 priv->chan[ch].tail = (tail + 1) & (priv->fifo_len - 1);
Kim Phillips9c4a7962008-06-23 19:50:15 +0800375
Kim Phillips4b9926282009-08-13 11:50:38 +1000376 spin_unlock_irqrestore(&priv->chan[ch].tail_lock, flags);
Kim Phillipsec6644d2008-07-17 20:16:40 +0800377
Kim Phillips4b9926282009-08-13 11:50:38 +1000378 atomic_dec(&priv->chan[ch].submit_count);
Kim Phillipsec6644d2008-07-17 20:16:40 +0800379
Kim Phillips9c4a7962008-06-23 19:50:15 +0800380 saved_req.callback(dev, saved_req.desc, saved_req.context,
381 status);
382 /* channel may resume processing in single desc error case */
383 if (error && !reset_ch && status == error)
384 return;
Kim Phillips4b9926282009-08-13 11:50:38 +1000385 spin_lock_irqsave(&priv->chan[ch].tail_lock, flags);
386 tail = priv->chan[ch].tail;
Kim Phillips9c4a7962008-06-23 19:50:15 +0800387 }
388
Kim Phillips4b9926282009-08-13 11:50:38 +1000389 spin_unlock_irqrestore(&priv->chan[ch].tail_lock, flags);
Kim Phillips9c4a7962008-06-23 19:50:15 +0800390}
391
392/*
393 * process completed requests for channels that have done status
394 */
LEROY Christophedd3c0982015-04-17 16:32:13 +0200395#define DEF_TALITOS1_DONE(name, ch_done_mask) \
396static void talitos1_done_##name(unsigned long data) \
397{ \
398 struct device *dev = (struct device *)data; \
399 struct talitos_private *priv = dev_get_drvdata(dev); \
400 unsigned long flags; \
401 \
402 if (ch_done_mask & 0x10000000) \
403 flush_channel(dev, 0, 0, 0); \
LEROY Christophedd3c0982015-04-17 16:32:13 +0200404 if (ch_done_mask & 0x40000000) \
405 flush_channel(dev, 1, 0, 0); \
406 if (ch_done_mask & 0x00010000) \
407 flush_channel(dev, 2, 0, 0); \
408 if (ch_done_mask & 0x00040000) \
409 flush_channel(dev, 3, 0, 0); \
410 \
LEROY Christophedd3c0982015-04-17 16:32:13 +0200411 /* At this point, all completed channels have been processed */ \
412 /* Unmask done interrupts for channels completed later on. */ \
413 spin_lock_irqsave(&priv->reg_lock, flags); \
414 clrbits32(priv->reg + TALITOS_IMR, ch_done_mask); \
415 clrbits32(priv->reg + TALITOS_IMR_LO, TALITOS1_IMR_LO_INIT); \
416 spin_unlock_irqrestore(&priv->reg_lock, flags); \
417}
418
419DEF_TALITOS1_DONE(4ch, TALITOS1_ISR_4CHDONE)
LEROY Christophe9c02e282017-10-06 15:04:55 +0200420DEF_TALITOS1_DONE(ch0, TALITOS1_ISR_CH_0_DONE)
LEROY Christophedd3c0982015-04-17 16:32:13 +0200421
422#define DEF_TALITOS2_DONE(name, ch_done_mask) \
423static void talitos2_done_##name(unsigned long data) \
Kim Phillipsc3e337f2011-11-21 16:13:27 +0800424{ \
425 struct device *dev = (struct device *)data; \
426 struct talitos_private *priv = dev_get_drvdata(dev); \
Horia Geanta511d63c2012-03-30 17:49:53 +0300427 unsigned long flags; \
Kim Phillipsc3e337f2011-11-21 16:13:27 +0800428 \
429 if (ch_done_mask & 1) \
430 flush_channel(dev, 0, 0, 0); \
Kim Phillipsc3e337f2011-11-21 16:13:27 +0800431 if (ch_done_mask & (1 << 2)) \
432 flush_channel(dev, 1, 0, 0); \
433 if (ch_done_mask & (1 << 4)) \
434 flush_channel(dev, 2, 0, 0); \
435 if (ch_done_mask & (1 << 6)) \
436 flush_channel(dev, 3, 0, 0); \
437 \
Kim Phillipsc3e337f2011-11-21 16:13:27 +0800438 /* At this point, all completed channels have been processed */ \
439 /* Unmask done interrupts for channels completed later on. */ \
Horia Geanta511d63c2012-03-30 17:49:53 +0300440 spin_lock_irqsave(&priv->reg_lock, flags); \
Kim Phillipsc3e337f2011-11-21 16:13:27 +0800441 setbits32(priv->reg + TALITOS_IMR, ch_done_mask); \
LEROY Christophedd3c0982015-04-17 16:32:13 +0200442 setbits32(priv->reg + TALITOS_IMR_LO, TALITOS2_IMR_LO_INIT); \
Horia Geanta511d63c2012-03-30 17:49:53 +0300443 spin_unlock_irqrestore(&priv->reg_lock, flags); \
Kim Phillips9c4a7962008-06-23 19:50:15 +0800444}
LEROY Christophedd3c0982015-04-17 16:32:13 +0200445
446DEF_TALITOS2_DONE(4ch, TALITOS2_ISR_4CHDONE)
LEROY Christophe9c02e282017-10-06 15:04:55 +0200447DEF_TALITOS2_DONE(ch0, TALITOS2_ISR_CH_0_DONE)
LEROY Christophedd3c0982015-04-17 16:32:13 +0200448DEF_TALITOS2_DONE(ch0_2, TALITOS2_ISR_CH_0_2_DONE)
449DEF_TALITOS2_DONE(ch1_3, TALITOS2_ISR_CH_1_3_DONE)
Kim Phillips9c4a7962008-06-23 19:50:15 +0800450
451/*
452 * locate current (offending) descriptor
453 */
Kim Phillips3e721ae2011-10-21 15:20:28 +0200454static u32 current_desc_hdr(struct device *dev, int ch)
Kim Phillips9c4a7962008-06-23 19:50:15 +0800455{
456 struct talitos_private *priv = dev_get_drvdata(dev);
Horia Geantab62ffd82013-11-13 12:20:37 +0200457 int tail, iter;
Kim Phillips9c4a7962008-06-23 19:50:15 +0800458 dma_addr_t cur_desc;
459
Horia Geantab62ffd82013-11-13 12:20:37 +0200460 cur_desc = ((u64)in_be32(priv->chan[ch].reg + TALITOS_CDPR)) << 32;
461 cur_desc |= in_be32(priv->chan[ch].reg + TALITOS_CDPR_LO);
Kim Phillips9c4a7962008-06-23 19:50:15 +0800462
Horia Geantab62ffd82013-11-13 12:20:37 +0200463 if (!cur_desc) {
464 dev_err(dev, "CDPR is NULL, giving up search for offending descriptor\n");
465 return 0;
466 }
467
468 tail = priv->chan[ch].tail;
469
470 iter = tail;
LEROY Christophe37b5e882017-10-06 15:05:06 +0200471 while (priv->chan[ch].fifo[iter].dma_desc != cur_desc &&
472 priv->chan[ch].fifo[iter].desc->next_desc != cur_desc) {
Horia Geantab62ffd82013-11-13 12:20:37 +0200473 iter = (iter + 1) & (priv->fifo_len - 1);
474 if (iter == tail) {
Kim Phillips9c4a7962008-06-23 19:50:15 +0800475 dev_err(dev, "couldn't locate current descriptor\n");
Kim Phillips3e721ae2011-10-21 15:20:28 +0200476 return 0;
Kim Phillips9c4a7962008-06-23 19:50:15 +0800477 }
478 }
479
LEROY Christophe37b5e882017-10-06 15:05:06 +0200480 if (priv->chan[ch].fifo[iter].desc->next_desc == cur_desc)
481 return (priv->chan[ch].fifo[iter].desc + 1)->hdr;
482
Horia Geantab62ffd82013-11-13 12:20:37 +0200483 return priv->chan[ch].fifo[iter].desc->hdr;
Kim Phillips9c4a7962008-06-23 19:50:15 +0800484}
485
486/*
487 * user diagnostics; report root cause of error based on execution unit status
488 */
Kim Phillips3e721ae2011-10-21 15:20:28 +0200489static void report_eu_error(struct device *dev, int ch, u32 desc_hdr)
Kim Phillips9c4a7962008-06-23 19:50:15 +0800490{
491 struct talitos_private *priv = dev_get_drvdata(dev);
492 int i;
493
Kim Phillips3e721ae2011-10-21 15:20:28 +0200494 if (!desc_hdr)
Kim Phillipsad42d5f2011-11-21 16:13:27 +0800495 desc_hdr = in_be32(priv->chan[ch].reg + TALITOS_DESCBUF);
Kim Phillips3e721ae2011-10-21 15:20:28 +0200496
497 switch (desc_hdr & DESC_HDR_SEL0_MASK) {
Kim Phillips9c4a7962008-06-23 19:50:15 +0800498 case DESC_HDR_SEL0_AFEU:
499 dev_err(dev, "AFEUISR 0x%08x_%08x\n",
LEROY Christophe5fa7fa12015-04-17 16:32:11 +0200500 in_be32(priv->reg_afeu + TALITOS_EUISR),
501 in_be32(priv->reg_afeu + TALITOS_EUISR_LO));
Kim Phillips9c4a7962008-06-23 19:50:15 +0800502 break;
503 case DESC_HDR_SEL0_DEU:
504 dev_err(dev, "DEUISR 0x%08x_%08x\n",
LEROY Christophe5fa7fa12015-04-17 16:32:11 +0200505 in_be32(priv->reg_deu + TALITOS_EUISR),
506 in_be32(priv->reg_deu + TALITOS_EUISR_LO));
Kim Phillips9c4a7962008-06-23 19:50:15 +0800507 break;
508 case DESC_HDR_SEL0_MDEUA:
509 case DESC_HDR_SEL0_MDEUB:
510 dev_err(dev, "MDEUISR 0x%08x_%08x\n",
LEROY Christophe5fa7fa12015-04-17 16:32:11 +0200511 in_be32(priv->reg_mdeu + TALITOS_EUISR),
512 in_be32(priv->reg_mdeu + TALITOS_EUISR_LO));
Kim Phillips9c4a7962008-06-23 19:50:15 +0800513 break;
514 case DESC_HDR_SEL0_RNG:
515 dev_err(dev, "RNGUISR 0x%08x_%08x\n",
LEROY Christophe5fa7fa12015-04-17 16:32:11 +0200516 in_be32(priv->reg_rngu + TALITOS_ISR),
517 in_be32(priv->reg_rngu + TALITOS_ISR_LO));
Kim Phillips9c4a7962008-06-23 19:50:15 +0800518 break;
519 case DESC_HDR_SEL0_PKEU:
520 dev_err(dev, "PKEUISR 0x%08x_%08x\n",
LEROY Christophe5fa7fa12015-04-17 16:32:11 +0200521 in_be32(priv->reg_pkeu + TALITOS_EUISR),
522 in_be32(priv->reg_pkeu + TALITOS_EUISR_LO));
Kim Phillips9c4a7962008-06-23 19:50:15 +0800523 break;
524 case DESC_HDR_SEL0_AESU:
525 dev_err(dev, "AESUISR 0x%08x_%08x\n",
LEROY Christophe5fa7fa12015-04-17 16:32:11 +0200526 in_be32(priv->reg_aesu + TALITOS_EUISR),
527 in_be32(priv->reg_aesu + TALITOS_EUISR_LO));
Kim Phillips9c4a7962008-06-23 19:50:15 +0800528 break;
529 case DESC_HDR_SEL0_CRCU:
530 dev_err(dev, "CRCUISR 0x%08x_%08x\n",
LEROY Christophe5fa7fa12015-04-17 16:32:11 +0200531 in_be32(priv->reg_crcu + TALITOS_EUISR),
532 in_be32(priv->reg_crcu + TALITOS_EUISR_LO));
Kim Phillips9c4a7962008-06-23 19:50:15 +0800533 break;
534 case DESC_HDR_SEL0_KEU:
535 dev_err(dev, "KEUISR 0x%08x_%08x\n",
LEROY Christophe5fa7fa12015-04-17 16:32:11 +0200536 in_be32(priv->reg_pkeu + TALITOS_EUISR),
537 in_be32(priv->reg_pkeu + TALITOS_EUISR_LO));
Kim Phillips9c4a7962008-06-23 19:50:15 +0800538 break;
539 }
540
Kim Phillips3e721ae2011-10-21 15:20:28 +0200541 switch (desc_hdr & DESC_HDR_SEL1_MASK) {
Kim Phillips9c4a7962008-06-23 19:50:15 +0800542 case DESC_HDR_SEL1_MDEUA:
543 case DESC_HDR_SEL1_MDEUB:
544 dev_err(dev, "MDEUISR 0x%08x_%08x\n",
LEROY Christophe5fa7fa12015-04-17 16:32:11 +0200545 in_be32(priv->reg_mdeu + TALITOS_EUISR),
546 in_be32(priv->reg_mdeu + TALITOS_EUISR_LO));
Kim Phillips9c4a7962008-06-23 19:50:15 +0800547 break;
548 case DESC_HDR_SEL1_CRCU:
549 dev_err(dev, "CRCUISR 0x%08x_%08x\n",
LEROY Christophe5fa7fa12015-04-17 16:32:11 +0200550 in_be32(priv->reg_crcu + TALITOS_EUISR),
551 in_be32(priv->reg_crcu + TALITOS_EUISR_LO));
Kim Phillips9c4a7962008-06-23 19:50:15 +0800552 break;
553 }
554
555 for (i = 0; i < 8; i++)
556 dev_err(dev, "DESCBUF 0x%08x_%08x\n",
Kim Phillipsad42d5f2011-11-21 16:13:27 +0800557 in_be32(priv->chan[ch].reg + TALITOS_DESCBUF + 8*i),
558 in_be32(priv->chan[ch].reg + TALITOS_DESCBUF_LO + 8*i));
Kim Phillips9c4a7962008-06-23 19:50:15 +0800559}
560
561/*
562 * recover from error interrupts
563 */
Kim Phillips5e718a02011-12-12 14:59:12 -0600564static void talitos_error(struct device *dev, u32 isr, u32 isr_lo)
Kim Phillips9c4a7962008-06-23 19:50:15 +0800565{
Kim Phillips9c4a7962008-06-23 19:50:15 +0800566 struct talitos_private *priv = dev_get_drvdata(dev);
567 unsigned int timeout = TALITOS_TIMEOUT;
LEROY Christophedd3c0982015-04-17 16:32:13 +0200568 int ch, error, reset_dev = 0;
Horia Geant?42e8b0d2015-05-11 20:04:56 +0300569 u32 v_lo;
LEROY Christophedd3c0982015-04-17 16:32:13 +0200570 bool is_sec1 = has_ftr_sec1(priv);
571 int reset_ch = is_sec1 ? 1 : 0; /* only SEC2 supports continuation */
Kim Phillips9c4a7962008-06-23 19:50:15 +0800572
573 for (ch = 0; ch < priv->num_channels; ch++) {
574 /* skip channels without errors */
LEROY Christophedd3c0982015-04-17 16:32:13 +0200575 if (is_sec1) {
576 /* bits 29, 31, 17, 19 */
577 if (!(isr & (1 << (29 + (ch & 1) * 2 - (ch & 2) * 6))))
578 continue;
579 } else {
580 if (!(isr & (1 << (ch * 2 + 1))))
581 continue;
582 }
Kim Phillips9c4a7962008-06-23 19:50:15 +0800583
584 error = -EINVAL;
585
Kim Phillipsad42d5f2011-11-21 16:13:27 +0800586 v_lo = in_be32(priv->chan[ch].reg + TALITOS_CCPSR_LO);
Kim Phillips9c4a7962008-06-23 19:50:15 +0800587
588 if (v_lo & TALITOS_CCPSR_LO_DOF) {
589 dev_err(dev, "double fetch fifo overflow error\n");
590 error = -EAGAIN;
591 reset_ch = 1;
592 }
593 if (v_lo & TALITOS_CCPSR_LO_SOF) {
594 /* h/w dropped descriptor */
595 dev_err(dev, "single fetch fifo overflow error\n");
596 error = -EAGAIN;
597 }
598 if (v_lo & TALITOS_CCPSR_LO_MDTE)
599 dev_err(dev, "master data transfer error\n");
600 if (v_lo & TALITOS_CCPSR_LO_SGDLZ)
Colin Ian King4d9b3a52016-11-01 20:14:04 -0600601 dev_err(dev, is_sec1 ? "pointer not complete error\n"
LEROY Christophedd3c0982015-04-17 16:32:13 +0200602 : "s/g data length zero error\n");
Kim Phillips9c4a7962008-06-23 19:50:15 +0800603 if (v_lo & TALITOS_CCPSR_LO_FPZ)
LEROY Christophedd3c0982015-04-17 16:32:13 +0200604 dev_err(dev, is_sec1 ? "parity error\n"
605 : "fetch pointer zero error\n");
Kim Phillips9c4a7962008-06-23 19:50:15 +0800606 if (v_lo & TALITOS_CCPSR_LO_IDH)
607 dev_err(dev, "illegal descriptor header error\n");
608 if (v_lo & TALITOS_CCPSR_LO_IEU)
LEROY Christophedd3c0982015-04-17 16:32:13 +0200609 dev_err(dev, is_sec1 ? "static assignment error\n"
610 : "invalid exec unit error\n");
Kim Phillips9c4a7962008-06-23 19:50:15 +0800611 if (v_lo & TALITOS_CCPSR_LO_EU)
Kim Phillips3e721ae2011-10-21 15:20:28 +0200612 report_eu_error(dev, ch, current_desc_hdr(dev, ch));
LEROY Christophedd3c0982015-04-17 16:32:13 +0200613 if (!is_sec1) {
614 if (v_lo & TALITOS_CCPSR_LO_GB)
615 dev_err(dev, "gather boundary error\n");
616 if (v_lo & TALITOS_CCPSR_LO_GRL)
617 dev_err(dev, "gather return/length error\n");
618 if (v_lo & TALITOS_CCPSR_LO_SB)
619 dev_err(dev, "scatter boundary error\n");
620 if (v_lo & TALITOS_CCPSR_LO_SRL)
621 dev_err(dev, "scatter return/length error\n");
622 }
Kim Phillips9c4a7962008-06-23 19:50:15 +0800623
624 flush_channel(dev, ch, error, reset_ch);
625
626 if (reset_ch) {
627 reset_channel(dev, ch);
628 } else {
Kim Phillipsad42d5f2011-11-21 16:13:27 +0800629 setbits32(priv->chan[ch].reg + TALITOS_CCCR,
LEROY Christophedd3c0982015-04-17 16:32:13 +0200630 TALITOS2_CCCR_CONT);
Kim Phillipsad42d5f2011-11-21 16:13:27 +0800631 setbits32(priv->chan[ch].reg + TALITOS_CCCR_LO, 0);
632 while ((in_be32(priv->chan[ch].reg + TALITOS_CCCR) &
LEROY Christophedd3c0982015-04-17 16:32:13 +0200633 TALITOS2_CCCR_CONT) && --timeout)
Kim Phillips9c4a7962008-06-23 19:50:15 +0800634 cpu_relax();
635 if (timeout == 0) {
636 dev_err(dev, "failed to restart channel %d\n",
637 ch);
638 reset_dev = 1;
639 }
640 }
641 }
LEROY Christophedd3c0982015-04-17 16:32:13 +0200642 if (reset_dev || (is_sec1 && isr & ~TALITOS1_ISR_4CHERR) ||
643 (!is_sec1 && isr & ~TALITOS2_ISR_4CHERR) || isr_lo) {
644 if (is_sec1 && (isr_lo & TALITOS1_ISR_TEA_ERR))
645 dev_err(dev, "TEA error: ISR 0x%08x_%08x\n",
646 isr, isr_lo);
647 else
648 dev_err(dev, "done overflow, internal time out, or "
649 "rngu error: ISR 0x%08x_%08x\n", isr, isr_lo);
Kim Phillips9c4a7962008-06-23 19:50:15 +0800650
651 /* purge request queues */
652 for (ch = 0; ch < priv->num_channels; ch++)
653 flush_channel(dev, ch, -EIO, 1);
654
655 /* reset and reinitialize the device */
656 init_device(dev);
657 }
658}
659
LEROY Christophedd3c0982015-04-17 16:32:13 +0200660#define DEF_TALITOS1_INTERRUPT(name, ch_done_mask, ch_err_mask, tlet) \
661static irqreturn_t talitos1_interrupt_##name(int irq, void *data) \
662{ \
663 struct device *dev = data; \
664 struct talitos_private *priv = dev_get_drvdata(dev); \
665 u32 isr, isr_lo; \
666 unsigned long flags; \
667 \
668 spin_lock_irqsave(&priv->reg_lock, flags); \
669 isr = in_be32(priv->reg + TALITOS_ISR); \
670 isr_lo = in_be32(priv->reg + TALITOS_ISR_LO); \
671 /* Acknowledge interrupt */ \
672 out_be32(priv->reg + TALITOS_ICR, isr & (ch_done_mask | ch_err_mask)); \
673 out_be32(priv->reg + TALITOS_ICR_LO, isr_lo); \
674 \
675 if (unlikely(isr & ch_err_mask || isr_lo & TALITOS1_IMR_LO_INIT)) { \
676 spin_unlock_irqrestore(&priv->reg_lock, flags); \
677 talitos_error(dev, isr & ch_err_mask, isr_lo); \
678 } \
679 else { \
680 if (likely(isr & ch_done_mask)) { \
681 /* mask further done interrupts. */ \
682 setbits32(priv->reg + TALITOS_IMR, ch_done_mask); \
683 /* done_task will unmask done interrupts at exit */ \
684 tasklet_schedule(&priv->done_task[tlet]); \
685 } \
686 spin_unlock_irqrestore(&priv->reg_lock, flags); \
687 } \
688 \
689 return (isr & (ch_done_mask | ch_err_mask) || isr_lo) ? IRQ_HANDLED : \
690 IRQ_NONE; \
691}
692
693DEF_TALITOS1_INTERRUPT(4ch, TALITOS1_ISR_4CHDONE, TALITOS1_ISR_4CHERR, 0)
694
695#define DEF_TALITOS2_INTERRUPT(name, ch_done_mask, ch_err_mask, tlet) \
696static irqreturn_t talitos2_interrupt_##name(int irq, void *data) \
Kim Phillipsc3e337f2011-11-21 16:13:27 +0800697{ \
698 struct device *dev = data; \
699 struct talitos_private *priv = dev_get_drvdata(dev); \
700 u32 isr, isr_lo; \
Horia Geanta511d63c2012-03-30 17:49:53 +0300701 unsigned long flags; \
Kim Phillipsc3e337f2011-11-21 16:13:27 +0800702 \
Horia Geanta511d63c2012-03-30 17:49:53 +0300703 spin_lock_irqsave(&priv->reg_lock, flags); \
Kim Phillipsc3e337f2011-11-21 16:13:27 +0800704 isr = in_be32(priv->reg + TALITOS_ISR); \
705 isr_lo = in_be32(priv->reg + TALITOS_ISR_LO); \
706 /* Acknowledge interrupt */ \
707 out_be32(priv->reg + TALITOS_ICR, isr & (ch_done_mask | ch_err_mask)); \
708 out_be32(priv->reg + TALITOS_ICR_LO, isr_lo); \
709 \
Horia Geanta511d63c2012-03-30 17:49:53 +0300710 if (unlikely(isr & ch_err_mask || isr_lo)) { \
711 spin_unlock_irqrestore(&priv->reg_lock, flags); \
712 talitos_error(dev, isr & ch_err_mask, isr_lo); \
713 } \
714 else { \
Kim Phillipsc3e337f2011-11-21 16:13:27 +0800715 if (likely(isr & ch_done_mask)) { \
716 /* mask further done interrupts. */ \
717 clrbits32(priv->reg + TALITOS_IMR, ch_done_mask); \
718 /* done_task will unmask done interrupts at exit */ \
719 tasklet_schedule(&priv->done_task[tlet]); \
720 } \
Horia Geanta511d63c2012-03-30 17:49:53 +0300721 spin_unlock_irqrestore(&priv->reg_lock, flags); \
722 } \
Kim Phillipsc3e337f2011-11-21 16:13:27 +0800723 \
724 return (isr & (ch_done_mask | ch_err_mask) || isr_lo) ? IRQ_HANDLED : \
725 IRQ_NONE; \
Kim Phillips9c4a7962008-06-23 19:50:15 +0800726}
LEROY Christophedd3c0982015-04-17 16:32:13 +0200727
728DEF_TALITOS2_INTERRUPT(4ch, TALITOS2_ISR_4CHDONE, TALITOS2_ISR_4CHERR, 0)
729DEF_TALITOS2_INTERRUPT(ch0_2, TALITOS2_ISR_CH_0_2_DONE, TALITOS2_ISR_CH_0_2_ERR,
730 0)
731DEF_TALITOS2_INTERRUPT(ch1_3, TALITOS2_ISR_CH_1_3_DONE, TALITOS2_ISR_CH_1_3_ERR,
732 1)
Kim Phillips9c4a7962008-06-23 19:50:15 +0800733
734/*
735 * hwrng
736 */
737static int talitos_rng_data_present(struct hwrng *rng, int wait)
738{
739 struct device *dev = (struct device *)rng->priv;
740 struct talitos_private *priv = dev_get_drvdata(dev);
741 u32 ofl;
742 int i;
743
744 for (i = 0; i < 20; i++) {
LEROY Christophe5fa7fa12015-04-17 16:32:11 +0200745 ofl = in_be32(priv->reg_rngu + TALITOS_EUSR_LO) &
Kim Phillips9c4a7962008-06-23 19:50:15 +0800746 TALITOS_RNGUSR_LO_OFL;
747 if (ofl || !wait)
748 break;
749 udelay(10);
750 }
751
752 return !!ofl;
753}
754
755static int talitos_rng_data_read(struct hwrng *rng, u32 *data)
756{
757 struct device *dev = (struct device *)rng->priv;
758 struct talitos_private *priv = dev_get_drvdata(dev);
759
760 /* rng fifo requires 64-bit accesses */
LEROY Christophe5fa7fa12015-04-17 16:32:11 +0200761 *data = in_be32(priv->reg_rngu + TALITOS_EU_FIFO);
762 *data = in_be32(priv->reg_rngu + TALITOS_EU_FIFO_LO);
Kim Phillips9c4a7962008-06-23 19:50:15 +0800763
764 return sizeof(u32);
765}
766
767static int talitos_rng_init(struct hwrng *rng)
768{
769 struct device *dev = (struct device *)rng->priv;
770 struct talitos_private *priv = dev_get_drvdata(dev);
771 unsigned int timeout = TALITOS_TIMEOUT;
772
LEROY Christophe5fa7fa12015-04-17 16:32:11 +0200773 setbits32(priv->reg_rngu + TALITOS_EURCR_LO, TALITOS_RNGURCR_LO_SR);
774 while (!(in_be32(priv->reg_rngu + TALITOS_EUSR_LO)
775 & TALITOS_RNGUSR_LO_RD)
Kim Phillips9c4a7962008-06-23 19:50:15 +0800776 && --timeout)
777 cpu_relax();
778 if (timeout == 0) {
779 dev_err(dev, "failed to reset rng hw\n");
780 return -ENODEV;
781 }
782
783 /* start generating */
LEROY Christophe5fa7fa12015-04-17 16:32:11 +0200784 setbits32(priv->reg_rngu + TALITOS_EUDSR_LO, 0);
Kim Phillips9c4a7962008-06-23 19:50:15 +0800785
786 return 0;
787}
788
789static int talitos_register_rng(struct device *dev)
790{
791 struct talitos_private *priv = dev_get_drvdata(dev);
Aaron Sierra35a3bb32015-08-05 16:52:08 -0500792 int err;
Kim Phillips9c4a7962008-06-23 19:50:15 +0800793
794 priv->rng.name = dev_driver_string(dev),
795 priv->rng.init = talitos_rng_init,
796 priv->rng.data_present = talitos_rng_data_present,
797 priv->rng.data_read = talitos_rng_data_read,
798 priv->rng.priv = (unsigned long)dev;
799
Aaron Sierra35a3bb32015-08-05 16:52:08 -0500800 err = hwrng_register(&priv->rng);
801 if (!err)
802 priv->rng_registered = true;
803
804 return err;
Kim Phillips9c4a7962008-06-23 19:50:15 +0800805}
806
807static void talitos_unregister_rng(struct device *dev)
808{
809 struct talitos_private *priv = dev_get_drvdata(dev);
810
Aaron Sierra35a3bb32015-08-05 16:52:08 -0500811 if (!priv->rng_registered)
812 return;
813
Kim Phillips9c4a7962008-06-23 19:50:15 +0800814 hwrng_unregister(&priv->rng);
Aaron Sierra35a3bb32015-08-05 16:52:08 -0500815 priv->rng_registered = false;
Kim Phillips9c4a7962008-06-23 19:50:15 +0800816}
817
818/*
819 * crypto alg
820 */
821#define TALITOS_CRA_PRIORITY 3000
LEROY Christophe7405c8d2016-06-06 13:20:46 +0200822/*
823 * Defines a priority for doing AEAD with descriptors type
824 * HMAC_SNOOP_NO_AFEA (HSNA) instead of type IPSEC_ESP
825 */
826#define TALITOS_CRA_PRIORITY_AEAD_HSNA (TALITOS_CRA_PRIORITY - 1)
Martin Hicks03d2c512017-05-02 09:38:35 -0400827#define TALITOS_MAX_KEY_SIZE (AES_MAX_KEY_SIZE + SHA512_BLOCK_SIZE)
Lee Nipper3952f172008-07-10 18:29:18 +0800828#define TALITOS_MAX_IV_LENGTH 16 /* max of AES_BLOCK_SIZE, DES3_EDE_BLOCK_SIZE */
Lee Nipper70bcaca2008-07-03 19:08:46 +0800829
Kim Phillips9c4a7962008-06-23 19:50:15 +0800830struct talitos_ctx {
831 struct device *dev;
Kim Phillips5228f0f2011-07-15 11:21:38 +0800832 int ch;
Kim Phillips9c4a7962008-06-23 19:50:15 +0800833 __be32 desc_hdr_template;
834 u8 key[TALITOS_MAX_KEY_SIZE];
Lee Nipper70bcaca2008-07-03 19:08:46 +0800835 u8 iv[TALITOS_MAX_IV_LENGTH];
LEROY Christophe2e13ce02017-10-06 15:05:02 +0200836 dma_addr_t dma_key;
Kim Phillips9c4a7962008-06-23 19:50:15 +0800837 unsigned int keylen;
838 unsigned int enckeylen;
839 unsigned int authkeylen;
Kim Phillips9c4a7962008-06-23 19:50:15 +0800840};
841
Lee Nipper497f2e62010-05-19 19:20:36 +1000842#define HASH_MAX_BLOCK_SIZE SHA512_BLOCK_SIZE
843#define TALITOS_MDEU_MAX_CONTEXT_SIZE TALITOS_MDEU_CONTEXT_SIZE_SHA384_SHA512
844
845struct talitos_ahash_req_ctx {
Kim Phillips60f208d2010-05-19 19:21:53 +1000846 u32 hw_context[TALITOS_MDEU_MAX_CONTEXT_SIZE / sizeof(u32)];
Lee Nipper497f2e62010-05-19 19:20:36 +1000847 unsigned int hw_context_size;
LEROY Christophe3c0dd192017-10-06 15:05:08 +0200848 u8 buf[2][HASH_MAX_BLOCK_SIZE];
849 int buf_idx;
Kim Phillips60f208d2010-05-19 19:21:53 +1000850 unsigned int swinit;
Lee Nipper497f2e62010-05-19 19:20:36 +1000851 unsigned int first;
852 unsigned int last;
853 unsigned int to_hash_later;
Horia Geant?42e8b0d2015-05-11 20:04:56 +0300854 unsigned int nbuf;
Lee Nipper497f2e62010-05-19 19:20:36 +1000855 struct scatterlist bufsl[2];
856 struct scatterlist *psrc;
857};
858
Horia Geant?3639ca82016-04-21 19:24:55 +0300859struct talitos_export_state {
860 u32 hw_context[TALITOS_MDEU_MAX_CONTEXT_SIZE / sizeof(u32)];
861 u8 buf[HASH_MAX_BLOCK_SIZE];
862 unsigned int swinit;
863 unsigned int first;
864 unsigned int last;
865 unsigned int to_hash_later;
866 unsigned int nbuf;
867};
868
Lee Nipper56af8cd2009-03-29 15:50:50 +0800869static int aead_setkey(struct crypto_aead *authenc,
870 const u8 *key, unsigned int keylen)
Kim Phillips9c4a7962008-06-23 19:50:15 +0800871{
872 struct talitos_ctx *ctx = crypto_aead_ctx(authenc);
LEROY Christophe2e13ce02017-10-06 15:05:02 +0200873 struct device *dev = ctx->dev;
Mathias Krausec306a982013-10-15 13:49:34 +0200874 struct crypto_authenc_keys keys;
Kim Phillips9c4a7962008-06-23 19:50:15 +0800875
Mathias Krausec306a982013-10-15 13:49:34 +0200876 if (crypto_authenc_extractkeys(&keys, key, keylen) != 0)
Kim Phillips9c4a7962008-06-23 19:50:15 +0800877 goto badkey;
878
Mathias Krausec306a982013-10-15 13:49:34 +0200879 if (keys.authkeylen + keys.enckeylen > TALITOS_MAX_KEY_SIZE)
Kim Phillips9c4a7962008-06-23 19:50:15 +0800880 goto badkey;
881
LEROY Christophe2e13ce02017-10-06 15:05:02 +0200882 if (ctx->keylen)
883 dma_unmap_single(dev, ctx->dma_key, ctx->keylen, DMA_TO_DEVICE);
884
Mathias Krausec306a982013-10-15 13:49:34 +0200885 memcpy(ctx->key, keys.authkey, keys.authkeylen);
886 memcpy(&ctx->key[keys.authkeylen], keys.enckey, keys.enckeylen);
Kim Phillips9c4a7962008-06-23 19:50:15 +0800887
Mathias Krausec306a982013-10-15 13:49:34 +0200888 ctx->keylen = keys.authkeylen + keys.enckeylen;
889 ctx->enckeylen = keys.enckeylen;
890 ctx->authkeylen = keys.authkeylen;
LEROY Christophe2e13ce02017-10-06 15:05:02 +0200891 ctx->dma_key = dma_map_single(dev, ctx->key, ctx->keylen,
892 DMA_TO_DEVICE);
Kim Phillips9c4a7962008-06-23 19:50:15 +0800893
Tudor-Dan Ambarus8f0691f2018-03-23 12:42:24 +0200894 memzero_explicit(&keys, sizeof(keys));
Kim Phillips9c4a7962008-06-23 19:50:15 +0800895 return 0;
896
897badkey:
898 crypto_aead_set_flags(authenc, CRYPTO_TFM_RES_BAD_KEY_LEN);
Tudor-Dan Ambarus8f0691f2018-03-23 12:42:24 +0200899 memzero_explicit(&keys, sizeof(keys));
Kim Phillips9c4a7962008-06-23 19:50:15 +0800900 return -EINVAL;
901}
902
Herbert Xuef7c5c82019-04-11 16:51:21 +0800903static int aead_des3_setkey(struct crypto_aead *authenc,
904 const u8 *key, unsigned int keylen)
905{
906 struct talitos_ctx *ctx = crypto_aead_ctx(authenc);
907 struct device *dev = ctx->dev;
908 struct crypto_authenc_keys keys;
909 u32 flags;
910 int err;
911
912 err = crypto_authenc_extractkeys(&keys, key, keylen);
913 if (unlikely(err))
914 goto badkey;
915
916 err = -EINVAL;
917 if (keys.authkeylen + keys.enckeylen > TALITOS_MAX_KEY_SIZE)
918 goto badkey;
919
920 if (keys.enckeylen != DES3_EDE_KEY_SIZE)
921 goto badkey;
922
923 flags = crypto_aead_get_flags(authenc);
924 err = __des3_verify_key(&flags, keys.enckey);
925 if (unlikely(err)) {
926 crypto_aead_set_flags(authenc, flags);
927 goto out;
928 }
929
930 if (ctx->keylen)
931 dma_unmap_single(dev, ctx->dma_key, ctx->keylen, DMA_TO_DEVICE);
932
933 memcpy(ctx->key, keys.authkey, keys.authkeylen);
934 memcpy(&ctx->key[keys.authkeylen], keys.enckey, keys.enckeylen);
935
936 ctx->keylen = keys.authkeylen + keys.enckeylen;
937 ctx->enckeylen = keys.enckeylen;
938 ctx->authkeylen = keys.authkeylen;
939 ctx->dma_key = dma_map_single(dev, ctx->key, ctx->keylen,
940 DMA_TO_DEVICE);
941
942out:
943 memzero_explicit(&keys, sizeof(keys));
944 return err;
945
946badkey:
947 crypto_aead_set_flags(authenc, CRYPTO_TFM_RES_BAD_KEY_LEN);
948 goto out;
949}
950
Kim Phillips9c4a7962008-06-23 19:50:15 +0800951/*
Lee Nipper56af8cd2009-03-29 15:50:50 +0800952 * talitos_edesc - s/w-extended descriptor
Kim Phillips9c4a7962008-06-23 19:50:15 +0800953 * @src_nents: number of segments in input scatterlist
954 * @dst_nents: number of segments in output scatterlist
Herbert Xuaeb4c132015-07-30 17:53:22 +0800955 * @icv_ool: whether ICV is out-of-line
Horia Geanta79fd31d2012-08-02 17:16:40 +0300956 * @iv_dma: dma address of iv for checking continuity and link table
Kim Phillips9c4a7962008-06-23 19:50:15 +0800957 * @dma_len: length of dma mapped link_tbl space
LEROY Christophe6f65f6a2015-04-17 16:32:15 +0200958 * @dma_link_tbl: bus physical address of link_tbl/buf
Kim Phillips9c4a7962008-06-23 19:50:15 +0800959 * @desc: h/w descriptor
LEROY Christophe6f65f6a2015-04-17 16:32:15 +0200960 * @link_tbl: input and output h/w link tables (if {src,dst}_nents > 1) (SEC2)
961 * @buf: input and output buffeur (if {src,dst}_nents > 1) (SEC1)
Kim Phillips9c4a7962008-06-23 19:50:15 +0800962 *
963 * if decrypting (with authcheck), or either one of src_nents or dst_nents
964 * is greater than 1, an integrity check value is concatenated to the end
965 * of link_tbl data
966 */
Lee Nipper56af8cd2009-03-29 15:50:50 +0800967struct talitos_edesc {
Kim Phillips9c4a7962008-06-23 19:50:15 +0800968 int src_nents;
969 int dst_nents;
Herbert Xuaeb4c132015-07-30 17:53:22 +0800970 bool icv_ool;
Horia Geanta79fd31d2012-08-02 17:16:40 +0300971 dma_addr_t iv_dma;
Kim Phillips9c4a7962008-06-23 19:50:15 +0800972 int dma_len;
973 dma_addr_t dma_link_tbl;
974 struct talitos_desc desc;
LEROY Christophe6f65f6a2015-04-17 16:32:15 +0200975 union {
976 struct talitos_ptr link_tbl[0];
977 u8 buf[0];
978 };
Kim Phillips9c4a7962008-06-23 19:50:15 +0800979};
980
Lee Nipper4de9d0b2009-03-29 15:52:32 +0800981static void talitos_sg_unmap(struct device *dev,
982 struct talitos_edesc *edesc,
983 struct scatterlist *src,
LEROY Christophe6a1e8d12016-06-06 13:20:38 +0200984 struct scatterlist *dst,
985 unsigned int len, unsigned int offset)
LEROY Christophe246a87c2016-06-06 13:20:36 +0200986{
987 struct talitos_private *priv = dev_get_drvdata(dev);
988 bool is_sec1 = has_ftr_sec1(priv);
LEROY Christophe6a1e8d12016-06-06 13:20:38 +0200989 unsigned int src_nents = edesc->src_nents ? : 1;
990 unsigned int dst_nents = edesc->dst_nents ? : 1;
LEROY Christophe246a87c2016-06-06 13:20:36 +0200991
LEROY Christophe6a1e8d12016-06-06 13:20:38 +0200992 if (is_sec1 && dst && dst_nents > 1) {
993 dma_sync_single_for_device(dev, edesc->dma_link_tbl + offset,
994 len, DMA_FROM_DEVICE);
995 sg_pcopy_from_buffer(dst, dst_nents, edesc->buf + offset, len,
996 offset);
997 }
998 if (src != dst) {
999 if (src_nents == 1 || !is_sec1)
1000 dma_unmap_sg(dev, src, src_nents, DMA_TO_DEVICE);
1001
1002 if (dst && (dst_nents == 1 || !is_sec1))
1003 dma_unmap_sg(dev, dst, dst_nents, DMA_FROM_DEVICE);
1004 } else if (src_nents == 1 || !is_sec1) {
1005 dma_unmap_sg(dev, src, src_nents, DMA_BIDIRECTIONAL);
LEROY Christophe246a87c2016-06-06 13:20:36 +02001006 }
1007}
1008
Kim Phillips9c4a7962008-06-23 19:50:15 +08001009static void ipsec_esp_unmap(struct device *dev,
Lee Nipper56af8cd2009-03-29 15:50:50 +08001010 struct talitos_edesc *edesc,
Kim Phillips9c4a7962008-06-23 19:50:15 +08001011 struct aead_request *areq)
1012{
LEROY Christophe549bd8b2016-06-06 13:20:40 +02001013 struct crypto_aead *aead = crypto_aead_reqtfm(areq);
1014 struct talitos_ctx *ctx = crypto_aead_ctx(aead);
1015 unsigned int ivsize = crypto_aead_ivsize(aead);
LEROY Christophe9a655602017-10-06 15:04:59 +02001016 bool is_ipsec_esp = edesc->desc.hdr & DESC_HDR_TYPE_IPSEC_ESP;
1017 struct talitos_ptr *civ_ptr = &edesc->desc.ptr[is_ipsec_esp ? 2 : 3];
LEROY Christophe549bd8b2016-06-06 13:20:40 +02001018
LEROY Christophe9a655602017-10-06 15:04:59 +02001019 if (is_ipsec_esp)
LEROY Christophe549bd8b2016-06-06 13:20:40 +02001020 unmap_single_talitos_ptr(dev, &edesc->desc.ptr[6],
1021 DMA_FROM_DEVICE);
LEROY Christophe9a655602017-10-06 15:04:59 +02001022 unmap_single_talitos_ptr(dev, civ_ptr, DMA_TO_DEVICE);
Kim Phillips9c4a7962008-06-23 19:50:15 +08001023
LEROY Christophe6a1e8d12016-06-06 13:20:38 +02001024 talitos_sg_unmap(dev, edesc, areq->src, areq->dst, areq->cryptlen,
1025 areq->assoclen);
Kim Phillips9c4a7962008-06-23 19:50:15 +08001026
1027 if (edesc->dma_len)
1028 dma_unmap_single(dev, edesc->dma_link_tbl, edesc->dma_len,
1029 DMA_BIDIRECTIONAL);
LEROY Christophe549bd8b2016-06-06 13:20:40 +02001030
LEROY Christophe9a655602017-10-06 15:04:59 +02001031 if (!is_ipsec_esp) {
LEROY Christophe549bd8b2016-06-06 13:20:40 +02001032 unsigned int dst_nents = edesc->dst_nents ? : 1;
1033
1034 sg_pcopy_to_buffer(areq->dst, dst_nents, ctx->iv, ivsize,
1035 areq->assoclen + areq->cryptlen - ivsize);
1036 }
Kim Phillips9c4a7962008-06-23 19:50:15 +08001037}
1038
1039/*
1040 * ipsec_esp descriptor callbacks
1041 */
1042static void ipsec_esp_encrypt_done(struct device *dev,
1043 struct talitos_desc *desc, void *context,
1044 int err)
1045{
LEROY Christophe549bd8b2016-06-06 13:20:40 +02001046 struct talitos_private *priv = dev_get_drvdata(dev);
1047 bool is_sec1 = has_ftr_sec1(priv);
Kim Phillips9c4a7962008-06-23 19:50:15 +08001048 struct aead_request *areq = context;
Kim Phillips9c4a7962008-06-23 19:50:15 +08001049 struct crypto_aead *authenc = crypto_aead_reqtfm(areq);
Herbert Xuaeb4c132015-07-30 17:53:22 +08001050 unsigned int authsize = crypto_aead_authsize(authenc);
LEROY Christophe2e13ce02017-10-06 15:05:02 +02001051 unsigned int ivsize = crypto_aead_ivsize(authenc);
Kim Phillips19bbbc62009-03-29 15:53:59 +08001052 struct talitos_edesc *edesc;
Kim Phillips9c4a7962008-06-23 19:50:15 +08001053 struct scatterlist *sg;
1054 void *icvdata;
1055
Kim Phillips19bbbc62009-03-29 15:53:59 +08001056 edesc = container_of(desc, struct talitos_edesc, desc);
1057
Kim Phillips9c4a7962008-06-23 19:50:15 +08001058 ipsec_esp_unmap(dev, edesc, areq);
1059
1060 /* copy the generated ICV to dst */
Herbert Xuaeb4c132015-07-30 17:53:22 +08001061 if (edesc->icv_ool) {
LEROY Christophe549bd8b2016-06-06 13:20:40 +02001062 if (is_sec1)
1063 icvdata = edesc->buf + areq->assoclen + areq->cryptlen;
1064 else
1065 icvdata = &edesc->link_tbl[edesc->src_nents +
1066 edesc->dst_nents + 2];
Kim Phillips9c4a7962008-06-23 19:50:15 +08001067 sg = sg_last(areq->dst, edesc->dst_nents);
Herbert Xuaeb4c132015-07-30 17:53:22 +08001068 memcpy((char *)sg_virt(sg) + sg->length - authsize,
1069 icvdata, authsize);
Kim Phillips9c4a7962008-06-23 19:50:15 +08001070 }
1071
LEROY Christophe2e13ce02017-10-06 15:05:02 +02001072 dma_unmap_single(dev, edesc->iv_dma, ivsize, DMA_TO_DEVICE);
1073
Kim Phillips9c4a7962008-06-23 19:50:15 +08001074 kfree(edesc);
1075
1076 aead_request_complete(areq, err);
1077}
1078
Kim Phillipsfe5720e2008-10-12 20:33:14 +08001079static void ipsec_esp_decrypt_swauth_done(struct device *dev,
Kim Phillipse938e462009-03-29 15:53:23 +08001080 struct talitos_desc *desc,
1081 void *context, int err)
Kim Phillips9c4a7962008-06-23 19:50:15 +08001082{
1083 struct aead_request *req = context;
Kim Phillips9c4a7962008-06-23 19:50:15 +08001084 struct crypto_aead *authenc = crypto_aead_reqtfm(req);
Herbert Xuaeb4c132015-07-30 17:53:22 +08001085 unsigned int authsize = crypto_aead_authsize(authenc);
Kim Phillips19bbbc62009-03-29 15:53:59 +08001086 struct talitos_edesc *edesc;
Kim Phillips9c4a7962008-06-23 19:50:15 +08001087 struct scatterlist *sg;
Herbert Xuaeb4c132015-07-30 17:53:22 +08001088 char *oicv, *icv;
LEROY Christophe549bd8b2016-06-06 13:20:40 +02001089 struct talitos_private *priv = dev_get_drvdata(dev);
1090 bool is_sec1 = has_ftr_sec1(priv);
Kim Phillips9c4a7962008-06-23 19:50:15 +08001091
Kim Phillips19bbbc62009-03-29 15:53:59 +08001092 edesc = container_of(desc, struct talitos_edesc, desc);
1093
Kim Phillips9c4a7962008-06-23 19:50:15 +08001094 ipsec_esp_unmap(dev, edesc, req);
1095
1096 if (!err) {
1097 /* auth check */
Kim Phillips9c4a7962008-06-23 19:50:15 +08001098 sg = sg_last(req->dst, edesc->dst_nents ? : 1);
Herbert Xuaeb4c132015-07-30 17:53:22 +08001099 icv = (char *)sg_virt(sg) + sg->length - authsize;
1100
1101 if (edesc->dma_len) {
LEROY Christophe549bd8b2016-06-06 13:20:40 +02001102 if (is_sec1)
1103 oicv = (char *)&edesc->dma_link_tbl +
1104 req->assoclen + req->cryptlen;
1105 else
1106 oicv = (char *)
1107 &edesc->link_tbl[edesc->src_nents +
Herbert Xuaeb4c132015-07-30 17:53:22 +08001108 edesc->dst_nents + 2];
1109 if (edesc->icv_ool)
1110 icv = oicv + authsize;
1111 } else
1112 oicv = (char *)&edesc->link_tbl[0];
1113
David Gstir79960942015-11-15 17:14:42 +01001114 err = crypto_memneq(oicv, icv, authsize) ? -EBADMSG : 0;
Kim Phillips9c4a7962008-06-23 19:50:15 +08001115 }
1116
1117 kfree(edesc);
1118
1119 aead_request_complete(req, err);
1120}
1121
Kim Phillipsfe5720e2008-10-12 20:33:14 +08001122static void ipsec_esp_decrypt_hwauth_done(struct device *dev,
Kim Phillipse938e462009-03-29 15:53:23 +08001123 struct talitos_desc *desc,
1124 void *context, int err)
Kim Phillipsfe5720e2008-10-12 20:33:14 +08001125{
1126 struct aead_request *req = context;
Kim Phillips19bbbc62009-03-29 15:53:59 +08001127 struct talitos_edesc *edesc;
1128
1129 edesc = container_of(desc, struct talitos_edesc, desc);
Kim Phillipsfe5720e2008-10-12 20:33:14 +08001130
1131 ipsec_esp_unmap(dev, edesc, req);
1132
1133 /* check ICV auth status */
Kim Phillipse938e462009-03-29 15:53:23 +08001134 if (!err && ((desc->hdr_lo & DESC_HDR_LO_ICCR1_MASK) !=
1135 DESC_HDR_LO_ICCR1_PASS))
1136 err = -EBADMSG;
Kim Phillipsfe5720e2008-10-12 20:33:14 +08001137
1138 kfree(edesc);
1139
1140 aead_request_complete(req, err);
1141}
1142
Kim Phillips9c4a7962008-06-23 19:50:15 +08001143/*
1144 * convert scatterlist to SEC h/w link table format
1145 * stop at cryptlen bytes
1146 */
Herbert Xuaeb4c132015-07-30 17:53:22 +08001147static int sg_to_link_tbl_offset(struct scatterlist *sg, int sg_count,
1148 unsigned int offset, int cryptlen,
1149 struct talitos_ptr *link_tbl_ptr)
Kim Phillips9c4a7962008-06-23 19:50:15 +08001150{
Lee Nipper70bcaca2008-07-03 19:08:46 +08001151 int n_sg = sg_count;
Herbert Xuaeb4c132015-07-30 17:53:22 +08001152 int count = 0;
Lee Nipper70bcaca2008-07-03 19:08:46 +08001153
Herbert Xuaeb4c132015-07-30 17:53:22 +08001154 while (cryptlen && sg && n_sg--) {
1155 unsigned int len = sg_dma_len(sg);
1156
1157 if (offset >= len) {
1158 offset -= len;
1159 goto next;
1160 }
1161
1162 len -= offset;
1163
1164 if (len > cryptlen)
1165 len = cryptlen;
1166
1167 to_talitos_ptr(link_tbl_ptr + count,
LEROY Christopheda9de142017-10-06 15:04:57 +02001168 sg_dma_address(sg) + offset, len, 0);
LEROY Christopheb096b542016-06-06 13:20:34 +02001169 to_talitos_ptr_ext_set(link_tbl_ptr + count, 0, 0);
Herbert Xuaeb4c132015-07-30 17:53:22 +08001170 count++;
1171 cryptlen -= len;
1172 offset = 0;
1173
1174next:
Cristian Stoica5be4d4c2015-01-20 10:06:16 +02001175 sg = sg_next(sg);
Kim Phillips9c4a7962008-06-23 19:50:15 +08001176 }
1177
Kim Phillips9c4a7962008-06-23 19:50:15 +08001178 /* tag end of link table */
Herbert Xuaeb4c132015-07-30 17:53:22 +08001179 if (count > 0)
LEROY Christopheb096b542016-06-06 13:20:34 +02001180 to_talitos_ptr_ext_set(link_tbl_ptr + count - 1,
1181 DESC_PTR_LNKTBL_RETURN, 0);
Lee Nipper70bcaca2008-07-03 19:08:46 +08001182
Herbert Xuaeb4c132015-07-30 17:53:22 +08001183 return count;
1184}
1185
LEROY Christophe2b122732018-03-22 10:57:01 +01001186static int talitos_sg_map_ext(struct device *dev, struct scatterlist *src,
1187 unsigned int len, struct talitos_edesc *edesc,
1188 struct talitos_ptr *ptr, int sg_count,
1189 unsigned int offset, int tbl_off, int elen)
LEROY Christophe246a87c2016-06-06 13:20:36 +02001190{
LEROY Christophe246a87c2016-06-06 13:20:36 +02001191 struct talitos_private *priv = dev_get_drvdata(dev);
1192 bool is_sec1 = has_ftr_sec1(priv);
1193
LEROY Christophe87a81dc2018-01-26 17:09:59 +01001194 if (!src) {
1195 to_talitos_ptr(ptr, 0, 0, is_sec1);
1196 return 1;
1197 }
LEROY Christophe2b122732018-03-22 10:57:01 +01001198 to_talitos_ptr_ext_set(ptr, elen, is_sec1);
LEROY Christophe6a1e8d12016-06-06 13:20:38 +02001199 if (sg_count == 1) {
LEROY Christopheda9de142017-10-06 15:04:57 +02001200 to_talitos_ptr(ptr, sg_dma_address(src) + offset, len, is_sec1);
LEROY Christophe6a1e8d12016-06-06 13:20:38 +02001201 return sg_count;
LEROY Christophe246a87c2016-06-06 13:20:36 +02001202 }
LEROY Christophe6a1e8d12016-06-06 13:20:38 +02001203 if (is_sec1) {
LEROY Christopheda9de142017-10-06 15:04:57 +02001204 to_talitos_ptr(ptr, edesc->dma_link_tbl + offset, len, is_sec1);
LEROY Christophe6a1e8d12016-06-06 13:20:38 +02001205 return sg_count;
1206 }
LEROY Christophe2b122732018-03-22 10:57:01 +01001207 sg_count = sg_to_link_tbl_offset(src, sg_count, offset, len + elen,
LEROY Christophe6a1e8d12016-06-06 13:20:38 +02001208 &edesc->link_tbl[tbl_off]);
1209 if (sg_count == 1) {
1210 /* Only one segment now, so no link tbl needed*/
1211 copy_talitos_ptr(ptr, &edesc->link_tbl[tbl_off], is_sec1);
1212 return sg_count;
1213 }
1214 to_talitos_ptr(ptr, edesc->dma_link_tbl +
LEROY Christopheda9de142017-10-06 15:04:57 +02001215 tbl_off * sizeof(struct talitos_ptr), len, is_sec1);
LEROY Christophe6a1e8d12016-06-06 13:20:38 +02001216 to_talitos_ptr_ext_or(ptr, DESC_PTR_LNKTBL_JUMP, is_sec1);
1217
LEROY Christophe246a87c2016-06-06 13:20:36 +02001218 return sg_count;
1219}
1220
LEROY Christophe2b122732018-03-22 10:57:01 +01001221static int talitos_sg_map(struct device *dev, struct scatterlist *src,
1222 unsigned int len, struct talitos_edesc *edesc,
1223 struct talitos_ptr *ptr, int sg_count,
1224 unsigned int offset, int tbl_off)
1225{
1226 return talitos_sg_map_ext(dev, src, len, edesc, ptr, sg_count, offset,
1227 tbl_off, 0);
1228}
1229
Kim Phillips9c4a7962008-06-23 19:50:15 +08001230/*
1231 * fill in and submit ipsec_esp descriptor
1232 */
Lee Nipper56af8cd2009-03-29 15:50:50 +08001233static int ipsec_esp(struct talitos_edesc *edesc, struct aead_request *areq,
Herbert Xuaeb4c132015-07-30 17:53:22 +08001234 void (*callback)(struct device *dev,
1235 struct talitos_desc *desc,
1236 void *context, int error))
Kim Phillips9c4a7962008-06-23 19:50:15 +08001237{
1238 struct crypto_aead *aead = crypto_aead_reqtfm(areq);
Herbert Xuaeb4c132015-07-30 17:53:22 +08001239 unsigned int authsize = crypto_aead_authsize(aead);
Kim Phillips9c4a7962008-06-23 19:50:15 +08001240 struct talitos_ctx *ctx = crypto_aead_ctx(aead);
1241 struct device *dev = ctx->dev;
1242 struct talitos_desc *desc = &edesc->desc;
1243 unsigned int cryptlen = areq->cryptlen;
Kim Phillipse41256f2009-08-13 11:49:06 +10001244 unsigned int ivsize = crypto_aead_ivsize(aead);
Herbert Xuaeb4c132015-07-30 17:53:22 +08001245 int tbl_off = 0;
Kim Phillipsfa86a262008-07-17 20:20:06 +08001246 int sg_count, ret;
LEROY Christophe2b122732018-03-22 10:57:01 +01001247 int elen = 0;
LEROY Christophe549bd8b2016-06-06 13:20:40 +02001248 bool sync_needed = false;
1249 struct talitos_private *priv = dev_get_drvdata(dev);
1250 bool is_sec1 = has_ftr_sec1(priv);
LEROY Christophe9a655602017-10-06 15:04:59 +02001251 bool is_ipsec_esp = desc->hdr & DESC_HDR_TYPE_IPSEC_ESP;
1252 struct talitos_ptr *civ_ptr = &desc->ptr[is_ipsec_esp ? 2 : 3];
1253 struct talitos_ptr *ckey_ptr = &desc->ptr[is_ipsec_esp ? 3 : 2];
Kim Phillips9c4a7962008-06-23 19:50:15 +08001254
1255 /* hmac key */
LEROY Christophe2e13ce02017-10-06 15:05:02 +02001256 to_talitos_ptr(&desc->ptr[0], ctx->dma_key, ctx->authkeylen, is_sec1);
Horia Geanta79fd31d2012-08-02 17:16:40 +03001257
LEROY Christophe549bd8b2016-06-06 13:20:40 +02001258 sg_count = edesc->src_nents ?: 1;
1259 if (is_sec1 && sg_count > 1)
1260 sg_copy_to_buffer(areq->src, sg_count, edesc->buf,
1261 areq->assoclen + cryptlen);
1262 else
1263 sg_count = dma_map_sg(dev, areq->src, sg_count,
1264 (areq->src == areq->dst) ?
1265 DMA_BIDIRECTIONAL : DMA_TO_DEVICE);
1266
Kim Phillips9c4a7962008-06-23 19:50:15 +08001267 /* hmac data */
LEROY Christophe549bd8b2016-06-06 13:20:40 +02001268 ret = talitos_sg_map(dev, areq->src, areq->assoclen, edesc,
1269 &desc->ptr[1], sg_count, 0, tbl_off);
Horia Geanta79fd31d2012-08-02 17:16:40 +03001270
LEROY Christophe549bd8b2016-06-06 13:20:40 +02001271 if (ret > 1) {
Horia Geant?340ff602016-04-19 20:33:48 +03001272 tbl_off += ret;
LEROY Christophe549bd8b2016-06-06 13:20:40 +02001273 sync_needed = true;
Horia Geanta79fd31d2012-08-02 17:16:40 +03001274 }
1275
Kim Phillips9c4a7962008-06-23 19:50:15 +08001276 /* cipher iv */
LEROY Christophe9a655602017-10-06 15:04:59 +02001277 to_talitos_ptr(civ_ptr, edesc->iv_dma, ivsize, is_sec1);
Kim Phillips9c4a7962008-06-23 19:50:15 +08001278
1279 /* cipher key */
LEROY Christophe2e13ce02017-10-06 15:05:02 +02001280 to_talitos_ptr(ckey_ptr, ctx->dma_key + ctx->authkeylen,
1281 ctx->enckeylen, is_sec1);
Kim Phillips9c4a7962008-06-23 19:50:15 +08001282
1283 /*
1284 * cipher in
1285 * map and adjust cipher len to aead request cryptlen.
1286 * extent is bytes of HMAC postpended to ciphertext,
1287 * typically 12 for ipsec
1288 */
LEROY Christophe2b122732018-03-22 10:57:01 +01001289 if (is_ipsec_esp && (desc->hdr & DESC_HDR_MODE1_MDEU_CICV))
1290 elen = authsize;
Kim Phillips9c4a7962008-06-23 19:50:15 +08001291
LEROY Christophe2b122732018-03-22 10:57:01 +01001292 ret = talitos_sg_map_ext(dev, areq->src, cryptlen, edesc, &desc->ptr[4],
1293 sg_count, areq->assoclen, tbl_off, elen);
LEROY Christophe549bd8b2016-06-06 13:20:40 +02001294
LEROY Christopheec8c7d12017-10-06 15:04:33 +02001295 if (ret > 1) {
1296 tbl_off += ret;
LEROY Christophe549bd8b2016-06-06 13:20:40 +02001297 sync_needed = true;
Horia Geant?340ff602016-04-19 20:33:48 +03001298 }
Kim Phillips9c4a7962008-06-23 19:50:15 +08001299
1300 /* cipher out */
LEROY Christophe549bd8b2016-06-06 13:20:40 +02001301 if (areq->src != areq->dst) {
1302 sg_count = edesc->dst_nents ? : 1;
1303 if (!is_sec1 || sg_count == 1)
1304 dma_map_sg(dev, areq->dst, sg_count, DMA_FROM_DEVICE);
1305 }
Kim Phillips9c4a7962008-06-23 19:50:15 +08001306
LEROY Christophee04a61b2017-10-06 15:04:35 +02001307 ret = talitos_sg_map(dev, areq->dst, cryptlen, edesc, &desc->ptr[5],
1308 sg_count, areq->assoclen, tbl_off);
Kim Phillips9c4a7962008-06-23 19:50:15 +08001309
LEROY Christophe9a655602017-10-06 15:04:59 +02001310 if (is_ipsec_esp)
LEROY Christophe549bd8b2016-06-06 13:20:40 +02001311 to_talitos_ptr_ext_or(&desc->ptr[5], authsize, is_sec1);
Herbert Xuaeb4c132015-07-30 17:53:22 +08001312
LEROY Christophee04a61b2017-10-06 15:04:35 +02001313 /* ICV data */
1314 if (ret > 1) {
1315 tbl_off += ret;
Herbert Xuaeb4c132015-07-30 17:53:22 +08001316 edesc->icv_ool = true;
LEROY Christophe549bd8b2016-06-06 13:20:40 +02001317 sync_needed = true;
1318
LEROY Christophe9a655602017-10-06 15:04:59 +02001319 if (is_ipsec_esp) {
LEROY Christophe549bd8b2016-06-06 13:20:40 +02001320 struct talitos_ptr *tbl_ptr = &edesc->link_tbl[tbl_off];
1321 int offset = (edesc->src_nents + edesc->dst_nents + 2) *
1322 sizeof(struct talitos_ptr) + authsize;
1323
1324 /* Add an entry to the link table for ICV data */
LEROY Christophee04a61b2017-10-06 15:04:35 +02001325 to_talitos_ptr_ext_set(tbl_ptr - 1, 0, is_sec1);
LEROY Christophe549bd8b2016-06-06 13:20:40 +02001326 to_talitos_ptr_ext_set(tbl_ptr, DESC_PTR_LNKTBL_RETURN,
1327 is_sec1);
LEROY Christophe549bd8b2016-06-06 13:20:40 +02001328
1329 /* icv data follows link tables */
1330 to_talitos_ptr(tbl_ptr, edesc->dma_link_tbl + offset,
LEROY Christopheda9de142017-10-06 15:04:57 +02001331 authsize, is_sec1);
LEROY Christophee04a61b2017-10-06 15:04:35 +02001332 } else {
1333 dma_addr_t addr = edesc->dma_link_tbl;
1334
1335 if (is_sec1)
1336 addr += areq->assoclen + cryptlen;
1337 else
1338 addr += sizeof(struct talitos_ptr) * tbl_off;
1339
LEROY Christopheda9de142017-10-06 15:04:57 +02001340 to_talitos_ptr(&desc->ptr[6], addr, authsize, is_sec1);
LEROY Christophee04a61b2017-10-06 15:04:35 +02001341 }
LEROY Christophe9a655602017-10-06 15:04:59 +02001342 } else if (!is_ipsec_esp) {
LEROY Christophee04a61b2017-10-06 15:04:35 +02001343 ret = talitos_sg_map(dev, areq->dst, authsize, edesc,
1344 &desc->ptr[6], sg_count, areq->assoclen +
1345 cryptlen,
1346 tbl_off);
1347 if (ret > 1) {
1348 tbl_off += ret;
1349 edesc->icv_ool = true;
1350 sync_needed = true;
1351 } else {
1352 edesc->icv_ool = false;
LEROY Christophe549bd8b2016-06-06 13:20:40 +02001353 }
Horia Geant?340ff602016-04-19 20:33:48 +03001354 } else {
LEROY Christophe549bd8b2016-06-06 13:20:40 +02001355 edesc->icv_ool = false;
1356 }
1357
Kim Phillips9c4a7962008-06-23 19:50:15 +08001358 /* iv out */
LEROY Christophe9a655602017-10-06 15:04:59 +02001359 if (is_ipsec_esp)
LEROY Christophe549bd8b2016-06-06 13:20:40 +02001360 map_single_talitos_ptr(dev, &desc->ptr[6], ivsize, ctx->iv,
1361 DMA_FROM_DEVICE);
1362
1363 if (sync_needed)
1364 dma_sync_single_for_device(dev, edesc->dma_link_tbl,
1365 edesc->dma_len,
1366 DMA_BIDIRECTIONAL);
Kim Phillips9c4a7962008-06-23 19:50:15 +08001367
Kim Phillips5228f0f2011-07-15 11:21:38 +08001368 ret = talitos_submit(dev, ctx->ch, desc, callback, areq);
Kim Phillipsfa86a262008-07-17 20:20:06 +08001369 if (ret != -EINPROGRESS) {
1370 ipsec_esp_unmap(dev, edesc, areq);
1371 kfree(edesc);
1372 }
1373 return ret;
Kim Phillips9c4a7962008-06-23 19:50:15 +08001374}
1375
Kim Phillips9c4a7962008-06-23 19:50:15 +08001376/*
Lee Nipper56af8cd2009-03-29 15:50:50 +08001377 * allocate and map the extended descriptor
Kim Phillips9c4a7962008-06-23 19:50:15 +08001378 */
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001379static struct talitos_edesc *talitos_edesc_alloc(struct device *dev,
1380 struct scatterlist *src,
1381 struct scatterlist *dst,
Horia Geanta79fd31d2012-08-02 17:16:40 +03001382 u8 *iv,
1383 unsigned int assoclen,
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001384 unsigned int cryptlen,
1385 unsigned int authsize,
Horia Geanta79fd31d2012-08-02 17:16:40 +03001386 unsigned int ivsize,
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001387 int icv_stashing,
Horia Geanta62293a32013-11-28 15:11:17 +02001388 u32 cryptoflags,
1389 bool encrypt)
Kim Phillips9c4a7962008-06-23 19:50:15 +08001390{
Lee Nipper56af8cd2009-03-29 15:50:50 +08001391 struct talitos_edesc *edesc;
LEROY Christophe6a1e8d12016-06-06 13:20:38 +02001392 int src_nents, dst_nents, alloc_len, dma_len, src_len, dst_len;
Horia Geanta79fd31d2012-08-02 17:16:40 +03001393 dma_addr_t iv_dma = 0;
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001394 gfp_t flags = cryptoflags & CRYPTO_TFM_REQ_MAY_SLEEP ? GFP_KERNEL :
Kim Phillips586725f2008-07-17 20:19:18 +08001395 GFP_ATOMIC;
LEROY Christophe6f65f6a2015-04-17 16:32:15 +02001396 struct talitos_private *priv = dev_get_drvdata(dev);
1397 bool is_sec1 = has_ftr_sec1(priv);
1398 int max_len = is_sec1 ? TALITOS1_MAX_DATA_LEN : TALITOS2_MAX_DATA_LEN;
Kim Phillips9c4a7962008-06-23 19:50:15 +08001399
LEROY Christophe6f65f6a2015-04-17 16:32:15 +02001400 if (cryptlen + authsize > max_len) {
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001401 dev_err(dev, "length exceeds h/w max limit\n");
Kim Phillips9c4a7962008-06-23 19:50:15 +08001402 return ERR_PTR(-EINVAL);
1403 }
1404
Horia Geanta62293a32013-11-28 15:11:17 +02001405 if (!dst || dst == src) {
LEROY Christophe6a1e8d12016-06-06 13:20:38 +02001406 src_len = assoclen + cryptlen + authsize;
1407 src_nents = sg_nents_for_len(src, src_len);
LABBE Corentin8e409fe2015-11-04 21:13:34 +01001408 if (src_nents < 0) {
1409 dev_err(dev, "Invalid number of src SG.\n");
Christophe Leroyc56c2e12019-01-08 06:56:46 +00001410 return ERR_PTR(-EINVAL);
LABBE Corentin8e409fe2015-11-04 21:13:34 +01001411 }
Horia Geanta62293a32013-11-28 15:11:17 +02001412 src_nents = (src_nents == 1) ? 0 : src_nents;
1413 dst_nents = dst ? src_nents : 0;
LEROY Christophe6a1e8d12016-06-06 13:20:38 +02001414 dst_len = 0;
Horia Geanta62293a32013-11-28 15:11:17 +02001415 } else { /* dst && dst != src*/
LEROY Christophe6a1e8d12016-06-06 13:20:38 +02001416 src_len = assoclen + cryptlen + (encrypt ? 0 : authsize);
1417 src_nents = sg_nents_for_len(src, src_len);
LABBE Corentin8e409fe2015-11-04 21:13:34 +01001418 if (src_nents < 0) {
1419 dev_err(dev, "Invalid number of src SG.\n");
Christophe Leroyc56c2e12019-01-08 06:56:46 +00001420 return ERR_PTR(-EINVAL);
LABBE Corentin8e409fe2015-11-04 21:13:34 +01001421 }
Horia Geanta62293a32013-11-28 15:11:17 +02001422 src_nents = (src_nents == 1) ? 0 : src_nents;
LEROY Christophe6a1e8d12016-06-06 13:20:38 +02001423 dst_len = assoclen + cryptlen + (encrypt ? authsize : 0);
1424 dst_nents = sg_nents_for_len(dst, dst_len);
LABBE Corentin8e409fe2015-11-04 21:13:34 +01001425 if (dst_nents < 0) {
1426 dev_err(dev, "Invalid number of dst SG.\n");
Christophe Leroyc56c2e12019-01-08 06:56:46 +00001427 return ERR_PTR(-EINVAL);
LABBE Corentin8e409fe2015-11-04 21:13:34 +01001428 }
Horia Geanta62293a32013-11-28 15:11:17 +02001429 dst_nents = (dst_nents == 1) ? 0 : dst_nents;
Kim Phillips9c4a7962008-06-23 19:50:15 +08001430 }
1431
1432 /*
1433 * allocate space for base edesc plus the link tables,
Herbert Xuaeb4c132015-07-30 17:53:22 +08001434 * allowing for two separate entries for AD and generated ICV (+ 2),
1435 * and space for two sets of ICVs (stashed and generated)
Kim Phillips9c4a7962008-06-23 19:50:15 +08001436 */
Lee Nipper56af8cd2009-03-29 15:50:50 +08001437 alloc_len = sizeof(struct talitos_edesc);
Herbert Xuaeb4c132015-07-30 17:53:22 +08001438 if (src_nents || dst_nents) {
LEROY Christophe6f65f6a2015-04-17 16:32:15 +02001439 if (is_sec1)
LEROY Christophe6a1e8d12016-06-06 13:20:38 +02001440 dma_len = (src_nents ? src_len : 0) +
1441 (dst_nents ? dst_len : 0);
LEROY Christophe6f65f6a2015-04-17 16:32:15 +02001442 else
Herbert Xuaeb4c132015-07-30 17:53:22 +08001443 dma_len = (src_nents + dst_nents + 2) *
1444 sizeof(struct talitos_ptr) + authsize * 2;
Kim Phillips9c4a7962008-06-23 19:50:15 +08001445 alloc_len += dma_len;
1446 } else {
1447 dma_len = 0;
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001448 alloc_len += icv_stashing ? authsize : 0;
Kim Phillips9c4a7962008-06-23 19:50:15 +08001449 }
1450
LEROY Christophe37b5e882017-10-06 15:05:06 +02001451 /* if its a ahash, add space for a second desc next to the first one */
1452 if (is_sec1 && !dst)
1453 alloc_len += sizeof(struct talitos_desc);
Christophe Leroy1bea4452019-01-08 06:56:48 +00001454 alloc_len += ivsize;
LEROY Christophe37b5e882017-10-06 15:05:06 +02001455
Kim Phillips586725f2008-07-17 20:19:18 +08001456 edesc = kmalloc(alloc_len, GFP_DMA | flags);
Christophe Leroyc56c2e12019-01-08 06:56:46 +00001457 if (!edesc)
1458 return ERR_PTR(-ENOMEM);
Christophe Leroy1bea4452019-01-08 06:56:48 +00001459 if (ivsize) {
1460 iv = memcpy(((u8 *)edesc) + alloc_len - ivsize, iv, ivsize);
Christophe Leroyc56c2e12019-01-08 06:56:46 +00001461 iv_dma = dma_map_single(dev, iv, ivsize, DMA_TO_DEVICE);
Christophe Leroy1bea4452019-01-08 06:56:48 +00001462 }
LEROY Christophee4a647c2017-10-06 15:04:45 +02001463 memset(&edesc->desc, 0, sizeof(edesc->desc));
Kim Phillips9c4a7962008-06-23 19:50:15 +08001464
1465 edesc->src_nents = src_nents;
1466 edesc->dst_nents = dst_nents;
Horia Geanta79fd31d2012-08-02 17:16:40 +03001467 edesc->iv_dma = iv_dma;
Kim Phillips9c4a7962008-06-23 19:50:15 +08001468 edesc->dma_len = dma_len;
LEROY Christophe37b5e882017-10-06 15:05:06 +02001469 if (dma_len) {
1470 void *addr = &edesc->link_tbl[0];
1471
1472 if (is_sec1 && !dst)
1473 addr += sizeof(struct talitos_desc);
1474 edesc->dma_link_tbl = dma_map_single(dev, addr,
Lee Nipper497f2e62010-05-19 19:20:36 +10001475 edesc->dma_len,
1476 DMA_BIDIRECTIONAL);
LEROY Christophe37b5e882017-10-06 15:05:06 +02001477 }
Kim Phillips9c4a7962008-06-23 19:50:15 +08001478 return edesc;
1479}
1480
Horia Geanta79fd31d2012-08-02 17:16:40 +03001481static struct talitos_edesc *aead_edesc_alloc(struct aead_request *areq, u8 *iv,
Horia Geanta62293a32013-11-28 15:11:17 +02001482 int icv_stashing, bool encrypt)
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001483{
1484 struct crypto_aead *authenc = crypto_aead_reqtfm(areq);
Herbert Xuaeb4c132015-07-30 17:53:22 +08001485 unsigned int authsize = crypto_aead_authsize(authenc);
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001486 struct talitos_ctx *ctx = crypto_aead_ctx(authenc);
Horia Geanta79fd31d2012-08-02 17:16:40 +03001487 unsigned int ivsize = crypto_aead_ivsize(authenc);
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001488
Herbert Xuaeb4c132015-07-30 17:53:22 +08001489 return talitos_edesc_alloc(ctx->dev, areq->src, areq->dst,
Horia Geanta79fd31d2012-08-02 17:16:40 +03001490 iv, areq->assoclen, areq->cryptlen,
Herbert Xuaeb4c132015-07-30 17:53:22 +08001491 authsize, ivsize, icv_stashing,
Horia Geanta62293a32013-11-28 15:11:17 +02001492 areq->base.flags, encrypt);
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001493}
1494
Lee Nipper56af8cd2009-03-29 15:50:50 +08001495static int aead_encrypt(struct aead_request *req)
Kim Phillips9c4a7962008-06-23 19:50:15 +08001496{
1497 struct crypto_aead *authenc = crypto_aead_reqtfm(req);
1498 struct talitos_ctx *ctx = crypto_aead_ctx(authenc);
Lee Nipper56af8cd2009-03-29 15:50:50 +08001499 struct talitos_edesc *edesc;
Kim Phillips9c4a7962008-06-23 19:50:15 +08001500
1501 /* allocate extended descriptor */
Horia Geanta62293a32013-11-28 15:11:17 +02001502 edesc = aead_edesc_alloc(req, req->iv, 0, true);
Kim Phillips9c4a7962008-06-23 19:50:15 +08001503 if (IS_ERR(edesc))
1504 return PTR_ERR(edesc);
1505
1506 /* set encrypt */
Lee Nipper70bcaca2008-07-03 19:08:46 +08001507 edesc->desc.hdr = ctx->desc_hdr_template | DESC_HDR_MODE0_ENCRYPT;
Kim Phillips9c4a7962008-06-23 19:50:15 +08001508
Herbert Xuaeb4c132015-07-30 17:53:22 +08001509 return ipsec_esp(edesc, req, ipsec_esp_encrypt_done);
Kim Phillips9c4a7962008-06-23 19:50:15 +08001510}
1511
Lee Nipper56af8cd2009-03-29 15:50:50 +08001512static int aead_decrypt(struct aead_request *req)
Kim Phillips9c4a7962008-06-23 19:50:15 +08001513{
1514 struct crypto_aead *authenc = crypto_aead_reqtfm(req);
Herbert Xuaeb4c132015-07-30 17:53:22 +08001515 unsigned int authsize = crypto_aead_authsize(authenc);
Kim Phillips9c4a7962008-06-23 19:50:15 +08001516 struct talitos_ctx *ctx = crypto_aead_ctx(authenc);
Kim Phillipsfe5720e2008-10-12 20:33:14 +08001517 struct talitos_private *priv = dev_get_drvdata(ctx->dev);
Lee Nipper56af8cd2009-03-29 15:50:50 +08001518 struct talitos_edesc *edesc;
Kim Phillips9c4a7962008-06-23 19:50:15 +08001519 struct scatterlist *sg;
1520 void *icvdata;
1521
1522 req->cryptlen -= authsize;
1523
1524 /* allocate extended descriptor */
Horia Geanta62293a32013-11-28 15:11:17 +02001525 edesc = aead_edesc_alloc(req, req->iv, 1, false);
Kim Phillips9c4a7962008-06-23 19:50:15 +08001526 if (IS_ERR(edesc))
1527 return PTR_ERR(edesc);
1528
Kim Phillipsfe5720e2008-10-12 20:33:14 +08001529 if ((priv->features & TALITOS_FTR_HW_AUTH_CHECK) &&
Kim Phillipse938e462009-03-29 15:53:23 +08001530 ((!edesc->src_nents && !edesc->dst_nents) ||
1531 priv->features & TALITOS_FTR_SRC_LINK_TBL_LEN_INCLUDES_EXTENT)) {
Kim Phillips9c4a7962008-06-23 19:50:15 +08001532
Kim Phillipsfe5720e2008-10-12 20:33:14 +08001533 /* decrypt and check the ICV */
Kim Phillipse938e462009-03-29 15:53:23 +08001534 edesc->desc.hdr = ctx->desc_hdr_template |
1535 DESC_HDR_DIR_INBOUND |
Kim Phillipsfe5720e2008-10-12 20:33:14 +08001536 DESC_HDR_MODE1_MDEU_CICV;
Kim Phillips9c4a7962008-06-23 19:50:15 +08001537
Kim Phillipsfe5720e2008-10-12 20:33:14 +08001538 /* reset integrity check result bits */
Kim Phillips9c4a7962008-06-23 19:50:15 +08001539
Herbert Xuaeb4c132015-07-30 17:53:22 +08001540 return ipsec_esp(edesc, req, ipsec_esp_decrypt_hwauth_done);
Kim Phillipsfe5720e2008-10-12 20:33:14 +08001541 }
Kim Phillipse938e462009-03-29 15:53:23 +08001542
1543 /* Have to check the ICV with software */
1544 edesc->desc.hdr = ctx->desc_hdr_template | DESC_HDR_DIR_INBOUND;
1545
1546 /* stash incoming ICV for later cmp with ICV generated by the h/w */
1547 if (edesc->dma_len)
Herbert Xuaeb4c132015-07-30 17:53:22 +08001548 icvdata = (char *)&edesc->link_tbl[edesc->src_nents +
1549 edesc->dst_nents + 2];
Kim Phillipse938e462009-03-29 15:53:23 +08001550 else
1551 icvdata = &edesc->link_tbl[0];
1552
1553 sg = sg_last(req->src, edesc->src_nents ? : 1);
1554
Herbert Xuaeb4c132015-07-30 17:53:22 +08001555 memcpy(icvdata, (char *)sg_virt(sg) + sg->length - authsize, authsize);
Kim Phillipse938e462009-03-29 15:53:23 +08001556
Herbert Xuaeb4c132015-07-30 17:53:22 +08001557 return ipsec_esp(edesc, req, ipsec_esp_decrypt_swauth_done);
Kim Phillips9c4a7962008-06-23 19:50:15 +08001558}
1559
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001560static int ablkcipher_setkey(struct crypto_ablkcipher *cipher,
1561 const u8 *key, unsigned int keylen)
1562{
1563 struct talitos_ctx *ctx = crypto_ablkcipher_ctx(cipher);
LEROY Christophe2e13ce02017-10-06 15:05:02 +02001564 struct device *dev = ctx->dev;
LEROY Christophef384cdc2017-10-06 15:04:37 +02001565
LEROY Christophe2e13ce02017-10-06 15:05:02 +02001566 if (ctx->keylen)
1567 dma_unmap_single(dev, ctx->dma_key, ctx->keylen, DMA_TO_DEVICE);
1568
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001569 memcpy(&ctx->key, key, keylen);
1570 ctx->keylen = keylen;
1571
LEROY Christophe2e13ce02017-10-06 15:05:02 +02001572 ctx->dma_key = dma_map_single(dev, ctx->key, keylen, DMA_TO_DEVICE);
1573
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001574 return 0;
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001575}
1576
Herbert Xuef7c5c82019-04-11 16:51:21 +08001577static int ablkcipher_des_setkey(struct crypto_ablkcipher *cipher,
1578 const u8 *key, unsigned int keylen)
1579{
1580 u32 tmp[DES_EXPKEY_WORDS];
1581
1582 if (unlikely(crypto_ablkcipher_get_flags(cipher) &
1583 CRYPTO_TFM_REQ_FORBID_WEAK_KEYS) &&
1584 !des_ekey(tmp, key)) {
1585 crypto_ablkcipher_set_flags(cipher, CRYPTO_TFM_RES_WEAK_KEY);
1586 return -EINVAL;
1587 }
1588
1589 return ablkcipher_setkey(cipher, key, keylen);
1590}
1591
1592static int ablkcipher_des3_setkey(struct crypto_ablkcipher *cipher,
1593 const u8 *key, unsigned int keylen)
1594{
1595 u32 flags;
1596 int err;
1597
1598 flags = crypto_ablkcipher_get_flags(cipher);
1599 err = __des3_verify_key(&flags, key);
1600 if (unlikely(err)) {
1601 crypto_ablkcipher_set_flags(cipher, flags);
1602 return err;
1603 }
1604
1605 return ablkcipher_setkey(cipher, key, keylen);
1606}
1607
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001608static void common_nonsnoop_unmap(struct device *dev,
1609 struct talitos_edesc *edesc,
1610 struct ablkcipher_request *areq)
1611{
1612 unmap_single_talitos_ptr(dev, &edesc->desc.ptr[5], DMA_FROM_DEVICE);
LEROY Christophe032d1972015-04-17 16:31:51 +02001613
LEROY Christophe6a1e8d12016-06-06 13:20:38 +02001614 talitos_sg_unmap(dev, edesc, areq->src, areq->dst, areq->nbytes, 0);
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001615 unmap_single_talitos_ptr(dev, &edesc->desc.ptr[1], DMA_TO_DEVICE);
1616
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001617 if (edesc->dma_len)
1618 dma_unmap_single(dev, edesc->dma_link_tbl, edesc->dma_len,
1619 DMA_BIDIRECTIONAL);
1620}
1621
1622static void ablkcipher_done(struct device *dev,
1623 struct talitos_desc *desc, void *context,
1624 int err)
1625{
1626 struct ablkcipher_request *areq = context;
Kim Phillips19bbbc62009-03-29 15:53:59 +08001627 struct talitos_edesc *edesc;
1628
1629 edesc = container_of(desc, struct talitos_edesc, desc);
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001630
1631 common_nonsnoop_unmap(dev, edesc, areq);
1632
1633 kfree(edesc);
1634
1635 areq->base.complete(&areq->base, err);
1636}
1637
1638static int common_nonsnoop(struct talitos_edesc *edesc,
1639 struct ablkcipher_request *areq,
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001640 void (*callback) (struct device *dev,
1641 struct talitos_desc *desc,
1642 void *context, int error))
1643{
1644 struct crypto_ablkcipher *cipher = crypto_ablkcipher_reqtfm(areq);
1645 struct talitos_ctx *ctx = crypto_ablkcipher_ctx(cipher);
1646 struct device *dev = ctx->dev;
1647 struct talitos_desc *desc = &edesc->desc;
1648 unsigned int cryptlen = areq->nbytes;
Horia Geanta79fd31d2012-08-02 17:16:40 +03001649 unsigned int ivsize = crypto_ablkcipher_ivsize(cipher);
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001650 int sg_count, ret;
LEROY Christophe6a1e8d12016-06-06 13:20:38 +02001651 bool sync_needed = false;
LEROY Christophe922f9dc2015-04-17 16:32:07 +02001652 struct talitos_private *priv = dev_get_drvdata(dev);
1653 bool is_sec1 = has_ftr_sec1(priv);
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001654
1655 /* first DWORD empty */
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001656
1657 /* cipher iv */
LEROY Christopheda9de142017-10-06 15:04:57 +02001658 to_talitos_ptr(&desc->ptr[1], edesc->iv_dma, ivsize, is_sec1);
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001659
1660 /* cipher key */
LEROY Christophe2e13ce02017-10-06 15:05:02 +02001661 to_talitos_ptr(&desc->ptr[2], ctx->dma_key, ctx->keylen, is_sec1);
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001662
LEROY Christophe6a1e8d12016-06-06 13:20:38 +02001663 sg_count = edesc->src_nents ?: 1;
1664 if (is_sec1 && sg_count > 1)
1665 sg_copy_to_buffer(areq->src, sg_count, edesc->buf,
1666 cryptlen);
1667 else
1668 sg_count = dma_map_sg(dev, areq->src, sg_count,
1669 (areq->src == areq->dst) ?
1670 DMA_BIDIRECTIONAL : DMA_TO_DEVICE);
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001671 /*
1672 * cipher in
1673 */
LEROY Christophe6a1e8d12016-06-06 13:20:38 +02001674 sg_count = talitos_sg_map(dev, areq->src, cryptlen, edesc,
1675 &desc->ptr[3], sg_count, 0, 0);
1676 if (sg_count > 1)
1677 sync_needed = true;
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001678
1679 /* cipher out */
LEROY Christophe6a1e8d12016-06-06 13:20:38 +02001680 if (areq->src != areq->dst) {
1681 sg_count = edesc->dst_nents ? : 1;
1682 if (!is_sec1 || sg_count == 1)
1683 dma_map_sg(dev, areq->dst, sg_count, DMA_FROM_DEVICE);
1684 }
1685
1686 ret = talitos_sg_map(dev, areq->dst, cryptlen, edesc, &desc->ptr[4],
1687 sg_count, 0, (edesc->src_nents + 1));
1688 if (ret > 1)
1689 sync_needed = true;
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001690
1691 /* iv out */
LEROY Christophea2b35aa2015-04-17 16:31:57 +02001692 map_single_talitos_ptr(dev, &desc->ptr[5], ivsize, ctx->iv,
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001693 DMA_FROM_DEVICE);
1694
1695 /* last DWORD empty */
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001696
LEROY Christophe6a1e8d12016-06-06 13:20:38 +02001697 if (sync_needed)
1698 dma_sync_single_for_device(dev, edesc->dma_link_tbl,
1699 edesc->dma_len, DMA_BIDIRECTIONAL);
1700
Kim Phillips5228f0f2011-07-15 11:21:38 +08001701 ret = talitos_submit(dev, ctx->ch, desc, callback, areq);
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001702 if (ret != -EINPROGRESS) {
1703 common_nonsnoop_unmap(dev, edesc, areq);
1704 kfree(edesc);
1705 }
1706 return ret;
1707}
1708
Kim Phillipse938e462009-03-29 15:53:23 +08001709static struct talitos_edesc *ablkcipher_edesc_alloc(struct ablkcipher_request *
Horia Geanta62293a32013-11-28 15:11:17 +02001710 areq, bool encrypt)
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001711{
1712 struct crypto_ablkcipher *cipher = crypto_ablkcipher_reqtfm(areq);
1713 struct talitos_ctx *ctx = crypto_ablkcipher_ctx(cipher);
Horia Geanta79fd31d2012-08-02 17:16:40 +03001714 unsigned int ivsize = crypto_ablkcipher_ivsize(cipher);
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001715
Herbert Xuaeb4c132015-07-30 17:53:22 +08001716 return talitos_edesc_alloc(ctx->dev, areq->src, areq->dst,
Horia Geanta79fd31d2012-08-02 17:16:40 +03001717 areq->info, 0, areq->nbytes, 0, ivsize, 0,
Horia Geanta62293a32013-11-28 15:11:17 +02001718 areq->base.flags, encrypt);
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001719}
1720
1721static int ablkcipher_encrypt(struct ablkcipher_request *areq)
1722{
1723 struct crypto_ablkcipher *cipher = crypto_ablkcipher_reqtfm(areq);
1724 struct talitos_ctx *ctx = crypto_ablkcipher_ctx(cipher);
1725 struct talitos_edesc *edesc;
1726
1727 /* allocate extended descriptor */
Horia Geanta62293a32013-11-28 15:11:17 +02001728 edesc = ablkcipher_edesc_alloc(areq, true);
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001729 if (IS_ERR(edesc))
1730 return PTR_ERR(edesc);
1731
1732 /* set encrypt */
1733 edesc->desc.hdr = ctx->desc_hdr_template | DESC_HDR_MODE0_ENCRYPT;
1734
Kim Phillipsfebec542011-07-15 11:21:39 +08001735 return common_nonsnoop(edesc, areq, ablkcipher_done);
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001736}
1737
1738static int ablkcipher_decrypt(struct ablkcipher_request *areq)
1739{
1740 struct crypto_ablkcipher *cipher = crypto_ablkcipher_reqtfm(areq);
1741 struct talitos_ctx *ctx = crypto_ablkcipher_ctx(cipher);
1742 struct talitos_edesc *edesc;
1743
1744 /* allocate extended descriptor */
Horia Geanta62293a32013-11-28 15:11:17 +02001745 edesc = ablkcipher_edesc_alloc(areq, false);
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001746 if (IS_ERR(edesc))
1747 return PTR_ERR(edesc);
1748
1749 edesc->desc.hdr = ctx->desc_hdr_template | DESC_HDR_DIR_INBOUND;
1750
Kim Phillipsfebec542011-07-15 11:21:39 +08001751 return common_nonsnoop(edesc, areq, ablkcipher_done);
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001752}
1753
Lee Nipper497f2e62010-05-19 19:20:36 +10001754static void common_nonsnoop_hash_unmap(struct device *dev,
1755 struct talitos_edesc *edesc,
1756 struct ahash_request *areq)
1757{
1758 struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
LEROY Christophead4cd512018-02-26 17:40:04 +01001759 struct talitos_private *priv = dev_get_drvdata(dev);
1760 bool is_sec1 = has_ftr_sec1(priv);
1761 struct talitos_desc *desc = &edesc->desc;
1762 struct talitos_desc *desc2 = desc + 1;
1763
1764 unmap_single_talitos_ptr(dev, &edesc->desc.ptr[5], DMA_FROM_DEVICE);
1765 if (desc->next_desc &&
1766 desc->ptr[5].ptr != desc2->ptr[5].ptr)
1767 unmap_single_talitos_ptr(dev, &desc2->ptr[5], DMA_FROM_DEVICE);
Lee Nipper497f2e62010-05-19 19:20:36 +10001768
LEROY Christophe6a1e8d12016-06-06 13:20:38 +02001769 talitos_sg_unmap(dev, edesc, req_ctx->psrc, NULL, 0, 0);
LEROY Christophe032d1972015-04-17 16:31:51 +02001770
LEROY Christophead4cd512018-02-26 17:40:04 +01001771 /* When using hashctx-in, must unmap it. */
1772 if (from_talitos_ptr_len(&edesc->desc.ptr[1], is_sec1))
1773 unmap_single_talitos_ptr(dev, &edesc->desc.ptr[1],
1774 DMA_TO_DEVICE);
1775 else if (desc->next_desc)
1776 unmap_single_talitos_ptr(dev, &desc2->ptr[1],
1777 DMA_TO_DEVICE);
1778
1779 if (is_sec1 && req_ctx->nbuf)
1780 unmap_single_talitos_ptr(dev, &desc->ptr[3],
1781 DMA_TO_DEVICE);
1782
Lee Nipper497f2e62010-05-19 19:20:36 +10001783 if (edesc->dma_len)
1784 dma_unmap_single(dev, edesc->dma_link_tbl, edesc->dma_len,
1785 DMA_BIDIRECTIONAL);
1786
LEROY Christophe37b5e882017-10-06 15:05:06 +02001787 if (edesc->desc.next_desc)
1788 dma_unmap_single(dev, be32_to_cpu(edesc->desc.next_desc),
1789 TALITOS_DESC_SIZE, DMA_BIDIRECTIONAL);
Lee Nipper497f2e62010-05-19 19:20:36 +10001790}
1791
1792static void ahash_done(struct device *dev,
1793 struct talitos_desc *desc, void *context,
1794 int err)
1795{
1796 struct ahash_request *areq = context;
1797 struct talitos_edesc *edesc =
1798 container_of(desc, struct talitos_edesc, desc);
1799 struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
1800
1801 if (!req_ctx->last && req_ctx->to_hash_later) {
1802 /* Position any partial block for next update/final/finup */
LEROY Christophe3c0dd192017-10-06 15:05:08 +02001803 req_ctx->buf_idx = (req_ctx->buf_idx + 1) & 1;
Lee Nipper5e833bc2010-06-16 15:29:15 +10001804 req_ctx->nbuf = req_ctx->to_hash_later;
Lee Nipper497f2e62010-05-19 19:20:36 +10001805 }
1806 common_nonsnoop_hash_unmap(dev, edesc, areq);
1807
1808 kfree(edesc);
1809
1810 areq->base.complete(&areq->base, err);
1811}
1812
LEROY Christophe2d029052015-04-17 16:32:18 +02001813/*
1814 * SEC1 doesn't like hashing of 0 sized message, so we do the padding
1815 * ourself and submit a padded block
1816 */
LEROY Christophe5b2cf262017-10-06 15:04:47 +02001817static void talitos_handle_buggy_hash(struct talitos_ctx *ctx,
LEROY Christophe2d029052015-04-17 16:32:18 +02001818 struct talitos_edesc *edesc,
1819 struct talitos_ptr *ptr)
1820{
1821 static u8 padded_hash[64] = {
1822 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1823 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1824 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1825 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1826 };
1827
1828 pr_err_once("Bug in SEC1, padding ourself\n");
1829 edesc->desc.hdr &= ~DESC_HDR_MODE0_MDEU_PAD;
1830 map_single_talitos_ptr(ctx->dev, ptr, sizeof(padded_hash),
1831 (char *)padded_hash, DMA_TO_DEVICE);
1832}
1833
Lee Nipper497f2e62010-05-19 19:20:36 +10001834static int common_nonsnoop_hash(struct talitos_edesc *edesc,
1835 struct ahash_request *areq, unsigned int length,
LEROY Christophe37b5e882017-10-06 15:05:06 +02001836 unsigned int offset,
Lee Nipper497f2e62010-05-19 19:20:36 +10001837 void (*callback) (struct device *dev,
1838 struct talitos_desc *desc,
1839 void *context, int error))
1840{
1841 struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq);
1842 struct talitos_ctx *ctx = crypto_ahash_ctx(tfm);
1843 struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
1844 struct device *dev = ctx->dev;
1845 struct talitos_desc *desc = &edesc->desc;
LEROY Christophe032d1972015-04-17 16:31:51 +02001846 int ret;
LEROY Christophe6a1e8d12016-06-06 13:20:38 +02001847 bool sync_needed = false;
LEROY Christophe922f9dc2015-04-17 16:32:07 +02001848 struct talitos_private *priv = dev_get_drvdata(dev);
1849 bool is_sec1 = has_ftr_sec1(priv);
LEROY Christophe6a1e8d12016-06-06 13:20:38 +02001850 int sg_count;
Lee Nipper497f2e62010-05-19 19:20:36 +10001851
1852 /* first DWORD empty */
Lee Nipper497f2e62010-05-19 19:20:36 +10001853
Kim Phillips60f208d2010-05-19 19:21:53 +10001854 /* hash context in */
1855 if (!req_ctx->first || req_ctx->swinit) {
LEROY Christophe6a4967c2018-02-26 17:40:06 +01001856 map_single_talitos_ptr_nosync(dev, &desc->ptr[1],
1857 req_ctx->hw_context_size,
1858 req_ctx->hw_context,
1859 DMA_TO_DEVICE);
Kim Phillips60f208d2010-05-19 19:21:53 +10001860 req_ctx->swinit = 0;
Lee Nipper497f2e62010-05-19 19:20:36 +10001861 }
LEROY Christopheafd62fa2017-09-13 12:44:51 +02001862 /* Indicate next op is not the first. */
1863 req_ctx->first = 0;
Lee Nipper497f2e62010-05-19 19:20:36 +10001864
1865 /* HMAC key */
1866 if (ctx->keylen)
LEROY Christophe2e13ce02017-10-06 15:05:02 +02001867 to_talitos_ptr(&desc->ptr[2], ctx->dma_key, ctx->keylen,
1868 is_sec1);
Lee Nipper497f2e62010-05-19 19:20:36 +10001869
LEROY Christophe37b5e882017-10-06 15:05:06 +02001870 if (is_sec1 && req_ctx->nbuf)
1871 length -= req_ctx->nbuf;
1872
LEROY Christophe6a1e8d12016-06-06 13:20:38 +02001873 sg_count = edesc->src_nents ?: 1;
1874 if (is_sec1 && sg_count > 1)
LEROY Christophe37b5e882017-10-06 15:05:06 +02001875 sg_pcopy_to_buffer(req_ctx->psrc, sg_count,
1876 edesc->buf + sizeof(struct talitos_desc),
1877 length, req_ctx->nbuf);
1878 else if (length)
LEROY Christophe6a1e8d12016-06-06 13:20:38 +02001879 sg_count = dma_map_sg(dev, req_ctx->psrc, sg_count,
1880 DMA_TO_DEVICE);
Lee Nipper497f2e62010-05-19 19:20:36 +10001881 /*
1882 * data in
1883 */
LEROY Christophe37b5e882017-10-06 15:05:06 +02001884 if (is_sec1 && req_ctx->nbuf) {
LEROY Christophead4cd512018-02-26 17:40:04 +01001885 map_single_talitos_ptr(dev, &desc->ptr[3], req_ctx->nbuf,
1886 req_ctx->buf[req_ctx->buf_idx],
1887 DMA_TO_DEVICE);
LEROY Christophe37b5e882017-10-06 15:05:06 +02001888 } else {
1889 sg_count = talitos_sg_map(dev, req_ctx->psrc, length, edesc,
1890 &desc->ptr[3], sg_count, offset, 0);
1891 if (sg_count > 1)
1892 sync_needed = true;
1893 }
Lee Nipper497f2e62010-05-19 19:20:36 +10001894
1895 /* fifth DWORD empty */
Lee Nipper497f2e62010-05-19 19:20:36 +10001896
1897 /* hash/HMAC out -or- hash context out */
1898 if (req_ctx->last)
1899 map_single_talitos_ptr(dev, &desc->ptr[5],
1900 crypto_ahash_digestsize(tfm),
LEROY Christophea2b35aa2015-04-17 16:31:57 +02001901 areq->result, DMA_FROM_DEVICE);
Lee Nipper497f2e62010-05-19 19:20:36 +10001902 else
LEROY Christophe6a4967c2018-02-26 17:40:06 +01001903 map_single_talitos_ptr_nosync(dev, &desc->ptr[5],
1904 req_ctx->hw_context_size,
1905 req_ctx->hw_context,
1906 DMA_FROM_DEVICE);
Lee Nipper497f2e62010-05-19 19:20:36 +10001907
1908 /* last DWORD empty */
Lee Nipper497f2e62010-05-19 19:20:36 +10001909
LEROY Christophe2d029052015-04-17 16:32:18 +02001910 if (is_sec1 && from_talitos_ptr_len(&desc->ptr[3], true) == 0)
1911 talitos_handle_buggy_hash(ctx, edesc, &desc->ptr[3]);
1912
LEROY Christophe37b5e882017-10-06 15:05:06 +02001913 if (is_sec1 && req_ctx->nbuf && length) {
1914 struct talitos_desc *desc2 = desc + 1;
1915 dma_addr_t next_desc;
1916
1917 memset(desc2, 0, sizeof(*desc2));
1918 desc2->hdr = desc->hdr;
1919 desc2->hdr &= ~DESC_HDR_MODE0_MDEU_INIT;
1920 desc2->hdr1 = desc2->hdr;
1921 desc->hdr &= ~DESC_HDR_MODE0_MDEU_PAD;
1922 desc->hdr |= DESC_HDR_MODE0_MDEU_CONT;
1923 desc->hdr &= ~DESC_HDR_DONE_NOTIFY;
1924
LEROY Christophead4cd512018-02-26 17:40:04 +01001925 if (desc->ptr[1].ptr)
1926 copy_talitos_ptr(&desc2->ptr[1], &desc->ptr[1],
1927 is_sec1);
1928 else
LEROY Christophe6a4967c2018-02-26 17:40:06 +01001929 map_single_talitos_ptr_nosync(dev, &desc2->ptr[1],
1930 req_ctx->hw_context_size,
1931 req_ctx->hw_context,
1932 DMA_TO_DEVICE);
LEROY Christophe37b5e882017-10-06 15:05:06 +02001933 copy_talitos_ptr(&desc2->ptr[2], &desc->ptr[2], is_sec1);
1934 sg_count = talitos_sg_map(dev, req_ctx->psrc, length, edesc,
1935 &desc2->ptr[3], sg_count, offset, 0);
1936 if (sg_count > 1)
1937 sync_needed = true;
1938 copy_talitos_ptr(&desc2->ptr[5], &desc->ptr[5], is_sec1);
1939 if (req_ctx->last)
LEROY Christophe6a4967c2018-02-26 17:40:06 +01001940 map_single_talitos_ptr_nosync(dev, &desc->ptr[5],
1941 req_ctx->hw_context_size,
1942 req_ctx->hw_context,
1943 DMA_FROM_DEVICE);
LEROY Christophe37b5e882017-10-06 15:05:06 +02001944
1945 next_desc = dma_map_single(dev, &desc2->hdr1, TALITOS_DESC_SIZE,
1946 DMA_BIDIRECTIONAL);
1947 desc->next_desc = cpu_to_be32(next_desc);
1948 }
1949
LEROY Christophe6a1e8d12016-06-06 13:20:38 +02001950 if (sync_needed)
1951 dma_sync_single_for_device(dev, edesc->dma_link_tbl,
1952 edesc->dma_len, DMA_BIDIRECTIONAL);
1953
Kim Phillips5228f0f2011-07-15 11:21:38 +08001954 ret = talitos_submit(dev, ctx->ch, desc, callback, areq);
Lee Nipper497f2e62010-05-19 19:20:36 +10001955 if (ret != -EINPROGRESS) {
1956 common_nonsnoop_hash_unmap(dev, edesc, areq);
1957 kfree(edesc);
1958 }
1959 return ret;
1960}
1961
1962static struct talitos_edesc *ahash_edesc_alloc(struct ahash_request *areq,
1963 unsigned int nbytes)
1964{
1965 struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq);
1966 struct talitos_ctx *ctx = crypto_ahash_ctx(tfm);
1967 struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
LEROY Christophe37b5e882017-10-06 15:05:06 +02001968 struct talitos_private *priv = dev_get_drvdata(ctx->dev);
1969 bool is_sec1 = has_ftr_sec1(priv);
1970
1971 if (is_sec1)
1972 nbytes -= req_ctx->nbuf;
Lee Nipper497f2e62010-05-19 19:20:36 +10001973
Herbert Xuaeb4c132015-07-30 17:53:22 +08001974 return talitos_edesc_alloc(ctx->dev, req_ctx->psrc, NULL, NULL, 0,
Horia Geanta62293a32013-11-28 15:11:17 +02001975 nbytes, 0, 0, 0, areq->base.flags, false);
Lee Nipper497f2e62010-05-19 19:20:36 +10001976}
1977
1978static int ahash_init(struct ahash_request *areq)
1979{
1980 struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq);
LEROY Christophe6a4967c2018-02-26 17:40:06 +01001981 struct talitos_ctx *ctx = crypto_ahash_ctx(tfm);
1982 struct device *dev = ctx->dev;
Lee Nipper497f2e62010-05-19 19:20:36 +10001983 struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
LEROY Christophe49f97832017-10-06 15:05:04 +02001984 unsigned int size;
LEROY Christophe6a4967c2018-02-26 17:40:06 +01001985 dma_addr_t dma;
Lee Nipper497f2e62010-05-19 19:20:36 +10001986
1987 /* Initialize the context */
LEROY Christophe3c0dd192017-10-06 15:05:08 +02001988 req_ctx->buf_idx = 0;
Lee Nipper5e833bc2010-06-16 15:29:15 +10001989 req_ctx->nbuf = 0;
Kim Phillips60f208d2010-05-19 19:21:53 +10001990 req_ctx->first = 1; /* first indicates h/w must init its context */
1991 req_ctx->swinit = 0; /* assume h/w init of context */
LEROY Christophe49f97832017-10-06 15:05:04 +02001992 size = (crypto_ahash_digestsize(tfm) <= SHA256_DIGEST_SIZE)
Lee Nipper497f2e62010-05-19 19:20:36 +10001993 ? TALITOS_MDEU_CONTEXT_SIZE_MD5_SHA1_SHA256
1994 : TALITOS_MDEU_CONTEXT_SIZE_SHA384_SHA512;
LEROY Christophe49f97832017-10-06 15:05:04 +02001995 req_ctx->hw_context_size = size;
Lee Nipper497f2e62010-05-19 19:20:36 +10001996
LEROY Christophe6a4967c2018-02-26 17:40:06 +01001997 dma = dma_map_single(dev, req_ctx->hw_context, req_ctx->hw_context_size,
1998 DMA_TO_DEVICE);
1999 dma_unmap_single(dev, dma, req_ctx->hw_context_size, DMA_TO_DEVICE);
2000
Lee Nipper497f2e62010-05-19 19:20:36 +10002001 return 0;
2002}
2003
Kim Phillips60f208d2010-05-19 19:21:53 +10002004/*
2005 * on h/w without explicit sha224 support, we initialize h/w context
2006 * manually with sha224 constants, and tell it to run sha256.
2007 */
2008static int ahash_init_sha224_swinit(struct ahash_request *areq)
2009{
2010 struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
2011
Kim Phillipsa7524472010-09-23 15:56:38 +08002012 req_ctx->hw_context[0] = SHA224_H0;
2013 req_ctx->hw_context[1] = SHA224_H1;
2014 req_ctx->hw_context[2] = SHA224_H2;
2015 req_ctx->hw_context[3] = SHA224_H3;
2016 req_ctx->hw_context[4] = SHA224_H4;
2017 req_ctx->hw_context[5] = SHA224_H5;
2018 req_ctx->hw_context[6] = SHA224_H6;
2019 req_ctx->hw_context[7] = SHA224_H7;
Kim Phillips60f208d2010-05-19 19:21:53 +10002020
2021 /* init 64-bit count */
2022 req_ctx->hw_context[8] = 0;
2023 req_ctx->hw_context[9] = 0;
2024
LEROY Christophe6a4967c2018-02-26 17:40:06 +01002025 ahash_init(areq);
2026 req_ctx->swinit = 1;/* prevent h/w initting context with sha256 values*/
2027
Kim Phillips60f208d2010-05-19 19:21:53 +10002028 return 0;
2029}
2030
Lee Nipper497f2e62010-05-19 19:20:36 +10002031static int ahash_process_req(struct ahash_request *areq, unsigned int nbytes)
2032{
2033 struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq);
2034 struct talitos_ctx *ctx = crypto_ahash_ctx(tfm);
2035 struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
2036 struct talitos_edesc *edesc;
2037 unsigned int blocksize =
2038 crypto_tfm_alg_blocksize(crypto_ahash_tfm(tfm));
2039 unsigned int nbytes_to_hash;
2040 unsigned int to_hash_later;
Lee Nipper5e833bc2010-06-16 15:29:15 +10002041 unsigned int nsg;
LABBE Corentin8e409fe2015-11-04 21:13:34 +01002042 int nents;
LEROY Christophe37b5e882017-10-06 15:05:06 +02002043 struct device *dev = ctx->dev;
2044 struct talitos_private *priv = dev_get_drvdata(dev);
2045 bool is_sec1 = has_ftr_sec1(priv);
2046 int offset = 0;
LEROY Christophe3c0dd192017-10-06 15:05:08 +02002047 u8 *ctx_buf = req_ctx->buf[req_ctx->buf_idx];
Lee Nipper497f2e62010-05-19 19:20:36 +10002048
Lee Nipper5e833bc2010-06-16 15:29:15 +10002049 if (!req_ctx->last && (nbytes + req_ctx->nbuf <= blocksize)) {
2050 /* Buffer up to one whole block */
LABBE Corentin8e409fe2015-11-04 21:13:34 +01002051 nents = sg_nents_for_len(areq->src, nbytes);
2052 if (nents < 0) {
2053 dev_err(ctx->dev, "Invalid number of src SG.\n");
2054 return nents;
2055 }
2056 sg_copy_to_buffer(areq->src, nents,
LEROY Christophe3c0dd192017-10-06 15:05:08 +02002057 ctx_buf + req_ctx->nbuf, nbytes);
Lee Nipper5e833bc2010-06-16 15:29:15 +10002058 req_ctx->nbuf += nbytes;
Lee Nipper497f2e62010-05-19 19:20:36 +10002059 return 0;
2060 }
2061
Lee Nipper5e833bc2010-06-16 15:29:15 +10002062 /* At least (blocksize + 1) bytes are available to hash */
2063 nbytes_to_hash = nbytes + req_ctx->nbuf;
2064 to_hash_later = nbytes_to_hash & (blocksize - 1);
2065
2066 if (req_ctx->last)
2067 to_hash_later = 0;
2068 else if (to_hash_later)
2069 /* There is a partial block. Hash the full block(s) now */
2070 nbytes_to_hash -= to_hash_later;
2071 else {
2072 /* Keep one block buffered */
2073 nbytes_to_hash -= blocksize;
2074 to_hash_later = blocksize;
2075 }
2076
2077 /* Chain in any previously buffered data */
LEROY Christophe37b5e882017-10-06 15:05:06 +02002078 if (!is_sec1 && req_ctx->nbuf) {
Lee Nipper5e833bc2010-06-16 15:29:15 +10002079 nsg = (req_ctx->nbuf < nbytes_to_hash) ? 2 : 1;
2080 sg_init_table(req_ctx->bufsl, nsg);
LEROY Christophe3c0dd192017-10-06 15:05:08 +02002081 sg_set_buf(req_ctx->bufsl, ctx_buf, req_ctx->nbuf);
Lee Nipper5e833bc2010-06-16 15:29:15 +10002082 if (nsg > 1)
Dan Williamsc56f6d12015-08-07 18:15:13 +02002083 sg_chain(req_ctx->bufsl, 2, areq->src);
Lee Nipper497f2e62010-05-19 19:20:36 +10002084 req_ctx->psrc = req_ctx->bufsl;
LEROY Christophe37b5e882017-10-06 15:05:06 +02002085 } else if (is_sec1 && req_ctx->nbuf && req_ctx->nbuf < blocksize) {
2086 if (nbytes_to_hash > blocksize)
2087 offset = blocksize - req_ctx->nbuf;
2088 else
2089 offset = nbytes_to_hash - req_ctx->nbuf;
2090 nents = sg_nents_for_len(areq->src, offset);
2091 if (nents < 0) {
2092 dev_err(ctx->dev, "Invalid number of src SG.\n");
2093 return nents;
2094 }
2095 sg_copy_to_buffer(areq->src, nents,
LEROY Christophe3c0dd192017-10-06 15:05:08 +02002096 ctx_buf + req_ctx->nbuf, offset);
LEROY Christophe37b5e882017-10-06 15:05:06 +02002097 req_ctx->nbuf += offset;
2098 req_ctx->psrc = areq->src;
Lee Nipper5e833bc2010-06-16 15:29:15 +10002099 } else
Lee Nipper497f2e62010-05-19 19:20:36 +10002100 req_ctx->psrc = areq->src;
Lee Nipper497f2e62010-05-19 19:20:36 +10002101
Lee Nipper5e833bc2010-06-16 15:29:15 +10002102 if (to_hash_later) {
LABBE Corentin8e409fe2015-11-04 21:13:34 +01002103 nents = sg_nents_for_len(areq->src, nbytes);
2104 if (nents < 0) {
2105 dev_err(ctx->dev, "Invalid number of src SG.\n");
2106 return nents;
2107 }
Akinobu Mitad0525722013-07-08 16:01:55 -07002108 sg_pcopy_to_buffer(areq->src, nents,
LEROY Christophe3c0dd192017-10-06 15:05:08 +02002109 req_ctx->buf[(req_ctx->buf_idx + 1) & 1],
Lee Nipper5e833bc2010-06-16 15:29:15 +10002110 to_hash_later,
2111 nbytes - to_hash_later);
Lee Nipper497f2e62010-05-19 19:20:36 +10002112 }
Lee Nipper5e833bc2010-06-16 15:29:15 +10002113 req_ctx->to_hash_later = to_hash_later;
Lee Nipper497f2e62010-05-19 19:20:36 +10002114
Lee Nipper5e833bc2010-06-16 15:29:15 +10002115 /* Allocate extended descriptor */
Lee Nipper497f2e62010-05-19 19:20:36 +10002116 edesc = ahash_edesc_alloc(areq, nbytes_to_hash);
2117 if (IS_ERR(edesc))
2118 return PTR_ERR(edesc);
2119
2120 edesc->desc.hdr = ctx->desc_hdr_template;
2121
2122 /* On last one, request SEC to pad; otherwise continue */
2123 if (req_ctx->last)
2124 edesc->desc.hdr |= DESC_HDR_MODE0_MDEU_PAD;
2125 else
2126 edesc->desc.hdr |= DESC_HDR_MODE0_MDEU_CONT;
2127
Kim Phillips60f208d2010-05-19 19:21:53 +10002128 /* request SEC to INIT hash. */
2129 if (req_ctx->first && !req_ctx->swinit)
Lee Nipper497f2e62010-05-19 19:20:36 +10002130 edesc->desc.hdr |= DESC_HDR_MODE0_MDEU_INIT;
2131
2132 /* When the tfm context has a keylen, it's an HMAC.
2133 * A first or last (ie. not middle) descriptor must request HMAC.
2134 */
2135 if (ctx->keylen && (req_ctx->first || req_ctx->last))
2136 edesc->desc.hdr |= DESC_HDR_MODE0_MDEU_HMAC;
2137
LEROY Christophe37b5e882017-10-06 15:05:06 +02002138 return common_nonsnoop_hash(edesc, areq, nbytes_to_hash, offset,
Lee Nipper497f2e62010-05-19 19:20:36 +10002139 ahash_done);
2140}
2141
2142static int ahash_update(struct ahash_request *areq)
2143{
2144 struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
2145
2146 req_ctx->last = 0;
2147
2148 return ahash_process_req(areq, areq->nbytes);
2149}
2150
2151static int ahash_final(struct ahash_request *areq)
2152{
2153 struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
2154
2155 req_ctx->last = 1;
2156
2157 return ahash_process_req(areq, 0);
2158}
2159
2160static int ahash_finup(struct ahash_request *areq)
2161{
2162 struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
2163
2164 req_ctx->last = 1;
2165
2166 return ahash_process_req(areq, areq->nbytes);
2167}
2168
2169static int ahash_digest(struct ahash_request *areq)
2170{
2171 struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
Kim Phillips60f208d2010-05-19 19:21:53 +10002172 struct crypto_ahash *ahash = crypto_ahash_reqtfm(areq);
Lee Nipper497f2e62010-05-19 19:20:36 +10002173
Kim Phillips60f208d2010-05-19 19:21:53 +10002174 ahash->init(areq);
Lee Nipper497f2e62010-05-19 19:20:36 +10002175 req_ctx->last = 1;
2176
2177 return ahash_process_req(areq, areq->nbytes);
2178}
2179
Horia Geant?3639ca82016-04-21 19:24:55 +03002180static int ahash_export(struct ahash_request *areq, void *out)
2181{
2182 struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
2183 struct talitos_export_state *export = out;
LEROY Christophe6a4967c2018-02-26 17:40:06 +01002184 struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq);
2185 struct talitos_ctx *ctx = crypto_ahash_ctx(tfm);
2186 struct device *dev = ctx->dev;
2187 dma_addr_t dma;
2188
2189 dma = dma_map_single(dev, req_ctx->hw_context, req_ctx->hw_context_size,
2190 DMA_FROM_DEVICE);
2191 dma_unmap_single(dev, dma, req_ctx->hw_context_size, DMA_FROM_DEVICE);
Horia Geant?3639ca82016-04-21 19:24:55 +03002192
2193 memcpy(export->hw_context, req_ctx->hw_context,
2194 req_ctx->hw_context_size);
LEROY Christophe3c0dd192017-10-06 15:05:08 +02002195 memcpy(export->buf, req_ctx->buf[req_ctx->buf_idx], req_ctx->nbuf);
Horia Geant?3639ca82016-04-21 19:24:55 +03002196 export->swinit = req_ctx->swinit;
2197 export->first = req_ctx->first;
2198 export->last = req_ctx->last;
2199 export->to_hash_later = req_ctx->to_hash_later;
2200 export->nbuf = req_ctx->nbuf;
2201
2202 return 0;
2203}
2204
2205static int ahash_import(struct ahash_request *areq, const void *in)
2206{
2207 struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
2208 struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq);
LEROY Christophe6a4967c2018-02-26 17:40:06 +01002209 struct talitos_ctx *ctx = crypto_ahash_ctx(tfm);
2210 struct device *dev = ctx->dev;
Horia Geant?3639ca82016-04-21 19:24:55 +03002211 const struct talitos_export_state *export = in;
LEROY Christophe49f97832017-10-06 15:05:04 +02002212 unsigned int size;
LEROY Christophe6a4967c2018-02-26 17:40:06 +01002213 dma_addr_t dma;
Horia Geant?3639ca82016-04-21 19:24:55 +03002214
2215 memset(req_ctx, 0, sizeof(*req_ctx));
LEROY Christophe49f97832017-10-06 15:05:04 +02002216 size = (crypto_ahash_digestsize(tfm) <= SHA256_DIGEST_SIZE)
Horia Geant?3639ca82016-04-21 19:24:55 +03002217 ? TALITOS_MDEU_CONTEXT_SIZE_MD5_SHA1_SHA256
2218 : TALITOS_MDEU_CONTEXT_SIZE_SHA384_SHA512;
LEROY Christophe49f97832017-10-06 15:05:04 +02002219 req_ctx->hw_context_size = size;
LEROY Christophe49f97832017-10-06 15:05:04 +02002220 memcpy(req_ctx->hw_context, export->hw_context, size);
LEROY Christophe3c0dd192017-10-06 15:05:08 +02002221 memcpy(req_ctx->buf[0], export->buf, export->nbuf);
Horia Geant?3639ca82016-04-21 19:24:55 +03002222 req_ctx->swinit = export->swinit;
2223 req_ctx->first = export->first;
2224 req_ctx->last = export->last;
2225 req_ctx->to_hash_later = export->to_hash_later;
2226 req_ctx->nbuf = export->nbuf;
2227
LEROY Christophe6a4967c2018-02-26 17:40:06 +01002228 dma = dma_map_single(dev, req_ctx->hw_context, req_ctx->hw_context_size,
2229 DMA_TO_DEVICE);
2230 dma_unmap_single(dev, dma, req_ctx->hw_context_size, DMA_TO_DEVICE);
2231
Horia Geant?3639ca82016-04-21 19:24:55 +03002232 return 0;
2233}
2234
Lee Nipper79b3a412011-11-21 16:13:25 +08002235static int keyhash(struct crypto_ahash *tfm, const u8 *key, unsigned int keylen,
2236 u8 *hash)
2237{
2238 struct talitos_ctx *ctx = crypto_tfm_ctx(crypto_ahash_tfm(tfm));
2239
2240 struct scatterlist sg[1];
2241 struct ahash_request *req;
Gilad Ben-Yosseff1c90ac32017-10-18 08:00:49 +01002242 struct crypto_wait wait;
Lee Nipper79b3a412011-11-21 16:13:25 +08002243 int ret;
2244
Gilad Ben-Yosseff1c90ac32017-10-18 08:00:49 +01002245 crypto_init_wait(&wait);
Lee Nipper79b3a412011-11-21 16:13:25 +08002246
2247 req = ahash_request_alloc(tfm, GFP_KERNEL);
2248 if (!req)
2249 return -ENOMEM;
2250
2251 /* Keep tfm keylen == 0 during hash of the long key */
2252 ctx->keylen = 0;
2253 ahash_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
Gilad Ben-Yosseff1c90ac32017-10-18 08:00:49 +01002254 crypto_req_done, &wait);
Lee Nipper79b3a412011-11-21 16:13:25 +08002255
2256 sg_init_one(&sg[0], key, keylen);
2257
2258 ahash_request_set_crypt(req, sg, hash, keylen);
Gilad Ben-Yosseff1c90ac32017-10-18 08:00:49 +01002259 ret = crypto_wait_req(crypto_ahash_digest(req), &wait);
2260
Lee Nipper79b3a412011-11-21 16:13:25 +08002261 ahash_request_free(req);
2262
2263 return ret;
2264}
2265
2266static int ahash_setkey(struct crypto_ahash *tfm, const u8 *key,
2267 unsigned int keylen)
2268{
2269 struct talitos_ctx *ctx = crypto_tfm_ctx(crypto_ahash_tfm(tfm));
LEROY Christophe2e13ce02017-10-06 15:05:02 +02002270 struct device *dev = ctx->dev;
Lee Nipper79b3a412011-11-21 16:13:25 +08002271 unsigned int blocksize =
2272 crypto_tfm_alg_blocksize(crypto_ahash_tfm(tfm));
2273 unsigned int digestsize = crypto_ahash_digestsize(tfm);
2274 unsigned int keysize = keylen;
2275 u8 hash[SHA512_DIGEST_SIZE];
2276 int ret;
2277
2278 if (keylen <= blocksize)
2279 memcpy(ctx->key, key, keysize);
2280 else {
2281 /* Must get the hash of the long key */
2282 ret = keyhash(tfm, key, keylen, hash);
2283
2284 if (ret) {
2285 crypto_ahash_set_flags(tfm, CRYPTO_TFM_RES_BAD_KEY_LEN);
2286 return -EINVAL;
2287 }
2288
2289 keysize = digestsize;
2290 memcpy(ctx->key, hash, digestsize);
2291 }
2292
LEROY Christophe2e13ce02017-10-06 15:05:02 +02002293 if (ctx->keylen)
2294 dma_unmap_single(dev, ctx->dma_key, ctx->keylen, DMA_TO_DEVICE);
2295
Lee Nipper79b3a412011-11-21 16:13:25 +08002296 ctx->keylen = keysize;
LEROY Christophe2e13ce02017-10-06 15:05:02 +02002297 ctx->dma_key = dma_map_single(dev, ctx->key, keysize, DMA_TO_DEVICE);
Lee Nipper79b3a412011-11-21 16:13:25 +08002298
2299 return 0;
2300}
2301
2302
Kim Phillips9c4a7962008-06-23 19:50:15 +08002303struct talitos_alg_template {
Lee Nipperd5e4aae2010-05-19 19:18:38 +10002304 u32 type;
LEROY Christopheb0057762016-06-06 13:20:44 +02002305 u32 priority;
Lee Nipperd5e4aae2010-05-19 19:18:38 +10002306 union {
2307 struct crypto_alg crypto;
Lee Nipperacbf7c622010-05-19 19:19:33 +10002308 struct ahash_alg hash;
Herbert Xuaeb4c132015-07-30 17:53:22 +08002309 struct aead_alg aead;
Lee Nipperd5e4aae2010-05-19 19:18:38 +10002310 } alg;
Kim Phillips9c4a7962008-06-23 19:50:15 +08002311 __be32 desc_hdr_template;
2312};
2313
2314static struct talitos_alg_template driver_algs[] = {
Horia Geanta991155b2013-03-20 16:31:38 +02002315 /* AEAD algorithms. These use a single-pass ipsec_esp descriptor */
Lee Nipperd5e4aae2010-05-19 19:18:38 +10002316 { .type = CRYPTO_ALG_TYPE_AEAD,
Herbert Xuaeb4c132015-07-30 17:53:22 +08002317 .alg.aead = {
2318 .base = {
2319 .cra_name = "authenc(hmac(sha1),cbc(aes))",
2320 .cra_driver_name = "authenc-hmac-sha1-"
2321 "cbc-aes-talitos",
2322 .cra_blocksize = AES_BLOCK_SIZE,
2323 .cra_flags = CRYPTO_ALG_ASYNC,
2324 },
2325 .ivsize = AES_BLOCK_SIZE,
2326 .maxauthsize = SHA1_DIGEST_SIZE,
Lee Nipper56af8cd2009-03-29 15:50:50 +08002327 },
Kim Phillips9c4a7962008-06-23 19:50:15 +08002328 .desc_hdr_template = DESC_HDR_TYPE_IPSEC_ESP |
2329 DESC_HDR_SEL0_AESU |
2330 DESC_HDR_MODE0_AESU_CBC |
2331 DESC_HDR_SEL1_MDEUA |
2332 DESC_HDR_MODE1_MDEU_INIT |
2333 DESC_HDR_MODE1_MDEU_PAD |
2334 DESC_HDR_MODE1_MDEU_SHA1_HMAC,
Lee Nipper70bcaca2008-07-03 19:08:46 +08002335 },
Lee Nipperd5e4aae2010-05-19 19:18:38 +10002336 { .type = CRYPTO_ALG_TYPE_AEAD,
LEROY Christophe7405c8d2016-06-06 13:20:46 +02002337 .priority = TALITOS_CRA_PRIORITY_AEAD_HSNA,
2338 .alg.aead = {
2339 .base = {
2340 .cra_name = "authenc(hmac(sha1),cbc(aes))",
2341 .cra_driver_name = "authenc-hmac-sha1-"
2342 "cbc-aes-talitos",
2343 .cra_blocksize = AES_BLOCK_SIZE,
2344 .cra_flags = CRYPTO_ALG_ASYNC,
2345 },
2346 .ivsize = AES_BLOCK_SIZE,
2347 .maxauthsize = SHA1_DIGEST_SIZE,
2348 },
2349 .desc_hdr_template = DESC_HDR_TYPE_HMAC_SNOOP_NO_AFEU |
2350 DESC_HDR_SEL0_AESU |
2351 DESC_HDR_MODE0_AESU_CBC |
2352 DESC_HDR_SEL1_MDEUA |
2353 DESC_HDR_MODE1_MDEU_INIT |
2354 DESC_HDR_MODE1_MDEU_PAD |
2355 DESC_HDR_MODE1_MDEU_SHA1_HMAC,
2356 },
2357 { .type = CRYPTO_ALG_TYPE_AEAD,
Herbert Xuaeb4c132015-07-30 17:53:22 +08002358 .alg.aead = {
2359 .base = {
2360 .cra_name = "authenc(hmac(sha1),"
2361 "cbc(des3_ede))",
2362 .cra_driver_name = "authenc-hmac-sha1-"
2363 "cbc-3des-talitos",
2364 .cra_blocksize = DES3_EDE_BLOCK_SIZE,
2365 .cra_flags = CRYPTO_ALG_ASYNC,
2366 },
2367 .ivsize = DES3_EDE_BLOCK_SIZE,
2368 .maxauthsize = SHA1_DIGEST_SIZE,
Herbert Xuef7c5c82019-04-11 16:51:21 +08002369 .setkey = aead_des3_setkey,
Lee Nipper56af8cd2009-03-29 15:50:50 +08002370 },
Lee Nipper70bcaca2008-07-03 19:08:46 +08002371 .desc_hdr_template = DESC_HDR_TYPE_IPSEC_ESP |
2372 DESC_HDR_SEL0_DEU |
2373 DESC_HDR_MODE0_DEU_CBC |
2374 DESC_HDR_MODE0_DEU_3DES |
2375 DESC_HDR_SEL1_MDEUA |
2376 DESC_HDR_MODE1_MDEU_INIT |
2377 DESC_HDR_MODE1_MDEU_PAD |
2378 DESC_HDR_MODE1_MDEU_SHA1_HMAC,
Lee Nipper3952f172008-07-10 18:29:18 +08002379 },
LEROY Christophe7405c8d2016-06-06 13:20:46 +02002380 { .type = CRYPTO_ALG_TYPE_AEAD,
2381 .priority = TALITOS_CRA_PRIORITY_AEAD_HSNA,
2382 .alg.aead = {
2383 .base = {
2384 .cra_name = "authenc(hmac(sha1),"
2385 "cbc(des3_ede))",
2386 .cra_driver_name = "authenc-hmac-sha1-"
2387 "cbc-3des-talitos",
2388 .cra_blocksize = DES3_EDE_BLOCK_SIZE,
2389 .cra_flags = CRYPTO_ALG_ASYNC,
2390 },
2391 .ivsize = DES3_EDE_BLOCK_SIZE,
2392 .maxauthsize = SHA1_DIGEST_SIZE,
Herbert Xuef7c5c82019-04-11 16:51:21 +08002393 .setkey = aead_des3_setkey,
LEROY Christophe7405c8d2016-06-06 13:20:46 +02002394 },
2395 .desc_hdr_template = DESC_HDR_TYPE_HMAC_SNOOP_NO_AFEU |
2396 DESC_HDR_SEL0_DEU |
2397 DESC_HDR_MODE0_DEU_CBC |
2398 DESC_HDR_MODE0_DEU_3DES |
2399 DESC_HDR_SEL1_MDEUA |
2400 DESC_HDR_MODE1_MDEU_INIT |
2401 DESC_HDR_MODE1_MDEU_PAD |
2402 DESC_HDR_MODE1_MDEU_SHA1_HMAC,
2403 },
Horia Geanta357fb602012-07-03 19:16:53 +03002404 { .type = CRYPTO_ALG_TYPE_AEAD,
Herbert Xuaeb4c132015-07-30 17:53:22 +08002405 .alg.aead = {
2406 .base = {
2407 .cra_name = "authenc(hmac(sha224),cbc(aes))",
2408 .cra_driver_name = "authenc-hmac-sha224-"
2409 "cbc-aes-talitos",
2410 .cra_blocksize = AES_BLOCK_SIZE,
2411 .cra_flags = CRYPTO_ALG_ASYNC,
2412 },
2413 .ivsize = AES_BLOCK_SIZE,
2414 .maxauthsize = SHA224_DIGEST_SIZE,
Horia Geanta357fb602012-07-03 19:16:53 +03002415 },
2416 .desc_hdr_template = DESC_HDR_TYPE_IPSEC_ESP |
2417 DESC_HDR_SEL0_AESU |
2418 DESC_HDR_MODE0_AESU_CBC |
2419 DESC_HDR_SEL1_MDEUA |
2420 DESC_HDR_MODE1_MDEU_INIT |
2421 DESC_HDR_MODE1_MDEU_PAD |
2422 DESC_HDR_MODE1_MDEU_SHA224_HMAC,
2423 },
LEROY Christophe7405c8d2016-06-06 13:20:46 +02002424 { .type = CRYPTO_ALG_TYPE_AEAD,
2425 .priority = TALITOS_CRA_PRIORITY_AEAD_HSNA,
2426 .alg.aead = {
2427 .base = {
2428 .cra_name = "authenc(hmac(sha224),cbc(aes))",
2429 .cra_driver_name = "authenc-hmac-sha224-"
2430 "cbc-aes-talitos",
2431 .cra_blocksize = AES_BLOCK_SIZE,
2432 .cra_flags = CRYPTO_ALG_ASYNC,
2433 },
2434 .ivsize = AES_BLOCK_SIZE,
2435 .maxauthsize = SHA224_DIGEST_SIZE,
2436 },
2437 .desc_hdr_template = DESC_HDR_TYPE_HMAC_SNOOP_NO_AFEU |
2438 DESC_HDR_SEL0_AESU |
2439 DESC_HDR_MODE0_AESU_CBC |
2440 DESC_HDR_SEL1_MDEUA |
2441 DESC_HDR_MODE1_MDEU_INIT |
2442 DESC_HDR_MODE1_MDEU_PAD |
2443 DESC_HDR_MODE1_MDEU_SHA224_HMAC,
2444 },
Horia Geanta357fb602012-07-03 19:16:53 +03002445 { .type = CRYPTO_ALG_TYPE_AEAD,
Herbert Xuaeb4c132015-07-30 17:53:22 +08002446 .alg.aead = {
2447 .base = {
2448 .cra_name = "authenc(hmac(sha224),"
2449 "cbc(des3_ede))",
2450 .cra_driver_name = "authenc-hmac-sha224-"
2451 "cbc-3des-talitos",
2452 .cra_blocksize = DES3_EDE_BLOCK_SIZE,
2453 .cra_flags = CRYPTO_ALG_ASYNC,
2454 },
2455 .ivsize = DES3_EDE_BLOCK_SIZE,
2456 .maxauthsize = SHA224_DIGEST_SIZE,
Herbert Xuef7c5c82019-04-11 16:51:21 +08002457 .setkey = aead_des3_setkey,
Horia Geanta357fb602012-07-03 19:16:53 +03002458 },
2459 .desc_hdr_template = DESC_HDR_TYPE_IPSEC_ESP |
2460 DESC_HDR_SEL0_DEU |
2461 DESC_HDR_MODE0_DEU_CBC |
2462 DESC_HDR_MODE0_DEU_3DES |
2463 DESC_HDR_SEL1_MDEUA |
2464 DESC_HDR_MODE1_MDEU_INIT |
2465 DESC_HDR_MODE1_MDEU_PAD |
2466 DESC_HDR_MODE1_MDEU_SHA224_HMAC,
2467 },
Lee Nipperd5e4aae2010-05-19 19:18:38 +10002468 { .type = CRYPTO_ALG_TYPE_AEAD,
LEROY Christophe7405c8d2016-06-06 13:20:46 +02002469 .priority = TALITOS_CRA_PRIORITY_AEAD_HSNA,
2470 .alg.aead = {
2471 .base = {
2472 .cra_name = "authenc(hmac(sha224),"
2473 "cbc(des3_ede))",
2474 .cra_driver_name = "authenc-hmac-sha224-"
2475 "cbc-3des-talitos",
2476 .cra_blocksize = DES3_EDE_BLOCK_SIZE,
2477 .cra_flags = CRYPTO_ALG_ASYNC,
2478 },
2479 .ivsize = DES3_EDE_BLOCK_SIZE,
2480 .maxauthsize = SHA224_DIGEST_SIZE,
Herbert Xuef7c5c82019-04-11 16:51:21 +08002481 .setkey = aead_des3_setkey,
LEROY Christophe7405c8d2016-06-06 13:20:46 +02002482 },
2483 .desc_hdr_template = DESC_HDR_TYPE_HMAC_SNOOP_NO_AFEU |
2484 DESC_HDR_SEL0_DEU |
2485 DESC_HDR_MODE0_DEU_CBC |
2486 DESC_HDR_MODE0_DEU_3DES |
2487 DESC_HDR_SEL1_MDEUA |
2488 DESC_HDR_MODE1_MDEU_INIT |
2489 DESC_HDR_MODE1_MDEU_PAD |
2490 DESC_HDR_MODE1_MDEU_SHA224_HMAC,
2491 },
2492 { .type = CRYPTO_ALG_TYPE_AEAD,
Herbert Xuaeb4c132015-07-30 17:53:22 +08002493 .alg.aead = {
2494 .base = {
2495 .cra_name = "authenc(hmac(sha256),cbc(aes))",
2496 .cra_driver_name = "authenc-hmac-sha256-"
2497 "cbc-aes-talitos",
2498 .cra_blocksize = AES_BLOCK_SIZE,
2499 .cra_flags = CRYPTO_ALG_ASYNC,
2500 },
2501 .ivsize = AES_BLOCK_SIZE,
2502 .maxauthsize = SHA256_DIGEST_SIZE,
Lee Nipper56af8cd2009-03-29 15:50:50 +08002503 },
Lee Nipper3952f172008-07-10 18:29:18 +08002504 .desc_hdr_template = DESC_HDR_TYPE_IPSEC_ESP |
2505 DESC_HDR_SEL0_AESU |
2506 DESC_HDR_MODE0_AESU_CBC |
2507 DESC_HDR_SEL1_MDEUA |
2508 DESC_HDR_MODE1_MDEU_INIT |
2509 DESC_HDR_MODE1_MDEU_PAD |
2510 DESC_HDR_MODE1_MDEU_SHA256_HMAC,
2511 },
Lee Nipperd5e4aae2010-05-19 19:18:38 +10002512 { .type = CRYPTO_ALG_TYPE_AEAD,
LEROY Christophe7405c8d2016-06-06 13:20:46 +02002513 .priority = TALITOS_CRA_PRIORITY_AEAD_HSNA,
2514 .alg.aead = {
2515 .base = {
2516 .cra_name = "authenc(hmac(sha256),cbc(aes))",
2517 .cra_driver_name = "authenc-hmac-sha256-"
2518 "cbc-aes-talitos",
2519 .cra_blocksize = AES_BLOCK_SIZE,
2520 .cra_flags = CRYPTO_ALG_ASYNC,
2521 },
2522 .ivsize = AES_BLOCK_SIZE,
2523 .maxauthsize = SHA256_DIGEST_SIZE,
2524 },
2525 .desc_hdr_template = DESC_HDR_TYPE_HMAC_SNOOP_NO_AFEU |
2526 DESC_HDR_SEL0_AESU |
2527 DESC_HDR_MODE0_AESU_CBC |
2528 DESC_HDR_SEL1_MDEUA |
2529 DESC_HDR_MODE1_MDEU_INIT |
2530 DESC_HDR_MODE1_MDEU_PAD |
2531 DESC_HDR_MODE1_MDEU_SHA256_HMAC,
2532 },
2533 { .type = CRYPTO_ALG_TYPE_AEAD,
Herbert Xuaeb4c132015-07-30 17:53:22 +08002534 .alg.aead = {
2535 .base = {
2536 .cra_name = "authenc(hmac(sha256),"
2537 "cbc(des3_ede))",
2538 .cra_driver_name = "authenc-hmac-sha256-"
2539 "cbc-3des-talitos",
2540 .cra_blocksize = DES3_EDE_BLOCK_SIZE,
2541 .cra_flags = CRYPTO_ALG_ASYNC,
2542 },
2543 .ivsize = DES3_EDE_BLOCK_SIZE,
2544 .maxauthsize = SHA256_DIGEST_SIZE,
Herbert Xuef7c5c82019-04-11 16:51:21 +08002545 .setkey = aead_des3_setkey,
Lee Nipper56af8cd2009-03-29 15:50:50 +08002546 },
Lee Nipper3952f172008-07-10 18:29:18 +08002547 .desc_hdr_template = DESC_HDR_TYPE_IPSEC_ESP |
2548 DESC_HDR_SEL0_DEU |
2549 DESC_HDR_MODE0_DEU_CBC |
2550 DESC_HDR_MODE0_DEU_3DES |
2551 DESC_HDR_SEL1_MDEUA |
2552 DESC_HDR_MODE1_MDEU_INIT |
2553 DESC_HDR_MODE1_MDEU_PAD |
2554 DESC_HDR_MODE1_MDEU_SHA256_HMAC,
2555 },
Lee Nipperd5e4aae2010-05-19 19:18:38 +10002556 { .type = CRYPTO_ALG_TYPE_AEAD,
LEROY Christophe7405c8d2016-06-06 13:20:46 +02002557 .priority = TALITOS_CRA_PRIORITY_AEAD_HSNA,
2558 .alg.aead = {
2559 .base = {
2560 .cra_name = "authenc(hmac(sha256),"
2561 "cbc(des3_ede))",
2562 .cra_driver_name = "authenc-hmac-sha256-"
2563 "cbc-3des-talitos",
2564 .cra_blocksize = DES3_EDE_BLOCK_SIZE,
2565 .cra_flags = CRYPTO_ALG_ASYNC,
2566 },
2567 .ivsize = DES3_EDE_BLOCK_SIZE,
2568 .maxauthsize = SHA256_DIGEST_SIZE,
Herbert Xuef7c5c82019-04-11 16:51:21 +08002569 .setkey = aead_des3_setkey,
LEROY Christophe7405c8d2016-06-06 13:20:46 +02002570 },
2571 .desc_hdr_template = DESC_HDR_TYPE_HMAC_SNOOP_NO_AFEU |
2572 DESC_HDR_SEL0_DEU |
2573 DESC_HDR_MODE0_DEU_CBC |
2574 DESC_HDR_MODE0_DEU_3DES |
2575 DESC_HDR_SEL1_MDEUA |
2576 DESC_HDR_MODE1_MDEU_INIT |
2577 DESC_HDR_MODE1_MDEU_PAD |
2578 DESC_HDR_MODE1_MDEU_SHA256_HMAC,
2579 },
2580 { .type = CRYPTO_ALG_TYPE_AEAD,
Herbert Xuaeb4c132015-07-30 17:53:22 +08002581 .alg.aead = {
2582 .base = {
2583 .cra_name = "authenc(hmac(sha384),cbc(aes))",
2584 .cra_driver_name = "authenc-hmac-sha384-"
2585 "cbc-aes-talitos",
2586 .cra_blocksize = AES_BLOCK_SIZE,
2587 .cra_flags = CRYPTO_ALG_ASYNC,
2588 },
2589 .ivsize = AES_BLOCK_SIZE,
2590 .maxauthsize = SHA384_DIGEST_SIZE,
Horia Geanta357fb602012-07-03 19:16:53 +03002591 },
2592 .desc_hdr_template = DESC_HDR_TYPE_IPSEC_ESP |
2593 DESC_HDR_SEL0_AESU |
2594 DESC_HDR_MODE0_AESU_CBC |
2595 DESC_HDR_SEL1_MDEUB |
2596 DESC_HDR_MODE1_MDEU_INIT |
2597 DESC_HDR_MODE1_MDEU_PAD |
2598 DESC_HDR_MODE1_MDEUB_SHA384_HMAC,
2599 },
2600 { .type = CRYPTO_ALG_TYPE_AEAD,
Herbert Xuaeb4c132015-07-30 17:53:22 +08002601 .alg.aead = {
2602 .base = {
2603 .cra_name = "authenc(hmac(sha384),"
2604 "cbc(des3_ede))",
2605 .cra_driver_name = "authenc-hmac-sha384-"
2606 "cbc-3des-talitos",
2607 .cra_blocksize = DES3_EDE_BLOCK_SIZE,
2608 .cra_flags = CRYPTO_ALG_ASYNC,
2609 },
2610 .ivsize = DES3_EDE_BLOCK_SIZE,
2611 .maxauthsize = SHA384_DIGEST_SIZE,
Herbert Xuef7c5c82019-04-11 16:51:21 +08002612 .setkey = aead_des3_setkey,
Horia Geanta357fb602012-07-03 19:16:53 +03002613 },
2614 .desc_hdr_template = DESC_HDR_TYPE_IPSEC_ESP |
2615 DESC_HDR_SEL0_DEU |
2616 DESC_HDR_MODE0_DEU_CBC |
2617 DESC_HDR_MODE0_DEU_3DES |
2618 DESC_HDR_SEL1_MDEUB |
2619 DESC_HDR_MODE1_MDEU_INIT |
2620 DESC_HDR_MODE1_MDEU_PAD |
2621 DESC_HDR_MODE1_MDEUB_SHA384_HMAC,
2622 },
2623 { .type = CRYPTO_ALG_TYPE_AEAD,
Herbert Xuaeb4c132015-07-30 17:53:22 +08002624 .alg.aead = {
2625 .base = {
2626 .cra_name = "authenc(hmac(sha512),cbc(aes))",
2627 .cra_driver_name = "authenc-hmac-sha512-"
2628 "cbc-aes-talitos",
2629 .cra_blocksize = AES_BLOCK_SIZE,
2630 .cra_flags = CRYPTO_ALG_ASYNC,
2631 },
2632 .ivsize = AES_BLOCK_SIZE,
2633 .maxauthsize = SHA512_DIGEST_SIZE,
Horia Geanta357fb602012-07-03 19:16:53 +03002634 },
2635 .desc_hdr_template = DESC_HDR_TYPE_IPSEC_ESP |
2636 DESC_HDR_SEL0_AESU |
2637 DESC_HDR_MODE0_AESU_CBC |
2638 DESC_HDR_SEL1_MDEUB |
2639 DESC_HDR_MODE1_MDEU_INIT |
2640 DESC_HDR_MODE1_MDEU_PAD |
2641 DESC_HDR_MODE1_MDEUB_SHA512_HMAC,
2642 },
2643 { .type = CRYPTO_ALG_TYPE_AEAD,
Herbert Xuaeb4c132015-07-30 17:53:22 +08002644 .alg.aead = {
2645 .base = {
2646 .cra_name = "authenc(hmac(sha512),"
2647 "cbc(des3_ede))",
2648 .cra_driver_name = "authenc-hmac-sha512-"
2649 "cbc-3des-talitos",
2650 .cra_blocksize = DES3_EDE_BLOCK_SIZE,
2651 .cra_flags = CRYPTO_ALG_ASYNC,
2652 },
2653 .ivsize = DES3_EDE_BLOCK_SIZE,
2654 .maxauthsize = SHA512_DIGEST_SIZE,
Herbert Xuef7c5c82019-04-11 16:51:21 +08002655 .setkey = aead_des3_setkey,
Horia Geanta357fb602012-07-03 19:16:53 +03002656 },
2657 .desc_hdr_template = DESC_HDR_TYPE_IPSEC_ESP |
2658 DESC_HDR_SEL0_DEU |
2659 DESC_HDR_MODE0_DEU_CBC |
2660 DESC_HDR_MODE0_DEU_3DES |
2661 DESC_HDR_SEL1_MDEUB |
2662 DESC_HDR_MODE1_MDEU_INIT |
2663 DESC_HDR_MODE1_MDEU_PAD |
2664 DESC_HDR_MODE1_MDEUB_SHA512_HMAC,
2665 },
2666 { .type = CRYPTO_ALG_TYPE_AEAD,
Herbert Xuaeb4c132015-07-30 17:53:22 +08002667 .alg.aead = {
2668 .base = {
2669 .cra_name = "authenc(hmac(md5),cbc(aes))",
2670 .cra_driver_name = "authenc-hmac-md5-"
2671 "cbc-aes-talitos",
2672 .cra_blocksize = AES_BLOCK_SIZE,
2673 .cra_flags = CRYPTO_ALG_ASYNC,
2674 },
2675 .ivsize = AES_BLOCK_SIZE,
2676 .maxauthsize = MD5_DIGEST_SIZE,
Lee Nipper56af8cd2009-03-29 15:50:50 +08002677 },
Lee Nipper3952f172008-07-10 18:29:18 +08002678 .desc_hdr_template = DESC_HDR_TYPE_IPSEC_ESP |
2679 DESC_HDR_SEL0_AESU |
2680 DESC_HDR_MODE0_AESU_CBC |
2681 DESC_HDR_SEL1_MDEUA |
2682 DESC_HDR_MODE1_MDEU_INIT |
2683 DESC_HDR_MODE1_MDEU_PAD |
2684 DESC_HDR_MODE1_MDEU_MD5_HMAC,
2685 },
Lee Nipperd5e4aae2010-05-19 19:18:38 +10002686 { .type = CRYPTO_ALG_TYPE_AEAD,
LEROY Christophe7405c8d2016-06-06 13:20:46 +02002687 .priority = TALITOS_CRA_PRIORITY_AEAD_HSNA,
2688 .alg.aead = {
2689 .base = {
2690 .cra_name = "authenc(hmac(md5),cbc(aes))",
2691 .cra_driver_name = "authenc-hmac-md5-"
2692 "cbc-aes-talitos",
2693 .cra_blocksize = AES_BLOCK_SIZE,
2694 .cra_flags = CRYPTO_ALG_ASYNC,
2695 },
2696 .ivsize = AES_BLOCK_SIZE,
2697 .maxauthsize = MD5_DIGEST_SIZE,
2698 },
2699 .desc_hdr_template = DESC_HDR_TYPE_HMAC_SNOOP_NO_AFEU |
2700 DESC_HDR_SEL0_AESU |
2701 DESC_HDR_MODE0_AESU_CBC |
2702 DESC_HDR_SEL1_MDEUA |
2703 DESC_HDR_MODE1_MDEU_INIT |
2704 DESC_HDR_MODE1_MDEU_PAD |
2705 DESC_HDR_MODE1_MDEU_MD5_HMAC,
2706 },
2707 { .type = CRYPTO_ALG_TYPE_AEAD,
Herbert Xuaeb4c132015-07-30 17:53:22 +08002708 .alg.aead = {
2709 .base = {
2710 .cra_name = "authenc(hmac(md5),cbc(des3_ede))",
2711 .cra_driver_name = "authenc-hmac-md5-"
2712 "cbc-3des-talitos",
2713 .cra_blocksize = DES3_EDE_BLOCK_SIZE,
2714 .cra_flags = CRYPTO_ALG_ASYNC,
2715 },
2716 .ivsize = DES3_EDE_BLOCK_SIZE,
2717 .maxauthsize = MD5_DIGEST_SIZE,
Herbert Xuef7c5c82019-04-11 16:51:21 +08002718 .setkey = aead_des3_setkey,
Lee Nipper56af8cd2009-03-29 15:50:50 +08002719 },
Lee Nipper3952f172008-07-10 18:29:18 +08002720 .desc_hdr_template = DESC_HDR_TYPE_IPSEC_ESP |
2721 DESC_HDR_SEL0_DEU |
2722 DESC_HDR_MODE0_DEU_CBC |
2723 DESC_HDR_MODE0_DEU_3DES |
2724 DESC_HDR_SEL1_MDEUA |
2725 DESC_HDR_MODE1_MDEU_INIT |
2726 DESC_HDR_MODE1_MDEU_PAD |
2727 DESC_HDR_MODE1_MDEU_MD5_HMAC,
Lee Nipper4de9d0b2009-03-29 15:52:32 +08002728 },
LEROY Christophe7405c8d2016-06-06 13:20:46 +02002729 { .type = CRYPTO_ALG_TYPE_AEAD,
2730 .priority = TALITOS_CRA_PRIORITY_AEAD_HSNA,
2731 .alg.aead = {
2732 .base = {
2733 .cra_name = "authenc(hmac(md5),cbc(des3_ede))",
2734 .cra_driver_name = "authenc-hmac-md5-"
2735 "cbc-3des-talitos",
2736 .cra_blocksize = DES3_EDE_BLOCK_SIZE,
2737 .cra_flags = CRYPTO_ALG_ASYNC,
2738 },
2739 .ivsize = DES3_EDE_BLOCK_SIZE,
2740 .maxauthsize = MD5_DIGEST_SIZE,
Herbert Xuef7c5c82019-04-11 16:51:21 +08002741 .setkey = aead_des3_setkey,
LEROY Christophe7405c8d2016-06-06 13:20:46 +02002742 },
2743 .desc_hdr_template = DESC_HDR_TYPE_HMAC_SNOOP_NO_AFEU |
2744 DESC_HDR_SEL0_DEU |
2745 DESC_HDR_MODE0_DEU_CBC |
2746 DESC_HDR_MODE0_DEU_3DES |
2747 DESC_HDR_SEL1_MDEUA |
2748 DESC_HDR_MODE1_MDEU_INIT |
2749 DESC_HDR_MODE1_MDEU_PAD |
2750 DESC_HDR_MODE1_MDEU_MD5_HMAC,
2751 },
Lee Nipper4de9d0b2009-03-29 15:52:32 +08002752 /* ABLKCIPHER algorithms. */
Lee Nipperd5e4aae2010-05-19 19:18:38 +10002753 { .type = CRYPTO_ALG_TYPE_ABLKCIPHER,
2754 .alg.crypto = {
LEROY Christophe5e75ae12015-12-01 12:44:15 +01002755 .cra_name = "ecb(aes)",
2756 .cra_driver_name = "ecb-aes-talitos",
2757 .cra_blocksize = AES_BLOCK_SIZE,
2758 .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER |
2759 CRYPTO_ALG_ASYNC,
2760 .cra_ablkcipher = {
2761 .min_keysize = AES_MIN_KEY_SIZE,
2762 .max_keysize = AES_MAX_KEY_SIZE,
2763 .ivsize = AES_BLOCK_SIZE,
2764 }
2765 },
2766 .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
2767 DESC_HDR_SEL0_AESU,
2768 },
2769 { .type = CRYPTO_ALG_TYPE_ABLKCIPHER,
2770 .alg.crypto = {
Lee Nipper4de9d0b2009-03-29 15:52:32 +08002771 .cra_name = "cbc(aes)",
2772 .cra_driver_name = "cbc-aes-talitos",
2773 .cra_blocksize = AES_BLOCK_SIZE,
2774 .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER |
2775 CRYPTO_ALG_ASYNC,
Lee Nipper4de9d0b2009-03-29 15:52:32 +08002776 .cra_ablkcipher = {
Lee Nipper4de9d0b2009-03-29 15:52:32 +08002777 .min_keysize = AES_MIN_KEY_SIZE,
2778 .max_keysize = AES_MAX_KEY_SIZE,
2779 .ivsize = AES_BLOCK_SIZE,
2780 }
2781 },
2782 .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
2783 DESC_HDR_SEL0_AESU |
2784 DESC_HDR_MODE0_AESU_CBC,
2785 },
Lee Nipperd5e4aae2010-05-19 19:18:38 +10002786 { .type = CRYPTO_ALG_TYPE_ABLKCIPHER,
2787 .alg.crypto = {
LEROY Christophe5e75ae12015-12-01 12:44:15 +01002788 .cra_name = "ctr(aes)",
2789 .cra_driver_name = "ctr-aes-talitos",
2790 .cra_blocksize = AES_BLOCK_SIZE,
2791 .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER |
2792 CRYPTO_ALG_ASYNC,
2793 .cra_ablkcipher = {
2794 .min_keysize = AES_MIN_KEY_SIZE,
2795 .max_keysize = AES_MAX_KEY_SIZE,
2796 .ivsize = AES_BLOCK_SIZE,
2797 }
2798 },
LEROY Christophe70d355c2017-10-06 15:04:43 +02002799 .desc_hdr_template = DESC_HDR_TYPE_AESU_CTR_NONSNOOP |
LEROY Christophe5e75ae12015-12-01 12:44:15 +01002800 DESC_HDR_SEL0_AESU |
2801 DESC_HDR_MODE0_AESU_CTR,
2802 },
2803 { .type = CRYPTO_ALG_TYPE_ABLKCIPHER,
2804 .alg.crypto = {
2805 .cra_name = "ecb(des)",
2806 .cra_driver_name = "ecb-des-talitos",
2807 .cra_blocksize = DES_BLOCK_SIZE,
2808 .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER |
2809 CRYPTO_ALG_ASYNC,
2810 .cra_ablkcipher = {
2811 .min_keysize = DES_KEY_SIZE,
2812 .max_keysize = DES_KEY_SIZE,
2813 .ivsize = DES_BLOCK_SIZE,
Herbert Xuef7c5c82019-04-11 16:51:21 +08002814 .setkey = ablkcipher_des_setkey,
LEROY Christophe5e75ae12015-12-01 12:44:15 +01002815 }
2816 },
2817 .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
2818 DESC_HDR_SEL0_DEU,
2819 },
2820 { .type = CRYPTO_ALG_TYPE_ABLKCIPHER,
2821 .alg.crypto = {
2822 .cra_name = "cbc(des)",
2823 .cra_driver_name = "cbc-des-talitos",
2824 .cra_blocksize = DES_BLOCK_SIZE,
2825 .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER |
2826 CRYPTO_ALG_ASYNC,
2827 .cra_ablkcipher = {
2828 .min_keysize = DES_KEY_SIZE,
2829 .max_keysize = DES_KEY_SIZE,
2830 .ivsize = DES_BLOCK_SIZE,
Herbert Xuef7c5c82019-04-11 16:51:21 +08002831 .setkey = ablkcipher_des_setkey,
LEROY Christophe5e75ae12015-12-01 12:44:15 +01002832 }
2833 },
2834 .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
2835 DESC_HDR_SEL0_DEU |
2836 DESC_HDR_MODE0_DEU_CBC,
2837 },
2838 { .type = CRYPTO_ALG_TYPE_ABLKCIPHER,
2839 .alg.crypto = {
2840 .cra_name = "ecb(des3_ede)",
2841 .cra_driver_name = "ecb-3des-talitos",
2842 .cra_blocksize = DES3_EDE_BLOCK_SIZE,
2843 .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER |
2844 CRYPTO_ALG_ASYNC,
2845 .cra_ablkcipher = {
2846 .min_keysize = DES3_EDE_KEY_SIZE,
2847 .max_keysize = DES3_EDE_KEY_SIZE,
2848 .ivsize = DES3_EDE_BLOCK_SIZE,
Herbert Xuef7c5c82019-04-11 16:51:21 +08002849 .setkey = ablkcipher_des3_setkey,
LEROY Christophe5e75ae12015-12-01 12:44:15 +01002850 }
2851 },
2852 .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
2853 DESC_HDR_SEL0_DEU |
2854 DESC_HDR_MODE0_DEU_3DES,
2855 },
2856 { .type = CRYPTO_ALG_TYPE_ABLKCIPHER,
2857 .alg.crypto = {
Lee Nipper4de9d0b2009-03-29 15:52:32 +08002858 .cra_name = "cbc(des3_ede)",
2859 .cra_driver_name = "cbc-3des-talitos",
2860 .cra_blocksize = DES3_EDE_BLOCK_SIZE,
2861 .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER |
2862 CRYPTO_ALG_ASYNC,
Lee Nipper4de9d0b2009-03-29 15:52:32 +08002863 .cra_ablkcipher = {
Lee Nipper4de9d0b2009-03-29 15:52:32 +08002864 .min_keysize = DES3_EDE_KEY_SIZE,
2865 .max_keysize = DES3_EDE_KEY_SIZE,
2866 .ivsize = DES3_EDE_BLOCK_SIZE,
Herbert Xuef7c5c82019-04-11 16:51:21 +08002867 .setkey = ablkcipher_des3_setkey,
Lee Nipper4de9d0b2009-03-29 15:52:32 +08002868 }
2869 },
2870 .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
2871 DESC_HDR_SEL0_DEU |
2872 DESC_HDR_MODE0_DEU_CBC |
2873 DESC_HDR_MODE0_DEU_3DES,
Lee Nipper497f2e62010-05-19 19:20:36 +10002874 },
2875 /* AHASH algorithms. */
2876 { .type = CRYPTO_ALG_TYPE_AHASH,
2877 .alg.hash = {
Lee Nipper497f2e62010-05-19 19:20:36 +10002878 .halg.digestsize = MD5_DIGEST_SIZE,
Horia Geant?3639ca82016-04-21 19:24:55 +03002879 .halg.statesize = sizeof(struct talitos_export_state),
Lee Nipper497f2e62010-05-19 19:20:36 +10002880 .halg.base = {
2881 .cra_name = "md5",
2882 .cra_driver_name = "md5-talitos",
Martin Hicksb3988612015-03-03 08:21:34 -05002883 .cra_blocksize = MD5_HMAC_BLOCK_SIZE,
Eric Biggers6a38f622018-06-30 15:16:12 -07002884 .cra_flags = CRYPTO_ALG_ASYNC,
Lee Nipper497f2e62010-05-19 19:20:36 +10002885 }
2886 },
2887 .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
2888 DESC_HDR_SEL0_MDEUA |
2889 DESC_HDR_MODE0_MDEU_MD5,
2890 },
2891 { .type = CRYPTO_ALG_TYPE_AHASH,
2892 .alg.hash = {
Lee Nipper497f2e62010-05-19 19:20:36 +10002893 .halg.digestsize = SHA1_DIGEST_SIZE,
Horia Geant?3639ca82016-04-21 19:24:55 +03002894 .halg.statesize = sizeof(struct talitos_export_state),
Lee Nipper497f2e62010-05-19 19:20:36 +10002895 .halg.base = {
2896 .cra_name = "sha1",
2897 .cra_driver_name = "sha1-talitos",
2898 .cra_blocksize = SHA1_BLOCK_SIZE,
Eric Biggers6a38f622018-06-30 15:16:12 -07002899 .cra_flags = CRYPTO_ALG_ASYNC,
Lee Nipper497f2e62010-05-19 19:20:36 +10002900 }
2901 },
2902 .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
2903 DESC_HDR_SEL0_MDEUA |
2904 DESC_HDR_MODE0_MDEU_SHA1,
2905 },
2906 { .type = CRYPTO_ALG_TYPE_AHASH,
2907 .alg.hash = {
Kim Phillips60f208d2010-05-19 19:21:53 +10002908 .halg.digestsize = SHA224_DIGEST_SIZE,
Horia Geant?3639ca82016-04-21 19:24:55 +03002909 .halg.statesize = sizeof(struct talitos_export_state),
Kim Phillips60f208d2010-05-19 19:21:53 +10002910 .halg.base = {
2911 .cra_name = "sha224",
2912 .cra_driver_name = "sha224-talitos",
2913 .cra_blocksize = SHA224_BLOCK_SIZE,
Eric Biggers6a38f622018-06-30 15:16:12 -07002914 .cra_flags = CRYPTO_ALG_ASYNC,
Kim Phillips60f208d2010-05-19 19:21:53 +10002915 }
2916 },
2917 .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
2918 DESC_HDR_SEL0_MDEUA |
2919 DESC_HDR_MODE0_MDEU_SHA224,
2920 },
2921 { .type = CRYPTO_ALG_TYPE_AHASH,
2922 .alg.hash = {
Lee Nipper497f2e62010-05-19 19:20:36 +10002923 .halg.digestsize = SHA256_DIGEST_SIZE,
Horia Geant?3639ca82016-04-21 19:24:55 +03002924 .halg.statesize = sizeof(struct talitos_export_state),
Lee Nipper497f2e62010-05-19 19:20:36 +10002925 .halg.base = {
2926 .cra_name = "sha256",
2927 .cra_driver_name = "sha256-talitos",
2928 .cra_blocksize = SHA256_BLOCK_SIZE,
Eric Biggers6a38f622018-06-30 15:16:12 -07002929 .cra_flags = CRYPTO_ALG_ASYNC,
Lee Nipper497f2e62010-05-19 19:20:36 +10002930 }
2931 },
2932 .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
2933 DESC_HDR_SEL0_MDEUA |
2934 DESC_HDR_MODE0_MDEU_SHA256,
2935 },
2936 { .type = CRYPTO_ALG_TYPE_AHASH,
2937 .alg.hash = {
Lee Nipper497f2e62010-05-19 19:20:36 +10002938 .halg.digestsize = SHA384_DIGEST_SIZE,
Horia Geant?3639ca82016-04-21 19:24:55 +03002939 .halg.statesize = sizeof(struct talitos_export_state),
Lee Nipper497f2e62010-05-19 19:20:36 +10002940 .halg.base = {
2941 .cra_name = "sha384",
2942 .cra_driver_name = "sha384-talitos",
2943 .cra_blocksize = SHA384_BLOCK_SIZE,
Eric Biggers6a38f622018-06-30 15:16:12 -07002944 .cra_flags = CRYPTO_ALG_ASYNC,
Lee Nipper497f2e62010-05-19 19:20:36 +10002945 }
2946 },
2947 .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
2948 DESC_HDR_SEL0_MDEUB |
2949 DESC_HDR_MODE0_MDEUB_SHA384,
2950 },
2951 { .type = CRYPTO_ALG_TYPE_AHASH,
2952 .alg.hash = {
Lee Nipper497f2e62010-05-19 19:20:36 +10002953 .halg.digestsize = SHA512_DIGEST_SIZE,
Horia Geant?3639ca82016-04-21 19:24:55 +03002954 .halg.statesize = sizeof(struct talitos_export_state),
Lee Nipper497f2e62010-05-19 19:20:36 +10002955 .halg.base = {
2956 .cra_name = "sha512",
2957 .cra_driver_name = "sha512-talitos",
2958 .cra_blocksize = SHA512_BLOCK_SIZE,
Eric Biggers6a38f622018-06-30 15:16:12 -07002959 .cra_flags = CRYPTO_ALG_ASYNC,
Lee Nipper497f2e62010-05-19 19:20:36 +10002960 }
2961 },
2962 .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
2963 DESC_HDR_SEL0_MDEUB |
2964 DESC_HDR_MODE0_MDEUB_SHA512,
2965 },
Lee Nipper79b3a412011-11-21 16:13:25 +08002966 { .type = CRYPTO_ALG_TYPE_AHASH,
2967 .alg.hash = {
Lee Nipper79b3a412011-11-21 16:13:25 +08002968 .halg.digestsize = MD5_DIGEST_SIZE,
Horia Geant?3639ca82016-04-21 19:24:55 +03002969 .halg.statesize = sizeof(struct talitos_export_state),
Lee Nipper79b3a412011-11-21 16:13:25 +08002970 .halg.base = {
2971 .cra_name = "hmac(md5)",
2972 .cra_driver_name = "hmac-md5-talitos",
Martin Hicksb3988612015-03-03 08:21:34 -05002973 .cra_blocksize = MD5_HMAC_BLOCK_SIZE,
Eric Biggers6a38f622018-06-30 15:16:12 -07002974 .cra_flags = CRYPTO_ALG_ASYNC,
Lee Nipper79b3a412011-11-21 16:13:25 +08002975 }
2976 },
2977 .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
2978 DESC_HDR_SEL0_MDEUA |
2979 DESC_HDR_MODE0_MDEU_MD5,
2980 },
2981 { .type = CRYPTO_ALG_TYPE_AHASH,
2982 .alg.hash = {
Lee Nipper79b3a412011-11-21 16:13:25 +08002983 .halg.digestsize = SHA1_DIGEST_SIZE,
Horia Geant?3639ca82016-04-21 19:24:55 +03002984 .halg.statesize = sizeof(struct talitos_export_state),
Lee Nipper79b3a412011-11-21 16:13:25 +08002985 .halg.base = {
2986 .cra_name = "hmac(sha1)",
2987 .cra_driver_name = "hmac-sha1-talitos",
2988 .cra_blocksize = SHA1_BLOCK_SIZE,
Eric Biggers6a38f622018-06-30 15:16:12 -07002989 .cra_flags = CRYPTO_ALG_ASYNC,
Lee Nipper79b3a412011-11-21 16:13:25 +08002990 }
2991 },
2992 .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
2993 DESC_HDR_SEL0_MDEUA |
2994 DESC_HDR_MODE0_MDEU_SHA1,
2995 },
2996 { .type = CRYPTO_ALG_TYPE_AHASH,
2997 .alg.hash = {
Lee Nipper79b3a412011-11-21 16:13:25 +08002998 .halg.digestsize = SHA224_DIGEST_SIZE,
Horia Geant?3639ca82016-04-21 19:24:55 +03002999 .halg.statesize = sizeof(struct talitos_export_state),
Lee Nipper79b3a412011-11-21 16:13:25 +08003000 .halg.base = {
3001 .cra_name = "hmac(sha224)",
3002 .cra_driver_name = "hmac-sha224-talitos",
3003 .cra_blocksize = SHA224_BLOCK_SIZE,
Eric Biggers6a38f622018-06-30 15:16:12 -07003004 .cra_flags = CRYPTO_ALG_ASYNC,
Lee Nipper79b3a412011-11-21 16:13:25 +08003005 }
3006 },
3007 .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
3008 DESC_HDR_SEL0_MDEUA |
3009 DESC_HDR_MODE0_MDEU_SHA224,
3010 },
3011 { .type = CRYPTO_ALG_TYPE_AHASH,
3012 .alg.hash = {
Lee Nipper79b3a412011-11-21 16:13:25 +08003013 .halg.digestsize = SHA256_DIGEST_SIZE,
Horia Geant?3639ca82016-04-21 19:24:55 +03003014 .halg.statesize = sizeof(struct talitos_export_state),
Lee Nipper79b3a412011-11-21 16:13:25 +08003015 .halg.base = {
3016 .cra_name = "hmac(sha256)",
3017 .cra_driver_name = "hmac-sha256-talitos",
3018 .cra_blocksize = SHA256_BLOCK_SIZE,
Eric Biggers6a38f622018-06-30 15:16:12 -07003019 .cra_flags = CRYPTO_ALG_ASYNC,
Lee Nipper79b3a412011-11-21 16:13:25 +08003020 }
3021 },
3022 .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
3023 DESC_HDR_SEL0_MDEUA |
3024 DESC_HDR_MODE0_MDEU_SHA256,
3025 },
3026 { .type = CRYPTO_ALG_TYPE_AHASH,
3027 .alg.hash = {
Lee Nipper79b3a412011-11-21 16:13:25 +08003028 .halg.digestsize = SHA384_DIGEST_SIZE,
Horia Geant?3639ca82016-04-21 19:24:55 +03003029 .halg.statesize = sizeof(struct talitos_export_state),
Lee Nipper79b3a412011-11-21 16:13:25 +08003030 .halg.base = {
3031 .cra_name = "hmac(sha384)",
3032 .cra_driver_name = "hmac-sha384-talitos",
3033 .cra_blocksize = SHA384_BLOCK_SIZE,
Eric Biggers6a38f622018-06-30 15:16:12 -07003034 .cra_flags = CRYPTO_ALG_ASYNC,
Lee Nipper79b3a412011-11-21 16:13:25 +08003035 }
3036 },
3037 .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
3038 DESC_HDR_SEL0_MDEUB |
3039 DESC_HDR_MODE0_MDEUB_SHA384,
3040 },
3041 { .type = CRYPTO_ALG_TYPE_AHASH,
3042 .alg.hash = {
Lee Nipper79b3a412011-11-21 16:13:25 +08003043 .halg.digestsize = SHA512_DIGEST_SIZE,
Horia Geant?3639ca82016-04-21 19:24:55 +03003044 .halg.statesize = sizeof(struct talitos_export_state),
Lee Nipper79b3a412011-11-21 16:13:25 +08003045 .halg.base = {
3046 .cra_name = "hmac(sha512)",
3047 .cra_driver_name = "hmac-sha512-talitos",
3048 .cra_blocksize = SHA512_BLOCK_SIZE,
Eric Biggers6a38f622018-06-30 15:16:12 -07003049 .cra_flags = CRYPTO_ALG_ASYNC,
Lee Nipper79b3a412011-11-21 16:13:25 +08003050 }
3051 },
3052 .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
3053 DESC_HDR_SEL0_MDEUB |
3054 DESC_HDR_MODE0_MDEUB_SHA512,
3055 }
Kim Phillips9c4a7962008-06-23 19:50:15 +08003056};
3057
3058struct talitos_crypto_alg {
3059 struct list_head entry;
3060 struct device *dev;
Lee Nipperacbf7c622010-05-19 19:19:33 +10003061 struct talitos_alg_template algt;
Kim Phillips9c4a7962008-06-23 19:50:15 +08003062};
3063
Jonas Eymann89d124c2016-04-19 20:33:47 +03003064static int talitos_init_common(struct talitos_ctx *ctx,
3065 struct talitos_crypto_alg *talitos_alg)
Kim Phillips9c4a7962008-06-23 19:50:15 +08003066{
Kim Phillips5228f0f2011-07-15 11:21:38 +08003067 struct talitos_private *priv;
Kim Phillips9c4a7962008-06-23 19:50:15 +08003068
3069 /* update context with ptr to dev */
3070 ctx->dev = talitos_alg->dev;
Kim Phillips19bbbc62009-03-29 15:53:59 +08003071
Kim Phillips5228f0f2011-07-15 11:21:38 +08003072 /* assign SEC channel to tfm in round-robin fashion */
3073 priv = dev_get_drvdata(ctx->dev);
3074 ctx->ch = atomic_inc_return(&priv->last_chan) &
3075 (priv->num_channels - 1);
3076
Kim Phillips9c4a7962008-06-23 19:50:15 +08003077 /* copy descriptor header template value */
Lee Nipperacbf7c622010-05-19 19:19:33 +10003078 ctx->desc_hdr_template = talitos_alg->algt.desc_hdr_template;
Kim Phillips9c4a7962008-06-23 19:50:15 +08003079
Kim Phillips602dba52011-07-15 11:21:39 +08003080 /* select done notification */
3081 ctx->desc_hdr_template |= DESC_HDR_DONE_NOTIFY;
3082
Lee Nipper497f2e62010-05-19 19:20:36 +10003083 return 0;
3084}
3085
Jonas Eymann89d124c2016-04-19 20:33:47 +03003086static int talitos_cra_init(struct crypto_tfm *tfm)
3087{
3088 struct crypto_alg *alg = tfm->__crt_alg;
3089 struct talitos_crypto_alg *talitos_alg;
3090 struct talitos_ctx *ctx = crypto_tfm_ctx(tfm);
3091
3092 if ((alg->cra_flags & CRYPTO_ALG_TYPE_MASK) == CRYPTO_ALG_TYPE_AHASH)
3093 talitos_alg = container_of(__crypto_ahash_alg(alg),
3094 struct talitos_crypto_alg,
3095 algt.alg.hash);
3096 else
3097 talitos_alg = container_of(alg, struct talitos_crypto_alg,
3098 algt.alg.crypto);
3099
3100 return talitos_init_common(ctx, talitos_alg);
3101}
3102
Herbert Xuaeb4c132015-07-30 17:53:22 +08003103static int talitos_cra_init_aead(struct crypto_aead *tfm)
Lee Nipper497f2e62010-05-19 19:20:36 +10003104{
Jonas Eymann89d124c2016-04-19 20:33:47 +03003105 struct aead_alg *alg = crypto_aead_alg(tfm);
3106 struct talitos_crypto_alg *talitos_alg;
3107 struct talitos_ctx *ctx = crypto_aead_ctx(tfm);
3108
3109 talitos_alg = container_of(alg, struct talitos_crypto_alg,
3110 algt.alg.aead);
3111
3112 return talitos_init_common(ctx, talitos_alg);
Kim Phillips9c4a7962008-06-23 19:50:15 +08003113}
3114
Lee Nipper497f2e62010-05-19 19:20:36 +10003115static int talitos_cra_init_ahash(struct crypto_tfm *tfm)
3116{
3117 struct talitos_ctx *ctx = crypto_tfm_ctx(tfm);
3118
3119 talitos_cra_init(tfm);
3120
3121 ctx->keylen = 0;
3122 crypto_ahash_set_reqsize(__crypto_ahash_cast(tfm),
3123 sizeof(struct talitos_ahash_req_ctx));
3124
3125 return 0;
3126}
3127
LEROY Christophe2e13ce02017-10-06 15:05:02 +02003128static void talitos_cra_exit(struct crypto_tfm *tfm)
3129{
3130 struct talitos_ctx *ctx = crypto_tfm_ctx(tfm);
3131 struct device *dev = ctx->dev;
3132
3133 if (ctx->keylen)
3134 dma_unmap_single(dev, ctx->dma_key, ctx->keylen, DMA_TO_DEVICE);
3135}
3136
Kim Phillips9c4a7962008-06-23 19:50:15 +08003137/*
3138 * given the alg's descriptor header template, determine whether descriptor
3139 * type and primary/secondary execution units required match the hw
3140 * capabilities description provided in the device tree node.
3141 */
3142static int hw_supports(struct device *dev, __be32 desc_hdr_template)
3143{
3144 struct talitos_private *priv = dev_get_drvdata(dev);
3145 int ret;
3146
3147 ret = (1 << DESC_TYPE(desc_hdr_template) & priv->desc_types) &&
3148 (1 << PRIMARY_EU(desc_hdr_template) & priv->exec_units);
3149
3150 if (SECONDARY_EU(desc_hdr_template))
3151 ret = ret && (1 << SECONDARY_EU(desc_hdr_template)
3152 & priv->exec_units);
3153
3154 return ret;
3155}
3156
Grant Likely2dc11582010-08-06 09:25:50 -06003157static int talitos_remove(struct platform_device *ofdev)
Kim Phillips9c4a7962008-06-23 19:50:15 +08003158{
3159 struct device *dev = &ofdev->dev;
3160 struct talitos_private *priv = dev_get_drvdata(dev);
3161 struct talitos_crypto_alg *t_alg, *n;
3162 int i;
3163
3164 list_for_each_entry_safe(t_alg, n, &priv->alg_list, entry) {
Lee Nipperacbf7c622010-05-19 19:19:33 +10003165 switch (t_alg->algt.type) {
3166 case CRYPTO_ALG_TYPE_ABLKCIPHER:
Lee Nipperacbf7c622010-05-19 19:19:33 +10003167 break;
Herbert Xuaeb4c132015-07-30 17:53:22 +08003168 case CRYPTO_ALG_TYPE_AEAD:
3169 crypto_unregister_aead(&t_alg->algt.alg.aead);
Lee Nipperacbf7c622010-05-19 19:19:33 +10003170 case CRYPTO_ALG_TYPE_AHASH:
3171 crypto_unregister_ahash(&t_alg->algt.alg.hash);
3172 break;
3173 }
Kim Phillips9c4a7962008-06-23 19:50:15 +08003174 list_del(&t_alg->entry);
Kim Phillips9c4a7962008-06-23 19:50:15 +08003175 }
3176
3177 if (hw_supports(dev, DESC_HDR_SEL0_RNG))
3178 talitos_unregister_rng(dev);
3179
Kim Phillipsc3e337f2011-11-21 16:13:27 +08003180 for (i = 0; i < 2; i++)
Kim Phillips2cdba3c2011-12-12 14:59:11 -06003181 if (priv->irq[i]) {
Kim Phillipsc3e337f2011-11-21 16:13:27 +08003182 free_irq(priv->irq[i], dev);
3183 irq_dispose_mapping(priv->irq[i]);
3184 }
Kim Phillips9c4a7962008-06-23 19:50:15 +08003185
Kim Phillipsc3e337f2011-11-21 16:13:27 +08003186 tasklet_kill(&priv->done_task[0]);
Kim Phillips2cdba3c2011-12-12 14:59:11 -06003187 if (priv->irq[1])
Kim Phillipsc3e337f2011-11-21 16:13:27 +08003188 tasklet_kill(&priv->done_task[1]);
Kim Phillips9c4a7962008-06-23 19:50:15 +08003189
Kim Phillips9c4a7962008-06-23 19:50:15 +08003190 return 0;
3191}
3192
3193static struct talitos_crypto_alg *talitos_alg_alloc(struct device *dev,
3194 struct talitos_alg_template
3195 *template)
3196{
Kim Phillips60f208d2010-05-19 19:21:53 +10003197 struct talitos_private *priv = dev_get_drvdata(dev);
Kim Phillips9c4a7962008-06-23 19:50:15 +08003198 struct talitos_crypto_alg *t_alg;
3199 struct crypto_alg *alg;
3200
LEROY Christophe24b92ff2017-10-06 15:04:49 +02003201 t_alg = devm_kzalloc(dev, sizeof(struct talitos_crypto_alg),
3202 GFP_KERNEL);
Kim Phillips9c4a7962008-06-23 19:50:15 +08003203 if (!t_alg)
3204 return ERR_PTR(-ENOMEM);
3205
Lee Nipperacbf7c622010-05-19 19:19:33 +10003206 t_alg->algt = *template;
3207
3208 switch (t_alg->algt.type) {
3209 case CRYPTO_ALG_TYPE_ABLKCIPHER:
Lee Nipper497f2e62010-05-19 19:20:36 +10003210 alg = &t_alg->algt.alg.crypto;
3211 alg->cra_init = talitos_cra_init;
LEROY Christophe2e13ce02017-10-06 15:05:02 +02003212 alg->cra_exit = talitos_cra_exit;
Kim Phillipsd4cd3282012-08-08 20:32:00 -05003213 alg->cra_type = &crypto_ablkcipher_type;
Herbert Xuef7c5c82019-04-11 16:51:21 +08003214 alg->cra_ablkcipher.setkey = alg->cra_ablkcipher.setkey ?:
3215 ablkcipher_setkey;
Kim Phillipsb286e002012-08-08 20:33:34 -05003216 alg->cra_ablkcipher.encrypt = ablkcipher_encrypt;
3217 alg->cra_ablkcipher.decrypt = ablkcipher_decrypt;
Lee Nipper497f2e62010-05-19 19:20:36 +10003218 break;
Lee Nipperacbf7c622010-05-19 19:19:33 +10003219 case CRYPTO_ALG_TYPE_AEAD:
Herbert Xuaeb4c132015-07-30 17:53:22 +08003220 alg = &t_alg->algt.alg.aead.base;
LEROY Christophe2e13ce02017-10-06 15:05:02 +02003221 alg->cra_exit = talitos_cra_exit;
Herbert Xuaeb4c132015-07-30 17:53:22 +08003222 t_alg->algt.alg.aead.init = talitos_cra_init_aead;
Herbert Xuef7c5c82019-04-11 16:51:21 +08003223 t_alg->algt.alg.aead.setkey = t_alg->algt.alg.aead.setkey ?:
3224 aead_setkey;
Herbert Xuaeb4c132015-07-30 17:53:22 +08003225 t_alg->algt.alg.aead.encrypt = aead_encrypt;
3226 t_alg->algt.alg.aead.decrypt = aead_decrypt;
LEROY Christophe6cda0752017-10-06 15:04:39 +02003227 if (!(priv->features & TALITOS_FTR_SHA224_HWINIT) &&
3228 !strncmp(alg->cra_name, "authenc(hmac(sha224)", 20)) {
LEROY Christophe24b92ff2017-10-06 15:04:49 +02003229 devm_kfree(dev, t_alg);
LEROY Christophe6cda0752017-10-06 15:04:39 +02003230 return ERR_PTR(-ENOTSUPP);
3231 }
Lee Nipperacbf7c622010-05-19 19:19:33 +10003232 break;
3233 case CRYPTO_ALG_TYPE_AHASH:
3234 alg = &t_alg->algt.alg.hash.halg.base;
Lee Nipper497f2e62010-05-19 19:20:36 +10003235 alg->cra_init = talitos_cra_init_ahash;
LEROY Christophead4cd512018-02-26 17:40:04 +01003236 alg->cra_exit = talitos_cra_exit;
Kim Phillipsb286e002012-08-08 20:33:34 -05003237 t_alg->algt.alg.hash.init = ahash_init;
3238 t_alg->algt.alg.hash.update = ahash_update;
3239 t_alg->algt.alg.hash.final = ahash_final;
3240 t_alg->algt.alg.hash.finup = ahash_finup;
3241 t_alg->algt.alg.hash.digest = ahash_digest;
LEROY Christophe56136632017-09-12 11:03:39 +02003242 if (!strncmp(alg->cra_name, "hmac", 4))
3243 t_alg->algt.alg.hash.setkey = ahash_setkey;
Horia Geant?3639ca82016-04-21 19:24:55 +03003244 t_alg->algt.alg.hash.import = ahash_import;
3245 t_alg->algt.alg.hash.export = ahash_export;
Kim Phillipsb286e002012-08-08 20:33:34 -05003246
Lee Nipper79b3a412011-11-21 16:13:25 +08003247 if (!(priv->features & TALITOS_FTR_HMAC_OK) &&
Kim Phillips0b2730d2011-12-12 14:59:10 -06003248 !strncmp(alg->cra_name, "hmac", 4)) {
LEROY Christophe24b92ff2017-10-06 15:04:49 +02003249 devm_kfree(dev, t_alg);
Lee Nipper79b3a412011-11-21 16:13:25 +08003250 return ERR_PTR(-ENOTSUPP);
Kim Phillips0b2730d2011-12-12 14:59:10 -06003251 }
Kim Phillips60f208d2010-05-19 19:21:53 +10003252 if (!(priv->features & TALITOS_FTR_SHA224_HWINIT) &&
Lee Nipper79b3a412011-11-21 16:13:25 +08003253 (!strcmp(alg->cra_name, "sha224") ||
3254 !strcmp(alg->cra_name, "hmac(sha224)"))) {
Kim Phillips60f208d2010-05-19 19:21:53 +10003255 t_alg->algt.alg.hash.init = ahash_init_sha224_swinit;
3256 t_alg->algt.desc_hdr_template =
3257 DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
3258 DESC_HDR_SEL0_MDEUA |
3259 DESC_HDR_MODE0_MDEU_SHA256;
3260 }
Lee Nipper497f2e62010-05-19 19:20:36 +10003261 break;
Kim Phillips1d119112010-09-23 15:55:27 +08003262 default:
3263 dev_err(dev, "unknown algorithm type %d\n", t_alg->algt.type);
LEROY Christophe24b92ff2017-10-06 15:04:49 +02003264 devm_kfree(dev, t_alg);
Kim Phillips1d119112010-09-23 15:55:27 +08003265 return ERR_PTR(-EINVAL);
Lee Nipperacbf7c622010-05-19 19:19:33 +10003266 }
Kim Phillips9c4a7962008-06-23 19:50:15 +08003267
Kim Phillips9c4a7962008-06-23 19:50:15 +08003268 alg->cra_module = THIS_MODULE;
LEROY Christopheb0057762016-06-06 13:20:44 +02003269 if (t_alg->algt.priority)
3270 alg->cra_priority = t_alg->algt.priority;
3271 else
3272 alg->cra_priority = TALITOS_CRA_PRIORITY;
Kim Phillips9c4a7962008-06-23 19:50:15 +08003273 alg->cra_alignmask = 0;
Kim Phillips9c4a7962008-06-23 19:50:15 +08003274 alg->cra_ctxsize = sizeof(struct talitos_ctx);
Nikos Mavrogiannopoulosd912bb72011-11-01 13:39:56 +01003275 alg->cra_flags |= CRYPTO_ALG_KERN_DRIVER_ONLY;
Kim Phillips9c4a7962008-06-23 19:50:15 +08003276
Kim Phillips9c4a7962008-06-23 19:50:15 +08003277 t_alg->dev = dev;
3278
3279 return t_alg;
3280}
3281
Kim Phillipsc3e337f2011-11-21 16:13:27 +08003282static int talitos_probe_irq(struct platform_device *ofdev)
3283{
3284 struct device *dev = &ofdev->dev;
3285 struct device_node *np = ofdev->dev.of_node;
3286 struct talitos_private *priv = dev_get_drvdata(dev);
3287 int err;
LEROY Christophedd3c0982015-04-17 16:32:13 +02003288 bool is_sec1 = has_ftr_sec1(priv);
Kim Phillipsc3e337f2011-11-21 16:13:27 +08003289
3290 priv->irq[0] = irq_of_parse_and_map(np, 0);
Kim Phillips2cdba3c2011-12-12 14:59:11 -06003291 if (!priv->irq[0]) {
Kim Phillipsc3e337f2011-11-21 16:13:27 +08003292 dev_err(dev, "failed to map irq\n");
3293 return -EINVAL;
3294 }
LEROY Christophedd3c0982015-04-17 16:32:13 +02003295 if (is_sec1) {
3296 err = request_irq(priv->irq[0], talitos1_interrupt_4ch, 0,
3297 dev_driver_string(dev), dev);
3298 goto primary_out;
3299 }
Kim Phillipsc3e337f2011-11-21 16:13:27 +08003300
3301 priv->irq[1] = irq_of_parse_and_map(np, 1);
3302
3303 /* get the primary irq line */
Kim Phillips2cdba3c2011-12-12 14:59:11 -06003304 if (!priv->irq[1]) {
LEROY Christophedd3c0982015-04-17 16:32:13 +02003305 err = request_irq(priv->irq[0], talitos2_interrupt_4ch, 0,
Kim Phillipsc3e337f2011-11-21 16:13:27 +08003306 dev_driver_string(dev), dev);
3307 goto primary_out;
3308 }
3309
LEROY Christophedd3c0982015-04-17 16:32:13 +02003310 err = request_irq(priv->irq[0], talitos2_interrupt_ch0_2, 0,
Kim Phillipsc3e337f2011-11-21 16:13:27 +08003311 dev_driver_string(dev), dev);
3312 if (err)
3313 goto primary_out;
3314
3315 /* get the secondary irq line */
LEROY Christophedd3c0982015-04-17 16:32:13 +02003316 err = request_irq(priv->irq[1], talitos2_interrupt_ch1_3, 0,
Kim Phillipsc3e337f2011-11-21 16:13:27 +08003317 dev_driver_string(dev), dev);
3318 if (err) {
3319 dev_err(dev, "failed to request secondary irq\n");
3320 irq_dispose_mapping(priv->irq[1]);
Kim Phillips2cdba3c2011-12-12 14:59:11 -06003321 priv->irq[1] = 0;
Kim Phillipsc3e337f2011-11-21 16:13:27 +08003322 }
3323
3324 return err;
3325
3326primary_out:
3327 if (err) {
3328 dev_err(dev, "failed to request primary irq\n");
3329 irq_dispose_mapping(priv->irq[0]);
Kim Phillips2cdba3c2011-12-12 14:59:11 -06003330 priv->irq[0] = 0;
Kim Phillipsc3e337f2011-11-21 16:13:27 +08003331 }
3332
3333 return err;
3334}
3335
Grant Likely1c48a5c2011-02-17 02:43:24 -07003336static int talitos_probe(struct platform_device *ofdev)
Kim Phillips9c4a7962008-06-23 19:50:15 +08003337{
3338 struct device *dev = &ofdev->dev;
Grant Likely61c7a082010-04-13 16:12:29 -07003339 struct device_node *np = ofdev->dev.of_node;
Kim Phillips9c4a7962008-06-23 19:50:15 +08003340 struct talitos_private *priv;
Kim Phillips9c4a7962008-06-23 19:50:15 +08003341 int i, err;
LEROY Christophe5fa7fa12015-04-17 16:32:11 +02003342 int stride;
LEROY Christophefd5ea7f2017-10-06 15:04:53 +02003343 struct resource *res;
Kim Phillips9c4a7962008-06-23 19:50:15 +08003344
LEROY Christophe24b92ff2017-10-06 15:04:49 +02003345 priv = devm_kzalloc(dev, sizeof(struct talitos_private), GFP_KERNEL);
Kim Phillips9c4a7962008-06-23 19:50:15 +08003346 if (!priv)
3347 return -ENOMEM;
3348
Kevin Haof3de9cb2014-01-28 20:17:23 +08003349 INIT_LIST_HEAD(&priv->alg_list);
3350
Kim Phillips9c4a7962008-06-23 19:50:15 +08003351 dev_set_drvdata(dev, priv);
3352
3353 priv->ofdev = ofdev;
3354
Horia Geanta511d63c2012-03-30 17:49:53 +03003355 spin_lock_init(&priv->reg_lock);
3356
LEROY Christophefd5ea7f2017-10-06 15:04:53 +02003357 res = platform_get_resource(ofdev, IORESOURCE_MEM, 0);
3358 if (!res)
3359 return -ENXIO;
3360 priv->reg = devm_ioremap(dev, res->start, resource_size(res));
Kim Phillips9c4a7962008-06-23 19:50:15 +08003361 if (!priv->reg) {
3362 dev_err(dev, "failed to of_iomap\n");
3363 err = -ENOMEM;
3364 goto err_out;
3365 }
3366
3367 /* get SEC version capabilities from device tree */
LEROY Christophefa14c6c2017-10-06 15:04:51 +02003368 of_property_read_u32(np, "fsl,num-channels", &priv->num_channels);
3369 of_property_read_u32(np, "fsl,channel-fifo-len", &priv->chfifo_len);
3370 of_property_read_u32(np, "fsl,exec-units-mask", &priv->exec_units);
3371 of_property_read_u32(np, "fsl,descriptor-types-mask",
3372 &priv->desc_types);
Kim Phillips9c4a7962008-06-23 19:50:15 +08003373
3374 if (!is_power_of_2(priv->num_channels) || !priv->chfifo_len ||
3375 !priv->exec_units || !priv->desc_types) {
3376 dev_err(dev, "invalid property data in device tree node\n");
3377 err = -EINVAL;
3378 goto err_out;
3379 }
3380
Lee Nipperf3c85bc2008-07-30 16:26:57 +08003381 if (of_device_is_compatible(np, "fsl,sec3.0"))
3382 priv->features |= TALITOS_FTR_SRC_LINK_TBL_LEN_INCLUDES_EXTENT;
3383
Kim Phillipsfe5720e2008-10-12 20:33:14 +08003384 if (of_device_is_compatible(np, "fsl,sec2.1"))
Kim Phillips60f208d2010-05-19 19:21:53 +10003385 priv->features |= TALITOS_FTR_HW_AUTH_CHECK |
Lee Nipper79b3a412011-11-21 16:13:25 +08003386 TALITOS_FTR_SHA224_HWINIT |
3387 TALITOS_FTR_HMAC_OK;
Kim Phillipsfe5720e2008-10-12 20:33:14 +08003388
LEROY Christophe21590882015-04-17 16:32:05 +02003389 if (of_device_is_compatible(np, "fsl,sec1.0"))
3390 priv->features |= TALITOS_FTR_SEC1;
3391
LEROY Christophe5fa7fa12015-04-17 16:32:11 +02003392 if (of_device_is_compatible(np, "fsl,sec1.2")) {
3393 priv->reg_deu = priv->reg + TALITOS12_DEU;
3394 priv->reg_aesu = priv->reg + TALITOS12_AESU;
3395 priv->reg_mdeu = priv->reg + TALITOS12_MDEU;
3396 stride = TALITOS1_CH_STRIDE;
3397 } else if (of_device_is_compatible(np, "fsl,sec1.0")) {
3398 priv->reg_deu = priv->reg + TALITOS10_DEU;
3399 priv->reg_aesu = priv->reg + TALITOS10_AESU;
3400 priv->reg_mdeu = priv->reg + TALITOS10_MDEU;
3401 priv->reg_afeu = priv->reg + TALITOS10_AFEU;
3402 priv->reg_rngu = priv->reg + TALITOS10_RNGU;
3403 priv->reg_pkeu = priv->reg + TALITOS10_PKEU;
3404 stride = TALITOS1_CH_STRIDE;
3405 } else {
3406 priv->reg_deu = priv->reg + TALITOS2_DEU;
3407 priv->reg_aesu = priv->reg + TALITOS2_AESU;
3408 priv->reg_mdeu = priv->reg + TALITOS2_MDEU;
3409 priv->reg_afeu = priv->reg + TALITOS2_AFEU;
3410 priv->reg_rngu = priv->reg + TALITOS2_RNGU;
3411 priv->reg_pkeu = priv->reg + TALITOS2_PKEU;
3412 priv->reg_keu = priv->reg + TALITOS2_KEU;
3413 priv->reg_crcu = priv->reg + TALITOS2_CRCU;
3414 stride = TALITOS2_CH_STRIDE;
3415 }
3416
LEROY Christophedd3c0982015-04-17 16:32:13 +02003417 err = talitos_probe_irq(ofdev);
3418 if (err)
3419 goto err_out;
3420
3421 if (of_device_is_compatible(np, "fsl,sec1.0")) {
LEROY Christophe9c02e282017-10-06 15:04:55 +02003422 if (priv->num_channels == 1)
3423 tasklet_init(&priv->done_task[0], talitos1_done_ch0,
LEROY Christophedd3c0982015-04-17 16:32:13 +02003424 (unsigned long)dev);
LEROY Christophe9c02e282017-10-06 15:04:55 +02003425 else
3426 tasklet_init(&priv->done_task[0], talitos1_done_4ch,
3427 (unsigned long)dev);
3428 } else {
3429 if (priv->irq[1]) {
LEROY Christophedd3c0982015-04-17 16:32:13 +02003430 tasklet_init(&priv->done_task[0], talitos2_done_ch0_2,
3431 (unsigned long)dev);
3432 tasklet_init(&priv->done_task[1], talitos2_done_ch1_3,
3433 (unsigned long)dev);
LEROY Christophe9c02e282017-10-06 15:04:55 +02003434 } else if (priv->num_channels == 1) {
3435 tasklet_init(&priv->done_task[0], talitos2_done_ch0,
3436 (unsigned long)dev);
3437 } else {
3438 tasklet_init(&priv->done_task[0], talitos2_done_4ch,
3439 (unsigned long)dev);
LEROY Christophedd3c0982015-04-17 16:32:13 +02003440 }
3441 }
3442
Kees Cooka86854d2018-06-12 14:07:58 -07003443 priv->chan = devm_kcalloc(dev,
3444 priv->num_channels,
3445 sizeof(struct talitos_channel),
3446 GFP_KERNEL);
Kim Phillips4b9926282009-08-13 11:50:38 +10003447 if (!priv->chan) {
3448 dev_err(dev, "failed to allocate channel management space\n");
Kim Phillips9c4a7962008-06-23 19:50:15 +08003449 err = -ENOMEM;
3450 goto err_out;
3451 }
3452
Martin Hicksf641ddd2015-03-03 08:21:33 -05003453 priv->fifo_len = roundup_pow_of_two(priv->chfifo_len);
3454
Kim Phillipsc3e337f2011-11-21 16:13:27 +08003455 for (i = 0; i < priv->num_channels; i++) {
LEROY Christophe5fa7fa12015-04-17 16:32:11 +02003456 priv->chan[i].reg = priv->reg + stride * (i + 1);
Kim Phillips2cdba3c2011-12-12 14:59:11 -06003457 if (!priv->irq[1] || !(i & 1))
Kim Phillipsc3e337f2011-11-21 16:13:27 +08003458 priv->chan[i].reg += TALITOS_CH_BASE_OFFSET;
Kim Phillipsad42d5f2011-11-21 16:13:27 +08003459
Kim Phillips4b9926282009-08-13 11:50:38 +10003460 spin_lock_init(&priv->chan[i].head_lock);
3461 spin_lock_init(&priv->chan[i].tail_lock);
Kim Phillips9c4a7962008-06-23 19:50:15 +08003462
Kees Cooka86854d2018-06-12 14:07:58 -07003463 priv->chan[i].fifo = devm_kcalloc(dev,
3464 priv->fifo_len,
3465 sizeof(struct talitos_request),
3466 GFP_KERNEL);
Kim Phillips4b9926282009-08-13 11:50:38 +10003467 if (!priv->chan[i].fifo) {
Kim Phillips9c4a7962008-06-23 19:50:15 +08003468 dev_err(dev, "failed to allocate request fifo %d\n", i);
3469 err = -ENOMEM;
3470 goto err_out;
3471 }
Kim Phillips9c4a7962008-06-23 19:50:15 +08003472
Kim Phillips4b9926282009-08-13 11:50:38 +10003473 atomic_set(&priv->chan[i].submit_count,
3474 -(priv->chfifo_len - 1));
Martin Hicksf641ddd2015-03-03 08:21:33 -05003475 }
Kim Phillips9c4a7962008-06-23 19:50:15 +08003476
Kim Phillips81eb0242009-08-13 11:51:51 +10003477 dma_set_mask(dev, DMA_BIT_MASK(36));
3478
Kim Phillips9c4a7962008-06-23 19:50:15 +08003479 /* reset and initialize the h/w */
3480 err = init_device(dev);
3481 if (err) {
3482 dev_err(dev, "failed to initialize device\n");
3483 goto err_out;
3484 }
3485
3486 /* register the RNG, if available */
3487 if (hw_supports(dev, DESC_HDR_SEL0_RNG)) {
3488 err = talitos_register_rng(dev);
3489 if (err) {
3490 dev_err(dev, "failed to register hwrng: %d\n", err);
3491 goto err_out;
3492 } else
3493 dev_info(dev, "hwrng\n");
3494 }
3495
3496 /* register crypto algorithms the device supports */
Kim Phillips9c4a7962008-06-23 19:50:15 +08003497 for (i = 0; i < ARRAY_SIZE(driver_algs); i++) {
3498 if (hw_supports(dev, driver_algs[i].desc_hdr_template)) {
3499 struct talitos_crypto_alg *t_alg;
Herbert Xuaeb4c132015-07-30 17:53:22 +08003500 struct crypto_alg *alg = NULL;
Kim Phillips9c4a7962008-06-23 19:50:15 +08003501
3502 t_alg = talitos_alg_alloc(dev, &driver_algs[i]);
3503 if (IS_ERR(t_alg)) {
3504 err = PTR_ERR(t_alg);
Kim Phillips0b2730d2011-12-12 14:59:10 -06003505 if (err == -ENOTSUPP)
Lee Nipper79b3a412011-11-21 16:13:25 +08003506 continue;
Kim Phillips9c4a7962008-06-23 19:50:15 +08003507 goto err_out;
3508 }
3509
Lee Nipperacbf7c622010-05-19 19:19:33 +10003510 switch (t_alg->algt.type) {
3511 case CRYPTO_ALG_TYPE_ABLKCIPHER:
Lee Nipperacbf7c622010-05-19 19:19:33 +10003512 err = crypto_register_alg(
3513 &t_alg->algt.alg.crypto);
Herbert Xuaeb4c132015-07-30 17:53:22 +08003514 alg = &t_alg->algt.alg.crypto;
Lee Nipperacbf7c622010-05-19 19:19:33 +10003515 break;
Herbert Xuaeb4c132015-07-30 17:53:22 +08003516
3517 case CRYPTO_ALG_TYPE_AEAD:
3518 err = crypto_register_aead(
3519 &t_alg->algt.alg.aead);
3520 alg = &t_alg->algt.alg.aead.base;
3521 break;
3522
Lee Nipperacbf7c622010-05-19 19:19:33 +10003523 case CRYPTO_ALG_TYPE_AHASH:
3524 err = crypto_register_ahash(
3525 &t_alg->algt.alg.hash);
Herbert Xuaeb4c132015-07-30 17:53:22 +08003526 alg = &t_alg->algt.alg.hash.halg.base;
Lee Nipperacbf7c622010-05-19 19:19:33 +10003527 break;
3528 }
Kim Phillips9c4a7962008-06-23 19:50:15 +08003529 if (err) {
3530 dev_err(dev, "%s alg registration failed\n",
Herbert Xuaeb4c132015-07-30 17:53:22 +08003531 alg->cra_driver_name);
LEROY Christophe24b92ff2017-10-06 15:04:49 +02003532 devm_kfree(dev, t_alg);
Horia Geanta991155b2013-03-20 16:31:38 +02003533 } else
Kim Phillips9c4a7962008-06-23 19:50:15 +08003534 list_add_tail(&t_alg->entry, &priv->alg_list);
Kim Phillips9c4a7962008-06-23 19:50:15 +08003535 }
3536 }
Kim Phillips5b859b6e2011-11-21 16:13:26 +08003537 if (!list_empty(&priv->alg_list))
3538 dev_info(dev, "%s algorithms registered in /proc/crypto\n",
3539 (char *)of_get_property(np, "compatible", NULL));
Kim Phillips9c4a7962008-06-23 19:50:15 +08003540
3541 return 0;
3542
3543err_out:
3544 talitos_remove(ofdev);
Kim Phillips9c4a7962008-06-23 19:50:15 +08003545
3546 return err;
3547}
3548
Márton Németh6c3f9752010-01-17 21:54:01 +11003549static const struct of_device_id talitos_match[] = {
LEROY Christophe0635b7db2015-04-17 16:32:20 +02003550#ifdef CONFIG_CRYPTO_DEV_TALITOS1
3551 {
3552 .compatible = "fsl,sec1.0",
3553 },
3554#endif
3555#ifdef CONFIG_CRYPTO_DEV_TALITOS2
Kim Phillips9c4a7962008-06-23 19:50:15 +08003556 {
3557 .compatible = "fsl,sec2.0",
3558 },
LEROY Christophe0635b7db2015-04-17 16:32:20 +02003559#endif
Kim Phillips9c4a7962008-06-23 19:50:15 +08003560 {},
3561};
3562MODULE_DEVICE_TABLE(of, talitos_match);
3563
Grant Likely1c48a5c2011-02-17 02:43:24 -07003564static struct platform_driver talitos_driver = {
Grant Likely40182942010-04-13 16:13:02 -07003565 .driver = {
3566 .name = "talitos",
Grant Likely40182942010-04-13 16:13:02 -07003567 .of_match_table = talitos_match,
3568 },
Kim Phillips9c4a7962008-06-23 19:50:15 +08003569 .probe = talitos_probe,
Al Viro596f1032008-11-22 17:34:24 +00003570 .remove = talitos_remove,
Kim Phillips9c4a7962008-06-23 19:50:15 +08003571};
3572
Axel Lin741e8c22011-11-26 21:26:19 +08003573module_platform_driver(talitos_driver);
Kim Phillips9c4a7962008-06-23 19:50:15 +08003574
3575MODULE_LICENSE("GPL");
3576MODULE_AUTHOR("Kim Phillips <kim.phillips@freescale.com>");
3577MODULE_DESCRIPTION("Freescale integrated security engine (SEC) driver");