blob: a6d2385ccb7af69adc603ef74e1b6ba723640786 [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*
2 * Cryptographic API.
3 *
Jan Glauberc1e26e12006-01-06 00:19:17 -08004 * s390 implementation of the DES Cipher Algorithm.
Linus Torvalds1da177e2005-04-16 15:20:36 -07005 *
6 * Copyright (c) 2003 IBM Deutschland Entwicklung GmbH, IBM Corporation
7 * Author(s): Thomas Spatzier (tspat@de.ibm.com)
8 *
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 */
Herbert Xua9e62fa2006-08-21 21:39:24 +100016
17#include <crypto/algapi.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070018#include <linux/init.h>
19#include <linux/module.h>
Jan Glauberc1357832006-01-14 13:20:53 -080020
Jan Glauberc1e26e12006-01-06 00:19:17 -080021#include "crypt_s390.h"
Linus Torvalds1da177e2005-04-16 15:20:36 -070022#include "crypto_des.h"
23
24#define DES_BLOCK_SIZE 8
25#define DES_KEY_SIZE 8
26
27#define DES3_128_KEY_SIZE (2 * DES_KEY_SIZE)
28#define DES3_128_BLOCK_SIZE DES_BLOCK_SIZE
29
30#define DES3_192_KEY_SIZE (3 * DES_KEY_SIZE)
31#define DES3_192_BLOCK_SIZE DES_BLOCK_SIZE
32
Jan Glauberc1e26e12006-01-06 00:19:17 -080033struct crypt_s390_des_ctx {
Linus Torvalds1da177e2005-04-16 15:20:36 -070034 u8 iv[DES_BLOCK_SIZE];
35 u8 key[DES_KEY_SIZE];
36};
37
Jan Glauberc1e26e12006-01-06 00:19:17 -080038struct crypt_s390_des3_128_ctx {
Linus Torvalds1da177e2005-04-16 15:20:36 -070039 u8 iv[DES_BLOCK_SIZE];
40 u8 key[DES3_128_KEY_SIZE];
41};
42
Jan Glauberc1e26e12006-01-06 00:19:17 -080043struct crypt_s390_des3_192_ctx {
Linus Torvalds1da177e2005-04-16 15:20:36 -070044 u8 iv[DES_BLOCK_SIZE];
45 u8 key[DES3_192_KEY_SIZE];
46};
47
Herbert Xu6c2bb982006-05-16 22:09:29 +100048static int des_setkey(struct crypto_tfm *tfm, const u8 *key,
Herbert Xu560c06a2006-08-13 14:16:39 +100049 unsigned int keylen)
Linus Torvalds1da177e2005-04-16 15:20:36 -070050{
Herbert Xu6c2bb982006-05-16 22:09:29 +100051 struct crypt_s390_des_ctx *dctx = crypto_tfm_ctx(tfm);
Herbert Xu560c06a2006-08-13 14:16:39 +100052 u32 *flags = &tfm->crt_flags;
Linus Torvalds1da177e2005-04-16 15:20:36 -070053 int ret;
54
Jan Glauberc1357832006-01-14 13:20:53 -080055 /* test if key is valid (not a weak key) */
Linus Torvalds1da177e2005-04-16 15:20:36 -070056 ret = crypto_des_check_key(key, keylen, flags);
Jan Glauberc1357832006-01-14 13:20:53 -080057 if (ret == 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -070058 memcpy(dctx->key, key, keylen);
Linus Torvalds1da177e2005-04-16 15:20:36 -070059 return ret;
60}
61
Herbert Xu6c2bb982006-05-16 22:09:29 +100062static void des_encrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in)
Linus Torvalds1da177e2005-04-16 15:20:36 -070063{
Herbert Xu6c2bb982006-05-16 22:09:29 +100064 struct crypt_s390_des_ctx *dctx = crypto_tfm_ctx(tfm);
Linus Torvalds1da177e2005-04-16 15:20:36 -070065
Jan Glauberb8dc6032006-01-14 13:20:53 -080066 crypt_s390_km(KM_DEA_ENCRYPT, dctx->key, out, in, DES_BLOCK_SIZE);
Linus Torvalds1da177e2005-04-16 15:20:36 -070067}
68
Herbert Xu6c2bb982006-05-16 22:09:29 +100069static void des_decrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in)
Linus Torvalds1da177e2005-04-16 15:20:36 -070070{
Herbert Xu6c2bb982006-05-16 22:09:29 +100071 struct crypt_s390_des_ctx *dctx = crypto_tfm_ctx(tfm);
Linus Torvalds1da177e2005-04-16 15:20:36 -070072
Jan Glauberb8dc6032006-01-14 13:20:53 -080073 crypt_s390_km(KM_DEA_DECRYPT, dctx->key, out, in, DES_BLOCK_SIZE);
74}
75
76static unsigned int des_encrypt_ecb(const struct cipher_desc *desc, u8 *out,
77 const u8 *in, unsigned int nbytes)
78{
79 struct crypt_s390_des_ctx *sctx = crypto_tfm_ctx(desc->tfm);
80 int ret;
81
82 /* only use complete blocks */
83 nbytes &= ~(DES_BLOCK_SIZE - 1);
84 ret = crypt_s390_km(KM_DEA_ENCRYPT, sctx->key, out, in, nbytes);
85 BUG_ON((ret < 0) || (ret != nbytes));
86
87 return nbytes;
88}
89
90static unsigned int des_decrypt_ecb(const struct cipher_desc *desc, u8 *out,
91 const u8 *in, unsigned int nbytes)
92{
93 struct crypt_s390_des_ctx *sctx = crypto_tfm_ctx(desc->tfm);
94 int ret;
95
96 /* only use complete blocks */
97 nbytes &= ~(DES_BLOCK_SIZE - 1);
98 ret = crypt_s390_km(KM_DEA_DECRYPT, sctx->key, out, in, nbytes);
99 BUG_ON((ret < 0) || (ret != nbytes));
100
101 return nbytes;
102}
103
104static unsigned int des_encrypt_cbc(const struct cipher_desc *desc, u8 *out,
105 const u8 *in, unsigned int nbytes)
106{
107 struct crypt_s390_des_ctx *sctx = crypto_tfm_ctx(desc->tfm);
108 int ret;
109
110 /* only use complete blocks */
111 nbytes &= ~(DES_BLOCK_SIZE - 1);
112
113 memcpy(sctx->iv, desc->info, DES_BLOCK_SIZE);
114 ret = crypt_s390_kmc(KMC_DEA_ENCRYPT, &sctx->iv, out, in, nbytes);
115 BUG_ON((ret < 0) || (ret != nbytes));
116
117 memcpy(desc->info, sctx->iv, DES_BLOCK_SIZE);
118 return nbytes;
119}
120
121static unsigned int des_decrypt_cbc(const struct cipher_desc *desc, u8 *out,
122 const u8 *in, unsigned int nbytes)
123{
124 struct crypt_s390_des_ctx *sctx = crypto_tfm_ctx(desc->tfm);
125 int ret;
126
127 /* only use complete blocks */
128 nbytes &= ~(DES_BLOCK_SIZE - 1);
129
130 memcpy(&sctx->iv, desc->info, DES_BLOCK_SIZE);
131 ret = crypt_s390_kmc(KMC_DEA_DECRYPT, &sctx->iv, out, in, nbytes);
132 BUG_ON((ret < 0) || (ret != nbytes));
133
134 return nbytes;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700135}
136
137static struct crypto_alg des_alg = {
138 .cra_name = "des",
Herbert Xu65b75c32006-08-21 21:18:50 +1000139 .cra_driver_name = "des-s390",
140 .cra_priority = CRYPT_S390_PRIORITY,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700141 .cra_flags = CRYPTO_ALG_TYPE_CIPHER,
142 .cra_blocksize = DES_BLOCK_SIZE,
Jan Glauberc1e26e12006-01-06 00:19:17 -0800143 .cra_ctxsize = sizeof(struct crypt_s390_des_ctx),
Linus Torvalds1da177e2005-04-16 15:20:36 -0700144 .cra_module = THIS_MODULE,
145 .cra_list = LIST_HEAD_INIT(des_alg.cra_list),
Jan Glauberc1357832006-01-14 13:20:53 -0800146 .cra_u = {
147 .cipher = {
148 .cia_min_keysize = DES_KEY_SIZE,
149 .cia_max_keysize = DES_KEY_SIZE,
150 .cia_setkey = des_setkey,
151 .cia_encrypt = des_encrypt,
Jan Glauberb8dc6032006-01-14 13:20:53 -0800152 .cia_decrypt = des_decrypt,
153 .cia_encrypt_ecb = des_encrypt_ecb,
154 .cia_decrypt_ecb = des_decrypt_ecb,
155 .cia_encrypt_cbc = des_encrypt_cbc,
156 .cia_decrypt_cbc = des_decrypt_cbc,
Jan Glauberc1357832006-01-14 13:20:53 -0800157 }
158 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700159};
160
Herbert Xua9e62fa2006-08-21 21:39:24 +1000161static int ecb_desall_crypt(struct blkcipher_desc *desc, long func,
162 void *param, struct blkcipher_walk *walk)
163{
164 int ret = blkcipher_walk_virt(desc, walk);
165 unsigned int nbytes;
166
167 while ((nbytes = walk->nbytes)) {
168 /* only use complete blocks */
169 unsigned int n = nbytes & ~(DES_BLOCK_SIZE - 1);
170 u8 *out = walk->dst.virt.addr;
171 u8 *in = walk->src.virt.addr;
172
173 ret = crypt_s390_km(func, param, out, in, n);
174 BUG_ON((ret < 0) || (ret != n));
175
176 nbytes &= DES_BLOCK_SIZE - 1;
177 ret = blkcipher_walk_done(desc, walk, nbytes);
178 }
179
180 return ret;
181}
182
183static int cbc_desall_crypt(struct blkcipher_desc *desc, long func,
184 void *param, struct blkcipher_walk *walk)
185{
186 int ret = blkcipher_walk_virt(desc, walk);
187 unsigned int nbytes = walk->nbytes;
188
189 if (!nbytes)
190 goto out;
191
192 memcpy(param, walk->iv, DES_BLOCK_SIZE);
193 do {
194 /* only use complete blocks */
195 unsigned int n = nbytes & ~(DES_BLOCK_SIZE - 1);
196 u8 *out = walk->dst.virt.addr;
197 u8 *in = walk->src.virt.addr;
198
199 ret = crypt_s390_kmc(func, param, out, in, n);
200 BUG_ON((ret < 0) || (ret != n));
201
202 nbytes &= DES_BLOCK_SIZE - 1;
203 ret = blkcipher_walk_done(desc, walk, nbytes);
204 } while ((nbytes = walk->nbytes));
205 memcpy(walk->iv, param, DES_BLOCK_SIZE);
206
207out:
208 return ret;
209}
210
211static int ecb_des_encrypt(struct blkcipher_desc *desc,
212 struct scatterlist *dst, struct scatterlist *src,
213 unsigned int nbytes)
214{
215 struct crypt_s390_des_ctx *sctx = crypto_blkcipher_ctx(desc->tfm);
216 struct blkcipher_walk walk;
217
218 blkcipher_walk_init(&walk, dst, src, nbytes);
219 return ecb_desall_crypt(desc, KM_DEA_ENCRYPT, sctx->key, &walk);
220}
221
222static int ecb_des_decrypt(struct blkcipher_desc *desc,
223 struct scatterlist *dst, struct scatterlist *src,
224 unsigned int nbytes)
225{
226 struct crypt_s390_des_ctx *sctx = crypto_blkcipher_ctx(desc->tfm);
227 struct blkcipher_walk walk;
228
229 blkcipher_walk_init(&walk, dst, src, nbytes);
230 return ecb_desall_crypt(desc, KM_DEA_DECRYPT, sctx->key, &walk);
231}
232
233static struct crypto_alg ecb_des_alg = {
234 .cra_name = "ecb(des)",
235 .cra_driver_name = "ecb-des-s390",
236 .cra_priority = CRYPT_S390_COMPOSITE_PRIORITY,
237 .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER,
238 .cra_blocksize = DES_BLOCK_SIZE,
239 .cra_ctxsize = sizeof(struct crypt_s390_des_ctx),
240 .cra_type = &crypto_blkcipher_type,
241 .cra_module = THIS_MODULE,
242 .cra_list = LIST_HEAD_INIT(ecb_des_alg.cra_list),
243 .cra_u = {
244 .blkcipher = {
245 .min_keysize = DES_KEY_SIZE,
246 .max_keysize = DES_KEY_SIZE,
247 .setkey = des_setkey,
248 .encrypt = ecb_des_encrypt,
249 .decrypt = ecb_des_decrypt,
250 }
251 }
252};
253
254static int cbc_des_encrypt(struct blkcipher_desc *desc,
255 struct scatterlist *dst, struct scatterlist *src,
256 unsigned int nbytes)
257{
258 struct crypt_s390_des_ctx *sctx = crypto_blkcipher_ctx(desc->tfm);
259 struct blkcipher_walk walk;
260
261 blkcipher_walk_init(&walk, dst, src, nbytes);
262 return cbc_desall_crypt(desc, KMC_DEA_ENCRYPT, sctx->iv, &walk);
263}
264
265static int cbc_des_decrypt(struct blkcipher_desc *desc,
266 struct scatterlist *dst, struct scatterlist *src,
267 unsigned int nbytes)
268{
269 struct crypt_s390_des_ctx *sctx = crypto_blkcipher_ctx(desc->tfm);
270 struct blkcipher_walk walk;
271
272 blkcipher_walk_init(&walk, dst, src, nbytes);
273 return cbc_desall_crypt(desc, KMC_DEA_DECRYPT, sctx->iv, &walk);
274}
275
276static struct crypto_alg cbc_des_alg = {
277 .cra_name = "cbc(des)",
278 .cra_driver_name = "cbc-des-s390",
279 .cra_priority = CRYPT_S390_COMPOSITE_PRIORITY,
280 .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER,
281 .cra_blocksize = DES_BLOCK_SIZE,
282 .cra_ctxsize = sizeof(struct crypt_s390_des_ctx),
283 .cra_type = &crypto_blkcipher_type,
284 .cra_module = THIS_MODULE,
285 .cra_list = LIST_HEAD_INIT(cbc_des_alg.cra_list),
286 .cra_u = {
287 .blkcipher = {
288 .min_keysize = DES_KEY_SIZE,
289 .max_keysize = DES_KEY_SIZE,
290 .ivsize = DES_BLOCK_SIZE,
291 .setkey = des_setkey,
292 .encrypt = cbc_des_encrypt,
293 .decrypt = cbc_des_decrypt,
294 }
295 }
296};
297
Linus Torvalds1da177e2005-04-16 15:20:36 -0700298/*
299 * RFC2451:
300 *
301 * For DES-EDE3, there is no known need to reject weak or
302 * complementation keys. Any weakness is obviated by the use of
303 * multiple keys.
304 *
305 * However, if the two independent 64-bit keys are equal,
306 * then the DES3 operation is simply the same as DES.
307 * Implementers MUST reject keys that exhibit this property.
308 *
309 */
Herbert Xu6c2bb982006-05-16 22:09:29 +1000310static int des3_128_setkey(struct crypto_tfm *tfm, const u8 *key,
Herbert Xu560c06a2006-08-13 14:16:39 +1000311 unsigned int keylen)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700312{
313 int i, ret;
Herbert Xu6c2bb982006-05-16 22:09:29 +1000314 struct crypt_s390_des3_128_ctx *dctx = crypto_tfm_ctx(tfm);
Herbert Xu560c06a2006-08-13 14:16:39 +1000315 const u8 *temp_key = key;
316 u32 *flags = &tfm->crt_flags;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700317
Linus Torvalds1da177e2005-04-16 15:20:36 -0700318 if (!(memcmp(key, &key[DES_KEY_SIZE], DES_KEY_SIZE))) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700319 *flags |= CRYPTO_TFM_RES_BAD_KEY_SCHED;
320 return -EINVAL;
321 }
Jan Glauberc1357832006-01-14 13:20:53 -0800322 for (i = 0; i < 2; i++, temp_key += DES_KEY_SIZE) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700323 ret = crypto_des_check_key(temp_key, DES_KEY_SIZE, flags);
324 if (ret < 0)
325 return ret;
326 }
327 memcpy(dctx->key, key, keylen);
328 return 0;
329}
330
Herbert Xu6c2bb982006-05-16 22:09:29 +1000331static void des3_128_encrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700332{
Herbert Xu6c2bb982006-05-16 22:09:29 +1000333 struct crypt_s390_des3_128_ctx *dctx = crypto_tfm_ctx(tfm);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700334
Jan Glauberc1e26e12006-01-06 00:19:17 -0800335 crypt_s390_km(KM_TDEA_128_ENCRYPT, dctx->key, dst, (void*)src,
Jan Glauberc1357832006-01-14 13:20:53 -0800336 DES3_128_BLOCK_SIZE);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700337}
338
Herbert Xu6c2bb982006-05-16 22:09:29 +1000339static void des3_128_decrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700340{
Herbert Xu6c2bb982006-05-16 22:09:29 +1000341 struct crypt_s390_des3_128_ctx *dctx = crypto_tfm_ctx(tfm);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700342
Jan Glauberc1e26e12006-01-06 00:19:17 -0800343 crypt_s390_km(KM_TDEA_128_DECRYPT, dctx->key, dst, (void*)src,
Jan Glauberc1357832006-01-14 13:20:53 -0800344 DES3_128_BLOCK_SIZE);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700345}
346
Jan Glauberb8dc6032006-01-14 13:20:53 -0800347static unsigned int des3_128_encrypt_ecb(const struct cipher_desc *desc,
348 u8 *out, const u8 *in,
349 unsigned int nbytes)
350{
351 struct crypt_s390_des3_128_ctx *sctx = crypto_tfm_ctx(desc->tfm);
352 int ret;
353
354 /* only use complete blocks */
355 nbytes &= ~(DES3_128_BLOCK_SIZE - 1);
356 ret = crypt_s390_km(KM_TDEA_128_ENCRYPT, sctx->key, out, in, nbytes);
357 BUG_ON((ret < 0) || (ret != nbytes));
358
359 return nbytes;
360}
361
362static unsigned int des3_128_decrypt_ecb(const struct cipher_desc *desc,
363 u8 *out, const u8 *in,
364 unsigned int nbytes)
365{
366 struct crypt_s390_des3_128_ctx *sctx = crypto_tfm_ctx(desc->tfm);
367 int ret;
368
369 /* only use complete blocks */
370 nbytes &= ~(DES3_128_BLOCK_SIZE - 1);
371 ret = crypt_s390_km(KM_TDEA_128_DECRYPT, sctx->key, out, in, nbytes);
372 BUG_ON((ret < 0) || (ret != nbytes));
373
374 return nbytes;
375}
376
377static unsigned int des3_128_encrypt_cbc(const struct cipher_desc *desc,
378 u8 *out, const u8 *in,
379 unsigned int nbytes)
380{
381 struct crypt_s390_des3_128_ctx *sctx = crypto_tfm_ctx(desc->tfm);
382 int ret;
383
384 /* only use complete blocks */
385 nbytes &= ~(DES3_128_BLOCK_SIZE - 1);
386
387 memcpy(sctx->iv, desc->info, DES3_128_BLOCK_SIZE);
388 ret = crypt_s390_kmc(KMC_TDEA_128_ENCRYPT, &sctx->iv, out, in, nbytes);
389 BUG_ON((ret < 0) || (ret != nbytes));
390
391 memcpy(desc->info, sctx->iv, DES3_128_BLOCK_SIZE);
392 return nbytes;
393}
394
395static unsigned int des3_128_decrypt_cbc(const struct cipher_desc *desc,
396 u8 *out, const u8 *in,
397 unsigned int nbytes)
398{
399 struct crypt_s390_des3_128_ctx *sctx = crypto_tfm_ctx(desc->tfm);
400 int ret;
401
402 /* only use complete blocks */
403 nbytes &= ~(DES3_128_BLOCK_SIZE - 1);
404
405 memcpy(&sctx->iv, desc->info, DES3_128_BLOCK_SIZE);
406 ret = crypt_s390_kmc(KMC_TDEA_128_DECRYPT, &sctx->iv, out, in, nbytes);
407 BUG_ON((ret < 0) || (ret != nbytes));
408
409 return nbytes;
410}
411
Linus Torvalds1da177e2005-04-16 15:20:36 -0700412static struct crypto_alg des3_128_alg = {
413 .cra_name = "des3_ede128",
Herbert Xu65b75c32006-08-21 21:18:50 +1000414 .cra_driver_name = "des3_ede128-s390",
415 .cra_priority = CRYPT_S390_PRIORITY,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700416 .cra_flags = CRYPTO_ALG_TYPE_CIPHER,
417 .cra_blocksize = DES3_128_BLOCK_SIZE,
Jan Glauberc1e26e12006-01-06 00:19:17 -0800418 .cra_ctxsize = sizeof(struct crypt_s390_des3_128_ctx),
Linus Torvalds1da177e2005-04-16 15:20:36 -0700419 .cra_module = THIS_MODULE,
420 .cra_list = LIST_HEAD_INIT(des3_128_alg.cra_list),
Jan Glauberc1357832006-01-14 13:20:53 -0800421 .cra_u = {
422 .cipher = {
423 .cia_min_keysize = DES3_128_KEY_SIZE,
424 .cia_max_keysize = DES3_128_KEY_SIZE,
425 .cia_setkey = des3_128_setkey,
426 .cia_encrypt = des3_128_encrypt,
Jan Glauberb8dc6032006-01-14 13:20:53 -0800427 .cia_decrypt = des3_128_decrypt,
428 .cia_encrypt_ecb = des3_128_encrypt_ecb,
429 .cia_decrypt_ecb = des3_128_decrypt_ecb,
430 .cia_encrypt_cbc = des3_128_encrypt_cbc,
431 .cia_decrypt_cbc = des3_128_decrypt_cbc,
Jan Glauberc1357832006-01-14 13:20:53 -0800432 }
433 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700434};
435
Herbert Xua9e62fa2006-08-21 21:39:24 +1000436static int ecb_des3_128_encrypt(struct blkcipher_desc *desc,
437 struct scatterlist *dst,
438 struct scatterlist *src, unsigned int nbytes)
439{
440 struct crypt_s390_des3_128_ctx *sctx = crypto_blkcipher_ctx(desc->tfm);
441 struct blkcipher_walk walk;
442
443 blkcipher_walk_init(&walk, dst, src, nbytes);
444 return ecb_desall_crypt(desc, KM_TDEA_128_ENCRYPT, sctx->key, &walk);
445}
446
447static int ecb_des3_128_decrypt(struct blkcipher_desc *desc,
448 struct scatterlist *dst,
449 struct scatterlist *src, unsigned int nbytes)
450{
451 struct crypt_s390_des3_128_ctx *sctx = crypto_blkcipher_ctx(desc->tfm);
452 struct blkcipher_walk walk;
453
454 blkcipher_walk_init(&walk, dst, src, nbytes);
455 return ecb_desall_crypt(desc, KM_TDEA_128_DECRYPT, sctx->key, &walk);
456}
457
458static struct crypto_alg ecb_des3_128_alg = {
459 .cra_name = "ecb(des3_ede128)",
460 .cra_driver_name = "ecb-des3_ede128-s390",
461 .cra_priority = CRYPT_S390_COMPOSITE_PRIORITY,
462 .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER,
463 .cra_blocksize = DES3_128_BLOCK_SIZE,
464 .cra_ctxsize = sizeof(struct crypt_s390_des3_128_ctx),
465 .cra_type = &crypto_blkcipher_type,
466 .cra_module = THIS_MODULE,
467 .cra_list = LIST_HEAD_INIT(
468 ecb_des3_128_alg.cra_list),
469 .cra_u = {
470 .blkcipher = {
471 .min_keysize = DES3_128_KEY_SIZE,
472 .max_keysize = DES3_128_KEY_SIZE,
473 .setkey = des3_128_setkey,
474 .encrypt = ecb_des3_128_encrypt,
475 .decrypt = ecb_des3_128_decrypt,
476 }
477 }
478};
479
480static int cbc_des3_128_encrypt(struct blkcipher_desc *desc,
481 struct scatterlist *dst,
482 struct scatterlist *src, unsigned int nbytes)
483{
484 struct crypt_s390_des3_128_ctx *sctx = crypto_blkcipher_ctx(desc->tfm);
485 struct blkcipher_walk walk;
486
487 blkcipher_walk_init(&walk, dst, src, nbytes);
488 return cbc_desall_crypt(desc, KMC_TDEA_128_ENCRYPT, sctx->iv, &walk);
489}
490
491static int cbc_des3_128_decrypt(struct blkcipher_desc *desc,
492 struct scatterlist *dst,
493 struct scatterlist *src, unsigned int nbytes)
494{
495 struct crypt_s390_des3_128_ctx *sctx = crypto_blkcipher_ctx(desc->tfm);
496 struct blkcipher_walk walk;
497
498 blkcipher_walk_init(&walk, dst, src, nbytes);
499 return cbc_desall_crypt(desc, KMC_TDEA_128_DECRYPT, sctx->iv, &walk);
500}
501
502static struct crypto_alg cbc_des3_128_alg = {
503 .cra_name = "cbc(des3_ede128)",
504 .cra_driver_name = "cbc-des3_ede128-s390",
505 .cra_priority = CRYPT_S390_COMPOSITE_PRIORITY,
506 .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER,
507 .cra_blocksize = DES3_128_BLOCK_SIZE,
508 .cra_ctxsize = sizeof(struct crypt_s390_des3_128_ctx),
509 .cra_type = &crypto_blkcipher_type,
510 .cra_module = THIS_MODULE,
511 .cra_list = LIST_HEAD_INIT(
512 cbc_des3_128_alg.cra_list),
513 .cra_u = {
514 .blkcipher = {
515 .min_keysize = DES3_128_KEY_SIZE,
516 .max_keysize = DES3_128_KEY_SIZE,
517 .ivsize = DES3_128_BLOCK_SIZE,
518 .setkey = des3_128_setkey,
519 .encrypt = cbc_des3_128_encrypt,
520 .decrypt = cbc_des3_128_decrypt,
521 }
522 }
523};
524
Linus Torvalds1da177e2005-04-16 15:20:36 -0700525/*
526 * RFC2451:
527 *
528 * For DES-EDE3, there is no known need to reject weak or
529 * complementation keys. Any weakness is obviated by the use of
530 * multiple keys.
531 *
532 * However, if the first two or last two independent 64-bit keys are
533 * equal (k1 == k2 or k2 == k3), then the DES3 operation is simply the
534 * same as DES. Implementers MUST reject keys that exhibit this
535 * property.
536 *
537 */
Herbert Xu6c2bb982006-05-16 22:09:29 +1000538static int des3_192_setkey(struct crypto_tfm *tfm, const u8 *key,
Herbert Xu560c06a2006-08-13 14:16:39 +1000539 unsigned int keylen)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700540{
541 int i, ret;
Herbert Xu6c2bb982006-05-16 22:09:29 +1000542 struct crypt_s390_des3_192_ctx *dctx = crypto_tfm_ctx(tfm);
Herbert Xu560c06a2006-08-13 14:16:39 +1000543 const u8 *temp_key = key;
544 u32 *flags = &tfm->crt_flags;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700545
Linus Torvalds1da177e2005-04-16 15:20:36 -0700546 if (!(memcmp(key, &key[DES_KEY_SIZE], DES_KEY_SIZE) &&
547 memcmp(&key[DES_KEY_SIZE], &key[DES_KEY_SIZE * 2],
Jan Glauberc1357832006-01-14 13:20:53 -0800548 DES_KEY_SIZE))) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700549
550 *flags |= CRYPTO_TFM_RES_BAD_KEY_SCHED;
551 return -EINVAL;
552 }
553 for (i = 0; i < 3; i++, temp_key += DES_KEY_SIZE) {
554 ret = crypto_des_check_key(temp_key, DES_KEY_SIZE, flags);
Jan Glauberc1357832006-01-14 13:20:53 -0800555 if (ret < 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700556 return ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700557 }
558 memcpy(dctx->key, key, keylen);
559 return 0;
560}
561
Herbert Xu6c2bb982006-05-16 22:09:29 +1000562static void des3_192_encrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700563{
Herbert Xu6c2bb982006-05-16 22:09:29 +1000564 struct crypt_s390_des3_192_ctx *dctx = crypto_tfm_ctx(tfm);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700565
Jan Glauberc1e26e12006-01-06 00:19:17 -0800566 crypt_s390_km(KM_TDEA_192_ENCRYPT, dctx->key, dst, (void*)src,
Jan Glauberc1357832006-01-14 13:20:53 -0800567 DES3_192_BLOCK_SIZE);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700568}
569
Herbert Xu6c2bb982006-05-16 22:09:29 +1000570static void des3_192_decrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700571{
Herbert Xu6c2bb982006-05-16 22:09:29 +1000572 struct crypt_s390_des3_192_ctx *dctx = crypto_tfm_ctx(tfm);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700573
Jan Glauberc1e26e12006-01-06 00:19:17 -0800574 crypt_s390_km(KM_TDEA_192_DECRYPT, dctx->key, dst, (void*)src,
Jan Glauberc1357832006-01-14 13:20:53 -0800575 DES3_192_BLOCK_SIZE);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700576}
577
Jan Glauberb8dc6032006-01-14 13:20:53 -0800578static unsigned int des3_192_encrypt_ecb(const struct cipher_desc *desc,
579 u8 *out, const u8 *in,
580 unsigned int nbytes)
581{
582 struct crypt_s390_des3_192_ctx *sctx = crypto_tfm_ctx(desc->tfm);
583 int ret;
584
585 /* only use complete blocks */
586 nbytes &= ~(DES3_192_BLOCK_SIZE - 1);
587 ret = crypt_s390_km(KM_TDEA_192_ENCRYPT, sctx->key, out, in, nbytes);
588 BUG_ON((ret < 0) || (ret != nbytes));
589
590 return nbytes;
591}
592
593static unsigned int des3_192_decrypt_ecb(const struct cipher_desc *desc,
594 u8 *out, const u8 *in,
595 unsigned int nbytes)
596{
597 struct crypt_s390_des3_192_ctx *sctx = crypto_tfm_ctx(desc->tfm);
598 int ret;
599
600 /* only use complete blocks */
601 nbytes &= ~(DES3_192_BLOCK_SIZE - 1);
602 ret = crypt_s390_km(KM_TDEA_192_DECRYPT, sctx->key, out, in, nbytes);
603 BUG_ON((ret < 0) || (ret != nbytes));
604
605 return nbytes;
606}
607
608static unsigned int des3_192_encrypt_cbc(const struct cipher_desc *desc,
609 u8 *out, const u8 *in,
610 unsigned int nbytes)
611{
612 struct crypt_s390_des3_192_ctx *sctx = crypto_tfm_ctx(desc->tfm);
613 int ret;
614
615 /* only use complete blocks */
616 nbytes &= ~(DES3_192_BLOCK_SIZE - 1);
617
618 memcpy(sctx->iv, desc->info, DES3_192_BLOCK_SIZE);
619 ret = crypt_s390_kmc(KMC_TDEA_192_ENCRYPT, &sctx->iv, out, in, nbytes);
620 BUG_ON((ret < 0) || (ret != nbytes));
621
622 memcpy(desc->info, sctx->iv, DES3_192_BLOCK_SIZE);
623 return nbytes;
624}
625
626static unsigned int des3_192_decrypt_cbc(const struct cipher_desc *desc,
627 u8 *out, const u8 *in,
628 unsigned int nbytes)
629{
630 struct crypt_s390_des3_192_ctx *sctx = crypto_tfm_ctx(desc->tfm);
631 int ret;
632
633 /* only use complete blocks */
634 nbytes &= ~(DES3_192_BLOCK_SIZE - 1);
635
636 memcpy(&sctx->iv, desc->info, DES3_192_BLOCK_SIZE);
637 ret = crypt_s390_kmc(KMC_TDEA_192_DECRYPT, &sctx->iv, out, in, nbytes);
638 BUG_ON((ret < 0) || (ret != nbytes));
639
640 return nbytes;
641}
642
Linus Torvalds1da177e2005-04-16 15:20:36 -0700643static struct crypto_alg des3_192_alg = {
644 .cra_name = "des3_ede",
Herbert Xu65b75c32006-08-21 21:18:50 +1000645 .cra_driver_name = "des3_ede-s390",
646 .cra_priority = CRYPT_S390_PRIORITY,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700647 .cra_flags = CRYPTO_ALG_TYPE_CIPHER,
648 .cra_blocksize = DES3_192_BLOCK_SIZE,
Jan Glauberc1e26e12006-01-06 00:19:17 -0800649 .cra_ctxsize = sizeof(struct crypt_s390_des3_192_ctx),
Linus Torvalds1da177e2005-04-16 15:20:36 -0700650 .cra_module = THIS_MODULE,
651 .cra_list = LIST_HEAD_INIT(des3_192_alg.cra_list),
Jan Glauberc1357832006-01-14 13:20:53 -0800652 .cra_u = {
653 .cipher = {
654 .cia_min_keysize = DES3_192_KEY_SIZE,
655 .cia_max_keysize = DES3_192_KEY_SIZE,
656 .cia_setkey = des3_192_setkey,
657 .cia_encrypt = des3_192_encrypt,
Jan Glauberb8dc6032006-01-14 13:20:53 -0800658 .cia_decrypt = des3_192_decrypt,
659 .cia_encrypt_ecb = des3_192_encrypt_ecb,
660 .cia_decrypt_ecb = des3_192_decrypt_ecb,
661 .cia_encrypt_cbc = des3_192_encrypt_cbc,
662 .cia_decrypt_cbc = des3_192_decrypt_cbc,
Jan Glauberc1357832006-01-14 13:20:53 -0800663 }
664 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700665};
666
Herbert Xua9e62fa2006-08-21 21:39:24 +1000667static int ecb_des3_192_encrypt(struct blkcipher_desc *desc,
668 struct scatterlist *dst,
669 struct scatterlist *src, unsigned int nbytes)
670{
671 struct crypt_s390_des3_192_ctx *sctx = crypto_blkcipher_ctx(desc->tfm);
672 struct blkcipher_walk walk;
673
674 blkcipher_walk_init(&walk, dst, src, nbytes);
675 return ecb_desall_crypt(desc, KM_TDEA_192_ENCRYPT, sctx->key, &walk);
676}
677
678static int ecb_des3_192_decrypt(struct blkcipher_desc *desc,
679 struct scatterlist *dst,
680 struct scatterlist *src, unsigned int nbytes)
681{
682 struct crypt_s390_des3_192_ctx *sctx = crypto_blkcipher_ctx(desc->tfm);
683 struct blkcipher_walk walk;
684
685 blkcipher_walk_init(&walk, dst, src, nbytes);
686 return ecb_desall_crypt(desc, KM_TDEA_192_DECRYPT, sctx->key, &walk);
687}
688
689static struct crypto_alg ecb_des3_192_alg = {
690 .cra_name = "ecb(des3_ede)",
691 .cra_driver_name = "ecb-des3_ede-s390",
692 .cra_priority = CRYPT_S390_COMPOSITE_PRIORITY,
693 .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER,
694 .cra_blocksize = DES3_192_BLOCK_SIZE,
695 .cra_ctxsize = sizeof(struct crypt_s390_des3_192_ctx),
696 .cra_type = &crypto_blkcipher_type,
697 .cra_module = THIS_MODULE,
698 .cra_list = LIST_HEAD_INIT(
699 ecb_des3_192_alg.cra_list),
700 .cra_u = {
701 .blkcipher = {
702 .min_keysize = DES3_192_KEY_SIZE,
703 .max_keysize = DES3_192_KEY_SIZE,
704 .setkey = des3_192_setkey,
705 .encrypt = ecb_des3_192_encrypt,
706 .decrypt = ecb_des3_192_decrypt,
707 }
708 }
709};
710
711static int cbc_des3_192_encrypt(struct blkcipher_desc *desc,
712 struct scatterlist *dst,
713 struct scatterlist *src, unsigned int nbytes)
714{
715 struct crypt_s390_des3_192_ctx *sctx = crypto_blkcipher_ctx(desc->tfm);
716 struct blkcipher_walk walk;
717
718 blkcipher_walk_init(&walk, dst, src, nbytes);
719 return cbc_desall_crypt(desc, KMC_TDEA_192_ENCRYPT, sctx->iv, &walk);
720}
721
722static int cbc_des3_192_decrypt(struct blkcipher_desc *desc,
723 struct scatterlist *dst,
724 struct scatterlist *src, unsigned int nbytes)
725{
726 struct crypt_s390_des3_192_ctx *sctx = crypto_blkcipher_ctx(desc->tfm);
727 struct blkcipher_walk walk;
728
729 blkcipher_walk_init(&walk, dst, src, nbytes);
730 return cbc_desall_crypt(desc, KMC_TDEA_192_DECRYPT, sctx->iv, &walk);
731}
732
733static struct crypto_alg cbc_des3_192_alg = {
734 .cra_name = "cbc(des3_ede)",
735 .cra_driver_name = "cbc-des3_ede-s390",
736 .cra_priority = CRYPT_S390_COMPOSITE_PRIORITY,
737 .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER,
738 .cra_blocksize = DES3_192_BLOCK_SIZE,
739 .cra_ctxsize = sizeof(struct crypt_s390_des3_192_ctx),
740 .cra_type = &crypto_blkcipher_type,
741 .cra_module = THIS_MODULE,
742 .cra_list = LIST_HEAD_INIT(
743 cbc_des3_192_alg.cra_list),
744 .cra_u = {
745 .blkcipher = {
746 .min_keysize = DES3_192_KEY_SIZE,
747 .max_keysize = DES3_192_KEY_SIZE,
748 .ivsize = DES3_192_BLOCK_SIZE,
749 .setkey = des3_192_setkey,
750 .encrypt = cbc_des3_192_encrypt,
751 .decrypt = cbc_des3_192_decrypt,
752 }
753 }
754};
755
Jan Glauberc1357832006-01-14 13:20:53 -0800756static int init(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700757{
Jan Glauberc1357832006-01-14 13:20:53 -0800758 int ret = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700759
Jan Glauberc1e26e12006-01-06 00:19:17 -0800760 if (!crypt_s390_func_available(KM_DEA_ENCRYPT) ||
761 !crypt_s390_func_available(KM_TDEA_128_ENCRYPT) ||
Jan Glauberc1357832006-01-14 13:20:53 -0800762 !crypt_s390_func_available(KM_TDEA_192_ENCRYPT))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700763 return -ENOSYS;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700764
Herbert Xua9e62fa2006-08-21 21:39:24 +1000765 ret = crypto_register_alg(&des_alg);
766 if (ret)
767 goto des_err;
768 ret = crypto_register_alg(&ecb_des_alg);
769 if (ret)
770 goto ecb_des_err;
771 ret = crypto_register_alg(&cbc_des_alg);
772 if (ret)
773 goto cbc_des_err;
774
775 ret = crypto_register_alg(&des3_128_alg);
776 if (ret)
777 goto des3_128_err;
778 ret = crypto_register_alg(&ecb_des3_128_alg);
779 if (ret)
780 goto ecb_des3_128_err;
781 ret = crypto_register_alg(&cbc_des3_128_alg);
782 if (ret)
783 goto cbc_des3_128_err;
784
785 ret = crypto_register_alg(&des3_192_alg);
786 if (ret)
787 goto des3_192_err;
788 ret = crypto_register_alg(&ecb_des3_192_alg);
789 if (ret)
790 goto ecb_des3_192_err;
791 ret = crypto_register_alg(&cbc_des3_192_alg);
792 if (ret)
793 goto cbc_des3_192_err;
794
795out:
796 return ret;
797
798cbc_des3_192_err:
799 crypto_unregister_alg(&ecb_des3_192_alg);
800ecb_des3_192_err:
801 crypto_unregister_alg(&des3_192_alg);
802des3_192_err:
803 crypto_unregister_alg(&cbc_des3_128_alg);
804cbc_des3_128_err:
805 crypto_unregister_alg(&ecb_des3_128_alg);
806ecb_des3_128_err:
807 crypto_unregister_alg(&des3_128_alg);
808des3_128_err:
809 crypto_unregister_alg(&cbc_des_alg);
810cbc_des_err:
811 crypto_unregister_alg(&ecb_des_alg);
812ecb_des_err:
813 crypto_unregister_alg(&des_alg);
814des_err:
815 goto out;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700816}
817
Jan Glauberc1357832006-01-14 13:20:53 -0800818static void __exit fini(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700819{
Herbert Xua9e62fa2006-08-21 21:39:24 +1000820 crypto_unregister_alg(&cbc_des3_192_alg);
821 crypto_unregister_alg(&ecb_des3_192_alg);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700822 crypto_unregister_alg(&des3_192_alg);
Herbert Xua9e62fa2006-08-21 21:39:24 +1000823 crypto_unregister_alg(&cbc_des3_128_alg);
824 crypto_unregister_alg(&ecb_des3_128_alg);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700825 crypto_unregister_alg(&des3_128_alg);
Herbert Xua9e62fa2006-08-21 21:39:24 +1000826 crypto_unregister_alg(&cbc_des_alg);
827 crypto_unregister_alg(&ecb_des_alg);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700828 crypto_unregister_alg(&des_alg);
829}
830
831module_init(init);
832module_exit(fini);
833
834MODULE_ALIAS("des");
835MODULE_ALIAS("des3_ede");
836
837MODULE_LICENSE("GPL");
838MODULE_DESCRIPTION("DES & Triple DES EDE Cipher Algorithms");