4 * s390 implementation of the AES Cipher Algorithm.
7 * Copyright IBM Corp. 2005,2007
8 * Author(s): Jan Glauber (jang@de.ibm.com)
10 * Derived from "crypto/aes.c"
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)
19 #include <crypto/algapi.h>
20 #include <linux/module.h>
21 #include <linux/init.h>
22 #include "crypt_s390.h"
24 #define AES_MIN_KEY_SIZE 16
25 #define AES_MAX_KEY_SIZE 32
27 /* data block size for all key lengths */
28 #define AES_BLOCK_SIZE 16
30 #define AES_KEYLEN_128 1
31 #define AES_KEYLEN_192 2
32 #define AES_KEYLEN_256 4
34 static char keylen_flag
= 0;
37 u8 iv
[AES_BLOCK_SIZE
];
38 u8 key
[AES_MAX_KEY_SIZE
];
44 static int aes_set_key(struct crypto_tfm
*tfm
, const u8
*in_key
,
47 struct s390_aes_ctx
*sctx
= crypto_tfm_ctx(tfm
);
48 u32
*flags
= &tfm
->crt_flags
;
52 if (!(keylen_flag
& AES_KEYLEN_128
))
56 if (!(keylen_flag
& AES_KEYLEN_192
))
61 if (!(keylen_flag
& AES_KEYLEN_256
))
69 sctx
->key_len
= key_len
;
70 memcpy(sctx
->key
, in_key
, key_len
);
73 *flags
|= CRYPTO_TFM_RES_BAD_KEY_LEN
;
77 static void aes_encrypt(struct crypto_tfm
*tfm
, u8
*out
, const u8
*in
)
79 const struct s390_aes_ctx
*sctx
= crypto_tfm_ctx(tfm
);
81 switch (sctx
->key_len
) {
83 crypt_s390_km(KM_AES_128_ENCRYPT
, &sctx
->key
, out
, in
,
87 crypt_s390_km(KM_AES_192_ENCRYPT
, &sctx
->key
, out
, in
,
91 crypt_s390_km(KM_AES_256_ENCRYPT
, &sctx
->key
, out
, in
,
97 static void aes_decrypt(struct crypto_tfm
*tfm
, u8
*out
, const u8
*in
)
99 const struct s390_aes_ctx
*sctx
= crypto_tfm_ctx(tfm
);
101 switch (sctx
->key_len
) {
103 crypt_s390_km(KM_AES_128_DECRYPT
, &sctx
->key
, out
, in
,
107 crypt_s390_km(KM_AES_192_DECRYPT
, &sctx
->key
, out
, in
,
111 crypt_s390_km(KM_AES_256_DECRYPT
, &sctx
->key
, out
, in
,
118 static struct crypto_alg aes_alg
= {
120 .cra_driver_name
= "aes-s390",
121 .cra_priority
= CRYPT_S390_PRIORITY
,
122 .cra_flags
= CRYPTO_ALG_TYPE_CIPHER
|
123 CRYPTO_ALG_NEED_FALLBACK
,
124 .cra_blocksize
= AES_BLOCK_SIZE
,
125 .cra_ctxsize
= sizeof(struct s390_aes_ctx
),
126 .cra_module
= THIS_MODULE
,
127 .cra_list
= LIST_HEAD_INIT(aes_alg
.cra_list
),
130 .cia_min_keysize
= AES_MIN_KEY_SIZE
,
131 .cia_max_keysize
= AES_MAX_KEY_SIZE
,
132 .cia_setkey
= aes_set_key
,
133 .cia_encrypt
= aes_encrypt
,
134 .cia_decrypt
= aes_decrypt
,
139 static int ecb_aes_set_key(struct crypto_tfm
*tfm
, const u8
*in_key
,
140 unsigned int key_len
)
142 struct s390_aes_ctx
*sctx
= crypto_tfm_ctx(tfm
);
146 sctx
->enc
= KM_AES_128_ENCRYPT
;
147 sctx
->dec
= KM_AES_128_DECRYPT
;
150 sctx
->enc
= KM_AES_192_ENCRYPT
;
151 sctx
->dec
= KM_AES_192_DECRYPT
;
154 sctx
->enc
= KM_AES_256_ENCRYPT
;
155 sctx
->dec
= KM_AES_256_DECRYPT
;
159 return aes_set_key(tfm
, in_key
, key_len
);
162 static int ecb_aes_crypt(struct blkcipher_desc
*desc
, long func
, void *param
,
163 struct blkcipher_walk
*walk
)
165 int ret
= blkcipher_walk_virt(desc
, walk
);
168 while ((nbytes
= walk
->nbytes
)) {
169 /* only use complete blocks */
170 unsigned int n
= nbytes
& ~(AES_BLOCK_SIZE
- 1);
171 u8
*out
= walk
->dst
.virt
.addr
;
172 u8
*in
= walk
->src
.virt
.addr
;
174 ret
= crypt_s390_km(func
, param
, out
, in
, n
);
175 BUG_ON((ret
< 0) || (ret
!= n
));
177 nbytes
&= AES_BLOCK_SIZE
- 1;
178 ret
= blkcipher_walk_done(desc
, walk
, nbytes
);
184 static int ecb_aes_encrypt(struct blkcipher_desc
*desc
,
185 struct scatterlist
*dst
, struct scatterlist
*src
,
188 struct s390_aes_ctx
*sctx
= crypto_blkcipher_ctx(desc
->tfm
);
189 struct blkcipher_walk walk
;
191 blkcipher_walk_init(&walk
, dst
, src
, nbytes
);
192 return ecb_aes_crypt(desc
, sctx
->enc
, sctx
->key
, &walk
);
195 static int ecb_aes_decrypt(struct blkcipher_desc
*desc
,
196 struct scatterlist
*dst
, struct scatterlist
*src
,
199 struct s390_aes_ctx
*sctx
= crypto_blkcipher_ctx(desc
->tfm
);
200 struct blkcipher_walk walk
;
202 blkcipher_walk_init(&walk
, dst
, src
, nbytes
);
203 return ecb_aes_crypt(desc
, sctx
->dec
, sctx
->key
, &walk
);
206 static struct crypto_alg ecb_aes_alg
= {
207 .cra_name
= "ecb(aes)",
208 .cra_driver_name
= "ecb-aes-s390",
209 .cra_priority
= CRYPT_S390_COMPOSITE_PRIORITY
,
210 .cra_flags
= CRYPTO_ALG_TYPE_BLKCIPHER
|
211 CRYPTO_ALG_NEED_FALLBACK
,
212 .cra_blocksize
= AES_BLOCK_SIZE
,
213 .cra_ctxsize
= sizeof(struct s390_aes_ctx
),
214 .cra_type
= &crypto_blkcipher_type
,
215 .cra_module
= THIS_MODULE
,
216 .cra_list
= LIST_HEAD_INIT(ecb_aes_alg
.cra_list
),
219 .min_keysize
= AES_MIN_KEY_SIZE
,
220 .max_keysize
= AES_MAX_KEY_SIZE
,
221 .setkey
= ecb_aes_set_key
,
222 .encrypt
= ecb_aes_encrypt
,
223 .decrypt
= ecb_aes_decrypt
,
228 static int cbc_aes_set_key(struct crypto_tfm
*tfm
, const u8
*in_key
,
229 unsigned int key_len
)
231 struct s390_aes_ctx
*sctx
= crypto_tfm_ctx(tfm
);
235 sctx
->enc
= KMC_AES_128_ENCRYPT
;
236 sctx
->dec
= KMC_AES_128_DECRYPT
;
239 sctx
->enc
= KMC_AES_192_ENCRYPT
;
240 sctx
->dec
= KMC_AES_192_DECRYPT
;
243 sctx
->enc
= KMC_AES_256_ENCRYPT
;
244 sctx
->dec
= KMC_AES_256_DECRYPT
;
248 return aes_set_key(tfm
, in_key
, key_len
);
251 static int cbc_aes_crypt(struct blkcipher_desc
*desc
, long func
, void *param
,
252 struct blkcipher_walk
*walk
)
254 int ret
= blkcipher_walk_virt(desc
, walk
);
255 unsigned int nbytes
= walk
->nbytes
;
260 memcpy(param
, walk
->iv
, AES_BLOCK_SIZE
);
262 /* only use complete blocks */
263 unsigned int n
= nbytes
& ~(AES_BLOCK_SIZE
- 1);
264 u8
*out
= walk
->dst
.virt
.addr
;
265 u8
*in
= walk
->src
.virt
.addr
;
267 ret
= crypt_s390_kmc(func
, param
, out
, in
, n
);
268 BUG_ON((ret
< 0) || (ret
!= n
));
270 nbytes
&= AES_BLOCK_SIZE
- 1;
271 ret
= blkcipher_walk_done(desc
, walk
, nbytes
);
272 } while ((nbytes
= walk
->nbytes
));
273 memcpy(walk
->iv
, param
, AES_BLOCK_SIZE
);
279 static int cbc_aes_encrypt(struct blkcipher_desc
*desc
,
280 struct scatterlist
*dst
, struct scatterlist
*src
,
283 struct s390_aes_ctx
*sctx
= crypto_blkcipher_ctx(desc
->tfm
);
284 struct blkcipher_walk walk
;
286 blkcipher_walk_init(&walk
, dst
, src
, nbytes
);
287 return cbc_aes_crypt(desc
, sctx
->enc
, sctx
->iv
, &walk
);
290 static int cbc_aes_decrypt(struct blkcipher_desc
*desc
,
291 struct scatterlist
*dst
, struct scatterlist
*src
,
294 struct s390_aes_ctx
*sctx
= crypto_blkcipher_ctx(desc
->tfm
);
295 struct blkcipher_walk walk
;
297 blkcipher_walk_init(&walk
, dst
, src
, nbytes
);
298 return cbc_aes_crypt(desc
, sctx
->dec
, sctx
->iv
, &walk
);
301 static struct crypto_alg cbc_aes_alg
= {
302 .cra_name
= "cbc(aes)",
303 .cra_driver_name
= "cbc-aes-s390",
304 .cra_priority
= CRYPT_S390_COMPOSITE_PRIORITY
,
305 .cra_flags
= CRYPTO_ALG_TYPE_BLKCIPHER
|
306 CRYPTO_ALG_NEED_FALLBACK
,
307 .cra_blocksize
= AES_BLOCK_SIZE
,
308 .cra_ctxsize
= sizeof(struct s390_aes_ctx
),
309 .cra_type
= &crypto_blkcipher_type
,
310 .cra_module
= THIS_MODULE
,
311 .cra_list
= LIST_HEAD_INIT(cbc_aes_alg
.cra_list
),
314 .min_keysize
= AES_MIN_KEY_SIZE
,
315 .max_keysize
= AES_MAX_KEY_SIZE
,
316 .ivsize
= AES_BLOCK_SIZE
,
317 .setkey
= cbc_aes_set_key
,
318 .encrypt
= cbc_aes_encrypt
,
319 .decrypt
= cbc_aes_decrypt
,
324 static int __init
aes_init(void)
328 if (crypt_s390_func_available(KM_AES_128_ENCRYPT
))
329 keylen_flag
|= AES_KEYLEN_128
;
330 if (crypt_s390_func_available(KM_AES_192_ENCRYPT
))
331 keylen_flag
|= AES_KEYLEN_192
;
332 if (crypt_s390_func_available(KM_AES_256_ENCRYPT
))
333 keylen_flag
|= AES_KEYLEN_256
;
338 /* z9 109 and z9 BC/EC only support 128 bit key length */
339 if (keylen_flag
== AES_KEYLEN_128
) {
340 aes_alg
.cra_u
.cipher
.cia_max_keysize
= AES_MIN_KEY_SIZE
;
341 ecb_aes_alg
.cra_u
.blkcipher
.max_keysize
= AES_MIN_KEY_SIZE
;
342 cbc_aes_alg
.cra_u
.blkcipher
.max_keysize
= AES_MIN_KEY_SIZE
;
344 "aes_s390: hardware acceleration only available for"
348 ret
= crypto_register_alg(&aes_alg
);
352 ret
= crypto_register_alg(&ecb_aes_alg
);
356 ret
= crypto_register_alg(&cbc_aes_alg
);
364 crypto_unregister_alg(&ecb_aes_alg
);
366 crypto_unregister_alg(&aes_alg
);
371 static void __exit
aes_fini(void)
373 crypto_unregister_alg(&cbc_aes_alg
);
374 crypto_unregister_alg(&ecb_aes_alg
);
375 crypto_unregister_alg(&aes_alg
);
378 module_init(aes_init
);
379 module_exit(aes_fini
);
383 MODULE_DESCRIPTION("Rijndael (AES) Cipher Algorithm");
384 MODULE_LICENSE("GPL");