Root/package/platform/lantiq/ltq-deu/src/ifxmips_aes.c

1/******************************************************************************
2**
3** FILE NAME : ifxmips_aes.c
4** PROJECT : IFX UEIP
5** MODULES : DEU Module
6**
7** DATE : September 8, 2009
8** AUTHOR : Mohammad Firdaus
9** DESCRIPTION : Data Encryption Unit Driver for AES Algorithm
10** COPYRIGHT : Copyright (c) 2009
11** Infineon Technologies AG
12** Am Campeon 1-12, 85579 Neubiberg, Germany
13**
14** This program is free software; you can redistribute it and/or modify
15** it under the terms of the GNU General Public License as published by
16** the Free Software Foundation; either version 2 of the License, or
17** (at your option) any later version.
18**
19** HISTORY
20** $Date $Author $Comment
21** 08,Sept 2009 Mohammad Firdaus Initial UEIP release
22*******************************************************************************/
23/*!
24 \defgroup IFX_DEU IFX_DEU_DRIVERS
25 \ingroup API
26 \brief ifx DEU driver module
27*/
28
29/*!
30  \file ifxmips_aes.c
31  \ingroup IFX_DEU
32  \brief AES Encryption Driver main file
33*/
34
35/*!
36 \defgroup IFX_AES_FUNCTIONS IFX_AES_FUNCTIONS
37 \ingroup IFX_DEU
38 \brief IFX AES driver Functions
39*/
40
41
42/* Project Header Files */
43#if defined(CONFIG_MODVERSIONS)
44#define MODVERSIONS
45#include <linux/modeversions>
46#endif
47
48#include <linux/version.h>
49#include <linux/module.h>
50#include <linux/init.h>
51#include <linux/proc_fs.h>
52#include <linux/fs.h>
53#include <linux/types.h>
54#include <linux/errno.h>
55#include <linux/crypto.h>
56#include <linux/interrupt.h>
57#include <linux/delay.h>
58#include <asm/byteorder.h>
59#include <crypto/algapi.h>
60
61#include "ifxmips_deu.h"
62
63#if defined(CONFIG_DANUBE)
64#include "ifxmips_deu_danube.h"
65extern int ifx_danube_pre_1_4;
66#elif defined(CONFIG_AR9)
67#include "ifxmips_deu_ar9.h"
68#elif defined(CONFIG_VR9) || defined(CONFIG_AR10)
69#include "ifxmips_deu_vr9.h"
70#else
71#error "Unkown platform"
72#endif
73
74/* DMA related header and variables */
75
76spinlock_t aes_lock;
77#define CRTCL_SECT_INIT spin_lock_init(&aes_lock)
78#define CRTCL_SECT_START spin_lock_irqsave(&aes_lock, flag)
79#define CRTCL_SECT_END spin_unlock_irqrestore(&aes_lock, flag)
80
81/* Definition of constants */
82#define AES_START IFX_AES_CON
83#define AES_MIN_KEY_SIZE 16
84#define AES_MAX_KEY_SIZE 32
85#define AES_BLOCK_SIZE 16
86#define CTR_RFC3686_NONCE_SIZE 4
87#define CTR_RFC3686_IV_SIZE 8
88#define CTR_RFC3686_MAX_KEY_SIZE (AES_MAX_KEY_SIZE + CTR_RFC3686_NONCE_SIZE)
89
90#ifdef CRYPTO_DEBUG
91extern char debug_level;
92#define DPRINTF(level, format, args...) if (level < debug_level) printk(KERN_INFO "[%s %s %d]: " format, __FILE__, __func__, __LINE__, ##args);
93#else
94#define DPRINTF(level, format, args...)
95#endif /* CRYPTO_DEBUG */
96
97/* Function decleration */
98int aes_chip_init(void);
99u32 endian_swap(u32 input);
100u32 input_swap(u32 input);
101u32* memory_alignment(const u8 *arg, u32 *buff_alloc, int in_out, int nbytes);
102void aes_dma_memory_copy(u32 *outcopy, u32 *out_dma, u8 *out_arg, int nbytes);
103void des_dma_memory_copy(u32 *outcopy, u32 *out_dma, u8 *out_arg, int nbytes);
104int aes_memory_allocate(int value);
105int des_memory_allocate(int value);
106void memory_release(u32 *addr);
107
108
109extern void ifx_deu_aes (void *ctx_arg, uint8_t *out_arg, const uint8_t *in_arg,
110        uint8_t *iv_arg, size_t nbytes, int encdec, int mode);
111/* End of function decleration */
112
113struct aes_ctx {
114    int key_length;
115    u32 buf[AES_MAX_KEY_SIZE];
116    u8 nonce[CTR_RFC3686_NONCE_SIZE];
117};
118
119extern int disable_deudma;
120extern int disable_multiblock;
121
122/*! \fn int aes_set_key (struct crypto_tfm *tfm, const uint8_t *in_key, unsigned int key_len)
123 * \ingroup IFX_AES_FUNCTIONS
124 * \brief sets the AES keys
125 * \param tfm linux crypto algo transform
126 * \param in_key input key
127 * \param key_len key lengths of 16, 24 and 32 bytes supported
128 * \return -EINVAL - bad key length, 0 - SUCCESS
129*/
130int aes_set_key (struct crypto_tfm *tfm, const u8 *in_key, unsigned int key_len)
131{
132    struct aes_ctx *ctx = crypto_tfm_ctx(tfm);
133    unsigned long *flags = (unsigned long *) &tfm->crt_flags;
134
135    //printk("set_key in %s\n", __FILE__);
136
137    //aes_chip_init();
138
139    if (key_len != 16 && key_len != 24 && key_len != 32) {
140        *flags |= CRYPTO_TFM_RES_BAD_KEY_LEN;
141        return -EINVAL;
142    }
143
144    ctx->key_length = key_len;
145    DPRINTF(0, "ctx @%p, key_len %d, ctx->key_length %d\n", ctx, key_len, ctx->key_length);
146    memcpy ((u8 *) (ctx->buf), in_key, key_len);
147
148    return 0;
149}
150
151
152/*! \fn void ifx_deu_aes (void *ctx_arg, u8 *out_arg, const u8 *in_arg, u8 *iv_arg, size_t nbytes, int encdec, int mode)
153 * \ingroup IFX_AES_FUNCTIONS
154 * \brief main interface to AES hardware
155 * \param ctx_arg crypto algo context
156 * \param out_arg output bytestream
157 * \param in_arg input bytestream
158 * \param iv_arg initialization vector
159 * \param nbytes length of bytestream
160 * \param encdec 1 for encrypt; 0 for decrypt
161 * \param mode operation mode such as ebc, cbc, ctr
162 *
163*/
164void ifx_deu_aes (void *ctx_arg, u8 *out_arg, const u8 *in_arg,
165        u8 *iv_arg, size_t nbytes, int encdec, int mode)
166
167{
168    /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
169    volatile struct aes_t *aes = (volatile struct aes_t *) AES_START;
170    struct aes_ctx *ctx = (struct aes_ctx *)ctx_arg;
171    u32 *in_key = ctx->buf;
172    unsigned long flag;
173    /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
174    int key_len = ctx->key_length;
175
176    int i = 0;
177    int byte_cnt = nbytes;
178
179
180    CRTCL_SECT_START;
181    /* 128, 192 or 256 bit key length */
182    aes->controlr.K = key_len / 8 - 2;
183        if (key_len == 128 / 8) {
184        aes->K3R = DEU_ENDIAN_SWAP(*((u32 *) in_key + 0));
185        aes->K2R = DEU_ENDIAN_SWAP(*((u32 *) in_key + 1));
186        aes->K1R = DEU_ENDIAN_SWAP(*((u32 *) in_key + 2));
187        aes->K0R = DEU_ENDIAN_SWAP(*((u32 *) in_key + 3));
188    }
189    else if (key_len == 192 / 8) {
190        aes->K5R = DEU_ENDIAN_SWAP(*((u32 *) in_key + 0));
191        aes->K4R = DEU_ENDIAN_SWAP(*((u32 *) in_key + 1));
192        aes->K3R = DEU_ENDIAN_SWAP(*((u32 *) in_key + 2));
193        aes->K2R = DEU_ENDIAN_SWAP(*((u32 *) in_key + 3));
194        aes->K1R = DEU_ENDIAN_SWAP(*((u32 *) in_key + 4));
195        aes->K0R = DEU_ENDIAN_SWAP(*((u32 *) in_key + 5));
196    }
197    else if (key_len == 256 / 8) {
198        aes->K7R = DEU_ENDIAN_SWAP(*((u32 *) in_key + 0));
199        aes->K6R = DEU_ENDIAN_SWAP(*((u32 *) in_key + 1));
200        aes->K5R = DEU_ENDIAN_SWAP(*((u32 *) in_key + 2));
201        aes->K4R = DEU_ENDIAN_SWAP(*((u32 *) in_key + 3));
202        aes->K3R = DEU_ENDIAN_SWAP(*((u32 *) in_key + 4));
203        aes->K2R = DEU_ENDIAN_SWAP(*((u32 *) in_key + 5));
204        aes->K1R = DEU_ENDIAN_SWAP(*((u32 *) in_key + 6));
205        aes->K0R = DEU_ENDIAN_SWAP(*((u32 *) in_key + 7));
206    }
207    else {
208        printk (KERN_ERR "[%s %s %d]: Invalid key_len : %d\n", __FILE__, __func__, __LINE__, key_len);
209        CRTCL_SECT_END;
210        return;// -EINVAL;
211    }
212
213    /* let HW pre-process DEcryption key in any case (even if
214       ENcryption is used). Key Valid (KV) bit is then only
215       checked in decryption routine! */
216    aes->controlr.PNK = 1;
217
218
219    aes->controlr.E_D = !encdec; //encryption
220    aes->controlr.O = mode; //0 ECB 1 CBC 2 OFB 3 CFB 4 CTR
221
222    //aes->controlr.F = 128; //default; only for CFB and OFB modes; change only for customer-specific apps
223    if (mode > 0) {
224        aes->IV3R = DEU_ENDIAN_SWAP(*(u32 *) iv_arg);
225        aes->IV2R = DEU_ENDIAN_SWAP(*((u32 *) iv_arg + 1));
226        aes->IV1R = DEU_ENDIAN_SWAP(*((u32 *) iv_arg + 2));
227        aes->IV0R = DEU_ENDIAN_SWAP(*((u32 *) iv_arg + 3));
228    };
229
230
231    i = 0;
232    while (byte_cnt >= 16) {
233
234        aes->ID3R = INPUT_ENDIAN_SWAP(*((u32 *) in_arg + (i * 4) + 0));
235        aes->ID2R = INPUT_ENDIAN_SWAP(*((u32 *) in_arg + (i * 4) + 1));
236        aes->ID1R = INPUT_ENDIAN_SWAP(*((u32 *) in_arg + (i * 4) + 2));
237        aes->ID0R = INPUT_ENDIAN_SWAP(*((u32 *) in_arg + (i * 4) + 3)); /* start crypto */
238        
239        while (aes->controlr.BUS) {
240            // this will not take long
241        }
242
243        *((volatile u32 *) out_arg + (i * 4) + 0) = aes->OD3R;
244        *((volatile u32 *) out_arg + (i * 4) + 1) = aes->OD2R;
245        *((volatile u32 *) out_arg + (i * 4) + 2) = aes->OD1R;
246        *((volatile u32 *) out_arg + (i * 4) + 3) = aes->OD0R;
247
248        i++;
249        byte_cnt -= 16;
250    }
251
252
253    //tc.chen : copy iv_arg back
254    if (mode > 0) {
255        *((u32 *) iv_arg) = DEU_ENDIAN_SWAP(*((u32 *) iv_arg));
256        *((u32 *) iv_arg + 1) = DEU_ENDIAN_SWAP(*((u32 *) iv_arg + 1));
257        *((u32 *) iv_arg + 2) = DEU_ENDIAN_SWAP(*((u32 *) iv_arg + 2));
258        *((u32 *) iv_arg + 3) = DEU_ENDIAN_SWAP(*((u32 *) iv_arg + 3));
259    }
260
261    CRTCL_SECT_END;
262}
263
264/*!
265 * \fn int ctr_rfc3686_aes_set_key (struct crypto_tfm *tfm, const uint8_t *in_key, unsigned int key_len)
266 * \ingroup IFX_AES_FUNCTIONS
267 * \brief sets RFC3686 key
268 * \param tfm linux crypto algo transform
269 * \param in_key input key
270 * \param key_len key lengths of 20, 28 and 36 bytes supported; last 4 bytes is nonce
271 * \return 0 - SUCCESS
272 * -EINVAL - bad key length
273*/
274int ctr_rfc3686_aes_set_key (struct crypto_tfm *tfm, const uint8_t *in_key, unsigned int key_len)
275{
276    struct aes_ctx *ctx = crypto_tfm_ctx(tfm);
277    unsigned long *flags = (unsigned long *)&tfm->crt_flags;
278
279    //printk("ctr_rfc3686_aes_set_key in %s\n", __FILE__);
280
281    memcpy(ctx->nonce, in_key + (key_len - CTR_RFC3686_NONCE_SIZE),
282           CTR_RFC3686_NONCE_SIZE);
283
284    key_len -= CTR_RFC3686_NONCE_SIZE; // remove 4 bytes of nonce
285
286    if (key_len != 16 && key_len != 24 && key_len != 32) {
287        *flags |= CRYPTO_TFM_RES_BAD_KEY_LEN;
288        return -EINVAL;
289    }
290
291    ctx->key_length = key_len;
292    
293    memcpy ((u8 *) (ctx->buf), in_key, key_len);
294
295    return 0;
296}
297
298/*! \fn void ifx_deu_aes (void *ctx_arg, u8 *out_arg, const u8 *in_arg, u8 *iv_arg, u32 nbytes, int encdec, int mode)
299 * \ingroup IFX_AES_FUNCTIONS
300 * \brief main interface with deu hardware in DMA mode
301 * \param ctx_arg crypto algo context
302 * \param out_arg output bytestream
303 * \param in_arg input bytestream
304 * \param iv_arg initialization vector
305 * \param nbytes length of bytestream
306 * \param encdec 1 for encrypt; 0 for decrypt
307 * \param mode operation mode such as ebc, cbc, ctr
308*/
309
310
311//definitions from linux/include/crypto.h:
312//#define CRYPTO_TFM_MODE_ECB 0x00000001
313//#define CRYPTO_TFM_MODE_CBC 0x00000002
314//#define CRYPTO_TFM_MODE_CFB 0x00000004
315//#define CRYPTO_TFM_MODE_CTR 0x00000008
316//#define CRYPTO_TFM_MODE_OFB 0x00000010 // not even defined
317//but hardware definition: 0 ECB 1 CBC 2 OFB 3 CFB 4 CTR
318
319/*! \fn void ifx_deu_aes_ecb (void *ctx, uint8_t *dst, const uint8_t *src, uint8_t *iv, size_t nbytes, int encdec, int inplace)
320 * \ingroup IFX_AES_FUNCTIONS
321 * \brief sets AES hardware to ECB mode
322 * \param ctx crypto algo context
323 * \param dst output bytestream
324 * \param src input bytestream
325 * \param iv initialization vector
326 * \param nbytes length of bytestream
327 * \param encdec 1 for encrypt; 0 for decrypt
328 * \param inplace not used
329*/
330void ifx_deu_aes_ecb (void *ctx, uint8_t *dst, const uint8_t *src,
331        uint8_t *iv, size_t nbytes, int encdec, int inplace)
332{
333     ifx_deu_aes (ctx, dst, src, NULL, nbytes, encdec, 0);
334}
335
336/*! \fn void ifx_deu_aes_cbc (void *ctx, uint8_t *dst, const uint8_t *src, uint8_t *iv, size_t nbytes, int encdec, int inplace)
337 * \ingroup IFX_AES_FUNCTIONS
338 * \brief sets AES hardware to CBC mode
339 * \param ctx crypto algo context
340 * \param dst output bytestream
341 * \param src input bytestream
342 * \param iv initialization vector
343 * \param nbytes length of bytestream
344 * \param encdec 1 for encrypt; 0 for decrypt
345 * \param inplace not used
346*/
347void ifx_deu_aes_cbc (void *ctx, uint8_t *dst, const uint8_t *src,
348        uint8_t *iv, size_t nbytes, int encdec, int inplace)
349{
350     ifx_deu_aes (ctx, dst, src, iv, nbytes, encdec, 1);
351}
352
353/*! \fn void ifx_deu_aes_ofb (void *ctx, uint8_t *dst, const uint8_t *src, uint8_t *iv, size_t nbytes, int encdec, int inplace)
354 * \ingroup IFX_AES_FUNCTIONS
355 * \brief sets AES hardware to OFB mode
356 * \param ctx crypto algo context
357 * \param dst output bytestream
358 * \param src input bytestream
359 * \param iv initialization vector
360 * \param nbytes length of bytestream
361 * \param encdec 1 for encrypt; 0 for decrypt
362 * \param inplace not used
363*/
364void ifx_deu_aes_ofb (void *ctx, uint8_t *dst, const uint8_t *src,
365        uint8_t *iv, size_t nbytes, int encdec, int inplace)
366{
367     ifx_deu_aes (ctx, dst, src, iv, nbytes, encdec, 2);
368}
369
370/*! \fn void ifx_deu_aes_cfb (void *ctx, uint8_t *dst, const uint8_t *src, uint8_t *iv, size_t nbytes, int encdec, int inplace)
371 * \ingroup IFX_AES_FUNCTIONS
372 * \brief sets AES hardware to CFB mode
373 * \param ctx crypto algo context
374 * \param dst output bytestream
375 * \param src input bytestream
376 * \param iv initialization vector
377 * \param nbytes length of bytestream
378 * \param encdec 1 for encrypt; 0 for decrypt
379 * \param inplace not used
380*/
381void ifx_deu_aes_cfb (void *ctx, uint8_t *dst, const uint8_t *src,
382        uint8_t *iv, size_t nbytes, int encdec, int inplace)
383{
384     ifx_deu_aes (ctx, dst, src, iv, nbytes, encdec, 3);
385}
386
387/*! \fn void ifx_deu_aes_ctr (void *ctx, uint8_t *dst, const uint8_t *src, uint8_t *iv, size_t nbytes, int encdec, int inplace)
388 * \ingroup IFX_AES_FUNCTIONS
389 * \brief sets AES hardware to CTR mode
390 * \param ctx crypto algo context
391 * \param dst output bytestream
392 * \param src input bytestream
393 * \param iv initialization vector
394 * \param nbytes length of bytestream
395 * \param encdec 1 for encrypt; 0 for decrypt
396 * \param inplace not used
397*/
398void ifx_deu_aes_ctr (void *ctx, uint8_t *dst, const uint8_t *src,
399        uint8_t *iv, size_t nbytes, int encdec, int inplace)
400{
401     ifx_deu_aes (ctx, dst, src, iv, nbytes, encdec, 4);
402}
403
404/*! \fn void aes_encrypt (struct crypto_tfm *tfm, uint8_t *out, const uint8_t *in)
405 * \ingroup IFX_AES_FUNCTIONS
406 * \brief encrypt AES_BLOCK_SIZE of data
407 * \param tfm linux crypto algo transform
408 * \param out output bytestream
409 * \param in input bytestream
410*/
411void aes_encrypt (struct crypto_tfm *tfm, uint8_t *out, const uint8_t *in)
412{
413    struct aes_ctx *ctx = crypto_tfm_ctx(tfm);
414    ifx_deu_aes (ctx, out, in, NULL, AES_BLOCK_SIZE,
415            CRYPTO_DIR_ENCRYPT, 0);
416}
417
418/*! \fn void aes_decrypt (struct crypto_tfm *tfm, uint8_t *out, const uint8_t *in)
419 * \ingroup IFX_AES_FUNCTIONS
420 * \brief decrypt AES_BLOCK_SIZE of data
421 * \param tfm linux crypto algo transform
422 * \param out output bytestream
423 * \param in input bytestream
424*/
425void aes_decrypt (struct crypto_tfm *tfm, uint8_t *out, const uint8_t *in)
426{
427    struct aes_ctx *ctx = crypto_tfm_ctx(tfm);
428    ifx_deu_aes (ctx, out, in, NULL, AES_BLOCK_SIZE,
429            CRYPTO_DIR_DECRYPT, 0);
430}
431
432/*
433 * \brief AES function mappings
434*/
435struct crypto_alg ifxdeu_aes_alg = {
436    .cra_name = "aes",
437    .cra_driver_name = "ifxdeu-aes",
438    .cra_flags = CRYPTO_ALG_TYPE_CIPHER,
439    .cra_blocksize = AES_BLOCK_SIZE,
440    .cra_ctxsize = sizeof(struct aes_ctx),
441    .cra_module = THIS_MODULE,
442    .cra_list = LIST_HEAD_INIT(ifxdeu_aes_alg.cra_list),
443    .cra_u = {
444        .cipher = {
445            .cia_min_keysize = AES_MIN_KEY_SIZE,
446            .cia_max_keysize = AES_MAX_KEY_SIZE,
447            .cia_setkey = aes_set_key,
448            .cia_encrypt = aes_encrypt,
449            .cia_decrypt = aes_decrypt,
450        }
451    }
452};
453
454/*! \fn int ecb_aes_encrypt(struct blkcipher_desc *desc, struct scatterlist *dst, struct scatterlist *src, unsigned int nbytes)
455 * \ingroup IFX_AES_FUNCTIONS
456 * \brief ECB AES encrypt using linux crypto blkcipher
457 * \param desc blkcipher descriptor
458 * \param dst output scatterlist
459 * \param src input scatterlist
460 * \param nbytes data size in bytes
461 * \return err
462*/
463int ecb_aes_encrypt(struct blkcipher_desc *desc,
464               struct scatterlist *dst, struct scatterlist *src,
465               unsigned int nbytes)
466{
467    struct aes_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
468    struct blkcipher_walk walk;
469    int err;
470    
471    blkcipher_walk_init(&walk, dst, src, nbytes);
472    err = blkcipher_walk_virt(desc, &walk);
473
474    while ((nbytes = walk.nbytes)) {
475            nbytes -= (nbytes % AES_BLOCK_SIZE);
476        ifx_deu_aes_ecb(ctx, walk.dst.virt.addr, walk.src.virt.addr,
477                       NULL, nbytes, CRYPTO_DIR_ENCRYPT, 0);
478                nbytes &= AES_BLOCK_SIZE - 1;
479        err = blkcipher_walk_done(desc, &walk, nbytes);
480    }
481
482    return err;
483}
484
485/*! \fn int ecb_aes_decrypt(struct blkcipher_desc *desc, struct scatterlist *dst, struct scatterlist *src, unsigned int nbytes)
486 * \ingroup IFX_AES_FUNCTIONS
487 * \brief ECB AES decrypt using linux crypto blkcipher
488 * \param desc blkcipher descriptor
489 * \param dst output scatterlist
490 * \param src input scatterlist
491 * \param nbytes data size in bytes
492 * \return err
493*/
494int ecb_aes_decrypt(struct blkcipher_desc *desc,
495               struct scatterlist *dst, struct scatterlist *src,
496               unsigned int nbytes)
497{
498    struct aes_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
499    struct blkcipher_walk walk;
500    int err;
501
502    blkcipher_walk_init(&walk, dst, src, nbytes);
503    err = blkcipher_walk_virt(desc, &walk);
504
505    while ((nbytes = walk.nbytes)) {
506            nbytes -= (nbytes % AES_BLOCK_SIZE);
507        ifx_deu_aes_ecb(ctx, walk.dst.virt.addr, walk.src.virt.addr,
508                       NULL, nbytes, CRYPTO_DIR_DECRYPT, 0);
509        nbytes &= AES_BLOCK_SIZE - 1;
510        err = blkcipher_walk_done(desc, &walk, nbytes);
511    }
512
513    return err;
514}
515
516/*
517 * \brief AES function mappings
518*/
519struct crypto_alg ifxdeu_ecb_aes_alg = {
520    .cra_name = "ecb(aes)",
521    .cra_driver_name = "ifxdeu-ecb(aes)",
522    .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER,
523    .cra_blocksize = AES_BLOCK_SIZE,
524    .cra_ctxsize = sizeof(struct aes_ctx),
525    .cra_type = &crypto_blkcipher_type,
526    .cra_module = THIS_MODULE,
527    .cra_list = LIST_HEAD_INIT(ifxdeu_ecb_aes_alg.cra_list),
528    .cra_u = {
529        .blkcipher = {
530            .min_keysize = AES_MIN_KEY_SIZE,
531            .max_keysize = AES_MAX_KEY_SIZE,
532            .setkey = aes_set_key,
533            .encrypt = ecb_aes_encrypt,
534            .decrypt = ecb_aes_decrypt,
535        }
536    }
537};
538
539
540/*! \fn int cbc_aes_encrypt(struct blkcipher_desc *desc, struct scatterlist *dst, struct scatterlist *src, unsigned int nbytes)
541 * \ingroup IFX_AES_FUNCTIONS
542 * \brief CBC AES encrypt using linux crypto blkcipher
543 * \param desc blkcipher descriptor
544 * \param dst output scatterlist
545 * \param src input scatterlist
546 * \param nbytes data size in bytes
547 * \return err
548*/
549int cbc_aes_encrypt(struct blkcipher_desc *desc,
550               struct scatterlist *dst, struct scatterlist *src,
551               unsigned int nbytes)
552{
553    struct aes_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
554    struct blkcipher_walk walk;
555    int err;
556
557    blkcipher_walk_init(&walk, dst, src, nbytes);
558    err = blkcipher_walk_virt(desc, &walk);
559
560    while ((nbytes = walk.nbytes)) {
561            u8 *iv = walk.iv;
562            nbytes -= (nbytes % AES_BLOCK_SIZE);
563            ifx_deu_aes_cbc(ctx, walk.dst.virt.addr, walk.src.virt.addr,
564                       iv, nbytes, CRYPTO_DIR_ENCRYPT, 0);
565        nbytes &= AES_BLOCK_SIZE - 1;
566        err = blkcipher_walk_done(desc, &walk, nbytes);
567    }
568
569    return err;
570}
571
572/*! \fn int cbc_aes_decrypt(struct blkcipher_desc *desc, struct scatterlist *dst, struct scatterlist *src, unsigned int nbytes)
573 * \ingroup IFX_AES_FUNCTIONS
574 * \brief CBC AES decrypt using linux crypto blkcipher
575 * \param desc blkcipher descriptor
576 * \param dst output scatterlist
577 * \param src input scatterlist
578 * \param nbytes data size in bytes
579 * \return err
580*/
581int cbc_aes_decrypt(struct blkcipher_desc *desc,
582               struct scatterlist *dst, struct scatterlist *src,
583               unsigned int nbytes)
584{
585    struct aes_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
586    struct blkcipher_walk walk;
587    int err;
588
589    blkcipher_walk_init(&walk, dst, src, nbytes);
590    err = blkcipher_walk_virt(desc, &walk);
591
592    while ((nbytes = walk.nbytes)) {
593        u8 *iv = walk.iv;
594            nbytes -= (nbytes % AES_BLOCK_SIZE);
595            ifx_deu_aes_cbc(ctx, walk.dst.virt.addr, walk.src.virt.addr,
596                       iv, nbytes, CRYPTO_DIR_DECRYPT, 0);
597        nbytes &= AES_BLOCK_SIZE - 1;
598        err = blkcipher_walk_done(desc, &walk, nbytes);
599    }
600
601    return err;
602}
603
604/*
605 * \brief AES function mappings
606*/
607struct crypto_alg ifxdeu_cbc_aes_alg = {
608    .cra_name = "cbc(aes)",
609    .cra_driver_name = "ifxdeu-cbc(aes)",
610    .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER,
611    .cra_blocksize = AES_BLOCK_SIZE,
612    .cra_ctxsize = sizeof(struct aes_ctx),
613    .cra_type = &crypto_blkcipher_type,
614    .cra_module = THIS_MODULE,
615    .cra_list = LIST_HEAD_INIT(ifxdeu_cbc_aes_alg.cra_list),
616    .cra_u = {
617        .blkcipher = {
618            .min_keysize = AES_MIN_KEY_SIZE,
619            .max_keysize = AES_MAX_KEY_SIZE,
620            .ivsize = AES_BLOCK_SIZE,
621            .setkey = aes_set_key,
622            .encrypt = cbc_aes_encrypt,
623            .decrypt = cbc_aes_decrypt,
624        }
625    }
626};
627
628
629/*! \fn int ctr_basic_aes_encrypt(struct blkcipher_desc *desc, struct scatterlist *dst, struct scatterlist *src, unsigned int nbytes)
630 * \ingroup IFX_AES_FUNCTIONS
631 * \brief Counter mode AES encrypt using linux crypto blkcipher
632 * \param desc blkcipher descriptor
633 * \param dst output scatterlist
634 * \param src input scatterlist
635 * \param nbytes data size in bytes
636 * \return err
637*/
638int ctr_basic_aes_encrypt(struct blkcipher_desc *desc,
639               struct scatterlist *dst, struct scatterlist *src,
640               unsigned int nbytes)
641{
642    struct aes_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
643    struct blkcipher_walk walk;
644    int err;
645
646    blkcipher_walk_init(&walk, dst, src, nbytes);
647    err = blkcipher_walk_virt(desc, &walk);
648
649    while ((nbytes = walk.nbytes)) {
650            u8 *iv = walk.iv;
651            nbytes -= (nbytes % AES_BLOCK_SIZE);
652            ifx_deu_aes_ctr(ctx, walk.dst.virt.addr, walk.src.virt.addr,
653                       iv, nbytes, CRYPTO_DIR_ENCRYPT, 0);
654        nbytes &= AES_BLOCK_SIZE - 1;
655        err = blkcipher_walk_done(desc, &walk, nbytes);
656    }
657
658    return err;
659}
660
661/*! \fn int ctr_basic_aes_decrypt(struct blkcipher_desc *desc, struct scatterlist *dst, struct scatterlist *src, unsigned int nbytes)
662 * \ingroup IFX_AES_FUNCTIONS
663 * \brief Counter mode AES decrypt using linux crypto blkcipher
664 * \param desc blkcipher descriptor
665 * \param dst output scatterlist
666 * \param src input scatterlist
667 * \param nbytes data size in bytes
668 * \return err
669*/
670int ctr_basic_aes_decrypt(struct blkcipher_desc *desc,
671               struct scatterlist *dst, struct scatterlist *src,
672               unsigned int nbytes)
673{
674    struct aes_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
675    struct blkcipher_walk walk;
676    int err;
677
678    blkcipher_walk_init(&walk, dst, src, nbytes);
679    err = blkcipher_walk_virt(desc, &walk);
680
681    while ((nbytes = walk.nbytes)) {
682        u8 *iv = walk.iv;
683            nbytes -= (nbytes % AES_BLOCK_SIZE);
684            ifx_deu_aes_ctr(ctx, walk.dst.virt.addr, walk.src.virt.addr,
685                       iv, nbytes, CRYPTO_DIR_DECRYPT, 0);
686        nbytes &= AES_BLOCK_SIZE - 1;
687        err = blkcipher_walk_done(desc, &walk, nbytes);
688    }
689
690    return err;
691}
692
693/*
694 * \brief AES function mappings
695*/
696struct crypto_alg ifxdeu_ctr_basic_aes_alg = {
697    .cra_name = "ctr(aes)",
698    .cra_driver_name = "ifxdeu-ctr(aes)",
699    .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER,
700    .cra_blocksize = AES_BLOCK_SIZE,
701    .cra_ctxsize = sizeof(struct aes_ctx),
702    .cra_type = &crypto_blkcipher_type,
703    .cra_module = THIS_MODULE,
704    .cra_list = LIST_HEAD_INIT(ifxdeu_ctr_basic_aes_alg.cra_list),
705    .cra_u = {
706        .blkcipher = {
707            .min_keysize = AES_MIN_KEY_SIZE,
708            .max_keysize = AES_MAX_KEY_SIZE,
709            .ivsize = AES_BLOCK_SIZE,
710            .setkey = aes_set_key,
711            .encrypt = ctr_basic_aes_encrypt,
712            .decrypt = ctr_basic_aes_decrypt,
713        }
714    }
715};
716
717
718/*! \fn int ctr_rfc3686_aes_encrypt(struct blkcipher_desc *desc, struct scatterlist *dst, struct scatterlist *src, unsigned int nbytes)
719 * \ingroup IFX_AES_FUNCTIONS
720 * \brief Counter mode AES (rfc3686) encrypt using linux crypto blkcipher
721 * \param desc blkcipher descriptor
722 * \param dst output scatterlist
723 * \param src input scatterlist
724 * \param nbytes data size in bytes
725 * \return err
726*/
727int ctr_rfc3686_aes_encrypt(struct blkcipher_desc *desc,
728               struct scatterlist *dst, struct scatterlist *src,
729               unsigned int nbytes)
730{
731    struct aes_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
732    struct blkcipher_walk walk;
733    int err;
734    u8 rfc3686_iv[16];
735
736    blkcipher_walk_init(&walk, dst, src, nbytes);
737    err = blkcipher_walk_virt(desc, &walk);
738    
739    /* set up counter block */
740    memcpy(rfc3686_iv, ctx->nonce, CTR_RFC3686_NONCE_SIZE);
741    memcpy(rfc3686_iv + CTR_RFC3686_NONCE_SIZE, walk.iv, CTR_RFC3686_IV_SIZE);
742
743    /* initialize counter portion of counter block */
744    *(__be32 *)(rfc3686_iv + CTR_RFC3686_NONCE_SIZE + CTR_RFC3686_IV_SIZE) =
745        cpu_to_be32(1);
746
747    while ((nbytes = walk.nbytes)) {
748            nbytes -= (nbytes % AES_BLOCK_SIZE);
749            ifx_deu_aes_ctr(ctx, walk.dst.virt.addr, walk.src.virt.addr,
750                       rfc3686_iv, nbytes, CRYPTO_DIR_ENCRYPT, 0);
751        nbytes &= AES_BLOCK_SIZE - 1;
752        err = blkcipher_walk_done(desc, &walk, nbytes);
753    }
754   
755    return err;
756}
757
758/*! \fn int ctr_rfc3686_aes_decrypt(struct blkcipher_desc *desc, struct scatterlist *dst, struct scatterlist *src, unsigned int nbytes)
759 * \ingroup IFX_AES_FUNCTIONS
760 * \brief Counter mode AES (rfc3686) decrypt using linux crypto blkcipher
761 * \param desc blkcipher descriptor
762 * \param dst output scatterlist
763 * \param src input scatterlist
764 * \param nbytes data size in bytes
765 * \return err
766*/
767int ctr_rfc3686_aes_decrypt(struct blkcipher_desc *desc,
768               struct scatterlist *dst, struct scatterlist *src,
769               unsigned int nbytes)
770{
771    struct aes_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
772    struct blkcipher_walk walk;
773    int err;
774    u8 rfc3686_iv[16];
775
776    blkcipher_walk_init(&walk, dst, src, nbytes);
777    err = blkcipher_walk_virt(desc, &walk);
778
779    /* set up counter block */
780    memcpy(rfc3686_iv, ctx->nonce, CTR_RFC3686_NONCE_SIZE);
781    memcpy(rfc3686_iv + CTR_RFC3686_NONCE_SIZE, walk.iv, CTR_RFC3686_IV_SIZE);
782
783    /* initialize counter portion of counter block */
784    *(__be32 *)(rfc3686_iv + CTR_RFC3686_NONCE_SIZE + CTR_RFC3686_IV_SIZE) =
785        cpu_to_be32(1);
786
787    while ((nbytes = walk.nbytes)) {
788            nbytes -= (nbytes % AES_BLOCK_SIZE);
789            ifx_deu_aes_ctr(ctx, walk.dst.virt.addr, walk.src.virt.addr,
790                       rfc3686_iv, nbytes, CRYPTO_DIR_DECRYPT, 0);
791        nbytes &= AES_BLOCK_SIZE - 1;
792        err = blkcipher_walk_done(desc, &walk, nbytes);
793    }
794
795    return err;
796}
797
798/*
799 * \brief AES function mappings
800*/
801struct crypto_alg ifxdeu_ctr_rfc3686_aes_alg = {
802    .cra_name = "rfc3686(ctr(aes))",
803    .cra_driver_name = "ifxdeu-ctr-rfc3686(aes)",
804    .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER,
805    .cra_blocksize = AES_BLOCK_SIZE,
806    .cra_ctxsize = sizeof(struct aes_ctx),
807    .cra_type = &crypto_blkcipher_type,
808    .cra_module = THIS_MODULE,
809    .cra_list = LIST_HEAD_INIT(ifxdeu_ctr_rfc3686_aes_alg.cra_list),
810    .cra_u = {
811        .blkcipher = {
812            .min_keysize = AES_MIN_KEY_SIZE,
813            .max_keysize = CTR_RFC3686_MAX_KEY_SIZE,
814            .ivsize = CTR_RFC3686_IV_SIZE,
815            .setkey = ctr_rfc3686_aes_set_key,
816            .encrypt = ctr_rfc3686_aes_encrypt,
817            .decrypt = ctr_rfc3686_aes_decrypt,
818        }
819    }
820};
821
822
823/*! \fn int __init ifxdeu_init_aes (void)
824 * \ingroup IFX_AES_FUNCTIONS
825 * \brief function to initialize AES driver
826 * \return ret
827*/
828int __init ifxdeu_init_aes (void)
829{
830    int ret = -ENOSYS;
831
832
833 
834#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20))
835    if (!disable_multiblock) {
836        ifxdeu_aes_alg.cra_u.cipher.cia_max_nbytes = AES_BLOCK_SIZE; //(size_t)-1;
837        ifxdeu_aes_alg.cra_u.cipher.cia_req_align = 16;
838        ifxdeu_aes_alg.cra_u.cipher.cia_ecb = ifx_deu_aes_ecb;
839        ifxdeu_aes_alg.cra_u.cipher.cia_cbc = ifx_deu_aes_cbc;
840        ifxdeu_aes_alg.cra_u.cipher.cia_cfb = ifx_deu_aes_cfb;
841        ifxdeu_aes_alg.cra_u.cipher.cia_ofb = ifx_deu_aes_ofb;
842    }
843#endif
844
845    if ((ret = crypto_register_alg(&ifxdeu_aes_alg)))
846        goto aes_err;
847
848    if ((ret = crypto_register_alg(&ifxdeu_ecb_aes_alg)))
849        goto ecb_aes_err;
850
851    if ((ret = crypto_register_alg(&ifxdeu_cbc_aes_alg)))
852        goto cbc_aes_err;
853
854    if ((ret = crypto_register_alg(&ifxdeu_ctr_basic_aes_alg)))
855        goto ctr_basic_aes_err;
856
857    if ((ret = crypto_register_alg(&ifxdeu_ctr_rfc3686_aes_alg)))
858        goto ctr_rfc3686_aes_err;
859
860    aes_chip_init ();
861
862    CRTCL_SECT_INIT;
863
864
865    printk (KERN_NOTICE "IFX DEU AES initialized%s%s.\n", disable_multiblock ? "" : " (multiblock)", disable_deudma ? "" : " (DMA)");
866    return ret;
867
868ctr_rfc3686_aes_err:
869    crypto_unregister_alg(&ifxdeu_ctr_rfc3686_aes_alg);
870    printk (KERN_ERR "IFX ctr_rfc3686_aes initialization failed!\n");
871    return ret;
872ctr_basic_aes_err:
873    crypto_unregister_alg(&ifxdeu_ctr_basic_aes_alg);
874    printk (KERN_ERR "IFX ctr_basic_aes initialization failed!\n");
875    return ret;
876cbc_aes_err:
877    crypto_unregister_alg(&ifxdeu_cbc_aes_alg);
878    printk (KERN_ERR "IFX cbc_aes initialization failed!\n");
879    return ret;
880ecb_aes_err:
881    crypto_unregister_alg(&ifxdeu_ecb_aes_alg);
882    printk (KERN_ERR "IFX aes initialization failed!\n");
883    return ret;
884aes_err:
885    printk(KERN_ERR "IFX DEU AES initialization failed!\n");
886
887    return ret;
888}
889
890/*! \fn void __exit ifxdeu_fini_aes (void)
891 * \ingroup IFX_AES_FUNCTIONS
892 * \brief unregister aes driver
893*/
894void __exit ifxdeu_fini_aes (void)
895{
896    crypto_unregister_alg (&ifxdeu_aes_alg);
897    crypto_unregister_alg (&ifxdeu_ecb_aes_alg);
898    crypto_unregister_alg (&ifxdeu_cbc_aes_alg);
899    crypto_unregister_alg (&ifxdeu_ctr_basic_aes_alg);
900    crypto_unregister_alg (&ifxdeu_ctr_rfc3686_aes_alg);
901
902}
903
904
905

Archive Download this file



interactive