aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/crypto/mxc-scc.c
diff options
context:
space:
mode:
authorSteffen Trumtrar <s.trumtrar@pengutronix.de>2016-04-12 05:04:26 -0400
committerHerbert Xu <herbert@gondor.apana.org.au>2016-04-15 10:36:35 -0400
commitd293b640ebd532eb9d65bc42d48fb9d2c06e71c9 (patch)
treef8277910439be81dfe10cf9b6acd06150bb0d46d /drivers/crypto/mxc-scc.c
parentba97eed2b62e97ab6a96d27ea6a049f3a815237c (diff)
crypto: mxc-scc - add basic driver for the MXC SCC
According to the Freescale GPL driver code, there are two different Security Controller (SCC) versions: SCC and SCC2. The SCC is found on older i.MX SoCs, e.g. the i.MX25. This is the version implemented and tested here. As there is no publicly available documentation for this IP core, all information about this unit is gathered from the GPL'ed driver from Freescale. Signed-off-by: Steffen Trumtrar <s.trumtrar@pengutronix.de> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Diffstat (limited to 'drivers/crypto/mxc-scc.c')
-rw-r--r--drivers/crypto/mxc-scc.c762
1 files changed, 762 insertions, 0 deletions
diff --git a/drivers/crypto/mxc-scc.c b/drivers/crypto/mxc-scc.c
new file mode 100644
index 000000000000..38b01bf141d3
--- /dev/null
+++ b/drivers/crypto/mxc-scc.c
@@ -0,0 +1,762 @@
1/*
2 * Copyright (C) 2016 Pengutronix, Steffen Trumtrar <kernel@pengutronix.de>
3 *
4 * The driver is based on information gathered from
5 * drivers/mxc/security/mxc_scc.c which can be found in
6 * the Freescale linux-2.6-imx.git in the imx_2.6.35_maintain branch.
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * version 2, as published by the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 */
18#include <linux/clk.h>
19#include <linux/crypto.h>
20#include <linux/interrupt.h>
21#include <linux/io.h>
22#include <linux/irq.h>
23#include <linux/kernel.h>
24#include <linux/module.h>
25#include <linux/mutex.h>
26#include <linux/of.h>
27#include <linux/of_device.h>
28#include <linux/platform_device.h>
29
30#include <crypto/algapi.h>
31#include <crypto/des.h>
32
33/* Secure Memory (SCM) registers */
34#define SCC_SCM_RED_START 0x0000
35#define SCC_SCM_BLACK_START 0x0004
36#define SCC_SCM_LENGTH 0x0008
37#define SCC_SCM_CTRL 0x000C
38#define SCC_SCM_STATUS 0x0010
39#define SCC_SCM_ERROR_STATUS 0x0014
40#define SCC_SCM_INTR_CTRL 0x0018
41#define SCC_SCM_CFG 0x001C
42#define SCC_SCM_INIT_VECTOR_0 0x0020
43#define SCC_SCM_INIT_VECTOR_1 0x0024
44#define SCC_SCM_RED_MEMORY 0x0400
45#define SCC_SCM_BLACK_MEMORY 0x0800
46
47/* Security Monitor (SMN) Registers */
48#define SCC_SMN_STATUS 0x1000
49#define SCC_SMN_COMMAND 0x1004
50#define SCC_SMN_SEQ_START 0x1008
51#define SCC_SMN_SEQ_END 0x100C
52#define SCC_SMN_SEQ_CHECK 0x1010
53#define SCC_SMN_BIT_COUNT 0x1014
54#define SCC_SMN_BITBANK_INC_SIZE 0x1018
55#define SCC_SMN_BITBANK_DECREMENT 0x101C
56#define SCC_SMN_COMPARE_SIZE 0x1020
57#define SCC_SMN_PLAINTEXT_CHECK 0x1024
58#define SCC_SMN_CIPHERTEXT_CHECK 0x1028
59#define SCC_SMN_TIMER_IV 0x102C
60#define SCC_SMN_TIMER_CONTROL 0x1030
61#define SCC_SMN_DEBUG_DETECT_STAT 0x1034
62#define SCC_SMN_TIMER 0x1038
63
64#define SCC_SCM_CTRL_START_CIPHER BIT(2)
65#define SCC_SCM_CTRL_CBC_MODE BIT(1)
66#define SCC_SCM_CTRL_DECRYPT_MODE BIT(0)
67
68#define SCC_SCM_STATUS_LEN_ERR BIT(12)
69#define SCC_SCM_STATUS_SMN_UNBLOCKED BIT(11)
70#define SCC_SCM_STATUS_CIPHERING_DONE BIT(10)
71#define SCC_SCM_STATUS_ZEROIZING_DONE BIT(9)
72#define SCC_SCM_STATUS_INTR_STATUS BIT(8)
73#define SCC_SCM_STATUS_SEC_KEY BIT(7)
74#define SCC_SCM_STATUS_INTERNAL_ERR BIT(6)
75#define SCC_SCM_STATUS_BAD_SEC_KEY BIT(5)
76#define SCC_SCM_STATUS_ZEROIZE_FAIL BIT(4)
77#define SCC_SCM_STATUS_SMN_BLOCKED BIT(3)
78#define SCC_SCM_STATUS_CIPHERING BIT(2)
79#define SCC_SCM_STATUS_ZEROIZING BIT(1)
80#define SCC_SCM_STATUS_BUSY BIT(0)
81
82#define SCC_SMN_STATUS_STATE_MASK 0x0000001F
83#define SCC_SMN_STATE_START 0x0
84/* The SMN is zeroizing its RAM during reset */
85#define SCC_SMN_STATE_ZEROIZE_RAM 0x5
86/* SMN has passed internal checks */
87#define SCC_SMN_STATE_HEALTH_CHECK 0x6
88/* Fatal Security Violation. SMN is locked, SCM is inoperative. */
89#define SCC_SMN_STATE_FAIL 0x9
90/* SCC is in secure state. SCM is using secret key. */
91#define SCC_SMN_STATE_SECURE 0xA
92/* SCC is not secure. SCM is using default key. */
93#define SCC_SMN_STATE_NON_SECURE 0xC
94
95#define SCC_SCM_INTR_CTRL_ZEROIZE_MEM BIT(2)
96#define SCC_SCM_INTR_CTRL_CLR_INTR BIT(1)
97#define SCC_SCM_INTR_CTRL_MASK_INTR BIT(0)
98
99/* Size, in blocks, of Red memory. */
100#define SCC_SCM_CFG_BLACK_SIZE_MASK 0x07fe0000
101#define SCC_SCM_CFG_BLACK_SIZE_SHIFT 17
102/* Size, in blocks, of Black memory. */
103#define SCC_SCM_CFG_RED_SIZE_MASK 0x0001ff80
104#define SCC_SCM_CFG_RED_SIZE_SHIFT 7
105/* Number of bytes per block. */
106#define SCC_SCM_CFG_BLOCK_SIZE_MASK 0x0000007f
107
108#define SCC_SMN_COMMAND_TAMPER_LOCK BIT(4)
109#define SCC_SMN_COMMAND_CLR_INTR BIT(3)
110#define SCC_SMN_COMMAND_CLR_BIT_BANK BIT(2)
111#define SCC_SMN_COMMAND_EN_INTR BIT(1)
112#define SCC_SMN_COMMAND_SET_SOFTWARE_ALARM BIT(0)
113
114#define SCC_KEY_SLOTS 20
115#define SCC_MAX_KEY_SIZE 32
116#define SCC_KEY_SLOT_SIZE 32
117
118#define SCC_CRC_CCITT_START 0xFFFF
119
120/*
121 * Offset into each RAM of the base of the area which is not
122 * used for Stored Keys.
123 */
124#define SCC_NON_RESERVED_OFFSET (SCC_KEY_SLOTS * SCC_KEY_SLOT_SIZE)
125
126/* Fixed padding for appending to plaintext to fill out a block */
127static char scc_block_padding[8] = { 0x80, 0, 0, 0, 0, 0, 0, 0 };
128
129enum mxc_scc_state {
130 SCC_STATE_OK,
131 SCC_STATE_UNIMPLEMENTED,
132 SCC_STATE_FAILED
133};
134
135struct mxc_scc {
136 struct device *dev;
137 void __iomem *base;
138 struct clk *clk;
139 bool hw_busy;
140 spinlock_t lock;
141 struct crypto_queue queue;
142 struct crypto_async_request *req;
143 int block_size_bytes;
144 int black_ram_size_blocks;
145 int memory_size_bytes;
146 int bytes_remaining;
147
148 void __iomem *red_memory;
149 void __iomem *black_memory;
150};
151
152struct mxc_scc_ctx {
153 struct mxc_scc *scc;
154 struct scatterlist *sg_src;
155 size_t src_nents;
156 struct scatterlist *sg_dst;
157 size_t dst_nents;
158 unsigned int offset;
159 unsigned int size;
160 unsigned int ctrl;
161};
162
163struct mxc_scc_crypto_tmpl {
164 struct mxc_scc *scc;
165 struct crypto_alg alg;
166};
167
168static int mxc_scc_get_data(struct mxc_scc_ctx *ctx,
169 struct crypto_async_request *req)
170{
171 struct ablkcipher_request *ablkreq = ablkcipher_request_cast(req);
172 struct mxc_scc *scc = ctx->scc;
173 size_t len;
174 void __iomem *from;
175
176 if (ctx->ctrl & SCC_SCM_CTRL_DECRYPT_MODE)
177 from = scc->red_memory;
178 else
179 from = scc->black_memory;
180
181 dev_dbg(scc->dev, "pcopy: from 0x%p %d bytes\n", from,
182 ctx->dst_nents * 8);
183 len = sg_pcopy_from_buffer(ablkreq->dst, ctx->dst_nents,
184 from, ctx->size, ctx->offset);
185 if (!len) {
186 dev_err(scc->dev, "pcopy err from 0x%p (len=%d)\n", from, len);
187 return -EINVAL;
188 }
189
190#ifdef DEBUG
191 print_hex_dump(KERN_ERR,
192 "red memory@"__stringify(__LINE__)": ",
193 DUMP_PREFIX_ADDRESS, 16, 4,
194 scc->red_memory, ctx->size, 1);
195 print_hex_dump(KERN_ERR,
196 "black memory@"__stringify(__LINE__)": ",
197 DUMP_PREFIX_ADDRESS, 16, 4,
198 scc->black_memory, ctx->size, 1);
199#endif
200
201 ctx->offset += len;
202
203 if (ctx->offset < ablkreq->nbytes)
204 return -EINPROGRESS;
205
206 return 0;
207}
208
209static int mxc_scc_ablkcipher_req_init(struct ablkcipher_request *req,
210 struct mxc_scc_ctx *ctx)
211{
212 struct mxc_scc *scc = ctx->scc;
213
214 ctx->src_nents = sg_nents_for_len(req->src, req->nbytes);
215 if (ctx->src_nents < 0) {
216 dev_err(scc->dev, "Invalid number of src SC");
217 return ctx->src_nents;
218 }
219
220 ctx->dst_nents = sg_nents_for_len(req->dst, req->nbytes);
221 if (ctx->dst_nents < 0) {
222 dev_err(scc->dev, "Invalid number of dst SC");
223 return ctx->dst_nents;
224 }
225
226 ctx->size = 0;
227 ctx->offset = 0;
228
229 return 0;
230}
231
232static int mxc_scc_ablkcipher_req_complete(struct crypto_async_request *req,
233 struct mxc_scc_ctx *ctx,
234 int result)
235{
236 struct ablkcipher_request *ablkreq = ablkcipher_request_cast(req);
237 struct mxc_scc *scc = ctx->scc;
238
239 scc->req = NULL;
240 scc->bytes_remaining = scc->memory_size_bytes;
241
242 if (ctx->ctrl & SCC_SCM_CTRL_CBC_MODE)
243 memcpy(ablkreq->info, scc->base + SCC_SCM_INIT_VECTOR_0,
244 scc->block_size_bytes);
245
246 req->complete(req, result);
247 scc->hw_busy = false;
248
249 return 0;
250}
251
252static int mxc_scc_put_data(struct mxc_scc_ctx *ctx,
253 struct ablkcipher_request *req)
254{
255 u8 padding_buffer[sizeof(u16) + sizeof(scc_block_padding)];
256 size_t len = min_t(size_t, req->nbytes - ctx->offset,
257 ctx->scc->bytes_remaining);
258 unsigned int padding_byte_count = 0;
259 struct mxc_scc *scc = ctx->scc;
260 void __iomem *to;
261
262 if (ctx->ctrl & SCC_SCM_CTRL_DECRYPT_MODE)
263 to = scc->black_memory;
264 else
265 to = scc->red_memory;
266
267 if (ctx->ctrl & SCC_SCM_CTRL_CBC_MODE && req->info)
268 memcpy(scc->base + SCC_SCM_INIT_VECTOR_0, req->info,
269 scc->block_size_bytes);
270
271 len = sg_pcopy_to_buffer(req->src, ctx->src_nents,
272 to, len, ctx->offset);
273 if (!len) {
274 dev_err(scc->dev, "pcopy err to 0x%p (len=%d)\n", to, len);
275 return -EINVAL;
276 }
277
278 ctx->size = len;
279
280#ifdef DEBUG
281 dev_dbg(scc->dev, "copied %d bytes to 0x%p\n", len, to);
282 print_hex_dump(KERN_ERR,
283 "init vector0@"__stringify(__LINE__)": ",
284 DUMP_PREFIX_ADDRESS, 16, 4,
285 scc->base + SCC_SCM_INIT_VECTOR_0, scc->block_size_bytes,
286 1);
287 print_hex_dump(KERN_ERR,
288 "red memory@"__stringify(__LINE__)": ",
289 DUMP_PREFIX_ADDRESS, 16, 4,
290 scc->red_memory, ctx->size, 1);
291 print_hex_dump(KERN_ERR,
292 "black memory@"__stringify(__LINE__)": ",
293 DUMP_PREFIX_ADDRESS, 16, 4,
294 scc->black_memory, ctx->size, 1);
295#endif
296
297 scc->bytes_remaining -= len;
298
299 padding_byte_count = len % scc->block_size_bytes;
300
301 if (padding_byte_count) {
302 memcpy(padding_buffer, scc_block_padding, padding_byte_count);
303 memcpy(to + len, padding_buffer, padding_byte_count);
304 ctx->size += padding_byte_count;
305 }
306
307#ifdef DEBUG
308 print_hex_dump(KERN_ERR,
309 "data to encrypt@"__stringify(__LINE__)": ",
310 DUMP_PREFIX_ADDRESS, 16, 4,
311 to, ctx->size, 1);
312#endif
313
314 return 0;
315}
316
317static void mxc_scc_ablkcipher_next(struct mxc_scc_ctx *ctx,
318 struct crypto_async_request *req)
319{
320 struct ablkcipher_request *ablkreq = ablkcipher_request_cast(req);
321 struct mxc_scc *scc = ctx->scc;
322 int err;
323
324 dev_dbg(scc->dev, "dispatch request (nbytes=%d, src=%p, dst=%p)\n",
325 ablkreq->nbytes, ablkreq->src, ablkreq->dst);
326
327 writel(0, scc->base + SCC_SCM_ERROR_STATUS);
328
329 err = mxc_scc_put_data(ctx, ablkreq);
330 if (err) {
331 mxc_scc_ablkcipher_req_complete(req, ctx, err);
332 return;
333 }
334
335 dev_dbg(scc->dev, "Start encryption (0x%p/0x%p)\n",
336 (void *)readl(scc->base + SCC_SCM_RED_START),
337 (void *)readl(scc->base + SCC_SCM_BLACK_START));
338
339 /* clear interrupt control registers */
340 writel(SCC_SCM_INTR_CTRL_CLR_INTR,
341 scc->base + SCC_SCM_INTR_CTRL);
342
343 writel((ctx->size / ctx->scc->block_size_bytes) - 1,
344 scc->base + SCC_SCM_LENGTH);
345
346 dev_dbg(scc->dev, "Process %d block(s) in 0x%p\n",
347 ctx->size / ctx->scc->block_size_bytes,
348 (ctx->ctrl & SCC_SCM_CTRL_DECRYPT_MODE) ? scc->black_memory :
349 scc->red_memory);
350
351 writel(ctx->ctrl, scc->base + SCC_SCM_CTRL);
352}
353
354static irqreturn_t mxc_scc_int(int irq, void *priv)
355{
356 struct crypto_async_request *req;
357 struct mxc_scc_ctx *ctx;
358 struct mxc_scc *scc = priv;
359 int status;
360 int ret;
361
362 status = readl(scc->base + SCC_SCM_STATUS);
363
364 /* clear interrupt control registers */
365 writel(SCC_SCM_INTR_CTRL_CLR_INTR, scc->base + SCC_SCM_INTR_CTRL);
366
367 if (status & SCC_SCM_STATUS_BUSY)
368 return IRQ_NONE;
369
370 req = scc->req;
371 if (req) {
372 ctx = crypto_tfm_ctx(req->tfm);
373 ret = mxc_scc_get_data(ctx, req);
374 if (ret != -EINPROGRESS)
375 mxc_scc_ablkcipher_req_complete(req, ctx, ret);
376 else
377 mxc_scc_ablkcipher_next(ctx, req);
378 }
379
380 return IRQ_HANDLED;
381}
382
383static int mxc_scc_cra_init(struct crypto_tfm *tfm)
384{
385 struct mxc_scc_ctx *ctx = crypto_tfm_ctx(tfm);
386 struct crypto_alg *alg = tfm->__crt_alg;
387 struct mxc_scc_crypto_tmpl *algt;
388
389 algt = container_of(alg, struct mxc_scc_crypto_tmpl, alg);
390
391 ctx->scc = algt->scc;
392 return 0;
393}
394
395static void mxc_scc_dequeue_req_unlocked(struct mxc_scc_ctx *ctx)
396{
397 struct crypto_async_request *req, *backlog;
398
399 if (ctx->scc->hw_busy)
400 return;
401
402 spin_lock_bh(&ctx->scc->lock);
403 backlog = crypto_get_backlog(&ctx->scc->queue);
404 req = crypto_dequeue_request(&ctx->scc->queue);
405 ctx->scc->req = req;
406 ctx->scc->hw_busy = true;
407 spin_unlock_bh(&ctx->scc->lock);
408
409 if (!req)
410 return;
411
412 if (backlog)
413 backlog->complete(backlog, -EINPROGRESS);
414
415 mxc_scc_ablkcipher_next(ctx, req);
416}
417
418static int mxc_scc_queue_req(struct mxc_scc_ctx *ctx,
419 struct crypto_async_request *req)
420{
421 int ret;
422
423 spin_lock_bh(&ctx->scc->lock);
424 ret = crypto_enqueue_request(&ctx->scc->queue, req);
425 spin_unlock_bh(&ctx->scc->lock);
426
427 if (ret != -EINPROGRESS)
428 return ret;
429
430 mxc_scc_dequeue_req_unlocked(ctx);
431
432 return -EINPROGRESS;
433}
434
435static int mxc_scc_des3_op(struct mxc_scc_ctx *ctx,
436 struct ablkcipher_request *req)
437{
438 int err;
439
440 err = mxc_scc_ablkcipher_req_init(req, ctx);
441 if (err)
442 return err;
443
444 return mxc_scc_queue_req(ctx, &req->base);
445}
446
447static int mxc_scc_ecb_des_encrypt(struct ablkcipher_request *req)
448{
449 struct crypto_ablkcipher *cipher = crypto_ablkcipher_reqtfm(req);
450 struct mxc_scc_ctx *ctx = crypto_ablkcipher_ctx(cipher);
451
452 ctx->ctrl = SCC_SCM_CTRL_START_CIPHER;
453
454 return mxc_scc_des3_op(ctx, req);
455}
456
457static int mxc_scc_ecb_des_decrypt(struct ablkcipher_request *req)
458{
459 struct crypto_ablkcipher *cipher = crypto_ablkcipher_reqtfm(req);
460 struct mxc_scc_ctx *ctx = crypto_ablkcipher_ctx(cipher);
461
462 ctx->ctrl = SCC_SCM_CTRL_START_CIPHER;
463 ctx->ctrl |= SCC_SCM_CTRL_DECRYPT_MODE;
464
465 return mxc_scc_des3_op(ctx, req);
466}
467
468static int mxc_scc_cbc_des_encrypt(struct ablkcipher_request *req)
469{
470 struct crypto_ablkcipher *cipher = crypto_ablkcipher_reqtfm(req);
471 struct mxc_scc_ctx *ctx = crypto_ablkcipher_ctx(cipher);
472
473 ctx->ctrl = SCC_SCM_CTRL_START_CIPHER;
474 ctx->ctrl |= SCC_SCM_CTRL_CBC_MODE;
475
476 return mxc_scc_des3_op(ctx, req);
477}
478
479static int mxc_scc_cbc_des_decrypt(struct ablkcipher_request *req)
480{
481 struct crypto_ablkcipher *cipher = crypto_ablkcipher_reqtfm(req);
482 struct mxc_scc_ctx *ctx = crypto_ablkcipher_ctx(cipher);
483
484 ctx->ctrl = SCC_SCM_CTRL_START_CIPHER;
485 ctx->ctrl |= SCC_SCM_CTRL_CBC_MODE;
486 ctx->ctrl |= SCC_SCM_CTRL_DECRYPT_MODE;
487
488 return mxc_scc_des3_op(ctx, req);
489}
490
491static void mxc_scc_hw_init(struct mxc_scc *scc)
492{
493 int offset;
494
495 offset = SCC_NON_RESERVED_OFFSET / scc->block_size_bytes;
496
497 /* Fill the RED_START register */
498 writel(offset, scc->base + SCC_SCM_RED_START);
499
500 /* Fill the BLACK_START register */
501 writel(offset, scc->base + SCC_SCM_BLACK_START);
502
503 scc->red_memory = scc->base + SCC_SCM_RED_MEMORY +
504 SCC_NON_RESERVED_OFFSET;
505
506 scc->black_memory = scc->base + SCC_SCM_BLACK_MEMORY +
507 SCC_NON_RESERVED_OFFSET;
508
509 scc->bytes_remaining = scc->memory_size_bytes;
510}
511
512static int mxc_scc_get_config(struct mxc_scc *scc)
513{
514 int config;
515
516 config = readl(scc->base + SCC_SCM_CFG);
517
518 scc->block_size_bytes = config & SCC_SCM_CFG_BLOCK_SIZE_MASK;
519
520 scc->black_ram_size_blocks = config & SCC_SCM_CFG_BLACK_SIZE_MASK;
521
522 scc->memory_size_bytes = (scc->block_size_bytes *
523 scc->black_ram_size_blocks) -
524 SCC_NON_RESERVED_OFFSET;
525
526 return 0;
527}
528
529static enum mxc_scc_state mxc_scc_get_state(struct mxc_scc *scc)
530{
531 enum mxc_scc_state state;
532 int status;
533
534 status = readl(scc->base + SCC_SMN_STATUS) &
535 SCC_SMN_STATUS_STATE_MASK;
536
537 /* If in Health Check, try to bringup to secure state */
538 if (status & SCC_SMN_STATE_HEALTH_CHECK) {
539 /*
540 * Write a simple algorithm to the Algorithm Sequence
541 * Checker (ASC)
542 */
543 writel(0xaaaa, scc->base + SCC_SMN_SEQ_START);
544 writel(0x5555, scc->base + SCC_SMN_SEQ_END);
545 writel(0x5555, scc->base + SCC_SMN_SEQ_CHECK);
546
547 status = readl(scc->base + SCC_SMN_STATUS) &
548 SCC_SMN_STATUS_STATE_MASK;
549 }
550
551 switch (status) {
552 case SCC_SMN_STATE_NON_SECURE:
553 case SCC_SMN_STATE_SECURE:
554 state = SCC_STATE_OK;
555 break;
556 case SCC_SMN_STATE_FAIL:
557 state = SCC_STATE_FAILED;
558 break;
559 default:
560 state = SCC_STATE_UNIMPLEMENTED;
561 break;
562 }
563
564 return state;
565}
566
567static struct mxc_scc_crypto_tmpl scc_ecb_des = {
568 .alg = {
569 .cra_name = "ecb(des3_ede)",
570 .cra_driver_name = "ecb-des3-scc",
571 .cra_priority = 300,
572 .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER,
573 .cra_blocksize = DES3_EDE_BLOCK_SIZE,
574 .cra_ctxsize = sizeof(struct mxc_scc_ctx),
575 .cra_alignmask = 0,
576 .cra_type = &crypto_ablkcipher_type,
577 .cra_module = THIS_MODULE,
578 .cra_init = mxc_scc_cra_init,
579 .cra_u.ablkcipher = {
580 .min_keysize = DES3_EDE_KEY_SIZE,
581 .max_keysize = DES3_EDE_KEY_SIZE,
582 .encrypt = mxc_scc_ecb_des_encrypt,
583 .decrypt = mxc_scc_ecb_des_decrypt,
584 }
585 }
586};
587
588static struct mxc_scc_crypto_tmpl scc_cbc_des = {
589 .alg = {
590 .cra_name = "cbc(des3_ede)",
591 .cra_driver_name = "cbc-des3-scc",
592 .cra_priority = 300,
593 .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER,
594 .cra_blocksize = DES3_EDE_BLOCK_SIZE,
595 .cra_ctxsize = sizeof(struct mxc_scc_ctx),
596 .cra_alignmask = 0,
597 .cra_type = &crypto_ablkcipher_type,
598 .cra_module = THIS_MODULE,
599 .cra_init = mxc_scc_cra_init,
600 .cra_u.ablkcipher = {
601 .min_keysize = DES3_EDE_KEY_SIZE,
602 .max_keysize = DES3_EDE_KEY_SIZE,
603 .encrypt = mxc_scc_cbc_des_encrypt,
604 .decrypt = mxc_scc_cbc_des_decrypt,
605 }
606 }
607};
608
609static struct mxc_scc_crypto_tmpl *scc_crypto_algs[] = {
610 &scc_ecb_des,
611 &scc_cbc_des,
612};
613
614static int mxc_scc_crypto_register(struct mxc_scc *scc)
615{
616 unsigned int i;
617 int err = 0;
618
619 for (i = 0; i < ARRAY_SIZE(scc_crypto_algs); i++) {
620 scc_crypto_algs[i]->scc = scc;
621 err = crypto_register_alg(&scc_crypto_algs[i]->alg);
622 if (err)
623 goto err_out;
624 }
625
626 return 0;
627
628err_out:
629 for (; i > 0; i--)
630 crypto_unregister_alg(&scc_crypto_algs[i]->alg);
631
632 return err;
633}
634
635static void mxc_scc_crypto_unregister(void)
636{
637 unsigned int i;
638
639 for (i = 0; i < ARRAY_SIZE(scc_crypto_algs); i++)
640 crypto_unregister_alg(&scc_crypto_algs[i]->alg);
641}
642
643static int mxc_scc_probe(struct platform_device *pdev)
644{
645 struct device *dev = &pdev->dev;
646 struct resource *res;
647 struct mxc_scc *scc;
648 enum mxc_scc_state state;
649 int irq;
650 int ret;
651 int i;
652
653 scc = devm_kzalloc(dev, sizeof(*scc), GFP_KERNEL);
654 if (!scc)
655 return -ENOMEM;
656
657 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
658 scc->base = devm_ioremap_resource(dev, res);
659 if (IS_ERR(scc->base))
660 return PTR_ERR(scc->base);
661
662 scc->clk = devm_clk_get(&pdev->dev, "ipg");
663 if (IS_ERR(scc->clk)) {
664 dev_err(dev, "Could not get ipg clock\n");
665 return PTR_ERR(scc->clk);
666 }
667
668 clk_prepare_enable(scc->clk);
669
670 /* clear error status register */
671 writel(0x0, scc->base + SCC_SCM_ERROR_STATUS);
672
673 /* clear interrupt control registers */
674 writel(SCC_SCM_INTR_CTRL_CLR_INTR |
675 SCC_SCM_INTR_CTRL_MASK_INTR,
676 scc->base + SCC_SCM_INTR_CTRL);
677
678 writel(SCC_SMN_COMMAND_CLR_INTR |
679 SCC_SMN_COMMAND_EN_INTR,
680 scc->base + SCC_SMN_COMMAND);
681
682 scc->dev = dev;
683 platform_set_drvdata(pdev, scc);
684
685 ret = mxc_scc_get_config(scc);
686 if (ret)
687 goto err_out;
688
689 state = mxc_scc_get_state(scc);
690
691 if (state != SCC_STATE_OK) {
692 dev_err(dev, "SCC in unusable state %d\n", state);
693 ret = -EINVAL;
694 goto err_out;
695 }
696
697 mxc_scc_hw_init(scc);
698
699 spin_lock_init(&scc->lock);
700 /* FIXME: calculate queue from RAM slots */
701 crypto_init_queue(&scc->queue, 50);
702
703 for (i = 0; i < 2; i++) {
704 irq = platform_get_irq(pdev, i);
705 if (irq < 0) {
706 dev_err(dev, "failed to get irq resource\n");
707 ret = -EINVAL;
708 goto err_out;
709 }
710
711 ret = devm_request_threaded_irq(dev, irq, NULL, mxc_scc_int,
712 IRQF_ONESHOT, dev_name(dev), scc);
713 if (ret)
714 goto err_out;
715 }
716
717 ret = mxc_scc_crypto_register(scc);
718 if (ret) {
719 dev_err(dev, "could not register algorithms");
720 goto err_out;
721 }
722
723 dev_info(dev, "registered successfully.\n");
724
725 return 0;
726
727err_out:
728 clk_disable_unprepare(scc->clk);
729
730 return ret;
731}
732
733static int mxc_scc_remove(struct platform_device *pdev)
734{
735 struct mxc_scc *scc = platform_get_drvdata(pdev);
736
737 mxc_scc_crypto_unregister();
738
739 clk_disable_unprepare(scc->clk);
740
741 return 0;
742}
743
744static const struct of_device_id mxc_scc_dt_ids[] = {
745 { .compatible = "fsl,imx25-scc", .data = NULL, },
746 { /* sentinel */ }
747};
748MODULE_DEVICE_TABLE(of, mxc_scc_dt_ids);
749
750static struct platform_driver mxc_scc_driver = {
751 .probe = mxc_scc_probe,
752 .remove = mxc_scc_remove,
753 .driver = {
754 .name = "mxc-scc",
755 .of_match_table = mxc_scc_dt_ids,
756 },
757};
758
759module_platform_driver(mxc_scc_driver);
760MODULE_AUTHOR("Steffen Trumtrar <kernel@pengutronix.de>");
761MODULE_DESCRIPTION("Freescale i.MX25 SCC Crypto driver");
762MODULE_LICENSE("GPL v2");