Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6
[pandora-kernel.git] / arch / s390 / crypto / aes_s390.c
1 /*
2  * Cryptographic API.
3  *
4  * s390 implementation of the AES Cipher Algorithm.
5  *
6  * s390 Version:
7  *   Copyright (C) 2005 IBM Deutschland GmbH, IBM Corporation
8  *   Author(s): Jan Glauber (jang@de.ibm.com)
9  *
10  * Derived from "crypto/aes.c"
11  *
12  * This program is free software; you can redistribute it and/or modify it
13  * under the terms of the GNU General Public License as published by the Free
14  * Software Foundation; either version 2 of the License, or (at your option)
15  * any later version.
16  *
17  */
18
19 #include <crypto/algapi.h>
20 #include <linux/module.h>
21 #include <linux/init.h>
22 #include "crypt_s390.h"
23
24 #define AES_MIN_KEY_SIZE        16
25 #define AES_MAX_KEY_SIZE        32
26
27 /* data block size for all key lengths */
28 #define AES_BLOCK_SIZE          16
29
30 int has_aes_128 = 0;
31 int has_aes_192 = 0;
32 int has_aes_256 = 0;
33
34 struct s390_aes_ctx {
35         u8 iv[AES_BLOCK_SIZE];
36         u8 key[AES_MAX_KEY_SIZE];
37         long enc;
38         long dec;
39         int key_len;
40 };
41
42 static int aes_set_key(struct crypto_tfm *tfm, const u8 *in_key,
43                        unsigned int key_len)
44 {
45         struct s390_aes_ctx *sctx = crypto_tfm_ctx(tfm);
46         u32 *flags = &tfm->crt_flags;
47
48         switch (key_len) {
49         case 16:
50                 if (!has_aes_128)
51                         goto fail;
52                 break;
53         case 24:
54                 if (!has_aes_192)
55                         goto fail;
56
57                 break;
58         case 32:
59                 if (!has_aes_256)
60                         goto fail;
61                 break;
62         default:
63                 /* invalid key length */
64                 goto fail;
65                 break;
66         }
67
68         sctx->key_len = key_len;
69         memcpy(sctx->key, in_key, key_len);
70         return 0;
71 fail:
72         *flags |= CRYPTO_TFM_RES_BAD_KEY_LEN;
73         return -EINVAL;
74 }
75
76 static void aes_encrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in)
77 {
78         const struct s390_aes_ctx *sctx = crypto_tfm_ctx(tfm);
79
80         switch (sctx->key_len) {
81         case 16:
82                 crypt_s390_km(KM_AES_128_ENCRYPT, &sctx->key, out, in,
83                               AES_BLOCK_SIZE);
84                 break;
85         case 24:
86                 crypt_s390_km(KM_AES_192_ENCRYPT, &sctx->key, out, in,
87                               AES_BLOCK_SIZE);
88                 break;
89         case 32:
90                 crypt_s390_km(KM_AES_256_ENCRYPT, &sctx->key, out, in,
91                               AES_BLOCK_SIZE);
92                 break;
93         }
94 }
95
96 static void aes_decrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in)
97 {
98         const struct s390_aes_ctx *sctx = crypto_tfm_ctx(tfm);
99
100         switch (sctx->key_len) {
101         case 16:
102                 crypt_s390_km(KM_AES_128_DECRYPT, &sctx->key, out, in,
103                               AES_BLOCK_SIZE);
104                 break;
105         case 24:
106                 crypt_s390_km(KM_AES_192_DECRYPT, &sctx->key, out, in,
107                               AES_BLOCK_SIZE);
108                 break;
109         case 32:
110                 crypt_s390_km(KM_AES_256_DECRYPT, &sctx->key, out, in,
111                               AES_BLOCK_SIZE);
112                 break;
113         }
114 }
115
116
117 static struct crypto_alg aes_alg = {
118         .cra_name               =       "aes",
119         .cra_driver_name        =       "aes-s390",
120         .cra_priority           =       CRYPT_S390_PRIORITY,
121         .cra_flags              =       CRYPTO_ALG_TYPE_CIPHER,
122         .cra_blocksize          =       AES_BLOCK_SIZE,
123         .cra_ctxsize            =       sizeof(struct s390_aes_ctx),
124         .cra_module             =       THIS_MODULE,
125         .cra_list               =       LIST_HEAD_INIT(aes_alg.cra_list),
126         .cra_u                  =       {
127                 .cipher = {
128                         .cia_min_keysize        =       AES_MIN_KEY_SIZE,
129                         .cia_max_keysize        =       AES_MAX_KEY_SIZE,
130                         .cia_setkey             =       aes_set_key,
131                         .cia_encrypt            =       aes_encrypt,
132                         .cia_decrypt            =       aes_decrypt,
133                 }
134         }
135 };
136
137 static int ecb_aes_set_key(struct crypto_tfm *tfm, const u8 *in_key,
138                            unsigned int key_len)
139 {
140         struct s390_aes_ctx *sctx = crypto_tfm_ctx(tfm);
141
142         switch (key_len) {
143         case 16:
144                 sctx->enc = KM_AES_128_ENCRYPT;
145                 sctx->dec = KM_AES_128_DECRYPT;
146                 break;
147         case 24:
148                 sctx->enc = KM_AES_192_ENCRYPT;
149                 sctx->dec = KM_AES_192_DECRYPT;
150                 break;
151         case 32:
152                 sctx->enc = KM_AES_256_ENCRYPT;
153                 sctx->dec = KM_AES_256_DECRYPT;
154                 break;
155         }
156
157         return aes_set_key(tfm, in_key, key_len);
158 }
159
160 static int ecb_aes_crypt(struct blkcipher_desc *desc, long func, void *param,
161                          struct blkcipher_walk *walk)
162 {
163         int ret = blkcipher_walk_virt(desc, walk);
164         unsigned int nbytes;
165
166         while ((nbytes = walk->nbytes)) {
167                 /* only use complete blocks */
168                 unsigned int n = nbytes & ~(AES_BLOCK_SIZE - 1);
169                 u8 *out = walk->dst.virt.addr;
170                 u8 *in = walk->src.virt.addr;
171
172                 ret = crypt_s390_km(func, param, out, in, n);
173                 BUG_ON((ret < 0) || (ret != n));
174
175                 nbytes &= AES_BLOCK_SIZE - 1;
176                 ret = blkcipher_walk_done(desc, walk, nbytes);
177         }
178
179         return ret;
180 }
181
182 static int ecb_aes_encrypt(struct blkcipher_desc *desc,
183                            struct scatterlist *dst, struct scatterlist *src,
184                            unsigned int nbytes)
185 {
186         struct s390_aes_ctx *sctx = crypto_blkcipher_ctx(desc->tfm);
187         struct blkcipher_walk walk;
188
189         blkcipher_walk_init(&walk, dst, src, nbytes);
190         return ecb_aes_crypt(desc, sctx->enc, sctx->key, &walk);
191 }
192
193 static int ecb_aes_decrypt(struct blkcipher_desc *desc,
194                            struct scatterlist *dst, struct scatterlist *src,
195                            unsigned int nbytes)
196 {
197         struct s390_aes_ctx *sctx = crypto_blkcipher_ctx(desc->tfm);
198         struct blkcipher_walk walk;
199
200         blkcipher_walk_init(&walk, dst, src, nbytes);
201         return ecb_aes_crypt(desc, sctx->dec, sctx->key, &walk);
202 }
203
204 static struct crypto_alg ecb_aes_alg = {
205         .cra_name               =       "ecb(aes)",
206         .cra_driver_name        =       "ecb-aes-s390",
207         .cra_priority           =       CRYPT_S390_COMPOSITE_PRIORITY,
208         .cra_flags              =       CRYPTO_ALG_TYPE_BLKCIPHER,
209         .cra_blocksize          =       AES_BLOCK_SIZE,
210         .cra_ctxsize            =       sizeof(struct s390_aes_ctx),
211         .cra_type               =       &crypto_blkcipher_type,
212         .cra_module             =       THIS_MODULE,
213         .cra_list               =       LIST_HEAD_INIT(ecb_aes_alg.cra_list),
214         .cra_u                  =       {
215                 .blkcipher = {
216                         .min_keysize            =       AES_MIN_KEY_SIZE,
217                         .max_keysize            =       AES_MAX_KEY_SIZE,
218                         .setkey                 =       ecb_aes_set_key,
219                         .encrypt                =       ecb_aes_encrypt,
220                         .decrypt                =       ecb_aes_decrypt,
221                 }
222         }
223 };
224
225 static int cbc_aes_set_key(struct crypto_tfm *tfm, const u8 *in_key,
226                            unsigned int key_len)
227 {
228         struct s390_aes_ctx *sctx = crypto_tfm_ctx(tfm);
229
230         switch (key_len) {
231         case 16:
232                 sctx->enc = KMC_AES_128_ENCRYPT;
233                 sctx->dec = KMC_AES_128_DECRYPT;
234                 break;
235         case 24:
236                 sctx->enc = KMC_AES_192_ENCRYPT;
237                 sctx->dec = KMC_AES_192_DECRYPT;
238                 break;
239         case 32:
240                 sctx->enc = KMC_AES_256_ENCRYPT;
241                 sctx->dec = KMC_AES_256_DECRYPT;
242                 break;
243         }
244
245         return aes_set_key(tfm, in_key, key_len);
246 }
247
248 static int cbc_aes_crypt(struct blkcipher_desc *desc, long func, void *param,
249                          struct blkcipher_walk *walk)
250 {
251         int ret = blkcipher_walk_virt(desc, walk);
252         unsigned int nbytes = walk->nbytes;
253
254         if (!nbytes)
255                 goto out;
256
257         memcpy(param, walk->iv, AES_BLOCK_SIZE);
258         do {
259                 /* only use complete blocks */
260                 unsigned int n = nbytes & ~(AES_BLOCK_SIZE - 1);
261                 u8 *out = walk->dst.virt.addr;
262                 u8 *in = walk->src.virt.addr;
263
264                 ret = crypt_s390_kmc(func, param, out, in, n);
265                 BUG_ON((ret < 0) || (ret != n));
266
267                 nbytes &= AES_BLOCK_SIZE - 1;
268                 ret = blkcipher_walk_done(desc, walk, nbytes);
269         } while ((nbytes = walk->nbytes));
270         memcpy(walk->iv, param, AES_BLOCK_SIZE);
271
272 out:
273         return ret;
274 }
275
276 static int cbc_aes_encrypt(struct blkcipher_desc *desc,
277                            struct scatterlist *dst, struct scatterlist *src,
278                            unsigned int nbytes)
279 {
280         struct s390_aes_ctx *sctx = crypto_blkcipher_ctx(desc->tfm);
281         struct blkcipher_walk walk;
282
283         blkcipher_walk_init(&walk, dst, src, nbytes);
284         return cbc_aes_crypt(desc, sctx->enc, sctx->iv, &walk);
285 }
286
287 static int cbc_aes_decrypt(struct blkcipher_desc *desc,
288                            struct scatterlist *dst, struct scatterlist *src,
289                            unsigned int nbytes)
290 {
291         struct s390_aes_ctx *sctx = crypto_blkcipher_ctx(desc->tfm);
292         struct blkcipher_walk walk;
293
294         blkcipher_walk_init(&walk, dst, src, nbytes);
295         return cbc_aes_crypt(desc, sctx->dec, sctx->iv, &walk);
296 }
297
298 static struct crypto_alg cbc_aes_alg = {
299         .cra_name               =       "cbc(aes)",
300         .cra_driver_name        =       "cbc-aes-s390",
301         .cra_priority           =       CRYPT_S390_COMPOSITE_PRIORITY,
302         .cra_flags              =       CRYPTO_ALG_TYPE_BLKCIPHER,
303         .cra_blocksize          =       AES_BLOCK_SIZE,
304         .cra_ctxsize            =       sizeof(struct s390_aes_ctx),
305         .cra_type               =       &crypto_blkcipher_type,
306         .cra_module             =       THIS_MODULE,
307         .cra_list               =       LIST_HEAD_INIT(cbc_aes_alg.cra_list),
308         .cra_u                  =       {
309                 .blkcipher = {
310                         .min_keysize            =       AES_MIN_KEY_SIZE,
311                         .max_keysize            =       AES_MAX_KEY_SIZE,
312                         .ivsize                 =       AES_BLOCK_SIZE,
313                         .setkey                 =       cbc_aes_set_key,
314                         .encrypt                =       cbc_aes_encrypt,
315                         .decrypt                =       cbc_aes_decrypt,
316                 }
317         }
318 };
319
320 static int __init aes_init(void)
321 {
322         int ret;
323
324         if (crypt_s390_func_available(KM_AES_128_ENCRYPT))
325                 has_aes_128 = 1;
326         if (crypt_s390_func_available(KM_AES_192_ENCRYPT))
327                 has_aes_192 = 1;
328         if (crypt_s390_func_available(KM_AES_256_ENCRYPT))
329                 has_aes_256 = 1;
330
331         if (!has_aes_128 && !has_aes_192 && !has_aes_256)
332                 return -ENOSYS;
333
334         ret = crypto_register_alg(&aes_alg);
335         if (ret != 0) {
336                 printk(KERN_INFO "crypt_s390: aes-s390 couldn't be loaded.\n");
337                 goto aes_err;
338         }
339
340         ret = crypto_register_alg(&ecb_aes_alg);
341         if (ret != 0) {
342                 printk(KERN_INFO
343                        "crypt_s390: ecb-aes-s390 couldn't be loaded.\n");
344                 goto ecb_aes_err;
345         }
346
347         ret = crypto_register_alg(&cbc_aes_alg);
348         if (ret != 0) {
349                 printk(KERN_INFO
350                        "crypt_s390: cbc-aes-s390 couldn't be loaded.\n");
351                 goto cbc_aes_err;
352         }
353
354 out:
355         return ret;
356
357 cbc_aes_err:
358         crypto_unregister_alg(&ecb_aes_alg);
359 ecb_aes_err:
360         crypto_unregister_alg(&aes_alg);
361 aes_err:
362         goto out;
363 }
364
365 static void __exit aes_fini(void)
366 {
367         crypto_unregister_alg(&cbc_aes_alg);
368         crypto_unregister_alg(&ecb_aes_alg);
369         crypto_unregister_alg(&aes_alg);
370 }
371
372 module_init(aes_init);
373 module_exit(aes_fini);
374
375 MODULE_ALIAS("aes");
376
377 MODULE_DESCRIPTION("Rijndael (AES) Cipher Algorithm");
378 MODULE_LICENSE("GPL");
379