blob: 7c71722be395965b688bab8b233e6f6a2d13d0e2 [file] [log] [blame]
Kim Phillips9c4a7962008-06-23 19:50:15 +08001/*
2 * talitos - Freescale Integrated Security Engine (SEC) device driver
3 *
Kim Phillips5228f0f2011-07-15 11:21:38 +08004 * Copyright (c) 2008-2011 Freescale Semiconductor, Inc.
Kim Phillips9c4a7962008-06-23 19:50:15 +08005 *
6 * Scatterlist Crypto API glue code copied from files with the following:
7 * Copyright (c) 2006-2007 Herbert Xu <herbert@gondor.apana.org.au>
8 *
9 * Crypto algorithm registration code copied from hifn driver:
10 * 2007+ Copyright (c) Evgeniy Polyakov <johnpol@2ka.mipt.ru>
11 * All rights reserved.
12 *
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2 of the License, or
16 * (at your option) any later version.
17 *
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
22 *
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, write to the Free Software
25 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
26 */
27
28#include <linux/kernel.h>
29#include <linux/module.h>
30#include <linux/mod_devicetable.h>
31#include <linux/device.h>
32#include <linux/interrupt.h>
33#include <linux/crypto.h>
34#include <linux/hw_random.h>
Rob Herring5af50732013-09-17 14:28:33 -050035#include <linux/of_address.h>
36#include <linux/of_irq.h>
Kim Phillips9c4a7962008-06-23 19:50:15 +080037#include <linux/of_platform.h>
38#include <linux/dma-mapping.h>
39#include <linux/io.h>
40#include <linux/spinlock.h>
41#include <linux/rtnetlink.h>
Tejun Heo5a0e3ad2010-03-24 17:04:11 +090042#include <linux/slab.h>
Kim Phillips9c4a7962008-06-23 19:50:15 +080043
44#include <crypto/algapi.h>
45#include <crypto/aes.h>
Lee Nipper3952f172008-07-10 18:29:18 +080046#include <crypto/des.h>
Kim Phillips9c4a7962008-06-23 19:50:15 +080047#include <crypto/sha.h>
Lee Nipper497f2e62010-05-19 19:20:36 +100048#include <crypto/md5.h>
Herbert Xue98014a2015-05-11 17:47:48 +080049#include <crypto/internal/aead.h>
Kim Phillips9c4a7962008-06-23 19:50:15 +080050#include <crypto/authenc.h>
Lee Nipper4de9d0b2009-03-29 15:52:32 +080051#include <crypto/skcipher.h>
Lee Nipperacbf7c622010-05-19 19:19:33 +100052#include <crypto/hash.h>
53#include <crypto/internal/hash.h>
Lee Nipper4de9d0b2009-03-29 15:52:32 +080054#include <crypto/scatterwalk.h>
Kim Phillips9c4a7962008-06-23 19:50:15 +080055
56#include "talitos.h"
57
LEROY Christophe922f9dc2015-04-17 16:32:07 +020058static void to_talitos_ptr(struct talitos_ptr *ptr, dma_addr_t dma_addr,
59 bool is_sec1)
Kim Phillips81eb0242009-08-13 11:51:51 +100060{
LEROY Christopheedc6bd62015-04-17 16:31:53 +020061 ptr->ptr = cpu_to_be32(lower_32_bits(dma_addr));
LEROY Christophe922f9dc2015-04-17 16:32:07 +020062 if (!is_sec1)
63 ptr->eptr = upper_32_bits(dma_addr);
Kim Phillips81eb0242009-08-13 11:51:51 +100064}
65
Horia Geant?340ff602016-04-19 20:33:48 +030066static void copy_talitos_ptr(struct talitos_ptr *dst_ptr,
67 struct talitos_ptr *src_ptr, bool is_sec1)
68{
69 dst_ptr->ptr = src_ptr->ptr;
70 if (!is_sec1)
71 dst_ptr->eptr = src_ptr->eptr;
72}
73
Horia Geant?42e8b0d2015-05-11 20:04:56 +030074static void to_talitos_ptr_len(struct talitos_ptr *ptr, unsigned int len,
LEROY Christophe922f9dc2015-04-17 16:32:07 +020075 bool is_sec1)
LEROY Christophe538caf82015-04-17 16:31:59 +020076{
LEROY Christophe922f9dc2015-04-17 16:32:07 +020077 if (is_sec1) {
78 ptr->res = 0;
79 ptr->len1 = cpu_to_be16(len);
80 } else {
81 ptr->len = cpu_to_be16(len);
82 }
LEROY Christophe538caf82015-04-17 16:31:59 +020083}
84
LEROY Christophe922f9dc2015-04-17 16:32:07 +020085static unsigned short from_talitos_ptr_len(struct talitos_ptr *ptr,
86 bool is_sec1)
LEROY Christophe538caf82015-04-17 16:31:59 +020087{
LEROY Christophe922f9dc2015-04-17 16:32:07 +020088 if (is_sec1)
89 return be16_to_cpu(ptr->len1);
90 else
91 return be16_to_cpu(ptr->len);
LEROY Christophe538caf82015-04-17 16:31:59 +020092}
93
LEROY Christopheb096b542016-06-06 13:20:34 +020094static void to_talitos_ptr_ext_set(struct talitos_ptr *ptr, u8 val,
95 bool is_sec1)
LEROY Christophe185eb792015-04-17 16:31:55 +020096{
LEROY Christophe922f9dc2015-04-17 16:32:07 +020097 if (!is_sec1)
LEROY Christopheb096b542016-06-06 13:20:34 +020098 ptr->j_extent = val;
99}
100
101static void to_talitos_ptr_ext_or(struct talitos_ptr *ptr, u8 val, bool is_sec1)
102{
103 if (!is_sec1)
104 ptr->j_extent |= val;
LEROY Christophe185eb792015-04-17 16:31:55 +0200105}
106
Kim Phillips9c4a7962008-06-23 19:50:15 +0800107/*
108 * map virtual single (contiguous) pointer to h/w descriptor pointer
109 */
110static void map_single_talitos_ptr(struct device *dev,
LEROY Christopheedc6bd62015-04-17 16:31:53 +0200111 struct talitos_ptr *ptr,
Horia Geant?42e8b0d2015-05-11 20:04:56 +0300112 unsigned int len, void *data,
Kim Phillips9c4a7962008-06-23 19:50:15 +0800113 enum dma_data_direction dir)
114{
Kim Phillips81eb0242009-08-13 11:51:51 +1000115 dma_addr_t dma_addr = dma_map_single(dev, data, len, dir);
LEROY Christophe922f9dc2015-04-17 16:32:07 +0200116 struct talitos_private *priv = dev_get_drvdata(dev);
117 bool is_sec1 = has_ftr_sec1(priv);
Kim Phillips81eb0242009-08-13 11:51:51 +1000118
LEROY Christophe922f9dc2015-04-17 16:32:07 +0200119 to_talitos_ptr_len(ptr, len, is_sec1);
120 to_talitos_ptr(ptr, dma_addr, is_sec1);
LEROY Christopheb096b542016-06-06 13:20:34 +0200121 to_talitos_ptr_ext_set(ptr, 0, is_sec1);
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 Christopheedc6bd62015-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 Christopheedc6bd62015-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);
Kim Phillips9c4a7962008-06-23 19:50:15 +0800168
Kim Phillipsfe5720e2008-10-12 20:33:14 +0800169 /* and ICCR writeback, if available */
170 if (priv->features & TALITOS_FTR_HW_AUTH_CHECK)
Kim Phillipsad42d5f2011-11-21 16:13:27 +0800171 setbits32(priv->chan[ch].reg + TALITOS_CCCR_LO,
Kim Phillipsfe5720e2008-10-12 20:33:14 +0800172 TALITOS_CCCR_LO_IWSE);
173
Kim Phillips9c4a7962008-06-23 19:50:15 +0800174 return 0;
175}
176
177static int reset_device(struct device *dev)
178{
179 struct talitos_private *priv = dev_get_drvdata(dev);
180 unsigned int timeout = TALITOS_TIMEOUT;
LEROY Christophedd3c0982015-04-17 16:32:13 +0200181 bool is_sec1 = has_ftr_sec1(priv);
182 u32 mcr = is_sec1 ? TALITOS1_MCR_SWR : TALITOS2_MCR_SWR;
Kim Phillips9c4a7962008-06-23 19:50:15 +0800183
Kim Phillipsc3e337f2011-11-21 16:13:27 +0800184 setbits32(priv->reg + TALITOS_MCR, mcr);
Kim Phillips9c4a7962008-06-23 19:50:15 +0800185
LEROY Christophedd3c0982015-04-17 16:32:13 +0200186 while ((in_be32(priv->reg + TALITOS_MCR) & mcr)
Kim Phillips9c4a7962008-06-23 19:50:15 +0800187 && --timeout)
188 cpu_relax();
189
Kim Phillips2cdba3c2011-12-12 14:59:11 -0600190 if (priv->irq[1]) {
Kim Phillipsc3e337f2011-11-21 16:13:27 +0800191 mcr = TALITOS_MCR_RCA1 | TALITOS_MCR_RCA3;
192 setbits32(priv->reg + TALITOS_MCR, mcr);
193 }
194
Kim Phillips9c4a7962008-06-23 19:50:15 +0800195 if (timeout == 0) {
196 dev_err(dev, "failed to reset device\n");
197 return -EIO;
198 }
199
200 return 0;
201}
202
203/*
204 * Reset and initialize the device
205 */
206static int init_device(struct device *dev)
207{
208 struct talitos_private *priv = dev_get_drvdata(dev);
209 int ch, err;
LEROY Christophedd3c0982015-04-17 16:32:13 +0200210 bool is_sec1 = has_ftr_sec1(priv);
Kim Phillips9c4a7962008-06-23 19:50:15 +0800211
212 /*
213 * Master reset
214 * errata documentation: warning: certain SEC interrupts
215 * are not fully cleared by writing the MCR:SWR bit,
216 * set bit twice to completely reset
217 */
218 err = reset_device(dev);
219 if (err)
220 return err;
221
222 err = reset_device(dev);
223 if (err)
224 return err;
225
226 /* reset channels */
227 for (ch = 0; ch < priv->num_channels; ch++) {
228 err = reset_channel(dev, ch);
229 if (err)
230 return err;
231 }
232
233 /* enable channel done and error interrupts */
LEROY Christophedd3c0982015-04-17 16:32:13 +0200234 if (is_sec1) {
235 clrbits32(priv->reg + TALITOS_IMR, TALITOS1_IMR_INIT);
236 clrbits32(priv->reg + TALITOS_IMR_LO, TALITOS1_IMR_LO_INIT);
237 /* disable parity error check in DEU (erroneous? test vect.) */
238 setbits32(priv->reg_deu + TALITOS_EUICR, TALITOS1_DEUICR_KPE);
239 } else {
240 setbits32(priv->reg + TALITOS_IMR, TALITOS2_IMR_INIT);
241 setbits32(priv->reg + TALITOS_IMR_LO, TALITOS2_IMR_LO_INIT);
242 }
Kim Phillips9c4a7962008-06-23 19:50:15 +0800243
Kim Phillipsfe5720e2008-10-12 20:33:14 +0800244 /* disable integrity check error interrupts (use writeback instead) */
245 if (priv->features & TALITOS_FTR_HW_AUTH_CHECK)
LEROY Christophe5fa7fa12015-04-17 16:32:11 +0200246 setbits32(priv->reg_mdeu + TALITOS_EUICR_LO,
Kim Phillipsfe5720e2008-10-12 20:33:14 +0800247 TALITOS_MDEUICR_LO_ICE);
248
Kim Phillips9c4a7962008-06-23 19:50:15 +0800249 return 0;
250}
251
252/**
253 * talitos_submit - submits a descriptor to the device for processing
254 * @dev: the SEC device to be used
Kim Phillips5228f0f2011-07-15 11:21:38 +0800255 * @ch: the SEC device channel to be used
Kim Phillips9c4a7962008-06-23 19:50:15 +0800256 * @desc: the descriptor to be processed by the device
257 * @callback: whom to call when processing is complete
258 * @context: a handle for use by caller (optional)
259 *
260 * desc must contain valid dma-mapped (bus physical) address pointers.
261 * callback must check err and feedback in descriptor header
262 * for device processing status.
263 */
Horia Geanta865d5062012-07-03 19:16:52 +0300264int talitos_submit(struct device *dev, int ch, struct talitos_desc *desc,
265 void (*callback)(struct device *dev,
266 struct talitos_desc *desc,
267 void *context, int error),
268 void *context)
Kim Phillips9c4a7962008-06-23 19:50:15 +0800269{
270 struct talitos_private *priv = dev_get_drvdata(dev);
271 struct talitos_request *request;
Kim Phillips5228f0f2011-07-15 11:21:38 +0800272 unsigned long flags;
Kim Phillips9c4a7962008-06-23 19:50:15 +0800273 int head;
LEROY Christophe7d607c6a2015-04-17 16:32:09 +0200274 bool is_sec1 = has_ftr_sec1(priv);
Kim Phillips9c4a7962008-06-23 19:50:15 +0800275
Kim Phillips4b9926282009-08-13 11:50:38 +1000276 spin_lock_irqsave(&priv->chan[ch].head_lock, flags);
Kim Phillips9c4a7962008-06-23 19:50:15 +0800277
Kim Phillips4b9926282009-08-13 11:50:38 +1000278 if (!atomic_inc_not_zero(&priv->chan[ch].submit_count)) {
Kim Phillipsec6644d2008-07-17 20:16:40 +0800279 /* h/w fifo is full */
Kim Phillips4b9926282009-08-13 11:50:38 +1000280 spin_unlock_irqrestore(&priv->chan[ch].head_lock, flags);
Kim Phillips9c4a7962008-06-23 19:50:15 +0800281 return -EAGAIN;
282 }
283
Kim Phillips4b9926282009-08-13 11:50:38 +1000284 head = priv->chan[ch].head;
285 request = &priv->chan[ch].fifo[head];
Kim Phillipsec6644d2008-07-17 20:16:40 +0800286
Kim Phillips9c4a7962008-06-23 19:50:15 +0800287 /* map descriptor and save caller data */
LEROY Christophe7d607c6a2015-04-17 16:32:09 +0200288 if (is_sec1) {
289 desc->hdr1 = desc->hdr;
290 desc->next_desc = 0;
291 request->dma_desc = dma_map_single(dev, &desc->hdr1,
292 TALITOS_DESC_SIZE,
293 DMA_BIDIRECTIONAL);
294 } else {
295 request->dma_desc = dma_map_single(dev, desc,
296 TALITOS_DESC_SIZE,
297 DMA_BIDIRECTIONAL);
298 }
Kim Phillips9c4a7962008-06-23 19:50:15 +0800299 request->callback = callback;
300 request->context = context;
301
302 /* increment fifo head */
Kim Phillips4b9926282009-08-13 11:50:38 +1000303 priv->chan[ch].head = (priv->chan[ch].head + 1) & (priv->fifo_len - 1);
Kim Phillips9c4a7962008-06-23 19:50:15 +0800304
305 smp_wmb();
306 request->desc = desc;
307
308 /* GO! */
309 wmb();
Kim Phillipsad42d5f2011-11-21 16:13:27 +0800310 out_be32(priv->chan[ch].reg + TALITOS_FF,
311 upper_32_bits(request->dma_desc));
312 out_be32(priv->chan[ch].reg + TALITOS_FF_LO,
Kim Phillipsa7524472010-09-23 15:56:38 +0800313 lower_32_bits(request->dma_desc));
Kim Phillips9c4a7962008-06-23 19:50:15 +0800314
Kim Phillips4b9926282009-08-13 11:50:38 +1000315 spin_unlock_irqrestore(&priv->chan[ch].head_lock, flags);
Kim Phillips9c4a7962008-06-23 19:50:15 +0800316
317 return -EINPROGRESS;
318}
Horia Geanta865d5062012-07-03 19:16:52 +0300319EXPORT_SYMBOL(talitos_submit);
Kim Phillips9c4a7962008-06-23 19:50:15 +0800320
321/*
322 * process what was done, notify callback of error if not
323 */
324static void flush_channel(struct device *dev, int ch, int error, int reset_ch)
325{
326 struct talitos_private *priv = dev_get_drvdata(dev);
327 struct talitos_request *request, saved_req;
328 unsigned long flags;
329 int tail, status;
LEROY Christophe7d607c6a2015-04-17 16:32:09 +0200330 bool is_sec1 = has_ftr_sec1(priv);
Kim Phillips9c4a7962008-06-23 19:50:15 +0800331
Kim Phillips4b9926282009-08-13 11:50:38 +1000332 spin_lock_irqsave(&priv->chan[ch].tail_lock, flags);
Kim Phillips9c4a7962008-06-23 19:50:15 +0800333
Kim Phillips4b9926282009-08-13 11:50:38 +1000334 tail = priv->chan[ch].tail;
335 while (priv->chan[ch].fifo[tail].desc) {
LEROY Christophe7d607c6a2015-04-17 16:32:09 +0200336 __be32 hdr;
337
Kim Phillips4b9926282009-08-13 11:50:38 +1000338 request = &priv->chan[ch].fifo[tail];
Kim Phillips9c4a7962008-06-23 19:50:15 +0800339
340 /* descriptors with their done bits set don't get the error */
341 rmb();
LEROY Christophe7d607c6a2015-04-17 16:32:09 +0200342 hdr = is_sec1 ? request->desc->hdr1 : request->desc->hdr;
343
344 if ((hdr & DESC_HDR_DONE) == DESC_HDR_DONE)
Kim Phillips9c4a7962008-06-23 19:50:15 +0800345 status = 0;
Lee Nipperca38a812008-12-20 17:09:25 +1100346 else
Kim Phillips9c4a7962008-06-23 19:50:15 +0800347 if (!error)
348 break;
349 else
350 status = error;
351
352 dma_unmap_single(dev, request->dma_desc,
LEROY Christophe7d607c6a2015-04-17 16:32:09 +0200353 TALITOS_DESC_SIZE,
Kim Phillipse938e462009-03-29 15:53:23 +0800354 DMA_BIDIRECTIONAL);
Kim Phillips9c4a7962008-06-23 19:50:15 +0800355
356 /* copy entries so we can call callback outside lock */
357 saved_req.desc = request->desc;
358 saved_req.callback = request->callback;
359 saved_req.context = request->context;
360
361 /* release request entry in fifo */
362 smp_wmb();
363 request->desc = NULL;
364
365 /* increment fifo tail */
Kim Phillips4b9926282009-08-13 11:50:38 +1000366 priv->chan[ch].tail = (tail + 1) & (priv->fifo_len - 1);
Kim Phillips9c4a7962008-06-23 19:50:15 +0800367
Kim Phillips4b9926282009-08-13 11:50:38 +1000368 spin_unlock_irqrestore(&priv->chan[ch].tail_lock, flags);
Kim Phillipsec6644d2008-07-17 20:16:40 +0800369
Kim Phillips4b9926282009-08-13 11:50:38 +1000370 atomic_dec(&priv->chan[ch].submit_count);
Kim Phillipsec6644d2008-07-17 20:16:40 +0800371
Kim Phillips9c4a7962008-06-23 19:50:15 +0800372 saved_req.callback(dev, saved_req.desc, saved_req.context,
373 status);
374 /* channel may resume processing in single desc error case */
375 if (error && !reset_ch && status == error)
376 return;
Kim Phillips4b9926282009-08-13 11:50:38 +1000377 spin_lock_irqsave(&priv->chan[ch].tail_lock, flags);
378 tail = priv->chan[ch].tail;
Kim Phillips9c4a7962008-06-23 19:50:15 +0800379 }
380
Kim Phillips4b9926282009-08-13 11:50:38 +1000381 spin_unlock_irqrestore(&priv->chan[ch].tail_lock, flags);
Kim Phillips9c4a7962008-06-23 19:50:15 +0800382}
383
384/*
385 * process completed requests for channels that have done status
386 */
LEROY Christophedd3c0982015-04-17 16:32:13 +0200387#define DEF_TALITOS1_DONE(name, ch_done_mask) \
388static void talitos1_done_##name(unsigned long data) \
389{ \
390 struct device *dev = (struct device *)data; \
391 struct talitos_private *priv = dev_get_drvdata(dev); \
392 unsigned long flags; \
393 \
394 if (ch_done_mask & 0x10000000) \
395 flush_channel(dev, 0, 0, 0); \
396 if (priv->num_channels == 1) \
397 goto out; \
398 if (ch_done_mask & 0x40000000) \
399 flush_channel(dev, 1, 0, 0); \
400 if (ch_done_mask & 0x00010000) \
401 flush_channel(dev, 2, 0, 0); \
402 if (ch_done_mask & 0x00040000) \
403 flush_channel(dev, 3, 0, 0); \
404 \
405out: \
406 /* At this point, all completed channels have been processed */ \
407 /* Unmask done interrupts for channels completed later on. */ \
408 spin_lock_irqsave(&priv->reg_lock, flags); \
409 clrbits32(priv->reg + TALITOS_IMR, ch_done_mask); \
410 clrbits32(priv->reg + TALITOS_IMR_LO, TALITOS1_IMR_LO_INIT); \
411 spin_unlock_irqrestore(&priv->reg_lock, flags); \
412}
413
414DEF_TALITOS1_DONE(4ch, TALITOS1_ISR_4CHDONE)
415
416#define DEF_TALITOS2_DONE(name, ch_done_mask) \
417static void talitos2_done_##name(unsigned long data) \
Kim Phillipsc3e337f2011-11-21 16:13:27 +0800418{ \
419 struct device *dev = (struct device *)data; \
420 struct talitos_private *priv = dev_get_drvdata(dev); \
Horia Geanta511d63c2012-03-30 17:49:53 +0300421 unsigned long flags; \
Kim Phillipsc3e337f2011-11-21 16:13:27 +0800422 \
423 if (ch_done_mask & 1) \
424 flush_channel(dev, 0, 0, 0); \
425 if (priv->num_channels == 1) \
426 goto out; \
427 if (ch_done_mask & (1 << 2)) \
428 flush_channel(dev, 1, 0, 0); \
429 if (ch_done_mask & (1 << 4)) \
430 flush_channel(dev, 2, 0, 0); \
431 if (ch_done_mask & (1 << 6)) \
432 flush_channel(dev, 3, 0, 0); \
433 \
434out: \
435 /* At this point, all completed channels have been processed */ \
436 /* Unmask done interrupts for channels completed later on. */ \
Horia Geanta511d63c2012-03-30 17:49:53 +0300437 spin_lock_irqsave(&priv->reg_lock, flags); \
Kim Phillipsc3e337f2011-11-21 16:13:27 +0800438 setbits32(priv->reg + TALITOS_IMR, ch_done_mask); \
LEROY Christophedd3c0982015-04-17 16:32:13 +0200439 setbits32(priv->reg + TALITOS_IMR_LO, TALITOS2_IMR_LO_INIT); \
Horia Geanta511d63c2012-03-30 17:49:53 +0300440 spin_unlock_irqrestore(&priv->reg_lock, flags); \
Kim Phillips9c4a7962008-06-23 19:50:15 +0800441}
LEROY Christophedd3c0982015-04-17 16:32:13 +0200442
443DEF_TALITOS2_DONE(4ch, TALITOS2_ISR_4CHDONE)
444DEF_TALITOS2_DONE(ch0_2, TALITOS2_ISR_CH_0_2_DONE)
445DEF_TALITOS2_DONE(ch1_3, TALITOS2_ISR_CH_1_3_DONE)
Kim Phillips9c4a7962008-06-23 19:50:15 +0800446
447/*
448 * locate current (offending) descriptor
449 */
Kim Phillips3e721ae2011-10-21 15:20:28 +0200450static u32 current_desc_hdr(struct device *dev, int ch)
Kim Phillips9c4a7962008-06-23 19:50:15 +0800451{
452 struct talitos_private *priv = dev_get_drvdata(dev);
Horia Geantab62ffd82013-11-13 12:20:37 +0200453 int tail, iter;
Kim Phillips9c4a7962008-06-23 19:50:15 +0800454 dma_addr_t cur_desc;
455
Horia Geantab62ffd82013-11-13 12:20:37 +0200456 cur_desc = ((u64)in_be32(priv->chan[ch].reg + TALITOS_CDPR)) << 32;
457 cur_desc |= in_be32(priv->chan[ch].reg + TALITOS_CDPR_LO);
Kim Phillips9c4a7962008-06-23 19:50:15 +0800458
Horia Geantab62ffd82013-11-13 12:20:37 +0200459 if (!cur_desc) {
460 dev_err(dev, "CDPR is NULL, giving up search for offending descriptor\n");
461 return 0;
462 }
463
464 tail = priv->chan[ch].tail;
465
466 iter = tail;
467 while (priv->chan[ch].fifo[iter].dma_desc != cur_desc) {
468 iter = (iter + 1) & (priv->fifo_len - 1);
469 if (iter == tail) {
Kim Phillips9c4a7962008-06-23 19:50:15 +0800470 dev_err(dev, "couldn't locate current descriptor\n");
Kim Phillips3e721ae2011-10-21 15:20:28 +0200471 return 0;
Kim Phillips9c4a7962008-06-23 19:50:15 +0800472 }
473 }
474
Horia Geantab62ffd82013-11-13 12:20:37 +0200475 return priv->chan[ch].fifo[iter].desc->hdr;
Kim Phillips9c4a7962008-06-23 19:50:15 +0800476}
477
478/*
479 * user diagnostics; report root cause of error based on execution unit status
480 */
Kim Phillips3e721ae2011-10-21 15:20:28 +0200481static void report_eu_error(struct device *dev, int ch, u32 desc_hdr)
Kim Phillips9c4a7962008-06-23 19:50:15 +0800482{
483 struct talitos_private *priv = dev_get_drvdata(dev);
484 int i;
485
Kim Phillips3e721ae2011-10-21 15:20:28 +0200486 if (!desc_hdr)
Kim Phillipsad42d5f2011-11-21 16:13:27 +0800487 desc_hdr = in_be32(priv->chan[ch].reg + TALITOS_DESCBUF);
Kim Phillips3e721ae2011-10-21 15:20:28 +0200488
489 switch (desc_hdr & DESC_HDR_SEL0_MASK) {
Kim Phillips9c4a7962008-06-23 19:50:15 +0800490 case DESC_HDR_SEL0_AFEU:
491 dev_err(dev, "AFEUISR 0x%08x_%08x\n",
LEROY Christophe5fa7fa12015-04-17 16:32:11 +0200492 in_be32(priv->reg_afeu + TALITOS_EUISR),
493 in_be32(priv->reg_afeu + TALITOS_EUISR_LO));
Kim Phillips9c4a7962008-06-23 19:50:15 +0800494 break;
495 case DESC_HDR_SEL0_DEU:
496 dev_err(dev, "DEUISR 0x%08x_%08x\n",
LEROY Christophe5fa7fa12015-04-17 16:32:11 +0200497 in_be32(priv->reg_deu + TALITOS_EUISR),
498 in_be32(priv->reg_deu + TALITOS_EUISR_LO));
Kim Phillips9c4a7962008-06-23 19:50:15 +0800499 break;
500 case DESC_HDR_SEL0_MDEUA:
501 case DESC_HDR_SEL0_MDEUB:
502 dev_err(dev, "MDEUISR 0x%08x_%08x\n",
LEROY Christophe5fa7fa12015-04-17 16:32:11 +0200503 in_be32(priv->reg_mdeu + TALITOS_EUISR),
504 in_be32(priv->reg_mdeu + TALITOS_EUISR_LO));
Kim Phillips9c4a7962008-06-23 19:50:15 +0800505 break;
506 case DESC_HDR_SEL0_RNG:
507 dev_err(dev, "RNGUISR 0x%08x_%08x\n",
LEROY Christophe5fa7fa12015-04-17 16:32:11 +0200508 in_be32(priv->reg_rngu + TALITOS_ISR),
509 in_be32(priv->reg_rngu + TALITOS_ISR_LO));
Kim Phillips9c4a7962008-06-23 19:50:15 +0800510 break;
511 case DESC_HDR_SEL0_PKEU:
512 dev_err(dev, "PKEUISR 0x%08x_%08x\n",
LEROY Christophe5fa7fa12015-04-17 16:32:11 +0200513 in_be32(priv->reg_pkeu + TALITOS_EUISR),
514 in_be32(priv->reg_pkeu + TALITOS_EUISR_LO));
Kim Phillips9c4a7962008-06-23 19:50:15 +0800515 break;
516 case DESC_HDR_SEL0_AESU:
517 dev_err(dev, "AESUISR 0x%08x_%08x\n",
LEROY Christophe5fa7fa12015-04-17 16:32:11 +0200518 in_be32(priv->reg_aesu + TALITOS_EUISR),
519 in_be32(priv->reg_aesu + TALITOS_EUISR_LO));
Kim Phillips9c4a7962008-06-23 19:50:15 +0800520 break;
521 case DESC_HDR_SEL0_CRCU:
522 dev_err(dev, "CRCUISR 0x%08x_%08x\n",
LEROY Christophe5fa7fa12015-04-17 16:32:11 +0200523 in_be32(priv->reg_crcu + TALITOS_EUISR),
524 in_be32(priv->reg_crcu + TALITOS_EUISR_LO));
Kim Phillips9c4a7962008-06-23 19:50:15 +0800525 break;
526 case DESC_HDR_SEL0_KEU:
527 dev_err(dev, "KEUISR 0x%08x_%08x\n",
LEROY Christophe5fa7fa12015-04-17 16:32:11 +0200528 in_be32(priv->reg_pkeu + TALITOS_EUISR),
529 in_be32(priv->reg_pkeu + TALITOS_EUISR_LO));
Kim Phillips9c4a7962008-06-23 19:50:15 +0800530 break;
531 }
532
Kim Phillips3e721ae2011-10-21 15:20:28 +0200533 switch (desc_hdr & DESC_HDR_SEL1_MASK) {
Kim Phillips9c4a7962008-06-23 19:50:15 +0800534 case DESC_HDR_SEL1_MDEUA:
535 case DESC_HDR_SEL1_MDEUB:
536 dev_err(dev, "MDEUISR 0x%08x_%08x\n",
LEROY Christophe5fa7fa12015-04-17 16:32:11 +0200537 in_be32(priv->reg_mdeu + TALITOS_EUISR),
538 in_be32(priv->reg_mdeu + TALITOS_EUISR_LO));
Kim Phillips9c4a7962008-06-23 19:50:15 +0800539 break;
540 case DESC_HDR_SEL1_CRCU:
541 dev_err(dev, "CRCUISR 0x%08x_%08x\n",
LEROY Christophe5fa7fa12015-04-17 16:32:11 +0200542 in_be32(priv->reg_crcu + TALITOS_EUISR),
543 in_be32(priv->reg_crcu + TALITOS_EUISR_LO));
Kim Phillips9c4a7962008-06-23 19:50:15 +0800544 break;
545 }
546
547 for (i = 0; i < 8; i++)
548 dev_err(dev, "DESCBUF 0x%08x_%08x\n",
Kim Phillipsad42d5f2011-11-21 16:13:27 +0800549 in_be32(priv->chan[ch].reg + TALITOS_DESCBUF + 8*i),
550 in_be32(priv->chan[ch].reg + TALITOS_DESCBUF_LO + 8*i));
Kim Phillips9c4a7962008-06-23 19:50:15 +0800551}
552
553/*
554 * recover from error interrupts
555 */
Kim Phillips5e718a02011-12-12 14:59:12 -0600556static void talitos_error(struct device *dev, u32 isr, u32 isr_lo)
Kim Phillips9c4a7962008-06-23 19:50:15 +0800557{
Kim Phillips9c4a7962008-06-23 19:50:15 +0800558 struct talitos_private *priv = dev_get_drvdata(dev);
559 unsigned int timeout = TALITOS_TIMEOUT;
LEROY Christophedd3c0982015-04-17 16:32:13 +0200560 int ch, error, reset_dev = 0;
Horia Geant?42e8b0d2015-05-11 20:04:56 +0300561 u32 v_lo;
LEROY Christophedd3c0982015-04-17 16:32:13 +0200562 bool is_sec1 = has_ftr_sec1(priv);
563 int reset_ch = is_sec1 ? 1 : 0; /* only SEC2 supports continuation */
Kim Phillips9c4a7962008-06-23 19:50:15 +0800564
565 for (ch = 0; ch < priv->num_channels; ch++) {
566 /* skip channels without errors */
LEROY Christophedd3c0982015-04-17 16:32:13 +0200567 if (is_sec1) {
568 /* bits 29, 31, 17, 19 */
569 if (!(isr & (1 << (29 + (ch & 1) * 2 - (ch & 2) * 6))))
570 continue;
571 } else {
572 if (!(isr & (1 << (ch * 2 + 1))))
573 continue;
574 }
Kim Phillips9c4a7962008-06-23 19:50:15 +0800575
576 error = -EINVAL;
577
Kim Phillipsad42d5f2011-11-21 16:13:27 +0800578 v_lo = in_be32(priv->chan[ch].reg + TALITOS_CCPSR_LO);
Kim Phillips9c4a7962008-06-23 19:50:15 +0800579
580 if (v_lo & TALITOS_CCPSR_LO_DOF) {
581 dev_err(dev, "double fetch fifo overflow error\n");
582 error = -EAGAIN;
583 reset_ch = 1;
584 }
585 if (v_lo & TALITOS_CCPSR_LO_SOF) {
586 /* h/w dropped descriptor */
587 dev_err(dev, "single fetch fifo overflow error\n");
588 error = -EAGAIN;
589 }
590 if (v_lo & TALITOS_CCPSR_LO_MDTE)
591 dev_err(dev, "master data transfer error\n");
592 if (v_lo & TALITOS_CCPSR_LO_SGDLZ)
LEROY Christophedd3c0982015-04-17 16:32:13 +0200593 dev_err(dev, is_sec1 ? "pointeur not complete error\n"
594 : "s/g data length zero error\n");
Kim Phillips9c4a7962008-06-23 19:50:15 +0800595 if (v_lo & TALITOS_CCPSR_LO_FPZ)
LEROY Christophedd3c0982015-04-17 16:32:13 +0200596 dev_err(dev, is_sec1 ? "parity error\n"
597 : "fetch pointer zero error\n");
Kim Phillips9c4a7962008-06-23 19:50:15 +0800598 if (v_lo & TALITOS_CCPSR_LO_IDH)
599 dev_err(dev, "illegal descriptor header error\n");
600 if (v_lo & TALITOS_CCPSR_LO_IEU)
LEROY Christophedd3c0982015-04-17 16:32:13 +0200601 dev_err(dev, is_sec1 ? "static assignment error\n"
602 : "invalid exec unit error\n");
Kim Phillips9c4a7962008-06-23 19:50:15 +0800603 if (v_lo & TALITOS_CCPSR_LO_EU)
Kim Phillips3e721ae2011-10-21 15:20:28 +0200604 report_eu_error(dev, ch, current_desc_hdr(dev, ch));
LEROY Christophedd3c0982015-04-17 16:32:13 +0200605 if (!is_sec1) {
606 if (v_lo & TALITOS_CCPSR_LO_GB)
607 dev_err(dev, "gather boundary error\n");
608 if (v_lo & TALITOS_CCPSR_LO_GRL)
609 dev_err(dev, "gather return/length error\n");
610 if (v_lo & TALITOS_CCPSR_LO_SB)
611 dev_err(dev, "scatter boundary error\n");
612 if (v_lo & TALITOS_CCPSR_LO_SRL)
613 dev_err(dev, "scatter return/length error\n");
614 }
Kim Phillips9c4a7962008-06-23 19:50:15 +0800615
616 flush_channel(dev, ch, error, reset_ch);
617
618 if (reset_ch) {
619 reset_channel(dev, ch);
620 } else {
Kim Phillipsad42d5f2011-11-21 16:13:27 +0800621 setbits32(priv->chan[ch].reg + TALITOS_CCCR,
LEROY Christophedd3c0982015-04-17 16:32:13 +0200622 TALITOS2_CCCR_CONT);
Kim Phillipsad42d5f2011-11-21 16:13:27 +0800623 setbits32(priv->chan[ch].reg + TALITOS_CCCR_LO, 0);
624 while ((in_be32(priv->chan[ch].reg + TALITOS_CCCR) &
LEROY Christophedd3c0982015-04-17 16:32:13 +0200625 TALITOS2_CCCR_CONT) && --timeout)
Kim Phillips9c4a7962008-06-23 19:50:15 +0800626 cpu_relax();
627 if (timeout == 0) {
628 dev_err(dev, "failed to restart channel %d\n",
629 ch);
630 reset_dev = 1;
631 }
632 }
633 }
LEROY Christophedd3c0982015-04-17 16:32:13 +0200634 if (reset_dev || (is_sec1 && isr & ~TALITOS1_ISR_4CHERR) ||
635 (!is_sec1 && isr & ~TALITOS2_ISR_4CHERR) || isr_lo) {
636 if (is_sec1 && (isr_lo & TALITOS1_ISR_TEA_ERR))
637 dev_err(dev, "TEA error: ISR 0x%08x_%08x\n",
638 isr, isr_lo);
639 else
640 dev_err(dev, "done overflow, internal time out, or "
641 "rngu error: ISR 0x%08x_%08x\n", isr, isr_lo);
Kim Phillips9c4a7962008-06-23 19:50:15 +0800642
643 /* purge request queues */
644 for (ch = 0; ch < priv->num_channels; ch++)
645 flush_channel(dev, ch, -EIO, 1);
646
647 /* reset and reinitialize the device */
648 init_device(dev);
649 }
650}
651
LEROY Christophedd3c0982015-04-17 16:32:13 +0200652#define DEF_TALITOS1_INTERRUPT(name, ch_done_mask, ch_err_mask, tlet) \
653static irqreturn_t talitos1_interrupt_##name(int irq, void *data) \
654{ \
655 struct device *dev = data; \
656 struct talitos_private *priv = dev_get_drvdata(dev); \
657 u32 isr, isr_lo; \
658 unsigned long flags; \
659 \
660 spin_lock_irqsave(&priv->reg_lock, flags); \
661 isr = in_be32(priv->reg + TALITOS_ISR); \
662 isr_lo = in_be32(priv->reg + TALITOS_ISR_LO); \
663 /* Acknowledge interrupt */ \
664 out_be32(priv->reg + TALITOS_ICR, isr & (ch_done_mask | ch_err_mask)); \
665 out_be32(priv->reg + TALITOS_ICR_LO, isr_lo); \
666 \
667 if (unlikely(isr & ch_err_mask || isr_lo & TALITOS1_IMR_LO_INIT)) { \
668 spin_unlock_irqrestore(&priv->reg_lock, flags); \
669 talitos_error(dev, isr & ch_err_mask, isr_lo); \
670 } \
671 else { \
672 if (likely(isr & ch_done_mask)) { \
673 /* mask further done interrupts. */ \
674 setbits32(priv->reg + TALITOS_IMR, ch_done_mask); \
675 /* done_task will unmask done interrupts at exit */ \
676 tasklet_schedule(&priv->done_task[tlet]); \
677 } \
678 spin_unlock_irqrestore(&priv->reg_lock, flags); \
679 } \
680 \
681 return (isr & (ch_done_mask | ch_err_mask) || isr_lo) ? IRQ_HANDLED : \
682 IRQ_NONE; \
683}
684
685DEF_TALITOS1_INTERRUPT(4ch, TALITOS1_ISR_4CHDONE, TALITOS1_ISR_4CHERR, 0)
686
687#define DEF_TALITOS2_INTERRUPT(name, ch_done_mask, ch_err_mask, tlet) \
688static irqreturn_t talitos2_interrupt_##name(int irq, void *data) \
Kim Phillipsc3e337f2011-11-21 16:13:27 +0800689{ \
690 struct device *dev = data; \
691 struct talitos_private *priv = dev_get_drvdata(dev); \
692 u32 isr, isr_lo; \
Horia Geanta511d63c2012-03-30 17:49:53 +0300693 unsigned long flags; \
Kim Phillipsc3e337f2011-11-21 16:13:27 +0800694 \
Horia Geanta511d63c2012-03-30 17:49:53 +0300695 spin_lock_irqsave(&priv->reg_lock, flags); \
Kim Phillipsc3e337f2011-11-21 16:13:27 +0800696 isr = in_be32(priv->reg + TALITOS_ISR); \
697 isr_lo = in_be32(priv->reg + TALITOS_ISR_LO); \
698 /* Acknowledge interrupt */ \
699 out_be32(priv->reg + TALITOS_ICR, isr & (ch_done_mask | ch_err_mask)); \
700 out_be32(priv->reg + TALITOS_ICR_LO, isr_lo); \
701 \
Horia Geanta511d63c2012-03-30 17:49:53 +0300702 if (unlikely(isr & ch_err_mask || isr_lo)) { \
703 spin_unlock_irqrestore(&priv->reg_lock, flags); \
704 talitos_error(dev, isr & ch_err_mask, isr_lo); \
705 } \
706 else { \
Kim Phillipsc3e337f2011-11-21 16:13:27 +0800707 if (likely(isr & ch_done_mask)) { \
708 /* mask further done interrupts. */ \
709 clrbits32(priv->reg + TALITOS_IMR, ch_done_mask); \
710 /* done_task will unmask done interrupts at exit */ \
711 tasklet_schedule(&priv->done_task[tlet]); \
712 } \
Horia Geanta511d63c2012-03-30 17:49:53 +0300713 spin_unlock_irqrestore(&priv->reg_lock, flags); \
714 } \
Kim Phillipsc3e337f2011-11-21 16:13:27 +0800715 \
716 return (isr & (ch_done_mask | ch_err_mask) || isr_lo) ? IRQ_HANDLED : \
717 IRQ_NONE; \
Kim Phillips9c4a7962008-06-23 19:50:15 +0800718}
LEROY Christophedd3c0982015-04-17 16:32:13 +0200719
720DEF_TALITOS2_INTERRUPT(4ch, TALITOS2_ISR_4CHDONE, TALITOS2_ISR_4CHERR, 0)
721DEF_TALITOS2_INTERRUPT(ch0_2, TALITOS2_ISR_CH_0_2_DONE, TALITOS2_ISR_CH_0_2_ERR,
722 0)
723DEF_TALITOS2_INTERRUPT(ch1_3, TALITOS2_ISR_CH_1_3_DONE, TALITOS2_ISR_CH_1_3_ERR,
724 1)
Kim Phillips9c4a7962008-06-23 19:50:15 +0800725
726/*
727 * hwrng
728 */
729static int talitos_rng_data_present(struct hwrng *rng, int wait)
730{
731 struct device *dev = (struct device *)rng->priv;
732 struct talitos_private *priv = dev_get_drvdata(dev);
733 u32 ofl;
734 int i;
735
736 for (i = 0; i < 20; i++) {
LEROY Christophe5fa7fa12015-04-17 16:32:11 +0200737 ofl = in_be32(priv->reg_rngu + TALITOS_EUSR_LO) &
Kim Phillips9c4a7962008-06-23 19:50:15 +0800738 TALITOS_RNGUSR_LO_OFL;
739 if (ofl || !wait)
740 break;
741 udelay(10);
742 }
743
744 return !!ofl;
745}
746
747static int talitos_rng_data_read(struct hwrng *rng, u32 *data)
748{
749 struct device *dev = (struct device *)rng->priv;
750 struct talitos_private *priv = dev_get_drvdata(dev);
751
752 /* rng fifo requires 64-bit accesses */
LEROY Christophe5fa7fa12015-04-17 16:32:11 +0200753 *data = in_be32(priv->reg_rngu + TALITOS_EU_FIFO);
754 *data = in_be32(priv->reg_rngu + TALITOS_EU_FIFO_LO);
Kim Phillips9c4a7962008-06-23 19:50:15 +0800755
756 return sizeof(u32);
757}
758
759static int talitos_rng_init(struct hwrng *rng)
760{
761 struct device *dev = (struct device *)rng->priv;
762 struct talitos_private *priv = dev_get_drvdata(dev);
763 unsigned int timeout = TALITOS_TIMEOUT;
764
LEROY Christophe5fa7fa12015-04-17 16:32:11 +0200765 setbits32(priv->reg_rngu + TALITOS_EURCR_LO, TALITOS_RNGURCR_LO_SR);
766 while (!(in_be32(priv->reg_rngu + TALITOS_EUSR_LO)
767 & TALITOS_RNGUSR_LO_RD)
Kim Phillips9c4a7962008-06-23 19:50:15 +0800768 && --timeout)
769 cpu_relax();
770 if (timeout == 0) {
771 dev_err(dev, "failed to reset rng hw\n");
772 return -ENODEV;
773 }
774
775 /* start generating */
LEROY Christophe5fa7fa12015-04-17 16:32:11 +0200776 setbits32(priv->reg_rngu + TALITOS_EUDSR_LO, 0);
Kim Phillips9c4a7962008-06-23 19:50:15 +0800777
778 return 0;
779}
780
781static int talitos_register_rng(struct device *dev)
782{
783 struct talitos_private *priv = dev_get_drvdata(dev);
Aaron Sierra35a3bb32015-08-05 16:52:08 -0500784 int err;
Kim Phillips9c4a7962008-06-23 19:50:15 +0800785
786 priv->rng.name = dev_driver_string(dev),
787 priv->rng.init = talitos_rng_init,
788 priv->rng.data_present = talitos_rng_data_present,
789 priv->rng.data_read = talitos_rng_data_read,
790 priv->rng.priv = (unsigned long)dev;
791
Aaron Sierra35a3bb32015-08-05 16:52:08 -0500792 err = hwrng_register(&priv->rng);
793 if (!err)
794 priv->rng_registered = true;
795
796 return err;
Kim Phillips9c4a7962008-06-23 19:50:15 +0800797}
798
799static void talitos_unregister_rng(struct device *dev)
800{
801 struct talitos_private *priv = dev_get_drvdata(dev);
802
Aaron Sierra35a3bb32015-08-05 16:52:08 -0500803 if (!priv->rng_registered)
804 return;
805
Kim Phillips9c4a7962008-06-23 19:50:15 +0800806 hwrng_unregister(&priv->rng);
Aaron Sierra35a3bb32015-08-05 16:52:08 -0500807 priv->rng_registered = false;
Kim Phillips9c4a7962008-06-23 19:50:15 +0800808}
809
810/*
811 * crypto alg
812 */
813#define TALITOS_CRA_PRIORITY 3000
LEROY Christophe7405c8d2016-06-06 13:20:46 +0200814/*
815 * Defines a priority for doing AEAD with descriptors type
816 * HMAC_SNOOP_NO_AFEA (HSNA) instead of type IPSEC_ESP
817 */
818#define TALITOS_CRA_PRIORITY_AEAD_HSNA (TALITOS_CRA_PRIORITY - 1)
Martin Hicks2ff2cc72017-05-02 09:38:35 -0400819#define TALITOS_MAX_KEY_SIZE (AES_MAX_KEY_SIZE + SHA512_BLOCK_SIZE)
Lee Nipper3952f172008-07-10 18:29:18 +0800820#define TALITOS_MAX_IV_LENGTH 16 /* max of AES_BLOCK_SIZE, DES3_EDE_BLOCK_SIZE */
Lee Nipper70bcaca2008-07-03 19:08:46 +0800821
Kim Phillips9c4a7962008-06-23 19:50:15 +0800822struct talitos_ctx {
823 struct device *dev;
Kim Phillips5228f0f2011-07-15 11:21:38 +0800824 int ch;
Kim Phillips9c4a7962008-06-23 19:50:15 +0800825 __be32 desc_hdr_template;
826 u8 key[TALITOS_MAX_KEY_SIZE];
Lee Nipper70bcaca2008-07-03 19:08:46 +0800827 u8 iv[TALITOS_MAX_IV_LENGTH];
Kim Phillips9c4a7962008-06-23 19:50:15 +0800828 unsigned int keylen;
829 unsigned int enckeylen;
830 unsigned int authkeylen;
Kim Phillips9c4a7962008-06-23 19:50:15 +0800831};
832
Lee Nipper497f2e62010-05-19 19:20:36 +1000833#define HASH_MAX_BLOCK_SIZE SHA512_BLOCK_SIZE
834#define TALITOS_MDEU_MAX_CONTEXT_SIZE TALITOS_MDEU_CONTEXT_SIZE_SHA384_SHA512
835
836struct talitos_ahash_req_ctx {
Kim Phillips60f208d2010-05-19 19:21:53 +1000837 u32 hw_context[TALITOS_MDEU_MAX_CONTEXT_SIZE / sizeof(u32)];
Lee Nipper497f2e62010-05-19 19:20:36 +1000838 unsigned int hw_context_size;
839 u8 buf[HASH_MAX_BLOCK_SIZE];
840 u8 bufnext[HASH_MAX_BLOCK_SIZE];
Kim Phillips60f208d2010-05-19 19:21:53 +1000841 unsigned int swinit;
Lee Nipper497f2e62010-05-19 19:20:36 +1000842 unsigned int first;
843 unsigned int last;
844 unsigned int to_hash_later;
Horia Geant?42e8b0d2015-05-11 20:04:56 +0300845 unsigned int nbuf;
Lee Nipper497f2e62010-05-19 19:20:36 +1000846 struct scatterlist bufsl[2];
847 struct scatterlist *psrc;
848};
849
Horia Geant?3639ca82016-04-21 19:24:55 +0300850struct talitos_export_state {
851 u32 hw_context[TALITOS_MDEU_MAX_CONTEXT_SIZE / sizeof(u32)];
852 u8 buf[HASH_MAX_BLOCK_SIZE];
853 unsigned int swinit;
854 unsigned int first;
855 unsigned int last;
856 unsigned int to_hash_later;
857 unsigned int nbuf;
858};
859
Lee Nipper56af8cd2009-03-29 15:50:50 +0800860static int aead_setkey(struct crypto_aead *authenc,
861 const u8 *key, unsigned int keylen)
Kim Phillips9c4a7962008-06-23 19:50:15 +0800862{
863 struct talitos_ctx *ctx = crypto_aead_ctx(authenc);
Mathias Krausec306a982013-10-15 13:49:34 +0200864 struct crypto_authenc_keys keys;
Kim Phillips9c4a7962008-06-23 19:50:15 +0800865
Mathias Krausec306a982013-10-15 13:49:34 +0200866 if (crypto_authenc_extractkeys(&keys, key, keylen) != 0)
Kim Phillips9c4a7962008-06-23 19:50:15 +0800867 goto badkey;
868
Mathias Krausec306a982013-10-15 13:49:34 +0200869 if (keys.authkeylen + keys.enckeylen > TALITOS_MAX_KEY_SIZE)
Kim Phillips9c4a7962008-06-23 19:50:15 +0800870 goto badkey;
871
Mathias Krausec306a982013-10-15 13:49:34 +0200872 memcpy(ctx->key, keys.authkey, keys.authkeylen);
873 memcpy(&ctx->key[keys.authkeylen], keys.enckey, keys.enckeylen);
Kim Phillips9c4a7962008-06-23 19:50:15 +0800874
Mathias Krausec306a982013-10-15 13:49:34 +0200875 ctx->keylen = keys.authkeylen + keys.enckeylen;
876 ctx->enckeylen = keys.enckeylen;
877 ctx->authkeylen = keys.authkeylen;
Kim Phillips9c4a7962008-06-23 19:50:15 +0800878
879 return 0;
880
881badkey:
882 crypto_aead_set_flags(authenc, CRYPTO_TFM_RES_BAD_KEY_LEN);
883 return -EINVAL;
884}
885
886/*
Lee Nipper56af8cd2009-03-29 15:50:50 +0800887 * talitos_edesc - s/w-extended descriptor
Kim Phillips9c4a7962008-06-23 19:50:15 +0800888 * @src_nents: number of segments in input scatterlist
889 * @dst_nents: number of segments in output scatterlist
Herbert Xuaeb4c132015-07-30 17:53:22 +0800890 * @icv_ool: whether ICV is out-of-line
Horia Geanta79fd31d2012-08-02 17:16:40 +0300891 * @iv_dma: dma address of iv for checking continuity and link table
Kim Phillips9c4a7962008-06-23 19:50:15 +0800892 * @dma_len: length of dma mapped link_tbl space
LEROY Christophe6f65f6a2015-04-17 16:32:15 +0200893 * @dma_link_tbl: bus physical address of link_tbl/buf
Kim Phillips9c4a7962008-06-23 19:50:15 +0800894 * @desc: h/w descriptor
LEROY Christophe6f65f6a2015-04-17 16:32:15 +0200895 * @link_tbl: input and output h/w link tables (if {src,dst}_nents > 1) (SEC2)
896 * @buf: input and output buffeur (if {src,dst}_nents > 1) (SEC1)
Kim Phillips9c4a7962008-06-23 19:50:15 +0800897 *
898 * if decrypting (with authcheck), or either one of src_nents or dst_nents
899 * is greater than 1, an integrity check value is concatenated to the end
900 * of link_tbl data
901 */
Lee Nipper56af8cd2009-03-29 15:50:50 +0800902struct talitos_edesc {
Kim Phillips9c4a7962008-06-23 19:50:15 +0800903 int src_nents;
904 int dst_nents;
Herbert Xuaeb4c132015-07-30 17:53:22 +0800905 bool icv_ool;
Horia Geanta79fd31d2012-08-02 17:16:40 +0300906 dma_addr_t iv_dma;
Kim Phillips9c4a7962008-06-23 19:50:15 +0800907 int dma_len;
908 dma_addr_t dma_link_tbl;
909 struct talitos_desc desc;
LEROY Christophe6f65f6a2015-04-17 16:32:15 +0200910 union {
911 struct talitos_ptr link_tbl[0];
912 u8 buf[0];
913 };
Kim Phillips9c4a7962008-06-23 19:50:15 +0800914};
915
Lee Nipper4de9d0b2009-03-29 15:52:32 +0800916static void talitos_sg_unmap(struct device *dev,
917 struct talitos_edesc *edesc,
918 struct scatterlist *src,
LEROY Christophe6a1e8d12016-06-06 13:20:38 +0200919 struct scatterlist *dst,
920 unsigned int len, unsigned int offset)
LEROY Christophe246a87c2016-06-06 13:20:36 +0200921{
922 struct talitos_private *priv = dev_get_drvdata(dev);
923 bool is_sec1 = has_ftr_sec1(priv);
LEROY Christophe6a1e8d12016-06-06 13:20:38 +0200924 unsigned int src_nents = edesc->src_nents ? : 1;
925 unsigned int dst_nents = edesc->dst_nents ? : 1;
LEROY Christophe246a87c2016-06-06 13:20:36 +0200926
LEROY Christophe6a1e8d12016-06-06 13:20:38 +0200927 if (is_sec1 && dst && dst_nents > 1) {
928 dma_sync_single_for_device(dev, edesc->dma_link_tbl + offset,
929 len, DMA_FROM_DEVICE);
930 sg_pcopy_from_buffer(dst, dst_nents, edesc->buf + offset, len,
931 offset);
932 }
933 if (src != dst) {
934 if (src_nents == 1 || !is_sec1)
935 dma_unmap_sg(dev, src, src_nents, DMA_TO_DEVICE);
936
937 if (dst && (dst_nents == 1 || !is_sec1))
938 dma_unmap_sg(dev, dst, dst_nents, DMA_FROM_DEVICE);
939 } else if (src_nents == 1 || !is_sec1) {
940 dma_unmap_sg(dev, src, src_nents, DMA_BIDIRECTIONAL);
LEROY Christophe246a87c2016-06-06 13:20:36 +0200941 }
942}
943
Kim Phillips9c4a7962008-06-23 19:50:15 +0800944static void ipsec_esp_unmap(struct device *dev,
Lee Nipper56af8cd2009-03-29 15:50:50 +0800945 struct talitos_edesc *edesc,
Kim Phillips9c4a7962008-06-23 19:50:15 +0800946 struct aead_request *areq)
947{
LEROY Christophe549bd8b2016-06-06 13:20:40 +0200948 struct crypto_aead *aead = crypto_aead_reqtfm(areq);
949 struct talitos_ctx *ctx = crypto_aead_ctx(aead);
950 unsigned int ivsize = crypto_aead_ivsize(aead);
951
952 if (edesc->desc.hdr & DESC_HDR_TYPE_IPSEC_ESP)
953 unmap_single_talitos_ptr(dev, &edesc->desc.ptr[6],
954 DMA_FROM_DEVICE);
Kim Phillips9c4a7962008-06-23 19:50:15 +0800955 unmap_single_talitos_ptr(dev, &edesc->desc.ptr[3], DMA_TO_DEVICE);
956 unmap_single_talitos_ptr(dev, &edesc->desc.ptr[2], DMA_TO_DEVICE);
957 unmap_single_talitos_ptr(dev, &edesc->desc.ptr[0], DMA_TO_DEVICE);
958
LEROY Christophe6a1e8d12016-06-06 13:20:38 +0200959 talitos_sg_unmap(dev, edesc, areq->src, areq->dst, areq->cryptlen,
960 areq->assoclen);
Kim Phillips9c4a7962008-06-23 19:50:15 +0800961
962 if (edesc->dma_len)
963 dma_unmap_single(dev, edesc->dma_link_tbl, edesc->dma_len,
964 DMA_BIDIRECTIONAL);
LEROY Christophe549bd8b2016-06-06 13:20:40 +0200965
966 if (!(edesc->desc.hdr & DESC_HDR_TYPE_IPSEC_ESP)) {
967 unsigned int dst_nents = edesc->dst_nents ? : 1;
968
969 sg_pcopy_to_buffer(areq->dst, dst_nents, ctx->iv, ivsize,
970 areq->assoclen + areq->cryptlen - ivsize);
971 }
Kim Phillips9c4a7962008-06-23 19:50:15 +0800972}
973
974/*
975 * ipsec_esp descriptor callbacks
976 */
977static void ipsec_esp_encrypt_done(struct device *dev,
978 struct talitos_desc *desc, void *context,
979 int err)
980{
LEROY Christophe549bd8b2016-06-06 13:20:40 +0200981 struct talitos_private *priv = dev_get_drvdata(dev);
982 bool is_sec1 = has_ftr_sec1(priv);
Kim Phillips9c4a7962008-06-23 19:50:15 +0800983 struct aead_request *areq = context;
Kim Phillips9c4a7962008-06-23 19:50:15 +0800984 struct crypto_aead *authenc = crypto_aead_reqtfm(areq);
Herbert Xuaeb4c132015-07-30 17:53:22 +0800985 unsigned int authsize = crypto_aead_authsize(authenc);
Kim Phillips19bbbc62009-03-29 15:53:59 +0800986 struct talitos_edesc *edesc;
Kim Phillips9c4a7962008-06-23 19:50:15 +0800987 struct scatterlist *sg;
988 void *icvdata;
989
Kim Phillips19bbbc62009-03-29 15:53:59 +0800990 edesc = container_of(desc, struct talitos_edesc, desc);
991
Kim Phillips9c4a7962008-06-23 19:50:15 +0800992 ipsec_esp_unmap(dev, edesc, areq);
993
994 /* copy the generated ICV to dst */
Herbert Xuaeb4c132015-07-30 17:53:22 +0800995 if (edesc->icv_ool) {
LEROY Christophe549bd8b2016-06-06 13:20:40 +0200996 if (is_sec1)
997 icvdata = edesc->buf + areq->assoclen + areq->cryptlen;
998 else
999 icvdata = &edesc->link_tbl[edesc->src_nents +
1000 edesc->dst_nents + 2];
Kim Phillips9c4a7962008-06-23 19:50:15 +08001001 sg = sg_last(areq->dst, edesc->dst_nents);
Herbert Xuaeb4c132015-07-30 17:53:22 +08001002 memcpy((char *)sg_virt(sg) + sg->length - authsize,
1003 icvdata, authsize);
Kim Phillips9c4a7962008-06-23 19:50:15 +08001004 }
1005
1006 kfree(edesc);
1007
1008 aead_request_complete(areq, err);
1009}
1010
Kim Phillipsfe5720e2008-10-12 20:33:14 +08001011static void ipsec_esp_decrypt_swauth_done(struct device *dev,
Kim Phillipse938e462009-03-29 15:53:23 +08001012 struct talitos_desc *desc,
1013 void *context, int err)
Kim Phillips9c4a7962008-06-23 19:50:15 +08001014{
1015 struct aead_request *req = context;
Kim Phillips9c4a7962008-06-23 19:50:15 +08001016 struct crypto_aead *authenc = crypto_aead_reqtfm(req);
Herbert Xuaeb4c132015-07-30 17:53:22 +08001017 unsigned int authsize = crypto_aead_authsize(authenc);
Kim Phillips19bbbc62009-03-29 15:53:59 +08001018 struct talitos_edesc *edesc;
Kim Phillips9c4a7962008-06-23 19:50:15 +08001019 struct scatterlist *sg;
Herbert Xuaeb4c132015-07-30 17:53:22 +08001020 char *oicv, *icv;
LEROY Christophe549bd8b2016-06-06 13:20:40 +02001021 struct talitos_private *priv = dev_get_drvdata(dev);
1022 bool is_sec1 = has_ftr_sec1(priv);
Kim Phillips9c4a7962008-06-23 19:50:15 +08001023
Kim Phillips19bbbc62009-03-29 15:53:59 +08001024 edesc = container_of(desc, struct talitos_edesc, desc);
1025
Kim Phillips9c4a7962008-06-23 19:50:15 +08001026 ipsec_esp_unmap(dev, edesc, req);
1027
1028 if (!err) {
1029 /* auth check */
Kim Phillips9c4a7962008-06-23 19:50:15 +08001030 sg = sg_last(req->dst, edesc->dst_nents ? : 1);
Herbert Xuaeb4c132015-07-30 17:53:22 +08001031 icv = (char *)sg_virt(sg) + sg->length - authsize;
1032
1033 if (edesc->dma_len) {
LEROY Christophe549bd8b2016-06-06 13:20:40 +02001034 if (is_sec1)
1035 oicv = (char *)&edesc->dma_link_tbl +
1036 req->assoclen + req->cryptlen;
1037 else
1038 oicv = (char *)
1039 &edesc->link_tbl[edesc->src_nents +
Herbert Xuaeb4c132015-07-30 17:53:22 +08001040 edesc->dst_nents + 2];
1041 if (edesc->icv_ool)
1042 icv = oicv + authsize;
1043 } else
1044 oicv = (char *)&edesc->link_tbl[0];
1045
David Gstir79960942015-11-15 17:14:42 +01001046 err = crypto_memneq(oicv, icv, authsize) ? -EBADMSG : 0;
Kim Phillips9c4a7962008-06-23 19:50:15 +08001047 }
1048
1049 kfree(edesc);
1050
1051 aead_request_complete(req, err);
1052}
1053
Kim Phillipsfe5720e2008-10-12 20:33:14 +08001054static void ipsec_esp_decrypt_hwauth_done(struct device *dev,
Kim Phillipse938e462009-03-29 15:53:23 +08001055 struct talitos_desc *desc,
1056 void *context, int err)
Kim Phillipsfe5720e2008-10-12 20:33:14 +08001057{
1058 struct aead_request *req = context;
Kim Phillips19bbbc62009-03-29 15:53:59 +08001059 struct talitos_edesc *edesc;
1060
1061 edesc = container_of(desc, struct talitos_edesc, desc);
Kim Phillipsfe5720e2008-10-12 20:33:14 +08001062
1063 ipsec_esp_unmap(dev, edesc, req);
1064
1065 /* check ICV auth status */
Kim Phillipse938e462009-03-29 15:53:23 +08001066 if (!err && ((desc->hdr_lo & DESC_HDR_LO_ICCR1_MASK) !=
1067 DESC_HDR_LO_ICCR1_PASS))
1068 err = -EBADMSG;
Kim Phillipsfe5720e2008-10-12 20:33:14 +08001069
1070 kfree(edesc);
1071
1072 aead_request_complete(req, err);
1073}
1074
Kim Phillips9c4a7962008-06-23 19:50:15 +08001075/*
1076 * convert scatterlist to SEC h/w link table format
1077 * stop at cryptlen bytes
1078 */
Herbert Xuaeb4c132015-07-30 17:53:22 +08001079static int sg_to_link_tbl_offset(struct scatterlist *sg, int sg_count,
1080 unsigned int offset, int cryptlen,
1081 struct talitos_ptr *link_tbl_ptr)
Kim Phillips9c4a7962008-06-23 19:50:15 +08001082{
Lee Nipper70bcaca2008-07-03 19:08:46 +08001083 int n_sg = sg_count;
Herbert Xuaeb4c132015-07-30 17:53:22 +08001084 int count = 0;
Lee Nipper70bcaca2008-07-03 19:08:46 +08001085
Herbert Xuaeb4c132015-07-30 17:53:22 +08001086 while (cryptlen && sg && n_sg--) {
1087 unsigned int len = sg_dma_len(sg);
1088
1089 if (offset >= len) {
1090 offset -= len;
1091 goto next;
1092 }
1093
1094 len -= offset;
1095
1096 if (len > cryptlen)
1097 len = cryptlen;
1098
1099 to_talitos_ptr(link_tbl_ptr + count,
1100 sg_dma_address(sg) + offset, 0);
LEROY Christopheb096b542016-06-06 13:20:34 +02001101 to_talitos_ptr_len(link_tbl_ptr + count, len, 0);
1102 to_talitos_ptr_ext_set(link_tbl_ptr + count, 0, 0);
Herbert Xuaeb4c132015-07-30 17:53:22 +08001103 count++;
1104 cryptlen -= len;
1105 offset = 0;
1106
1107next:
Cristian Stoica5be4d4c2015-01-20 10:06:16 +02001108 sg = sg_next(sg);
Kim Phillips9c4a7962008-06-23 19:50:15 +08001109 }
1110
Kim Phillips9c4a7962008-06-23 19:50:15 +08001111 /* tag end of link table */
Herbert Xuaeb4c132015-07-30 17:53:22 +08001112 if (count > 0)
LEROY Christopheb096b542016-06-06 13:20:34 +02001113 to_talitos_ptr_ext_set(link_tbl_ptr + count - 1,
1114 DESC_PTR_LNKTBL_RETURN, 0);
Lee Nipper70bcaca2008-07-03 19:08:46 +08001115
Herbert Xuaeb4c132015-07-30 17:53:22 +08001116 return count;
1117}
1118
LEROY Christophe23fb8f72018-03-22 10:57:01 +01001119static int talitos_sg_map_ext(struct device *dev, struct scatterlist *src,
1120 unsigned int len, struct talitos_edesc *edesc,
1121 struct talitos_ptr *ptr, int sg_count,
1122 unsigned int offset, int tbl_off, int elen)
LEROY Christophe246a87c2016-06-06 13:20:36 +02001123{
LEROY Christophe246a87c2016-06-06 13:20:36 +02001124 struct talitos_private *priv = dev_get_drvdata(dev);
1125 bool is_sec1 = has_ftr_sec1(priv);
1126
LEROY Christophec4cef782018-01-26 17:09:59 +01001127 if (!src) {
1128 *ptr = zero_entry;
1129 return 1;
1130 }
1131
LEROY Christophe246a87c2016-06-06 13:20:36 +02001132 to_talitos_ptr_len(ptr, len, is_sec1);
LEROY Christophe23fb8f72018-03-22 10:57:01 +01001133 to_talitos_ptr_ext_set(ptr, elen, is_sec1);
LEROY Christophe246a87c2016-06-06 13:20:36 +02001134
LEROY Christophe6a1e8d12016-06-06 13:20:38 +02001135 if (sg_count == 1) {
1136 to_talitos_ptr(ptr, sg_dma_address(src) + offset, is_sec1);
1137 return sg_count;
LEROY Christophe246a87c2016-06-06 13:20:36 +02001138 }
LEROY Christophe6a1e8d12016-06-06 13:20:38 +02001139 if (is_sec1) {
1140 to_talitos_ptr(ptr, edesc->dma_link_tbl + offset, is_sec1);
1141 return sg_count;
1142 }
LEROY Christophe23fb8f72018-03-22 10:57:01 +01001143 sg_count = sg_to_link_tbl_offset(src, sg_count, offset, len + elen,
LEROY Christophe6a1e8d12016-06-06 13:20:38 +02001144 &edesc->link_tbl[tbl_off]);
1145 if (sg_count == 1) {
1146 /* Only one segment now, so no link tbl needed*/
1147 copy_talitos_ptr(ptr, &edesc->link_tbl[tbl_off], is_sec1);
1148 return sg_count;
1149 }
1150 to_talitos_ptr(ptr, edesc->dma_link_tbl +
1151 tbl_off * sizeof(struct talitos_ptr), is_sec1);
1152 to_talitos_ptr_ext_or(ptr, DESC_PTR_LNKTBL_JUMP, is_sec1);
1153
LEROY Christophe246a87c2016-06-06 13:20:36 +02001154 return sg_count;
1155}
1156
LEROY Christophe23fb8f72018-03-22 10:57:01 +01001157static int talitos_sg_map(struct device *dev, struct scatterlist *src,
1158 unsigned int len, struct talitos_edesc *edesc,
1159 struct talitos_ptr *ptr, int sg_count,
1160 unsigned int offset, int tbl_off)
1161{
1162 return talitos_sg_map_ext(dev, src, len, edesc, ptr, sg_count, offset,
1163 tbl_off, 0);
1164}
1165
Kim Phillips9c4a7962008-06-23 19:50:15 +08001166/*
1167 * fill in and submit ipsec_esp descriptor
1168 */
Lee Nipper56af8cd2009-03-29 15:50:50 +08001169static int ipsec_esp(struct talitos_edesc *edesc, struct aead_request *areq,
Herbert Xuaeb4c132015-07-30 17:53:22 +08001170 void (*callback)(struct device *dev,
1171 struct talitos_desc *desc,
1172 void *context, int error))
Kim Phillips9c4a7962008-06-23 19:50:15 +08001173{
1174 struct crypto_aead *aead = crypto_aead_reqtfm(areq);
Herbert Xuaeb4c132015-07-30 17:53:22 +08001175 unsigned int authsize = crypto_aead_authsize(aead);
Kim Phillips9c4a7962008-06-23 19:50:15 +08001176 struct talitos_ctx *ctx = crypto_aead_ctx(aead);
1177 struct device *dev = ctx->dev;
1178 struct talitos_desc *desc = &edesc->desc;
1179 unsigned int cryptlen = areq->cryptlen;
Kim Phillipse41256f2009-08-13 11:49:06 +10001180 unsigned int ivsize = crypto_aead_ivsize(aead);
Herbert Xuaeb4c132015-07-30 17:53:22 +08001181 int tbl_off = 0;
Kim Phillipsfa86a262008-07-17 20:20:06 +08001182 int sg_count, ret;
LEROY Christophe23fb8f72018-03-22 10:57:01 +01001183 int elen = 0;
LEROY Christophe549bd8b2016-06-06 13:20:40 +02001184 bool sync_needed = false;
1185 struct talitos_private *priv = dev_get_drvdata(dev);
1186 bool is_sec1 = has_ftr_sec1(priv);
Kim Phillips9c4a7962008-06-23 19:50:15 +08001187
1188 /* hmac key */
1189 map_single_talitos_ptr(dev, &desc->ptr[0], ctx->authkeylen, &ctx->key,
LEROY Christophea2b35aa2015-04-17 16:31:57 +02001190 DMA_TO_DEVICE);
Horia Geanta79fd31d2012-08-02 17:16:40 +03001191
LEROY Christophe549bd8b2016-06-06 13:20:40 +02001192 sg_count = edesc->src_nents ?: 1;
1193 if (is_sec1 && sg_count > 1)
1194 sg_copy_to_buffer(areq->src, sg_count, edesc->buf,
1195 areq->assoclen + cryptlen);
1196 else
1197 sg_count = dma_map_sg(dev, areq->src, sg_count,
1198 (areq->src == areq->dst) ?
1199 DMA_BIDIRECTIONAL : DMA_TO_DEVICE);
1200
Kim Phillips9c4a7962008-06-23 19:50:15 +08001201 /* hmac data */
LEROY Christophe549bd8b2016-06-06 13:20:40 +02001202 ret = talitos_sg_map(dev, areq->src, areq->assoclen, edesc,
1203 &desc->ptr[1], sg_count, 0, tbl_off);
Horia Geanta79fd31d2012-08-02 17:16:40 +03001204
LEROY Christophe549bd8b2016-06-06 13:20:40 +02001205 if (ret > 1) {
Horia Geant?340ff602016-04-19 20:33:48 +03001206 tbl_off += ret;
LEROY Christophe549bd8b2016-06-06 13:20:40 +02001207 sync_needed = true;
Horia Geanta79fd31d2012-08-02 17:16:40 +03001208 }
1209
Kim Phillips9c4a7962008-06-23 19:50:15 +08001210 /* cipher iv */
LEROY Christophe549bd8b2016-06-06 13:20:40 +02001211 if (desc->hdr & DESC_HDR_TYPE_IPSEC_ESP) {
1212 to_talitos_ptr(&desc->ptr[2], edesc->iv_dma, is_sec1);
1213 to_talitos_ptr_len(&desc->ptr[2], ivsize, is_sec1);
1214 to_talitos_ptr_ext_set(&desc->ptr[2], 0, is_sec1);
1215 } else {
1216 to_talitos_ptr(&desc->ptr[3], edesc->iv_dma, is_sec1);
1217 to_talitos_ptr_len(&desc->ptr[3], ivsize, is_sec1);
1218 to_talitos_ptr_ext_set(&desc->ptr[3], 0, is_sec1);
1219 }
Kim Phillips9c4a7962008-06-23 19:50:15 +08001220
1221 /* cipher key */
LEROY Christophe549bd8b2016-06-06 13:20:40 +02001222 if (desc->hdr & DESC_HDR_TYPE_IPSEC_ESP)
1223 map_single_talitos_ptr(dev, &desc->ptr[3], ctx->enckeylen,
1224 (char *)&ctx->key + ctx->authkeylen,
1225 DMA_TO_DEVICE);
1226 else
1227 map_single_talitos_ptr(dev, &desc->ptr[2], ctx->enckeylen,
1228 (char *)&ctx->key + ctx->authkeylen,
1229 DMA_TO_DEVICE);
Kim Phillips9c4a7962008-06-23 19:50:15 +08001230
1231 /*
1232 * cipher in
1233 * map and adjust cipher len to aead request cryptlen.
1234 * extent is bytes of HMAC postpended to ciphertext,
1235 * typically 12 for ipsec
1236 */
LEROY Christophe23fb8f72018-03-22 10:57:01 +01001237 if ((desc->hdr & DESC_HDR_TYPE_IPSEC_ESP) &&
1238 (desc->hdr & DESC_HDR_MODE1_MDEU_CICV))
1239 elen = authsize;
Kim Phillips9c4a7962008-06-23 19:50:15 +08001240
LEROY Christophe23fb8f72018-03-22 10:57:01 +01001241 ret = talitos_sg_map_ext(dev, areq->src, cryptlen, edesc, &desc->ptr[4],
1242 sg_count, areq->assoclen, tbl_off, elen);
LEROY Christophe549bd8b2016-06-06 13:20:40 +02001243
LEROY Christophebde66672017-10-06 15:04:33 +02001244 if (ret > 1) {
1245 tbl_off += ret;
LEROY Christophe549bd8b2016-06-06 13:20:40 +02001246 sync_needed = true;
Horia Geant?340ff602016-04-19 20:33:48 +03001247 }
Kim Phillips9c4a7962008-06-23 19:50:15 +08001248
1249 /* cipher out */
LEROY Christophe549bd8b2016-06-06 13:20:40 +02001250 if (areq->src != areq->dst) {
1251 sg_count = edesc->dst_nents ? : 1;
1252 if (!is_sec1 || sg_count == 1)
1253 dma_map_sg(dev, areq->dst, sg_count, DMA_FROM_DEVICE);
1254 }
Kim Phillips9c4a7962008-06-23 19:50:15 +08001255
LEROY Christophe5272b0e2017-10-06 15:04:35 +02001256 ret = talitos_sg_map(dev, areq->dst, cryptlen, edesc, &desc->ptr[5],
1257 sg_count, areq->assoclen, tbl_off);
Kim Phillips9c4a7962008-06-23 19:50:15 +08001258
LEROY Christophe549bd8b2016-06-06 13:20:40 +02001259 if (desc->hdr & DESC_HDR_TYPE_IPSEC_ESP)
1260 to_talitos_ptr_ext_or(&desc->ptr[5], authsize, is_sec1);
Herbert Xuaeb4c132015-07-30 17:53:22 +08001261
LEROY Christophe5272b0e2017-10-06 15:04:35 +02001262 /* ICV data */
1263 if (ret > 1) {
1264 tbl_off += ret;
Herbert Xuaeb4c132015-07-30 17:53:22 +08001265 edesc->icv_ool = true;
LEROY Christophe549bd8b2016-06-06 13:20:40 +02001266 sync_needed = true;
1267
1268 if (desc->hdr & DESC_HDR_TYPE_IPSEC_ESP) {
1269 struct talitos_ptr *tbl_ptr = &edesc->link_tbl[tbl_off];
1270 int offset = (edesc->src_nents + edesc->dst_nents + 2) *
1271 sizeof(struct talitos_ptr) + authsize;
1272
1273 /* Add an entry to the link table for ICV data */
LEROY Christophe5272b0e2017-10-06 15:04:35 +02001274 to_talitos_ptr_ext_set(tbl_ptr - 1, 0, is_sec1);
LEROY Christophe549bd8b2016-06-06 13:20:40 +02001275 to_talitos_ptr_ext_set(tbl_ptr, DESC_PTR_LNKTBL_RETURN,
1276 is_sec1);
1277 to_talitos_ptr_len(tbl_ptr, authsize, is_sec1);
1278
1279 /* icv data follows link tables */
1280 to_talitos_ptr(tbl_ptr, edesc->dma_link_tbl + offset,
1281 is_sec1);
LEROY Christophe5272b0e2017-10-06 15:04:35 +02001282 } else {
1283 dma_addr_t addr = edesc->dma_link_tbl;
1284
1285 if (is_sec1)
1286 addr += areq->assoclen + cryptlen;
1287 else
1288 addr += sizeof(struct talitos_ptr) * tbl_off;
1289
1290 to_talitos_ptr(&desc->ptr[6], addr, is_sec1);
1291 to_talitos_ptr_len(&desc->ptr[6], authsize, is_sec1);
1292 }
1293 } else if (!(desc->hdr & DESC_HDR_TYPE_IPSEC_ESP)) {
1294 ret = talitos_sg_map(dev, areq->dst, authsize, edesc,
1295 &desc->ptr[6], sg_count, areq->assoclen +
1296 cryptlen,
1297 tbl_off);
1298 if (ret > 1) {
1299 tbl_off += ret;
1300 edesc->icv_ool = true;
1301 sync_needed = true;
1302 } else {
1303 edesc->icv_ool = false;
LEROY Christophe549bd8b2016-06-06 13:20:40 +02001304 }
Horia Geant?340ff602016-04-19 20:33:48 +03001305 } else {
LEROY Christophe549bd8b2016-06-06 13:20:40 +02001306 edesc->icv_ool = false;
1307 }
1308
Kim Phillips9c4a7962008-06-23 19:50:15 +08001309 /* iv out */
LEROY Christophe549bd8b2016-06-06 13:20:40 +02001310 if (desc->hdr & DESC_HDR_TYPE_IPSEC_ESP)
1311 map_single_talitos_ptr(dev, &desc->ptr[6], ivsize, ctx->iv,
1312 DMA_FROM_DEVICE);
1313
1314 if (sync_needed)
1315 dma_sync_single_for_device(dev, edesc->dma_link_tbl,
1316 edesc->dma_len,
1317 DMA_BIDIRECTIONAL);
Kim Phillips9c4a7962008-06-23 19:50:15 +08001318
Kim Phillips5228f0f2011-07-15 11:21:38 +08001319 ret = talitos_submit(dev, ctx->ch, desc, callback, areq);
Kim Phillipsfa86a262008-07-17 20:20:06 +08001320 if (ret != -EINPROGRESS) {
1321 ipsec_esp_unmap(dev, edesc, areq);
1322 kfree(edesc);
1323 }
1324 return ret;
Kim Phillips9c4a7962008-06-23 19:50:15 +08001325}
1326
Kim Phillips9c4a7962008-06-23 19:50:15 +08001327/*
Lee Nipper56af8cd2009-03-29 15:50:50 +08001328 * allocate and map the extended descriptor
Kim Phillips9c4a7962008-06-23 19:50:15 +08001329 */
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001330static struct talitos_edesc *talitos_edesc_alloc(struct device *dev,
1331 struct scatterlist *src,
1332 struct scatterlist *dst,
Horia Geanta79fd31d2012-08-02 17:16:40 +03001333 u8 *iv,
1334 unsigned int assoclen,
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001335 unsigned int cryptlen,
1336 unsigned int authsize,
Horia Geanta79fd31d2012-08-02 17:16:40 +03001337 unsigned int ivsize,
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001338 int icv_stashing,
Horia Geanta62293a32013-11-28 15:11:17 +02001339 u32 cryptoflags,
1340 bool encrypt)
Kim Phillips9c4a7962008-06-23 19:50:15 +08001341{
Lee Nipper56af8cd2009-03-29 15:50:50 +08001342 struct talitos_edesc *edesc;
LEROY Christophe6a1e8d12016-06-06 13:20:38 +02001343 int src_nents, dst_nents, alloc_len, dma_len, src_len, dst_len;
Horia Geanta79fd31d2012-08-02 17:16:40 +03001344 dma_addr_t iv_dma = 0;
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001345 gfp_t flags = cryptoflags & CRYPTO_TFM_REQ_MAY_SLEEP ? GFP_KERNEL :
Kim Phillips586725f2008-07-17 20:19:18 +08001346 GFP_ATOMIC;
LEROY Christophe6f65f6a2015-04-17 16:32:15 +02001347 struct talitos_private *priv = dev_get_drvdata(dev);
1348 bool is_sec1 = has_ftr_sec1(priv);
1349 int max_len = is_sec1 ? TALITOS1_MAX_DATA_LEN : TALITOS2_MAX_DATA_LEN;
LABBE Corentin8e409fe2015-11-04 21:13:34 +01001350 void *err;
Kim Phillips9c4a7962008-06-23 19:50:15 +08001351
LEROY Christophe6f65f6a2015-04-17 16:32:15 +02001352 if (cryptlen + authsize > max_len) {
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001353 dev_err(dev, "length exceeds h/w max limit\n");
Kim Phillips9c4a7962008-06-23 19:50:15 +08001354 return ERR_PTR(-EINVAL);
1355 }
1356
Horia Geanta935e99a2013-11-19 14:57:49 +02001357 if (ivsize)
Horia Geanta79fd31d2012-08-02 17:16:40 +03001358 iv_dma = dma_map_single(dev, iv, ivsize, DMA_TO_DEVICE);
1359
Horia Geanta62293a32013-11-28 15:11:17 +02001360 if (!dst || dst == src) {
LEROY Christophe6a1e8d12016-06-06 13:20:38 +02001361 src_len = assoclen + cryptlen + authsize;
1362 src_nents = sg_nents_for_len(src, src_len);
LABBE Corentin8e409fe2015-11-04 21:13:34 +01001363 if (src_nents < 0) {
1364 dev_err(dev, "Invalid number of src SG.\n");
1365 err = ERR_PTR(-EINVAL);
1366 goto error_sg;
1367 }
Horia Geanta62293a32013-11-28 15:11:17 +02001368 src_nents = (src_nents == 1) ? 0 : src_nents;
1369 dst_nents = dst ? src_nents : 0;
LEROY Christophe6a1e8d12016-06-06 13:20:38 +02001370 dst_len = 0;
Horia Geanta62293a32013-11-28 15:11:17 +02001371 } else { /* dst && dst != src*/
LEROY Christophe6a1e8d12016-06-06 13:20:38 +02001372 src_len = assoclen + cryptlen + (encrypt ? 0 : authsize);
1373 src_nents = sg_nents_for_len(src, src_len);
LABBE Corentin8e409fe2015-11-04 21:13:34 +01001374 if (src_nents < 0) {
1375 dev_err(dev, "Invalid number of src SG.\n");
1376 err = ERR_PTR(-EINVAL);
1377 goto error_sg;
1378 }
Horia Geanta62293a32013-11-28 15:11:17 +02001379 src_nents = (src_nents == 1) ? 0 : src_nents;
LEROY Christophe6a1e8d12016-06-06 13:20:38 +02001380 dst_len = assoclen + cryptlen + (encrypt ? authsize : 0);
1381 dst_nents = sg_nents_for_len(dst, dst_len);
LABBE Corentin8e409fe2015-11-04 21:13:34 +01001382 if (dst_nents < 0) {
1383 dev_err(dev, "Invalid number of dst SG.\n");
1384 err = ERR_PTR(-EINVAL);
1385 goto error_sg;
1386 }
Horia Geanta62293a32013-11-28 15:11:17 +02001387 dst_nents = (dst_nents == 1) ? 0 : dst_nents;
Kim Phillips9c4a7962008-06-23 19:50:15 +08001388 }
1389
1390 /*
1391 * allocate space for base edesc plus the link tables,
Herbert Xuaeb4c132015-07-30 17:53:22 +08001392 * allowing for two separate entries for AD and generated ICV (+ 2),
1393 * and space for two sets of ICVs (stashed and generated)
Kim Phillips9c4a7962008-06-23 19:50:15 +08001394 */
Lee Nipper56af8cd2009-03-29 15:50:50 +08001395 alloc_len = sizeof(struct talitos_edesc);
Herbert Xuaeb4c132015-07-30 17:53:22 +08001396 if (src_nents || dst_nents) {
LEROY Christophe6f65f6a2015-04-17 16:32:15 +02001397 if (is_sec1)
LEROY Christophe6a1e8d12016-06-06 13:20:38 +02001398 dma_len = (src_nents ? src_len : 0) +
1399 (dst_nents ? dst_len : 0);
LEROY Christophe6f65f6a2015-04-17 16:32:15 +02001400 else
Herbert Xuaeb4c132015-07-30 17:53:22 +08001401 dma_len = (src_nents + dst_nents + 2) *
1402 sizeof(struct talitos_ptr) + authsize * 2;
Kim Phillips9c4a7962008-06-23 19:50:15 +08001403 alloc_len += dma_len;
1404 } else {
1405 dma_len = 0;
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001406 alloc_len += icv_stashing ? authsize : 0;
Kim Phillips9c4a7962008-06-23 19:50:15 +08001407 }
1408
Kim Phillips586725f2008-07-17 20:19:18 +08001409 edesc = kmalloc(alloc_len, GFP_DMA | flags);
Kim Phillips9c4a7962008-06-23 19:50:15 +08001410 if (!edesc) {
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001411 dev_err(dev, "could not allocate edescriptor\n");
LABBE Corentin8e409fe2015-11-04 21:13:34 +01001412 err = ERR_PTR(-ENOMEM);
1413 goto error_sg;
Kim Phillips9c4a7962008-06-23 19:50:15 +08001414 }
1415
1416 edesc->src_nents = src_nents;
1417 edesc->dst_nents = dst_nents;
Horia Geanta79fd31d2012-08-02 17:16:40 +03001418 edesc->iv_dma = iv_dma;
Kim Phillips9c4a7962008-06-23 19:50:15 +08001419 edesc->dma_len = dma_len;
Lee Nipper497f2e62010-05-19 19:20:36 +10001420 if (dma_len)
1421 edesc->dma_link_tbl = dma_map_single(dev, &edesc->link_tbl[0],
1422 edesc->dma_len,
1423 DMA_BIDIRECTIONAL);
Kim Phillips9c4a7962008-06-23 19:50:15 +08001424
1425 return edesc;
LABBE Corentin8e409fe2015-11-04 21:13:34 +01001426error_sg:
1427 if (iv_dma)
1428 dma_unmap_single(dev, iv_dma, ivsize, DMA_TO_DEVICE);
1429 return err;
Kim Phillips9c4a7962008-06-23 19:50:15 +08001430}
1431
Horia Geanta79fd31d2012-08-02 17:16:40 +03001432static struct talitos_edesc *aead_edesc_alloc(struct aead_request *areq, u8 *iv,
Horia Geanta62293a32013-11-28 15:11:17 +02001433 int icv_stashing, bool encrypt)
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001434{
1435 struct crypto_aead *authenc = crypto_aead_reqtfm(areq);
Herbert Xuaeb4c132015-07-30 17:53:22 +08001436 unsigned int authsize = crypto_aead_authsize(authenc);
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001437 struct talitos_ctx *ctx = crypto_aead_ctx(authenc);
Horia Geanta79fd31d2012-08-02 17:16:40 +03001438 unsigned int ivsize = crypto_aead_ivsize(authenc);
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001439
Herbert Xuaeb4c132015-07-30 17:53:22 +08001440 return talitos_edesc_alloc(ctx->dev, areq->src, areq->dst,
Horia Geanta79fd31d2012-08-02 17:16:40 +03001441 iv, areq->assoclen, areq->cryptlen,
Herbert Xuaeb4c132015-07-30 17:53:22 +08001442 authsize, ivsize, icv_stashing,
Horia Geanta62293a32013-11-28 15:11:17 +02001443 areq->base.flags, encrypt);
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001444}
1445
Lee Nipper56af8cd2009-03-29 15:50:50 +08001446static int aead_encrypt(struct aead_request *req)
Kim Phillips9c4a7962008-06-23 19:50:15 +08001447{
1448 struct crypto_aead *authenc = crypto_aead_reqtfm(req);
1449 struct talitos_ctx *ctx = crypto_aead_ctx(authenc);
Lee Nipper56af8cd2009-03-29 15:50:50 +08001450 struct talitos_edesc *edesc;
Kim Phillips9c4a7962008-06-23 19:50:15 +08001451
1452 /* allocate extended descriptor */
Horia Geanta62293a32013-11-28 15:11:17 +02001453 edesc = aead_edesc_alloc(req, req->iv, 0, true);
Kim Phillips9c4a7962008-06-23 19:50:15 +08001454 if (IS_ERR(edesc))
1455 return PTR_ERR(edesc);
1456
1457 /* set encrypt */
Lee Nipper70bcaca2008-07-03 19:08:46 +08001458 edesc->desc.hdr = ctx->desc_hdr_template | DESC_HDR_MODE0_ENCRYPT;
Kim Phillips9c4a7962008-06-23 19:50:15 +08001459
Herbert Xuaeb4c132015-07-30 17:53:22 +08001460 return ipsec_esp(edesc, req, ipsec_esp_encrypt_done);
Kim Phillips9c4a7962008-06-23 19:50:15 +08001461}
1462
Lee Nipper56af8cd2009-03-29 15:50:50 +08001463static int aead_decrypt(struct aead_request *req)
Kim Phillips9c4a7962008-06-23 19:50:15 +08001464{
1465 struct crypto_aead *authenc = crypto_aead_reqtfm(req);
Herbert Xuaeb4c132015-07-30 17:53:22 +08001466 unsigned int authsize = crypto_aead_authsize(authenc);
Kim Phillips9c4a7962008-06-23 19:50:15 +08001467 struct talitos_ctx *ctx = crypto_aead_ctx(authenc);
Kim Phillipsfe5720e2008-10-12 20:33:14 +08001468 struct talitos_private *priv = dev_get_drvdata(ctx->dev);
Lee Nipper56af8cd2009-03-29 15:50:50 +08001469 struct talitos_edesc *edesc;
Kim Phillips9c4a7962008-06-23 19:50:15 +08001470 struct scatterlist *sg;
1471 void *icvdata;
1472
1473 req->cryptlen -= authsize;
1474
1475 /* allocate extended descriptor */
Horia Geanta62293a32013-11-28 15:11:17 +02001476 edesc = aead_edesc_alloc(req, req->iv, 1, false);
Kim Phillips9c4a7962008-06-23 19:50:15 +08001477 if (IS_ERR(edesc))
1478 return PTR_ERR(edesc);
1479
Kim Phillipsfe5720e2008-10-12 20:33:14 +08001480 if ((priv->features & TALITOS_FTR_HW_AUTH_CHECK) &&
Kim Phillipse938e462009-03-29 15:53:23 +08001481 ((!edesc->src_nents && !edesc->dst_nents) ||
1482 priv->features & TALITOS_FTR_SRC_LINK_TBL_LEN_INCLUDES_EXTENT)) {
Kim Phillips9c4a7962008-06-23 19:50:15 +08001483
Kim Phillipsfe5720e2008-10-12 20:33:14 +08001484 /* decrypt and check the ICV */
Kim Phillipse938e462009-03-29 15:53:23 +08001485 edesc->desc.hdr = ctx->desc_hdr_template |
1486 DESC_HDR_DIR_INBOUND |
Kim Phillipsfe5720e2008-10-12 20:33:14 +08001487 DESC_HDR_MODE1_MDEU_CICV;
Kim Phillips9c4a7962008-06-23 19:50:15 +08001488
Kim Phillipsfe5720e2008-10-12 20:33:14 +08001489 /* reset integrity check result bits */
1490 edesc->desc.hdr_lo = 0;
Kim Phillips9c4a7962008-06-23 19:50:15 +08001491
Herbert Xuaeb4c132015-07-30 17:53:22 +08001492 return ipsec_esp(edesc, req, ipsec_esp_decrypt_hwauth_done);
Kim Phillipsfe5720e2008-10-12 20:33:14 +08001493 }
Kim Phillipse938e462009-03-29 15:53:23 +08001494
1495 /* Have to check the ICV with software */
1496 edesc->desc.hdr = ctx->desc_hdr_template | DESC_HDR_DIR_INBOUND;
1497
1498 /* stash incoming ICV for later cmp with ICV generated by the h/w */
1499 if (edesc->dma_len)
Herbert Xuaeb4c132015-07-30 17:53:22 +08001500 icvdata = (char *)&edesc->link_tbl[edesc->src_nents +
1501 edesc->dst_nents + 2];
Kim Phillipse938e462009-03-29 15:53:23 +08001502 else
1503 icvdata = &edesc->link_tbl[0];
1504
1505 sg = sg_last(req->src, edesc->src_nents ? : 1);
1506
Herbert Xuaeb4c132015-07-30 17:53:22 +08001507 memcpy(icvdata, (char *)sg_virt(sg) + sg->length - authsize, authsize);
Kim Phillipse938e462009-03-29 15:53:23 +08001508
Herbert Xuaeb4c132015-07-30 17:53:22 +08001509 return ipsec_esp(edesc, req, ipsec_esp_decrypt_swauth_done);
Kim Phillips9c4a7962008-06-23 19:50:15 +08001510}
1511
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001512static int ablkcipher_setkey(struct crypto_ablkcipher *cipher,
1513 const u8 *key, unsigned int keylen)
1514{
1515 struct talitos_ctx *ctx = crypto_ablkcipher_ctx(cipher);
LEROY Christophe552f74c2017-10-06 15:04:37 +02001516 u32 tmp[DES_EXPKEY_WORDS];
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001517
Martin Hicks2ff2cc72017-05-02 09:38:35 -04001518 if (keylen > TALITOS_MAX_KEY_SIZE) {
1519 crypto_ablkcipher_set_flags(cipher, CRYPTO_TFM_RES_BAD_KEY_LEN);
1520 return -EINVAL;
1521 }
1522
LEROY Christophe552f74c2017-10-06 15:04:37 +02001523 if (unlikely(crypto_ablkcipher_get_flags(cipher) &
1524 CRYPTO_TFM_REQ_WEAK_KEY) &&
1525 !des_ekey(tmp, key)) {
1526 crypto_ablkcipher_set_flags(cipher, CRYPTO_TFM_RES_WEAK_KEY);
1527 return -EINVAL;
1528 }
1529
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001530 memcpy(&ctx->key, key, keylen);
1531 ctx->keylen = keylen;
1532
1533 return 0;
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001534}
1535
1536static void common_nonsnoop_unmap(struct device *dev,
1537 struct talitos_edesc *edesc,
1538 struct ablkcipher_request *areq)
1539{
1540 unmap_single_talitos_ptr(dev, &edesc->desc.ptr[5], DMA_FROM_DEVICE);
LEROY Christophe032d1972015-04-17 16:31:51 +02001541
LEROY Christophe6a1e8d12016-06-06 13:20:38 +02001542 talitos_sg_unmap(dev, edesc, areq->src, areq->dst, areq->nbytes, 0);
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001543 unmap_single_talitos_ptr(dev, &edesc->desc.ptr[2], DMA_TO_DEVICE);
1544 unmap_single_talitos_ptr(dev, &edesc->desc.ptr[1], DMA_TO_DEVICE);
1545
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001546 if (edesc->dma_len)
1547 dma_unmap_single(dev, edesc->dma_link_tbl, edesc->dma_len,
1548 DMA_BIDIRECTIONAL);
1549}
1550
1551static void ablkcipher_done(struct device *dev,
1552 struct talitos_desc *desc, void *context,
1553 int err)
1554{
1555 struct ablkcipher_request *areq = context;
Kim Phillips19bbbc62009-03-29 15:53:59 +08001556 struct talitos_edesc *edesc;
1557
1558 edesc = container_of(desc, struct talitos_edesc, desc);
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001559
1560 common_nonsnoop_unmap(dev, edesc, areq);
1561
1562 kfree(edesc);
1563
1564 areq->base.complete(&areq->base, err);
1565}
1566
1567static int common_nonsnoop(struct talitos_edesc *edesc,
1568 struct ablkcipher_request *areq,
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001569 void (*callback) (struct device *dev,
1570 struct talitos_desc *desc,
1571 void *context, int error))
1572{
1573 struct crypto_ablkcipher *cipher = crypto_ablkcipher_reqtfm(areq);
1574 struct talitos_ctx *ctx = crypto_ablkcipher_ctx(cipher);
1575 struct device *dev = ctx->dev;
1576 struct talitos_desc *desc = &edesc->desc;
1577 unsigned int cryptlen = areq->nbytes;
Horia Geanta79fd31d2012-08-02 17:16:40 +03001578 unsigned int ivsize = crypto_ablkcipher_ivsize(cipher);
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001579 int sg_count, ret;
LEROY Christophe6a1e8d12016-06-06 13:20:38 +02001580 bool sync_needed = false;
LEROY Christophe922f9dc2015-04-17 16:32:07 +02001581 struct talitos_private *priv = dev_get_drvdata(dev);
1582 bool is_sec1 = has_ftr_sec1(priv);
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001583
1584 /* first DWORD empty */
LEROY Christophe2529bc32015-04-17 16:31:49 +02001585 desc->ptr[0] = zero_entry;
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001586
1587 /* cipher iv */
LEROY Christophe922f9dc2015-04-17 16:32:07 +02001588 to_talitos_ptr(&desc->ptr[1], edesc->iv_dma, is_sec1);
1589 to_talitos_ptr_len(&desc->ptr[1], ivsize, is_sec1);
LEROY Christopheb096b542016-06-06 13:20:34 +02001590 to_talitos_ptr_ext_set(&desc->ptr[1], 0, is_sec1);
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001591
1592 /* cipher key */
1593 map_single_talitos_ptr(dev, &desc->ptr[2], ctx->keylen,
LEROY Christophea2b35aa2015-04-17 16:31:57 +02001594 (char *)&ctx->key, DMA_TO_DEVICE);
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001595
LEROY Christophe6a1e8d12016-06-06 13:20:38 +02001596 sg_count = edesc->src_nents ?: 1;
1597 if (is_sec1 && sg_count > 1)
1598 sg_copy_to_buffer(areq->src, sg_count, edesc->buf,
1599 cryptlen);
1600 else
1601 sg_count = dma_map_sg(dev, areq->src, sg_count,
1602 (areq->src == areq->dst) ?
1603 DMA_BIDIRECTIONAL : DMA_TO_DEVICE);
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001604 /*
1605 * cipher in
1606 */
LEROY Christophe6a1e8d12016-06-06 13:20:38 +02001607 sg_count = talitos_sg_map(dev, areq->src, cryptlen, edesc,
1608 &desc->ptr[3], sg_count, 0, 0);
1609 if (sg_count > 1)
1610 sync_needed = true;
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001611
1612 /* cipher out */
LEROY Christophe6a1e8d12016-06-06 13:20:38 +02001613 if (areq->src != areq->dst) {
1614 sg_count = edesc->dst_nents ? : 1;
1615 if (!is_sec1 || sg_count == 1)
1616 dma_map_sg(dev, areq->dst, sg_count, DMA_FROM_DEVICE);
1617 }
1618
1619 ret = talitos_sg_map(dev, areq->dst, cryptlen, edesc, &desc->ptr[4],
1620 sg_count, 0, (edesc->src_nents + 1));
1621 if (ret > 1)
1622 sync_needed = true;
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001623
1624 /* iv out */
LEROY Christophea2b35aa2015-04-17 16:31:57 +02001625 map_single_talitos_ptr(dev, &desc->ptr[5], ivsize, ctx->iv,
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001626 DMA_FROM_DEVICE);
1627
1628 /* last DWORD empty */
LEROY Christophe2529bc32015-04-17 16:31:49 +02001629 desc->ptr[6] = zero_entry;
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001630
LEROY Christophe6a1e8d12016-06-06 13:20:38 +02001631 if (sync_needed)
1632 dma_sync_single_for_device(dev, edesc->dma_link_tbl,
1633 edesc->dma_len, DMA_BIDIRECTIONAL);
1634
Kim Phillips5228f0f2011-07-15 11:21:38 +08001635 ret = talitos_submit(dev, ctx->ch, desc, callback, areq);
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001636 if (ret != -EINPROGRESS) {
1637 common_nonsnoop_unmap(dev, edesc, areq);
1638 kfree(edesc);
1639 }
1640 return ret;
1641}
1642
Kim Phillipse938e462009-03-29 15:53:23 +08001643static struct talitos_edesc *ablkcipher_edesc_alloc(struct ablkcipher_request *
Horia Geanta62293a32013-11-28 15:11:17 +02001644 areq, bool encrypt)
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001645{
1646 struct crypto_ablkcipher *cipher = crypto_ablkcipher_reqtfm(areq);
1647 struct talitos_ctx *ctx = crypto_ablkcipher_ctx(cipher);
Horia Geanta79fd31d2012-08-02 17:16:40 +03001648 unsigned int ivsize = crypto_ablkcipher_ivsize(cipher);
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001649
Herbert Xuaeb4c132015-07-30 17:53:22 +08001650 return talitos_edesc_alloc(ctx->dev, areq->src, areq->dst,
Horia Geanta79fd31d2012-08-02 17:16:40 +03001651 areq->info, 0, areq->nbytes, 0, ivsize, 0,
Horia Geanta62293a32013-11-28 15:11:17 +02001652 areq->base.flags, encrypt);
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001653}
1654
1655static int ablkcipher_encrypt(struct ablkcipher_request *areq)
1656{
1657 struct crypto_ablkcipher *cipher = crypto_ablkcipher_reqtfm(areq);
1658 struct talitos_ctx *ctx = crypto_ablkcipher_ctx(cipher);
1659 struct talitos_edesc *edesc;
1660
1661 /* allocate extended descriptor */
Horia Geanta62293a32013-11-28 15:11:17 +02001662 edesc = ablkcipher_edesc_alloc(areq, true);
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001663 if (IS_ERR(edesc))
1664 return PTR_ERR(edesc);
1665
1666 /* set encrypt */
1667 edesc->desc.hdr = ctx->desc_hdr_template | DESC_HDR_MODE0_ENCRYPT;
1668
Kim Phillipsfebec542011-07-15 11:21:39 +08001669 return common_nonsnoop(edesc, areq, ablkcipher_done);
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001670}
1671
1672static int ablkcipher_decrypt(struct ablkcipher_request *areq)
1673{
1674 struct crypto_ablkcipher *cipher = crypto_ablkcipher_reqtfm(areq);
1675 struct talitos_ctx *ctx = crypto_ablkcipher_ctx(cipher);
1676 struct talitos_edesc *edesc;
1677
1678 /* allocate extended descriptor */
Horia Geanta62293a32013-11-28 15:11:17 +02001679 edesc = ablkcipher_edesc_alloc(areq, false);
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001680 if (IS_ERR(edesc))
1681 return PTR_ERR(edesc);
1682
1683 edesc->desc.hdr = ctx->desc_hdr_template | DESC_HDR_DIR_INBOUND;
1684
Kim Phillipsfebec542011-07-15 11:21:39 +08001685 return common_nonsnoop(edesc, areq, ablkcipher_done);
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001686}
1687
Lee Nipper497f2e62010-05-19 19:20:36 +10001688static void common_nonsnoop_hash_unmap(struct device *dev,
1689 struct talitos_edesc *edesc,
1690 struct ahash_request *areq)
1691{
1692 struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
LEROY Christophe922f9dc2015-04-17 16:32:07 +02001693 struct talitos_private *priv = dev_get_drvdata(dev);
1694 bool is_sec1 = has_ftr_sec1(priv);
Lee Nipper497f2e62010-05-19 19:20:36 +10001695
1696 unmap_single_talitos_ptr(dev, &edesc->desc.ptr[5], DMA_FROM_DEVICE);
1697
LEROY Christophe6a1e8d12016-06-06 13:20:38 +02001698 talitos_sg_unmap(dev, edesc, req_ctx->psrc, NULL, 0, 0);
LEROY Christophe032d1972015-04-17 16:31:51 +02001699
Lee Nipper497f2e62010-05-19 19:20:36 +10001700 /* When using hashctx-in, must unmap it. */
LEROY Christophe922f9dc2015-04-17 16:32:07 +02001701 if (from_talitos_ptr_len(&edesc->desc.ptr[1], is_sec1))
Lee Nipper497f2e62010-05-19 19:20:36 +10001702 unmap_single_talitos_ptr(dev, &edesc->desc.ptr[1],
1703 DMA_TO_DEVICE);
1704
LEROY Christophe922f9dc2015-04-17 16:32:07 +02001705 if (from_talitos_ptr_len(&edesc->desc.ptr[2], is_sec1))
Lee Nipper497f2e62010-05-19 19:20:36 +10001706 unmap_single_talitos_ptr(dev, &edesc->desc.ptr[2],
1707 DMA_TO_DEVICE);
1708
Lee Nipper497f2e62010-05-19 19:20:36 +10001709 if (edesc->dma_len)
1710 dma_unmap_single(dev, edesc->dma_link_tbl, edesc->dma_len,
1711 DMA_BIDIRECTIONAL);
1712
1713}
1714
1715static void ahash_done(struct device *dev,
1716 struct talitos_desc *desc, void *context,
1717 int err)
1718{
1719 struct ahash_request *areq = context;
1720 struct talitos_edesc *edesc =
1721 container_of(desc, struct talitos_edesc, desc);
1722 struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
1723
1724 if (!req_ctx->last && req_ctx->to_hash_later) {
1725 /* Position any partial block for next update/final/finup */
1726 memcpy(req_ctx->buf, req_ctx->bufnext, req_ctx->to_hash_later);
Lee Nipper5e833bc2010-06-16 15:29:15 +10001727 req_ctx->nbuf = req_ctx->to_hash_later;
Lee Nipper497f2e62010-05-19 19:20:36 +10001728 }
1729 common_nonsnoop_hash_unmap(dev, edesc, areq);
1730
1731 kfree(edesc);
1732
1733 areq->base.complete(&areq->base, err);
1734}
1735
LEROY Christophe2d029052015-04-17 16:32:18 +02001736/*
1737 * SEC1 doesn't like hashing of 0 sized message, so we do the padding
1738 * ourself and submit a padded block
1739 */
1740void talitos_handle_buggy_hash(struct talitos_ctx *ctx,
1741 struct talitos_edesc *edesc,
1742 struct talitos_ptr *ptr)
1743{
1744 static u8 padded_hash[64] = {
1745 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1746 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1747 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1748 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1749 };
1750
1751 pr_err_once("Bug in SEC1, padding ourself\n");
1752 edesc->desc.hdr &= ~DESC_HDR_MODE0_MDEU_PAD;
1753 map_single_talitos_ptr(ctx->dev, ptr, sizeof(padded_hash),
1754 (char *)padded_hash, DMA_TO_DEVICE);
1755}
1756
Lee Nipper497f2e62010-05-19 19:20:36 +10001757static int common_nonsnoop_hash(struct talitos_edesc *edesc,
1758 struct ahash_request *areq, unsigned int length,
1759 void (*callback) (struct device *dev,
1760 struct talitos_desc *desc,
1761 void *context, int error))
1762{
1763 struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq);
1764 struct talitos_ctx *ctx = crypto_ahash_ctx(tfm);
1765 struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
1766 struct device *dev = ctx->dev;
1767 struct talitos_desc *desc = &edesc->desc;
LEROY Christophe032d1972015-04-17 16:31:51 +02001768 int ret;
LEROY Christophe6a1e8d12016-06-06 13:20:38 +02001769 bool sync_needed = false;
LEROY Christophe922f9dc2015-04-17 16:32:07 +02001770 struct talitos_private *priv = dev_get_drvdata(dev);
1771 bool is_sec1 = has_ftr_sec1(priv);
LEROY Christophe6a1e8d12016-06-06 13:20:38 +02001772 int sg_count;
Lee Nipper497f2e62010-05-19 19:20:36 +10001773
1774 /* first DWORD empty */
1775 desc->ptr[0] = zero_entry;
1776
Kim Phillips60f208d2010-05-19 19:21:53 +10001777 /* hash context in */
1778 if (!req_ctx->first || req_ctx->swinit) {
Lee Nipper497f2e62010-05-19 19:20:36 +10001779 map_single_talitos_ptr(dev, &desc->ptr[1],
1780 req_ctx->hw_context_size,
LEROY Christophea2b35aa2015-04-17 16:31:57 +02001781 (char *)req_ctx->hw_context,
Lee Nipper497f2e62010-05-19 19:20:36 +10001782 DMA_TO_DEVICE);
Kim Phillips60f208d2010-05-19 19:21:53 +10001783 req_ctx->swinit = 0;
Lee Nipper497f2e62010-05-19 19:20:36 +10001784 } else {
1785 desc->ptr[1] = zero_entry;
Lee Nipper497f2e62010-05-19 19:20:36 +10001786 }
LEROY Christophe14922592017-09-13 12:44:51 +02001787 /* Indicate next op is not the first. */
1788 req_ctx->first = 0;
Lee Nipper497f2e62010-05-19 19:20:36 +10001789
1790 /* HMAC key */
1791 if (ctx->keylen)
1792 map_single_talitos_ptr(dev, &desc->ptr[2], ctx->keylen,
LEROY Christophea2b35aa2015-04-17 16:31:57 +02001793 (char *)&ctx->key, DMA_TO_DEVICE);
Lee Nipper497f2e62010-05-19 19:20:36 +10001794 else
1795 desc->ptr[2] = zero_entry;
1796
LEROY Christophe6a1e8d12016-06-06 13:20:38 +02001797 sg_count = edesc->src_nents ?: 1;
1798 if (is_sec1 && sg_count > 1)
LEROY Christopheb60f7912017-09-13 12:44:57 +02001799 sg_copy_to_buffer(req_ctx->psrc, sg_count, edesc->buf, length);
LEROY Christophe6a1e8d12016-06-06 13:20:38 +02001800 else
1801 sg_count = dma_map_sg(dev, req_ctx->psrc, sg_count,
1802 DMA_TO_DEVICE);
Lee Nipper497f2e62010-05-19 19:20:36 +10001803 /*
1804 * data in
1805 */
LEROY Christophe6a1e8d12016-06-06 13:20:38 +02001806 sg_count = talitos_sg_map(dev, req_ctx->psrc, length, edesc,
1807 &desc->ptr[3], sg_count, 0, 0);
1808 if (sg_count > 1)
1809 sync_needed = true;
Lee Nipper497f2e62010-05-19 19:20:36 +10001810
1811 /* fifth DWORD empty */
1812 desc->ptr[4] = zero_entry;
1813
1814 /* hash/HMAC out -or- hash context out */
1815 if (req_ctx->last)
1816 map_single_talitos_ptr(dev, &desc->ptr[5],
1817 crypto_ahash_digestsize(tfm),
LEROY Christophea2b35aa2015-04-17 16:31:57 +02001818 areq->result, DMA_FROM_DEVICE);
Lee Nipper497f2e62010-05-19 19:20:36 +10001819 else
1820 map_single_talitos_ptr(dev, &desc->ptr[5],
1821 req_ctx->hw_context_size,
LEROY Christophea2b35aa2015-04-17 16:31:57 +02001822 req_ctx->hw_context, DMA_FROM_DEVICE);
Lee Nipper497f2e62010-05-19 19:20:36 +10001823
1824 /* last DWORD empty */
1825 desc->ptr[6] = zero_entry;
1826
LEROY Christophe2d029052015-04-17 16:32:18 +02001827 if (is_sec1 && from_talitos_ptr_len(&desc->ptr[3], true) == 0)
1828 talitos_handle_buggy_hash(ctx, edesc, &desc->ptr[3]);
1829
LEROY Christophe6a1e8d12016-06-06 13:20:38 +02001830 if (sync_needed)
1831 dma_sync_single_for_device(dev, edesc->dma_link_tbl,
1832 edesc->dma_len, DMA_BIDIRECTIONAL);
1833
Kim Phillips5228f0f2011-07-15 11:21:38 +08001834 ret = talitos_submit(dev, ctx->ch, desc, callback, areq);
Lee Nipper497f2e62010-05-19 19:20:36 +10001835 if (ret != -EINPROGRESS) {
1836 common_nonsnoop_hash_unmap(dev, edesc, areq);
1837 kfree(edesc);
1838 }
1839 return ret;
1840}
1841
1842static struct talitos_edesc *ahash_edesc_alloc(struct ahash_request *areq,
1843 unsigned int nbytes)
1844{
1845 struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq);
1846 struct talitos_ctx *ctx = crypto_ahash_ctx(tfm);
1847 struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
1848
Herbert Xuaeb4c132015-07-30 17:53:22 +08001849 return talitos_edesc_alloc(ctx->dev, req_ctx->psrc, NULL, NULL, 0,
Horia Geanta62293a32013-11-28 15:11:17 +02001850 nbytes, 0, 0, 0, areq->base.flags, false);
Lee Nipper497f2e62010-05-19 19:20:36 +10001851}
1852
1853static int ahash_init(struct ahash_request *areq)
1854{
1855 struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq);
1856 struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
1857
1858 /* Initialize the context */
Lee Nipper5e833bc2010-06-16 15:29:15 +10001859 req_ctx->nbuf = 0;
Kim Phillips60f208d2010-05-19 19:21:53 +10001860 req_ctx->first = 1; /* first indicates h/w must init its context */
1861 req_ctx->swinit = 0; /* assume h/w init of context */
Lee Nipper497f2e62010-05-19 19:20:36 +10001862 req_ctx->hw_context_size =
1863 (crypto_ahash_digestsize(tfm) <= SHA256_DIGEST_SIZE)
1864 ? TALITOS_MDEU_CONTEXT_SIZE_MD5_SHA1_SHA256
1865 : TALITOS_MDEU_CONTEXT_SIZE_SHA384_SHA512;
1866
1867 return 0;
1868}
1869
Kim Phillips60f208d2010-05-19 19:21:53 +10001870/*
1871 * on h/w without explicit sha224 support, we initialize h/w context
1872 * manually with sha224 constants, and tell it to run sha256.
1873 */
1874static int ahash_init_sha224_swinit(struct ahash_request *areq)
1875{
1876 struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
1877
1878 ahash_init(areq);
1879 req_ctx->swinit = 1;/* prevent h/w initting context with sha256 values*/
1880
Kim Phillipsa7524472010-09-23 15:56:38 +08001881 req_ctx->hw_context[0] = SHA224_H0;
1882 req_ctx->hw_context[1] = SHA224_H1;
1883 req_ctx->hw_context[2] = SHA224_H2;
1884 req_ctx->hw_context[3] = SHA224_H3;
1885 req_ctx->hw_context[4] = SHA224_H4;
1886 req_ctx->hw_context[5] = SHA224_H5;
1887 req_ctx->hw_context[6] = SHA224_H6;
1888 req_ctx->hw_context[7] = SHA224_H7;
Kim Phillips60f208d2010-05-19 19:21:53 +10001889
1890 /* init 64-bit count */
1891 req_ctx->hw_context[8] = 0;
1892 req_ctx->hw_context[9] = 0;
1893
1894 return 0;
1895}
1896
Lee Nipper497f2e62010-05-19 19:20:36 +10001897static int ahash_process_req(struct ahash_request *areq, unsigned int nbytes)
1898{
1899 struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq);
1900 struct talitos_ctx *ctx = crypto_ahash_ctx(tfm);
1901 struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
1902 struct talitos_edesc *edesc;
1903 unsigned int blocksize =
1904 crypto_tfm_alg_blocksize(crypto_ahash_tfm(tfm));
1905 unsigned int nbytes_to_hash;
1906 unsigned int to_hash_later;
Lee Nipper5e833bc2010-06-16 15:29:15 +10001907 unsigned int nsg;
LABBE Corentin8e409fe2015-11-04 21:13:34 +01001908 int nents;
Lee Nipper497f2e62010-05-19 19:20:36 +10001909
Lee Nipper5e833bc2010-06-16 15:29:15 +10001910 if (!req_ctx->last && (nbytes + req_ctx->nbuf <= blocksize)) {
1911 /* Buffer up to one whole block */
LABBE Corentin8e409fe2015-11-04 21:13:34 +01001912 nents = sg_nents_for_len(areq->src, nbytes);
1913 if (nents < 0) {
1914 dev_err(ctx->dev, "Invalid number of src SG.\n");
1915 return nents;
1916 }
1917 sg_copy_to_buffer(areq->src, nents,
Lee Nipper5e833bc2010-06-16 15:29:15 +10001918 req_ctx->buf + req_ctx->nbuf, nbytes);
1919 req_ctx->nbuf += nbytes;
Lee Nipper497f2e62010-05-19 19:20:36 +10001920 return 0;
1921 }
1922
Lee Nipper5e833bc2010-06-16 15:29:15 +10001923 /* At least (blocksize + 1) bytes are available to hash */
1924 nbytes_to_hash = nbytes + req_ctx->nbuf;
1925 to_hash_later = nbytes_to_hash & (blocksize - 1);
1926
1927 if (req_ctx->last)
1928 to_hash_later = 0;
1929 else if (to_hash_later)
1930 /* There is a partial block. Hash the full block(s) now */
1931 nbytes_to_hash -= to_hash_later;
1932 else {
1933 /* Keep one block buffered */
1934 nbytes_to_hash -= blocksize;
1935 to_hash_later = blocksize;
1936 }
1937
1938 /* Chain in any previously buffered data */
1939 if (req_ctx->nbuf) {
1940 nsg = (req_ctx->nbuf < nbytes_to_hash) ? 2 : 1;
1941 sg_init_table(req_ctx->bufsl, nsg);
1942 sg_set_buf(req_ctx->bufsl, req_ctx->buf, req_ctx->nbuf);
1943 if (nsg > 1)
Dan Williamsc56f6d12015-08-07 18:15:13 +02001944 sg_chain(req_ctx->bufsl, 2, areq->src);
Lee Nipper497f2e62010-05-19 19:20:36 +10001945 req_ctx->psrc = req_ctx->bufsl;
Lee Nipper5e833bc2010-06-16 15:29:15 +10001946 } else
Lee Nipper497f2e62010-05-19 19:20:36 +10001947 req_ctx->psrc = areq->src;
Lee Nipper497f2e62010-05-19 19:20:36 +10001948
Lee Nipper5e833bc2010-06-16 15:29:15 +10001949 if (to_hash_later) {
LABBE Corentin8e409fe2015-11-04 21:13:34 +01001950 nents = sg_nents_for_len(areq->src, nbytes);
1951 if (nents < 0) {
1952 dev_err(ctx->dev, "Invalid number of src SG.\n");
1953 return nents;
1954 }
Akinobu Mitad0525722013-07-08 16:01:55 -07001955 sg_pcopy_to_buffer(areq->src, nents,
Lee Nipper5e833bc2010-06-16 15:29:15 +10001956 req_ctx->bufnext,
1957 to_hash_later,
1958 nbytes - to_hash_later);
Lee Nipper497f2e62010-05-19 19:20:36 +10001959 }
Lee Nipper5e833bc2010-06-16 15:29:15 +10001960 req_ctx->to_hash_later = to_hash_later;
Lee Nipper497f2e62010-05-19 19:20:36 +10001961
Lee Nipper5e833bc2010-06-16 15:29:15 +10001962 /* Allocate extended descriptor */
Lee Nipper497f2e62010-05-19 19:20:36 +10001963 edesc = ahash_edesc_alloc(areq, nbytes_to_hash);
1964 if (IS_ERR(edesc))
1965 return PTR_ERR(edesc);
1966
1967 edesc->desc.hdr = ctx->desc_hdr_template;
1968
1969 /* On last one, request SEC to pad; otherwise continue */
1970 if (req_ctx->last)
1971 edesc->desc.hdr |= DESC_HDR_MODE0_MDEU_PAD;
1972 else
1973 edesc->desc.hdr |= DESC_HDR_MODE0_MDEU_CONT;
1974
Kim Phillips60f208d2010-05-19 19:21:53 +10001975 /* request SEC to INIT hash. */
1976 if (req_ctx->first && !req_ctx->swinit)
Lee Nipper497f2e62010-05-19 19:20:36 +10001977 edesc->desc.hdr |= DESC_HDR_MODE0_MDEU_INIT;
1978
1979 /* When the tfm context has a keylen, it's an HMAC.
1980 * A first or last (ie. not middle) descriptor must request HMAC.
1981 */
1982 if (ctx->keylen && (req_ctx->first || req_ctx->last))
1983 edesc->desc.hdr |= DESC_HDR_MODE0_MDEU_HMAC;
1984
1985 return common_nonsnoop_hash(edesc, areq, nbytes_to_hash,
1986 ahash_done);
1987}
1988
1989static int ahash_update(struct ahash_request *areq)
1990{
1991 struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
1992
1993 req_ctx->last = 0;
1994
1995 return ahash_process_req(areq, areq->nbytes);
1996}
1997
1998static int ahash_final(struct ahash_request *areq)
1999{
2000 struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
2001
2002 req_ctx->last = 1;
2003
2004 return ahash_process_req(areq, 0);
2005}
2006
2007static int ahash_finup(struct ahash_request *areq)
2008{
2009 struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
2010
2011 req_ctx->last = 1;
2012
2013 return ahash_process_req(areq, areq->nbytes);
2014}
2015
2016static int ahash_digest(struct ahash_request *areq)
2017{
2018 struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
Kim Phillips60f208d2010-05-19 19:21:53 +10002019 struct crypto_ahash *ahash = crypto_ahash_reqtfm(areq);
Lee Nipper497f2e62010-05-19 19:20:36 +10002020
Kim Phillips60f208d2010-05-19 19:21:53 +10002021 ahash->init(areq);
Lee Nipper497f2e62010-05-19 19:20:36 +10002022 req_ctx->last = 1;
2023
2024 return ahash_process_req(areq, areq->nbytes);
2025}
2026
Horia Geant?3639ca82016-04-21 19:24:55 +03002027static int ahash_export(struct ahash_request *areq, void *out)
2028{
2029 struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
2030 struct talitos_export_state *export = out;
2031
2032 memcpy(export->hw_context, req_ctx->hw_context,
2033 req_ctx->hw_context_size);
2034 memcpy(export->buf, req_ctx->buf, req_ctx->nbuf);
2035 export->swinit = req_ctx->swinit;
2036 export->first = req_ctx->first;
2037 export->last = req_ctx->last;
2038 export->to_hash_later = req_ctx->to_hash_later;
2039 export->nbuf = req_ctx->nbuf;
2040
2041 return 0;
2042}
2043
2044static int ahash_import(struct ahash_request *areq, const void *in)
2045{
2046 struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
2047 struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq);
2048 const struct talitos_export_state *export = in;
2049
2050 memset(req_ctx, 0, sizeof(*req_ctx));
2051 req_ctx->hw_context_size =
2052 (crypto_ahash_digestsize(tfm) <= SHA256_DIGEST_SIZE)
2053 ? TALITOS_MDEU_CONTEXT_SIZE_MD5_SHA1_SHA256
2054 : TALITOS_MDEU_CONTEXT_SIZE_SHA384_SHA512;
2055 memcpy(req_ctx->hw_context, export->hw_context,
2056 req_ctx->hw_context_size);
2057 memcpy(req_ctx->buf, export->buf, export->nbuf);
2058 req_ctx->swinit = export->swinit;
2059 req_ctx->first = export->first;
2060 req_ctx->last = export->last;
2061 req_ctx->to_hash_later = export->to_hash_later;
2062 req_ctx->nbuf = export->nbuf;
2063
2064 return 0;
2065}
2066
Lee Nipper79b3a412011-11-21 16:13:25 +08002067struct keyhash_result {
2068 struct completion completion;
2069 int err;
2070};
2071
2072static void keyhash_complete(struct crypto_async_request *req, int err)
2073{
2074 struct keyhash_result *res = req->data;
2075
2076 if (err == -EINPROGRESS)
2077 return;
2078
2079 res->err = err;
2080 complete(&res->completion);
2081}
2082
2083static int keyhash(struct crypto_ahash *tfm, const u8 *key, unsigned int keylen,
2084 u8 *hash)
2085{
2086 struct talitos_ctx *ctx = crypto_tfm_ctx(crypto_ahash_tfm(tfm));
2087
2088 struct scatterlist sg[1];
2089 struct ahash_request *req;
2090 struct keyhash_result hresult;
2091 int ret;
2092
2093 init_completion(&hresult.completion);
2094
2095 req = ahash_request_alloc(tfm, GFP_KERNEL);
2096 if (!req)
2097 return -ENOMEM;
2098
2099 /* Keep tfm keylen == 0 during hash of the long key */
2100 ctx->keylen = 0;
2101 ahash_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
2102 keyhash_complete, &hresult);
2103
2104 sg_init_one(&sg[0], key, keylen);
2105
2106 ahash_request_set_crypt(req, sg, hash, keylen);
2107 ret = crypto_ahash_digest(req);
2108 switch (ret) {
2109 case 0:
2110 break;
2111 case -EINPROGRESS:
2112 case -EBUSY:
2113 ret = wait_for_completion_interruptible(
2114 &hresult.completion);
2115 if (!ret)
2116 ret = hresult.err;
2117 break;
2118 default:
2119 break;
2120 }
2121 ahash_request_free(req);
2122
2123 return ret;
2124}
2125
2126static int ahash_setkey(struct crypto_ahash *tfm, const u8 *key,
2127 unsigned int keylen)
2128{
2129 struct talitos_ctx *ctx = crypto_tfm_ctx(crypto_ahash_tfm(tfm));
2130 unsigned int blocksize =
2131 crypto_tfm_alg_blocksize(crypto_ahash_tfm(tfm));
2132 unsigned int digestsize = crypto_ahash_digestsize(tfm);
2133 unsigned int keysize = keylen;
2134 u8 hash[SHA512_DIGEST_SIZE];
2135 int ret;
2136
2137 if (keylen <= blocksize)
2138 memcpy(ctx->key, key, keysize);
2139 else {
2140 /* Must get the hash of the long key */
2141 ret = keyhash(tfm, key, keylen, hash);
2142
2143 if (ret) {
2144 crypto_ahash_set_flags(tfm, CRYPTO_TFM_RES_BAD_KEY_LEN);
2145 return -EINVAL;
2146 }
2147
2148 keysize = digestsize;
2149 memcpy(ctx->key, hash, digestsize);
2150 }
2151
2152 ctx->keylen = keysize;
2153
2154 return 0;
2155}
2156
2157
Kim Phillips9c4a7962008-06-23 19:50:15 +08002158struct talitos_alg_template {
Lee Nipperd5e4aae2010-05-19 19:18:38 +10002159 u32 type;
LEROY Christopheb0057762016-06-06 13:20:44 +02002160 u32 priority;
Lee Nipperd5e4aae2010-05-19 19:18:38 +10002161 union {
2162 struct crypto_alg crypto;
Lee Nipperacbf7c622010-05-19 19:19:33 +10002163 struct ahash_alg hash;
Herbert Xuaeb4c132015-07-30 17:53:22 +08002164 struct aead_alg aead;
Lee Nipperd5e4aae2010-05-19 19:18:38 +10002165 } alg;
Kim Phillips9c4a7962008-06-23 19:50:15 +08002166 __be32 desc_hdr_template;
2167};
2168
2169static struct talitos_alg_template driver_algs[] = {
Horia Geanta991155b2013-03-20 16:31:38 +02002170 /* AEAD algorithms. These use a single-pass ipsec_esp descriptor */
Lee Nipperd5e4aae2010-05-19 19:18:38 +10002171 { .type = CRYPTO_ALG_TYPE_AEAD,
Herbert Xuaeb4c132015-07-30 17:53:22 +08002172 .alg.aead = {
2173 .base = {
2174 .cra_name = "authenc(hmac(sha1),cbc(aes))",
2175 .cra_driver_name = "authenc-hmac-sha1-"
2176 "cbc-aes-talitos",
2177 .cra_blocksize = AES_BLOCK_SIZE,
2178 .cra_flags = CRYPTO_ALG_ASYNC,
2179 },
2180 .ivsize = AES_BLOCK_SIZE,
2181 .maxauthsize = SHA1_DIGEST_SIZE,
Lee Nipper56af8cd2009-03-29 15:50:50 +08002182 },
Kim Phillips9c4a7962008-06-23 19:50:15 +08002183 .desc_hdr_template = DESC_HDR_TYPE_IPSEC_ESP |
2184 DESC_HDR_SEL0_AESU |
2185 DESC_HDR_MODE0_AESU_CBC |
2186 DESC_HDR_SEL1_MDEUA |
2187 DESC_HDR_MODE1_MDEU_INIT |
2188 DESC_HDR_MODE1_MDEU_PAD |
2189 DESC_HDR_MODE1_MDEU_SHA1_HMAC,
Lee Nipper70bcaca2008-07-03 19:08:46 +08002190 },
Lee Nipperd5e4aae2010-05-19 19:18:38 +10002191 { .type = CRYPTO_ALG_TYPE_AEAD,
LEROY Christophe7405c8d2016-06-06 13:20:46 +02002192 .priority = TALITOS_CRA_PRIORITY_AEAD_HSNA,
2193 .alg.aead = {
2194 .base = {
2195 .cra_name = "authenc(hmac(sha1),cbc(aes))",
2196 .cra_driver_name = "authenc-hmac-sha1-"
2197 "cbc-aes-talitos",
2198 .cra_blocksize = AES_BLOCK_SIZE,
2199 .cra_flags = CRYPTO_ALG_ASYNC,
2200 },
2201 .ivsize = AES_BLOCK_SIZE,
2202 .maxauthsize = SHA1_DIGEST_SIZE,
2203 },
2204 .desc_hdr_template = DESC_HDR_TYPE_HMAC_SNOOP_NO_AFEU |
2205 DESC_HDR_SEL0_AESU |
2206 DESC_HDR_MODE0_AESU_CBC |
2207 DESC_HDR_SEL1_MDEUA |
2208 DESC_HDR_MODE1_MDEU_INIT |
2209 DESC_HDR_MODE1_MDEU_PAD |
2210 DESC_HDR_MODE1_MDEU_SHA1_HMAC,
2211 },
2212 { .type = CRYPTO_ALG_TYPE_AEAD,
Herbert Xuaeb4c132015-07-30 17:53:22 +08002213 .alg.aead = {
2214 .base = {
2215 .cra_name = "authenc(hmac(sha1),"
2216 "cbc(des3_ede))",
2217 .cra_driver_name = "authenc-hmac-sha1-"
2218 "cbc-3des-talitos",
2219 .cra_blocksize = DES3_EDE_BLOCK_SIZE,
2220 .cra_flags = CRYPTO_ALG_ASYNC,
2221 },
2222 .ivsize = DES3_EDE_BLOCK_SIZE,
2223 .maxauthsize = SHA1_DIGEST_SIZE,
Lee Nipper56af8cd2009-03-29 15:50:50 +08002224 },
Lee Nipper70bcaca2008-07-03 19:08:46 +08002225 .desc_hdr_template = DESC_HDR_TYPE_IPSEC_ESP |
2226 DESC_HDR_SEL0_DEU |
2227 DESC_HDR_MODE0_DEU_CBC |
2228 DESC_HDR_MODE0_DEU_3DES |
2229 DESC_HDR_SEL1_MDEUA |
2230 DESC_HDR_MODE1_MDEU_INIT |
2231 DESC_HDR_MODE1_MDEU_PAD |
2232 DESC_HDR_MODE1_MDEU_SHA1_HMAC,
Lee Nipper3952f172008-07-10 18:29:18 +08002233 },
LEROY Christophe7405c8d2016-06-06 13:20:46 +02002234 { .type = CRYPTO_ALG_TYPE_AEAD,
2235 .priority = TALITOS_CRA_PRIORITY_AEAD_HSNA,
2236 .alg.aead = {
2237 .base = {
2238 .cra_name = "authenc(hmac(sha1),"
2239 "cbc(des3_ede))",
2240 .cra_driver_name = "authenc-hmac-sha1-"
2241 "cbc-3des-talitos",
2242 .cra_blocksize = DES3_EDE_BLOCK_SIZE,
2243 .cra_flags = CRYPTO_ALG_ASYNC,
2244 },
2245 .ivsize = DES3_EDE_BLOCK_SIZE,
2246 .maxauthsize = SHA1_DIGEST_SIZE,
2247 },
2248 .desc_hdr_template = DESC_HDR_TYPE_HMAC_SNOOP_NO_AFEU |
2249 DESC_HDR_SEL0_DEU |
2250 DESC_HDR_MODE0_DEU_CBC |
2251 DESC_HDR_MODE0_DEU_3DES |
2252 DESC_HDR_SEL1_MDEUA |
2253 DESC_HDR_MODE1_MDEU_INIT |
2254 DESC_HDR_MODE1_MDEU_PAD |
2255 DESC_HDR_MODE1_MDEU_SHA1_HMAC,
2256 },
Horia Geanta357fb602012-07-03 19:16:53 +03002257 { .type = CRYPTO_ALG_TYPE_AEAD,
Herbert Xuaeb4c132015-07-30 17:53:22 +08002258 .alg.aead = {
2259 .base = {
2260 .cra_name = "authenc(hmac(sha224),cbc(aes))",
2261 .cra_driver_name = "authenc-hmac-sha224-"
2262 "cbc-aes-talitos",
2263 .cra_blocksize = AES_BLOCK_SIZE,
2264 .cra_flags = CRYPTO_ALG_ASYNC,
2265 },
2266 .ivsize = AES_BLOCK_SIZE,
2267 .maxauthsize = SHA224_DIGEST_SIZE,
Horia Geanta357fb602012-07-03 19:16:53 +03002268 },
2269 .desc_hdr_template = DESC_HDR_TYPE_IPSEC_ESP |
2270 DESC_HDR_SEL0_AESU |
2271 DESC_HDR_MODE0_AESU_CBC |
2272 DESC_HDR_SEL1_MDEUA |
2273 DESC_HDR_MODE1_MDEU_INIT |
2274 DESC_HDR_MODE1_MDEU_PAD |
2275 DESC_HDR_MODE1_MDEU_SHA224_HMAC,
2276 },
LEROY Christophe7405c8d2016-06-06 13:20:46 +02002277 { .type = CRYPTO_ALG_TYPE_AEAD,
2278 .priority = TALITOS_CRA_PRIORITY_AEAD_HSNA,
2279 .alg.aead = {
2280 .base = {
2281 .cra_name = "authenc(hmac(sha224),cbc(aes))",
2282 .cra_driver_name = "authenc-hmac-sha224-"
2283 "cbc-aes-talitos",
2284 .cra_blocksize = AES_BLOCK_SIZE,
2285 .cra_flags = CRYPTO_ALG_ASYNC,
2286 },
2287 .ivsize = AES_BLOCK_SIZE,
2288 .maxauthsize = SHA224_DIGEST_SIZE,
2289 },
2290 .desc_hdr_template = DESC_HDR_TYPE_HMAC_SNOOP_NO_AFEU |
2291 DESC_HDR_SEL0_AESU |
2292 DESC_HDR_MODE0_AESU_CBC |
2293 DESC_HDR_SEL1_MDEUA |
2294 DESC_HDR_MODE1_MDEU_INIT |
2295 DESC_HDR_MODE1_MDEU_PAD |
2296 DESC_HDR_MODE1_MDEU_SHA224_HMAC,
2297 },
Horia Geanta357fb602012-07-03 19:16:53 +03002298 { .type = CRYPTO_ALG_TYPE_AEAD,
Herbert Xuaeb4c132015-07-30 17:53:22 +08002299 .alg.aead = {
2300 .base = {
2301 .cra_name = "authenc(hmac(sha224),"
2302 "cbc(des3_ede))",
2303 .cra_driver_name = "authenc-hmac-sha224-"
2304 "cbc-3des-talitos",
2305 .cra_blocksize = DES3_EDE_BLOCK_SIZE,
2306 .cra_flags = CRYPTO_ALG_ASYNC,
2307 },
2308 .ivsize = DES3_EDE_BLOCK_SIZE,
2309 .maxauthsize = SHA224_DIGEST_SIZE,
Horia Geanta357fb602012-07-03 19:16:53 +03002310 },
2311 .desc_hdr_template = DESC_HDR_TYPE_IPSEC_ESP |
2312 DESC_HDR_SEL0_DEU |
2313 DESC_HDR_MODE0_DEU_CBC |
2314 DESC_HDR_MODE0_DEU_3DES |
2315 DESC_HDR_SEL1_MDEUA |
2316 DESC_HDR_MODE1_MDEU_INIT |
2317 DESC_HDR_MODE1_MDEU_PAD |
2318 DESC_HDR_MODE1_MDEU_SHA224_HMAC,
2319 },
Lee Nipperd5e4aae2010-05-19 19:18:38 +10002320 { .type = CRYPTO_ALG_TYPE_AEAD,
LEROY Christophe7405c8d2016-06-06 13:20:46 +02002321 .priority = TALITOS_CRA_PRIORITY_AEAD_HSNA,
2322 .alg.aead = {
2323 .base = {
2324 .cra_name = "authenc(hmac(sha224),"
2325 "cbc(des3_ede))",
2326 .cra_driver_name = "authenc-hmac-sha224-"
2327 "cbc-3des-talitos",
2328 .cra_blocksize = DES3_EDE_BLOCK_SIZE,
2329 .cra_flags = CRYPTO_ALG_ASYNC,
2330 },
2331 .ivsize = DES3_EDE_BLOCK_SIZE,
2332 .maxauthsize = SHA224_DIGEST_SIZE,
2333 },
2334 .desc_hdr_template = DESC_HDR_TYPE_HMAC_SNOOP_NO_AFEU |
2335 DESC_HDR_SEL0_DEU |
2336 DESC_HDR_MODE0_DEU_CBC |
2337 DESC_HDR_MODE0_DEU_3DES |
2338 DESC_HDR_SEL1_MDEUA |
2339 DESC_HDR_MODE1_MDEU_INIT |
2340 DESC_HDR_MODE1_MDEU_PAD |
2341 DESC_HDR_MODE1_MDEU_SHA224_HMAC,
2342 },
2343 { .type = CRYPTO_ALG_TYPE_AEAD,
Herbert Xuaeb4c132015-07-30 17:53:22 +08002344 .alg.aead = {
2345 .base = {
2346 .cra_name = "authenc(hmac(sha256),cbc(aes))",
2347 .cra_driver_name = "authenc-hmac-sha256-"
2348 "cbc-aes-talitos",
2349 .cra_blocksize = AES_BLOCK_SIZE,
2350 .cra_flags = CRYPTO_ALG_ASYNC,
2351 },
2352 .ivsize = AES_BLOCK_SIZE,
2353 .maxauthsize = SHA256_DIGEST_SIZE,
Lee Nipper56af8cd2009-03-29 15:50:50 +08002354 },
Lee Nipper3952f172008-07-10 18:29:18 +08002355 .desc_hdr_template = DESC_HDR_TYPE_IPSEC_ESP |
2356 DESC_HDR_SEL0_AESU |
2357 DESC_HDR_MODE0_AESU_CBC |
2358 DESC_HDR_SEL1_MDEUA |
2359 DESC_HDR_MODE1_MDEU_INIT |
2360 DESC_HDR_MODE1_MDEU_PAD |
2361 DESC_HDR_MODE1_MDEU_SHA256_HMAC,
2362 },
Lee Nipperd5e4aae2010-05-19 19:18:38 +10002363 { .type = CRYPTO_ALG_TYPE_AEAD,
LEROY Christophe7405c8d2016-06-06 13:20:46 +02002364 .priority = TALITOS_CRA_PRIORITY_AEAD_HSNA,
2365 .alg.aead = {
2366 .base = {
2367 .cra_name = "authenc(hmac(sha256),cbc(aes))",
2368 .cra_driver_name = "authenc-hmac-sha256-"
2369 "cbc-aes-talitos",
2370 .cra_blocksize = AES_BLOCK_SIZE,
2371 .cra_flags = CRYPTO_ALG_ASYNC,
2372 },
2373 .ivsize = AES_BLOCK_SIZE,
2374 .maxauthsize = SHA256_DIGEST_SIZE,
2375 },
2376 .desc_hdr_template = DESC_HDR_TYPE_HMAC_SNOOP_NO_AFEU |
2377 DESC_HDR_SEL0_AESU |
2378 DESC_HDR_MODE0_AESU_CBC |
2379 DESC_HDR_SEL1_MDEUA |
2380 DESC_HDR_MODE1_MDEU_INIT |
2381 DESC_HDR_MODE1_MDEU_PAD |
2382 DESC_HDR_MODE1_MDEU_SHA256_HMAC,
2383 },
2384 { .type = CRYPTO_ALG_TYPE_AEAD,
Herbert Xuaeb4c132015-07-30 17:53:22 +08002385 .alg.aead = {
2386 .base = {
2387 .cra_name = "authenc(hmac(sha256),"
2388 "cbc(des3_ede))",
2389 .cra_driver_name = "authenc-hmac-sha256-"
2390 "cbc-3des-talitos",
2391 .cra_blocksize = DES3_EDE_BLOCK_SIZE,
2392 .cra_flags = CRYPTO_ALG_ASYNC,
2393 },
2394 .ivsize = DES3_EDE_BLOCK_SIZE,
2395 .maxauthsize = SHA256_DIGEST_SIZE,
Lee Nipper56af8cd2009-03-29 15:50:50 +08002396 },
Lee Nipper3952f172008-07-10 18:29:18 +08002397 .desc_hdr_template = DESC_HDR_TYPE_IPSEC_ESP |
2398 DESC_HDR_SEL0_DEU |
2399 DESC_HDR_MODE0_DEU_CBC |
2400 DESC_HDR_MODE0_DEU_3DES |
2401 DESC_HDR_SEL1_MDEUA |
2402 DESC_HDR_MODE1_MDEU_INIT |
2403 DESC_HDR_MODE1_MDEU_PAD |
2404 DESC_HDR_MODE1_MDEU_SHA256_HMAC,
2405 },
Lee Nipperd5e4aae2010-05-19 19:18:38 +10002406 { .type = CRYPTO_ALG_TYPE_AEAD,
LEROY Christophe7405c8d2016-06-06 13:20:46 +02002407 .priority = TALITOS_CRA_PRIORITY_AEAD_HSNA,
2408 .alg.aead = {
2409 .base = {
2410 .cra_name = "authenc(hmac(sha256),"
2411 "cbc(des3_ede))",
2412 .cra_driver_name = "authenc-hmac-sha256-"
2413 "cbc-3des-talitos",
2414 .cra_blocksize = DES3_EDE_BLOCK_SIZE,
2415 .cra_flags = CRYPTO_ALG_ASYNC,
2416 },
2417 .ivsize = DES3_EDE_BLOCK_SIZE,
2418 .maxauthsize = SHA256_DIGEST_SIZE,
2419 },
2420 .desc_hdr_template = DESC_HDR_TYPE_HMAC_SNOOP_NO_AFEU |
2421 DESC_HDR_SEL0_DEU |
2422 DESC_HDR_MODE0_DEU_CBC |
2423 DESC_HDR_MODE0_DEU_3DES |
2424 DESC_HDR_SEL1_MDEUA |
2425 DESC_HDR_MODE1_MDEU_INIT |
2426 DESC_HDR_MODE1_MDEU_PAD |
2427 DESC_HDR_MODE1_MDEU_SHA256_HMAC,
2428 },
2429 { .type = CRYPTO_ALG_TYPE_AEAD,
Herbert Xuaeb4c132015-07-30 17:53:22 +08002430 .alg.aead = {
2431 .base = {
2432 .cra_name = "authenc(hmac(sha384),cbc(aes))",
2433 .cra_driver_name = "authenc-hmac-sha384-"
2434 "cbc-aes-talitos",
2435 .cra_blocksize = AES_BLOCK_SIZE,
2436 .cra_flags = CRYPTO_ALG_ASYNC,
2437 },
2438 .ivsize = AES_BLOCK_SIZE,
2439 .maxauthsize = SHA384_DIGEST_SIZE,
Horia Geanta357fb602012-07-03 19:16:53 +03002440 },
2441 .desc_hdr_template = DESC_HDR_TYPE_IPSEC_ESP |
2442 DESC_HDR_SEL0_AESU |
2443 DESC_HDR_MODE0_AESU_CBC |
2444 DESC_HDR_SEL1_MDEUB |
2445 DESC_HDR_MODE1_MDEU_INIT |
2446 DESC_HDR_MODE1_MDEU_PAD |
2447 DESC_HDR_MODE1_MDEUB_SHA384_HMAC,
2448 },
2449 { .type = CRYPTO_ALG_TYPE_AEAD,
Herbert Xuaeb4c132015-07-30 17:53:22 +08002450 .alg.aead = {
2451 .base = {
2452 .cra_name = "authenc(hmac(sha384),"
2453 "cbc(des3_ede))",
2454 .cra_driver_name = "authenc-hmac-sha384-"
2455 "cbc-3des-talitos",
2456 .cra_blocksize = DES3_EDE_BLOCK_SIZE,
2457 .cra_flags = CRYPTO_ALG_ASYNC,
2458 },
2459 .ivsize = DES3_EDE_BLOCK_SIZE,
2460 .maxauthsize = SHA384_DIGEST_SIZE,
Horia Geanta357fb602012-07-03 19:16:53 +03002461 },
2462 .desc_hdr_template = DESC_HDR_TYPE_IPSEC_ESP |
2463 DESC_HDR_SEL0_DEU |
2464 DESC_HDR_MODE0_DEU_CBC |
2465 DESC_HDR_MODE0_DEU_3DES |
2466 DESC_HDR_SEL1_MDEUB |
2467 DESC_HDR_MODE1_MDEU_INIT |
2468 DESC_HDR_MODE1_MDEU_PAD |
2469 DESC_HDR_MODE1_MDEUB_SHA384_HMAC,
2470 },
2471 { .type = CRYPTO_ALG_TYPE_AEAD,
Herbert Xuaeb4c132015-07-30 17:53:22 +08002472 .alg.aead = {
2473 .base = {
2474 .cra_name = "authenc(hmac(sha512),cbc(aes))",
2475 .cra_driver_name = "authenc-hmac-sha512-"
2476 "cbc-aes-talitos",
2477 .cra_blocksize = AES_BLOCK_SIZE,
2478 .cra_flags = CRYPTO_ALG_ASYNC,
2479 },
2480 .ivsize = AES_BLOCK_SIZE,
2481 .maxauthsize = SHA512_DIGEST_SIZE,
Horia Geanta357fb602012-07-03 19:16:53 +03002482 },
2483 .desc_hdr_template = DESC_HDR_TYPE_IPSEC_ESP |
2484 DESC_HDR_SEL0_AESU |
2485 DESC_HDR_MODE0_AESU_CBC |
2486 DESC_HDR_SEL1_MDEUB |
2487 DESC_HDR_MODE1_MDEU_INIT |
2488 DESC_HDR_MODE1_MDEU_PAD |
2489 DESC_HDR_MODE1_MDEUB_SHA512_HMAC,
2490 },
2491 { .type = CRYPTO_ALG_TYPE_AEAD,
Herbert Xuaeb4c132015-07-30 17:53:22 +08002492 .alg.aead = {
2493 .base = {
2494 .cra_name = "authenc(hmac(sha512),"
2495 "cbc(des3_ede))",
2496 .cra_driver_name = "authenc-hmac-sha512-"
2497 "cbc-3des-talitos",
2498 .cra_blocksize = DES3_EDE_BLOCK_SIZE,
2499 .cra_flags = CRYPTO_ALG_ASYNC,
2500 },
2501 .ivsize = DES3_EDE_BLOCK_SIZE,
2502 .maxauthsize = SHA512_DIGEST_SIZE,
Horia Geanta357fb602012-07-03 19:16:53 +03002503 },
2504 .desc_hdr_template = DESC_HDR_TYPE_IPSEC_ESP |
2505 DESC_HDR_SEL0_DEU |
2506 DESC_HDR_MODE0_DEU_CBC |
2507 DESC_HDR_MODE0_DEU_3DES |
2508 DESC_HDR_SEL1_MDEUB |
2509 DESC_HDR_MODE1_MDEU_INIT |
2510 DESC_HDR_MODE1_MDEU_PAD |
2511 DESC_HDR_MODE1_MDEUB_SHA512_HMAC,
2512 },
2513 { .type = CRYPTO_ALG_TYPE_AEAD,
Herbert Xuaeb4c132015-07-30 17:53:22 +08002514 .alg.aead = {
2515 .base = {
2516 .cra_name = "authenc(hmac(md5),cbc(aes))",
2517 .cra_driver_name = "authenc-hmac-md5-"
2518 "cbc-aes-talitos",
2519 .cra_blocksize = AES_BLOCK_SIZE,
2520 .cra_flags = CRYPTO_ALG_ASYNC,
2521 },
2522 .ivsize = AES_BLOCK_SIZE,
2523 .maxauthsize = MD5_DIGEST_SIZE,
Lee Nipper56af8cd2009-03-29 15:50:50 +08002524 },
Lee Nipper3952f172008-07-10 18:29:18 +08002525 .desc_hdr_template = DESC_HDR_TYPE_IPSEC_ESP |
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_MD5_HMAC,
2532 },
Lee Nipperd5e4aae2010-05-19 19:18:38 +10002533 { .type = CRYPTO_ALG_TYPE_AEAD,
LEROY Christophe7405c8d2016-06-06 13:20:46 +02002534 .priority = TALITOS_CRA_PRIORITY_AEAD_HSNA,
2535 .alg.aead = {
2536 .base = {
2537 .cra_name = "authenc(hmac(md5),cbc(aes))",
2538 .cra_driver_name = "authenc-hmac-md5-"
2539 "cbc-aes-talitos",
2540 .cra_blocksize = AES_BLOCK_SIZE,
2541 .cra_flags = CRYPTO_ALG_ASYNC,
2542 },
2543 .ivsize = AES_BLOCK_SIZE,
2544 .maxauthsize = MD5_DIGEST_SIZE,
2545 },
2546 .desc_hdr_template = DESC_HDR_TYPE_HMAC_SNOOP_NO_AFEU |
2547 DESC_HDR_SEL0_AESU |
2548 DESC_HDR_MODE0_AESU_CBC |
2549 DESC_HDR_SEL1_MDEUA |
2550 DESC_HDR_MODE1_MDEU_INIT |
2551 DESC_HDR_MODE1_MDEU_PAD |
2552 DESC_HDR_MODE1_MDEU_MD5_HMAC,
2553 },
2554 { .type = CRYPTO_ALG_TYPE_AEAD,
Herbert Xuaeb4c132015-07-30 17:53:22 +08002555 .alg.aead = {
2556 .base = {
2557 .cra_name = "authenc(hmac(md5),cbc(des3_ede))",
2558 .cra_driver_name = "authenc-hmac-md5-"
2559 "cbc-3des-talitos",
2560 .cra_blocksize = DES3_EDE_BLOCK_SIZE,
2561 .cra_flags = CRYPTO_ALG_ASYNC,
2562 },
2563 .ivsize = DES3_EDE_BLOCK_SIZE,
2564 .maxauthsize = MD5_DIGEST_SIZE,
Lee Nipper56af8cd2009-03-29 15:50:50 +08002565 },
Lee Nipper3952f172008-07-10 18:29:18 +08002566 .desc_hdr_template = DESC_HDR_TYPE_IPSEC_ESP |
2567 DESC_HDR_SEL0_DEU |
2568 DESC_HDR_MODE0_DEU_CBC |
2569 DESC_HDR_MODE0_DEU_3DES |
2570 DESC_HDR_SEL1_MDEUA |
2571 DESC_HDR_MODE1_MDEU_INIT |
2572 DESC_HDR_MODE1_MDEU_PAD |
2573 DESC_HDR_MODE1_MDEU_MD5_HMAC,
Lee Nipper4de9d0b2009-03-29 15:52:32 +08002574 },
LEROY Christophe7405c8d2016-06-06 13:20:46 +02002575 { .type = CRYPTO_ALG_TYPE_AEAD,
2576 .priority = TALITOS_CRA_PRIORITY_AEAD_HSNA,
2577 .alg.aead = {
2578 .base = {
2579 .cra_name = "authenc(hmac(md5),cbc(des3_ede))",
2580 .cra_driver_name = "authenc-hmac-md5-"
2581 "cbc-3des-talitos",
2582 .cra_blocksize = DES3_EDE_BLOCK_SIZE,
2583 .cra_flags = CRYPTO_ALG_ASYNC,
2584 },
2585 .ivsize = DES3_EDE_BLOCK_SIZE,
2586 .maxauthsize = MD5_DIGEST_SIZE,
2587 },
2588 .desc_hdr_template = DESC_HDR_TYPE_HMAC_SNOOP_NO_AFEU |
2589 DESC_HDR_SEL0_DEU |
2590 DESC_HDR_MODE0_DEU_CBC |
2591 DESC_HDR_MODE0_DEU_3DES |
2592 DESC_HDR_SEL1_MDEUA |
2593 DESC_HDR_MODE1_MDEU_INIT |
2594 DESC_HDR_MODE1_MDEU_PAD |
2595 DESC_HDR_MODE1_MDEU_MD5_HMAC,
2596 },
Lee Nipper4de9d0b2009-03-29 15:52:32 +08002597 /* ABLKCIPHER algorithms. */
Lee Nipperd5e4aae2010-05-19 19:18:38 +10002598 { .type = CRYPTO_ALG_TYPE_ABLKCIPHER,
2599 .alg.crypto = {
LEROY Christophe5e75ae12015-12-01 12:44:15 +01002600 .cra_name = "ecb(aes)",
2601 .cra_driver_name = "ecb-aes-talitos",
2602 .cra_blocksize = AES_BLOCK_SIZE,
2603 .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER |
2604 CRYPTO_ALG_ASYNC,
2605 .cra_ablkcipher = {
2606 .min_keysize = AES_MIN_KEY_SIZE,
2607 .max_keysize = AES_MAX_KEY_SIZE,
2608 .ivsize = AES_BLOCK_SIZE,
2609 }
2610 },
2611 .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
2612 DESC_HDR_SEL0_AESU,
2613 },
2614 { .type = CRYPTO_ALG_TYPE_ABLKCIPHER,
2615 .alg.crypto = {
Lee Nipper4de9d0b2009-03-29 15:52:32 +08002616 .cra_name = "cbc(aes)",
2617 .cra_driver_name = "cbc-aes-talitos",
2618 .cra_blocksize = AES_BLOCK_SIZE,
2619 .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER |
2620 CRYPTO_ALG_ASYNC,
Lee Nipper4de9d0b2009-03-29 15:52:32 +08002621 .cra_ablkcipher = {
Lee Nipper4de9d0b2009-03-29 15:52:32 +08002622 .min_keysize = AES_MIN_KEY_SIZE,
2623 .max_keysize = AES_MAX_KEY_SIZE,
2624 .ivsize = AES_BLOCK_SIZE,
2625 }
2626 },
2627 .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
2628 DESC_HDR_SEL0_AESU |
2629 DESC_HDR_MODE0_AESU_CBC,
2630 },
Lee Nipperd5e4aae2010-05-19 19:18:38 +10002631 { .type = CRYPTO_ALG_TYPE_ABLKCIPHER,
2632 .alg.crypto = {
LEROY Christophe5e75ae12015-12-01 12:44:15 +01002633 .cra_name = "ctr(aes)",
2634 .cra_driver_name = "ctr-aes-talitos",
2635 .cra_blocksize = AES_BLOCK_SIZE,
2636 .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER |
2637 CRYPTO_ALG_ASYNC,
2638 .cra_ablkcipher = {
2639 .min_keysize = AES_MIN_KEY_SIZE,
2640 .max_keysize = AES_MAX_KEY_SIZE,
2641 .ivsize = AES_BLOCK_SIZE,
2642 }
2643 },
LEROY Christophe47ab7202017-10-06 15:04:43 +02002644 .desc_hdr_template = DESC_HDR_TYPE_AESU_CTR_NONSNOOP |
LEROY Christophe5e75ae12015-12-01 12:44:15 +01002645 DESC_HDR_SEL0_AESU |
2646 DESC_HDR_MODE0_AESU_CTR,
2647 },
2648 { .type = CRYPTO_ALG_TYPE_ABLKCIPHER,
2649 .alg.crypto = {
2650 .cra_name = "ecb(des)",
2651 .cra_driver_name = "ecb-des-talitos",
2652 .cra_blocksize = DES_BLOCK_SIZE,
2653 .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER |
2654 CRYPTO_ALG_ASYNC,
2655 .cra_ablkcipher = {
2656 .min_keysize = DES_KEY_SIZE,
2657 .max_keysize = DES_KEY_SIZE,
2658 .ivsize = DES_BLOCK_SIZE,
2659 }
2660 },
2661 .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
2662 DESC_HDR_SEL0_DEU,
2663 },
2664 { .type = CRYPTO_ALG_TYPE_ABLKCIPHER,
2665 .alg.crypto = {
2666 .cra_name = "cbc(des)",
2667 .cra_driver_name = "cbc-des-talitos",
2668 .cra_blocksize = DES_BLOCK_SIZE,
2669 .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER |
2670 CRYPTO_ALG_ASYNC,
2671 .cra_ablkcipher = {
2672 .min_keysize = DES_KEY_SIZE,
2673 .max_keysize = DES_KEY_SIZE,
2674 .ivsize = DES_BLOCK_SIZE,
2675 }
2676 },
2677 .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
2678 DESC_HDR_SEL0_DEU |
2679 DESC_HDR_MODE0_DEU_CBC,
2680 },
2681 { .type = CRYPTO_ALG_TYPE_ABLKCIPHER,
2682 .alg.crypto = {
2683 .cra_name = "ecb(des3_ede)",
2684 .cra_driver_name = "ecb-3des-talitos",
2685 .cra_blocksize = DES3_EDE_BLOCK_SIZE,
2686 .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER |
2687 CRYPTO_ALG_ASYNC,
2688 .cra_ablkcipher = {
2689 .min_keysize = DES3_EDE_KEY_SIZE,
2690 .max_keysize = DES3_EDE_KEY_SIZE,
2691 .ivsize = DES3_EDE_BLOCK_SIZE,
2692 }
2693 },
2694 .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
2695 DESC_HDR_SEL0_DEU |
2696 DESC_HDR_MODE0_DEU_3DES,
2697 },
2698 { .type = CRYPTO_ALG_TYPE_ABLKCIPHER,
2699 .alg.crypto = {
Lee Nipper4de9d0b2009-03-29 15:52:32 +08002700 .cra_name = "cbc(des3_ede)",
2701 .cra_driver_name = "cbc-3des-talitos",
2702 .cra_blocksize = DES3_EDE_BLOCK_SIZE,
2703 .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER |
2704 CRYPTO_ALG_ASYNC,
Lee Nipper4de9d0b2009-03-29 15:52:32 +08002705 .cra_ablkcipher = {
Lee Nipper4de9d0b2009-03-29 15:52:32 +08002706 .min_keysize = DES3_EDE_KEY_SIZE,
2707 .max_keysize = DES3_EDE_KEY_SIZE,
2708 .ivsize = DES3_EDE_BLOCK_SIZE,
2709 }
2710 },
2711 .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
2712 DESC_HDR_SEL0_DEU |
2713 DESC_HDR_MODE0_DEU_CBC |
2714 DESC_HDR_MODE0_DEU_3DES,
Lee Nipper497f2e62010-05-19 19:20:36 +10002715 },
2716 /* AHASH algorithms. */
2717 { .type = CRYPTO_ALG_TYPE_AHASH,
2718 .alg.hash = {
Lee Nipper497f2e62010-05-19 19:20:36 +10002719 .halg.digestsize = MD5_DIGEST_SIZE,
Horia Geant?3639ca82016-04-21 19:24:55 +03002720 .halg.statesize = sizeof(struct talitos_export_state),
Lee Nipper497f2e62010-05-19 19:20:36 +10002721 .halg.base = {
2722 .cra_name = "md5",
2723 .cra_driver_name = "md5-talitos",
Martin Hicksb3988612015-03-03 08:21:34 -05002724 .cra_blocksize = MD5_HMAC_BLOCK_SIZE,
Lee Nipper497f2e62010-05-19 19:20:36 +10002725 .cra_flags = CRYPTO_ALG_TYPE_AHASH |
2726 CRYPTO_ALG_ASYNC,
Lee Nipper497f2e62010-05-19 19:20:36 +10002727 }
2728 },
2729 .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
2730 DESC_HDR_SEL0_MDEUA |
2731 DESC_HDR_MODE0_MDEU_MD5,
2732 },
2733 { .type = CRYPTO_ALG_TYPE_AHASH,
2734 .alg.hash = {
Lee Nipper497f2e62010-05-19 19:20:36 +10002735 .halg.digestsize = SHA1_DIGEST_SIZE,
Horia Geant?3639ca82016-04-21 19:24:55 +03002736 .halg.statesize = sizeof(struct talitos_export_state),
Lee Nipper497f2e62010-05-19 19:20:36 +10002737 .halg.base = {
2738 .cra_name = "sha1",
2739 .cra_driver_name = "sha1-talitos",
2740 .cra_blocksize = SHA1_BLOCK_SIZE,
2741 .cra_flags = CRYPTO_ALG_TYPE_AHASH |
2742 CRYPTO_ALG_ASYNC,
Lee Nipper497f2e62010-05-19 19:20:36 +10002743 }
2744 },
2745 .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
2746 DESC_HDR_SEL0_MDEUA |
2747 DESC_HDR_MODE0_MDEU_SHA1,
2748 },
2749 { .type = CRYPTO_ALG_TYPE_AHASH,
2750 .alg.hash = {
Kim Phillips60f208d2010-05-19 19:21:53 +10002751 .halg.digestsize = SHA224_DIGEST_SIZE,
Horia Geant?3639ca82016-04-21 19:24:55 +03002752 .halg.statesize = sizeof(struct talitos_export_state),
Kim Phillips60f208d2010-05-19 19:21:53 +10002753 .halg.base = {
2754 .cra_name = "sha224",
2755 .cra_driver_name = "sha224-talitos",
2756 .cra_blocksize = SHA224_BLOCK_SIZE,
2757 .cra_flags = CRYPTO_ALG_TYPE_AHASH |
2758 CRYPTO_ALG_ASYNC,
Kim Phillips60f208d2010-05-19 19:21:53 +10002759 }
2760 },
2761 .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
2762 DESC_HDR_SEL0_MDEUA |
2763 DESC_HDR_MODE0_MDEU_SHA224,
2764 },
2765 { .type = CRYPTO_ALG_TYPE_AHASH,
2766 .alg.hash = {
Lee Nipper497f2e62010-05-19 19:20:36 +10002767 .halg.digestsize = SHA256_DIGEST_SIZE,
Horia Geant?3639ca82016-04-21 19:24:55 +03002768 .halg.statesize = sizeof(struct talitos_export_state),
Lee Nipper497f2e62010-05-19 19:20:36 +10002769 .halg.base = {
2770 .cra_name = "sha256",
2771 .cra_driver_name = "sha256-talitos",
2772 .cra_blocksize = SHA256_BLOCK_SIZE,
2773 .cra_flags = CRYPTO_ALG_TYPE_AHASH |
2774 CRYPTO_ALG_ASYNC,
Lee Nipper497f2e62010-05-19 19:20:36 +10002775 }
2776 },
2777 .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
2778 DESC_HDR_SEL0_MDEUA |
2779 DESC_HDR_MODE0_MDEU_SHA256,
2780 },
2781 { .type = CRYPTO_ALG_TYPE_AHASH,
2782 .alg.hash = {
Lee Nipper497f2e62010-05-19 19:20:36 +10002783 .halg.digestsize = SHA384_DIGEST_SIZE,
Horia Geant?3639ca82016-04-21 19:24:55 +03002784 .halg.statesize = sizeof(struct talitos_export_state),
Lee Nipper497f2e62010-05-19 19:20:36 +10002785 .halg.base = {
2786 .cra_name = "sha384",
2787 .cra_driver_name = "sha384-talitos",
2788 .cra_blocksize = SHA384_BLOCK_SIZE,
2789 .cra_flags = CRYPTO_ALG_TYPE_AHASH |
2790 CRYPTO_ALG_ASYNC,
Lee Nipper497f2e62010-05-19 19:20:36 +10002791 }
2792 },
2793 .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
2794 DESC_HDR_SEL0_MDEUB |
2795 DESC_HDR_MODE0_MDEUB_SHA384,
2796 },
2797 { .type = CRYPTO_ALG_TYPE_AHASH,
2798 .alg.hash = {
Lee Nipper497f2e62010-05-19 19:20:36 +10002799 .halg.digestsize = SHA512_DIGEST_SIZE,
Horia Geant?3639ca82016-04-21 19:24:55 +03002800 .halg.statesize = sizeof(struct talitos_export_state),
Lee Nipper497f2e62010-05-19 19:20:36 +10002801 .halg.base = {
2802 .cra_name = "sha512",
2803 .cra_driver_name = "sha512-talitos",
2804 .cra_blocksize = SHA512_BLOCK_SIZE,
2805 .cra_flags = CRYPTO_ALG_TYPE_AHASH |
2806 CRYPTO_ALG_ASYNC,
Lee Nipper497f2e62010-05-19 19:20:36 +10002807 }
2808 },
2809 .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
2810 DESC_HDR_SEL0_MDEUB |
2811 DESC_HDR_MODE0_MDEUB_SHA512,
2812 },
Lee Nipper79b3a412011-11-21 16:13:25 +08002813 { .type = CRYPTO_ALG_TYPE_AHASH,
2814 .alg.hash = {
Lee Nipper79b3a412011-11-21 16:13:25 +08002815 .halg.digestsize = MD5_DIGEST_SIZE,
Horia Geant?3639ca82016-04-21 19:24:55 +03002816 .halg.statesize = sizeof(struct talitos_export_state),
Lee Nipper79b3a412011-11-21 16:13:25 +08002817 .halg.base = {
2818 .cra_name = "hmac(md5)",
2819 .cra_driver_name = "hmac-md5-talitos",
Martin Hicksb3988612015-03-03 08:21:34 -05002820 .cra_blocksize = MD5_HMAC_BLOCK_SIZE,
Lee Nipper79b3a412011-11-21 16:13:25 +08002821 .cra_flags = CRYPTO_ALG_TYPE_AHASH |
2822 CRYPTO_ALG_ASYNC,
Lee Nipper79b3a412011-11-21 16:13:25 +08002823 }
2824 },
2825 .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
2826 DESC_HDR_SEL0_MDEUA |
2827 DESC_HDR_MODE0_MDEU_MD5,
2828 },
2829 { .type = CRYPTO_ALG_TYPE_AHASH,
2830 .alg.hash = {
Lee Nipper79b3a412011-11-21 16:13:25 +08002831 .halg.digestsize = SHA1_DIGEST_SIZE,
Horia Geant?3639ca82016-04-21 19:24:55 +03002832 .halg.statesize = sizeof(struct talitos_export_state),
Lee Nipper79b3a412011-11-21 16:13:25 +08002833 .halg.base = {
2834 .cra_name = "hmac(sha1)",
2835 .cra_driver_name = "hmac-sha1-talitos",
2836 .cra_blocksize = SHA1_BLOCK_SIZE,
2837 .cra_flags = CRYPTO_ALG_TYPE_AHASH |
2838 CRYPTO_ALG_ASYNC,
Lee Nipper79b3a412011-11-21 16:13:25 +08002839 }
2840 },
2841 .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
2842 DESC_HDR_SEL0_MDEUA |
2843 DESC_HDR_MODE0_MDEU_SHA1,
2844 },
2845 { .type = CRYPTO_ALG_TYPE_AHASH,
2846 .alg.hash = {
Lee Nipper79b3a412011-11-21 16:13:25 +08002847 .halg.digestsize = SHA224_DIGEST_SIZE,
Horia Geant?3639ca82016-04-21 19:24:55 +03002848 .halg.statesize = sizeof(struct talitos_export_state),
Lee Nipper79b3a412011-11-21 16:13:25 +08002849 .halg.base = {
2850 .cra_name = "hmac(sha224)",
2851 .cra_driver_name = "hmac-sha224-talitos",
2852 .cra_blocksize = SHA224_BLOCK_SIZE,
2853 .cra_flags = CRYPTO_ALG_TYPE_AHASH |
2854 CRYPTO_ALG_ASYNC,
Lee Nipper79b3a412011-11-21 16:13:25 +08002855 }
2856 },
2857 .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
2858 DESC_HDR_SEL0_MDEUA |
2859 DESC_HDR_MODE0_MDEU_SHA224,
2860 },
2861 { .type = CRYPTO_ALG_TYPE_AHASH,
2862 .alg.hash = {
Lee Nipper79b3a412011-11-21 16:13:25 +08002863 .halg.digestsize = SHA256_DIGEST_SIZE,
Horia Geant?3639ca82016-04-21 19:24:55 +03002864 .halg.statesize = sizeof(struct talitos_export_state),
Lee Nipper79b3a412011-11-21 16:13:25 +08002865 .halg.base = {
2866 .cra_name = "hmac(sha256)",
2867 .cra_driver_name = "hmac-sha256-talitos",
2868 .cra_blocksize = SHA256_BLOCK_SIZE,
2869 .cra_flags = CRYPTO_ALG_TYPE_AHASH |
2870 CRYPTO_ALG_ASYNC,
Lee Nipper79b3a412011-11-21 16:13:25 +08002871 }
2872 },
2873 .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
2874 DESC_HDR_SEL0_MDEUA |
2875 DESC_HDR_MODE0_MDEU_SHA256,
2876 },
2877 { .type = CRYPTO_ALG_TYPE_AHASH,
2878 .alg.hash = {
Lee Nipper79b3a412011-11-21 16:13:25 +08002879 .halg.digestsize = SHA384_DIGEST_SIZE,
Horia Geant?3639ca82016-04-21 19:24:55 +03002880 .halg.statesize = sizeof(struct talitos_export_state),
Lee Nipper79b3a412011-11-21 16:13:25 +08002881 .halg.base = {
2882 .cra_name = "hmac(sha384)",
2883 .cra_driver_name = "hmac-sha384-talitos",
2884 .cra_blocksize = SHA384_BLOCK_SIZE,
2885 .cra_flags = CRYPTO_ALG_TYPE_AHASH |
2886 CRYPTO_ALG_ASYNC,
Lee Nipper79b3a412011-11-21 16:13:25 +08002887 }
2888 },
2889 .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
2890 DESC_HDR_SEL0_MDEUB |
2891 DESC_HDR_MODE0_MDEUB_SHA384,
2892 },
2893 { .type = CRYPTO_ALG_TYPE_AHASH,
2894 .alg.hash = {
Lee Nipper79b3a412011-11-21 16:13:25 +08002895 .halg.digestsize = SHA512_DIGEST_SIZE,
Horia Geant?3639ca82016-04-21 19:24:55 +03002896 .halg.statesize = sizeof(struct talitos_export_state),
Lee Nipper79b3a412011-11-21 16:13:25 +08002897 .halg.base = {
2898 .cra_name = "hmac(sha512)",
2899 .cra_driver_name = "hmac-sha512-talitos",
2900 .cra_blocksize = SHA512_BLOCK_SIZE,
2901 .cra_flags = CRYPTO_ALG_TYPE_AHASH |
2902 CRYPTO_ALG_ASYNC,
Lee Nipper79b3a412011-11-21 16:13:25 +08002903 }
2904 },
2905 .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
2906 DESC_HDR_SEL0_MDEUB |
2907 DESC_HDR_MODE0_MDEUB_SHA512,
2908 }
Kim Phillips9c4a7962008-06-23 19:50:15 +08002909};
2910
2911struct talitos_crypto_alg {
2912 struct list_head entry;
2913 struct device *dev;
Lee Nipperacbf7c622010-05-19 19:19:33 +10002914 struct talitos_alg_template algt;
Kim Phillips9c4a7962008-06-23 19:50:15 +08002915};
2916
Jonas Eymann89d124c2016-04-19 20:33:47 +03002917static int talitos_init_common(struct talitos_ctx *ctx,
2918 struct talitos_crypto_alg *talitos_alg)
Kim Phillips9c4a7962008-06-23 19:50:15 +08002919{
Kim Phillips5228f0f2011-07-15 11:21:38 +08002920 struct talitos_private *priv;
Kim Phillips9c4a7962008-06-23 19:50:15 +08002921
2922 /* update context with ptr to dev */
2923 ctx->dev = talitos_alg->dev;
Kim Phillips19bbbc62009-03-29 15:53:59 +08002924
Kim Phillips5228f0f2011-07-15 11:21:38 +08002925 /* assign SEC channel to tfm in round-robin fashion */
2926 priv = dev_get_drvdata(ctx->dev);
2927 ctx->ch = atomic_inc_return(&priv->last_chan) &
2928 (priv->num_channels - 1);
2929
Kim Phillips9c4a7962008-06-23 19:50:15 +08002930 /* copy descriptor header template value */
Lee Nipperacbf7c622010-05-19 19:19:33 +10002931 ctx->desc_hdr_template = talitos_alg->algt.desc_hdr_template;
Kim Phillips9c4a7962008-06-23 19:50:15 +08002932
Kim Phillips602dba52011-07-15 11:21:39 +08002933 /* select done notification */
2934 ctx->desc_hdr_template |= DESC_HDR_DONE_NOTIFY;
2935
Lee Nipper497f2e62010-05-19 19:20:36 +10002936 return 0;
2937}
2938
Jonas Eymann89d124c2016-04-19 20:33:47 +03002939static int talitos_cra_init(struct crypto_tfm *tfm)
2940{
2941 struct crypto_alg *alg = tfm->__crt_alg;
2942 struct talitos_crypto_alg *talitos_alg;
2943 struct talitos_ctx *ctx = crypto_tfm_ctx(tfm);
2944
2945 if ((alg->cra_flags & CRYPTO_ALG_TYPE_MASK) == CRYPTO_ALG_TYPE_AHASH)
2946 talitos_alg = container_of(__crypto_ahash_alg(alg),
2947 struct talitos_crypto_alg,
2948 algt.alg.hash);
2949 else
2950 talitos_alg = container_of(alg, struct talitos_crypto_alg,
2951 algt.alg.crypto);
2952
2953 return talitos_init_common(ctx, talitos_alg);
2954}
2955
Herbert Xuaeb4c132015-07-30 17:53:22 +08002956static int talitos_cra_init_aead(struct crypto_aead *tfm)
Lee Nipper497f2e62010-05-19 19:20:36 +10002957{
Jonas Eymann89d124c2016-04-19 20:33:47 +03002958 struct aead_alg *alg = crypto_aead_alg(tfm);
2959 struct talitos_crypto_alg *talitos_alg;
2960 struct talitos_ctx *ctx = crypto_aead_ctx(tfm);
2961
2962 talitos_alg = container_of(alg, struct talitos_crypto_alg,
2963 algt.alg.aead);
2964
2965 return talitos_init_common(ctx, talitos_alg);
Kim Phillips9c4a7962008-06-23 19:50:15 +08002966}
2967
Lee Nipper497f2e62010-05-19 19:20:36 +10002968static int talitos_cra_init_ahash(struct crypto_tfm *tfm)
2969{
2970 struct talitos_ctx *ctx = crypto_tfm_ctx(tfm);
2971
2972 talitos_cra_init(tfm);
2973
2974 ctx->keylen = 0;
2975 crypto_ahash_set_reqsize(__crypto_ahash_cast(tfm),
2976 sizeof(struct talitos_ahash_req_ctx));
2977
2978 return 0;
2979}
2980
Kim Phillips9c4a7962008-06-23 19:50:15 +08002981/*
2982 * given the alg's descriptor header template, determine whether descriptor
2983 * type and primary/secondary execution units required match the hw
2984 * capabilities description provided in the device tree node.
2985 */
2986static int hw_supports(struct device *dev, __be32 desc_hdr_template)
2987{
2988 struct talitos_private *priv = dev_get_drvdata(dev);
2989 int ret;
2990
2991 ret = (1 << DESC_TYPE(desc_hdr_template) & priv->desc_types) &&
2992 (1 << PRIMARY_EU(desc_hdr_template) & priv->exec_units);
2993
2994 if (SECONDARY_EU(desc_hdr_template))
2995 ret = ret && (1 << SECONDARY_EU(desc_hdr_template)
2996 & priv->exec_units);
2997
2998 return ret;
2999}
3000
Grant Likely2dc11582010-08-06 09:25:50 -06003001static int talitos_remove(struct platform_device *ofdev)
Kim Phillips9c4a7962008-06-23 19:50:15 +08003002{
3003 struct device *dev = &ofdev->dev;
3004 struct talitos_private *priv = dev_get_drvdata(dev);
3005 struct talitos_crypto_alg *t_alg, *n;
3006 int i;
3007
3008 list_for_each_entry_safe(t_alg, n, &priv->alg_list, entry) {
Lee Nipperacbf7c622010-05-19 19:19:33 +10003009 switch (t_alg->algt.type) {
3010 case CRYPTO_ALG_TYPE_ABLKCIPHER:
Lee Nipperacbf7c622010-05-19 19:19:33 +10003011 break;
Herbert Xuaeb4c132015-07-30 17:53:22 +08003012 case CRYPTO_ALG_TYPE_AEAD:
3013 crypto_unregister_aead(&t_alg->algt.alg.aead);
Lee Nipperacbf7c622010-05-19 19:19:33 +10003014 case CRYPTO_ALG_TYPE_AHASH:
3015 crypto_unregister_ahash(&t_alg->algt.alg.hash);
3016 break;
3017 }
Kim Phillips9c4a7962008-06-23 19:50:15 +08003018 list_del(&t_alg->entry);
3019 kfree(t_alg);
3020 }
3021
3022 if (hw_supports(dev, DESC_HDR_SEL0_RNG))
3023 talitos_unregister_rng(dev);
3024
Aaron Sierra35a3bb32015-08-05 16:52:08 -05003025 for (i = 0; priv->chan && i < priv->num_channels; i++)
Kim Phillips0b798242010-09-23 15:56:08 +08003026 kfree(priv->chan[i].fifo);
Kim Phillips9c4a7962008-06-23 19:50:15 +08003027
Kim Phillips4b9926282009-08-13 11:50:38 +10003028 kfree(priv->chan);
Kim Phillips9c4a7962008-06-23 19:50:15 +08003029
Kim Phillipsc3e337f2011-11-21 16:13:27 +08003030 for (i = 0; i < 2; i++)
Kim Phillips2cdba3c2011-12-12 14:59:11 -06003031 if (priv->irq[i]) {
Kim Phillipsc3e337f2011-11-21 16:13:27 +08003032 free_irq(priv->irq[i], dev);
3033 irq_dispose_mapping(priv->irq[i]);
3034 }
Kim Phillips9c4a7962008-06-23 19:50:15 +08003035
Kim Phillipsc3e337f2011-11-21 16:13:27 +08003036 tasklet_kill(&priv->done_task[0]);
Kim Phillips2cdba3c2011-12-12 14:59:11 -06003037 if (priv->irq[1])
Kim Phillipsc3e337f2011-11-21 16:13:27 +08003038 tasklet_kill(&priv->done_task[1]);
Kim Phillips9c4a7962008-06-23 19:50:15 +08003039
3040 iounmap(priv->reg);
3041
Kim Phillips9c4a7962008-06-23 19:50:15 +08003042 kfree(priv);
3043
3044 return 0;
3045}
3046
3047static struct talitos_crypto_alg *talitos_alg_alloc(struct device *dev,
3048 struct talitos_alg_template
3049 *template)
3050{
Kim Phillips60f208d2010-05-19 19:21:53 +10003051 struct talitos_private *priv = dev_get_drvdata(dev);
Kim Phillips9c4a7962008-06-23 19:50:15 +08003052 struct talitos_crypto_alg *t_alg;
3053 struct crypto_alg *alg;
3054
3055 t_alg = kzalloc(sizeof(struct talitos_crypto_alg), GFP_KERNEL);
3056 if (!t_alg)
3057 return ERR_PTR(-ENOMEM);
3058
Lee Nipperacbf7c622010-05-19 19:19:33 +10003059 t_alg->algt = *template;
3060
3061 switch (t_alg->algt.type) {
3062 case CRYPTO_ALG_TYPE_ABLKCIPHER:
Lee Nipper497f2e62010-05-19 19:20:36 +10003063 alg = &t_alg->algt.alg.crypto;
3064 alg->cra_init = talitos_cra_init;
Kim Phillipsd4cd3282012-08-08 20:32:00 -05003065 alg->cra_type = &crypto_ablkcipher_type;
Kim Phillipsb286e002012-08-08 20:33:34 -05003066 alg->cra_ablkcipher.setkey = ablkcipher_setkey;
3067 alg->cra_ablkcipher.encrypt = ablkcipher_encrypt;
3068 alg->cra_ablkcipher.decrypt = ablkcipher_decrypt;
3069 alg->cra_ablkcipher.geniv = "eseqiv";
Lee Nipper497f2e62010-05-19 19:20:36 +10003070 break;
Lee Nipperacbf7c622010-05-19 19:19:33 +10003071 case CRYPTO_ALG_TYPE_AEAD:
Herbert Xuaeb4c132015-07-30 17:53:22 +08003072 alg = &t_alg->algt.alg.aead.base;
Herbert Xuaeb4c132015-07-30 17:53:22 +08003073 t_alg->algt.alg.aead.init = talitos_cra_init_aead;
3074 t_alg->algt.alg.aead.setkey = aead_setkey;
3075 t_alg->algt.alg.aead.encrypt = aead_encrypt;
3076 t_alg->algt.alg.aead.decrypt = aead_decrypt;
LEROY Christophe6bf30e62017-10-06 15:04:39 +02003077 if (!(priv->features & TALITOS_FTR_SHA224_HWINIT) &&
3078 !strncmp(alg->cra_name, "authenc(hmac(sha224)", 20)) {
3079 kfree(t_alg);
3080 return ERR_PTR(-ENOTSUPP);
3081 }
Lee Nipperacbf7c622010-05-19 19:19:33 +10003082 break;
3083 case CRYPTO_ALG_TYPE_AHASH:
3084 alg = &t_alg->algt.alg.hash.halg.base;
Lee Nipper497f2e62010-05-19 19:20:36 +10003085 alg->cra_init = talitos_cra_init_ahash;
Kim Phillipsd4cd3282012-08-08 20:32:00 -05003086 alg->cra_type = &crypto_ahash_type;
Kim Phillipsb286e002012-08-08 20:33:34 -05003087 t_alg->algt.alg.hash.init = ahash_init;
3088 t_alg->algt.alg.hash.update = ahash_update;
3089 t_alg->algt.alg.hash.final = ahash_final;
3090 t_alg->algt.alg.hash.finup = ahash_finup;
3091 t_alg->algt.alg.hash.digest = ahash_digest;
LEROY Christophe70117b72017-09-12 11:03:39 +02003092 if (!strncmp(alg->cra_name, "hmac", 4))
3093 t_alg->algt.alg.hash.setkey = ahash_setkey;
Horia Geant?3639ca82016-04-21 19:24:55 +03003094 t_alg->algt.alg.hash.import = ahash_import;
3095 t_alg->algt.alg.hash.export = ahash_export;
Kim Phillipsb286e002012-08-08 20:33:34 -05003096
Lee Nipper79b3a412011-11-21 16:13:25 +08003097 if (!(priv->features & TALITOS_FTR_HMAC_OK) &&
Kim Phillips0b2730d2011-12-12 14:59:10 -06003098 !strncmp(alg->cra_name, "hmac", 4)) {
3099 kfree(t_alg);
Lee Nipper79b3a412011-11-21 16:13:25 +08003100 return ERR_PTR(-ENOTSUPP);
Kim Phillips0b2730d2011-12-12 14:59:10 -06003101 }
Kim Phillips60f208d2010-05-19 19:21:53 +10003102 if (!(priv->features & TALITOS_FTR_SHA224_HWINIT) &&
Lee Nipper79b3a412011-11-21 16:13:25 +08003103 (!strcmp(alg->cra_name, "sha224") ||
3104 !strcmp(alg->cra_name, "hmac(sha224)"))) {
Kim Phillips60f208d2010-05-19 19:21:53 +10003105 t_alg->algt.alg.hash.init = ahash_init_sha224_swinit;
3106 t_alg->algt.desc_hdr_template =
3107 DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
3108 DESC_HDR_SEL0_MDEUA |
3109 DESC_HDR_MODE0_MDEU_SHA256;
3110 }
Lee Nipper497f2e62010-05-19 19:20:36 +10003111 break;
Kim Phillips1d119112010-09-23 15:55:27 +08003112 default:
3113 dev_err(dev, "unknown algorithm type %d\n", t_alg->algt.type);
Horia Geant?5fa7dad2015-05-11 20:03:24 +03003114 kfree(t_alg);
Kim Phillips1d119112010-09-23 15:55:27 +08003115 return ERR_PTR(-EINVAL);
Lee Nipperacbf7c622010-05-19 19:19:33 +10003116 }
Kim Phillips9c4a7962008-06-23 19:50:15 +08003117
Kim Phillips9c4a7962008-06-23 19:50:15 +08003118 alg->cra_module = THIS_MODULE;
LEROY Christopheb0057762016-06-06 13:20:44 +02003119 if (t_alg->algt.priority)
3120 alg->cra_priority = t_alg->algt.priority;
3121 else
3122 alg->cra_priority = TALITOS_CRA_PRIORITY;
Kim Phillips9c4a7962008-06-23 19:50:15 +08003123 alg->cra_alignmask = 0;
Kim Phillips9c4a7962008-06-23 19:50:15 +08003124 alg->cra_ctxsize = sizeof(struct talitos_ctx);
Nikos Mavrogiannopoulosd912bb72011-11-01 13:39:56 +01003125 alg->cra_flags |= CRYPTO_ALG_KERN_DRIVER_ONLY;
Kim Phillips9c4a7962008-06-23 19:50:15 +08003126
Kim Phillips9c4a7962008-06-23 19:50:15 +08003127 t_alg->dev = dev;
3128
3129 return t_alg;
3130}
3131
Kim Phillipsc3e337f2011-11-21 16:13:27 +08003132static int talitos_probe_irq(struct platform_device *ofdev)
3133{
3134 struct device *dev = &ofdev->dev;
3135 struct device_node *np = ofdev->dev.of_node;
3136 struct talitos_private *priv = dev_get_drvdata(dev);
3137 int err;
LEROY Christophedd3c0982015-04-17 16:32:13 +02003138 bool is_sec1 = has_ftr_sec1(priv);
Kim Phillipsc3e337f2011-11-21 16:13:27 +08003139
3140 priv->irq[0] = irq_of_parse_and_map(np, 0);
Kim Phillips2cdba3c2011-12-12 14:59:11 -06003141 if (!priv->irq[0]) {
Kim Phillipsc3e337f2011-11-21 16:13:27 +08003142 dev_err(dev, "failed to map irq\n");
3143 return -EINVAL;
3144 }
LEROY Christophedd3c0982015-04-17 16:32:13 +02003145 if (is_sec1) {
3146 err = request_irq(priv->irq[0], talitos1_interrupt_4ch, 0,
3147 dev_driver_string(dev), dev);
3148 goto primary_out;
3149 }
Kim Phillipsc3e337f2011-11-21 16:13:27 +08003150
3151 priv->irq[1] = irq_of_parse_and_map(np, 1);
3152
3153 /* get the primary irq line */
Kim Phillips2cdba3c2011-12-12 14:59:11 -06003154 if (!priv->irq[1]) {
LEROY Christophedd3c0982015-04-17 16:32:13 +02003155 err = request_irq(priv->irq[0], talitos2_interrupt_4ch, 0,
Kim Phillipsc3e337f2011-11-21 16:13:27 +08003156 dev_driver_string(dev), dev);
3157 goto primary_out;
3158 }
3159
LEROY Christophedd3c0982015-04-17 16:32:13 +02003160 err = request_irq(priv->irq[0], talitos2_interrupt_ch0_2, 0,
Kim Phillipsc3e337f2011-11-21 16:13:27 +08003161 dev_driver_string(dev), dev);
3162 if (err)
3163 goto primary_out;
3164
3165 /* get the secondary irq line */
LEROY Christophedd3c0982015-04-17 16:32:13 +02003166 err = request_irq(priv->irq[1], talitos2_interrupt_ch1_3, 0,
Kim Phillipsc3e337f2011-11-21 16:13:27 +08003167 dev_driver_string(dev), dev);
3168 if (err) {
3169 dev_err(dev, "failed to request secondary irq\n");
3170 irq_dispose_mapping(priv->irq[1]);
Kim Phillips2cdba3c2011-12-12 14:59:11 -06003171 priv->irq[1] = 0;
Kim Phillipsc3e337f2011-11-21 16:13:27 +08003172 }
3173
3174 return err;
3175
3176primary_out:
3177 if (err) {
3178 dev_err(dev, "failed to request primary irq\n");
3179 irq_dispose_mapping(priv->irq[0]);
Kim Phillips2cdba3c2011-12-12 14:59:11 -06003180 priv->irq[0] = 0;
Kim Phillipsc3e337f2011-11-21 16:13:27 +08003181 }
3182
3183 return err;
3184}
3185
Grant Likely1c48a5c2011-02-17 02:43:24 -07003186static int talitos_probe(struct platform_device *ofdev)
Kim Phillips9c4a7962008-06-23 19:50:15 +08003187{
3188 struct device *dev = &ofdev->dev;
Grant Likely61c7a082010-04-13 16:12:29 -07003189 struct device_node *np = ofdev->dev.of_node;
Kim Phillips9c4a7962008-06-23 19:50:15 +08003190 struct talitos_private *priv;
3191 const unsigned int *prop;
3192 int i, err;
LEROY Christophe5fa7fa12015-04-17 16:32:11 +02003193 int stride;
Kim Phillips9c4a7962008-06-23 19:50:15 +08003194
3195 priv = kzalloc(sizeof(struct talitos_private), GFP_KERNEL);
3196 if (!priv)
3197 return -ENOMEM;
3198
Kevin Haof3de9cb2014-01-28 20:17:23 +08003199 INIT_LIST_HEAD(&priv->alg_list);
3200
Kim Phillips9c4a7962008-06-23 19:50:15 +08003201 dev_set_drvdata(dev, priv);
3202
3203 priv->ofdev = ofdev;
3204
Horia Geanta511d63c2012-03-30 17:49:53 +03003205 spin_lock_init(&priv->reg_lock);
3206
Kim Phillips9c4a7962008-06-23 19:50:15 +08003207 priv->reg = of_iomap(np, 0);
3208 if (!priv->reg) {
3209 dev_err(dev, "failed to of_iomap\n");
3210 err = -ENOMEM;
3211 goto err_out;
3212 }
3213
3214 /* get SEC version capabilities from device tree */
3215 prop = of_get_property(np, "fsl,num-channels", NULL);
3216 if (prop)
3217 priv->num_channels = *prop;
3218
3219 prop = of_get_property(np, "fsl,channel-fifo-len", NULL);
3220 if (prop)
3221 priv->chfifo_len = *prop;
3222
3223 prop = of_get_property(np, "fsl,exec-units-mask", NULL);
3224 if (prop)
3225 priv->exec_units = *prop;
3226
3227 prop = of_get_property(np, "fsl,descriptor-types-mask", NULL);
3228 if (prop)
3229 priv->desc_types = *prop;
3230
3231 if (!is_power_of_2(priv->num_channels) || !priv->chfifo_len ||
3232 !priv->exec_units || !priv->desc_types) {
3233 dev_err(dev, "invalid property data in device tree node\n");
3234 err = -EINVAL;
3235 goto err_out;
3236 }
3237
Lee Nipperf3c85bc2008-07-30 16:26:57 +08003238 if (of_device_is_compatible(np, "fsl,sec3.0"))
3239 priv->features |= TALITOS_FTR_SRC_LINK_TBL_LEN_INCLUDES_EXTENT;
3240
Kim Phillipsfe5720e2008-10-12 20:33:14 +08003241 if (of_device_is_compatible(np, "fsl,sec2.1"))
Kim Phillips60f208d2010-05-19 19:21:53 +10003242 priv->features |= TALITOS_FTR_HW_AUTH_CHECK |
Lee Nipper79b3a412011-11-21 16:13:25 +08003243 TALITOS_FTR_SHA224_HWINIT |
3244 TALITOS_FTR_HMAC_OK;
Kim Phillipsfe5720e2008-10-12 20:33:14 +08003245
LEROY Christophe21590882015-04-17 16:32:05 +02003246 if (of_device_is_compatible(np, "fsl,sec1.0"))
3247 priv->features |= TALITOS_FTR_SEC1;
3248
LEROY Christophe5fa7fa12015-04-17 16:32:11 +02003249 if (of_device_is_compatible(np, "fsl,sec1.2")) {
3250 priv->reg_deu = priv->reg + TALITOS12_DEU;
3251 priv->reg_aesu = priv->reg + TALITOS12_AESU;
3252 priv->reg_mdeu = priv->reg + TALITOS12_MDEU;
3253 stride = TALITOS1_CH_STRIDE;
3254 } else if (of_device_is_compatible(np, "fsl,sec1.0")) {
3255 priv->reg_deu = priv->reg + TALITOS10_DEU;
3256 priv->reg_aesu = priv->reg + TALITOS10_AESU;
3257 priv->reg_mdeu = priv->reg + TALITOS10_MDEU;
3258 priv->reg_afeu = priv->reg + TALITOS10_AFEU;
3259 priv->reg_rngu = priv->reg + TALITOS10_RNGU;
3260 priv->reg_pkeu = priv->reg + TALITOS10_PKEU;
3261 stride = TALITOS1_CH_STRIDE;
3262 } else {
3263 priv->reg_deu = priv->reg + TALITOS2_DEU;
3264 priv->reg_aesu = priv->reg + TALITOS2_AESU;
3265 priv->reg_mdeu = priv->reg + TALITOS2_MDEU;
3266 priv->reg_afeu = priv->reg + TALITOS2_AFEU;
3267 priv->reg_rngu = priv->reg + TALITOS2_RNGU;
3268 priv->reg_pkeu = priv->reg + TALITOS2_PKEU;
3269 priv->reg_keu = priv->reg + TALITOS2_KEU;
3270 priv->reg_crcu = priv->reg + TALITOS2_CRCU;
3271 stride = TALITOS2_CH_STRIDE;
3272 }
3273
LEROY Christophedd3c0982015-04-17 16:32:13 +02003274 err = talitos_probe_irq(ofdev);
3275 if (err)
3276 goto err_out;
3277
3278 if (of_device_is_compatible(np, "fsl,sec1.0")) {
3279 tasklet_init(&priv->done_task[0], talitos1_done_4ch,
3280 (unsigned long)dev);
3281 } else {
3282 if (!priv->irq[1]) {
3283 tasklet_init(&priv->done_task[0], talitos2_done_4ch,
3284 (unsigned long)dev);
3285 } else {
3286 tasklet_init(&priv->done_task[0], talitos2_done_ch0_2,
3287 (unsigned long)dev);
3288 tasklet_init(&priv->done_task[1], talitos2_done_ch1_3,
3289 (unsigned long)dev);
3290 }
3291 }
3292
Kim Phillips4b9926282009-08-13 11:50:38 +10003293 priv->chan = kzalloc(sizeof(struct talitos_channel) *
3294 priv->num_channels, GFP_KERNEL);
3295 if (!priv->chan) {
3296 dev_err(dev, "failed to allocate channel management space\n");
Kim Phillips9c4a7962008-06-23 19:50:15 +08003297 err = -ENOMEM;
3298 goto err_out;
3299 }
3300
Martin Hicksf641ddd2015-03-03 08:21:33 -05003301 priv->fifo_len = roundup_pow_of_two(priv->chfifo_len);
3302
Kim Phillipsc3e337f2011-11-21 16:13:27 +08003303 for (i = 0; i < priv->num_channels; i++) {
LEROY Christophe5fa7fa12015-04-17 16:32:11 +02003304 priv->chan[i].reg = priv->reg + stride * (i + 1);
Kim Phillips2cdba3c2011-12-12 14:59:11 -06003305 if (!priv->irq[1] || !(i & 1))
Kim Phillipsc3e337f2011-11-21 16:13:27 +08003306 priv->chan[i].reg += TALITOS_CH_BASE_OFFSET;
Kim Phillipsad42d5f2011-11-21 16:13:27 +08003307
Kim Phillips4b9926282009-08-13 11:50:38 +10003308 spin_lock_init(&priv->chan[i].head_lock);
3309 spin_lock_init(&priv->chan[i].tail_lock);
Kim Phillips9c4a7962008-06-23 19:50:15 +08003310
Kim Phillips4b9926282009-08-13 11:50:38 +10003311 priv->chan[i].fifo = kzalloc(sizeof(struct talitos_request) *
3312 priv->fifo_len, GFP_KERNEL);
3313 if (!priv->chan[i].fifo) {
Kim Phillips9c4a7962008-06-23 19:50:15 +08003314 dev_err(dev, "failed to allocate request fifo %d\n", i);
3315 err = -ENOMEM;
3316 goto err_out;
3317 }
Kim Phillips9c4a7962008-06-23 19:50:15 +08003318
Kim Phillips4b9926282009-08-13 11:50:38 +10003319 atomic_set(&priv->chan[i].submit_count,
3320 -(priv->chfifo_len - 1));
Martin Hicksf641ddd2015-03-03 08:21:33 -05003321 }
Kim Phillips9c4a7962008-06-23 19:50:15 +08003322
Kim Phillips81eb0242009-08-13 11:51:51 +10003323 dma_set_mask(dev, DMA_BIT_MASK(36));
3324
Kim Phillips9c4a7962008-06-23 19:50:15 +08003325 /* reset and initialize the h/w */
3326 err = init_device(dev);
3327 if (err) {
3328 dev_err(dev, "failed to initialize device\n");
3329 goto err_out;
3330 }
3331
3332 /* register the RNG, if available */
3333 if (hw_supports(dev, DESC_HDR_SEL0_RNG)) {
3334 err = talitos_register_rng(dev);
3335 if (err) {
3336 dev_err(dev, "failed to register hwrng: %d\n", err);
3337 goto err_out;
3338 } else
3339 dev_info(dev, "hwrng\n");
3340 }
3341
3342 /* register crypto algorithms the device supports */
Kim Phillips9c4a7962008-06-23 19:50:15 +08003343 for (i = 0; i < ARRAY_SIZE(driver_algs); i++) {
3344 if (hw_supports(dev, driver_algs[i].desc_hdr_template)) {
3345 struct talitos_crypto_alg *t_alg;
Herbert Xuaeb4c132015-07-30 17:53:22 +08003346 struct crypto_alg *alg = NULL;
Kim Phillips9c4a7962008-06-23 19:50:15 +08003347
3348 t_alg = talitos_alg_alloc(dev, &driver_algs[i]);
3349 if (IS_ERR(t_alg)) {
3350 err = PTR_ERR(t_alg);
Kim Phillips0b2730d2011-12-12 14:59:10 -06003351 if (err == -ENOTSUPP)
Lee Nipper79b3a412011-11-21 16:13:25 +08003352 continue;
Kim Phillips9c4a7962008-06-23 19:50:15 +08003353 goto err_out;
3354 }
3355
Lee Nipperacbf7c622010-05-19 19:19:33 +10003356 switch (t_alg->algt.type) {
3357 case CRYPTO_ALG_TYPE_ABLKCIPHER:
Lee Nipperacbf7c622010-05-19 19:19:33 +10003358 err = crypto_register_alg(
3359 &t_alg->algt.alg.crypto);
Herbert Xuaeb4c132015-07-30 17:53:22 +08003360 alg = &t_alg->algt.alg.crypto;
Lee Nipperacbf7c622010-05-19 19:19:33 +10003361 break;
Herbert Xuaeb4c132015-07-30 17:53:22 +08003362
3363 case CRYPTO_ALG_TYPE_AEAD:
3364 err = crypto_register_aead(
3365 &t_alg->algt.alg.aead);
3366 alg = &t_alg->algt.alg.aead.base;
3367 break;
3368
Lee Nipperacbf7c622010-05-19 19:19:33 +10003369 case CRYPTO_ALG_TYPE_AHASH:
3370 err = crypto_register_ahash(
3371 &t_alg->algt.alg.hash);
Herbert Xuaeb4c132015-07-30 17:53:22 +08003372 alg = &t_alg->algt.alg.hash.halg.base;
Lee Nipperacbf7c622010-05-19 19:19:33 +10003373 break;
3374 }
Kim Phillips9c4a7962008-06-23 19:50:15 +08003375 if (err) {
3376 dev_err(dev, "%s alg registration failed\n",
Herbert Xuaeb4c132015-07-30 17:53:22 +08003377 alg->cra_driver_name);
Kim Phillips9c4a7962008-06-23 19:50:15 +08003378 kfree(t_alg);
Horia Geanta991155b2013-03-20 16:31:38 +02003379 } else
Kim Phillips9c4a7962008-06-23 19:50:15 +08003380 list_add_tail(&t_alg->entry, &priv->alg_list);
Kim Phillips9c4a7962008-06-23 19:50:15 +08003381 }
3382 }
Kim Phillips5b859b6e2011-11-21 16:13:26 +08003383 if (!list_empty(&priv->alg_list))
3384 dev_info(dev, "%s algorithms registered in /proc/crypto\n",
3385 (char *)of_get_property(np, "compatible", NULL));
Kim Phillips9c4a7962008-06-23 19:50:15 +08003386
3387 return 0;
3388
3389err_out:
3390 talitos_remove(ofdev);
Kim Phillips9c4a7962008-06-23 19:50:15 +08003391
3392 return err;
3393}
3394
Márton Németh6c3f9752010-01-17 21:54:01 +11003395static const struct of_device_id talitos_match[] = {
LEROY Christophe0635b7d2015-04-17 16:32:20 +02003396#ifdef CONFIG_CRYPTO_DEV_TALITOS1
3397 {
3398 .compatible = "fsl,sec1.0",
3399 },
3400#endif
3401#ifdef CONFIG_CRYPTO_DEV_TALITOS2
Kim Phillips9c4a7962008-06-23 19:50:15 +08003402 {
3403 .compatible = "fsl,sec2.0",
3404 },
LEROY Christophe0635b7d2015-04-17 16:32:20 +02003405#endif
Kim Phillips9c4a7962008-06-23 19:50:15 +08003406 {},
3407};
3408MODULE_DEVICE_TABLE(of, talitos_match);
3409
Grant Likely1c48a5c2011-02-17 02:43:24 -07003410static struct platform_driver talitos_driver = {
Grant Likely40182942010-04-13 16:13:02 -07003411 .driver = {
3412 .name = "talitos",
Grant Likely40182942010-04-13 16:13:02 -07003413 .of_match_table = talitos_match,
3414 },
Kim Phillips9c4a7962008-06-23 19:50:15 +08003415 .probe = talitos_probe,
Al Viro596f1032008-11-22 17:34:24 +00003416 .remove = talitos_remove,
Kim Phillips9c4a7962008-06-23 19:50:15 +08003417};
3418
Axel Lin741e8c22011-11-26 21:26:19 +08003419module_platform_driver(talitos_driver);
Kim Phillips9c4a7962008-06-23 19:50:15 +08003420
3421MODULE_LICENSE("GPL");
3422MODULE_AUTHOR("Kim Phillips <kim.phillips@freescale.com>");
3423MODULE_DESCRIPTION("Freescale integrated security engine (SEC) driver");