Commit | Line | Data |
---|---|---|
20a884f5 | 1 | // SPDX-License-Identifier: GPL-2.0 |
27937843 MS |
2 | /* |
3 | * Cryptographic API. | |
4 | * | |
5 | * s390 implementation of the AES Cipher Algorithm with protected keys. | |
6 | * | |
7 | * s390 Version: | |
416f79c2 | 8 | * Copyright IBM Corp. 2017,2019 |
27937843 MS |
9 | * Author(s): Martin Schwidefsky <schwidefsky@de.ibm.com> |
10 | * Harald Freudenberger <freude@de.ibm.com> | |
27937843 MS |
11 | */ |
12 | ||
13 | #define KMSG_COMPONENT "paes_s390" | |
14 | #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt | |
15 | ||
16 | #include <crypto/aes.h> | |
17 | #include <crypto/algapi.h> | |
18 | #include <linux/bug.h> | |
19 | #include <linux/err.h> | |
20 | #include <linux/module.h> | |
21 | #include <linux/cpufeature.h> | |
22 | #include <linux/init.h> | |
23 | #include <linux/spinlock.h> | |
d00c0639 | 24 | #include <crypto/internal/skcipher.h> |
27937843 MS |
25 | #include <crypto/xts.h> |
26 | #include <asm/cpacf.h> | |
27 | #include <asm/pkey.h> | |
28 | ||
416f79c2 HF |
29 | /* |
30 | * Key blobs smaller/bigger than these defines are rejected | |
31 | * by the common code even before the individual setkey function | |
32 | * is called. As paes can handle different kinds of key blobs | |
33 | * and padding is also possible, the limits need to be generous. | |
34 | */ | |
35 | #define PAES_MIN_KEYSIZE 64 | |
36 | #define PAES_MAX_KEYSIZE 256 | |
37 | ||
27937843 MS |
38 | static u8 *ctrblk; |
39 | static DEFINE_SPINLOCK(ctrblk_lock); | |
40 | ||
41 | static cpacf_mask_t km_functions, kmc_functions, kmctr_functions; | |
42 | ||
52a34b34 | 43 | struct key_blob { |
416f79c2 HF |
44 | /* |
45 | * Small keys will be stored in the keybuf. Larger keys are | |
46 | * stored in extra allocated memory. In both cases does | |
47 | * key point to the memory where the key is stored. | |
48 | * The code distinguishes by checking keylen against | |
49 | * sizeof(keybuf). See the two following helper functions. | |
50 | */ | |
51 | u8 *key; | |
52 | u8 keybuf[128]; | |
52a34b34 IF |
53 | unsigned int keylen; |
54 | }; | |
55 | ||
416f79c2 HF |
56 | static inline int _copy_key_to_kb(struct key_blob *kb, |
57 | const u8 *key, | |
58 | unsigned int keylen) | |
59 | { | |
60 | if (keylen <= sizeof(kb->keybuf)) | |
61 | kb->key = kb->keybuf; | |
62 | else { | |
63 | kb->key = kmalloc(keylen, GFP_KERNEL); | |
64 | if (!kb->key) | |
65 | return -ENOMEM; | |
66 | } | |
67 | memcpy(kb->key, key, keylen); | |
68 | kb->keylen = keylen; | |
69 | ||
70 | return 0; | |
71 | } | |
72 | ||
73 | static inline void _free_kb_keybuf(struct key_blob *kb) | |
74 | { | |
75 | if (kb->key && kb->key != kb->keybuf | |
76 | && kb->keylen > sizeof(kb->keybuf)) { | |
77 | kfree(kb->key); | |
78 | kb->key = NULL; | |
79 | } | |
80 | } | |
81 | ||
27937843 | 82 | struct s390_paes_ctx { |
52a34b34 | 83 | struct key_blob kb; |
27937843 MS |
84 | struct pkey_protkey pk; |
85 | unsigned long fc; | |
86 | }; | |
87 | ||
88 | struct s390_pxts_ctx { | |
52a34b34 | 89 | struct key_blob kb[2]; |
27937843 MS |
90 | struct pkey_protkey pk[2]; |
91 | unsigned long fc; | |
92 | }; | |
93 | ||
52a34b34 | 94 | static inline int __paes_convert_key(struct key_blob *kb, |
27937843 MS |
95 | struct pkey_protkey *pk) |
96 | { | |
97 | int i, ret; | |
98 | ||
99 | /* try three times in case of failure */ | |
100 | for (i = 0; i < 3; i++) { | |
52a34b34 | 101 | ret = pkey_keyblob2pkey(kb->key, kb->keylen, pk); |
27937843 MS |
102 | if (ret == 0) |
103 | break; | |
104 | } | |
105 | ||
106 | return ret; | |
107 | } | |
108 | ||
109 | static int __paes_set_key(struct s390_paes_ctx *ctx) | |
110 | { | |
111 | unsigned long fc; | |
112 | ||
52a34b34 | 113 | if (__paes_convert_key(&ctx->kb, &ctx->pk)) |
27937843 MS |
114 | return -EINVAL; |
115 | ||
116 | /* Pick the correct function code based on the protected key type */ | |
117 | fc = (ctx->pk.type == PKEY_KEYTYPE_AES_128) ? CPACF_KM_PAES_128 : | |
118 | (ctx->pk.type == PKEY_KEYTYPE_AES_192) ? CPACF_KM_PAES_192 : | |
119 | (ctx->pk.type == PKEY_KEYTYPE_AES_256) ? CPACF_KM_PAES_256 : 0; | |
120 | ||
121 | /* Check if the function code is available */ | |
122 | ctx->fc = (fc && cpacf_test_func(&km_functions, fc)) ? fc : 0; | |
123 | ||
124 | return ctx->fc ? 0 : -EINVAL; | |
125 | } | |
126 | ||
d00c0639 | 127 | static int ecb_paes_init(struct crypto_skcipher *tfm) |
416f79c2 | 128 | { |
d00c0639 | 129 | struct s390_paes_ctx *ctx = crypto_skcipher_ctx(tfm); |
416f79c2 HF |
130 | |
131 | ctx->kb.key = NULL; | |
132 | ||
133 | return 0; | |
134 | } | |
135 | ||
d00c0639 | 136 | static void ecb_paes_exit(struct crypto_skcipher *tfm) |
416f79c2 | 137 | { |
d00c0639 | 138 | struct s390_paes_ctx *ctx = crypto_skcipher_ctx(tfm); |
416f79c2 HF |
139 | |
140 | _free_kb_keybuf(&ctx->kb); | |
141 | } | |
142 | ||
d00c0639 | 143 | static int ecb_paes_set_key(struct crypto_skcipher *tfm, const u8 *in_key, |
27937843 MS |
144 | unsigned int key_len) |
145 | { | |
416f79c2 | 146 | int rc; |
d00c0639 | 147 | struct s390_paes_ctx *ctx = crypto_skcipher_ctx(tfm); |
27937843 | 148 | |
416f79c2 HF |
149 | _free_kb_keybuf(&ctx->kb); |
150 | rc = _copy_key_to_kb(&ctx->kb, in_key, key_len); | |
151 | if (rc) | |
152 | return rc; | |
153 | ||
674f368a | 154 | return __paes_set_key(ctx); |
27937843 MS |
155 | } |
156 | ||
d00c0639 | 157 | static int ecb_paes_crypt(struct skcipher_request *req, unsigned long modifier) |
27937843 | 158 | { |
d00c0639 EB |
159 | struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); |
160 | struct s390_paes_ctx *ctx = crypto_skcipher_ctx(tfm); | |
161 | struct skcipher_walk walk; | |
27937843 MS |
162 | unsigned int nbytes, n, k; |
163 | int ret; | |
164 | ||
d00c0639 EB |
165 | ret = skcipher_walk_virt(&walk, req, false); |
166 | while ((nbytes = walk.nbytes) != 0) { | |
27937843 MS |
167 | /* only use complete blocks */ |
168 | n = nbytes & ~(AES_BLOCK_SIZE - 1); | |
169 | k = cpacf_km(ctx->fc | modifier, ctx->pk.protkey, | |
d00c0639 | 170 | walk.dst.virt.addr, walk.src.virt.addr, n); |
27937843 | 171 | if (k) |
d00c0639 | 172 | ret = skcipher_walk_done(&walk, nbytes - k); |
27937843 MS |
173 | if (k < n) { |
174 | if (__paes_set_key(ctx) != 0) | |
d00c0639 | 175 | return skcipher_walk_done(&walk, -EIO); |
27937843 MS |
176 | } |
177 | } | |
178 | return ret; | |
179 | } | |
180 | ||
d00c0639 | 181 | static int ecb_paes_encrypt(struct skcipher_request *req) |
27937843 | 182 | { |
d00c0639 | 183 | return ecb_paes_crypt(req, 0); |
27937843 MS |
184 | } |
185 | ||
d00c0639 | 186 | static int ecb_paes_decrypt(struct skcipher_request *req) |
27937843 | 187 | { |
d00c0639 | 188 | return ecb_paes_crypt(req, CPACF_DECRYPT); |
27937843 MS |
189 | } |
190 | ||
d00c0639 EB |
191 | static struct skcipher_alg ecb_paes_alg = { |
192 | .base.cra_name = "ecb(paes)", | |
193 | .base.cra_driver_name = "ecb-paes-s390", | |
194 | .base.cra_priority = 401, /* combo: aes + ecb + 1 */ | |
195 | .base.cra_blocksize = AES_BLOCK_SIZE, | |
196 | .base.cra_ctxsize = sizeof(struct s390_paes_ctx), | |
197 | .base.cra_module = THIS_MODULE, | |
198 | .base.cra_list = LIST_HEAD_INIT(ecb_paes_alg.base.cra_list), | |
199 | .init = ecb_paes_init, | |
200 | .exit = ecb_paes_exit, | |
201 | .min_keysize = PAES_MIN_KEYSIZE, | |
202 | .max_keysize = PAES_MAX_KEYSIZE, | |
203 | .setkey = ecb_paes_set_key, | |
204 | .encrypt = ecb_paes_encrypt, | |
205 | .decrypt = ecb_paes_decrypt, | |
27937843 MS |
206 | }; |
207 | ||
d00c0639 | 208 | static int cbc_paes_init(struct crypto_skcipher *tfm) |
416f79c2 | 209 | { |
d00c0639 | 210 | struct s390_paes_ctx *ctx = crypto_skcipher_ctx(tfm); |
416f79c2 HF |
211 | |
212 | ctx->kb.key = NULL; | |
213 | ||
214 | return 0; | |
215 | } | |
216 | ||
d00c0639 | 217 | static void cbc_paes_exit(struct crypto_skcipher *tfm) |
416f79c2 | 218 | { |
d00c0639 | 219 | struct s390_paes_ctx *ctx = crypto_skcipher_ctx(tfm); |
416f79c2 HF |
220 | |
221 | _free_kb_keybuf(&ctx->kb); | |
222 | } | |
223 | ||
27937843 MS |
224 | static int __cbc_paes_set_key(struct s390_paes_ctx *ctx) |
225 | { | |
226 | unsigned long fc; | |
227 | ||
52a34b34 | 228 | if (__paes_convert_key(&ctx->kb, &ctx->pk)) |
27937843 MS |
229 | return -EINVAL; |
230 | ||
231 | /* Pick the correct function code based on the protected key type */ | |
232 | fc = (ctx->pk.type == PKEY_KEYTYPE_AES_128) ? CPACF_KMC_PAES_128 : | |
233 | (ctx->pk.type == PKEY_KEYTYPE_AES_192) ? CPACF_KMC_PAES_192 : | |
234 | (ctx->pk.type == PKEY_KEYTYPE_AES_256) ? CPACF_KMC_PAES_256 : 0; | |
235 | ||
236 | /* Check if the function code is available */ | |
237 | ctx->fc = (fc && cpacf_test_func(&kmc_functions, fc)) ? fc : 0; | |
238 | ||
239 | return ctx->fc ? 0 : -EINVAL; | |
240 | } | |
241 | ||
d00c0639 | 242 | static int cbc_paes_set_key(struct crypto_skcipher *tfm, const u8 *in_key, |
27937843 MS |
243 | unsigned int key_len) |
244 | { | |
416f79c2 | 245 | int rc; |
d00c0639 | 246 | struct s390_paes_ctx *ctx = crypto_skcipher_ctx(tfm); |
27937843 | 247 | |
416f79c2 HF |
248 | _free_kb_keybuf(&ctx->kb); |
249 | rc = _copy_key_to_kb(&ctx->kb, in_key, key_len); | |
250 | if (rc) | |
251 | return rc; | |
252 | ||
674f368a | 253 | return __cbc_paes_set_key(ctx); |
27937843 MS |
254 | } |
255 | ||
d00c0639 | 256 | static int cbc_paes_crypt(struct skcipher_request *req, unsigned long modifier) |
27937843 | 257 | { |
d00c0639 EB |
258 | struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); |
259 | struct s390_paes_ctx *ctx = crypto_skcipher_ctx(tfm); | |
260 | struct skcipher_walk walk; | |
27937843 MS |
261 | unsigned int nbytes, n, k; |
262 | int ret; | |
263 | struct { | |
264 | u8 iv[AES_BLOCK_SIZE]; | |
265 | u8 key[MAXPROTKEYSIZE]; | |
266 | } param; | |
267 | ||
d00c0639 EB |
268 | ret = skcipher_walk_virt(&walk, req, false); |
269 | if (ret) | |
270 | return ret; | |
271 | memcpy(param.iv, walk.iv, AES_BLOCK_SIZE); | |
27937843 | 272 | memcpy(param.key, ctx->pk.protkey, MAXPROTKEYSIZE); |
d00c0639 | 273 | while ((nbytes = walk.nbytes) != 0) { |
27937843 MS |
274 | /* only use complete blocks */ |
275 | n = nbytes & ~(AES_BLOCK_SIZE - 1); | |
276 | k = cpacf_kmc(ctx->fc | modifier, ¶m, | |
d00c0639 EB |
277 | walk.dst.virt.addr, walk.src.virt.addr, n); |
278 | if (k) { | |
279 | memcpy(walk.iv, param.iv, AES_BLOCK_SIZE); | |
280 | ret = skcipher_walk_done(&walk, nbytes - k); | |
281 | } | |
b81126e0 | 282 | if (k < n) { |
27937843 | 283 | if (__cbc_paes_set_key(ctx) != 0) |
d00c0639 | 284 | return skcipher_walk_done(&walk, -EIO); |
27937843 MS |
285 | memcpy(param.key, ctx->pk.protkey, MAXPROTKEYSIZE); |
286 | } | |
287 | } | |
27937843 MS |
288 | return ret; |
289 | } | |
290 | ||
d00c0639 | 291 | static int cbc_paes_encrypt(struct skcipher_request *req) |
27937843 | 292 | { |
d00c0639 | 293 | return cbc_paes_crypt(req, 0); |
27937843 MS |
294 | } |
295 | ||
d00c0639 | 296 | static int cbc_paes_decrypt(struct skcipher_request *req) |
27937843 | 297 | { |
d00c0639 | 298 | return cbc_paes_crypt(req, CPACF_DECRYPT); |
27937843 MS |
299 | } |
300 | ||
d00c0639 EB |
301 | static struct skcipher_alg cbc_paes_alg = { |
302 | .base.cra_name = "cbc(paes)", | |
303 | .base.cra_driver_name = "cbc-paes-s390", | |
304 | .base.cra_priority = 402, /* ecb-paes-s390 + 1 */ | |
305 | .base.cra_blocksize = AES_BLOCK_SIZE, | |
306 | .base.cra_ctxsize = sizeof(struct s390_paes_ctx), | |
307 | .base.cra_module = THIS_MODULE, | |
308 | .base.cra_list = LIST_HEAD_INIT(cbc_paes_alg.base.cra_list), | |
309 | .init = cbc_paes_init, | |
310 | .exit = cbc_paes_exit, | |
311 | .min_keysize = PAES_MIN_KEYSIZE, | |
312 | .max_keysize = PAES_MAX_KEYSIZE, | |
313 | .ivsize = AES_BLOCK_SIZE, | |
314 | .setkey = cbc_paes_set_key, | |
315 | .encrypt = cbc_paes_encrypt, | |
316 | .decrypt = cbc_paes_decrypt, | |
27937843 MS |
317 | }; |
318 | ||
d00c0639 | 319 | static int xts_paes_init(struct crypto_skcipher *tfm) |
416f79c2 | 320 | { |
d00c0639 | 321 | struct s390_pxts_ctx *ctx = crypto_skcipher_ctx(tfm); |
416f79c2 HF |
322 | |
323 | ctx->kb[0].key = NULL; | |
324 | ctx->kb[1].key = NULL; | |
325 | ||
326 | return 0; | |
327 | } | |
328 | ||
d00c0639 | 329 | static void xts_paes_exit(struct crypto_skcipher *tfm) |
416f79c2 | 330 | { |
d00c0639 | 331 | struct s390_pxts_ctx *ctx = crypto_skcipher_ctx(tfm); |
416f79c2 HF |
332 | |
333 | _free_kb_keybuf(&ctx->kb[0]); | |
334 | _free_kb_keybuf(&ctx->kb[1]); | |
335 | } | |
336 | ||
27937843 MS |
337 | static int __xts_paes_set_key(struct s390_pxts_ctx *ctx) |
338 | { | |
339 | unsigned long fc; | |
340 | ||
52a34b34 IF |
341 | if (__paes_convert_key(&ctx->kb[0], &ctx->pk[0]) || |
342 | __paes_convert_key(&ctx->kb[1], &ctx->pk[1])) | |
27937843 MS |
343 | return -EINVAL; |
344 | ||
345 | if (ctx->pk[0].type != ctx->pk[1].type) | |
346 | return -EINVAL; | |
347 | ||
348 | /* Pick the correct function code based on the protected key type */ | |
349 | fc = (ctx->pk[0].type == PKEY_KEYTYPE_AES_128) ? CPACF_KM_PXTS_128 : | |
350 | (ctx->pk[0].type == PKEY_KEYTYPE_AES_256) ? | |
351 | CPACF_KM_PXTS_256 : 0; | |
352 | ||
353 | /* Check if the function code is available */ | |
354 | ctx->fc = (fc && cpacf_test_func(&km_functions, fc)) ? fc : 0; | |
355 | ||
356 | return ctx->fc ? 0 : -EINVAL; | |
357 | } | |
358 | ||
d00c0639 | 359 | static int xts_paes_set_key(struct crypto_skcipher *tfm, const u8 *in_key, |
416f79c2 | 360 | unsigned int xts_key_len) |
27937843 | 361 | { |
416f79c2 | 362 | int rc; |
d00c0639 | 363 | struct s390_pxts_ctx *ctx = crypto_skcipher_ctx(tfm); |
27937843 | 364 | u8 ckey[2 * AES_MAX_KEY_SIZE]; |
416f79c2 | 365 | unsigned int ckey_len, key_len; |
52a34b34 | 366 | |
416f79c2 | 367 | if (xts_key_len % 2) |
52a34b34 | 368 | return -EINVAL; |
27937843 | 369 | |
416f79c2 HF |
370 | key_len = xts_key_len / 2; |
371 | ||
372 | _free_kb_keybuf(&ctx->kb[0]); | |
373 | _free_kb_keybuf(&ctx->kb[1]); | |
374 | rc = _copy_key_to_kb(&ctx->kb[0], in_key, key_len); | |
375 | if (rc) | |
376 | return rc; | |
377 | rc = _copy_key_to_kb(&ctx->kb[1], in_key + key_len, key_len); | |
378 | if (rc) | |
379 | return rc; | |
380 | ||
674f368a EB |
381 | rc = __xts_paes_set_key(ctx); |
382 | if (rc) | |
383 | return rc; | |
27937843 MS |
384 | |
385 | /* | |
386 | * xts_check_key verifies the key length is not odd and makes | |
387 | * sure that the two keys are not the same. This can be done | |
388 | * on the two protected keys as well | |
389 | */ | |
390 | ckey_len = (ctx->pk[0].type == PKEY_KEYTYPE_AES_128) ? | |
391 | AES_KEYSIZE_128 : AES_KEYSIZE_256; | |
392 | memcpy(ckey, ctx->pk[0].protkey, ckey_len); | |
393 | memcpy(ckey + ckey_len, ctx->pk[1].protkey, ckey_len); | |
d00c0639 | 394 | return xts_verify_key(tfm, ckey, 2*ckey_len); |
27937843 MS |
395 | } |
396 | ||
d00c0639 | 397 | static int xts_paes_crypt(struct skcipher_request *req, unsigned long modifier) |
27937843 | 398 | { |
d00c0639 EB |
399 | struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); |
400 | struct s390_pxts_ctx *ctx = crypto_skcipher_ctx(tfm); | |
401 | struct skcipher_walk walk; | |
27937843 MS |
402 | unsigned int keylen, offset, nbytes, n, k; |
403 | int ret; | |
404 | struct { | |
405 | u8 key[MAXPROTKEYSIZE]; /* key + verification pattern */ | |
406 | u8 tweak[16]; | |
407 | u8 block[16]; | |
408 | u8 bit[16]; | |
409 | u8 xts[16]; | |
410 | } pcc_param; | |
411 | struct { | |
412 | u8 key[MAXPROTKEYSIZE]; /* key + verification pattern */ | |
413 | u8 init[16]; | |
414 | } xts_param; | |
415 | ||
d00c0639 EB |
416 | ret = skcipher_walk_virt(&walk, req, false); |
417 | if (ret) | |
418 | return ret; | |
27937843 MS |
419 | keylen = (ctx->pk[0].type == PKEY_KEYTYPE_AES_128) ? 48 : 64; |
420 | offset = (ctx->pk[0].type == PKEY_KEYTYPE_AES_128) ? 16 : 0; | |
421 | retry: | |
422 | memset(&pcc_param, 0, sizeof(pcc_param)); | |
d00c0639 | 423 | memcpy(pcc_param.tweak, walk.iv, sizeof(pcc_param.tweak)); |
27937843 MS |
424 | memcpy(pcc_param.key + offset, ctx->pk[1].protkey, keylen); |
425 | cpacf_pcc(ctx->fc, pcc_param.key + offset); | |
426 | ||
427 | memcpy(xts_param.key + offset, ctx->pk[0].protkey, keylen); | |
428 | memcpy(xts_param.init, pcc_param.xts, 16); | |
429 | ||
d00c0639 | 430 | while ((nbytes = walk.nbytes) != 0) { |
27937843 MS |
431 | /* only use complete blocks */ |
432 | n = nbytes & ~(AES_BLOCK_SIZE - 1); | |
433 | k = cpacf_km(ctx->fc | modifier, xts_param.key + offset, | |
d00c0639 | 434 | walk.dst.virt.addr, walk.src.virt.addr, n); |
27937843 | 435 | if (k) |
d00c0639 | 436 | ret = skcipher_walk_done(&walk, nbytes - k); |
27937843 MS |
437 | if (k < n) { |
438 | if (__xts_paes_set_key(ctx) != 0) | |
d00c0639 | 439 | return skcipher_walk_done(&walk, -EIO); |
27937843 MS |
440 | goto retry; |
441 | } | |
442 | } | |
443 | return ret; | |
444 | } | |
445 | ||
d00c0639 | 446 | static int xts_paes_encrypt(struct skcipher_request *req) |
27937843 | 447 | { |
d00c0639 | 448 | return xts_paes_crypt(req, 0); |
27937843 MS |
449 | } |
450 | ||
d00c0639 | 451 | static int xts_paes_decrypt(struct skcipher_request *req) |
27937843 | 452 | { |
d00c0639 | 453 | return xts_paes_crypt(req, CPACF_DECRYPT); |
27937843 MS |
454 | } |
455 | ||
d00c0639 EB |
456 | static struct skcipher_alg xts_paes_alg = { |
457 | .base.cra_name = "xts(paes)", | |
458 | .base.cra_driver_name = "xts-paes-s390", | |
459 | .base.cra_priority = 402, /* ecb-paes-s390 + 1 */ | |
460 | .base.cra_blocksize = AES_BLOCK_SIZE, | |
461 | .base.cra_ctxsize = sizeof(struct s390_pxts_ctx), | |
462 | .base.cra_module = THIS_MODULE, | |
463 | .base.cra_list = LIST_HEAD_INIT(xts_paes_alg.base.cra_list), | |
464 | .init = xts_paes_init, | |
465 | .exit = xts_paes_exit, | |
466 | .min_keysize = 2 * PAES_MIN_KEYSIZE, | |
467 | .max_keysize = 2 * PAES_MAX_KEYSIZE, | |
468 | .ivsize = AES_BLOCK_SIZE, | |
469 | .setkey = xts_paes_set_key, | |
470 | .encrypt = xts_paes_encrypt, | |
471 | .decrypt = xts_paes_decrypt, | |
27937843 MS |
472 | }; |
473 | ||
d00c0639 | 474 | static int ctr_paes_init(struct crypto_skcipher *tfm) |
416f79c2 | 475 | { |
d00c0639 | 476 | struct s390_paes_ctx *ctx = crypto_skcipher_ctx(tfm); |
416f79c2 HF |
477 | |
478 | ctx->kb.key = NULL; | |
479 | ||
480 | return 0; | |
481 | } | |
482 | ||
d00c0639 | 483 | static void ctr_paes_exit(struct crypto_skcipher *tfm) |
416f79c2 | 484 | { |
d00c0639 | 485 | struct s390_paes_ctx *ctx = crypto_skcipher_ctx(tfm); |
416f79c2 HF |
486 | |
487 | _free_kb_keybuf(&ctx->kb); | |
488 | } | |
489 | ||
27937843 MS |
490 | static int __ctr_paes_set_key(struct s390_paes_ctx *ctx) |
491 | { | |
492 | unsigned long fc; | |
493 | ||
52a34b34 | 494 | if (__paes_convert_key(&ctx->kb, &ctx->pk)) |
27937843 MS |
495 | return -EINVAL; |
496 | ||
497 | /* Pick the correct function code based on the protected key type */ | |
498 | fc = (ctx->pk.type == PKEY_KEYTYPE_AES_128) ? CPACF_KMCTR_PAES_128 : | |
499 | (ctx->pk.type == PKEY_KEYTYPE_AES_192) ? CPACF_KMCTR_PAES_192 : | |
500 | (ctx->pk.type == PKEY_KEYTYPE_AES_256) ? | |
501 | CPACF_KMCTR_PAES_256 : 0; | |
502 | ||
503 | /* Check if the function code is available */ | |
504 | ctx->fc = (fc && cpacf_test_func(&kmctr_functions, fc)) ? fc : 0; | |
505 | ||
506 | return ctx->fc ? 0 : -EINVAL; | |
507 | } | |
508 | ||
d00c0639 | 509 | static int ctr_paes_set_key(struct crypto_skcipher *tfm, const u8 *in_key, |
27937843 MS |
510 | unsigned int key_len) |
511 | { | |
416f79c2 | 512 | int rc; |
d00c0639 | 513 | struct s390_paes_ctx *ctx = crypto_skcipher_ctx(tfm); |
27937843 | 514 | |
416f79c2 HF |
515 | _free_kb_keybuf(&ctx->kb); |
516 | rc = _copy_key_to_kb(&ctx->kb, in_key, key_len); | |
517 | if (rc) | |
518 | return rc; | |
519 | ||
674f368a | 520 | return __ctr_paes_set_key(ctx); |
27937843 MS |
521 | } |
522 | ||
523 | static unsigned int __ctrblk_init(u8 *ctrptr, u8 *iv, unsigned int nbytes) | |
524 | { | |
525 | unsigned int i, n; | |
526 | ||
527 | /* only use complete blocks, max. PAGE_SIZE */ | |
528 | memcpy(ctrptr, iv, AES_BLOCK_SIZE); | |
529 | n = (nbytes > PAGE_SIZE) ? PAGE_SIZE : nbytes & ~(AES_BLOCK_SIZE - 1); | |
530 | for (i = (n / AES_BLOCK_SIZE) - 1; i > 0; i--) { | |
531 | memcpy(ctrptr + AES_BLOCK_SIZE, ctrptr, AES_BLOCK_SIZE); | |
532 | crypto_inc(ctrptr + AES_BLOCK_SIZE, AES_BLOCK_SIZE); | |
533 | ctrptr += AES_BLOCK_SIZE; | |
534 | } | |
535 | return n; | |
536 | } | |
537 | ||
d00c0639 | 538 | static int ctr_paes_crypt(struct skcipher_request *req) |
27937843 | 539 | { |
d00c0639 EB |
540 | struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); |
541 | struct s390_paes_ctx *ctx = crypto_skcipher_ctx(tfm); | |
27937843 | 542 | u8 buf[AES_BLOCK_SIZE], *ctrptr; |
d00c0639 | 543 | struct skcipher_walk walk; |
27937843 MS |
544 | unsigned int nbytes, n, k; |
545 | int ret, locked; | |
546 | ||
547 | locked = spin_trylock(&ctrblk_lock); | |
548 | ||
d00c0639 EB |
549 | ret = skcipher_walk_virt(&walk, req, false); |
550 | while ((nbytes = walk.nbytes) >= AES_BLOCK_SIZE) { | |
27937843 MS |
551 | n = AES_BLOCK_SIZE; |
552 | if (nbytes >= 2*AES_BLOCK_SIZE && locked) | |
d00c0639 EB |
553 | n = __ctrblk_init(ctrblk, walk.iv, nbytes); |
554 | ctrptr = (n > AES_BLOCK_SIZE) ? ctrblk : walk.iv; | |
555 | k = cpacf_kmctr(ctx->fc, ctx->pk.protkey, walk.dst.virt.addr, | |
556 | walk.src.virt.addr, n, ctrptr); | |
27937843 MS |
557 | if (k) { |
558 | if (ctrptr == ctrblk) | |
d00c0639 | 559 | memcpy(walk.iv, ctrptr + k - AES_BLOCK_SIZE, |
27937843 | 560 | AES_BLOCK_SIZE); |
d00c0639 EB |
561 | crypto_inc(walk.iv, AES_BLOCK_SIZE); |
562 | ret = skcipher_walk_done(&walk, nbytes - n); | |
27937843 MS |
563 | } |
564 | if (k < n) { | |
e7c95eff MS |
565 | if (__ctr_paes_set_key(ctx) != 0) { |
566 | if (locked) | |
567 | spin_unlock(&ctrblk_lock); | |
d00c0639 | 568 | return skcipher_walk_done(&walk, -EIO); |
e7c95eff | 569 | } |
27937843 MS |
570 | } |
571 | } | |
572 | if (locked) | |
573 | spin_unlock(&ctrblk_lock); | |
574 | /* | |
575 | * final block may be < AES_BLOCK_SIZE, copy only nbytes | |
576 | */ | |
577 | if (nbytes) { | |
578 | while (1) { | |
d00c0639 EB |
579 | if (cpacf_kmctr(ctx->fc, ctx->pk.protkey, buf, |
580 | walk.src.virt.addr, AES_BLOCK_SIZE, | |
581 | walk.iv) == AES_BLOCK_SIZE) | |
27937843 MS |
582 | break; |
583 | if (__ctr_paes_set_key(ctx) != 0) | |
d00c0639 | 584 | return skcipher_walk_done(&walk, -EIO); |
27937843 | 585 | } |
d00c0639 EB |
586 | memcpy(walk.dst.virt.addr, buf, nbytes); |
587 | crypto_inc(walk.iv, AES_BLOCK_SIZE); | |
588 | ret = skcipher_walk_done(&walk, 0); | |
27937843 MS |
589 | } |
590 | ||
591 | return ret; | |
592 | } | |
593 | ||
d00c0639 EB |
594 | static struct skcipher_alg ctr_paes_alg = { |
595 | .base.cra_name = "ctr(paes)", | |
596 | .base.cra_driver_name = "ctr-paes-s390", | |
597 | .base.cra_priority = 402, /* ecb-paes-s390 + 1 */ | |
598 | .base.cra_blocksize = 1, | |
599 | .base.cra_ctxsize = sizeof(struct s390_paes_ctx), | |
600 | .base.cra_module = THIS_MODULE, | |
601 | .base.cra_list = LIST_HEAD_INIT(ctr_paes_alg.base.cra_list), | |
602 | .init = ctr_paes_init, | |
603 | .exit = ctr_paes_exit, | |
604 | .min_keysize = PAES_MIN_KEYSIZE, | |
605 | .max_keysize = PAES_MAX_KEYSIZE, | |
606 | .ivsize = AES_BLOCK_SIZE, | |
607 | .setkey = ctr_paes_set_key, | |
608 | .encrypt = ctr_paes_crypt, | |
609 | .decrypt = ctr_paes_crypt, | |
610 | .chunksize = AES_BLOCK_SIZE, | |
27937843 MS |
611 | }; |
612 | ||
d00c0639 | 613 | static inline void __crypto_unregister_skcipher(struct skcipher_alg *alg) |
27937843 | 614 | { |
d00c0639 EB |
615 | if (!list_empty(&alg->base.cra_list)) |
616 | crypto_unregister_skcipher(alg); | |
27937843 MS |
617 | } |
618 | ||
619 | static void paes_s390_fini(void) | |
620 | { | |
621 | if (ctrblk) | |
622 | free_page((unsigned long) ctrblk); | |
d00c0639 EB |
623 | __crypto_unregister_skcipher(&ctr_paes_alg); |
624 | __crypto_unregister_skcipher(&xts_paes_alg); | |
625 | __crypto_unregister_skcipher(&cbc_paes_alg); | |
626 | __crypto_unregister_skcipher(&ecb_paes_alg); | |
27937843 MS |
627 | } |
628 | ||
629 | static int __init paes_s390_init(void) | |
630 | { | |
631 | int ret; | |
632 | ||
633 | /* Query available functions for KM, KMC and KMCTR */ | |
634 | cpacf_query(CPACF_KM, &km_functions); | |
635 | cpacf_query(CPACF_KMC, &kmc_functions); | |
636 | cpacf_query(CPACF_KMCTR, &kmctr_functions); | |
637 | ||
638 | if (cpacf_test_func(&km_functions, CPACF_KM_PAES_128) || | |
639 | cpacf_test_func(&km_functions, CPACF_KM_PAES_192) || | |
640 | cpacf_test_func(&km_functions, CPACF_KM_PAES_256)) { | |
d00c0639 | 641 | ret = crypto_register_skcipher(&ecb_paes_alg); |
27937843 MS |
642 | if (ret) |
643 | goto out_err; | |
644 | } | |
645 | ||
646 | if (cpacf_test_func(&kmc_functions, CPACF_KMC_PAES_128) || | |
647 | cpacf_test_func(&kmc_functions, CPACF_KMC_PAES_192) || | |
648 | cpacf_test_func(&kmc_functions, CPACF_KMC_PAES_256)) { | |
d00c0639 | 649 | ret = crypto_register_skcipher(&cbc_paes_alg); |
27937843 MS |
650 | if (ret) |
651 | goto out_err; | |
652 | } | |
653 | ||
654 | if (cpacf_test_func(&km_functions, CPACF_KM_PXTS_128) || | |
655 | cpacf_test_func(&km_functions, CPACF_KM_PXTS_256)) { | |
d00c0639 | 656 | ret = crypto_register_skcipher(&xts_paes_alg); |
27937843 MS |
657 | if (ret) |
658 | goto out_err; | |
659 | } | |
660 | ||
661 | if (cpacf_test_func(&kmctr_functions, CPACF_KMCTR_PAES_128) || | |
662 | cpacf_test_func(&kmctr_functions, CPACF_KMCTR_PAES_192) || | |
663 | cpacf_test_func(&kmctr_functions, CPACF_KMCTR_PAES_256)) { | |
d00c0639 | 664 | ret = crypto_register_skcipher(&ctr_paes_alg); |
27937843 MS |
665 | if (ret) |
666 | goto out_err; | |
667 | ctrblk = (u8 *) __get_free_page(GFP_KERNEL); | |
668 | if (!ctrblk) { | |
669 | ret = -ENOMEM; | |
670 | goto out_err; | |
671 | } | |
672 | } | |
673 | ||
674 | return 0; | |
675 | out_err: | |
676 | paes_s390_fini(); | |
677 | return ret; | |
678 | } | |
679 | ||
680 | module_init(paes_s390_init); | |
681 | module_exit(paes_s390_fini); | |
682 | ||
284c43e6 | 683 | MODULE_ALIAS_CRYPTO("paes"); |
27937843 MS |
684 | |
685 | MODULE_DESCRIPTION("Rijndael (AES) Cipher Algorithm with protected keys"); | |
686 | MODULE_LICENSE("GPL"); |