4 * s390 implementation of the AES Cipher Algorithm.
7 * Copyright (C) 2005 IBM Deutschland GmbH, IBM Corporation
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 <linux/module.h>
20 #include <linux/init.h>
21 #include <linux/crypto.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
35 u8 iv[AES_BLOCK_SIZE];
36 u8 key[AES_MAX_KEY_SIZE];
40 static int aes_set_key(struct crypto_tfm *tfm, const u8 *in_key,
43 struct s390_aes_ctx *sctx = crypto_tfm_ctx(tfm);
44 u32 *flags = &tfm->crt_flags;
61 /* invalid key length */
66 sctx->key_len = key_len;
67 memcpy(sctx->key, in_key, key_len);
70 *flags |= CRYPTO_TFM_RES_BAD_KEY_LEN;
74 static void aes_encrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in)
76 const struct s390_aes_ctx *sctx = crypto_tfm_ctx(tfm);
78 switch (sctx->key_len) {
80 crypt_s390_km(KM_AES_128_ENCRYPT, &sctx->key, out, in,
84 crypt_s390_km(KM_AES_192_ENCRYPT, &sctx->key, out, in,
88 crypt_s390_km(KM_AES_256_ENCRYPT, &sctx->key, out, in,
94 static void aes_decrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in)
96 const struct s390_aes_ctx *sctx = crypto_tfm_ctx(tfm);
98 switch (sctx->key_len) {
100 crypt_s390_km(KM_AES_128_DECRYPT, &sctx->key, out, in,
104 crypt_s390_km(KM_AES_192_DECRYPT, &sctx->key, out, in,
108 crypt_s390_km(KM_AES_256_DECRYPT, &sctx->key, out, in,
114 static unsigned int aes_encrypt_ecb(const struct cipher_desc *desc, u8 *out,
115 const u8 *in, unsigned int nbytes)
117 struct s390_aes_ctx *sctx = crypto_tfm_ctx(desc->tfm);
120 /* only use complete blocks */
121 nbytes &= ~(AES_BLOCK_SIZE - 1);
123 switch (sctx->key_len) {
125 ret = crypt_s390_km(KM_AES_128_ENCRYPT, &sctx->key, out, in, nbytes);
126 BUG_ON((ret < 0) || (ret != nbytes));
129 ret = crypt_s390_km(KM_AES_192_ENCRYPT, &sctx->key, out, in, nbytes);
130 BUG_ON((ret < 0) || (ret != nbytes));
133 ret = crypt_s390_km(KM_AES_256_ENCRYPT, &sctx->key, out, in, nbytes);
134 BUG_ON((ret < 0) || (ret != nbytes));
140 static unsigned int aes_decrypt_ecb(const struct cipher_desc *desc, u8 *out,
141 const u8 *in, unsigned int nbytes)
143 struct s390_aes_ctx *sctx = crypto_tfm_ctx(desc->tfm);
146 /* only use complete blocks */
147 nbytes &= ~(AES_BLOCK_SIZE - 1);
149 switch (sctx->key_len) {
151 ret = crypt_s390_km(KM_AES_128_DECRYPT, &sctx->key, out, in, nbytes);
152 BUG_ON((ret < 0) || (ret != nbytes));
155 ret = crypt_s390_km(KM_AES_192_DECRYPT, &sctx->key, out, in, nbytes);
156 BUG_ON((ret < 0) || (ret != nbytes));
159 ret = crypt_s390_km(KM_AES_256_DECRYPT, &sctx->key, out, in, nbytes);
160 BUG_ON((ret < 0) || (ret != nbytes));
166 static unsigned int aes_encrypt_cbc(const struct cipher_desc *desc, u8 *out,
167 const u8 *in, unsigned int nbytes)
169 struct s390_aes_ctx *sctx = crypto_tfm_ctx(desc->tfm);
172 /* only use complete blocks */
173 nbytes &= ~(AES_BLOCK_SIZE - 1);
175 memcpy(&sctx->iv, desc->info, AES_BLOCK_SIZE);
176 switch (sctx->key_len) {
178 ret = crypt_s390_kmc(KMC_AES_128_ENCRYPT, &sctx->iv, out, in, nbytes);
179 BUG_ON((ret < 0) || (ret != nbytes));
182 ret = crypt_s390_kmc(KMC_AES_192_ENCRYPT, &sctx->iv, out, in, nbytes);
183 BUG_ON((ret < 0) || (ret != nbytes));
186 ret = crypt_s390_kmc(KMC_AES_256_ENCRYPT, &sctx->iv, out, in, nbytes);
187 BUG_ON((ret < 0) || (ret != nbytes));
190 memcpy(desc->info, &sctx->iv, AES_BLOCK_SIZE);
195 static unsigned int aes_decrypt_cbc(const struct cipher_desc *desc, u8 *out,
196 const u8 *in, unsigned int nbytes)
198 struct s390_aes_ctx *sctx = crypto_tfm_ctx(desc->tfm);
201 /* only use complete blocks */
202 nbytes &= ~(AES_BLOCK_SIZE - 1);
204 memcpy(&sctx->iv, desc->info, AES_BLOCK_SIZE);
205 switch (sctx->key_len) {
207 ret = crypt_s390_kmc(KMC_AES_128_DECRYPT, &sctx->iv, out, in, nbytes);
208 BUG_ON((ret < 0) || (ret != nbytes));
211 ret = crypt_s390_kmc(KMC_AES_192_DECRYPT, &sctx->iv, out, in, nbytes);
212 BUG_ON((ret < 0) || (ret != nbytes));
215 ret = crypt_s390_kmc(KMC_AES_256_DECRYPT, &sctx->iv, out, in, nbytes);
216 BUG_ON((ret < 0) || (ret != nbytes));
223 static struct crypto_alg aes_alg = {
225 .cra_driver_name = "aes-s390",
226 .cra_priority = CRYPT_S390_PRIORITY,
227 .cra_flags = CRYPTO_ALG_TYPE_CIPHER,
228 .cra_blocksize = AES_BLOCK_SIZE,
229 .cra_ctxsize = sizeof(struct s390_aes_ctx),
230 .cra_module = THIS_MODULE,
231 .cra_list = LIST_HEAD_INIT(aes_alg.cra_list),
234 .cia_min_keysize = AES_MIN_KEY_SIZE,
235 .cia_max_keysize = AES_MAX_KEY_SIZE,
236 .cia_setkey = aes_set_key,
237 .cia_encrypt = aes_encrypt,
238 .cia_decrypt = aes_decrypt,
239 .cia_encrypt_ecb = aes_encrypt_ecb,
240 .cia_decrypt_ecb = aes_decrypt_ecb,
241 .cia_encrypt_cbc = aes_encrypt_cbc,
242 .cia_decrypt_cbc = aes_decrypt_cbc,
247 static int __init aes_init(void)
251 if (crypt_s390_func_available(KM_AES_128_ENCRYPT))
253 if (crypt_s390_func_available(KM_AES_192_ENCRYPT))
255 if (crypt_s390_func_available(KM_AES_256_ENCRYPT))
258 if (!has_aes_128 && !has_aes_192 && !has_aes_256)
261 ret = crypto_register_alg(&aes_alg);
263 printk(KERN_INFO "crypt_s390: aes_s390 couldn't be loaded.\n");
267 static void __exit aes_fini(void)
269 crypto_unregister_alg(&aes_alg);
272 module_init(aes_init);
273 module_exit(aes_fini);
277 MODULE_DESCRIPTION("Rijndael (AES) Cipher Algorithm");
278 MODULE_LICENSE("GPL");