Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/arch/s390/crypto/des_s390.c
26424 views
1
// SPDX-License-Identifier: GPL-2.0+
2
/*
3
* Cryptographic API.
4
*
5
* s390 implementation of the DES Cipher Algorithm.
6
*
7
* Copyright IBM Corp. 2003, 2011
8
* Author(s): Thomas Spatzier
9
* Jan Glauber ([email protected])
10
*/
11
12
#include <linux/init.h>
13
#include <linux/module.h>
14
#include <linux/cpufeature.h>
15
#include <linux/crypto.h>
16
#include <linux/fips.h>
17
#include <linux/mutex.h>
18
#include <crypto/algapi.h>
19
#include <crypto/internal/des.h>
20
#include <crypto/internal/skcipher.h>
21
#include <asm/cpacf.h>
22
23
#define DES3_KEY_SIZE (3 * DES_KEY_SIZE)
24
25
static u8 *ctrblk;
26
static DEFINE_MUTEX(ctrblk_lock);
27
28
static cpacf_mask_t km_functions, kmc_functions, kmctr_functions;
29
30
struct s390_des_ctx {
31
u8 iv[DES_BLOCK_SIZE];
32
u8 key[DES3_KEY_SIZE];
33
};
34
35
static int des_setkey(struct crypto_tfm *tfm, const u8 *key,
36
unsigned int key_len)
37
{
38
struct s390_des_ctx *ctx = crypto_tfm_ctx(tfm);
39
int err;
40
41
err = crypto_des_verify_key(tfm, key);
42
if (err)
43
return err;
44
45
memcpy(ctx->key, key, key_len);
46
return 0;
47
}
48
49
static int des_setkey_skcipher(struct crypto_skcipher *tfm, const u8 *key,
50
unsigned int key_len)
51
{
52
return des_setkey(crypto_skcipher_tfm(tfm), key, key_len);
53
}
54
55
static void s390_des_encrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in)
56
{
57
struct s390_des_ctx *ctx = crypto_tfm_ctx(tfm);
58
59
cpacf_km(CPACF_KM_DEA, ctx->key, out, in, DES_BLOCK_SIZE);
60
}
61
62
static void s390_des_decrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in)
63
{
64
struct s390_des_ctx *ctx = crypto_tfm_ctx(tfm);
65
66
cpacf_km(CPACF_KM_DEA | CPACF_DECRYPT,
67
ctx->key, out, in, DES_BLOCK_SIZE);
68
}
69
70
static struct crypto_alg des_alg = {
71
.cra_name = "des",
72
.cra_driver_name = "des-s390",
73
.cra_priority = 300,
74
.cra_flags = CRYPTO_ALG_TYPE_CIPHER,
75
.cra_blocksize = DES_BLOCK_SIZE,
76
.cra_ctxsize = sizeof(struct s390_des_ctx),
77
.cra_module = THIS_MODULE,
78
.cra_u = {
79
.cipher = {
80
.cia_min_keysize = DES_KEY_SIZE,
81
.cia_max_keysize = DES_KEY_SIZE,
82
.cia_setkey = des_setkey,
83
.cia_encrypt = s390_des_encrypt,
84
.cia_decrypt = s390_des_decrypt,
85
}
86
}
87
};
88
89
static int ecb_desall_crypt(struct skcipher_request *req, unsigned long fc)
90
{
91
struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
92
struct s390_des_ctx *ctx = crypto_skcipher_ctx(tfm);
93
struct skcipher_walk walk;
94
unsigned int nbytes, n;
95
int ret;
96
97
ret = skcipher_walk_virt(&walk, req, false);
98
while ((nbytes = walk.nbytes) != 0) {
99
/* only use complete blocks */
100
n = nbytes & ~(DES_BLOCK_SIZE - 1);
101
cpacf_km(fc, ctx->key, walk.dst.virt.addr,
102
walk.src.virt.addr, n);
103
ret = skcipher_walk_done(&walk, nbytes - n);
104
}
105
return ret;
106
}
107
108
static int cbc_desall_crypt(struct skcipher_request *req, unsigned long fc)
109
{
110
struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
111
struct s390_des_ctx *ctx = crypto_skcipher_ctx(tfm);
112
struct skcipher_walk walk;
113
unsigned int nbytes, n;
114
int ret;
115
struct {
116
u8 iv[DES_BLOCK_SIZE];
117
u8 key[DES3_KEY_SIZE];
118
} param;
119
120
ret = skcipher_walk_virt(&walk, req, false);
121
if (ret)
122
return ret;
123
memcpy(param.iv, walk.iv, DES_BLOCK_SIZE);
124
memcpy(param.key, ctx->key, DES3_KEY_SIZE);
125
while ((nbytes = walk.nbytes) != 0) {
126
/* only use complete blocks */
127
n = nbytes & ~(DES_BLOCK_SIZE - 1);
128
cpacf_kmc(fc, &param, walk.dst.virt.addr,
129
walk.src.virt.addr, n);
130
memcpy(walk.iv, param.iv, DES_BLOCK_SIZE);
131
ret = skcipher_walk_done(&walk, nbytes - n);
132
}
133
return ret;
134
}
135
136
static int ecb_des_encrypt(struct skcipher_request *req)
137
{
138
return ecb_desall_crypt(req, CPACF_KM_DEA);
139
}
140
141
static int ecb_des_decrypt(struct skcipher_request *req)
142
{
143
return ecb_desall_crypt(req, CPACF_KM_DEA | CPACF_DECRYPT);
144
}
145
146
static struct skcipher_alg ecb_des_alg = {
147
.base.cra_name = "ecb(des)",
148
.base.cra_driver_name = "ecb-des-s390",
149
.base.cra_priority = 400, /* combo: des + ecb */
150
.base.cra_blocksize = DES_BLOCK_SIZE,
151
.base.cra_ctxsize = sizeof(struct s390_des_ctx),
152
.base.cra_module = THIS_MODULE,
153
.min_keysize = DES_KEY_SIZE,
154
.max_keysize = DES_KEY_SIZE,
155
.setkey = des_setkey_skcipher,
156
.encrypt = ecb_des_encrypt,
157
.decrypt = ecb_des_decrypt,
158
};
159
160
static int cbc_des_encrypt(struct skcipher_request *req)
161
{
162
return cbc_desall_crypt(req, CPACF_KMC_DEA);
163
}
164
165
static int cbc_des_decrypt(struct skcipher_request *req)
166
{
167
return cbc_desall_crypt(req, CPACF_KMC_DEA | CPACF_DECRYPT);
168
}
169
170
static struct skcipher_alg cbc_des_alg = {
171
.base.cra_name = "cbc(des)",
172
.base.cra_driver_name = "cbc-des-s390",
173
.base.cra_priority = 400, /* combo: des + cbc */
174
.base.cra_blocksize = DES_BLOCK_SIZE,
175
.base.cra_ctxsize = sizeof(struct s390_des_ctx),
176
.base.cra_module = THIS_MODULE,
177
.min_keysize = DES_KEY_SIZE,
178
.max_keysize = DES_KEY_SIZE,
179
.ivsize = DES_BLOCK_SIZE,
180
.setkey = des_setkey_skcipher,
181
.encrypt = cbc_des_encrypt,
182
.decrypt = cbc_des_decrypt,
183
};
184
185
/*
186
* RFC2451:
187
*
188
* For DES-EDE3, there is no known need to reject weak or
189
* complementation keys. Any weakness is obviated by the use of
190
* multiple keys.
191
*
192
* However, if the first two or last two independent 64-bit keys are
193
* equal (k1 == k2 or k2 == k3), then the DES3 operation is simply the
194
* same as DES. Implementers MUST reject keys that exhibit this
195
* property.
196
*
197
* In fips mode additionally check for all 3 keys are unique.
198
*
199
*/
200
static int des3_setkey(struct crypto_tfm *tfm, const u8 *key,
201
unsigned int key_len)
202
{
203
struct s390_des_ctx *ctx = crypto_tfm_ctx(tfm);
204
int err;
205
206
err = crypto_des3_ede_verify_key(tfm, key);
207
if (err)
208
return err;
209
210
memcpy(ctx->key, key, key_len);
211
return 0;
212
}
213
214
static int des3_setkey_skcipher(struct crypto_skcipher *tfm, const u8 *key,
215
unsigned int key_len)
216
{
217
return des3_setkey(crypto_skcipher_tfm(tfm), key, key_len);
218
}
219
220
static void des3_encrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)
221
{
222
struct s390_des_ctx *ctx = crypto_tfm_ctx(tfm);
223
224
cpacf_km(CPACF_KM_TDEA_192, ctx->key, dst, src, DES_BLOCK_SIZE);
225
}
226
227
static void des3_decrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)
228
{
229
struct s390_des_ctx *ctx = crypto_tfm_ctx(tfm);
230
231
cpacf_km(CPACF_KM_TDEA_192 | CPACF_DECRYPT,
232
ctx->key, dst, src, DES_BLOCK_SIZE);
233
}
234
235
static struct crypto_alg des3_alg = {
236
.cra_name = "des3_ede",
237
.cra_driver_name = "des3_ede-s390",
238
.cra_priority = 300,
239
.cra_flags = CRYPTO_ALG_TYPE_CIPHER,
240
.cra_blocksize = DES_BLOCK_SIZE,
241
.cra_ctxsize = sizeof(struct s390_des_ctx),
242
.cra_module = THIS_MODULE,
243
.cra_u = {
244
.cipher = {
245
.cia_min_keysize = DES3_KEY_SIZE,
246
.cia_max_keysize = DES3_KEY_SIZE,
247
.cia_setkey = des3_setkey,
248
.cia_encrypt = des3_encrypt,
249
.cia_decrypt = des3_decrypt,
250
}
251
}
252
};
253
254
static int ecb_des3_encrypt(struct skcipher_request *req)
255
{
256
return ecb_desall_crypt(req, CPACF_KM_TDEA_192);
257
}
258
259
static int ecb_des3_decrypt(struct skcipher_request *req)
260
{
261
return ecb_desall_crypt(req, CPACF_KM_TDEA_192 | CPACF_DECRYPT);
262
}
263
264
static struct skcipher_alg ecb_des3_alg = {
265
.base.cra_name = "ecb(des3_ede)",
266
.base.cra_driver_name = "ecb-des3_ede-s390",
267
.base.cra_priority = 400, /* combo: des3 + ecb */
268
.base.cra_blocksize = DES_BLOCK_SIZE,
269
.base.cra_ctxsize = sizeof(struct s390_des_ctx),
270
.base.cra_module = THIS_MODULE,
271
.min_keysize = DES3_KEY_SIZE,
272
.max_keysize = DES3_KEY_SIZE,
273
.setkey = des3_setkey_skcipher,
274
.encrypt = ecb_des3_encrypt,
275
.decrypt = ecb_des3_decrypt,
276
};
277
278
static int cbc_des3_encrypt(struct skcipher_request *req)
279
{
280
return cbc_desall_crypt(req, CPACF_KMC_TDEA_192);
281
}
282
283
static int cbc_des3_decrypt(struct skcipher_request *req)
284
{
285
return cbc_desall_crypt(req, CPACF_KMC_TDEA_192 | CPACF_DECRYPT);
286
}
287
288
static struct skcipher_alg cbc_des3_alg = {
289
.base.cra_name = "cbc(des3_ede)",
290
.base.cra_driver_name = "cbc-des3_ede-s390",
291
.base.cra_priority = 400, /* combo: des3 + cbc */
292
.base.cra_blocksize = DES_BLOCK_SIZE,
293
.base.cra_ctxsize = sizeof(struct s390_des_ctx),
294
.base.cra_module = THIS_MODULE,
295
.min_keysize = DES3_KEY_SIZE,
296
.max_keysize = DES3_KEY_SIZE,
297
.ivsize = DES_BLOCK_SIZE,
298
.setkey = des3_setkey_skcipher,
299
.encrypt = cbc_des3_encrypt,
300
.decrypt = cbc_des3_decrypt,
301
};
302
303
static unsigned int __ctrblk_init(u8 *ctrptr, u8 *iv, unsigned int nbytes)
304
{
305
unsigned int i, n;
306
307
/* align to block size, max. PAGE_SIZE */
308
n = (nbytes > PAGE_SIZE) ? PAGE_SIZE : nbytes & ~(DES_BLOCK_SIZE - 1);
309
memcpy(ctrptr, iv, DES_BLOCK_SIZE);
310
for (i = (n / DES_BLOCK_SIZE) - 1; i > 0; i--) {
311
memcpy(ctrptr + DES_BLOCK_SIZE, ctrptr, DES_BLOCK_SIZE);
312
crypto_inc(ctrptr + DES_BLOCK_SIZE, DES_BLOCK_SIZE);
313
ctrptr += DES_BLOCK_SIZE;
314
}
315
return n;
316
}
317
318
static int ctr_desall_crypt(struct skcipher_request *req, unsigned long fc)
319
{
320
struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
321
struct s390_des_ctx *ctx = crypto_skcipher_ctx(tfm);
322
u8 buf[DES_BLOCK_SIZE], *ctrptr;
323
struct skcipher_walk walk;
324
unsigned int n, nbytes;
325
int ret, locked;
326
327
locked = mutex_trylock(&ctrblk_lock);
328
329
ret = skcipher_walk_virt(&walk, req, false);
330
while ((nbytes = walk.nbytes) >= DES_BLOCK_SIZE) {
331
n = DES_BLOCK_SIZE;
332
if (nbytes >= 2*DES_BLOCK_SIZE && locked)
333
n = __ctrblk_init(ctrblk, walk.iv, nbytes);
334
ctrptr = (n > DES_BLOCK_SIZE) ? ctrblk : walk.iv;
335
cpacf_kmctr(fc, ctx->key, walk.dst.virt.addr,
336
walk.src.virt.addr, n, ctrptr);
337
if (ctrptr == ctrblk)
338
memcpy(walk.iv, ctrptr + n - DES_BLOCK_SIZE,
339
DES_BLOCK_SIZE);
340
crypto_inc(walk.iv, DES_BLOCK_SIZE);
341
ret = skcipher_walk_done(&walk, nbytes - n);
342
}
343
if (locked)
344
mutex_unlock(&ctrblk_lock);
345
/* final block may be < DES_BLOCK_SIZE, copy only nbytes */
346
if (nbytes) {
347
cpacf_kmctr(fc, ctx->key, buf, walk.src.virt.addr,
348
DES_BLOCK_SIZE, walk.iv);
349
memcpy(walk.dst.virt.addr, buf, nbytes);
350
crypto_inc(walk.iv, DES_BLOCK_SIZE);
351
ret = skcipher_walk_done(&walk, 0);
352
}
353
return ret;
354
}
355
356
static int ctr_des_crypt(struct skcipher_request *req)
357
{
358
return ctr_desall_crypt(req, CPACF_KMCTR_DEA);
359
}
360
361
static struct skcipher_alg ctr_des_alg = {
362
.base.cra_name = "ctr(des)",
363
.base.cra_driver_name = "ctr-des-s390",
364
.base.cra_priority = 400, /* combo: des + ctr */
365
.base.cra_blocksize = 1,
366
.base.cra_ctxsize = sizeof(struct s390_des_ctx),
367
.base.cra_module = THIS_MODULE,
368
.min_keysize = DES_KEY_SIZE,
369
.max_keysize = DES_KEY_SIZE,
370
.ivsize = DES_BLOCK_SIZE,
371
.setkey = des_setkey_skcipher,
372
.encrypt = ctr_des_crypt,
373
.decrypt = ctr_des_crypt,
374
.chunksize = DES_BLOCK_SIZE,
375
};
376
377
static int ctr_des3_crypt(struct skcipher_request *req)
378
{
379
return ctr_desall_crypt(req, CPACF_KMCTR_TDEA_192);
380
}
381
382
static struct skcipher_alg ctr_des3_alg = {
383
.base.cra_name = "ctr(des3_ede)",
384
.base.cra_driver_name = "ctr-des3_ede-s390",
385
.base.cra_priority = 400, /* combo: des3 + ede */
386
.base.cra_blocksize = 1,
387
.base.cra_ctxsize = sizeof(struct s390_des_ctx),
388
.base.cra_module = THIS_MODULE,
389
.min_keysize = DES3_KEY_SIZE,
390
.max_keysize = DES3_KEY_SIZE,
391
.ivsize = DES_BLOCK_SIZE,
392
.setkey = des3_setkey_skcipher,
393
.encrypt = ctr_des3_crypt,
394
.decrypt = ctr_des3_crypt,
395
.chunksize = DES_BLOCK_SIZE,
396
};
397
398
static struct crypto_alg *des_s390_algs_ptr[2];
399
static int des_s390_algs_num;
400
static struct skcipher_alg *des_s390_skciphers_ptr[6];
401
static int des_s390_skciphers_num;
402
403
static int des_s390_register_alg(struct crypto_alg *alg)
404
{
405
int ret;
406
407
ret = crypto_register_alg(alg);
408
if (!ret)
409
des_s390_algs_ptr[des_s390_algs_num++] = alg;
410
return ret;
411
}
412
413
static int des_s390_register_skcipher(struct skcipher_alg *alg)
414
{
415
int ret;
416
417
ret = crypto_register_skcipher(alg);
418
if (!ret)
419
des_s390_skciphers_ptr[des_s390_skciphers_num++] = alg;
420
return ret;
421
}
422
423
static void des_s390_exit(void)
424
{
425
while (des_s390_algs_num--)
426
crypto_unregister_alg(des_s390_algs_ptr[des_s390_algs_num]);
427
while (des_s390_skciphers_num--)
428
crypto_unregister_skcipher(des_s390_skciphers_ptr[des_s390_skciphers_num]);
429
if (ctrblk)
430
free_page((unsigned long) ctrblk);
431
}
432
433
static int __init des_s390_init(void)
434
{
435
int ret;
436
437
/* Query available functions for KM, KMC and KMCTR */
438
cpacf_query(CPACF_KM, &km_functions);
439
cpacf_query(CPACF_KMC, &kmc_functions);
440
cpacf_query(CPACF_KMCTR, &kmctr_functions);
441
442
if (cpacf_test_func(&km_functions, CPACF_KM_DEA)) {
443
ret = des_s390_register_alg(&des_alg);
444
if (ret)
445
goto out_err;
446
ret = des_s390_register_skcipher(&ecb_des_alg);
447
if (ret)
448
goto out_err;
449
}
450
if (cpacf_test_func(&kmc_functions, CPACF_KMC_DEA)) {
451
ret = des_s390_register_skcipher(&cbc_des_alg);
452
if (ret)
453
goto out_err;
454
}
455
if (cpacf_test_func(&km_functions, CPACF_KM_TDEA_192)) {
456
ret = des_s390_register_alg(&des3_alg);
457
if (ret)
458
goto out_err;
459
ret = des_s390_register_skcipher(&ecb_des3_alg);
460
if (ret)
461
goto out_err;
462
}
463
if (cpacf_test_func(&kmc_functions, CPACF_KMC_TDEA_192)) {
464
ret = des_s390_register_skcipher(&cbc_des3_alg);
465
if (ret)
466
goto out_err;
467
}
468
469
if (cpacf_test_func(&kmctr_functions, CPACF_KMCTR_DEA) ||
470
cpacf_test_func(&kmctr_functions, CPACF_KMCTR_TDEA_192)) {
471
ctrblk = (u8 *) __get_free_page(GFP_KERNEL);
472
if (!ctrblk) {
473
ret = -ENOMEM;
474
goto out_err;
475
}
476
}
477
478
if (cpacf_test_func(&kmctr_functions, CPACF_KMCTR_DEA)) {
479
ret = des_s390_register_skcipher(&ctr_des_alg);
480
if (ret)
481
goto out_err;
482
}
483
if (cpacf_test_func(&kmctr_functions, CPACF_KMCTR_TDEA_192)) {
484
ret = des_s390_register_skcipher(&ctr_des3_alg);
485
if (ret)
486
goto out_err;
487
}
488
489
return 0;
490
out_err:
491
des_s390_exit();
492
return ret;
493
}
494
495
module_cpu_feature_match(S390_CPU_FEATURE_MSA, des_s390_init);
496
module_exit(des_s390_exit);
497
498
MODULE_ALIAS_CRYPTO("des");
499
MODULE_ALIAS_CRYPTO("des3_ede");
500
501
MODULE_LICENSE("GPL");
502
MODULE_DESCRIPTION("DES & Triple DES EDE Cipher Algorithms");
503
504