blob: bf4daac14fdf1cf36233155ff6b96670e67bfa78 [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 void *icvdata;
988
Kim Phillips19bbbc62009-03-29 15:53:59 +0800989 edesc = container_of(desc, struct talitos_edesc, desc);
990
Kim Phillips9c4a7962008-06-23 19:50:15 +0800991 ipsec_esp_unmap(dev, edesc, areq);
992
993 /* copy the generated ICV to dst */
Herbert Xuaeb4c132015-07-30 17:53:22 +0800994 if (edesc->icv_ool) {
LEROY Christophe549bd8b2016-06-06 13:20:40 +0200995 if (is_sec1)
996 icvdata = edesc->buf + areq->assoclen + areq->cryptlen;
997 else
998 icvdata = &edesc->link_tbl[edesc->src_nents +
999 edesc->dst_nents + 2];
Christophe Leroy26b269a2019-05-21 13:34:17 +00001000 sg_pcopy_from_buffer(areq->dst, edesc->dst_nents ? : 1, icvdata,
1001 authsize, areq->assoclen + areq->cryptlen);
Kim Phillips9c4a7962008-06-23 19:50:15 +08001002 }
1003
1004 kfree(edesc);
1005
1006 aead_request_complete(areq, err);
1007}
1008
Kim Phillipsfe5720e2008-10-12 20:33:14 +08001009static void ipsec_esp_decrypt_swauth_done(struct device *dev,
Kim Phillipse938e462009-03-29 15:53:23 +08001010 struct talitos_desc *desc,
1011 void *context, int err)
Kim Phillips9c4a7962008-06-23 19:50:15 +08001012{
1013 struct aead_request *req = context;
Kim Phillips9c4a7962008-06-23 19:50:15 +08001014 struct crypto_aead *authenc = crypto_aead_reqtfm(req);
Herbert Xuaeb4c132015-07-30 17:53:22 +08001015 unsigned int authsize = crypto_aead_authsize(authenc);
Kim Phillips19bbbc62009-03-29 15:53:59 +08001016 struct talitos_edesc *edesc;
Herbert Xuaeb4c132015-07-30 17:53:22 +08001017 char *oicv, *icv;
LEROY Christophe549bd8b2016-06-06 13:20:40 +02001018 struct talitos_private *priv = dev_get_drvdata(dev);
1019 bool is_sec1 = has_ftr_sec1(priv);
Kim Phillips9c4a7962008-06-23 19:50:15 +08001020
Kim Phillips19bbbc62009-03-29 15:53:59 +08001021 edesc = container_of(desc, struct talitos_edesc, desc);
1022
Kim Phillips9c4a7962008-06-23 19:50:15 +08001023 ipsec_esp_unmap(dev, edesc, req);
1024
1025 if (!err) {
Christophe Leroy26b269a2019-05-21 13:34:17 +00001026 char icvdata[SHA512_DIGEST_SIZE];
1027 int nents = edesc->dst_nents ? : 1;
1028 unsigned int len = req->assoclen + req->cryptlen;
1029
Kim Phillips9c4a7962008-06-23 19:50:15 +08001030 /* auth check */
Christophe Leroy26b269a2019-05-21 13:34:17 +00001031 if (nents > 1) {
1032 sg_pcopy_to_buffer(req->dst, nents, icvdata, authsize,
1033 len - authsize);
1034 icv = icvdata;
1035 } else {
1036 icv = (char *)sg_virt(req->dst) + len - authsize;
1037 }
Herbert Xuaeb4c132015-07-30 17:53:22 +08001038
1039 if (edesc->dma_len) {
LEROY Christophe549bd8b2016-06-06 13:20:40 +02001040 if (is_sec1)
1041 oicv = (char *)&edesc->dma_link_tbl +
1042 req->assoclen + req->cryptlen;
1043 else
1044 oicv = (char *)
1045 &edesc->link_tbl[edesc->src_nents +
Herbert Xuaeb4c132015-07-30 17:53:22 +08001046 edesc->dst_nents + 2];
1047 if (edesc->icv_ool)
1048 icv = oicv + authsize;
1049 } else
1050 oicv = (char *)&edesc->link_tbl[0];
1051
David Gstir79960942015-11-15 17:14:42 +01001052 err = crypto_memneq(oicv, icv, authsize) ? -EBADMSG : 0;
Kim Phillips9c4a7962008-06-23 19:50:15 +08001053 }
1054
1055 kfree(edesc);
1056
1057 aead_request_complete(req, err);
1058}
1059
Kim Phillipsfe5720e2008-10-12 20:33:14 +08001060static void ipsec_esp_decrypt_hwauth_done(struct device *dev,
Kim Phillipse938e462009-03-29 15:53:23 +08001061 struct talitos_desc *desc,
1062 void *context, int err)
Kim Phillipsfe5720e2008-10-12 20:33:14 +08001063{
1064 struct aead_request *req = context;
Kim Phillips19bbbc62009-03-29 15:53:59 +08001065 struct talitos_edesc *edesc;
1066
1067 edesc = container_of(desc, struct talitos_edesc, desc);
Kim Phillipsfe5720e2008-10-12 20:33:14 +08001068
1069 ipsec_esp_unmap(dev, edesc, req);
1070
1071 /* check ICV auth status */
Kim Phillipse938e462009-03-29 15:53:23 +08001072 if (!err && ((desc->hdr_lo & DESC_HDR_LO_ICCR1_MASK) !=
1073 DESC_HDR_LO_ICCR1_PASS))
1074 err = -EBADMSG;
Kim Phillipsfe5720e2008-10-12 20:33:14 +08001075
1076 kfree(edesc);
1077
1078 aead_request_complete(req, err);
1079}
1080
Kim Phillips9c4a7962008-06-23 19:50:15 +08001081/*
1082 * convert scatterlist to SEC h/w link table format
1083 * stop at cryptlen bytes
1084 */
Herbert Xuaeb4c132015-07-30 17:53:22 +08001085static int sg_to_link_tbl_offset(struct scatterlist *sg, int sg_count,
1086 unsigned int offset, int cryptlen,
1087 struct talitos_ptr *link_tbl_ptr)
Kim Phillips9c4a7962008-06-23 19:50:15 +08001088{
Lee Nipper70bcaca2008-07-03 19:08:46 +08001089 int n_sg = sg_count;
Herbert Xuaeb4c132015-07-30 17:53:22 +08001090 int count = 0;
Lee Nipper70bcaca2008-07-03 19:08:46 +08001091
Herbert Xuaeb4c132015-07-30 17:53:22 +08001092 while (cryptlen && sg && n_sg--) {
1093 unsigned int len = sg_dma_len(sg);
1094
1095 if (offset >= len) {
1096 offset -= len;
1097 goto next;
1098 }
1099
1100 len -= offset;
1101
1102 if (len > cryptlen)
1103 len = cryptlen;
1104
1105 to_talitos_ptr(link_tbl_ptr + count,
1106 sg_dma_address(sg) + offset, 0);
LEROY Christopheb096b542016-06-06 13:20:34 +02001107 to_talitos_ptr_len(link_tbl_ptr + count, len, 0);
1108 to_talitos_ptr_ext_set(link_tbl_ptr + count, 0, 0);
Herbert Xuaeb4c132015-07-30 17:53:22 +08001109 count++;
1110 cryptlen -= len;
1111 offset = 0;
1112
1113next:
Cristian Stoica5be4d4c2015-01-20 10:06:16 +02001114 sg = sg_next(sg);
Kim Phillips9c4a7962008-06-23 19:50:15 +08001115 }
1116
Kim Phillips9c4a7962008-06-23 19:50:15 +08001117 /* tag end of link table */
Herbert Xuaeb4c132015-07-30 17:53:22 +08001118 if (count > 0)
LEROY Christopheb096b542016-06-06 13:20:34 +02001119 to_talitos_ptr_ext_set(link_tbl_ptr + count - 1,
1120 DESC_PTR_LNKTBL_RETURN, 0);
Lee Nipper70bcaca2008-07-03 19:08:46 +08001121
Herbert Xuaeb4c132015-07-30 17:53:22 +08001122 return count;
1123}
1124
LEROY Christophe23fb8f72018-03-22 10:57:01 +01001125static int talitos_sg_map_ext(struct device *dev, struct scatterlist *src,
1126 unsigned int len, struct talitos_edesc *edesc,
1127 struct talitos_ptr *ptr, int sg_count,
1128 unsigned int offset, int tbl_off, int elen)
LEROY Christophe246a87c2016-06-06 13:20:36 +02001129{
LEROY Christophe246a87c2016-06-06 13:20:36 +02001130 struct talitos_private *priv = dev_get_drvdata(dev);
1131 bool is_sec1 = has_ftr_sec1(priv);
1132
LEROY Christophec4cef782018-01-26 17:09:59 +01001133 if (!src) {
1134 *ptr = zero_entry;
1135 return 1;
1136 }
1137
LEROY Christophe246a87c2016-06-06 13:20:36 +02001138 to_talitos_ptr_len(ptr, len, is_sec1);
LEROY Christophe23fb8f72018-03-22 10:57:01 +01001139 to_talitos_ptr_ext_set(ptr, elen, is_sec1);
LEROY Christophe246a87c2016-06-06 13:20:36 +02001140
LEROY Christophe6a1e8d12016-06-06 13:20:38 +02001141 if (sg_count == 1) {
1142 to_talitos_ptr(ptr, sg_dma_address(src) + offset, is_sec1);
1143 return sg_count;
LEROY Christophe246a87c2016-06-06 13:20:36 +02001144 }
LEROY Christophe6a1e8d12016-06-06 13:20:38 +02001145 if (is_sec1) {
1146 to_talitos_ptr(ptr, edesc->dma_link_tbl + offset, is_sec1);
1147 return sg_count;
1148 }
LEROY Christophe23fb8f72018-03-22 10:57:01 +01001149 sg_count = sg_to_link_tbl_offset(src, sg_count, offset, len + elen,
LEROY Christophe6a1e8d12016-06-06 13:20:38 +02001150 &edesc->link_tbl[tbl_off]);
1151 if (sg_count == 1) {
1152 /* Only one segment now, so no link tbl needed*/
1153 copy_talitos_ptr(ptr, &edesc->link_tbl[tbl_off], is_sec1);
1154 return sg_count;
1155 }
1156 to_talitos_ptr(ptr, edesc->dma_link_tbl +
1157 tbl_off * sizeof(struct talitos_ptr), is_sec1);
1158 to_talitos_ptr_ext_or(ptr, DESC_PTR_LNKTBL_JUMP, is_sec1);
1159
LEROY Christophe246a87c2016-06-06 13:20:36 +02001160 return sg_count;
1161}
1162
LEROY Christophe23fb8f72018-03-22 10:57:01 +01001163static int talitos_sg_map(struct device *dev, struct scatterlist *src,
1164 unsigned int len, struct talitos_edesc *edesc,
1165 struct talitos_ptr *ptr, int sg_count,
1166 unsigned int offset, int tbl_off)
1167{
1168 return talitos_sg_map_ext(dev, src, len, edesc, ptr, sg_count, offset,
1169 tbl_off, 0);
1170}
1171
Kim Phillips9c4a7962008-06-23 19:50:15 +08001172/*
1173 * fill in and submit ipsec_esp descriptor
1174 */
Lee Nipper56af8cd2009-03-29 15:50:50 +08001175static int ipsec_esp(struct talitos_edesc *edesc, struct aead_request *areq,
Herbert Xuaeb4c132015-07-30 17:53:22 +08001176 void (*callback)(struct device *dev,
1177 struct talitos_desc *desc,
1178 void *context, int error))
Kim Phillips9c4a7962008-06-23 19:50:15 +08001179{
1180 struct crypto_aead *aead = crypto_aead_reqtfm(areq);
Herbert Xuaeb4c132015-07-30 17:53:22 +08001181 unsigned int authsize = crypto_aead_authsize(aead);
Kim Phillips9c4a7962008-06-23 19:50:15 +08001182 struct talitos_ctx *ctx = crypto_aead_ctx(aead);
1183 struct device *dev = ctx->dev;
1184 struct talitos_desc *desc = &edesc->desc;
1185 unsigned int cryptlen = areq->cryptlen;
Kim Phillipse41256f2009-08-13 11:49:06 +10001186 unsigned int ivsize = crypto_aead_ivsize(aead);
Herbert Xuaeb4c132015-07-30 17:53:22 +08001187 int tbl_off = 0;
Kim Phillipsfa86a262008-07-17 20:20:06 +08001188 int sg_count, ret;
LEROY Christophe23fb8f72018-03-22 10:57:01 +01001189 int elen = 0;
LEROY Christophe549bd8b2016-06-06 13:20:40 +02001190 bool sync_needed = false;
1191 struct talitos_private *priv = dev_get_drvdata(dev);
1192 bool is_sec1 = has_ftr_sec1(priv);
Kim Phillips9c4a7962008-06-23 19:50:15 +08001193
1194 /* hmac key */
1195 map_single_talitos_ptr(dev, &desc->ptr[0], ctx->authkeylen, &ctx->key,
LEROY Christophea2b35aa2015-04-17 16:31:57 +02001196 DMA_TO_DEVICE);
Horia Geanta79fd31d2012-08-02 17:16:40 +03001197
LEROY Christophe549bd8b2016-06-06 13:20:40 +02001198 sg_count = edesc->src_nents ?: 1;
1199 if (is_sec1 && sg_count > 1)
1200 sg_copy_to_buffer(areq->src, sg_count, edesc->buf,
1201 areq->assoclen + cryptlen);
1202 else
1203 sg_count = dma_map_sg(dev, areq->src, sg_count,
1204 (areq->src == areq->dst) ?
1205 DMA_BIDIRECTIONAL : DMA_TO_DEVICE);
1206
Kim Phillips9c4a7962008-06-23 19:50:15 +08001207 /* hmac data */
LEROY Christophe549bd8b2016-06-06 13:20:40 +02001208 ret = talitos_sg_map(dev, areq->src, areq->assoclen, edesc,
1209 &desc->ptr[1], sg_count, 0, tbl_off);
Horia Geanta79fd31d2012-08-02 17:16:40 +03001210
LEROY Christophe549bd8b2016-06-06 13:20:40 +02001211 if (ret > 1) {
Horia Geant?340ff602016-04-19 20:33:48 +03001212 tbl_off += ret;
LEROY Christophe549bd8b2016-06-06 13:20:40 +02001213 sync_needed = true;
Horia Geanta79fd31d2012-08-02 17:16:40 +03001214 }
1215
Kim Phillips9c4a7962008-06-23 19:50:15 +08001216 /* cipher iv */
LEROY Christophe549bd8b2016-06-06 13:20:40 +02001217 if (desc->hdr & DESC_HDR_TYPE_IPSEC_ESP) {
1218 to_talitos_ptr(&desc->ptr[2], edesc->iv_dma, is_sec1);
1219 to_talitos_ptr_len(&desc->ptr[2], ivsize, is_sec1);
1220 to_talitos_ptr_ext_set(&desc->ptr[2], 0, is_sec1);
1221 } else {
1222 to_talitos_ptr(&desc->ptr[3], edesc->iv_dma, is_sec1);
1223 to_talitos_ptr_len(&desc->ptr[3], ivsize, is_sec1);
1224 to_talitos_ptr_ext_set(&desc->ptr[3], 0, is_sec1);
1225 }
Kim Phillips9c4a7962008-06-23 19:50:15 +08001226
1227 /* cipher key */
LEROY Christophe549bd8b2016-06-06 13:20:40 +02001228 if (desc->hdr & DESC_HDR_TYPE_IPSEC_ESP)
1229 map_single_talitos_ptr(dev, &desc->ptr[3], ctx->enckeylen,
1230 (char *)&ctx->key + ctx->authkeylen,
1231 DMA_TO_DEVICE);
1232 else
1233 map_single_talitos_ptr(dev, &desc->ptr[2], ctx->enckeylen,
1234 (char *)&ctx->key + ctx->authkeylen,
1235 DMA_TO_DEVICE);
Kim Phillips9c4a7962008-06-23 19:50:15 +08001236
1237 /*
1238 * cipher in
1239 * map and adjust cipher len to aead request cryptlen.
1240 * extent is bytes of HMAC postpended to ciphertext,
1241 * typically 12 for ipsec
1242 */
LEROY Christophe23fb8f72018-03-22 10:57:01 +01001243 if ((desc->hdr & DESC_HDR_TYPE_IPSEC_ESP) &&
1244 (desc->hdr & DESC_HDR_MODE1_MDEU_CICV))
1245 elen = authsize;
Kim Phillips9c4a7962008-06-23 19:50:15 +08001246
LEROY Christophe23fb8f72018-03-22 10:57:01 +01001247 ret = talitos_sg_map_ext(dev, areq->src, cryptlen, edesc, &desc->ptr[4],
1248 sg_count, areq->assoclen, tbl_off, elen);
LEROY Christophe549bd8b2016-06-06 13:20:40 +02001249
LEROY Christophebde66672017-10-06 15:04:33 +02001250 if (ret > 1) {
1251 tbl_off += ret;
LEROY Christophe549bd8b2016-06-06 13:20:40 +02001252 sync_needed = true;
Horia Geant?340ff602016-04-19 20:33:48 +03001253 }
Kim Phillips9c4a7962008-06-23 19:50:15 +08001254
1255 /* cipher out */
LEROY Christophe549bd8b2016-06-06 13:20:40 +02001256 if (areq->src != areq->dst) {
1257 sg_count = edesc->dst_nents ? : 1;
1258 if (!is_sec1 || sg_count == 1)
1259 dma_map_sg(dev, areq->dst, sg_count, DMA_FROM_DEVICE);
1260 }
Kim Phillips9c4a7962008-06-23 19:50:15 +08001261
LEROY Christophe5272b0e2017-10-06 15:04:35 +02001262 ret = talitos_sg_map(dev, areq->dst, cryptlen, edesc, &desc->ptr[5],
1263 sg_count, areq->assoclen, tbl_off);
Kim Phillips9c4a7962008-06-23 19:50:15 +08001264
LEROY Christophe549bd8b2016-06-06 13:20:40 +02001265 if (desc->hdr & DESC_HDR_TYPE_IPSEC_ESP)
1266 to_talitos_ptr_ext_or(&desc->ptr[5], authsize, is_sec1);
Herbert Xuaeb4c132015-07-30 17:53:22 +08001267
LEROY Christophe5272b0e2017-10-06 15:04:35 +02001268 /* ICV data */
1269 if (ret > 1) {
1270 tbl_off += ret;
Herbert Xuaeb4c132015-07-30 17:53:22 +08001271 edesc->icv_ool = true;
LEROY Christophe549bd8b2016-06-06 13:20:40 +02001272 sync_needed = true;
1273
1274 if (desc->hdr & DESC_HDR_TYPE_IPSEC_ESP) {
1275 struct talitos_ptr *tbl_ptr = &edesc->link_tbl[tbl_off];
1276 int offset = (edesc->src_nents + edesc->dst_nents + 2) *
1277 sizeof(struct talitos_ptr) + authsize;
1278
1279 /* Add an entry to the link table for ICV data */
LEROY Christophe5272b0e2017-10-06 15:04:35 +02001280 to_talitos_ptr_ext_set(tbl_ptr - 1, 0, is_sec1);
LEROY Christophe549bd8b2016-06-06 13:20:40 +02001281 to_talitos_ptr_ext_set(tbl_ptr, DESC_PTR_LNKTBL_RETURN,
1282 is_sec1);
1283 to_talitos_ptr_len(tbl_ptr, authsize, is_sec1);
1284
1285 /* icv data follows link tables */
1286 to_talitos_ptr(tbl_ptr, edesc->dma_link_tbl + offset,
1287 is_sec1);
LEROY Christophe5272b0e2017-10-06 15:04:35 +02001288 } else {
1289 dma_addr_t addr = edesc->dma_link_tbl;
1290
1291 if (is_sec1)
1292 addr += areq->assoclen + cryptlen;
1293 else
1294 addr += sizeof(struct talitos_ptr) * tbl_off;
1295
1296 to_talitos_ptr(&desc->ptr[6], addr, is_sec1);
1297 to_talitos_ptr_len(&desc->ptr[6], authsize, is_sec1);
1298 }
1299 } else if (!(desc->hdr & DESC_HDR_TYPE_IPSEC_ESP)) {
1300 ret = talitos_sg_map(dev, areq->dst, authsize, edesc,
1301 &desc->ptr[6], sg_count, areq->assoclen +
1302 cryptlen,
1303 tbl_off);
1304 if (ret > 1) {
1305 tbl_off += ret;
1306 edesc->icv_ool = true;
1307 sync_needed = true;
1308 } else {
1309 edesc->icv_ool = false;
LEROY Christophe549bd8b2016-06-06 13:20:40 +02001310 }
Horia Geant?340ff602016-04-19 20:33:48 +03001311 } else {
LEROY Christophe549bd8b2016-06-06 13:20:40 +02001312 edesc->icv_ool = false;
1313 }
1314
Kim Phillips9c4a7962008-06-23 19:50:15 +08001315 /* iv out */
LEROY Christophe549bd8b2016-06-06 13:20:40 +02001316 if (desc->hdr & DESC_HDR_TYPE_IPSEC_ESP)
1317 map_single_talitos_ptr(dev, &desc->ptr[6], ivsize, ctx->iv,
1318 DMA_FROM_DEVICE);
1319
1320 if (sync_needed)
1321 dma_sync_single_for_device(dev, edesc->dma_link_tbl,
1322 edesc->dma_len,
1323 DMA_BIDIRECTIONAL);
Kim Phillips9c4a7962008-06-23 19:50:15 +08001324
Kim Phillips5228f0f2011-07-15 11:21:38 +08001325 ret = talitos_submit(dev, ctx->ch, desc, callback, areq);
Kim Phillipsfa86a262008-07-17 20:20:06 +08001326 if (ret != -EINPROGRESS) {
1327 ipsec_esp_unmap(dev, edesc, areq);
1328 kfree(edesc);
1329 }
1330 return ret;
Kim Phillips9c4a7962008-06-23 19:50:15 +08001331}
1332
Kim Phillips9c4a7962008-06-23 19:50:15 +08001333/*
Lee Nipper56af8cd2009-03-29 15:50:50 +08001334 * allocate and map the extended descriptor
Kim Phillips9c4a7962008-06-23 19:50:15 +08001335 */
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001336static struct talitos_edesc *talitos_edesc_alloc(struct device *dev,
1337 struct scatterlist *src,
1338 struct scatterlist *dst,
Horia Geanta79fd31d2012-08-02 17:16:40 +03001339 u8 *iv,
1340 unsigned int assoclen,
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001341 unsigned int cryptlen,
1342 unsigned int authsize,
Horia Geanta79fd31d2012-08-02 17:16:40 +03001343 unsigned int ivsize,
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001344 int icv_stashing,
Horia Geanta62293a32013-11-28 15:11:17 +02001345 u32 cryptoflags,
1346 bool encrypt)
Kim Phillips9c4a7962008-06-23 19:50:15 +08001347{
Lee Nipper56af8cd2009-03-29 15:50:50 +08001348 struct talitos_edesc *edesc;
LEROY Christophe6a1e8d12016-06-06 13:20:38 +02001349 int src_nents, dst_nents, alloc_len, dma_len, src_len, dst_len;
Horia Geanta79fd31d2012-08-02 17:16:40 +03001350 dma_addr_t iv_dma = 0;
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001351 gfp_t flags = cryptoflags & CRYPTO_TFM_REQ_MAY_SLEEP ? GFP_KERNEL :
Kim Phillips586725f2008-07-17 20:19:18 +08001352 GFP_ATOMIC;
LEROY Christophe6f65f6a2015-04-17 16:32:15 +02001353 struct talitos_private *priv = dev_get_drvdata(dev);
1354 bool is_sec1 = has_ftr_sec1(priv);
1355 int max_len = is_sec1 ? TALITOS1_MAX_DATA_LEN : TALITOS2_MAX_DATA_LEN;
Kim Phillips9c4a7962008-06-23 19:50:15 +08001356
LEROY Christophe6f65f6a2015-04-17 16:32:15 +02001357 if (cryptlen + authsize > max_len) {
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001358 dev_err(dev, "length exceeds h/w max limit\n");
Kim Phillips9c4a7962008-06-23 19:50:15 +08001359 return ERR_PTR(-EINVAL);
1360 }
1361
Horia Geanta62293a32013-11-28 15:11:17 +02001362 if (!dst || dst == src) {
LEROY Christophe6a1e8d12016-06-06 13:20:38 +02001363 src_len = assoclen + cryptlen + authsize;
1364 src_nents = sg_nents_for_len(src, src_len);
LABBE Corentin8e409fe2015-11-04 21:13:34 +01001365 if (src_nents < 0) {
1366 dev_err(dev, "Invalid number of src SG.\n");
Christophe Leroy47fbc542019-01-08 06:56:46 +00001367 return ERR_PTR(-EINVAL);
LABBE Corentin8e409fe2015-11-04 21:13:34 +01001368 }
Horia Geanta62293a32013-11-28 15:11:17 +02001369 src_nents = (src_nents == 1) ? 0 : src_nents;
1370 dst_nents = dst ? src_nents : 0;
LEROY Christophe6a1e8d12016-06-06 13:20:38 +02001371 dst_len = 0;
Horia Geanta62293a32013-11-28 15:11:17 +02001372 } else { /* dst && dst != src*/
LEROY Christophe6a1e8d12016-06-06 13:20:38 +02001373 src_len = assoclen + cryptlen + (encrypt ? 0 : authsize);
1374 src_nents = sg_nents_for_len(src, src_len);
LABBE Corentin8e409fe2015-11-04 21:13:34 +01001375 if (src_nents < 0) {
1376 dev_err(dev, "Invalid number of src SG.\n");
Christophe Leroy47fbc542019-01-08 06:56:46 +00001377 return ERR_PTR(-EINVAL);
LABBE Corentin8e409fe2015-11-04 21:13:34 +01001378 }
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");
Christophe Leroy47fbc542019-01-08 06:56:46 +00001384 return ERR_PTR(-EINVAL);
LABBE Corentin8e409fe2015-11-04 21:13:34 +01001385 }
Horia Geanta62293a32013-11-28 15:11:17 +02001386 dst_nents = (dst_nents == 1) ? 0 : dst_nents;
Kim Phillips9c4a7962008-06-23 19:50:15 +08001387 }
1388
1389 /*
1390 * allocate space for base edesc plus the link tables,
Herbert Xuaeb4c132015-07-30 17:53:22 +08001391 * allowing for two separate entries for AD and generated ICV (+ 2),
1392 * and space for two sets of ICVs (stashed and generated)
Kim Phillips9c4a7962008-06-23 19:50:15 +08001393 */
Lee Nipper56af8cd2009-03-29 15:50:50 +08001394 alloc_len = sizeof(struct talitos_edesc);
Herbert Xuaeb4c132015-07-30 17:53:22 +08001395 if (src_nents || dst_nents) {
LEROY Christophe6f65f6a2015-04-17 16:32:15 +02001396 if (is_sec1)
LEROY Christophe6a1e8d12016-06-06 13:20:38 +02001397 dma_len = (src_nents ? src_len : 0) +
1398 (dst_nents ? dst_len : 0);
LEROY Christophe6f65f6a2015-04-17 16:32:15 +02001399 else
Herbert Xuaeb4c132015-07-30 17:53:22 +08001400 dma_len = (src_nents + dst_nents + 2) *
1401 sizeof(struct talitos_ptr) + authsize * 2;
Kim Phillips9c4a7962008-06-23 19:50:15 +08001402 alloc_len += dma_len;
1403 } else {
1404 dma_len = 0;
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001405 alloc_len += icv_stashing ? authsize : 0;
Kim Phillips9c4a7962008-06-23 19:50:15 +08001406 }
Christophe Leroyadcbf712019-01-08 06:56:48 +00001407 alloc_len += ivsize;
Kim Phillips9c4a7962008-06-23 19:50:15 +08001408
Kim Phillips586725f2008-07-17 20:19:18 +08001409 edesc = kmalloc(alloc_len, GFP_DMA | flags);
Christophe Leroy47fbc542019-01-08 06:56:46 +00001410 if (!edesc)
1411 return ERR_PTR(-ENOMEM);
Christophe Leroyadcbf712019-01-08 06:56:48 +00001412 if (ivsize) {
1413 iv = memcpy(((u8 *)edesc) + alloc_len - ivsize, iv, ivsize);
Christophe Leroy47fbc542019-01-08 06:56:46 +00001414 iv_dma = dma_map_single(dev, iv, ivsize, DMA_TO_DEVICE);
Christophe Leroyadcbf712019-01-08 06:56:48 +00001415 }
Kim Phillips9c4a7962008-06-23 19:50:15 +08001416
1417 edesc->src_nents = src_nents;
1418 edesc->dst_nents = dst_nents;
Horia Geanta79fd31d2012-08-02 17:16:40 +03001419 edesc->iv_dma = iv_dma;
Kim Phillips9c4a7962008-06-23 19:50:15 +08001420 edesc->dma_len = dma_len;
Lee Nipper497f2e62010-05-19 19:20:36 +10001421 if (dma_len)
1422 edesc->dma_link_tbl = dma_map_single(dev, &edesc->link_tbl[0],
1423 edesc->dma_len,
1424 DMA_BIDIRECTIONAL);
Kim Phillips9c4a7962008-06-23 19:50:15 +08001425
1426 return edesc;
1427}
1428
Horia Geanta79fd31d2012-08-02 17:16:40 +03001429static struct talitos_edesc *aead_edesc_alloc(struct aead_request *areq, u8 *iv,
Horia Geanta62293a32013-11-28 15:11:17 +02001430 int icv_stashing, bool encrypt)
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001431{
1432 struct crypto_aead *authenc = crypto_aead_reqtfm(areq);
Herbert Xuaeb4c132015-07-30 17:53:22 +08001433 unsigned int authsize = crypto_aead_authsize(authenc);
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001434 struct talitos_ctx *ctx = crypto_aead_ctx(authenc);
Horia Geanta79fd31d2012-08-02 17:16:40 +03001435 unsigned int ivsize = crypto_aead_ivsize(authenc);
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001436
Herbert Xuaeb4c132015-07-30 17:53:22 +08001437 return talitos_edesc_alloc(ctx->dev, areq->src, areq->dst,
Horia Geanta79fd31d2012-08-02 17:16:40 +03001438 iv, areq->assoclen, areq->cryptlen,
Herbert Xuaeb4c132015-07-30 17:53:22 +08001439 authsize, ivsize, icv_stashing,
Horia Geanta62293a32013-11-28 15:11:17 +02001440 areq->base.flags, encrypt);
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001441}
1442
Lee Nipper56af8cd2009-03-29 15:50:50 +08001443static int aead_encrypt(struct aead_request *req)
Kim Phillips9c4a7962008-06-23 19:50:15 +08001444{
1445 struct crypto_aead *authenc = crypto_aead_reqtfm(req);
1446 struct talitos_ctx *ctx = crypto_aead_ctx(authenc);
Lee Nipper56af8cd2009-03-29 15:50:50 +08001447 struct talitos_edesc *edesc;
Kim Phillips9c4a7962008-06-23 19:50:15 +08001448
1449 /* allocate extended descriptor */
Horia Geanta62293a32013-11-28 15:11:17 +02001450 edesc = aead_edesc_alloc(req, req->iv, 0, true);
Kim Phillips9c4a7962008-06-23 19:50:15 +08001451 if (IS_ERR(edesc))
1452 return PTR_ERR(edesc);
1453
1454 /* set encrypt */
Lee Nipper70bcaca2008-07-03 19:08:46 +08001455 edesc->desc.hdr = ctx->desc_hdr_template | DESC_HDR_MODE0_ENCRYPT;
Kim Phillips9c4a7962008-06-23 19:50:15 +08001456
Herbert Xuaeb4c132015-07-30 17:53:22 +08001457 return ipsec_esp(edesc, req, ipsec_esp_encrypt_done);
Kim Phillips9c4a7962008-06-23 19:50:15 +08001458}
1459
Lee Nipper56af8cd2009-03-29 15:50:50 +08001460static int aead_decrypt(struct aead_request *req)
Kim Phillips9c4a7962008-06-23 19:50:15 +08001461{
1462 struct crypto_aead *authenc = crypto_aead_reqtfm(req);
Herbert Xuaeb4c132015-07-30 17:53:22 +08001463 unsigned int authsize = crypto_aead_authsize(authenc);
Kim Phillips9c4a7962008-06-23 19:50:15 +08001464 struct talitos_ctx *ctx = crypto_aead_ctx(authenc);
Kim Phillipsfe5720e2008-10-12 20:33:14 +08001465 struct talitos_private *priv = dev_get_drvdata(ctx->dev);
Lee Nipper56af8cd2009-03-29 15:50:50 +08001466 struct talitos_edesc *edesc;
Kim Phillips9c4a7962008-06-23 19:50:15 +08001467 void *icvdata;
1468
1469 req->cryptlen -= authsize;
1470
1471 /* allocate extended descriptor */
Horia Geanta62293a32013-11-28 15:11:17 +02001472 edesc = aead_edesc_alloc(req, req->iv, 1, false);
Kim Phillips9c4a7962008-06-23 19:50:15 +08001473 if (IS_ERR(edesc))
1474 return PTR_ERR(edesc);
1475
Kim Phillipsfe5720e2008-10-12 20:33:14 +08001476 if ((priv->features & TALITOS_FTR_HW_AUTH_CHECK) &&
Kim Phillipse938e462009-03-29 15:53:23 +08001477 ((!edesc->src_nents && !edesc->dst_nents) ||
1478 priv->features & TALITOS_FTR_SRC_LINK_TBL_LEN_INCLUDES_EXTENT)) {
Kim Phillips9c4a7962008-06-23 19:50:15 +08001479
Kim Phillipsfe5720e2008-10-12 20:33:14 +08001480 /* decrypt and check the ICV */
Kim Phillipse938e462009-03-29 15:53:23 +08001481 edesc->desc.hdr = ctx->desc_hdr_template |
1482 DESC_HDR_DIR_INBOUND |
Kim Phillipsfe5720e2008-10-12 20:33:14 +08001483 DESC_HDR_MODE1_MDEU_CICV;
Kim Phillips9c4a7962008-06-23 19:50:15 +08001484
Kim Phillipsfe5720e2008-10-12 20:33:14 +08001485 /* reset integrity check result bits */
1486 edesc->desc.hdr_lo = 0;
Kim Phillips9c4a7962008-06-23 19:50:15 +08001487
Herbert Xuaeb4c132015-07-30 17:53:22 +08001488 return ipsec_esp(edesc, req, ipsec_esp_decrypt_hwauth_done);
Kim Phillipsfe5720e2008-10-12 20:33:14 +08001489 }
Kim Phillipse938e462009-03-29 15:53:23 +08001490
1491 /* Have to check the ICV with software */
1492 edesc->desc.hdr = ctx->desc_hdr_template | DESC_HDR_DIR_INBOUND;
1493
1494 /* stash incoming ICV for later cmp with ICV generated by the h/w */
1495 if (edesc->dma_len)
Herbert Xuaeb4c132015-07-30 17:53:22 +08001496 icvdata = (char *)&edesc->link_tbl[edesc->src_nents +
1497 edesc->dst_nents + 2];
Kim Phillipse938e462009-03-29 15:53:23 +08001498 else
1499 icvdata = &edesc->link_tbl[0];
1500
Christophe Leroy26b269a2019-05-21 13:34:17 +00001501 sg_pcopy_to_buffer(req->src, edesc->src_nents ? : 1, icvdata, authsize,
1502 req->assoclen + req->cryptlen - authsize);
Kim Phillipse938e462009-03-29 15:53:23 +08001503
Herbert Xuaeb4c132015-07-30 17:53:22 +08001504 return ipsec_esp(edesc, req, ipsec_esp_decrypt_swauth_done);
Kim Phillips9c4a7962008-06-23 19:50:15 +08001505}
1506
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001507static int ablkcipher_setkey(struct crypto_ablkcipher *cipher,
1508 const u8 *key, unsigned int keylen)
1509{
1510 struct talitos_ctx *ctx = crypto_ablkcipher_ctx(cipher);
LEROY Christophe552f74c2017-10-06 15:04:37 +02001511 u32 tmp[DES_EXPKEY_WORDS];
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001512
Martin Hicks2ff2cc72017-05-02 09:38:35 -04001513 if (keylen > TALITOS_MAX_KEY_SIZE) {
1514 crypto_ablkcipher_set_flags(cipher, CRYPTO_TFM_RES_BAD_KEY_LEN);
1515 return -EINVAL;
1516 }
1517
LEROY Christophe552f74c2017-10-06 15:04:37 +02001518 if (unlikely(crypto_ablkcipher_get_flags(cipher) &
1519 CRYPTO_TFM_REQ_WEAK_KEY) &&
1520 !des_ekey(tmp, key)) {
1521 crypto_ablkcipher_set_flags(cipher, CRYPTO_TFM_RES_WEAK_KEY);
1522 return -EINVAL;
1523 }
1524
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001525 memcpy(&ctx->key, key, keylen);
1526 ctx->keylen = keylen;
1527
1528 return 0;
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001529}
1530
Christophe Leroy3e2a5c12019-05-21 13:34:10 +00001531static int ablkcipher_aes_setkey(struct crypto_ablkcipher *cipher,
1532 const u8 *key, unsigned int keylen)
1533{
1534 if (keylen == AES_KEYSIZE_128 || keylen == AES_KEYSIZE_192 ||
1535 keylen == AES_KEYSIZE_256)
1536 return ablkcipher_setkey(cipher, key, keylen);
1537
1538 crypto_ablkcipher_set_flags(cipher, CRYPTO_TFM_RES_BAD_KEY_LEN);
1539
1540 return -EINVAL;
1541}
1542
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001543static void common_nonsnoop_unmap(struct device *dev,
1544 struct talitos_edesc *edesc,
1545 struct ablkcipher_request *areq)
1546{
1547 unmap_single_talitos_ptr(dev, &edesc->desc.ptr[5], DMA_FROM_DEVICE);
LEROY Christophe032d1972015-04-17 16:31:51 +02001548
LEROY Christophe6a1e8d12016-06-06 13:20:38 +02001549 talitos_sg_unmap(dev, edesc, areq->src, areq->dst, areq->nbytes, 0);
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001550 unmap_single_talitos_ptr(dev, &edesc->desc.ptr[2], DMA_TO_DEVICE);
1551 unmap_single_talitos_ptr(dev, &edesc->desc.ptr[1], DMA_TO_DEVICE);
1552
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001553 if (edesc->dma_len)
1554 dma_unmap_single(dev, edesc->dma_link_tbl, edesc->dma_len,
1555 DMA_BIDIRECTIONAL);
1556}
1557
1558static void ablkcipher_done(struct device *dev,
1559 struct talitos_desc *desc, void *context,
1560 int err)
1561{
1562 struct ablkcipher_request *areq = context;
Christophe Leroy920cceb2019-05-15 12:29:03 +00001563 struct crypto_ablkcipher *cipher = crypto_ablkcipher_reqtfm(areq);
1564 struct talitos_ctx *ctx = crypto_ablkcipher_ctx(cipher);
1565 unsigned int ivsize = crypto_ablkcipher_ivsize(cipher);
Kim Phillips19bbbc62009-03-29 15:53:59 +08001566 struct talitos_edesc *edesc;
1567
1568 edesc = container_of(desc, struct talitos_edesc, desc);
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001569
1570 common_nonsnoop_unmap(dev, edesc, areq);
Christophe Leroy920cceb2019-05-15 12:29:03 +00001571 memcpy(areq->info, ctx->iv, ivsize);
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001572
1573 kfree(edesc);
1574
1575 areq->base.complete(&areq->base, err);
1576}
1577
1578static int common_nonsnoop(struct talitos_edesc *edesc,
1579 struct ablkcipher_request *areq,
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001580 void (*callback) (struct device *dev,
1581 struct talitos_desc *desc,
1582 void *context, int error))
1583{
1584 struct crypto_ablkcipher *cipher = crypto_ablkcipher_reqtfm(areq);
1585 struct talitos_ctx *ctx = crypto_ablkcipher_ctx(cipher);
1586 struct device *dev = ctx->dev;
1587 struct talitos_desc *desc = &edesc->desc;
1588 unsigned int cryptlen = areq->nbytes;
Horia Geanta79fd31d2012-08-02 17:16:40 +03001589 unsigned int ivsize = crypto_ablkcipher_ivsize(cipher);
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001590 int sg_count, ret;
LEROY Christophe6a1e8d12016-06-06 13:20:38 +02001591 bool sync_needed = false;
LEROY Christophe922f9dc2015-04-17 16:32:07 +02001592 struct talitos_private *priv = dev_get_drvdata(dev);
1593 bool is_sec1 = has_ftr_sec1(priv);
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001594
1595 /* first DWORD empty */
LEROY Christophe2529bc32015-04-17 16:31:49 +02001596 desc->ptr[0] = zero_entry;
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001597
1598 /* cipher iv */
LEROY Christophe922f9dc2015-04-17 16:32:07 +02001599 to_talitos_ptr(&desc->ptr[1], edesc->iv_dma, is_sec1);
1600 to_talitos_ptr_len(&desc->ptr[1], ivsize, is_sec1);
LEROY Christopheb096b542016-06-06 13:20:34 +02001601 to_talitos_ptr_ext_set(&desc->ptr[1], 0, is_sec1);
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001602
1603 /* cipher key */
1604 map_single_talitos_ptr(dev, &desc->ptr[2], ctx->keylen,
LEROY Christophea2b35aa2015-04-17 16:31:57 +02001605 (char *)&ctx->key, DMA_TO_DEVICE);
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001606
LEROY Christophe6a1e8d12016-06-06 13:20:38 +02001607 sg_count = edesc->src_nents ?: 1;
1608 if (is_sec1 && sg_count > 1)
1609 sg_copy_to_buffer(areq->src, sg_count, edesc->buf,
1610 cryptlen);
1611 else
1612 sg_count = dma_map_sg(dev, areq->src, sg_count,
1613 (areq->src == areq->dst) ?
1614 DMA_BIDIRECTIONAL : DMA_TO_DEVICE);
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001615 /*
1616 * cipher in
1617 */
LEROY Christophe6a1e8d12016-06-06 13:20:38 +02001618 sg_count = talitos_sg_map(dev, areq->src, cryptlen, edesc,
1619 &desc->ptr[3], sg_count, 0, 0);
1620 if (sg_count > 1)
1621 sync_needed = true;
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001622
1623 /* cipher out */
LEROY Christophe6a1e8d12016-06-06 13:20:38 +02001624 if (areq->src != areq->dst) {
1625 sg_count = edesc->dst_nents ? : 1;
1626 if (!is_sec1 || sg_count == 1)
1627 dma_map_sg(dev, areq->dst, sg_count, DMA_FROM_DEVICE);
1628 }
1629
1630 ret = talitos_sg_map(dev, areq->dst, cryptlen, edesc, &desc->ptr[4],
1631 sg_count, 0, (edesc->src_nents + 1));
1632 if (ret > 1)
1633 sync_needed = true;
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001634
1635 /* iv out */
LEROY Christophea2b35aa2015-04-17 16:31:57 +02001636 map_single_talitos_ptr(dev, &desc->ptr[5], ivsize, ctx->iv,
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001637 DMA_FROM_DEVICE);
1638
1639 /* last DWORD empty */
LEROY Christophe2529bc32015-04-17 16:31:49 +02001640 desc->ptr[6] = zero_entry;
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001641
LEROY Christophe6a1e8d12016-06-06 13:20:38 +02001642 if (sync_needed)
1643 dma_sync_single_for_device(dev, edesc->dma_link_tbl,
1644 edesc->dma_len, DMA_BIDIRECTIONAL);
1645
Kim Phillips5228f0f2011-07-15 11:21:38 +08001646 ret = talitos_submit(dev, ctx->ch, desc, callback, areq);
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001647 if (ret != -EINPROGRESS) {
1648 common_nonsnoop_unmap(dev, edesc, areq);
1649 kfree(edesc);
1650 }
1651 return ret;
1652}
1653
Kim Phillipse938e462009-03-29 15:53:23 +08001654static struct talitos_edesc *ablkcipher_edesc_alloc(struct ablkcipher_request *
Horia Geanta62293a32013-11-28 15:11:17 +02001655 areq, bool encrypt)
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001656{
1657 struct crypto_ablkcipher *cipher = crypto_ablkcipher_reqtfm(areq);
1658 struct talitos_ctx *ctx = crypto_ablkcipher_ctx(cipher);
Horia Geanta79fd31d2012-08-02 17:16:40 +03001659 unsigned int ivsize = crypto_ablkcipher_ivsize(cipher);
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001660
Herbert Xuaeb4c132015-07-30 17:53:22 +08001661 return talitos_edesc_alloc(ctx->dev, areq->src, areq->dst,
Horia Geanta79fd31d2012-08-02 17:16:40 +03001662 areq->info, 0, areq->nbytes, 0, ivsize, 0,
Horia Geanta62293a32013-11-28 15:11:17 +02001663 areq->base.flags, encrypt);
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001664}
1665
1666static int ablkcipher_encrypt(struct ablkcipher_request *areq)
1667{
1668 struct crypto_ablkcipher *cipher = crypto_ablkcipher_reqtfm(areq);
1669 struct talitos_ctx *ctx = crypto_ablkcipher_ctx(cipher);
1670 struct talitos_edesc *edesc;
1671
1672 /* allocate extended descriptor */
Horia Geanta62293a32013-11-28 15:11:17 +02001673 edesc = ablkcipher_edesc_alloc(areq, true);
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001674 if (IS_ERR(edesc))
1675 return PTR_ERR(edesc);
1676
1677 /* set encrypt */
1678 edesc->desc.hdr = ctx->desc_hdr_template | DESC_HDR_MODE0_ENCRYPT;
1679
Kim Phillipsfebec542011-07-15 11:21:39 +08001680 return common_nonsnoop(edesc, areq, ablkcipher_done);
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001681}
1682
1683static int ablkcipher_decrypt(struct ablkcipher_request *areq)
1684{
1685 struct crypto_ablkcipher *cipher = crypto_ablkcipher_reqtfm(areq);
1686 struct talitos_ctx *ctx = crypto_ablkcipher_ctx(cipher);
1687 struct talitos_edesc *edesc;
1688
1689 /* allocate extended descriptor */
Horia Geanta62293a32013-11-28 15:11:17 +02001690 edesc = ablkcipher_edesc_alloc(areq, false);
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001691 if (IS_ERR(edesc))
1692 return PTR_ERR(edesc);
1693
1694 edesc->desc.hdr = ctx->desc_hdr_template | DESC_HDR_DIR_INBOUND;
1695
Kim Phillipsfebec542011-07-15 11:21:39 +08001696 return common_nonsnoop(edesc, areq, ablkcipher_done);
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001697}
1698
Lee Nipper497f2e62010-05-19 19:20:36 +10001699static void common_nonsnoop_hash_unmap(struct device *dev,
1700 struct talitos_edesc *edesc,
1701 struct ahash_request *areq)
1702{
1703 struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
LEROY Christophe922f9dc2015-04-17 16:32:07 +02001704 struct talitos_private *priv = dev_get_drvdata(dev);
1705 bool is_sec1 = has_ftr_sec1(priv);
Lee Nipper497f2e62010-05-19 19:20:36 +10001706
1707 unmap_single_talitos_ptr(dev, &edesc->desc.ptr[5], DMA_FROM_DEVICE);
1708
LEROY Christophe6a1e8d12016-06-06 13:20:38 +02001709 talitos_sg_unmap(dev, edesc, req_ctx->psrc, NULL, 0, 0);
LEROY Christophe032d1972015-04-17 16:31:51 +02001710
Lee Nipper497f2e62010-05-19 19:20:36 +10001711 /* When using hashctx-in, must unmap it. */
LEROY Christophe922f9dc2015-04-17 16:32:07 +02001712 if (from_talitos_ptr_len(&edesc->desc.ptr[1], is_sec1))
Lee Nipper497f2e62010-05-19 19:20:36 +10001713 unmap_single_talitos_ptr(dev, &edesc->desc.ptr[1],
1714 DMA_TO_DEVICE);
1715
LEROY Christophe922f9dc2015-04-17 16:32:07 +02001716 if (from_talitos_ptr_len(&edesc->desc.ptr[2], is_sec1))
Lee Nipper497f2e62010-05-19 19:20:36 +10001717 unmap_single_talitos_ptr(dev, &edesc->desc.ptr[2],
1718 DMA_TO_DEVICE);
1719
Lee Nipper497f2e62010-05-19 19:20:36 +10001720 if (edesc->dma_len)
1721 dma_unmap_single(dev, edesc->dma_link_tbl, edesc->dma_len,
1722 DMA_BIDIRECTIONAL);
1723
1724}
1725
1726static void ahash_done(struct device *dev,
1727 struct talitos_desc *desc, void *context,
1728 int err)
1729{
1730 struct ahash_request *areq = context;
1731 struct talitos_edesc *edesc =
1732 container_of(desc, struct talitos_edesc, desc);
1733 struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
1734
1735 if (!req_ctx->last && req_ctx->to_hash_later) {
1736 /* Position any partial block for next update/final/finup */
1737 memcpy(req_ctx->buf, req_ctx->bufnext, req_ctx->to_hash_later);
Lee Nipper5e833bc2010-06-16 15:29:15 +10001738 req_ctx->nbuf = req_ctx->to_hash_later;
Lee Nipper497f2e62010-05-19 19:20:36 +10001739 }
1740 common_nonsnoop_hash_unmap(dev, edesc, areq);
1741
1742 kfree(edesc);
1743
1744 areq->base.complete(&areq->base, err);
1745}
1746
LEROY Christophe2d029052015-04-17 16:32:18 +02001747/*
1748 * SEC1 doesn't like hashing of 0 sized message, so we do the padding
1749 * ourself and submit a padded block
1750 */
1751void talitos_handle_buggy_hash(struct talitos_ctx *ctx,
1752 struct talitos_edesc *edesc,
1753 struct talitos_ptr *ptr)
1754{
1755 static u8 padded_hash[64] = {
1756 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1757 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1758 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1759 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1760 };
1761
1762 pr_err_once("Bug in SEC1, padding ourself\n");
1763 edesc->desc.hdr &= ~DESC_HDR_MODE0_MDEU_PAD;
1764 map_single_talitos_ptr(ctx->dev, ptr, sizeof(padded_hash),
1765 (char *)padded_hash, DMA_TO_DEVICE);
1766}
1767
Lee Nipper497f2e62010-05-19 19:20:36 +10001768static int common_nonsnoop_hash(struct talitos_edesc *edesc,
1769 struct ahash_request *areq, unsigned int length,
1770 void (*callback) (struct device *dev,
1771 struct talitos_desc *desc,
1772 void *context, int error))
1773{
1774 struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq);
1775 struct talitos_ctx *ctx = crypto_ahash_ctx(tfm);
1776 struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
1777 struct device *dev = ctx->dev;
1778 struct talitos_desc *desc = &edesc->desc;
LEROY Christophe032d1972015-04-17 16:31:51 +02001779 int ret;
LEROY Christophe6a1e8d12016-06-06 13:20:38 +02001780 bool sync_needed = false;
LEROY Christophe922f9dc2015-04-17 16:32:07 +02001781 struct talitos_private *priv = dev_get_drvdata(dev);
1782 bool is_sec1 = has_ftr_sec1(priv);
LEROY Christophe6a1e8d12016-06-06 13:20:38 +02001783 int sg_count;
Lee Nipper497f2e62010-05-19 19:20:36 +10001784
1785 /* first DWORD empty */
1786 desc->ptr[0] = zero_entry;
1787
Kim Phillips60f208d2010-05-19 19:21:53 +10001788 /* hash context in */
1789 if (!req_ctx->first || req_ctx->swinit) {
Lee Nipper497f2e62010-05-19 19:20:36 +10001790 map_single_talitos_ptr(dev, &desc->ptr[1],
1791 req_ctx->hw_context_size,
LEROY Christophea2b35aa2015-04-17 16:31:57 +02001792 (char *)req_ctx->hw_context,
Lee Nipper497f2e62010-05-19 19:20:36 +10001793 DMA_TO_DEVICE);
Kim Phillips60f208d2010-05-19 19:21:53 +10001794 req_ctx->swinit = 0;
Lee Nipper497f2e62010-05-19 19:20:36 +10001795 } else {
1796 desc->ptr[1] = zero_entry;
Lee Nipper497f2e62010-05-19 19:20:36 +10001797 }
LEROY Christophe14922592017-09-13 12:44:51 +02001798 /* Indicate next op is not the first. */
1799 req_ctx->first = 0;
Lee Nipper497f2e62010-05-19 19:20:36 +10001800
1801 /* HMAC key */
1802 if (ctx->keylen)
1803 map_single_talitos_ptr(dev, &desc->ptr[2], ctx->keylen,
LEROY Christophea2b35aa2015-04-17 16:31:57 +02001804 (char *)&ctx->key, DMA_TO_DEVICE);
Lee Nipper497f2e62010-05-19 19:20:36 +10001805 else
1806 desc->ptr[2] = zero_entry;
1807
LEROY Christophe6a1e8d12016-06-06 13:20:38 +02001808 sg_count = edesc->src_nents ?: 1;
1809 if (is_sec1 && sg_count > 1)
LEROY Christopheb60f7912017-09-13 12:44:57 +02001810 sg_copy_to_buffer(req_ctx->psrc, sg_count, edesc->buf, length);
LEROY Christophe6a1e8d12016-06-06 13:20:38 +02001811 else
1812 sg_count = dma_map_sg(dev, req_ctx->psrc, sg_count,
1813 DMA_TO_DEVICE);
Lee Nipper497f2e62010-05-19 19:20:36 +10001814 /*
1815 * data in
1816 */
LEROY Christophe6a1e8d12016-06-06 13:20:38 +02001817 sg_count = talitos_sg_map(dev, req_ctx->psrc, length, edesc,
1818 &desc->ptr[3], sg_count, 0, 0);
1819 if (sg_count > 1)
1820 sync_needed = true;
Lee Nipper497f2e62010-05-19 19:20:36 +10001821
1822 /* fifth DWORD empty */
1823 desc->ptr[4] = zero_entry;
1824
1825 /* hash/HMAC out -or- hash context out */
1826 if (req_ctx->last)
1827 map_single_talitos_ptr(dev, &desc->ptr[5],
1828 crypto_ahash_digestsize(tfm),
LEROY Christophea2b35aa2015-04-17 16:31:57 +02001829 areq->result, DMA_FROM_DEVICE);
Lee Nipper497f2e62010-05-19 19:20:36 +10001830 else
1831 map_single_talitos_ptr(dev, &desc->ptr[5],
1832 req_ctx->hw_context_size,
LEROY Christophea2b35aa2015-04-17 16:31:57 +02001833 req_ctx->hw_context, DMA_FROM_DEVICE);
Lee Nipper497f2e62010-05-19 19:20:36 +10001834
1835 /* last DWORD empty */
1836 desc->ptr[6] = zero_entry;
1837
LEROY Christophe2d029052015-04-17 16:32:18 +02001838 if (is_sec1 && from_talitos_ptr_len(&desc->ptr[3], true) == 0)
1839 talitos_handle_buggy_hash(ctx, edesc, &desc->ptr[3]);
1840
LEROY Christophe6a1e8d12016-06-06 13:20:38 +02001841 if (sync_needed)
1842 dma_sync_single_for_device(dev, edesc->dma_link_tbl,
1843 edesc->dma_len, DMA_BIDIRECTIONAL);
1844
Kim Phillips5228f0f2011-07-15 11:21:38 +08001845 ret = talitos_submit(dev, ctx->ch, desc, callback, areq);
Lee Nipper497f2e62010-05-19 19:20:36 +10001846 if (ret != -EINPROGRESS) {
1847 common_nonsnoop_hash_unmap(dev, edesc, areq);
1848 kfree(edesc);
1849 }
1850 return ret;
1851}
1852
1853static struct talitos_edesc *ahash_edesc_alloc(struct ahash_request *areq,
1854 unsigned int nbytes)
1855{
1856 struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq);
1857 struct talitos_ctx *ctx = crypto_ahash_ctx(tfm);
1858 struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
1859
Herbert Xuaeb4c132015-07-30 17:53:22 +08001860 return talitos_edesc_alloc(ctx->dev, req_ctx->psrc, NULL, NULL, 0,
Horia Geanta62293a32013-11-28 15:11:17 +02001861 nbytes, 0, 0, 0, areq->base.flags, false);
Lee Nipper497f2e62010-05-19 19:20:36 +10001862}
1863
1864static int ahash_init(struct ahash_request *areq)
1865{
1866 struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq);
1867 struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
1868
1869 /* Initialize the context */
Lee Nipper5e833bc2010-06-16 15:29:15 +10001870 req_ctx->nbuf = 0;
Kim Phillips60f208d2010-05-19 19:21:53 +10001871 req_ctx->first = 1; /* first indicates h/w must init its context */
1872 req_ctx->swinit = 0; /* assume h/w init of context */
Lee Nipper497f2e62010-05-19 19:20:36 +10001873 req_ctx->hw_context_size =
1874 (crypto_ahash_digestsize(tfm) <= SHA256_DIGEST_SIZE)
1875 ? TALITOS_MDEU_CONTEXT_SIZE_MD5_SHA1_SHA256
1876 : TALITOS_MDEU_CONTEXT_SIZE_SHA384_SHA512;
1877
1878 return 0;
1879}
1880
Kim Phillips60f208d2010-05-19 19:21:53 +10001881/*
1882 * on h/w without explicit sha224 support, we initialize h/w context
1883 * manually with sha224 constants, and tell it to run sha256.
1884 */
1885static int ahash_init_sha224_swinit(struct ahash_request *areq)
1886{
1887 struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
1888
1889 ahash_init(areq);
1890 req_ctx->swinit = 1;/* prevent h/w initting context with sha256 values*/
1891
Kim Phillipsa7524472010-09-23 15:56:38 +08001892 req_ctx->hw_context[0] = SHA224_H0;
1893 req_ctx->hw_context[1] = SHA224_H1;
1894 req_ctx->hw_context[2] = SHA224_H2;
1895 req_ctx->hw_context[3] = SHA224_H3;
1896 req_ctx->hw_context[4] = SHA224_H4;
1897 req_ctx->hw_context[5] = SHA224_H5;
1898 req_ctx->hw_context[6] = SHA224_H6;
1899 req_ctx->hw_context[7] = SHA224_H7;
Kim Phillips60f208d2010-05-19 19:21:53 +10001900
1901 /* init 64-bit count */
1902 req_ctx->hw_context[8] = 0;
1903 req_ctx->hw_context[9] = 0;
1904
1905 return 0;
1906}
1907
Lee Nipper497f2e62010-05-19 19:20:36 +10001908static int ahash_process_req(struct ahash_request *areq, unsigned int nbytes)
1909{
1910 struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq);
1911 struct talitos_ctx *ctx = crypto_ahash_ctx(tfm);
1912 struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
1913 struct talitos_edesc *edesc;
1914 unsigned int blocksize =
1915 crypto_tfm_alg_blocksize(crypto_ahash_tfm(tfm));
1916 unsigned int nbytes_to_hash;
1917 unsigned int to_hash_later;
Lee Nipper5e833bc2010-06-16 15:29:15 +10001918 unsigned int nsg;
LABBE Corentin8e409fe2015-11-04 21:13:34 +01001919 int nents;
Lee Nipper497f2e62010-05-19 19:20:36 +10001920
Lee Nipper5e833bc2010-06-16 15:29:15 +10001921 if (!req_ctx->last && (nbytes + req_ctx->nbuf <= blocksize)) {
1922 /* Buffer up to one whole block */
LABBE Corentin8e409fe2015-11-04 21:13:34 +01001923 nents = sg_nents_for_len(areq->src, nbytes);
1924 if (nents < 0) {
1925 dev_err(ctx->dev, "Invalid number of src SG.\n");
1926 return nents;
1927 }
1928 sg_copy_to_buffer(areq->src, nents,
Lee Nipper5e833bc2010-06-16 15:29:15 +10001929 req_ctx->buf + req_ctx->nbuf, nbytes);
1930 req_ctx->nbuf += nbytes;
Lee Nipper497f2e62010-05-19 19:20:36 +10001931 return 0;
1932 }
1933
Lee Nipper5e833bc2010-06-16 15:29:15 +10001934 /* At least (blocksize + 1) bytes are available to hash */
1935 nbytes_to_hash = nbytes + req_ctx->nbuf;
1936 to_hash_later = nbytes_to_hash & (blocksize - 1);
1937
1938 if (req_ctx->last)
1939 to_hash_later = 0;
1940 else if (to_hash_later)
1941 /* There is a partial block. Hash the full block(s) now */
1942 nbytes_to_hash -= to_hash_later;
1943 else {
1944 /* Keep one block buffered */
1945 nbytes_to_hash -= blocksize;
1946 to_hash_later = blocksize;
1947 }
1948
1949 /* Chain in any previously buffered data */
1950 if (req_ctx->nbuf) {
1951 nsg = (req_ctx->nbuf < nbytes_to_hash) ? 2 : 1;
1952 sg_init_table(req_ctx->bufsl, nsg);
1953 sg_set_buf(req_ctx->bufsl, req_ctx->buf, req_ctx->nbuf);
1954 if (nsg > 1)
Dan Williamsc56f6d12015-08-07 18:15:13 +02001955 sg_chain(req_ctx->bufsl, 2, areq->src);
Lee Nipper497f2e62010-05-19 19:20:36 +10001956 req_ctx->psrc = req_ctx->bufsl;
Lee Nipper5e833bc2010-06-16 15:29:15 +10001957 } else
Lee Nipper497f2e62010-05-19 19:20:36 +10001958 req_ctx->psrc = areq->src;
Lee Nipper497f2e62010-05-19 19:20:36 +10001959
Lee Nipper5e833bc2010-06-16 15:29:15 +10001960 if (to_hash_later) {
LABBE Corentin8e409fe2015-11-04 21:13:34 +01001961 nents = sg_nents_for_len(areq->src, nbytes);
1962 if (nents < 0) {
1963 dev_err(ctx->dev, "Invalid number of src SG.\n");
1964 return nents;
1965 }
Akinobu Mitad0525722013-07-08 16:01:55 -07001966 sg_pcopy_to_buffer(areq->src, nents,
Lee Nipper5e833bc2010-06-16 15:29:15 +10001967 req_ctx->bufnext,
1968 to_hash_later,
1969 nbytes - to_hash_later);
Lee Nipper497f2e62010-05-19 19:20:36 +10001970 }
Lee Nipper5e833bc2010-06-16 15:29:15 +10001971 req_ctx->to_hash_later = to_hash_later;
Lee Nipper497f2e62010-05-19 19:20:36 +10001972
Lee Nipper5e833bc2010-06-16 15:29:15 +10001973 /* Allocate extended descriptor */
Lee Nipper497f2e62010-05-19 19:20:36 +10001974 edesc = ahash_edesc_alloc(areq, nbytes_to_hash);
1975 if (IS_ERR(edesc))
1976 return PTR_ERR(edesc);
1977
1978 edesc->desc.hdr = ctx->desc_hdr_template;
1979
1980 /* On last one, request SEC to pad; otherwise continue */
1981 if (req_ctx->last)
1982 edesc->desc.hdr |= DESC_HDR_MODE0_MDEU_PAD;
1983 else
1984 edesc->desc.hdr |= DESC_HDR_MODE0_MDEU_CONT;
1985
Kim Phillips60f208d2010-05-19 19:21:53 +10001986 /* request SEC to INIT hash. */
1987 if (req_ctx->first && !req_ctx->swinit)
Lee Nipper497f2e62010-05-19 19:20:36 +10001988 edesc->desc.hdr |= DESC_HDR_MODE0_MDEU_INIT;
1989
1990 /* When the tfm context has a keylen, it's an HMAC.
1991 * A first or last (ie. not middle) descriptor must request HMAC.
1992 */
1993 if (ctx->keylen && (req_ctx->first || req_ctx->last))
1994 edesc->desc.hdr |= DESC_HDR_MODE0_MDEU_HMAC;
1995
1996 return common_nonsnoop_hash(edesc, areq, nbytes_to_hash,
1997 ahash_done);
1998}
1999
2000static int ahash_update(struct ahash_request *areq)
2001{
2002 struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
2003
2004 req_ctx->last = 0;
2005
2006 return ahash_process_req(areq, areq->nbytes);
2007}
2008
2009static int ahash_final(struct ahash_request *areq)
2010{
2011 struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
2012
2013 req_ctx->last = 1;
2014
2015 return ahash_process_req(areq, 0);
2016}
2017
2018static int ahash_finup(struct ahash_request *areq)
2019{
2020 struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
2021
2022 req_ctx->last = 1;
2023
2024 return ahash_process_req(areq, areq->nbytes);
2025}
2026
2027static int ahash_digest(struct ahash_request *areq)
2028{
2029 struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
Kim Phillips60f208d2010-05-19 19:21:53 +10002030 struct crypto_ahash *ahash = crypto_ahash_reqtfm(areq);
Lee Nipper497f2e62010-05-19 19:20:36 +10002031
Kim Phillips60f208d2010-05-19 19:21:53 +10002032 ahash->init(areq);
Lee Nipper497f2e62010-05-19 19:20:36 +10002033 req_ctx->last = 1;
2034
2035 return ahash_process_req(areq, areq->nbytes);
2036}
2037
Horia Geant?3639ca82016-04-21 19:24:55 +03002038static int ahash_export(struct ahash_request *areq, void *out)
2039{
2040 struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
2041 struct talitos_export_state *export = out;
2042
2043 memcpy(export->hw_context, req_ctx->hw_context,
2044 req_ctx->hw_context_size);
2045 memcpy(export->buf, req_ctx->buf, req_ctx->nbuf);
2046 export->swinit = req_ctx->swinit;
2047 export->first = req_ctx->first;
2048 export->last = req_ctx->last;
2049 export->to_hash_later = req_ctx->to_hash_later;
2050 export->nbuf = req_ctx->nbuf;
2051
2052 return 0;
2053}
2054
2055static int ahash_import(struct ahash_request *areq, const void *in)
2056{
2057 struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
2058 struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq);
2059 const struct talitos_export_state *export = in;
2060
2061 memset(req_ctx, 0, sizeof(*req_ctx));
2062 req_ctx->hw_context_size =
2063 (crypto_ahash_digestsize(tfm) <= SHA256_DIGEST_SIZE)
2064 ? TALITOS_MDEU_CONTEXT_SIZE_MD5_SHA1_SHA256
2065 : TALITOS_MDEU_CONTEXT_SIZE_SHA384_SHA512;
2066 memcpy(req_ctx->hw_context, export->hw_context,
2067 req_ctx->hw_context_size);
2068 memcpy(req_ctx->buf, export->buf, export->nbuf);
2069 req_ctx->swinit = export->swinit;
2070 req_ctx->first = export->first;
2071 req_ctx->last = export->last;
2072 req_ctx->to_hash_later = export->to_hash_later;
2073 req_ctx->nbuf = export->nbuf;
2074
2075 return 0;
2076}
2077
Lee Nipper79b3a412011-11-21 16:13:25 +08002078struct keyhash_result {
2079 struct completion completion;
2080 int err;
2081};
2082
2083static void keyhash_complete(struct crypto_async_request *req, int err)
2084{
2085 struct keyhash_result *res = req->data;
2086
2087 if (err == -EINPROGRESS)
2088 return;
2089
2090 res->err = err;
2091 complete(&res->completion);
2092}
2093
2094static int keyhash(struct crypto_ahash *tfm, const u8 *key, unsigned int keylen,
2095 u8 *hash)
2096{
2097 struct talitos_ctx *ctx = crypto_tfm_ctx(crypto_ahash_tfm(tfm));
2098
2099 struct scatterlist sg[1];
2100 struct ahash_request *req;
2101 struct keyhash_result hresult;
2102 int ret;
2103
2104 init_completion(&hresult.completion);
2105
2106 req = ahash_request_alloc(tfm, GFP_KERNEL);
2107 if (!req)
2108 return -ENOMEM;
2109
2110 /* Keep tfm keylen == 0 during hash of the long key */
2111 ctx->keylen = 0;
2112 ahash_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
2113 keyhash_complete, &hresult);
2114
2115 sg_init_one(&sg[0], key, keylen);
2116
2117 ahash_request_set_crypt(req, sg, hash, keylen);
2118 ret = crypto_ahash_digest(req);
2119 switch (ret) {
2120 case 0:
2121 break;
2122 case -EINPROGRESS:
2123 case -EBUSY:
2124 ret = wait_for_completion_interruptible(
2125 &hresult.completion);
2126 if (!ret)
2127 ret = hresult.err;
2128 break;
2129 default:
2130 break;
2131 }
2132 ahash_request_free(req);
2133
2134 return ret;
2135}
2136
2137static int ahash_setkey(struct crypto_ahash *tfm, const u8 *key,
2138 unsigned int keylen)
2139{
2140 struct talitos_ctx *ctx = crypto_tfm_ctx(crypto_ahash_tfm(tfm));
2141 unsigned int blocksize =
2142 crypto_tfm_alg_blocksize(crypto_ahash_tfm(tfm));
2143 unsigned int digestsize = crypto_ahash_digestsize(tfm);
2144 unsigned int keysize = keylen;
2145 u8 hash[SHA512_DIGEST_SIZE];
2146 int ret;
2147
2148 if (keylen <= blocksize)
2149 memcpy(ctx->key, key, keysize);
2150 else {
2151 /* Must get the hash of the long key */
2152 ret = keyhash(tfm, key, keylen, hash);
2153
2154 if (ret) {
2155 crypto_ahash_set_flags(tfm, CRYPTO_TFM_RES_BAD_KEY_LEN);
2156 return -EINVAL;
2157 }
2158
2159 keysize = digestsize;
2160 memcpy(ctx->key, hash, digestsize);
2161 }
2162
2163 ctx->keylen = keysize;
2164
2165 return 0;
2166}
2167
2168
Kim Phillips9c4a7962008-06-23 19:50:15 +08002169struct talitos_alg_template {
Lee Nipperd5e4aae2010-05-19 19:18:38 +10002170 u32 type;
LEROY Christopheb0057762016-06-06 13:20:44 +02002171 u32 priority;
Lee Nipperd5e4aae2010-05-19 19:18:38 +10002172 union {
2173 struct crypto_alg crypto;
Lee Nipperacbf7c622010-05-19 19:19:33 +10002174 struct ahash_alg hash;
Herbert Xuaeb4c132015-07-30 17:53:22 +08002175 struct aead_alg aead;
Lee Nipperd5e4aae2010-05-19 19:18:38 +10002176 } alg;
Kim Phillips9c4a7962008-06-23 19:50:15 +08002177 __be32 desc_hdr_template;
2178};
2179
2180static struct talitos_alg_template driver_algs[] = {
Horia Geanta991155b2013-03-20 16:31:38 +02002181 /* AEAD algorithms. These use a single-pass ipsec_esp descriptor */
Lee Nipperd5e4aae2010-05-19 19:18:38 +10002182 { .type = CRYPTO_ALG_TYPE_AEAD,
Herbert Xuaeb4c132015-07-30 17:53:22 +08002183 .alg.aead = {
2184 .base = {
2185 .cra_name = "authenc(hmac(sha1),cbc(aes))",
2186 .cra_driver_name = "authenc-hmac-sha1-"
2187 "cbc-aes-talitos",
2188 .cra_blocksize = AES_BLOCK_SIZE,
2189 .cra_flags = CRYPTO_ALG_ASYNC,
2190 },
2191 .ivsize = AES_BLOCK_SIZE,
2192 .maxauthsize = SHA1_DIGEST_SIZE,
Lee Nipper56af8cd2009-03-29 15:50:50 +08002193 },
Kim Phillips9c4a7962008-06-23 19:50:15 +08002194 .desc_hdr_template = DESC_HDR_TYPE_IPSEC_ESP |
2195 DESC_HDR_SEL0_AESU |
2196 DESC_HDR_MODE0_AESU_CBC |
2197 DESC_HDR_SEL1_MDEUA |
2198 DESC_HDR_MODE1_MDEU_INIT |
2199 DESC_HDR_MODE1_MDEU_PAD |
2200 DESC_HDR_MODE1_MDEU_SHA1_HMAC,
Lee Nipper70bcaca2008-07-03 19:08:46 +08002201 },
Lee Nipperd5e4aae2010-05-19 19:18:38 +10002202 { .type = CRYPTO_ALG_TYPE_AEAD,
LEROY Christophe7405c8d2016-06-06 13:20:46 +02002203 .priority = TALITOS_CRA_PRIORITY_AEAD_HSNA,
2204 .alg.aead = {
2205 .base = {
2206 .cra_name = "authenc(hmac(sha1),cbc(aes))",
2207 .cra_driver_name = "authenc-hmac-sha1-"
Christophe Leroy0aefa742019-05-21 13:34:08 +00002208 "cbc-aes-talitos-hsna",
LEROY Christophe7405c8d2016-06-06 13:20:46 +02002209 .cra_blocksize = AES_BLOCK_SIZE,
2210 .cra_flags = CRYPTO_ALG_ASYNC,
2211 },
2212 .ivsize = AES_BLOCK_SIZE,
2213 .maxauthsize = SHA1_DIGEST_SIZE,
2214 },
2215 .desc_hdr_template = DESC_HDR_TYPE_HMAC_SNOOP_NO_AFEU |
2216 DESC_HDR_SEL0_AESU |
2217 DESC_HDR_MODE0_AESU_CBC |
2218 DESC_HDR_SEL1_MDEUA |
2219 DESC_HDR_MODE1_MDEU_INIT |
2220 DESC_HDR_MODE1_MDEU_PAD |
2221 DESC_HDR_MODE1_MDEU_SHA1_HMAC,
2222 },
2223 { .type = CRYPTO_ALG_TYPE_AEAD,
Herbert Xuaeb4c132015-07-30 17:53:22 +08002224 .alg.aead = {
2225 .base = {
2226 .cra_name = "authenc(hmac(sha1),"
2227 "cbc(des3_ede))",
2228 .cra_driver_name = "authenc-hmac-sha1-"
2229 "cbc-3des-talitos",
2230 .cra_blocksize = DES3_EDE_BLOCK_SIZE,
2231 .cra_flags = CRYPTO_ALG_ASYNC,
2232 },
2233 .ivsize = DES3_EDE_BLOCK_SIZE,
2234 .maxauthsize = SHA1_DIGEST_SIZE,
Lee Nipper56af8cd2009-03-29 15:50:50 +08002235 },
Lee Nipper70bcaca2008-07-03 19:08:46 +08002236 .desc_hdr_template = DESC_HDR_TYPE_IPSEC_ESP |
2237 DESC_HDR_SEL0_DEU |
2238 DESC_HDR_MODE0_DEU_CBC |
2239 DESC_HDR_MODE0_DEU_3DES |
2240 DESC_HDR_SEL1_MDEUA |
2241 DESC_HDR_MODE1_MDEU_INIT |
2242 DESC_HDR_MODE1_MDEU_PAD |
2243 DESC_HDR_MODE1_MDEU_SHA1_HMAC,
Lee Nipper3952f172008-07-10 18:29:18 +08002244 },
LEROY Christophe7405c8d2016-06-06 13:20:46 +02002245 { .type = CRYPTO_ALG_TYPE_AEAD,
2246 .priority = TALITOS_CRA_PRIORITY_AEAD_HSNA,
2247 .alg.aead = {
2248 .base = {
2249 .cra_name = "authenc(hmac(sha1),"
2250 "cbc(des3_ede))",
2251 .cra_driver_name = "authenc-hmac-sha1-"
Christophe Leroy0aefa742019-05-21 13:34:08 +00002252 "cbc-3des-talitos-hsna",
LEROY Christophe7405c8d2016-06-06 13:20:46 +02002253 .cra_blocksize = DES3_EDE_BLOCK_SIZE,
2254 .cra_flags = CRYPTO_ALG_ASYNC,
2255 },
2256 .ivsize = DES3_EDE_BLOCK_SIZE,
2257 .maxauthsize = SHA1_DIGEST_SIZE,
2258 },
2259 .desc_hdr_template = DESC_HDR_TYPE_HMAC_SNOOP_NO_AFEU |
2260 DESC_HDR_SEL0_DEU |
2261 DESC_HDR_MODE0_DEU_CBC |
2262 DESC_HDR_MODE0_DEU_3DES |
2263 DESC_HDR_SEL1_MDEUA |
2264 DESC_HDR_MODE1_MDEU_INIT |
2265 DESC_HDR_MODE1_MDEU_PAD |
2266 DESC_HDR_MODE1_MDEU_SHA1_HMAC,
2267 },
Horia Geanta357fb602012-07-03 19:16:53 +03002268 { .type = CRYPTO_ALG_TYPE_AEAD,
Herbert Xuaeb4c132015-07-30 17:53:22 +08002269 .alg.aead = {
2270 .base = {
2271 .cra_name = "authenc(hmac(sha224),cbc(aes))",
2272 .cra_driver_name = "authenc-hmac-sha224-"
2273 "cbc-aes-talitos",
2274 .cra_blocksize = AES_BLOCK_SIZE,
2275 .cra_flags = CRYPTO_ALG_ASYNC,
2276 },
2277 .ivsize = AES_BLOCK_SIZE,
2278 .maxauthsize = SHA224_DIGEST_SIZE,
Horia Geanta357fb602012-07-03 19:16:53 +03002279 },
2280 .desc_hdr_template = DESC_HDR_TYPE_IPSEC_ESP |
2281 DESC_HDR_SEL0_AESU |
2282 DESC_HDR_MODE0_AESU_CBC |
2283 DESC_HDR_SEL1_MDEUA |
2284 DESC_HDR_MODE1_MDEU_INIT |
2285 DESC_HDR_MODE1_MDEU_PAD |
2286 DESC_HDR_MODE1_MDEU_SHA224_HMAC,
2287 },
LEROY Christophe7405c8d2016-06-06 13:20:46 +02002288 { .type = CRYPTO_ALG_TYPE_AEAD,
2289 .priority = TALITOS_CRA_PRIORITY_AEAD_HSNA,
2290 .alg.aead = {
2291 .base = {
2292 .cra_name = "authenc(hmac(sha224),cbc(aes))",
2293 .cra_driver_name = "authenc-hmac-sha224-"
Christophe Leroy0aefa742019-05-21 13:34:08 +00002294 "cbc-aes-talitos-hsna",
LEROY Christophe7405c8d2016-06-06 13:20:46 +02002295 .cra_blocksize = AES_BLOCK_SIZE,
2296 .cra_flags = CRYPTO_ALG_ASYNC,
2297 },
2298 .ivsize = AES_BLOCK_SIZE,
2299 .maxauthsize = SHA224_DIGEST_SIZE,
2300 },
2301 .desc_hdr_template = DESC_HDR_TYPE_HMAC_SNOOP_NO_AFEU |
2302 DESC_HDR_SEL0_AESU |
2303 DESC_HDR_MODE0_AESU_CBC |
2304 DESC_HDR_SEL1_MDEUA |
2305 DESC_HDR_MODE1_MDEU_INIT |
2306 DESC_HDR_MODE1_MDEU_PAD |
2307 DESC_HDR_MODE1_MDEU_SHA224_HMAC,
2308 },
Horia Geanta357fb602012-07-03 19:16:53 +03002309 { .type = CRYPTO_ALG_TYPE_AEAD,
Herbert Xuaeb4c132015-07-30 17:53:22 +08002310 .alg.aead = {
2311 .base = {
2312 .cra_name = "authenc(hmac(sha224),"
2313 "cbc(des3_ede))",
2314 .cra_driver_name = "authenc-hmac-sha224-"
2315 "cbc-3des-talitos",
2316 .cra_blocksize = DES3_EDE_BLOCK_SIZE,
2317 .cra_flags = CRYPTO_ALG_ASYNC,
2318 },
2319 .ivsize = DES3_EDE_BLOCK_SIZE,
2320 .maxauthsize = SHA224_DIGEST_SIZE,
Horia Geanta357fb602012-07-03 19:16:53 +03002321 },
2322 .desc_hdr_template = DESC_HDR_TYPE_IPSEC_ESP |
2323 DESC_HDR_SEL0_DEU |
2324 DESC_HDR_MODE0_DEU_CBC |
2325 DESC_HDR_MODE0_DEU_3DES |
2326 DESC_HDR_SEL1_MDEUA |
2327 DESC_HDR_MODE1_MDEU_INIT |
2328 DESC_HDR_MODE1_MDEU_PAD |
2329 DESC_HDR_MODE1_MDEU_SHA224_HMAC,
2330 },
Lee Nipperd5e4aae2010-05-19 19:18:38 +10002331 { .type = CRYPTO_ALG_TYPE_AEAD,
LEROY Christophe7405c8d2016-06-06 13:20:46 +02002332 .priority = TALITOS_CRA_PRIORITY_AEAD_HSNA,
2333 .alg.aead = {
2334 .base = {
2335 .cra_name = "authenc(hmac(sha224),"
2336 "cbc(des3_ede))",
2337 .cra_driver_name = "authenc-hmac-sha224-"
Christophe Leroy0aefa742019-05-21 13:34:08 +00002338 "cbc-3des-talitos-hsna",
LEROY Christophe7405c8d2016-06-06 13:20:46 +02002339 .cra_blocksize = DES3_EDE_BLOCK_SIZE,
2340 .cra_flags = CRYPTO_ALG_ASYNC,
2341 },
2342 .ivsize = DES3_EDE_BLOCK_SIZE,
2343 .maxauthsize = SHA224_DIGEST_SIZE,
2344 },
2345 .desc_hdr_template = DESC_HDR_TYPE_HMAC_SNOOP_NO_AFEU |
2346 DESC_HDR_SEL0_DEU |
2347 DESC_HDR_MODE0_DEU_CBC |
2348 DESC_HDR_MODE0_DEU_3DES |
2349 DESC_HDR_SEL1_MDEUA |
2350 DESC_HDR_MODE1_MDEU_INIT |
2351 DESC_HDR_MODE1_MDEU_PAD |
2352 DESC_HDR_MODE1_MDEU_SHA224_HMAC,
2353 },
2354 { .type = CRYPTO_ALG_TYPE_AEAD,
Herbert Xuaeb4c132015-07-30 17:53:22 +08002355 .alg.aead = {
2356 .base = {
2357 .cra_name = "authenc(hmac(sha256),cbc(aes))",
2358 .cra_driver_name = "authenc-hmac-sha256-"
2359 "cbc-aes-talitos",
2360 .cra_blocksize = AES_BLOCK_SIZE,
2361 .cra_flags = CRYPTO_ALG_ASYNC,
2362 },
2363 .ivsize = AES_BLOCK_SIZE,
2364 .maxauthsize = SHA256_DIGEST_SIZE,
Lee Nipper56af8cd2009-03-29 15:50:50 +08002365 },
Lee Nipper3952f172008-07-10 18:29:18 +08002366 .desc_hdr_template = DESC_HDR_TYPE_IPSEC_ESP |
2367 DESC_HDR_SEL0_AESU |
2368 DESC_HDR_MODE0_AESU_CBC |
2369 DESC_HDR_SEL1_MDEUA |
2370 DESC_HDR_MODE1_MDEU_INIT |
2371 DESC_HDR_MODE1_MDEU_PAD |
2372 DESC_HDR_MODE1_MDEU_SHA256_HMAC,
2373 },
Lee Nipperd5e4aae2010-05-19 19:18:38 +10002374 { .type = CRYPTO_ALG_TYPE_AEAD,
LEROY Christophe7405c8d2016-06-06 13:20:46 +02002375 .priority = TALITOS_CRA_PRIORITY_AEAD_HSNA,
2376 .alg.aead = {
2377 .base = {
2378 .cra_name = "authenc(hmac(sha256),cbc(aes))",
2379 .cra_driver_name = "authenc-hmac-sha256-"
Christophe Leroy0aefa742019-05-21 13:34:08 +00002380 "cbc-aes-talitos-hsna",
LEROY Christophe7405c8d2016-06-06 13:20:46 +02002381 .cra_blocksize = AES_BLOCK_SIZE,
2382 .cra_flags = CRYPTO_ALG_ASYNC,
2383 },
2384 .ivsize = AES_BLOCK_SIZE,
2385 .maxauthsize = SHA256_DIGEST_SIZE,
2386 },
2387 .desc_hdr_template = DESC_HDR_TYPE_HMAC_SNOOP_NO_AFEU |
2388 DESC_HDR_SEL0_AESU |
2389 DESC_HDR_MODE0_AESU_CBC |
2390 DESC_HDR_SEL1_MDEUA |
2391 DESC_HDR_MODE1_MDEU_INIT |
2392 DESC_HDR_MODE1_MDEU_PAD |
2393 DESC_HDR_MODE1_MDEU_SHA256_HMAC,
2394 },
2395 { .type = CRYPTO_ALG_TYPE_AEAD,
Herbert Xuaeb4c132015-07-30 17:53:22 +08002396 .alg.aead = {
2397 .base = {
2398 .cra_name = "authenc(hmac(sha256),"
2399 "cbc(des3_ede))",
2400 .cra_driver_name = "authenc-hmac-sha256-"
2401 "cbc-3des-talitos",
2402 .cra_blocksize = DES3_EDE_BLOCK_SIZE,
2403 .cra_flags = CRYPTO_ALG_ASYNC,
2404 },
2405 .ivsize = DES3_EDE_BLOCK_SIZE,
2406 .maxauthsize = SHA256_DIGEST_SIZE,
Lee Nipper56af8cd2009-03-29 15:50:50 +08002407 },
Lee Nipper3952f172008-07-10 18:29:18 +08002408 .desc_hdr_template = DESC_HDR_TYPE_IPSEC_ESP |
2409 DESC_HDR_SEL0_DEU |
2410 DESC_HDR_MODE0_DEU_CBC |
2411 DESC_HDR_MODE0_DEU_3DES |
2412 DESC_HDR_SEL1_MDEUA |
2413 DESC_HDR_MODE1_MDEU_INIT |
2414 DESC_HDR_MODE1_MDEU_PAD |
2415 DESC_HDR_MODE1_MDEU_SHA256_HMAC,
2416 },
Lee Nipperd5e4aae2010-05-19 19:18:38 +10002417 { .type = CRYPTO_ALG_TYPE_AEAD,
LEROY Christophe7405c8d2016-06-06 13:20:46 +02002418 .priority = TALITOS_CRA_PRIORITY_AEAD_HSNA,
2419 .alg.aead = {
2420 .base = {
2421 .cra_name = "authenc(hmac(sha256),"
2422 "cbc(des3_ede))",
2423 .cra_driver_name = "authenc-hmac-sha256-"
Christophe Leroy0aefa742019-05-21 13:34:08 +00002424 "cbc-3des-talitos-hsna",
LEROY Christophe7405c8d2016-06-06 13:20:46 +02002425 .cra_blocksize = DES3_EDE_BLOCK_SIZE,
2426 .cra_flags = CRYPTO_ALG_ASYNC,
2427 },
2428 .ivsize = DES3_EDE_BLOCK_SIZE,
2429 .maxauthsize = SHA256_DIGEST_SIZE,
2430 },
2431 .desc_hdr_template = DESC_HDR_TYPE_HMAC_SNOOP_NO_AFEU |
2432 DESC_HDR_SEL0_DEU |
2433 DESC_HDR_MODE0_DEU_CBC |
2434 DESC_HDR_MODE0_DEU_3DES |
2435 DESC_HDR_SEL1_MDEUA |
2436 DESC_HDR_MODE1_MDEU_INIT |
2437 DESC_HDR_MODE1_MDEU_PAD |
2438 DESC_HDR_MODE1_MDEU_SHA256_HMAC,
2439 },
2440 { .type = CRYPTO_ALG_TYPE_AEAD,
Herbert Xuaeb4c132015-07-30 17:53:22 +08002441 .alg.aead = {
2442 .base = {
2443 .cra_name = "authenc(hmac(sha384),cbc(aes))",
2444 .cra_driver_name = "authenc-hmac-sha384-"
2445 "cbc-aes-talitos",
2446 .cra_blocksize = AES_BLOCK_SIZE,
2447 .cra_flags = CRYPTO_ALG_ASYNC,
2448 },
2449 .ivsize = AES_BLOCK_SIZE,
2450 .maxauthsize = SHA384_DIGEST_SIZE,
Horia Geanta357fb602012-07-03 19:16:53 +03002451 },
2452 .desc_hdr_template = DESC_HDR_TYPE_IPSEC_ESP |
2453 DESC_HDR_SEL0_AESU |
2454 DESC_HDR_MODE0_AESU_CBC |
2455 DESC_HDR_SEL1_MDEUB |
2456 DESC_HDR_MODE1_MDEU_INIT |
2457 DESC_HDR_MODE1_MDEU_PAD |
2458 DESC_HDR_MODE1_MDEUB_SHA384_HMAC,
2459 },
2460 { .type = CRYPTO_ALG_TYPE_AEAD,
Herbert Xuaeb4c132015-07-30 17:53:22 +08002461 .alg.aead = {
2462 .base = {
2463 .cra_name = "authenc(hmac(sha384),"
2464 "cbc(des3_ede))",
2465 .cra_driver_name = "authenc-hmac-sha384-"
2466 "cbc-3des-talitos",
2467 .cra_blocksize = DES3_EDE_BLOCK_SIZE,
2468 .cra_flags = CRYPTO_ALG_ASYNC,
2469 },
2470 .ivsize = DES3_EDE_BLOCK_SIZE,
2471 .maxauthsize = SHA384_DIGEST_SIZE,
Horia Geanta357fb602012-07-03 19:16:53 +03002472 },
2473 .desc_hdr_template = DESC_HDR_TYPE_IPSEC_ESP |
2474 DESC_HDR_SEL0_DEU |
2475 DESC_HDR_MODE0_DEU_CBC |
2476 DESC_HDR_MODE0_DEU_3DES |
2477 DESC_HDR_SEL1_MDEUB |
2478 DESC_HDR_MODE1_MDEU_INIT |
2479 DESC_HDR_MODE1_MDEU_PAD |
2480 DESC_HDR_MODE1_MDEUB_SHA384_HMAC,
2481 },
2482 { .type = CRYPTO_ALG_TYPE_AEAD,
Herbert Xuaeb4c132015-07-30 17:53:22 +08002483 .alg.aead = {
2484 .base = {
2485 .cra_name = "authenc(hmac(sha512),cbc(aes))",
2486 .cra_driver_name = "authenc-hmac-sha512-"
2487 "cbc-aes-talitos",
2488 .cra_blocksize = AES_BLOCK_SIZE,
2489 .cra_flags = CRYPTO_ALG_ASYNC,
2490 },
2491 .ivsize = AES_BLOCK_SIZE,
2492 .maxauthsize = SHA512_DIGEST_SIZE,
Horia Geanta357fb602012-07-03 19:16:53 +03002493 },
2494 .desc_hdr_template = DESC_HDR_TYPE_IPSEC_ESP |
2495 DESC_HDR_SEL0_AESU |
2496 DESC_HDR_MODE0_AESU_CBC |
2497 DESC_HDR_SEL1_MDEUB |
2498 DESC_HDR_MODE1_MDEU_INIT |
2499 DESC_HDR_MODE1_MDEU_PAD |
2500 DESC_HDR_MODE1_MDEUB_SHA512_HMAC,
2501 },
2502 { .type = CRYPTO_ALG_TYPE_AEAD,
Herbert Xuaeb4c132015-07-30 17:53:22 +08002503 .alg.aead = {
2504 .base = {
2505 .cra_name = "authenc(hmac(sha512),"
2506 "cbc(des3_ede))",
2507 .cra_driver_name = "authenc-hmac-sha512-"
2508 "cbc-3des-talitos",
2509 .cra_blocksize = DES3_EDE_BLOCK_SIZE,
2510 .cra_flags = CRYPTO_ALG_ASYNC,
2511 },
2512 .ivsize = DES3_EDE_BLOCK_SIZE,
2513 .maxauthsize = SHA512_DIGEST_SIZE,
Horia Geanta357fb602012-07-03 19:16:53 +03002514 },
2515 .desc_hdr_template = DESC_HDR_TYPE_IPSEC_ESP |
2516 DESC_HDR_SEL0_DEU |
2517 DESC_HDR_MODE0_DEU_CBC |
2518 DESC_HDR_MODE0_DEU_3DES |
2519 DESC_HDR_SEL1_MDEUB |
2520 DESC_HDR_MODE1_MDEU_INIT |
2521 DESC_HDR_MODE1_MDEU_PAD |
2522 DESC_HDR_MODE1_MDEUB_SHA512_HMAC,
2523 },
2524 { .type = CRYPTO_ALG_TYPE_AEAD,
Herbert Xuaeb4c132015-07-30 17:53:22 +08002525 .alg.aead = {
2526 .base = {
2527 .cra_name = "authenc(hmac(md5),cbc(aes))",
2528 .cra_driver_name = "authenc-hmac-md5-"
2529 "cbc-aes-talitos",
2530 .cra_blocksize = AES_BLOCK_SIZE,
2531 .cra_flags = CRYPTO_ALG_ASYNC,
2532 },
2533 .ivsize = AES_BLOCK_SIZE,
2534 .maxauthsize = MD5_DIGEST_SIZE,
Lee Nipper56af8cd2009-03-29 15:50:50 +08002535 },
Lee Nipper3952f172008-07-10 18:29:18 +08002536 .desc_hdr_template = DESC_HDR_TYPE_IPSEC_ESP |
2537 DESC_HDR_SEL0_AESU |
2538 DESC_HDR_MODE0_AESU_CBC |
2539 DESC_HDR_SEL1_MDEUA |
2540 DESC_HDR_MODE1_MDEU_INIT |
2541 DESC_HDR_MODE1_MDEU_PAD |
2542 DESC_HDR_MODE1_MDEU_MD5_HMAC,
2543 },
Lee Nipperd5e4aae2010-05-19 19:18:38 +10002544 { .type = CRYPTO_ALG_TYPE_AEAD,
LEROY Christophe7405c8d2016-06-06 13:20:46 +02002545 .priority = TALITOS_CRA_PRIORITY_AEAD_HSNA,
2546 .alg.aead = {
2547 .base = {
2548 .cra_name = "authenc(hmac(md5),cbc(aes))",
2549 .cra_driver_name = "authenc-hmac-md5-"
Christophe Leroy0aefa742019-05-21 13:34:08 +00002550 "cbc-aes-talitos-hsna",
LEROY Christophe7405c8d2016-06-06 13:20:46 +02002551 .cra_blocksize = AES_BLOCK_SIZE,
2552 .cra_flags = CRYPTO_ALG_ASYNC,
2553 },
2554 .ivsize = AES_BLOCK_SIZE,
2555 .maxauthsize = MD5_DIGEST_SIZE,
2556 },
2557 .desc_hdr_template = DESC_HDR_TYPE_HMAC_SNOOP_NO_AFEU |
2558 DESC_HDR_SEL0_AESU |
2559 DESC_HDR_MODE0_AESU_CBC |
2560 DESC_HDR_SEL1_MDEUA |
2561 DESC_HDR_MODE1_MDEU_INIT |
2562 DESC_HDR_MODE1_MDEU_PAD |
2563 DESC_HDR_MODE1_MDEU_MD5_HMAC,
2564 },
2565 { .type = CRYPTO_ALG_TYPE_AEAD,
Herbert Xuaeb4c132015-07-30 17:53:22 +08002566 .alg.aead = {
2567 .base = {
2568 .cra_name = "authenc(hmac(md5),cbc(des3_ede))",
2569 .cra_driver_name = "authenc-hmac-md5-"
2570 "cbc-3des-talitos",
2571 .cra_blocksize = DES3_EDE_BLOCK_SIZE,
2572 .cra_flags = CRYPTO_ALG_ASYNC,
2573 },
2574 .ivsize = DES3_EDE_BLOCK_SIZE,
2575 .maxauthsize = MD5_DIGEST_SIZE,
Lee Nipper56af8cd2009-03-29 15:50:50 +08002576 },
Lee Nipper3952f172008-07-10 18:29:18 +08002577 .desc_hdr_template = DESC_HDR_TYPE_IPSEC_ESP |
2578 DESC_HDR_SEL0_DEU |
2579 DESC_HDR_MODE0_DEU_CBC |
2580 DESC_HDR_MODE0_DEU_3DES |
2581 DESC_HDR_SEL1_MDEUA |
2582 DESC_HDR_MODE1_MDEU_INIT |
2583 DESC_HDR_MODE1_MDEU_PAD |
2584 DESC_HDR_MODE1_MDEU_MD5_HMAC,
Lee Nipper4de9d0b2009-03-29 15:52:32 +08002585 },
LEROY Christophe7405c8d2016-06-06 13:20:46 +02002586 { .type = CRYPTO_ALG_TYPE_AEAD,
2587 .priority = TALITOS_CRA_PRIORITY_AEAD_HSNA,
2588 .alg.aead = {
2589 .base = {
2590 .cra_name = "authenc(hmac(md5),cbc(des3_ede))",
2591 .cra_driver_name = "authenc-hmac-md5-"
Christophe Leroy0aefa742019-05-21 13:34:08 +00002592 "cbc-3des-talitos-hsna",
LEROY Christophe7405c8d2016-06-06 13:20:46 +02002593 .cra_blocksize = DES3_EDE_BLOCK_SIZE,
2594 .cra_flags = CRYPTO_ALG_ASYNC,
2595 },
2596 .ivsize = DES3_EDE_BLOCK_SIZE,
2597 .maxauthsize = MD5_DIGEST_SIZE,
2598 },
2599 .desc_hdr_template = DESC_HDR_TYPE_HMAC_SNOOP_NO_AFEU |
2600 DESC_HDR_SEL0_DEU |
2601 DESC_HDR_MODE0_DEU_CBC |
2602 DESC_HDR_MODE0_DEU_3DES |
2603 DESC_HDR_SEL1_MDEUA |
2604 DESC_HDR_MODE1_MDEU_INIT |
2605 DESC_HDR_MODE1_MDEU_PAD |
2606 DESC_HDR_MODE1_MDEU_MD5_HMAC,
2607 },
Lee Nipper4de9d0b2009-03-29 15:52:32 +08002608 /* ABLKCIPHER algorithms. */
Lee Nipperd5e4aae2010-05-19 19:18:38 +10002609 { .type = CRYPTO_ALG_TYPE_ABLKCIPHER,
2610 .alg.crypto = {
LEROY Christophe5e75ae12015-12-01 12:44:15 +01002611 .cra_name = "ecb(aes)",
2612 .cra_driver_name = "ecb-aes-talitos",
2613 .cra_blocksize = AES_BLOCK_SIZE,
2614 .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER |
2615 CRYPTO_ALG_ASYNC,
2616 .cra_ablkcipher = {
2617 .min_keysize = AES_MIN_KEY_SIZE,
2618 .max_keysize = AES_MAX_KEY_SIZE,
2619 .ivsize = AES_BLOCK_SIZE,
2620 }
2621 },
2622 .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
2623 DESC_HDR_SEL0_AESU,
2624 },
2625 { .type = CRYPTO_ALG_TYPE_ABLKCIPHER,
2626 .alg.crypto = {
Lee Nipper4de9d0b2009-03-29 15:52:32 +08002627 .cra_name = "cbc(aes)",
2628 .cra_driver_name = "cbc-aes-talitos",
2629 .cra_blocksize = AES_BLOCK_SIZE,
2630 .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER |
2631 CRYPTO_ALG_ASYNC,
Lee Nipper4de9d0b2009-03-29 15:52:32 +08002632 .cra_ablkcipher = {
Lee Nipper4de9d0b2009-03-29 15:52:32 +08002633 .min_keysize = AES_MIN_KEY_SIZE,
2634 .max_keysize = AES_MAX_KEY_SIZE,
2635 .ivsize = AES_BLOCK_SIZE,
Christophe Leroy3e2a5c12019-05-21 13:34:10 +00002636 .setkey = ablkcipher_aes_setkey,
Lee Nipper4de9d0b2009-03-29 15:52:32 +08002637 }
2638 },
2639 .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
2640 DESC_HDR_SEL0_AESU |
2641 DESC_HDR_MODE0_AESU_CBC,
2642 },
Lee Nipperd5e4aae2010-05-19 19:18:38 +10002643 { .type = CRYPTO_ALG_TYPE_ABLKCIPHER,
2644 .alg.crypto = {
LEROY Christophe5e75ae12015-12-01 12:44:15 +01002645 .cra_name = "ctr(aes)",
2646 .cra_driver_name = "ctr-aes-talitos",
Christophe Leroyf065ad32019-05-21 13:34:11 +00002647 .cra_blocksize = 1,
LEROY Christophe5e75ae12015-12-01 12:44:15 +01002648 .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER |
2649 CRYPTO_ALG_ASYNC,
2650 .cra_ablkcipher = {
2651 .min_keysize = AES_MIN_KEY_SIZE,
2652 .max_keysize = AES_MAX_KEY_SIZE,
2653 .ivsize = AES_BLOCK_SIZE,
Christophe Leroy3e2a5c12019-05-21 13:34:10 +00002654 .setkey = ablkcipher_aes_setkey,
LEROY Christophe5e75ae12015-12-01 12:44:15 +01002655 }
2656 },
LEROY Christophe47ab7202017-10-06 15:04:43 +02002657 .desc_hdr_template = DESC_HDR_TYPE_AESU_CTR_NONSNOOP |
LEROY Christophe5e75ae12015-12-01 12:44:15 +01002658 DESC_HDR_SEL0_AESU |
2659 DESC_HDR_MODE0_AESU_CTR,
2660 },
2661 { .type = CRYPTO_ALG_TYPE_ABLKCIPHER,
2662 .alg.crypto = {
2663 .cra_name = "ecb(des)",
2664 .cra_driver_name = "ecb-des-talitos",
2665 .cra_blocksize = DES_BLOCK_SIZE,
2666 .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER |
2667 CRYPTO_ALG_ASYNC,
2668 .cra_ablkcipher = {
2669 .min_keysize = DES_KEY_SIZE,
2670 .max_keysize = DES_KEY_SIZE,
2671 .ivsize = DES_BLOCK_SIZE,
2672 }
2673 },
2674 .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
2675 DESC_HDR_SEL0_DEU,
2676 },
2677 { .type = CRYPTO_ALG_TYPE_ABLKCIPHER,
2678 .alg.crypto = {
2679 .cra_name = "cbc(des)",
2680 .cra_driver_name = "cbc-des-talitos",
2681 .cra_blocksize = DES_BLOCK_SIZE,
2682 .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER |
2683 CRYPTO_ALG_ASYNC,
2684 .cra_ablkcipher = {
2685 .min_keysize = DES_KEY_SIZE,
2686 .max_keysize = DES_KEY_SIZE,
2687 .ivsize = DES_BLOCK_SIZE,
2688 }
2689 },
2690 .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
2691 DESC_HDR_SEL0_DEU |
2692 DESC_HDR_MODE0_DEU_CBC,
2693 },
2694 { .type = CRYPTO_ALG_TYPE_ABLKCIPHER,
2695 .alg.crypto = {
2696 .cra_name = "ecb(des3_ede)",
2697 .cra_driver_name = "ecb-3des-talitos",
2698 .cra_blocksize = DES3_EDE_BLOCK_SIZE,
2699 .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER |
2700 CRYPTO_ALG_ASYNC,
2701 .cra_ablkcipher = {
2702 .min_keysize = DES3_EDE_KEY_SIZE,
2703 .max_keysize = DES3_EDE_KEY_SIZE,
2704 .ivsize = DES3_EDE_BLOCK_SIZE,
2705 }
2706 },
2707 .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
2708 DESC_HDR_SEL0_DEU |
2709 DESC_HDR_MODE0_DEU_3DES,
2710 },
2711 { .type = CRYPTO_ALG_TYPE_ABLKCIPHER,
2712 .alg.crypto = {
Lee Nipper4de9d0b2009-03-29 15:52:32 +08002713 .cra_name = "cbc(des3_ede)",
2714 .cra_driver_name = "cbc-3des-talitos",
2715 .cra_blocksize = DES3_EDE_BLOCK_SIZE,
2716 .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER |
2717 CRYPTO_ALG_ASYNC,
Lee Nipper4de9d0b2009-03-29 15:52:32 +08002718 .cra_ablkcipher = {
Lee Nipper4de9d0b2009-03-29 15:52:32 +08002719 .min_keysize = DES3_EDE_KEY_SIZE,
2720 .max_keysize = DES3_EDE_KEY_SIZE,
2721 .ivsize = DES3_EDE_BLOCK_SIZE,
2722 }
2723 },
2724 .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
2725 DESC_HDR_SEL0_DEU |
2726 DESC_HDR_MODE0_DEU_CBC |
2727 DESC_HDR_MODE0_DEU_3DES,
Lee Nipper497f2e62010-05-19 19:20:36 +10002728 },
2729 /* AHASH algorithms. */
2730 { .type = CRYPTO_ALG_TYPE_AHASH,
2731 .alg.hash = {
Lee Nipper497f2e62010-05-19 19:20:36 +10002732 .halg.digestsize = MD5_DIGEST_SIZE,
Horia Geant?3639ca82016-04-21 19:24:55 +03002733 .halg.statesize = sizeof(struct talitos_export_state),
Lee Nipper497f2e62010-05-19 19:20:36 +10002734 .halg.base = {
2735 .cra_name = "md5",
2736 .cra_driver_name = "md5-talitos",
Martin Hicksb3988612015-03-03 08:21:34 -05002737 .cra_blocksize = MD5_HMAC_BLOCK_SIZE,
Lee Nipper497f2e62010-05-19 19:20:36 +10002738 .cra_flags = CRYPTO_ALG_TYPE_AHASH |
2739 CRYPTO_ALG_ASYNC,
Lee Nipper497f2e62010-05-19 19:20:36 +10002740 }
2741 },
2742 .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
2743 DESC_HDR_SEL0_MDEUA |
2744 DESC_HDR_MODE0_MDEU_MD5,
2745 },
2746 { .type = CRYPTO_ALG_TYPE_AHASH,
2747 .alg.hash = {
Lee Nipper497f2e62010-05-19 19:20:36 +10002748 .halg.digestsize = SHA1_DIGEST_SIZE,
Horia Geant?3639ca82016-04-21 19:24:55 +03002749 .halg.statesize = sizeof(struct talitos_export_state),
Lee Nipper497f2e62010-05-19 19:20:36 +10002750 .halg.base = {
2751 .cra_name = "sha1",
2752 .cra_driver_name = "sha1-talitos",
2753 .cra_blocksize = SHA1_BLOCK_SIZE,
2754 .cra_flags = CRYPTO_ALG_TYPE_AHASH |
2755 CRYPTO_ALG_ASYNC,
Lee Nipper497f2e62010-05-19 19:20:36 +10002756 }
2757 },
2758 .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
2759 DESC_HDR_SEL0_MDEUA |
2760 DESC_HDR_MODE0_MDEU_SHA1,
2761 },
2762 { .type = CRYPTO_ALG_TYPE_AHASH,
2763 .alg.hash = {
Kim Phillips60f208d2010-05-19 19:21:53 +10002764 .halg.digestsize = SHA224_DIGEST_SIZE,
Horia Geant?3639ca82016-04-21 19:24:55 +03002765 .halg.statesize = sizeof(struct talitos_export_state),
Kim Phillips60f208d2010-05-19 19:21:53 +10002766 .halg.base = {
2767 .cra_name = "sha224",
2768 .cra_driver_name = "sha224-talitos",
2769 .cra_blocksize = SHA224_BLOCK_SIZE,
2770 .cra_flags = CRYPTO_ALG_TYPE_AHASH |
2771 CRYPTO_ALG_ASYNC,
Kim Phillips60f208d2010-05-19 19:21:53 +10002772 }
2773 },
2774 .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
2775 DESC_HDR_SEL0_MDEUA |
2776 DESC_HDR_MODE0_MDEU_SHA224,
2777 },
2778 { .type = CRYPTO_ALG_TYPE_AHASH,
2779 .alg.hash = {
Lee Nipper497f2e62010-05-19 19:20:36 +10002780 .halg.digestsize = SHA256_DIGEST_SIZE,
Horia Geant?3639ca82016-04-21 19:24:55 +03002781 .halg.statesize = sizeof(struct talitos_export_state),
Lee Nipper497f2e62010-05-19 19:20:36 +10002782 .halg.base = {
2783 .cra_name = "sha256",
2784 .cra_driver_name = "sha256-talitos",
2785 .cra_blocksize = SHA256_BLOCK_SIZE,
2786 .cra_flags = CRYPTO_ALG_TYPE_AHASH |
2787 CRYPTO_ALG_ASYNC,
Lee Nipper497f2e62010-05-19 19:20:36 +10002788 }
2789 },
2790 .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
2791 DESC_HDR_SEL0_MDEUA |
2792 DESC_HDR_MODE0_MDEU_SHA256,
2793 },
2794 { .type = CRYPTO_ALG_TYPE_AHASH,
2795 .alg.hash = {
Lee Nipper497f2e62010-05-19 19:20:36 +10002796 .halg.digestsize = SHA384_DIGEST_SIZE,
Horia Geant?3639ca82016-04-21 19:24:55 +03002797 .halg.statesize = sizeof(struct talitos_export_state),
Lee Nipper497f2e62010-05-19 19:20:36 +10002798 .halg.base = {
2799 .cra_name = "sha384",
2800 .cra_driver_name = "sha384-talitos",
2801 .cra_blocksize = SHA384_BLOCK_SIZE,
2802 .cra_flags = CRYPTO_ALG_TYPE_AHASH |
2803 CRYPTO_ALG_ASYNC,
Lee Nipper497f2e62010-05-19 19:20:36 +10002804 }
2805 },
2806 .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
2807 DESC_HDR_SEL0_MDEUB |
2808 DESC_HDR_MODE0_MDEUB_SHA384,
2809 },
2810 { .type = CRYPTO_ALG_TYPE_AHASH,
2811 .alg.hash = {
Lee Nipper497f2e62010-05-19 19:20:36 +10002812 .halg.digestsize = SHA512_DIGEST_SIZE,
Horia Geant?3639ca82016-04-21 19:24:55 +03002813 .halg.statesize = sizeof(struct talitos_export_state),
Lee Nipper497f2e62010-05-19 19:20:36 +10002814 .halg.base = {
2815 .cra_name = "sha512",
2816 .cra_driver_name = "sha512-talitos",
2817 .cra_blocksize = SHA512_BLOCK_SIZE,
2818 .cra_flags = CRYPTO_ALG_TYPE_AHASH |
2819 CRYPTO_ALG_ASYNC,
Lee Nipper497f2e62010-05-19 19:20:36 +10002820 }
2821 },
2822 .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
2823 DESC_HDR_SEL0_MDEUB |
2824 DESC_HDR_MODE0_MDEUB_SHA512,
2825 },
Lee Nipper79b3a412011-11-21 16:13:25 +08002826 { .type = CRYPTO_ALG_TYPE_AHASH,
2827 .alg.hash = {
Lee Nipper79b3a412011-11-21 16:13:25 +08002828 .halg.digestsize = MD5_DIGEST_SIZE,
Horia Geant?3639ca82016-04-21 19:24:55 +03002829 .halg.statesize = sizeof(struct talitos_export_state),
Lee Nipper79b3a412011-11-21 16:13:25 +08002830 .halg.base = {
2831 .cra_name = "hmac(md5)",
2832 .cra_driver_name = "hmac-md5-talitos",
Martin Hicksb3988612015-03-03 08:21:34 -05002833 .cra_blocksize = MD5_HMAC_BLOCK_SIZE,
Lee Nipper79b3a412011-11-21 16:13:25 +08002834 .cra_flags = CRYPTO_ALG_TYPE_AHASH |
2835 CRYPTO_ALG_ASYNC,
Lee Nipper79b3a412011-11-21 16:13:25 +08002836 }
2837 },
2838 .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
2839 DESC_HDR_SEL0_MDEUA |
2840 DESC_HDR_MODE0_MDEU_MD5,
2841 },
2842 { .type = CRYPTO_ALG_TYPE_AHASH,
2843 .alg.hash = {
Lee Nipper79b3a412011-11-21 16:13:25 +08002844 .halg.digestsize = SHA1_DIGEST_SIZE,
Horia Geant?3639ca82016-04-21 19:24:55 +03002845 .halg.statesize = sizeof(struct talitos_export_state),
Lee Nipper79b3a412011-11-21 16:13:25 +08002846 .halg.base = {
2847 .cra_name = "hmac(sha1)",
2848 .cra_driver_name = "hmac-sha1-talitos",
2849 .cra_blocksize = SHA1_BLOCK_SIZE,
2850 .cra_flags = CRYPTO_ALG_TYPE_AHASH |
2851 CRYPTO_ALG_ASYNC,
Lee Nipper79b3a412011-11-21 16:13:25 +08002852 }
2853 },
2854 .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
2855 DESC_HDR_SEL0_MDEUA |
2856 DESC_HDR_MODE0_MDEU_SHA1,
2857 },
2858 { .type = CRYPTO_ALG_TYPE_AHASH,
2859 .alg.hash = {
Lee Nipper79b3a412011-11-21 16:13:25 +08002860 .halg.digestsize = SHA224_DIGEST_SIZE,
Horia Geant?3639ca82016-04-21 19:24:55 +03002861 .halg.statesize = sizeof(struct talitos_export_state),
Lee Nipper79b3a412011-11-21 16:13:25 +08002862 .halg.base = {
2863 .cra_name = "hmac(sha224)",
2864 .cra_driver_name = "hmac-sha224-talitos",
2865 .cra_blocksize = SHA224_BLOCK_SIZE,
2866 .cra_flags = CRYPTO_ALG_TYPE_AHASH |
2867 CRYPTO_ALG_ASYNC,
Lee Nipper79b3a412011-11-21 16:13:25 +08002868 }
2869 },
2870 .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
2871 DESC_HDR_SEL0_MDEUA |
2872 DESC_HDR_MODE0_MDEU_SHA224,
2873 },
2874 { .type = CRYPTO_ALG_TYPE_AHASH,
2875 .alg.hash = {
Lee Nipper79b3a412011-11-21 16:13:25 +08002876 .halg.digestsize = SHA256_DIGEST_SIZE,
Horia Geant?3639ca82016-04-21 19:24:55 +03002877 .halg.statesize = sizeof(struct talitos_export_state),
Lee Nipper79b3a412011-11-21 16:13:25 +08002878 .halg.base = {
2879 .cra_name = "hmac(sha256)",
2880 .cra_driver_name = "hmac-sha256-talitos",
2881 .cra_blocksize = SHA256_BLOCK_SIZE,
2882 .cra_flags = CRYPTO_ALG_TYPE_AHASH |
2883 CRYPTO_ALG_ASYNC,
Lee Nipper79b3a412011-11-21 16:13:25 +08002884 }
2885 },
2886 .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
2887 DESC_HDR_SEL0_MDEUA |
2888 DESC_HDR_MODE0_MDEU_SHA256,
2889 },
2890 { .type = CRYPTO_ALG_TYPE_AHASH,
2891 .alg.hash = {
Lee Nipper79b3a412011-11-21 16:13:25 +08002892 .halg.digestsize = SHA384_DIGEST_SIZE,
Horia Geant?3639ca82016-04-21 19:24:55 +03002893 .halg.statesize = sizeof(struct talitos_export_state),
Lee Nipper79b3a412011-11-21 16:13:25 +08002894 .halg.base = {
2895 .cra_name = "hmac(sha384)",
2896 .cra_driver_name = "hmac-sha384-talitos",
2897 .cra_blocksize = SHA384_BLOCK_SIZE,
2898 .cra_flags = CRYPTO_ALG_TYPE_AHASH |
2899 CRYPTO_ALG_ASYNC,
Lee Nipper79b3a412011-11-21 16:13:25 +08002900 }
2901 },
2902 .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
2903 DESC_HDR_SEL0_MDEUB |
2904 DESC_HDR_MODE0_MDEUB_SHA384,
2905 },
2906 { .type = CRYPTO_ALG_TYPE_AHASH,
2907 .alg.hash = {
Lee Nipper79b3a412011-11-21 16:13:25 +08002908 .halg.digestsize = SHA512_DIGEST_SIZE,
Horia Geant?3639ca82016-04-21 19:24:55 +03002909 .halg.statesize = sizeof(struct talitos_export_state),
Lee Nipper79b3a412011-11-21 16:13:25 +08002910 .halg.base = {
2911 .cra_name = "hmac(sha512)",
2912 .cra_driver_name = "hmac-sha512-talitos",
2913 .cra_blocksize = SHA512_BLOCK_SIZE,
2914 .cra_flags = CRYPTO_ALG_TYPE_AHASH |
2915 CRYPTO_ALG_ASYNC,
Lee Nipper79b3a412011-11-21 16:13:25 +08002916 }
2917 },
2918 .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
2919 DESC_HDR_SEL0_MDEUB |
2920 DESC_HDR_MODE0_MDEUB_SHA512,
2921 }
Kim Phillips9c4a7962008-06-23 19:50:15 +08002922};
2923
2924struct talitos_crypto_alg {
2925 struct list_head entry;
2926 struct device *dev;
Lee Nipperacbf7c622010-05-19 19:19:33 +10002927 struct talitos_alg_template algt;
Kim Phillips9c4a7962008-06-23 19:50:15 +08002928};
2929
Jonas Eymann89d124c2016-04-19 20:33:47 +03002930static int talitos_init_common(struct talitos_ctx *ctx,
2931 struct talitos_crypto_alg *talitos_alg)
Kim Phillips9c4a7962008-06-23 19:50:15 +08002932{
Kim Phillips5228f0f2011-07-15 11:21:38 +08002933 struct talitos_private *priv;
Kim Phillips9c4a7962008-06-23 19:50:15 +08002934
2935 /* update context with ptr to dev */
2936 ctx->dev = talitos_alg->dev;
Kim Phillips19bbbc62009-03-29 15:53:59 +08002937
Kim Phillips5228f0f2011-07-15 11:21:38 +08002938 /* assign SEC channel to tfm in round-robin fashion */
2939 priv = dev_get_drvdata(ctx->dev);
2940 ctx->ch = atomic_inc_return(&priv->last_chan) &
2941 (priv->num_channels - 1);
2942
Kim Phillips9c4a7962008-06-23 19:50:15 +08002943 /* copy descriptor header template value */
Lee Nipperacbf7c622010-05-19 19:19:33 +10002944 ctx->desc_hdr_template = talitos_alg->algt.desc_hdr_template;
Kim Phillips9c4a7962008-06-23 19:50:15 +08002945
Kim Phillips602dba52011-07-15 11:21:39 +08002946 /* select done notification */
2947 ctx->desc_hdr_template |= DESC_HDR_DONE_NOTIFY;
2948
Lee Nipper497f2e62010-05-19 19:20:36 +10002949 return 0;
2950}
2951
Jonas Eymann89d124c2016-04-19 20:33:47 +03002952static int talitos_cra_init(struct crypto_tfm *tfm)
2953{
2954 struct crypto_alg *alg = tfm->__crt_alg;
2955 struct talitos_crypto_alg *talitos_alg;
2956 struct talitos_ctx *ctx = crypto_tfm_ctx(tfm);
2957
2958 if ((alg->cra_flags & CRYPTO_ALG_TYPE_MASK) == CRYPTO_ALG_TYPE_AHASH)
2959 talitos_alg = container_of(__crypto_ahash_alg(alg),
2960 struct talitos_crypto_alg,
2961 algt.alg.hash);
2962 else
2963 talitos_alg = container_of(alg, struct talitos_crypto_alg,
2964 algt.alg.crypto);
2965
2966 return talitos_init_common(ctx, talitos_alg);
2967}
2968
Herbert Xuaeb4c132015-07-30 17:53:22 +08002969static int talitos_cra_init_aead(struct crypto_aead *tfm)
Lee Nipper497f2e62010-05-19 19:20:36 +10002970{
Jonas Eymann89d124c2016-04-19 20:33:47 +03002971 struct aead_alg *alg = crypto_aead_alg(tfm);
2972 struct talitos_crypto_alg *talitos_alg;
2973 struct talitos_ctx *ctx = crypto_aead_ctx(tfm);
2974
2975 talitos_alg = container_of(alg, struct talitos_crypto_alg,
2976 algt.alg.aead);
2977
2978 return talitos_init_common(ctx, talitos_alg);
Kim Phillips9c4a7962008-06-23 19:50:15 +08002979}
2980
Lee Nipper497f2e62010-05-19 19:20:36 +10002981static int talitos_cra_init_ahash(struct crypto_tfm *tfm)
2982{
2983 struct talitos_ctx *ctx = crypto_tfm_ctx(tfm);
2984
2985 talitos_cra_init(tfm);
2986
2987 ctx->keylen = 0;
2988 crypto_ahash_set_reqsize(__crypto_ahash_cast(tfm),
2989 sizeof(struct talitos_ahash_req_ctx));
2990
2991 return 0;
2992}
2993
Kim Phillips9c4a7962008-06-23 19:50:15 +08002994/*
2995 * given the alg's descriptor header template, determine whether descriptor
2996 * type and primary/secondary execution units required match the hw
2997 * capabilities description provided in the device tree node.
2998 */
2999static int hw_supports(struct device *dev, __be32 desc_hdr_template)
3000{
3001 struct talitos_private *priv = dev_get_drvdata(dev);
3002 int ret;
3003
3004 ret = (1 << DESC_TYPE(desc_hdr_template) & priv->desc_types) &&
3005 (1 << PRIMARY_EU(desc_hdr_template) & priv->exec_units);
3006
3007 if (SECONDARY_EU(desc_hdr_template))
3008 ret = ret && (1 << SECONDARY_EU(desc_hdr_template)
3009 & priv->exec_units);
3010
3011 return ret;
3012}
3013
Grant Likely2dc11582010-08-06 09:25:50 -06003014static int talitos_remove(struct platform_device *ofdev)
Kim Phillips9c4a7962008-06-23 19:50:15 +08003015{
3016 struct device *dev = &ofdev->dev;
3017 struct talitos_private *priv = dev_get_drvdata(dev);
3018 struct talitos_crypto_alg *t_alg, *n;
3019 int i;
3020
3021 list_for_each_entry_safe(t_alg, n, &priv->alg_list, entry) {
Lee Nipperacbf7c622010-05-19 19:19:33 +10003022 switch (t_alg->algt.type) {
3023 case CRYPTO_ALG_TYPE_ABLKCIPHER:
Lee Nipperacbf7c622010-05-19 19:19:33 +10003024 break;
Herbert Xuaeb4c132015-07-30 17:53:22 +08003025 case CRYPTO_ALG_TYPE_AEAD:
3026 crypto_unregister_aead(&t_alg->algt.alg.aead);
Lee Nipperacbf7c622010-05-19 19:19:33 +10003027 case CRYPTO_ALG_TYPE_AHASH:
3028 crypto_unregister_ahash(&t_alg->algt.alg.hash);
3029 break;
3030 }
Kim Phillips9c4a7962008-06-23 19:50:15 +08003031 list_del(&t_alg->entry);
3032 kfree(t_alg);
3033 }
3034
3035 if (hw_supports(dev, DESC_HDR_SEL0_RNG))
3036 talitos_unregister_rng(dev);
3037
Aaron Sierra35a3bb32015-08-05 16:52:08 -05003038 for (i = 0; priv->chan && i < priv->num_channels; i++)
Kim Phillips0b798242010-09-23 15:56:08 +08003039 kfree(priv->chan[i].fifo);
Kim Phillips9c4a7962008-06-23 19:50:15 +08003040
Kim Phillips4b9926282009-08-13 11:50:38 +10003041 kfree(priv->chan);
Kim Phillips9c4a7962008-06-23 19:50:15 +08003042
Kim Phillipsc3e337f2011-11-21 16:13:27 +08003043 for (i = 0; i < 2; i++)
Kim Phillips2cdba3c2011-12-12 14:59:11 -06003044 if (priv->irq[i]) {
Kim Phillipsc3e337f2011-11-21 16:13:27 +08003045 free_irq(priv->irq[i], dev);
3046 irq_dispose_mapping(priv->irq[i]);
3047 }
Kim Phillips9c4a7962008-06-23 19:50:15 +08003048
Kim Phillipsc3e337f2011-11-21 16:13:27 +08003049 tasklet_kill(&priv->done_task[0]);
Kim Phillips2cdba3c2011-12-12 14:59:11 -06003050 if (priv->irq[1])
Kim Phillipsc3e337f2011-11-21 16:13:27 +08003051 tasklet_kill(&priv->done_task[1]);
Kim Phillips9c4a7962008-06-23 19:50:15 +08003052
3053 iounmap(priv->reg);
3054
Kim Phillips9c4a7962008-06-23 19:50:15 +08003055 kfree(priv);
3056
3057 return 0;
3058}
3059
3060static struct talitos_crypto_alg *talitos_alg_alloc(struct device *dev,
3061 struct talitos_alg_template
3062 *template)
3063{
Kim Phillips60f208d2010-05-19 19:21:53 +10003064 struct talitos_private *priv = dev_get_drvdata(dev);
Kim Phillips9c4a7962008-06-23 19:50:15 +08003065 struct talitos_crypto_alg *t_alg;
3066 struct crypto_alg *alg;
3067
3068 t_alg = kzalloc(sizeof(struct talitos_crypto_alg), GFP_KERNEL);
3069 if (!t_alg)
3070 return ERR_PTR(-ENOMEM);
3071
Lee Nipperacbf7c622010-05-19 19:19:33 +10003072 t_alg->algt = *template;
3073
3074 switch (t_alg->algt.type) {
3075 case CRYPTO_ALG_TYPE_ABLKCIPHER:
Lee Nipper497f2e62010-05-19 19:20:36 +10003076 alg = &t_alg->algt.alg.crypto;
3077 alg->cra_init = talitos_cra_init;
Kim Phillipsd4cd3282012-08-08 20:32:00 -05003078 alg->cra_type = &crypto_ablkcipher_type;
Kim Phillipsb286e002012-08-08 20:33:34 -05003079 alg->cra_ablkcipher.setkey = ablkcipher_setkey;
3080 alg->cra_ablkcipher.encrypt = ablkcipher_encrypt;
3081 alg->cra_ablkcipher.decrypt = ablkcipher_decrypt;
3082 alg->cra_ablkcipher.geniv = "eseqiv";
Lee Nipper497f2e62010-05-19 19:20:36 +10003083 break;
Lee Nipperacbf7c622010-05-19 19:19:33 +10003084 case CRYPTO_ALG_TYPE_AEAD:
Herbert Xuaeb4c132015-07-30 17:53:22 +08003085 alg = &t_alg->algt.alg.aead.base;
Herbert Xuaeb4c132015-07-30 17:53:22 +08003086 t_alg->algt.alg.aead.init = talitos_cra_init_aead;
3087 t_alg->algt.alg.aead.setkey = aead_setkey;
3088 t_alg->algt.alg.aead.encrypt = aead_encrypt;
3089 t_alg->algt.alg.aead.decrypt = aead_decrypt;
LEROY Christophe6bf30e62017-10-06 15:04:39 +02003090 if (!(priv->features & TALITOS_FTR_SHA224_HWINIT) &&
3091 !strncmp(alg->cra_name, "authenc(hmac(sha224)", 20)) {
3092 kfree(t_alg);
3093 return ERR_PTR(-ENOTSUPP);
3094 }
Lee Nipperacbf7c622010-05-19 19:19:33 +10003095 break;
3096 case CRYPTO_ALG_TYPE_AHASH:
3097 alg = &t_alg->algt.alg.hash.halg.base;
Lee Nipper497f2e62010-05-19 19:20:36 +10003098 alg->cra_init = talitos_cra_init_ahash;
Kim Phillipsd4cd3282012-08-08 20:32:00 -05003099 alg->cra_type = &crypto_ahash_type;
Kim Phillipsb286e002012-08-08 20:33:34 -05003100 t_alg->algt.alg.hash.init = ahash_init;
3101 t_alg->algt.alg.hash.update = ahash_update;
3102 t_alg->algt.alg.hash.final = ahash_final;
3103 t_alg->algt.alg.hash.finup = ahash_finup;
3104 t_alg->algt.alg.hash.digest = ahash_digest;
LEROY Christophe70117b72017-09-12 11:03:39 +02003105 if (!strncmp(alg->cra_name, "hmac", 4))
3106 t_alg->algt.alg.hash.setkey = ahash_setkey;
Horia Geant?3639ca82016-04-21 19:24:55 +03003107 t_alg->algt.alg.hash.import = ahash_import;
3108 t_alg->algt.alg.hash.export = ahash_export;
Kim Phillipsb286e002012-08-08 20:33:34 -05003109
Lee Nipper79b3a412011-11-21 16:13:25 +08003110 if (!(priv->features & TALITOS_FTR_HMAC_OK) &&
Kim Phillips0b2730d2011-12-12 14:59:10 -06003111 !strncmp(alg->cra_name, "hmac", 4)) {
3112 kfree(t_alg);
Lee Nipper79b3a412011-11-21 16:13:25 +08003113 return ERR_PTR(-ENOTSUPP);
Kim Phillips0b2730d2011-12-12 14:59:10 -06003114 }
Kim Phillips60f208d2010-05-19 19:21:53 +10003115 if (!(priv->features & TALITOS_FTR_SHA224_HWINIT) &&
Lee Nipper79b3a412011-11-21 16:13:25 +08003116 (!strcmp(alg->cra_name, "sha224") ||
3117 !strcmp(alg->cra_name, "hmac(sha224)"))) {
Kim Phillips60f208d2010-05-19 19:21:53 +10003118 t_alg->algt.alg.hash.init = ahash_init_sha224_swinit;
3119 t_alg->algt.desc_hdr_template =
3120 DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
3121 DESC_HDR_SEL0_MDEUA |
3122 DESC_HDR_MODE0_MDEU_SHA256;
3123 }
Lee Nipper497f2e62010-05-19 19:20:36 +10003124 break;
Kim Phillips1d119112010-09-23 15:55:27 +08003125 default:
3126 dev_err(dev, "unknown algorithm type %d\n", t_alg->algt.type);
Horia Geant?5fa7dad2015-05-11 20:03:24 +03003127 kfree(t_alg);
Kim Phillips1d119112010-09-23 15:55:27 +08003128 return ERR_PTR(-EINVAL);
Lee Nipperacbf7c622010-05-19 19:19:33 +10003129 }
Kim Phillips9c4a7962008-06-23 19:50:15 +08003130
Kim Phillips9c4a7962008-06-23 19:50:15 +08003131 alg->cra_module = THIS_MODULE;
LEROY Christopheb0057762016-06-06 13:20:44 +02003132 if (t_alg->algt.priority)
3133 alg->cra_priority = t_alg->algt.priority;
3134 else
3135 alg->cra_priority = TALITOS_CRA_PRIORITY;
Christophe Leroyb24e8162019-05-21 13:34:18 +00003136 if (has_ftr_sec1(priv))
3137 alg->cra_alignmask = 3;
3138 else
3139 alg->cra_alignmask = 0;
Kim Phillips9c4a7962008-06-23 19:50:15 +08003140 alg->cra_ctxsize = sizeof(struct talitos_ctx);
Nikos Mavrogiannopoulosd912bb72011-11-01 13:39:56 +01003141 alg->cra_flags |= CRYPTO_ALG_KERN_DRIVER_ONLY;
Kim Phillips9c4a7962008-06-23 19:50:15 +08003142
Kim Phillips9c4a7962008-06-23 19:50:15 +08003143 t_alg->dev = dev;
3144
3145 return t_alg;
3146}
3147
Kim Phillipsc3e337f2011-11-21 16:13:27 +08003148static int talitos_probe_irq(struct platform_device *ofdev)
3149{
3150 struct device *dev = &ofdev->dev;
3151 struct device_node *np = ofdev->dev.of_node;
3152 struct talitos_private *priv = dev_get_drvdata(dev);
3153 int err;
LEROY Christophedd3c0982015-04-17 16:32:13 +02003154 bool is_sec1 = has_ftr_sec1(priv);
Kim Phillipsc3e337f2011-11-21 16:13:27 +08003155
3156 priv->irq[0] = irq_of_parse_and_map(np, 0);
Kim Phillips2cdba3c2011-12-12 14:59:11 -06003157 if (!priv->irq[0]) {
Kim Phillipsc3e337f2011-11-21 16:13:27 +08003158 dev_err(dev, "failed to map irq\n");
3159 return -EINVAL;
3160 }
LEROY Christophedd3c0982015-04-17 16:32:13 +02003161 if (is_sec1) {
3162 err = request_irq(priv->irq[0], talitos1_interrupt_4ch, 0,
3163 dev_driver_string(dev), dev);
3164 goto primary_out;
3165 }
Kim Phillipsc3e337f2011-11-21 16:13:27 +08003166
3167 priv->irq[1] = irq_of_parse_and_map(np, 1);
3168
3169 /* get the primary irq line */
Kim Phillips2cdba3c2011-12-12 14:59:11 -06003170 if (!priv->irq[1]) {
LEROY Christophedd3c0982015-04-17 16:32:13 +02003171 err = request_irq(priv->irq[0], talitos2_interrupt_4ch, 0,
Kim Phillipsc3e337f2011-11-21 16:13:27 +08003172 dev_driver_string(dev), dev);
3173 goto primary_out;
3174 }
3175
LEROY Christophedd3c0982015-04-17 16:32:13 +02003176 err = request_irq(priv->irq[0], talitos2_interrupt_ch0_2, 0,
Kim Phillipsc3e337f2011-11-21 16:13:27 +08003177 dev_driver_string(dev), dev);
3178 if (err)
3179 goto primary_out;
3180
3181 /* get the secondary irq line */
LEROY Christophedd3c0982015-04-17 16:32:13 +02003182 err = request_irq(priv->irq[1], talitos2_interrupt_ch1_3, 0,
Kim Phillipsc3e337f2011-11-21 16:13:27 +08003183 dev_driver_string(dev), dev);
3184 if (err) {
3185 dev_err(dev, "failed to request secondary irq\n");
3186 irq_dispose_mapping(priv->irq[1]);
Kim Phillips2cdba3c2011-12-12 14:59:11 -06003187 priv->irq[1] = 0;
Kim Phillipsc3e337f2011-11-21 16:13:27 +08003188 }
3189
3190 return err;
3191
3192primary_out:
3193 if (err) {
3194 dev_err(dev, "failed to request primary irq\n");
3195 irq_dispose_mapping(priv->irq[0]);
Kim Phillips2cdba3c2011-12-12 14:59:11 -06003196 priv->irq[0] = 0;
Kim Phillipsc3e337f2011-11-21 16:13:27 +08003197 }
3198
3199 return err;
3200}
3201
Grant Likely1c48a5c2011-02-17 02:43:24 -07003202static int talitos_probe(struct platform_device *ofdev)
Kim Phillips9c4a7962008-06-23 19:50:15 +08003203{
3204 struct device *dev = &ofdev->dev;
Grant Likely61c7a082010-04-13 16:12:29 -07003205 struct device_node *np = ofdev->dev.of_node;
Kim Phillips9c4a7962008-06-23 19:50:15 +08003206 struct talitos_private *priv;
3207 const unsigned int *prop;
3208 int i, err;
LEROY Christophe5fa7fa12015-04-17 16:32:11 +02003209 int stride;
Kim Phillips9c4a7962008-06-23 19:50:15 +08003210
3211 priv = kzalloc(sizeof(struct talitos_private), GFP_KERNEL);
3212 if (!priv)
3213 return -ENOMEM;
3214
Kevin Haof3de9cb2014-01-28 20:17:23 +08003215 INIT_LIST_HEAD(&priv->alg_list);
3216
Kim Phillips9c4a7962008-06-23 19:50:15 +08003217 dev_set_drvdata(dev, priv);
3218
3219 priv->ofdev = ofdev;
3220
Horia Geanta511d63c2012-03-30 17:49:53 +03003221 spin_lock_init(&priv->reg_lock);
3222
Kim Phillips9c4a7962008-06-23 19:50:15 +08003223 priv->reg = of_iomap(np, 0);
3224 if (!priv->reg) {
3225 dev_err(dev, "failed to of_iomap\n");
3226 err = -ENOMEM;
3227 goto err_out;
3228 }
3229
3230 /* get SEC version capabilities from device tree */
3231 prop = of_get_property(np, "fsl,num-channels", NULL);
3232 if (prop)
3233 priv->num_channels = *prop;
3234
3235 prop = of_get_property(np, "fsl,channel-fifo-len", NULL);
3236 if (prop)
3237 priv->chfifo_len = *prop;
3238
3239 prop = of_get_property(np, "fsl,exec-units-mask", NULL);
3240 if (prop)
3241 priv->exec_units = *prop;
3242
3243 prop = of_get_property(np, "fsl,descriptor-types-mask", NULL);
3244 if (prop)
3245 priv->desc_types = *prop;
3246
3247 if (!is_power_of_2(priv->num_channels) || !priv->chfifo_len ||
3248 !priv->exec_units || !priv->desc_types) {
3249 dev_err(dev, "invalid property data in device tree node\n");
3250 err = -EINVAL;
3251 goto err_out;
3252 }
3253
Lee Nipperf3c85bc2008-07-30 16:26:57 +08003254 if (of_device_is_compatible(np, "fsl,sec3.0"))
3255 priv->features |= TALITOS_FTR_SRC_LINK_TBL_LEN_INCLUDES_EXTENT;
3256
Kim Phillipsfe5720e2008-10-12 20:33:14 +08003257 if (of_device_is_compatible(np, "fsl,sec2.1"))
Kim Phillips60f208d2010-05-19 19:21:53 +10003258 priv->features |= TALITOS_FTR_HW_AUTH_CHECK |
Lee Nipper79b3a412011-11-21 16:13:25 +08003259 TALITOS_FTR_SHA224_HWINIT |
3260 TALITOS_FTR_HMAC_OK;
Kim Phillipsfe5720e2008-10-12 20:33:14 +08003261
LEROY Christophe21590882015-04-17 16:32:05 +02003262 if (of_device_is_compatible(np, "fsl,sec1.0"))
3263 priv->features |= TALITOS_FTR_SEC1;
3264
LEROY Christophe5fa7fa12015-04-17 16:32:11 +02003265 if (of_device_is_compatible(np, "fsl,sec1.2")) {
3266 priv->reg_deu = priv->reg + TALITOS12_DEU;
3267 priv->reg_aesu = priv->reg + TALITOS12_AESU;
3268 priv->reg_mdeu = priv->reg + TALITOS12_MDEU;
3269 stride = TALITOS1_CH_STRIDE;
3270 } else if (of_device_is_compatible(np, "fsl,sec1.0")) {
3271 priv->reg_deu = priv->reg + TALITOS10_DEU;
3272 priv->reg_aesu = priv->reg + TALITOS10_AESU;
3273 priv->reg_mdeu = priv->reg + TALITOS10_MDEU;
3274 priv->reg_afeu = priv->reg + TALITOS10_AFEU;
3275 priv->reg_rngu = priv->reg + TALITOS10_RNGU;
3276 priv->reg_pkeu = priv->reg + TALITOS10_PKEU;
3277 stride = TALITOS1_CH_STRIDE;
3278 } else {
3279 priv->reg_deu = priv->reg + TALITOS2_DEU;
3280 priv->reg_aesu = priv->reg + TALITOS2_AESU;
3281 priv->reg_mdeu = priv->reg + TALITOS2_MDEU;
3282 priv->reg_afeu = priv->reg + TALITOS2_AFEU;
3283 priv->reg_rngu = priv->reg + TALITOS2_RNGU;
3284 priv->reg_pkeu = priv->reg + TALITOS2_PKEU;
3285 priv->reg_keu = priv->reg + TALITOS2_KEU;
3286 priv->reg_crcu = priv->reg + TALITOS2_CRCU;
3287 stride = TALITOS2_CH_STRIDE;
3288 }
3289
LEROY Christophedd3c0982015-04-17 16:32:13 +02003290 err = talitos_probe_irq(ofdev);
3291 if (err)
3292 goto err_out;
3293
3294 if (of_device_is_compatible(np, "fsl,sec1.0")) {
3295 tasklet_init(&priv->done_task[0], talitos1_done_4ch,
3296 (unsigned long)dev);
3297 } else {
3298 if (!priv->irq[1]) {
3299 tasklet_init(&priv->done_task[0], talitos2_done_4ch,
3300 (unsigned long)dev);
3301 } else {
3302 tasklet_init(&priv->done_task[0], talitos2_done_ch0_2,
3303 (unsigned long)dev);
3304 tasklet_init(&priv->done_task[1], talitos2_done_ch1_3,
3305 (unsigned long)dev);
3306 }
3307 }
3308
Kim Phillips4b9926282009-08-13 11:50:38 +10003309 priv->chan = kzalloc(sizeof(struct talitos_channel) *
3310 priv->num_channels, GFP_KERNEL);
3311 if (!priv->chan) {
3312 dev_err(dev, "failed to allocate channel management space\n");
Kim Phillips9c4a7962008-06-23 19:50:15 +08003313 err = -ENOMEM;
3314 goto err_out;
3315 }
3316
Martin Hicksf641ddd2015-03-03 08:21:33 -05003317 priv->fifo_len = roundup_pow_of_two(priv->chfifo_len);
3318
Kim Phillipsc3e337f2011-11-21 16:13:27 +08003319 for (i = 0; i < priv->num_channels; i++) {
LEROY Christophe5fa7fa12015-04-17 16:32:11 +02003320 priv->chan[i].reg = priv->reg + stride * (i + 1);
Kim Phillips2cdba3c2011-12-12 14:59:11 -06003321 if (!priv->irq[1] || !(i & 1))
Kim Phillipsc3e337f2011-11-21 16:13:27 +08003322 priv->chan[i].reg += TALITOS_CH_BASE_OFFSET;
Kim Phillipsad42d5f2011-11-21 16:13:27 +08003323
Kim Phillips4b9926282009-08-13 11:50:38 +10003324 spin_lock_init(&priv->chan[i].head_lock);
3325 spin_lock_init(&priv->chan[i].tail_lock);
Kim Phillips9c4a7962008-06-23 19:50:15 +08003326
Kim Phillips4b9926282009-08-13 11:50:38 +10003327 priv->chan[i].fifo = kzalloc(sizeof(struct talitos_request) *
3328 priv->fifo_len, GFP_KERNEL);
3329 if (!priv->chan[i].fifo) {
Kim Phillips9c4a7962008-06-23 19:50:15 +08003330 dev_err(dev, "failed to allocate request fifo %d\n", i);
3331 err = -ENOMEM;
3332 goto err_out;
3333 }
Kim Phillips9c4a7962008-06-23 19:50:15 +08003334
Kim Phillips4b9926282009-08-13 11:50:38 +10003335 atomic_set(&priv->chan[i].submit_count,
3336 -(priv->chfifo_len - 1));
Martin Hicksf641ddd2015-03-03 08:21:33 -05003337 }
Kim Phillips9c4a7962008-06-23 19:50:15 +08003338
Kim Phillips81eb0242009-08-13 11:51:51 +10003339 dma_set_mask(dev, DMA_BIT_MASK(36));
3340
Kim Phillips9c4a7962008-06-23 19:50:15 +08003341 /* reset and initialize the h/w */
3342 err = init_device(dev);
3343 if (err) {
3344 dev_err(dev, "failed to initialize device\n");
3345 goto err_out;
3346 }
3347
3348 /* register the RNG, if available */
3349 if (hw_supports(dev, DESC_HDR_SEL0_RNG)) {
3350 err = talitos_register_rng(dev);
3351 if (err) {
3352 dev_err(dev, "failed to register hwrng: %d\n", err);
3353 goto err_out;
3354 } else
3355 dev_info(dev, "hwrng\n");
3356 }
3357
3358 /* register crypto algorithms the device supports */
Kim Phillips9c4a7962008-06-23 19:50:15 +08003359 for (i = 0; i < ARRAY_SIZE(driver_algs); i++) {
3360 if (hw_supports(dev, driver_algs[i].desc_hdr_template)) {
3361 struct talitos_crypto_alg *t_alg;
Herbert Xuaeb4c132015-07-30 17:53:22 +08003362 struct crypto_alg *alg = NULL;
Kim Phillips9c4a7962008-06-23 19:50:15 +08003363
3364 t_alg = talitos_alg_alloc(dev, &driver_algs[i]);
3365 if (IS_ERR(t_alg)) {
3366 err = PTR_ERR(t_alg);
Kim Phillips0b2730d2011-12-12 14:59:10 -06003367 if (err == -ENOTSUPP)
Lee Nipper79b3a412011-11-21 16:13:25 +08003368 continue;
Kim Phillips9c4a7962008-06-23 19:50:15 +08003369 goto err_out;
3370 }
3371
Lee Nipperacbf7c622010-05-19 19:19:33 +10003372 switch (t_alg->algt.type) {
3373 case CRYPTO_ALG_TYPE_ABLKCIPHER:
Lee Nipperacbf7c622010-05-19 19:19:33 +10003374 err = crypto_register_alg(
3375 &t_alg->algt.alg.crypto);
Herbert Xuaeb4c132015-07-30 17:53:22 +08003376 alg = &t_alg->algt.alg.crypto;
Lee Nipperacbf7c622010-05-19 19:19:33 +10003377 break;
Herbert Xuaeb4c132015-07-30 17:53:22 +08003378
3379 case CRYPTO_ALG_TYPE_AEAD:
3380 err = crypto_register_aead(
3381 &t_alg->algt.alg.aead);
3382 alg = &t_alg->algt.alg.aead.base;
3383 break;
3384
Lee Nipperacbf7c622010-05-19 19:19:33 +10003385 case CRYPTO_ALG_TYPE_AHASH:
3386 err = crypto_register_ahash(
3387 &t_alg->algt.alg.hash);
Herbert Xuaeb4c132015-07-30 17:53:22 +08003388 alg = &t_alg->algt.alg.hash.halg.base;
Lee Nipperacbf7c622010-05-19 19:19:33 +10003389 break;
3390 }
Kim Phillips9c4a7962008-06-23 19:50:15 +08003391 if (err) {
3392 dev_err(dev, "%s alg registration failed\n",
Herbert Xuaeb4c132015-07-30 17:53:22 +08003393 alg->cra_driver_name);
Kim Phillips9c4a7962008-06-23 19:50:15 +08003394 kfree(t_alg);
Horia Geanta991155b2013-03-20 16:31:38 +02003395 } else
Kim Phillips9c4a7962008-06-23 19:50:15 +08003396 list_add_tail(&t_alg->entry, &priv->alg_list);
Kim Phillips9c4a7962008-06-23 19:50:15 +08003397 }
3398 }
Kim Phillips5b859b6e2011-11-21 16:13:26 +08003399 if (!list_empty(&priv->alg_list))
3400 dev_info(dev, "%s algorithms registered in /proc/crypto\n",
3401 (char *)of_get_property(np, "compatible", NULL));
Kim Phillips9c4a7962008-06-23 19:50:15 +08003402
3403 return 0;
3404
3405err_out:
3406 talitos_remove(ofdev);
Kim Phillips9c4a7962008-06-23 19:50:15 +08003407
3408 return err;
3409}
3410
Márton Németh6c3f9752010-01-17 21:54:01 +11003411static const struct of_device_id talitos_match[] = {
LEROY Christophe0635b7d2015-04-17 16:32:20 +02003412#ifdef CONFIG_CRYPTO_DEV_TALITOS1
3413 {
3414 .compatible = "fsl,sec1.0",
3415 },
3416#endif
3417#ifdef CONFIG_CRYPTO_DEV_TALITOS2
Kim Phillips9c4a7962008-06-23 19:50:15 +08003418 {
3419 .compatible = "fsl,sec2.0",
3420 },
LEROY Christophe0635b7d2015-04-17 16:32:20 +02003421#endif
Kim Phillips9c4a7962008-06-23 19:50:15 +08003422 {},
3423};
3424MODULE_DEVICE_TABLE(of, talitos_match);
3425
Grant Likely1c48a5c2011-02-17 02:43:24 -07003426static struct platform_driver talitos_driver = {
Grant Likely40182942010-04-13 16:13:02 -07003427 .driver = {
3428 .name = "talitos",
Grant Likely40182942010-04-13 16:13:02 -07003429 .of_match_table = talitos_match,
3430 },
Kim Phillips9c4a7962008-06-23 19:50:15 +08003431 .probe = talitos_probe,
Al Viro596f1032008-11-22 17:34:24 +00003432 .remove = talitos_remove,
Kim Phillips9c4a7962008-06-23 19:50:15 +08003433};
3434
Axel Lin741e8c22011-11-26 21:26:19 +08003435module_platform_driver(talitos_driver);
Kim Phillips9c4a7962008-06-23 19:50:15 +08003436
3437MODULE_LICENSE("GPL");
3438MODULE_AUTHOR("Kim Phillips <kim.phillips@freescale.com>");
3439MODULE_DESCRIPTION("Freescale integrated security engine (SEC) driver");