]> git.kernelconcepts.de Git - karo-tx-linux.git/blob - arch/arm/crypto/aes_glue.c
Merge branch 'pci/misc' into next
[karo-tx-linux.git] / arch / arm / crypto / aes_glue.c
1 /*
2  * Glue Code for the asm optimized version of the AES Cipher Algorithm
3  */
4
5 #include <linux/module.h>
6 #include <linux/crypto.h>
7 #include <crypto/aes.h>
8
9 #define AES_MAXNR 14
10
11 typedef struct {
12         unsigned int rd_key[4 *(AES_MAXNR + 1)];
13         int rounds;
14 } AES_KEY;
15
16 struct AES_CTX {
17         AES_KEY enc_key;
18         AES_KEY dec_key;
19 };
20
21 asmlinkage void AES_encrypt(const u8 *in, u8 *out, AES_KEY *ctx);
22 asmlinkage void AES_decrypt(const u8 *in, u8 *out, AES_KEY *ctx);
23 asmlinkage int private_AES_set_decrypt_key(const unsigned char *userKey, const int bits, AES_KEY *key);
24 asmlinkage int private_AES_set_encrypt_key(const unsigned char *userKey, const int bits, AES_KEY *key);
25
26 static void aes_encrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)
27 {
28         struct AES_CTX *ctx = crypto_tfm_ctx(tfm);
29         AES_encrypt(src, dst, &ctx->enc_key);
30 }
31
32 static void aes_decrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)
33 {
34         struct AES_CTX *ctx = crypto_tfm_ctx(tfm);
35         AES_decrypt(src, dst, &ctx->dec_key);
36 }
37
38 static int aes_set_key(struct crypto_tfm *tfm, const u8 *in_key,
39                 unsigned int key_len)
40 {
41         struct AES_CTX *ctx = crypto_tfm_ctx(tfm);
42
43         switch (key_len) {
44         case AES_KEYSIZE_128:
45                 key_len = 128;
46                 break;
47         case AES_KEYSIZE_192:
48                 key_len = 192;
49                 break;
50         case AES_KEYSIZE_256:
51                 key_len = 256;
52                 break;
53         default:
54                 tfm->crt_flags |= CRYPTO_TFM_RES_BAD_KEY_LEN;
55                 return -EINVAL;
56         }
57
58         if (private_AES_set_encrypt_key(in_key, key_len, &ctx->enc_key) == -1) {
59                 tfm->crt_flags |= CRYPTO_TFM_RES_BAD_KEY_LEN;
60                 return -EINVAL;
61         }
62         /* private_AES_set_decrypt_key expects an encryption key as input */
63         ctx->dec_key = ctx->enc_key;
64         if (private_AES_set_decrypt_key(in_key, key_len, &ctx->dec_key) == -1) {
65                 tfm->crt_flags |= CRYPTO_TFM_RES_BAD_KEY_LEN;
66                 return -EINVAL;
67         }
68         return 0;
69 }
70
71 static struct crypto_alg aes_alg = {
72         .cra_name               = "aes",
73         .cra_driver_name        = "aes-asm",
74         .cra_priority           = 200,
75         .cra_flags              = CRYPTO_ALG_TYPE_CIPHER,
76         .cra_blocksize          = AES_BLOCK_SIZE,
77         .cra_ctxsize            = sizeof(struct AES_CTX),
78         .cra_module             = THIS_MODULE,
79         .cra_list               = LIST_HEAD_INIT(aes_alg.cra_list),
80         .cra_u  = {
81                 .cipher = {
82                         .cia_min_keysize        = AES_MIN_KEY_SIZE,
83                         .cia_max_keysize        = AES_MAX_KEY_SIZE,
84                         .cia_setkey                     = aes_set_key,
85                         .cia_encrypt            = aes_encrypt,
86                         .cia_decrypt            = aes_decrypt
87                 }
88         }
89 };
90
91 static int __init aes_init(void)
92 {
93         return crypto_register_alg(&aes_alg);
94 }
95
96 static void __exit aes_fini(void)
97 {
98         crypto_unregister_alg(&aes_alg);
99 }
100
101 module_init(aes_init);
102 module_exit(aes_fini);
103
104 MODULE_DESCRIPTION("Rijndael (AES) Cipher Algorithm (ASM)");
105 MODULE_LICENSE("GPL");
106 MODULE_ALIAS("aes");
107 MODULE_ALIAS("aes-asm");
108 MODULE_AUTHOR("David McCullough <ucdevel@gmail.com>");