aboutsummaryrefslogtreecommitdiffstats
path: root/arch/s390/crypto/aes_s390.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/s390/crypto/aes_s390.c')
-rw-r--r--arch/s390/crypto/aes_s390.c285
1 files changed, 194 insertions, 91 deletions
diff --git a/arch/s390/crypto/aes_s390.c b/arch/s390/crypto/aes_s390.c
index 5713c7e5bd16..15c9eec02928 100644
--- a/arch/s390/crypto/aes_s390.c
+++ b/arch/s390/crypto/aes_s390.c
@@ -16,9 +16,9 @@
16 * 16 *
17 */ 17 */
18 18
19#include <crypto/algapi.h>
19#include <linux/module.h> 20#include <linux/module.h>
20#include <linux/init.h> 21#include <linux/init.h>
21#include <linux/crypto.h>
22#include "crypt_s390.h" 22#include "crypt_s390.h"
23 23
24#define AES_MIN_KEY_SIZE 16 24#define AES_MIN_KEY_SIZE 16
@@ -34,13 +34,16 @@ int has_aes_256 = 0;
34struct s390_aes_ctx { 34struct s390_aes_ctx {
35 u8 iv[AES_BLOCK_SIZE]; 35 u8 iv[AES_BLOCK_SIZE];
36 u8 key[AES_MAX_KEY_SIZE]; 36 u8 key[AES_MAX_KEY_SIZE];
37 long enc;
38 long dec;
37 int key_len; 39 int key_len;
38}; 40};
39 41
40static int aes_set_key(struct crypto_tfm *tfm, const u8 *in_key, 42static int aes_set_key(struct crypto_tfm *tfm, const u8 *in_key,
41 unsigned int key_len, u32 *flags) 43 unsigned int key_len)
42{ 44{
43 struct s390_aes_ctx *sctx = crypto_tfm_ctx(tfm); 45 struct s390_aes_ctx *sctx = crypto_tfm_ctx(tfm);
46 u32 *flags = &tfm->crt_flags;
44 47
45 switch (key_len) { 48 switch (key_len) {
46 case 16: 49 case 16:
@@ -110,133 +113,206 @@ static void aes_decrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in)
110 } 113 }
111} 114}
112 115
113static unsigned int aes_encrypt_ecb(const struct cipher_desc *desc, u8 *out,
114 const u8 *in, unsigned int nbytes)
115{
116 struct s390_aes_ctx *sctx = crypto_tfm_ctx(desc->tfm);
117 int ret;
118 116
119 /* only use complete blocks */ 117static struct crypto_alg aes_alg = {
120 nbytes &= ~(AES_BLOCK_SIZE - 1); 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
137static 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);
121 141
122 switch (sctx->key_len) { 142 switch (key_len) {
123 case 16: 143 case 16:
124 ret = crypt_s390_km(KM_AES_128_ENCRYPT, &sctx->key, out, in, nbytes); 144 sctx->enc = KM_AES_128_ENCRYPT;
125 BUG_ON((ret < 0) || (ret != nbytes)); 145 sctx->dec = KM_AES_128_DECRYPT;
126 break; 146 break;
127 case 24: 147 case 24:
128 ret = crypt_s390_km(KM_AES_192_ENCRYPT, &sctx->key, out, in, nbytes); 148 sctx->enc = KM_AES_192_ENCRYPT;
129 BUG_ON((ret < 0) || (ret != nbytes)); 149 sctx->dec = KM_AES_192_DECRYPT;
130 break; 150 break;
131 case 32: 151 case 32:
132 ret = crypt_s390_km(KM_AES_256_ENCRYPT, &sctx->key, out, in, nbytes); 152 sctx->enc = KM_AES_256_ENCRYPT;
133 BUG_ON((ret < 0) || (ret != nbytes)); 153 sctx->dec = KM_AES_256_DECRYPT;
134 break; 154 break;
135 } 155 }
136 return nbytes; 156
157 return aes_set_key(tfm, in_key, key_len);
137} 158}
138 159
139static unsigned int aes_decrypt_ecb(const struct cipher_desc *desc, u8 *out, 160static int ecb_aes_crypt(struct blkcipher_desc *desc, long func, void *param,
140 const u8 *in, unsigned int nbytes) 161 struct blkcipher_walk *walk)
141{ 162{
142 struct s390_aes_ctx *sctx = crypto_tfm_ctx(desc->tfm); 163 int ret = blkcipher_walk_virt(desc, walk);
143 int ret; 164 unsigned int nbytes;
144 165
145 /* only use complete blocks */ 166 while ((nbytes = walk->nbytes)) {
146 nbytes &= ~(AES_BLOCK_SIZE - 1); 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;
147 171
148 switch (sctx->key_len) { 172 ret = crypt_s390_km(func, param, out, in, n);
149 case 16: 173 BUG_ON((ret < 0) || (ret != n));
150 ret = crypt_s390_km(KM_AES_128_DECRYPT, &sctx->key, out, in, nbytes); 174
151 BUG_ON((ret < 0) || (ret != nbytes)); 175 nbytes &= AES_BLOCK_SIZE - 1;
152 break; 176 ret = blkcipher_walk_done(desc, walk, nbytes);
153 case 24:
154 ret = crypt_s390_km(KM_AES_192_DECRYPT, &sctx->key, out, in, nbytes);
155 BUG_ON((ret < 0) || (ret != nbytes));
156 break;
157 case 32:
158 ret = crypt_s390_km(KM_AES_256_DECRYPT, &sctx->key, out, in, nbytes);
159 BUG_ON((ret < 0) || (ret != nbytes));
160 break;
161 } 177 }
162 return nbytes; 178
179 return ret;
163} 180}
164 181
165static unsigned int aes_encrypt_cbc(const struct cipher_desc *desc, u8 *out, 182static int ecb_aes_encrypt(struct blkcipher_desc *desc,
166 const u8 *in, unsigned int nbytes) 183 struct scatterlist *dst, struct scatterlist *src,
184 unsigned int nbytes)
167{ 185{
168 struct s390_aes_ctx *sctx = crypto_tfm_ctx(desc->tfm); 186 struct s390_aes_ctx *sctx = crypto_blkcipher_ctx(desc->tfm);
169 int ret; 187 struct blkcipher_walk walk;
170 188
171 /* only use complete blocks */ 189 blkcipher_walk_init(&walk, dst, src, nbytes);
172 nbytes &= ~(AES_BLOCK_SIZE - 1); 190 return ecb_aes_crypt(desc, sctx->enc, sctx->key, &walk);
191}
173 192
174 memcpy(&sctx->iv, desc->info, AES_BLOCK_SIZE); 193static int ecb_aes_decrypt(struct blkcipher_desc *desc,
175 switch (sctx->key_len) { 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
204static 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
225static 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) {
176 case 16: 231 case 16:
177 ret = crypt_s390_kmc(KMC_AES_128_ENCRYPT, &sctx->iv, out, in, nbytes); 232 sctx->enc = KMC_AES_128_ENCRYPT;
178 BUG_ON((ret < 0) || (ret != nbytes)); 233 sctx->dec = KMC_AES_128_DECRYPT;
179 break; 234 break;
180 case 24: 235 case 24:
181 ret = crypt_s390_kmc(KMC_AES_192_ENCRYPT, &sctx->iv, out, in, nbytes); 236 sctx->enc = KMC_AES_192_ENCRYPT;
182 BUG_ON((ret < 0) || (ret != nbytes)); 237 sctx->dec = KMC_AES_192_DECRYPT;
183 break; 238 break;
184 case 32: 239 case 32:
185 ret = crypt_s390_kmc(KMC_AES_256_ENCRYPT, &sctx->iv, out, in, nbytes); 240 sctx->enc = KMC_AES_256_ENCRYPT;
186 BUG_ON((ret < 0) || (ret != nbytes)); 241 sctx->dec = KMC_AES_256_DECRYPT;
187 break; 242 break;
188 } 243 }
189 memcpy(desc->info, &sctx->iv, AES_BLOCK_SIZE);
190 244
191 return nbytes; 245 return aes_set_key(tfm, in_key, key_len);
192} 246}
193 247
194static unsigned int aes_decrypt_cbc(const struct cipher_desc *desc, u8 *out, 248static int cbc_aes_crypt(struct blkcipher_desc *desc, long func, void *param,
195 const u8 *in, unsigned int nbytes) 249 struct blkcipher_walk *walk)
196{ 250{
197 struct s390_aes_ctx *sctx = crypto_tfm_ctx(desc->tfm); 251 int ret = blkcipher_walk_virt(desc, walk);
198 int ret; 252 unsigned int nbytes = walk->nbytes;
199 253
200 /* only use complete blocks */ 254 if (!nbytes)
201 nbytes &= ~(AES_BLOCK_SIZE - 1); 255 goto out;
202 256
203 memcpy(&sctx->iv, desc->info, AES_BLOCK_SIZE); 257 memcpy(param, walk->iv, AES_BLOCK_SIZE);
204 switch (sctx->key_len) { 258 do {
205 case 16: 259 /* only use complete blocks */
206 ret = crypt_s390_kmc(KMC_AES_128_DECRYPT, &sctx->iv, out, in, nbytes); 260 unsigned int n = nbytes & ~(AES_BLOCK_SIZE - 1);
207 BUG_ON((ret < 0) || (ret != nbytes)); 261 u8 *out = walk->dst.virt.addr;
208 break; 262 u8 *in = walk->src.virt.addr;
209 case 24: 263
210 ret = crypt_s390_kmc(KMC_AES_192_DECRYPT, &sctx->iv, out, in, nbytes); 264 ret = crypt_s390_kmc(func, param, out, in, n);
211 BUG_ON((ret < 0) || (ret != nbytes)); 265 BUG_ON((ret < 0) || (ret != n));
212 break; 266
213 case 32: 267 nbytes &= AES_BLOCK_SIZE - 1;
214 ret = crypt_s390_kmc(KMC_AES_256_DECRYPT, &sctx->iv, out, in, nbytes); 268 ret = blkcipher_walk_done(desc, walk, nbytes);
215 BUG_ON((ret < 0) || (ret != nbytes)); 269 } while ((nbytes = walk->nbytes));
216 break; 270 memcpy(walk->iv, param, AES_BLOCK_SIZE);
217 } 271
218 return nbytes; 272out:
273 return ret;
219} 274}
220 275
276static 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;
221 282
222static struct crypto_alg aes_alg = { 283 blkcipher_walk_init(&walk, dst, src, nbytes);
223 .cra_name = "aes", 284 return cbc_aes_crypt(desc, sctx->enc, sctx->iv, &walk);
224 .cra_flags = CRYPTO_ALG_TYPE_CIPHER, 285}
286
287static 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
298static 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,
225 .cra_blocksize = AES_BLOCK_SIZE, 303 .cra_blocksize = AES_BLOCK_SIZE,
226 .cra_ctxsize = sizeof(struct s390_aes_ctx), 304 .cra_ctxsize = sizeof(struct s390_aes_ctx),
305 .cra_type = &crypto_blkcipher_type,
227 .cra_module = THIS_MODULE, 306 .cra_module = THIS_MODULE,
228 .cra_list = LIST_HEAD_INIT(aes_alg.cra_list), 307 .cra_list = LIST_HEAD_INIT(cbc_aes_alg.cra_list),
229 .cra_u = { 308 .cra_u = {
230 .cipher = { 309 .blkcipher = {
231 .cia_min_keysize = AES_MIN_KEY_SIZE, 310 .min_keysize = AES_MIN_KEY_SIZE,
232 .cia_max_keysize = AES_MAX_KEY_SIZE, 311 .max_keysize = AES_MAX_KEY_SIZE,
233 .cia_setkey = aes_set_key, 312 .ivsize = AES_BLOCK_SIZE,
234 .cia_encrypt = aes_encrypt, 313 .setkey = cbc_aes_set_key,
235 .cia_decrypt = aes_decrypt, 314 .encrypt = cbc_aes_encrypt,
236 .cia_encrypt_ecb = aes_encrypt_ecb, 315 .decrypt = cbc_aes_decrypt,
237 .cia_decrypt_ecb = aes_decrypt_ecb,
238 .cia_encrypt_cbc = aes_encrypt_cbc,
239 .cia_decrypt_cbc = aes_decrypt_cbc,
240 } 316 }
241 } 317 }
242}; 318};
@@ -256,13 +332,40 @@ static int __init aes_init(void)
256 return -ENOSYS; 332 return -ENOSYS;
257 333
258 ret = crypto_register_alg(&aes_alg); 334 ret = crypto_register_alg(&aes_alg);
259 if (ret != 0) 335 if (ret != 0) {
260 printk(KERN_INFO "crypt_s390: aes_s390 couldn't be loaded.\n"); 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
354out:
261 return ret; 355 return ret;
356
357cbc_aes_err:
358 crypto_unregister_alg(&ecb_aes_alg);
359ecb_aes_err:
360 crypto_unregister_alg(&aes_alg);
361aes_err:
362 goto out;
262} 363}
263 364
264static void __exit aes_fini(void) 365static void __exit aes_fini(void)
265{ 366{
367 crypto_unregister_alg(&cbc_aes_alg);
368 crypto_unregister_alg(&ecb_aes_alg);
266 crypto_unregister_alg(&aes_alg); 369 crypto_unregister_alg(&aes_alg);
267} 370}
268 371