1 | // SPDX-License-Identifier: GPL-2.0 |
2 | /* |
3 | * pkey device driver |
4 | * |
5 | * Copyright IBM Corp. 2017, 2023 |
6 | * |
7 | * Author(s): Harald Freudenberger |
8 | */ |
9 | |
10 | #define KMSG_COMPONENT "pkey" |
11 | #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt |
12 | |
13 | #include <linux/fs.h> |
14 | #include <linux/init.h> |
15 | #include <linux/miscdevice.h> |
16 | #include <linux/module.h> |
17 | #include <linux/slab.h> |
18 | #include <linux/kallsyms.h> |
19 | #include <linux/debugfs.h> |
20 | #include <linux/random.h> |
21 | #include <linux/cpufeature.h> |
22 | #include <asm/zcrypt.h> |
23 | #include <asm/cpacf.h> |
24 | #include <asm/pkey.h> |
25 | #include <crypto/aes.h> |
26 | |
27 | #include "zcrypt_api.h" |
28 | #include "zcrypt_ccamisc.h" |
29 | #include "zcrypt_ep11misc.h" |
30 | |
31 | MODULE_LICENSE("GPL" ); |
32 | MODULE_AUTHOR("IBM Corporation" ); |
33 | MODULE_DESCRIPTION("s390 protected key interface" ); |
34 | |
35 | #define KEYBLOBBUFSIZE 8192 /* key buffer size used for internal processing */ |
36 | #define MINKEYBLOBBUFSIZE (sizeof(struct keytoken_header)) |
37 | #define PROTKEYBLOBBUFSIZE 256 /* protected key buffer size used internal */ |
38 | #define MAXAPQNSINLIST 64 /* max 64 apqns within a apqn list */ |
39 | #define AES_WK_VP_SIZE 32 /* Size of WK VP block appended to a prot key */ |
40 | |
41 | /* |
42 | * debug feature data and functions |
43 | */ |
44 | |
45 | static debug_info_t *debug_info; |
46 | |
47 | #define DEBUG_DBG(...) debug_sprintf_event(debug_info, 6, ##__VA_ARGS__) |
48 | #define DEBUG_INFO(...) debug_sprintf_event(debug_info, 5, ##__VA_ARGS__) |
49 | #define DEBUG_WARN(...) debug_sprintf_event(debug_info, 4, ##__VA_ARGS__) |
50 | #define DEBUG_ERR(...) debug_sprintf_event(debug_info, 3, ##__VA_ARGS__) |
51 | |
52 | static void __init pkey_debug_init(void) |
53 | { |
54 | /* 5 arguments per dbf entry (including the format string ptr) */ |
55 | debug_info = debug_register("pkey" , 1, 1, 5 * sizeof(long)); |
56 | debug_register_view(debug_info, &debug_sprintf_view); |
57 | debug_set_level(debug_info, 3); |
58 | } |
59 | |
60 | static void __exit pkey_debug_exit(void) |
61 | { |
62 | debug_unregister(debug_info); |
63 | } |
64 | |
65 | /* inside view of a protected key token (only type 0x00 version 0x01) */ |
66 | struct protaeskeytoken { |
67 | u8 type; /* 0x00 for PAES specific key tokens */ |
68 | u8 res0[3]; |
69 | u8 version; /* should be 0x01 for protected AES key token */ |
70 | u8 res1[3]; |
71 | u32 keytype; /* key type, one of the PKEY_KEYTYPE values */ |
72 | u32 len; /* bytes actually stored in protkey[] */ |
73 | u8 protkey[MAXPROTKEYSIZE]; /* the protected key blob */ |
74 | } __packed; |
75 | |
76 | /* inside view of a clear key token (type 0x00 version 0x02) */ |
77 | struct clearkeytoken { |
78 | u8 type; /* 0x00 for PAES specific key tokens */ |
79 | u8 res0[3]; |
80 | u8 version; /* 0x02 for clear key token */ |
81 | u8 res1[3]; |
82 | u32 keytype; /* key type, one of the PKEY_KEYTYPE_* values */ |
83 | u32 len; /* bytes actually stored in clearkey[] */ |
84 | u8 clearkey[]; /* clear key value */ |
85 | } __packed; |
86 | |
87 | /* helper function which translates the PKEY_KEYTYPE_AES_* to their keysize */ |
88 | static inline u32 pkey_keytype_aes_to_size(u32 keytype) |
89 | { |
90 | switch (keytype) { |
91 | case PKEY_KEYTYPE_AES_128: |
92 | return 16; |
93 | case PKEY_KEYTYPE_AES_192: |
94 | return 24; |
95 | case PKEY_KEYTYPE_AES_256: |
96 | return 32; |
97 | default: |
98 | return 0; |
99 | } |
100 | } |
101 | |
102 | /* |
103 | * Create a protected key from a clear key value via PCKMO instruction. |
104 | */ |
105 | static int pkey_clr2protkey(u32 keytype, const u8 *clrkey, |
106 | u8 *protkey, u32 *protkeylen, u32 *protkeytype) |
107 | { |
108 | /* mask of available pckmo subfunctions */ |
109 | static cpacf_mask_t pckmo_functions; |
110 | |
111 | u8 paramblock[112]; |
112 | u32 pkeytype; |
113 | int keysize; |
114 | long fc; |
115 | |
116 | switch (keytype) { |
117 | case PKEY_KEYTYPE_AES_128: |
118 | /* 16 byte key, 32 byte aes wkvp, total 48 bytes */ |
119 | keysize = 16; |
120 | pkeytype = keytype; |
121 | fc = CPACF_PCKMO_ENC_AES_128_KEY; |
122 | break; |
123 | case PKEY_KEYTYPE_AES_192: |
124 | /* 24 byte key, 32 byte aes wkvp, total 56 bytes */ |
125 | keysize = 24; |
126 | pkeytype = keytype; |
127 | fc = CPACF_PCKMO_ENC_AES_192_KEY; |
128 | break; |
129 | case PKEY_KEYTYPE_AES_256: |
130 | /* 32 byte key, 32 byte aes wkvp, total 64 bytes */ |
131 | keysize = 32; |
132 | pkeytype = keytype; |
133 | fc = CPACF_PCKMO_ENC_AES_256_KEY; |
134 | break; |
135 | case PKEY_KEYTYPE_ECC_P256: |
136 | /* 32 byte key, 32 byte aes wkvp, total 64 bytes */ |
137 | keysize = 32; |
138 | pkeytype = PKEY_KEYTYPE_ECC; |
139 | fc = CPACF_PCKMO_ENC_ECC_P256_KEY; |
140 | break; |
141 | case PKEY_KEYTYPE_ECC_P384: |
142 | /* 48 byte key, 32 byte aes wkvp, total 80 bytes */ |
143 | keysize = 48; |
144 | pkeytype = PKEY_KEYTYPE_ECC; |
145 | fc = CPACF_PCKMO_ENC_ECC_P384_KEY; |
146 | break; |
147 | case PKEY_KEYTYPE_ECC_P521: |
148 | /* 80 byte key, 32 byte aes wkvp, total 112 bytes */ |
149 | keysize = 80; |
150 | pkeytype = PKEY_KEYTYPE_ECC; |
151 | fc = CPACF_PCKMO_ENC_ECC_P521_KEY; |
152 | break; |
153 | case PKEY_KEYTYPE_ECC_ED25519: |
154 | /* 32 byte key, 32 byte aes wkvp, total 64 bytes */ |
155 | keysize = 32; |
156 | pkeytype = PKEY_KEYTYPE_ECC; |
157 | fc = CPACF_PCKMO_ENC_ECC_ED25519_KEY; |
158 | break; |
159 | case PKEY_KEYTYPE_ECC_ED448: |
160 | /* 64 byte key, 32 byte aes wkvp, total 96 bytes */ |
161 | keysize = 64; |
162 | pkeytype = PKEY_KEYTYPE_ECC; |
163 | fc = CPACF_PCKMO_ENC_ECC_ED448_KEY; |
164 | break; |
165 | default: |
166 | DEBUG_ERR("%s unknown/unsupported keytype %u\n" , |
167 | __func__, keytype); |
168 | return -EINVAL; |
169 | } |
170 | |
171 | if (*protkeylen < keysize + AES_WK_VP_SIZE) { |
172 | DEBUG_ERR("%s prot key buffer size too small: %u < %d\n" , |
173 | __func__, *protkeylen, keysize + AES_WK_VP_SIZE); |
174 | return -EINVAL; |
175 | } |
176 | |
177 | /* Did we already check for PCKMO ? */ |
178 | if (!pckmo_functions.bytes[0]) { |
179 | /* no, so check now */ |
180 | if (!cpacf_query(CPACF_PCKMO, &pckmo_functions)) |
181 | return -ENODEV; |
182 | } |
183 | /* check for the pckmo subfunction we need now */ |
184 | if (!cpacf_test_func(&pckmo_functions, fc)) { |
185 | DEBUG_ERR("%s pckmo functions not available\n" , __func__); |
186 | return -ENODEV; |
187 | } |
188 | |
189 | /* prepare param block */ |
190 | memset(paramblock, 0, sizeof(paramblock)); |
191 | memcpy(paramblock, clrkey, keysize); |
192 | |
193 | /* call the pckmo instruction */ |
194 | cpacf_pckmo(fc, paramblock); |
195 | |
196 | /* copy created protected key to key buffer including the wkvp block */ |
197 | *protkeylen = keysize + AES_WK_VP_SIZE; |
198 | memcpy(protkey, paramblock, *protkeylen); |
199 | *protkeytype = pkeytype; |
200 | |
201 | return 0; |
202 | } |
203 | |
204 | /* |
205 | * Find card and transform secure key into protected key. |
206 | */ |
207 | static int pkey_skey2pkey(const u8 *key, u8 *protkey, |
208 | u32 *protkeylen, u32 *protkeytype) |
209 | { |
210 | struct keytoken_header *hdr = (struct keytoken_header *)key; |
211 | u16 cardnr, domain; |
212 | int rc, verify; |
213 | |
214 | zcrypt_wait_api_operational(); |
215 | |
216 | /* |
217 | * The cca_xxx2protkey call may fail when a card has been |
218 | * addressed where the master key was changed after last fetch |
219 | * of the mkvp into the cache. Try 3 times: First without verify |
220 | * then with verify and last round with verify and old master |
221 | * key verification pattern match not ignored. |
222 | */ |
223 | for (verify = 0; verify < 3; verify++) { |
224 | rc = cca_findcard(key, pcardnr: &cardnr, pdomain: &domain, verify); |
225 | if (rc < 0) |
226 | continue; |
227 | if (rc > 0 && verify < 2) |
228 | continue; |
229 | switch (hdr->version) { |
230 | case TOKVER_CCA_AES: |
231 | rc = cca_sec2protkey(cardnr, domain, seckey: key, |
232 | protkey, protkeylen, protkeytype); |
233 | break; |
234 | case TOKVER_CCA_VLSC: |
235 | rc = cca_cipher2protkey(cardnr, domain, ckey: key, |
236 | protkey, protkeylen, |
237 | protkeytype); |
238 | break; |
239 | default: |
240 | return -EINVAL; |
241 | } |
242 | if (rc == 0) |
243 | break; |
244 | } |
245 | |
246 | if (rc) |
247 | DEBUG_DBG("%s failed rc=%d\n" , __func__, rc); |
248 | |
249 | return rc; |
250 | } |
251 | |
252 | /* |
253 | * Construct EP11 key with given clear key value. |
254 | */ |
255 | static int pkey_clr2ep11key(const u8 *clrkey, size_t clrkeylen, |
256 | u8 *keybuf, size_t *keybuflen) |
257 | { |
258 | u32 nr_apqns, *apqns = NULL; |
259 | u16 card, dom; |
260 | int i, rc; |
261 | |
262 | zcrypt_wait_api_operational(); |
263 | |
264 | /* build a list of apqns suitable for ep11 keys with cpacf support */ |
265 | rc = ep11_findcard2(apqns: &apqns, nr_apqns: &nr_apqns, cardnr: 0xFFFF, domain: 0xFFFF, |
266 | ZCRYPT_CEX7, |
267 | minapi: ap_is_se_guest() ? EP11_API_V6 : EP11_API_V4, |
268 | NULL); |
269 | if (rc) |
270 | goto out; |
271 | |
272 | /* go through the list of apqns and try to bild an ep11 key */ |
273 | for (rc = -ENODEV, i = 0; i < nr_apqns; i++) { |
274 | card = apqns[i] >> 16; |
275 | dom = apqns[i] & 0xFFFF; |
276 | rc = ep11_clr2keyblob(card, dom, clrkeylen * 8, |
277 | 0, clrkey, keybuf, keybuflen, |
278 | PKEY_TYPE_EP11); |
279 | if (rc == 0) |
280 | break; |
281 | } |
282 | |
283 | out: |
284 | kfree(objp: apqns); |
285 | if (rc) |
286 | DEBUG_DBG("%s failed rc=%d\n" , __func__, rc); |
287 | return rc; |
288 | } |
289 | |
290 | /* |
291 | * Find card and transform EP11 secure key into protected key. |
292 | */ |
293 | static int pkey_ep11key2pkey(const u8 *key, size_t keylen, |
294 | u8 *protkey, u32 *protkeylen, u32 *protkeytype) |
295 | { |
296 | u32 nr_apqns, *apqns = NULL; |
297 | u16 card, dom; |
298 | int i, rc; |
299 | |
300 | zcrypt_wait_api_operational(); |
301 | |
302 | /* build a list of apqns suitable for this key */ |
303 | rc = ep11_findcard2(apqns: &apqns, nr_apqns: &nr_apqns, cardnr: 0xFFFF, domain: 0xFFFF, |
304 | ZCRYPT_CEX7, |
305 | minapi: ap_is_se_guest() ? EP11_API_V6 : EP11_API_V4, |
306 | wkvp: ep11_kb_wkvp(kblob: key, kbloblen: keylen)); |
307 | if (rc) |
308 | goto out; |
309 | |
310 | /* go through the list of apqns and try to derive an pkey */ |
311 | for (rc = -ENODEV, i = 0; i < nr_apqns; i++) { |
312 | card = apqns[i] >> 16; |
313 | dom = apqns[i] & 0xFFFF; |
314 | rc = ep11_kblob2protkey(card, dom, key, keylen, |
315 | protkey, protkeylen, protkeytype); |
316 | if (rc == 0) |
317 | break; |
318 | } |
319 | |
320 | out: |
321 | kfree(objp: apqns); |
322 | if (rc) |
323 | DEBUG_DBG("%s failed rc=%d\n" , __func__, rc); |
324 | return rc; |
325 | } |
326 | |
327 | /* |
328 | * Verify key and give back some info about the key. |
329 | */ |
330 | static int pkey_verifykey(const struct pkey_seckey *seckey, |
331 | u16 *pcardnr, u16 *pdomain, |
332 | u16 *pkeysize, u32 *pattributes) |
333 | { |
334 | struct secaeskeytoken *t = (struct secaeskeytoken *)seckey; |
335 | u16 cardnr, domain; |
336 | int rc; |
337 | |
338 | /* check the secure key for valid AES secure key */ |
339 | rc = cca_check_secaeskeytoken(debug_info, 3, (u8 *)seckey, 0); |
340 | if (rc) |
341 | goto out; |
342 | if (pattributes) |
343 | *pattributes = PKEY_VERIFY_ATTR_AES; |
344 | if (pkeysize) |
345 | *pkeysize = t->bitsize; |
346 | |
347 | /* try to find a card which can handle this key */ |
348 | rc = cca_findcard(key: seckey->seckey, pcardnr: &cardnr, pdomain: &domain, verify: 1); |
349 | if (rc < 0) |
350 | goto out; |
351 | |
352 | if (rc > 0) { |
353 | /* key mkvp matches to old master key mkvp */ |
354 | DEBUG_DBG("%s secure key has old mkvp\n" , __func__); |
355 | if (pattributes) |
356 | *pattributes |= PKEY_VERIFY_ATTR_OLD_MKVP; |
357 | rc = 0; |
358 | } |
359 | |
360 | if (pcardnr) |
361 | *pcardnr = cardnr; |
362 | if (pdomain) |
363 | *pdomain = domain; |
364 | |
365 | out: |
366 | DEBUG_DBG("%s rc=%d\n" , __func__, rc); |
367 | return rc; |
368 | } |
369 | |
370 | /* |
371 | * Generate a random protected key |
372 | */ |
373 | static int pkey_genprotkey(u32 keytype, u8 *protkey, |
374 | u32 *protkeylen, u32 *protkeytype) |
375 | { |
376 | u8 clrkey[32]; |
377 | int keysize; |
378 | int rc; |
379 | |
380 | keysize = pkey_keytype_aes_to_size(keytype); |
381 | if (!keysize) { |
382 | DEBUG_ERR("%s unknown/unsupported keytype %d\n" , __func__, |
383 | keytype); |
384 | return -EINVAL; |
385 | } |
386 | |
387 | /* generate a dummy random clear key */ |
388 | get_random_bytes(buf: clrkey, len: keysize); |
389 | |
390 | /* convert it to a dummy protected key */ |
391 | rc = pkey_clr2protkey(keytype, clrkey, |
392 | protkey, protkeylen, protkeytype); |
393 | if (rc) |
394 | return rc; |
395 | |
396 | /* replace the key part of the protected key with random bytes */ |
397 | get_random_bytes(buf: protkey, len: keysize); |
398 | |
399 | return 0; |
400 | } |
401 | |
402 | /* |
403 | * Verify if a protected key is still valid |
404 | */ |
405 | static int pkey_verifyprotkey(const u8 *protkey, u32 protkeylen, |
406 | u32 protkeytype) |
407 | { |
408 | struct { |
409 | u8 iv[AES_BLOCK_SIZE]; |
410 | u8 key[MAXPROTKEYSIZE]; |
411 | } param; |
412 | u8 null_msg[AES_BLOCK_SIZE]; |
413 | u8 dest_buf[AES_BLOCK_SIZE]; |
414 | unsigned int k, pkeylen; |
415 | unsigned long fc; |
416 | |
417 | switch (protkeytype) { |
418 | case PKEY_KEYTYPE_AES_128: |
419 | pkeylen = 16 + AES_WK_VP_SIZE; |
420 | fc = CPACF_KMC_PAES_128; |
421 | break; |
422 | case PKEY_KEYTYPE_AES_192: |
423 | pkeylen = 24 + AES_WK_VP_SIZE; |
424 | fc = CPACF_KMC_PAES_192; |
425 | break; |
426 | case PKEY_KEYTYPE_AES_256: |
427 | pkeylen = 32 + AES_WK_VP_SIZE; |
428 | fc = CPACF_KMC_PAES_256; |
429 | break; |
430 | default: |
431 | DEBUG_ERR("%s unknown/unsupported keytype %u\n" , __func__, |
432 | protkeytype); |
433 | return -EINVAL; |
434 | } |
435 | if (protkeylen != pkeylen) { |
436 | DEBUG_ERR("%s invalid protected key size %u for keytype %u\n" , |
437 | __func__, protkeylen, protkeytype); |
438 | return -EINVAL; |
439 | } |
440 | |
441 | memset(null_msg, 0, sizeof(null_msg)); |
442 | |
443 | memset(param.iv, 0, sizeof(param.iv)); |
444 | memcpy(param.key, protkey, protkeylen); |
445 | |
446 | k = cpacf_kmc(fc | CPACF_ENCRYPT, ¶m, null_msg, dest_buf, |
447 | sizeof(null_msg)); |
448 | if (k != sizeof(null_msg)) { |
449 | DEBUG_ERR("%s protected key is not valid\n" , __func__); |
450 | return -EKEYREJECTED; |
451 | } |
452 | |
453 | return 0; |
454 | } |
455 | |
456 | /* Helper for pkey_nonccatok2pkey, handles aes clear key token */ |
457 | static int nonccatokaes2pkey(const struct clearkeytoken *t, |
458 | u8 *protkey, u32 *protkeylen, u32 *protkeytype) |
459 | { |
460 | size_t tmpbuflen = max_t(size_t, SECKEYBLOBSIZE, MAXEP11AESKEYBLOBSIZE); |
461 | u8 *tmpbuf = NULL; |
462 | u32 keysize; |
463 | int rc; |
464 | |
465 | keysize = pkey_keytype_aes_to_size(keytype: t->keytype); |
466 | if (!keysize) { |
467 | DEBUG_ERR("%s unknown/unsupported keytype %u\n" , |
468 | __func__, t->keytype); |
469 | return -EINVAL; |
470 | } |
471 | if (t->len != keysize) { |
472 | DEBUG_ERR("%s non clear key aes token: invalid key len %u\n" , |
473 | __func__, t->len); |
474 | return -EINVAL; |
475 | } |
476 | |
477 | /* try direct way with the PCKMO instruction */ |
478 | rc = pkey_clr2protkey(keytype: t->keytype, clrkey: t->clearkey, |
479 | protkey, protkeylen, protkeytype); |
480 | if (!rc) |
481 | goto out; |
482 | |
483 | /* PCKMO failed, so try the CCA secure key way */ |
484 | tmpbuf = kmalloc(size: tmpbuflen, GFP_ATOMIC); |
485 | if (!tmpbuf) |
486 | return -ENOMEM; |
487 | zcrypt_wait_api_operational(); |
488 | rc = cca_clr2seckey(cardnr: 0xFFFF, domain: 0xFFFF, keybitsize: t->keytype, clrkey: t->clearkey, seckey: tmpbuf); |
489 | if (rc) |
490 | goto try_via_ep11; |
491 | rc = pkey_skey2pkey(key: tmpbuf, |
492 | protkey, protkeylen, protkeytype); |
493 | if (!rc) |
494 | goto out; |
495 | |
496 | try_via_ep11: |
497 | /* if the CCA way also failed, let's try via EP11 */ |
498 | rc = pkey_clr2ep11key(clrkey: t->clearkey, clrkeylen: t->len, |
499 | keybuf: tmpbuf, keybuflen: &tmpbuflen); |
500 | if (rc) |
501 | goto failure; |
502 | rc = pkey_ep11key2pkey(key: tmpbuf, keylen: tmpbuflen, |
503 | protkey, protkeylen, protkeytype); |
504 | if (!rc) |
505 | goto out; |
506 | |
507 | failure: |
508 | DEBUG_ERR("%s unable to build protected key from clear" , __func__); |
509 | |
510 | out: |
511 | kfree(objp: tmpbuf); |
512 | return rc; |
513 | } |
514 | |
515 | /* Helper for pkey_nonccatok2pkey, handles ecc clear key token */ |
516 | static int nonccatokecc2pkey(const struct clearkeytoken *t, |
517 | u8 *protkey, u32 *protkeylen, u32 *protkeytype) |
518 | { |
519 | u32 keylen; |
520 | int rc; |
521 | |
522 | switch (t->keytype) { |
523 | case PKEY_KEYTYPE_ECC_P256: |
524 | keylen = 32; |
525 | break; |
526 | case PKEY_KEYTYPE_ECC_P384: |
527 | keylen = 48; |
528 | break; |
529 | case PKEY_KEYTYPE_ECC_P521: |
530 | keylen = 80; |
531 | break; |
532 | case PKEY_KEYTYPE_ECC_ED25519: |
533 | keylen = 32; |
534 | break; |
535 | case PKEY_KEYTYPE_ECC_ED448: |
536 | keylen = 64; |
537 | break; |
538 | default: |
539 | DEBUG_ERR("%s unknown/unsupported keytype %u\n" , |
540 | __func__, t->keytype); |
541 | return -EINVAL; |
542 | } |
543 | |
544 | if (t->len != keylen) { |
545 | DEBUG_ERR("%s non clear key ecc token: invalid key len %u\n" , |
546 | __func__, t->len); |
547 | return -EINVAL; |
548 | } |
549 | |
550 | /* only one path possible: via PCKMO instruction */ |
551 | rc = pkey_clr2protkey(keytype: t->keytype, clrkey: t->clearkey, |
552 | protkey, protkeylen, protkeytype); |
553 | if (rc) { |
554 | DEBUG_ERR("%s unable to build protected key from clear" , |
555 | __func__); |
556 | } |
557 | |
558 | return rc; |
559 | } |
560 | |
561 | /* |
562 | * Transform a non-CCA key token into a protected key |
563 | */ |
564 | static int pkey_nonccatok2pkey(const u8 *key, u32 keylen, |
565 | u8 *protkey, u32 *protkeylen, u32 *protkeytype) |
566 | { |
567 | struct keytoken_header *hdr = (struct keytoken_header *)key; |
568 | int rc = -EINVAL; |
569 | |
570 | switch (hdr->version) { |
571 | case TOKVER_PROTECTED_KEY: { |
572 | struct protaeskeytoken *t; |
573 | |
574 | if (keylen != sizeof(struct protaeskeytoken)) |
575 | goto out; |
576 | t = (struct protaeskeytoken *)key; |
577 | rc = pkey_verifyprotkey(protkey: t->protkey, protkeylen: t->len, protkeytype: t->keytype); |
578 | if (rc) |
579 | goto out; |
580 | memcpy(protkey, t->protkey, t->len); |
581 | *protkeylen = t->len; |
582 | *protkeytype = t->keytype; |
583 | break; |
584 | } |
585 | case TOKVER_CLEAR_KEY: { |
586 | struct clearkeytoken *t = (struct clearkeytoken *)key; |
587 | |
588 | if (keylen < sizeof(struct clearkeytoken) || |
589 | keylen != sizeof(*t) + t->len) |
590 | goto out; |
591 | switch (t->keytype) { |
592 | case PKEY_KEYTYPE_AES_128: |
593 | case PKEY_KEYTYPE_AES_192: |
594 | case PKEY_KEYTYPE_AES_256: |
595 | rc = nonccatokaes2pkey(t, protkey, |
596 | protkeylen, protkeytype); |
597 | break; |
598 | case PKEY_KEYTYPE_ECC_P256: |
599 | case PKEY_KEYTYPE_ECC_P384: |
600 | case PKEY_KEYTYPE_ECC_P521: |
601 | case PKEY_KEYTYPE_ECC_ED25519: |
602 | case PKEY_KEYTYPE_ECC_ED448: |
603 | rc = nonccatokecc2pkey(t, protkey, |
604 | protkeylen, protkeytype); |
605 | break; |
606 | default: |
607 | DEBUG_ERR("%s unknown/unsupported non cca clear key type %u\n" , |
608 | __func__, t->keytype); |
609 | return -EINVAL; |
610 | } |
611 | break; |
612 | } |
613 | case TOKVER_EP11_AES: { |
614 | /* check ep11 key for exportable as protected key */ |
615 | rc = ep11_check_aes_key(debug_info, 3, key, keylen, 1); |
616 | if (rc) |
617 | goto out; |
618 | rc = pkey_ep11key2pkey(key, keylen, |
619 | protkey, protkeylen, protkeytype); |
620 | break; |
621 | } |
622 | case TOKVER_EP11_AES_WITH_HEADER: |
623 | /* check ep11 key with header for exportable as protected key */ |
624 | rc = ep11_check_aes_key_with_hdr(debug_info, 3, key, keylen, 1); |
625 | if (rc) |
626 | goto out; |
627 | rc = pkey_ep11key2pkey(key, keylen, |
628 | protkey, protkeylen, protkeytype); |
629 | break; |
630 | default: |
631 | DEBUG_ERR("%s unknown/unsupported non-CCA token version %d\n" , |
632 | __func__, hdr->version); |
633 | } |
634 | |
635 | out: |
636 | return rc; |
637 | } |
638 | |
639 | /* |
640 | * Transform a CCA internal key token into a protected key |
641 | */ |
642 | static int pkey_ccainttok2pkey(const u8 *key, u32 keylen, |
643 | u8 *protkey, u32 *protkeylen, u32 *protkeytype) |
644 | { |
645 | struct keytoken_header *hdr = (struct keytoken_header *)key; |
646 | |
647 | switch (hdr->version) { |
648 | case TOKVER_CCA_AES: |
649 | if (keylen != sizeof(struct secaeskeytoken)) |
650 | return -EINVAL; |
651 | break; |
652 | case TOKVER_CCA_VLSC: |
653 | if (keylen < hdr->len || keylen > MAXCCAVLSCTOKENSIZE) |
654 | return -EINVAL; |
655 | break; |
656 | default: |
657 | DEBUG_ERR("%s unknown/unsupported CCA internal token version %d\n" , |
658 | __func__, hdr->version); |
659 | return -EINVAL; |
660 | } |
661 | |
662 | return pkey_skey2pkey(key, protkey, protkeylen, protkeytype); |
663 | } |
664 | |
665 | /* |
666 | * Transform a key blob (of any type) into a protected key |
667 | */ |
668 | int pkey_keyblob2pkey(const u8 *key, u32 keylen, |
669 | u8 *protkey, u32 *protkeylen, u32 *protkeytype) |
670 | { |
671 | struct keytoken_header *hdr = (struct keytoken_header *)key; |
672 | int rc; |
673 | |
674 | if (keylen < sizeof(struct keytoken_header)) { |
675 | DEBUG_ERR("%s invalid keylen %d\n" , __func__, keylen); |
676 | return -EINVAL; |
677 | } |
678 | |
679 | switch (hdr->type) { |
680 | case TOKTYPE_NON_CCA: |
681 | rc = pkey_nonccatok2pkey(key, keylen, |
682 | protkey, protkeylen, protkeytype); |
683 | break; |
684 | case TOKTYPE_CCA_INTERNAL: |
685 | rc = pkey_ccainttok2pkey(key, keylen, |
686 | protkey, protkeylen, protkeytype); |
687 | break; |
688 | default: |
689 | DEBUG_ERR("%s unknown/unsupported blob type %d\n" , |
690 | __func__, hdr->type); |
691 | return -EINVAL; |
692 | } |
693 | |
694 | DEBUG_DBG("%s rc=%d\n" , __func__, rc); |
695 | return rc; |
696 | } |
697 | EXPORT_SYMBOL(pkey_keyblob2pkey); |
698 | |
699 | static int pkey_genseckey2(const struct pkey_apqn *apqns, size_t nr_apqns, |
700 | enum pkey_key_type ktype, enum pkey_key_size ksize, |
701 | u32 kflags, u8 *keybuf, size_t *keybufsize) |
702 | { |
703 | int i, card, dom, rc; |
704 | |
705 | /* check for at least one apqn given */ |
706 | if (!apqns || !nr_apqns) |
707 | return -EINVAL; |
708 | |
709 | /* check key type and size */ |
710 | switch (ktype) { |
711 | case PKEY_TYPE_CCA_DATA: |
712 | case PKEY_TYPE_CCA_CIPHER: |
713 | if (*keybufsize < SECKEYBLOBSIZE) |
714 | return -EINVAL; |
715 | break; |
716 | case PKEY_TYPE_EP11: |
717 | if (*keybufsize < MINEP11AESKEYBLOBSIZE) |
718 | return -EINVAL; |
719 | break; |
720 | case PKEY_TYPE_EP11_AES: |
721 | if (*keybufsize < (sizeof(struct ep11kblob_header) + |
722 | MINEP11AESKEYBLOBSIZE)) |
723 | return -EINVAL; |
724 | break; |
725 | default: |
726 | return -EINVAL; |
727 | } |
728 | switch (ksize) { |
729 | case PKEY_SIZE_AES_128: |
730 | case PKEY_SIZE_AES_192: |
731 | case PKEY_SIZE_AES_256: |
732 | break; |
733 | default: |
734 | return -EINVAL; |
735 | } |
736 | |
737 | /* simple try all apqns from the list */ |
738 | for (i = 0, rc = -ENODEV; i < nr_apqns; i++) { |
739 | card = apqns[i].card; |
740 | dom = apqns[i].domain; |
741 | if (ktype == PKEY_TYPE_EP11 || |
742 | ktype == PKEY_TYPE_EP11_AES) { |
743 | rc = ep11_genaeskey(card, domain: dom, keybitsize: ksize, keygenflags: kflags, |
744 | keybuf, keybufsize, keybufver: ktype); |
745 | } else if (ktype == PKEY_TYPE_CCA_DATA) { |
746 | rc = cca_genseckey(cardnr: card, domain: dom, keybitsize: ksize, seckey: keybuf); |
747 | *keybufsize = (rc ? 0 : SECKEYBLOBSIZE); |
748 | } else { |
749 | /* TOKVER_CCA_VLSC */ |
750 | rc = cca_gencipherkey(cardnr: card, domain: dom, keybitsize: ksize, keygenflags: kflags, |
751 | keybuf, keybufsize); |
752 | } |
753 | if (rc == 0) |
754 | break; |
755 | } |
756 | |
757 | return rc; |
758 | } |
759 | |
760 | static int pkey_clr2seckey2(const struct pkey_apqn *apqns, size_t nr_apqns, |
761 | enum pkey_key_type ktype, enum pkey_key_size ksize, |
762 | u32 kflags, const u8 *clrkey, |
763 | u8 *keybuf, size_t *keybufsize) |
764 | { |
765 | int i, card, dom, rc; |
766 | |
767 | /* check for at least one apqn given */ |
768 | if (!apqns || !nr_apqns) |
769 | return -EINVAL; |
770 | |
771 | /* check key type and size */ |
772 | switch (ktype) { |
773 | case PKEY_TYPE_CCA_DATA: |
774 | case PKEY_TYPE_CCA_CIPHER: |
775 | if (*keybufsize < SECKEYBLOBSIZE) |
776 | return -EINVAL; |
777 | break; |
778 | case PKEY_TYPE_EP11: |
779 | if (*keybufsize < MINEP11AESKEYBLOBSIZE) |
780 | return -EINVAL; |
781 | break; |
782 | case PKEY_TYPE_EP11_AES: |
783 | if (*keybufsize < (sizeof(struct ep11kblob_header) + |
784 | MINEP11AESKEYBLOBSIZE)) |
785 | return -EINVAL; |
786 | break; |
787 | default: |
788 | return -EINVAL; |
789 | } |
790 | switch (ksize) { |
791 | case PKEY_SIZE_AES_128: |
792 | case PKEY_SIZE_AES_192: |
793 | case PKEY_SIZE_AES_256: |
794 | break; |
795 | default: |
796 | return -EINVAL; |
797 | } |
798 | |
799 | zcrypt_wait_api_operational(); |
800 | |
801 | /* simple try all apqns from the list */ |
802 | for (i = 0, rc = -ENODEV; i < nr_apqns; i++) { |
803 | card = apqns[i].card; |
804 | dom = apqns[i].domain; |
805 | if (ktype == PKEY_TYPE_EP11 || |
806 | ktype == PKEY_TYPE_EP11_AES) { |
807 | rc = ep11_clr2keyblob(cardnr: card, domain: dom, keybitsize: ksize, keygenflags: kflags, |
808 | clrkey, keybuf, keybufsize, |
809 | keytype: ktype); |
810 | } else if (ktype == PKEY_TYPE_CCA_DATA) { |
811 | rc = cca_clr2seckey(cardnr: card, domain: dom, keybitsize: ksize, |
812 | clrkey, seckey: keybuf); |
813 | *keybufsize = (rc ? 0 : SECKEYBLOBSIZE); |
814 | } else { |
815 | /* TOKVER_CCA_VLSC */ |
816 | rc = cca_clr2cipherkey(cardnr: card, domain: dom, keybitsize: ksize, keygenflags: kflags, |
817 | clrkey, keybuf, keybufsize); |
818 | } |
819 | if (rc == 0) |
820 | break; |
821 | } |
822 | |
823 | return rc; |
824 | } |
825 | |
826 | static int pkey_verifykey2(const u8 *key, size_t keylen, |
827 | u16 *cardnr, u16 *domain, |
828 | enum pkey_key_type *ktype, |
829 | enum pkey_key_size *ksize, u32 *flags) |
830 | { |
831 | struct keytoken_header *hdr = (struct keytoken_header *)key; |
832 | u32 _nr_apqns, *_apqns = NULL; |
833 | int rc; |
834 | |
835 | if (keylen < sizeof(struct keytoken_header)) |
836 | return -EINVAL; |
837 | |
838 | if (hdr->type == TOKTYPE_CCA_INTERNAL && |
839 | hdr->version == TOKVER_CCA_AES) { |
840 | struct secaeskeytoken *t = (struct secaeskeytoken *)key; |
841 | |
842 | rc = cca_check_secaeskeytoken(debug_info, 3, key, 0); |
843 | if (rc) |
844 | goto out; |
845 | if (ktype) |
846 | *ktype = PKEY_TYPE_CCA_DATA; |
847 | if (ksize) |
848 | *ksize = (enum pkey_key_size)t->bitsize; |
849 | |
850 | rc = cca_findcard2(apqns: &_apqns, nr_apqns: &_nr_apqns, cardnr: *cardnr, domain: *domain, |
851 | ZCRYPT_CEX3C, AES_MK_SET, cur_mkvp: t->mkvp, old_mkvp: 0, verify: 1); |
852 | if (rc == 0 && flags) |
853 | *flags = PKEY_FLAGS_MATCH_CUR_MKVP; |
854 | if (rc == -ENODEV) { |
855 | rc = cca_findcard2(apqns: &_apqns, nr_apqns: &_nr_apqns, |
856 | cardnr: *cardnr, domain: *domain, |
857 | ZCRYPT_CEX3C, AES_MK_SET, |
858 | cur_mkvp: 0, old_mkvp: t->mkvp, verify: 1); |
859 | if (rc == 0 && flags) |
860 | *flags = PKEY_FLAGS_MATCH_ALT_MKVP; |
861 | } |
862 | if (rc) |
863 | goto out; |
864 | |
865 | *cardnr = ((struct pkey_apqn *)_apqns)->card; |
866 | *domain = ((struct pkey_apqn *)_apqns)->domain; |
867 | |
868 | } else if (hdr->type == TOKTYPE_CCA_INTERNAL && |
869 | hdr->version == TOKVER_CCA_VLSC) { |
870 | struct cipherkeytoken *t = (struct cipherkeytoken *)key; |
871 | |
872 | rc = cca_check_secaescipherkey(debug_info, 3, key, 0, 1); |
873 | if (rc) |
874 | goto out; |
875 | if (ktype) |
876 | *ktype = PKEY_TYPE_CCA_CIPHER; |
877 | if (ksize) { |
878 | *ksize = PKEY_SIZE_UNKNOWN; |
879 | if (!t->plfver && t->wpllen == 512) |
880 | *ksize = PKEY_SIZE_AES_128; |
881 | else if (!t->plfver && t->wpllen == 576) |
882 | *ksize = PKEY_SIZE_AES_192; |
883 | else if (!t->plfver && t->wpllen == 640) |
884 | *ksize = PKEY_SIZE_AES_256; |
885 | } |
886 | |
887 | rc = cca_findcard2(apqns: &_apqns, nr_apqns: &_nr_apqns, cardnr: *cardnr, domain: *domain, |
888 | ZCRYPT_CEX6, AES_MK_SET, cur_mkvp: t->mkvp0, old_mkvp: 0, verify: 1); |
889 | if (rc == 0 && flags) |
890 | *flags = PKEY_FLAGS_MATCH_CUR_MKVP; |
891 | if (rc == -ENODEV) { |
892 | rc = cca_findcard2(apqns: &_apqns, nr_apqns: &_nr_apqns, |
893 | cardnr: *cardnr, domain: *domain, |
894 | ZCRYPT_CEX6, AES_MK_SET, |
895 | cur_mkvp: 0, old_mkvp: t->mkvp0, verify: 1); |
896 | if (rc == 0 && flags) |
897 | *flags = PKEY_FLAGS_MATCH_ALT_MKVP; |
898 | } |
899 | if (rc) |
900 | goto out; |
901 | |
902 | *cardnr = ((struct pkey_apqn *)_apqns)->card; |
903 | *domain = ((struct pkey_apqn *)_apqns)->domain; |
904 | |
905 | } else if (hdr->type == TOKTYPE_NON_CCA && |
906 | hdr->version == TOKVER_EP11_AES) { |
907 | struct ep11keyblob *kb = (struct ep11keyblob *)key; |
908 | int api; |
909 | |
910 | rc = ep11_check_aes_key(debug_info, 3, key, keylen, 1); |
911 | if (rc) |
912 | goto out; |
913 | if (ktype) |
914 | *ktype = PKEY_TYPE_EP11; |
915 | if (ksize) |
916 | *ksize = kb->head.bitlen; |
917 | |
918 | api = ap_is_se_guest() ? EP11_API_V6 : EP11_API_V4; |
919 | rc = ep11_findcard2(apqns: &_apqns, nr_apqns: &_nr_apqns, cardnr: *cardnr, domain: *domain, |
920 | ZCRYPT_CEX7, minapi: api, |
921 | wkvp: ep11_kb_wkvp(kblob: key, kbloblen: keylen)); |
922 | if (rc) |
923 | goto out; |
924 | |
925 | if (flags) |
926 | *flags = PKEY_FLAGS_MATCH_CUR_MKVP; |
927 | |
928 | *cardnr = ((struct pkey_apqn *)_apqns)->card; |
929 | *domain = ((struct pkey_apqn *)_apqns)->domain; |
930 | |
931 | } else if (hdr->type == TOKTYPE_NON_CCA && |
932 | hdr->version == TOKVER_EP11_AES_WITH_HEADER) { |
933 | struct ep11kblob_header *kh = (struct ep11kblob_header *)key; |
934 | int api; |
935 | |
936 | rc = ep11_check_aes_key_with_hdr(debug_info, 3, |
937 | key, keylen, 1); |
938 | if (rc) |
939 | goto out; |
940 | if (ktype) |
941 | *ktype = PKEY_TYPE_EP11_AES; |
942 | if (ksize) |
943 | *ksize = kh->bitlen; |
944 | |
945 | api = ap_is_se_guest() ? EP11_API_V6 : EP11_API_V4; |
946 | rc = ep11_findcard2(apqns: &_apqns, nr_apqns: &_nr_apqns, cardnr: *cardnr, domain: *domain, |
947 | ZCRYPT_CEX7, minapi: api, |
948 | wkvp: ep11_kb_wkvp(kblob: key, kbloblen: keylen)); |
949 | if (rc) |
950 | goto out; |
951 | |
952 | if (flags) |
953 | *flags = PKEY_FLAGS_MATCH_CUR_MKVP; |
954 | |
955 | *cardnr = ((struct pkey_apqn *)_apqns)->card; |
956 | *domain = ((struct pkey_apqn *)_apqns)->domain; |
957 | } else { |
958 | rc = -EINVAL; |
959 | } |
960 | |
961 | out: |
962 | kfree(objp: _apqns); |
963 | return rc; |
964 | } |
965 | |
966 | static int pkey_keyblob2pkey2(const struct pkey_apqn *apqns, size_t nr_apqns, |
967 | const u8 *key, size_t keylen, |
968 | u8 *protkey, u32 *protkeylen, u32 *protkeytype) |
969 | { |
970 | struct keytoken_header *hdr = (struct keytoken_header *)key; |
971 | int i, card, dom, rc; |
972 | |
973 | /* check for at least one apqn given */ |
974 | if (!apqns || !nr_apqns) |
975 | return -EINVAL; |
976 | |
977 | if (keylen < sizeof(struct keytoken_header)) |
978 | return -EINVAL; |
979 | |
980 | if (hdr->type == TOKTYPE_CCA_INTERNAL) { |
981 | if (hdr->version == TOKVER_CCA_AES) { |
982 | if (keylen != sizeof(struct secaeskeytoken)) |
983 | return -EINVAL; |
984 | if (cca_check_secaeskeytoken(debug_info, 3, key, 0)) |
985 | return -EINVAL; |
986 | } else if (hdr->version == TOKVER_CCA_VLSC) { |
987 | if (keylen < hdr->len || keylen > MAXCCAVLSCTOKENSIZE) |
988 | return -EINVAL; |
989 | if (cca_check_secaescipherkey(debug_info, 3, key, 0, 1)) |
990 | return -EINVAL; |
991 | } else { |
992 | DEBUG_ERR("%s unknown CCA internal token version %d\n" , |
993 | __func__, hdr->version); |
994 | return -EINVAL; |
995 | } |
996 | } else if (hdr->type == TOKTYPE_NON_CCA) { |
997 | if (hdr->version == TOKVER_EP11_AES) { |
998 | if (ep11_check_aes_key(debug_info, 3, key, keylen, 1)) |
999 | return -EINVAL; |
1000 | } else if (hdr->version == TOKVER_EP11_AES_WITH_HEADER) { |
1001 | if (ep11_check_aes_key_with_hdr(debug_info, 3, |
1002 | key, keylen, 1)) |
1003 | return -EINVAL; |
1004 | } else { |
1005 | return pkey_nonccatok2pkey(key, keylen, |
1006 | protkey, protkeylen, |
1007 | protkeytype); |
1008 | } |
1009 | } else { |
1010 | DEBUG_ERR("%s unknown/unsupported blob type %d\n" , |
1011 | __func__, hdr->type); |
1012 | return -EINVAL; |
1013 | } |
1014 | |
1015 | zcrypt_wait_api_operational(); |
1016 | |
1017 | /* simple try all apqns from the list */ |
1018 | for (i = 0, rc = -ENODEV; i < nr_apqns; i++) { |
1019 | card = apqns[i].card; |
1020 | dom = apqns[i].domain; |
1021 | if (hdr->type == TOKTYPE_CCA_INTERNAL && |
1022 | hdr->version == TOKVER_CCA_AES) { |
1023 | rc = cca_sec2protkey(cardnr: card, domain: dom, seckey: key, |
1024 | protkey, protkeylen, protkeytype); |
1025 | } else if (hdr->type == TOKTYPE_CCA_INTERNAL && |
1026 | hdr->version == TOKVER_CCA_VLSC) { |
1027 | rc = cca_cipher2protkey(cardnr: card, domain: dom, ckey: key, |
1028 | protkey, protkeylen, |
1029 | protkeytype); |
1030 | } else { |
1031 | rc = ep11_kblob2protkey(card, dom, key, keylen, |
1032 | protkey, protkeylen, |
1033 | protkeytype); |
1034 | } |
1035 | if (rc == 0) |
1036 | break; |
1037 | } |
1038 | |
1039 | return rc; |
1040 | } |
1041 | |
1042 | static int pkey_apqns4key(const u8 *key, size_t keylen, u32 flags, |
1043 | struct pkey_apqn *apqns, size_t *nr_apqns) |
1044 | { |
1045 | struct keytoken_header *hdr = (struct keytoken_header *)key; |
1046 | u32 _nr_apqns, *_apqns = NULL; |
1047 | int rc; |
1048 | |
1049 | if (keylen < sizeof(struct keytoken_header) || flags == 0) |
1050 | return -EINVAL; |
1051 | |
1052 | zcrypt_wait_api_operational(); |
1053 | |
1054 | if (hdr->type == TOKTYPE_NON_CCA && |
1055 | (hdr->version == TOKVER_EP11_AES_WITH_HEADER || |
1056 | hdr->version == TOKVER_EP11_ECC_WITH_HEADER) && |
1057 | is_ep11_keyblob(key + sizeof(struct ep11kblob_header))) { |
1058 | struct ep11keyblob *kb = (struct ep11keyblob *) |
1059 | (key + sizeof(struct ep11kblob_header)); |
1060 | int minhwtype = 0, api = 0; |
1061 | |
1062 | if (flags != PKEY_FLAGS_MATCH_CUR_MKVP) |
1063 | return -EINVAL; |
1064 | if (kb->attr & EP11_BLOB_PKEY_EXTRACTABLE) { |
1065 | minhwtype = ZCRYPT_CEX7; |
1066 | api = ap_is_se_guest() ? EP11_API_V6 : EP11_API_V4; |
1067 | } |
1068 | rc = ep11_findcard2(apqns: &_apqns, nr_apqns: &_nr_apqns, cardnr: 0xFFFF, domain: 0xFFFF, |
1069 | minhwtype, minapi: api, wkvp: kb->wkvp); |
1070 | if (rc) |
1071 | goto out; |
1072 | } else if (hdr->type == TOKTYPE_NON_CCA && |
1073 | hdr->version == TOKVER_EP11_AES && |
1074 | is_ep11_keyblob(key)) { |
1075 | struct ep11keyblob *kb = (struct ep11keyblob *)key; |
1076 | int minhwtype = 0, api = 0; |
1077 | |
1078 | if (flags != PKEY_FLAGS_MATCH_CUR_MKVP) |
1079 | return -EINVAL; |
1080 | if (kb->attr & EP11_BLOB_PKEY_EXTRACTABLE) { |
1081 | minhwtype = ZCRYPT_CEX7; |
1082 | api = ap_is_se_guest() ? EP11_API_V6 : EP11_API_V4; |
1083 | } |
1084 | rc = ep11_findcard2(apqns: &_apqns, nr_apqns: &_nr_apqns, cardnr: 0xFFFF, domain: 0xFFFF, |
1085 | minhwtype, minapi: api, wkvp: kb->wkvp); |
1086 | if (rc) |
1087 | goto out; |
1088 | } else if (hdr->type == TOKTYPE_CCA_INTERNAL) { |
1089 | u64 cur_mkvp = 0, old_mkvp = 0; |
1090 | int minhwtype = ZCRYPT_CEX3C; |
1091 | |
1092 | if (hdr->version == TOKVER_CCA_AES) { |
1093 | struct secaeskeytoken *t = (struct secaeskeytoken *)key; |
1094 | |
1095 | if (flags & PKEY_FLAGS_MATCH_CUR_MKVP) |
1096 | cur_mkvp = t->mkvp; |
1097 | if (flags & PKEY_FLAGS_MATCH_ALT_MKVP) |
1098 | old_mkvp = t->mkvp; |
1099 | } else if (hdr->version == TOKVER_CCA_VLSC) { |
1100 | struct cipherkeytoken *t = (struct cipherkeytoken *)key; |
1101 | |
1102 | minhwtype = ZCRYPT_CEX6; |
1103 | if (flags & PKEY_FLAGS_MATCH_CUR_MKVP) |
1104 | cur_mkvp = t->mkvp0; |
1105 | if (flags & PKEY_FLAGS_MATCH_ALT_MKVP) |
1106 | old_mkvp = t->mkvp0; |
1107 | } else { |
1108 | /* unknown cca internal token type */ |
1109 | return -EINVAL; |
1110 | } |
1111 | rc = cca_findcard2(apqns: &_apqns, nr_apqns: &_nr_apqns, cardnr: 0xFFFF, domain: 0xFFFF, |
1112 | minhwtype, AES_MK_SET, |
1113 | cur_mkvp, old_mkvp, verify: 1); |
1114 | if (rc) |
1115 | goto out; |
1116 | } else if (hdr->type == TOKTYPE_CCA_INTERNAL_PKA) { |
1117 | struct eccprivkeytoken *t = (struct eccprivkeytoken *)key; |
1118 | u64 cur_mkvp = 0, old_mkvp = 0; |
1119 | |
1120 | if (t->secid == 0x20) { |
1121 | if (flags & PKEY_FLAGS_MATCH_CUR_MKVP) |
1122 | cur_mkvp = t->mkvp; |
1123 | if (flags & PKEY_FLAGS_MATCH_ALT_MKVP) |
1124 | old_mkvp = t->mkvp; |
1125 | } else { |
1126 | /* unknown cca internal 2 token type */ |
1127 | return -EINVAL; |
1128 | } |
1129 | rc = cca_findcard2(apqns: &_apqns, nr_apqns: &_nr_apqns, cardnr: 0xFFFF, domain: 0xFFFF, |
1130 | ZCRYPT_CEX7, APKA_MK_SET, |
1131 | cur_mkvp, old_mkvp, verify: 1); |
1132 | if (rc) |
1133 | goto out; |
1134 | } else { |
1135 | return -EINVAL; |
1136 | } |
1137 | |
1138 | if (apqns) { |
1139 | if (*nr_apqns < _nr_apqns) |
1140 | rc = -ENOSPC; |
1141 | else |
1142 | memcpy(apqns, _apqns, _nr_apqns * sizeof(u32)); |
1143 | } |
1144 | *nr_apqns = _nr_apqns; |
1145 | |
1146 | out: |
1147 | kfree(objp: _apqns); |
1148 | return rc; |
1149 | } |
1150 | |
1151 | static int pkey_apqns4keytype(enum pkey_key_type ktype, |
1152 | u8 cur_mkvp[32], u8 alt_mkvp[32], u32 flags, |
1153 | struct pkey_apqn *apqns, size_t *nr_apqns) |
1154 | { |
1155 | u32 _nr_apqns, *_apqns = NULL; |
1156 | int rc; |
1157 | |
1158 | zcrypt_wait_api_operational(); |
1159 | |
1160 | if (ktype == PKEY_TYPE_CCA_DATA || ktype == PKEY_TYPE_CCA_CIPHER) { |
1161 | u64 cur_mkvp = 0, old_mkvp = 0; |
1162 | int minhwtype = ZCRYPT_CEX3C; |
1163 | |
1164 | if (flags & PKEY_FLAGS_MATCH_CUR_MKVP) |
1165 | cur_mkvp = *((u64 *)cur_mkvp); |
1166 | if (flags & PKEY_FLAGS_MATCH_ALT_MKVP) |
1167 | old_mkvp = *((u64 *)alt_mkvp); |
1168 | if (ktype == PKEY_TYPE_CCA_CIPHER) |
1169 | minhwtype = ZCRYPT_CEX6; |
1170 | rc = cca_findcard2(apqns: &_apqns, nr_apqns: &_nr_apqns, cardnr: 0xFFFF, domain: 0xFFFF, |
1171 | minhwtype, AES_MK_SET, |
1172 | cur_mkvp, old_mkvp, verify: 1); |
1173 | if (rc) |
1174 | goto out; |
1175 | } else if (ktype == PKEY_TYPE_CCA_ECC) { |
1176 | u64 cur_mkvp = 0, old_mkvp = 0; |
1177 | |
1178 | if (flags & PKEY_FLAGS_MATCH_CUR_MKVP) |
1179 | cur_mkvp = *((u64 *)cur_mkvp); |
1180 | if (flags & PKEY_FLAGS_MATCH_ALT_MKVP) |
1181 | old_mkvp = *((u64 *)alt_mkvp); |
1182 | rc = cca_findcard2(apqns: &_apqns, nr_apqns: &_nr_apqns, cardnr: 0xFFFF, domain: 0xFFFF, |
1183 | ZCRYPT_CEX7, APKA_MK_SET, |
1184 | cur_mkvp, old_mkvp, verify: 1); |
1185 | if (rc) |
1186 | goto out; |
1187 | |
1188 | } else if (ktype == PKEY_TYPE_EP11 || |
1189 | ktype == PKEY_TYPE_EP11_AES || |
1190 | ktype == PKEY_TYPE_EP11_ECC) { |
1191 | u8 *wkvp = NULL; |
1192 | int api; |
1193 | |
1194 | if (flags & PKEY_FLAGS_MATCH_CUR_MKVP) |
1195 | wkvp = cur_mkvp; |
1196 | api = ap_is_se_guest() ? EP11_API_V6 : EP11_API_V4; |
1197 | rc = ep11_findcard2(apqns: &_apqns, nr_apqns: &_nr_apqns, cardnr: 0xFFFF, domain: 0xFFFF, |
1198 | ZCRYPT_CEX7, minapi: api, wkvp); |
1199 | if (rc) |
1200 | goto out; |
1201 | |
1202 | } else { |
1203 | return -EINVAL; |
1204 | } |
1205 | |
1206 | if (apqns) { |
1207 | if (*nr_apqns < _nr_apqns) |
1208 | rc = -ENOSPC; |
1209 | else |
1210 | memcpy(apqns, _apqns, _nr_apqns * sizeof(u32)); |
1211 | } |
1212 | *nr_apqns = _nr_apqns; |
1213 | |
1214 | out: |
1215 | kfree(objp: _apqns); |
1216 | return rc; |
1217 | } |
1218 | |
1219 | static int pkey_keyblob2pkey3(const struct pkey_apqn *apqns, size_t nr_apqns, |
1220 | const u8 *key, size_t keylen, |
1221 | u8 *protkey, u32 *protkeylen, u32 *protkeytype) |
1222 | { |
1223 | struct keytoken_header *hdr = (struct keytoken_header *)key; |
1224 | int i, card, dom, rc; |
1225 | |
1226 | /* check for at least one apqn given */ |
1227 | if (!apqns || !nr_apqns) |
1228 | return -EINVAL; |
1229 | |
1230 | if (keylen < sizeof(struct keytoken_header)) |
1231 | return -EINVAL; |
1232 | |
1233 | if (hdr->type == TOKTYPE_NON_CCA && |
1234 | hdr->version == TOKVER_EP11_AES_WITH_HEADER && |
1235 | is_ep11_keyblob(key + sizeof(struct ep11kblob_header))) { |
1236 | /* EP11 AES key blob with header */ |
1237 | if (ep11_check_aes_key_with_hdr(debug_info, 3, key, keylen, 1)) |
1238 | return -EINVAL; |
1239 | } else if (hdr->type == TOKTYPE_NON_CCA && |
1240 | hdr->version == TOKVER_EP11_ECC_WITH_HEADER && |
1241 | is_ep11_keyblob(key + sizeof(struct ep11kblob_header))) { |
1242 | /* EP11 ECC key blob with header */ |
1243 | if (ep11_check_ecc_key_with_hdr(debug_info, 3, key, keylen, 1)) |
1244 | return -EINVAL; |
1245 | } else if (hdr->type == TOKTYPE_NON_CCA && |
1246 | hdr->version == TOKVER_EP11_AES && |
1247 | is_ep11_keyblob(key)) { |
1248 | /* EP11 AES key blob with header in session field */ |
1249 | if (ep11_check_aes_key(debug_info, 3, key, keylen, 1)) |
1250 | return -EINVAL; |
1251 | } else if (hdr->type == TOKTYPE_CCA_INTERNAL) { |
1252 | if (hdr->version == TOKVER_CCA_AES) { |
1253 | /* CCA AES data key */ |
1254 | if (keylen != sizeof(struct secaeskeytoken)) |
1255 | return -EINVAL; |
1256 | if (cca_check_secaeskeytoken(debug_info, 3, key, 0)) |
1257 | return -EINVAL; |
1258 | } else if (hdr->version == TOKVER_CCA_VLSC) { |
1259 | /* CCA AES cipher key */ |
1260 | if (keylen < hdr->len || keylen > MAXCCAVLSCTOKENSIZE) |
1261 | return -EINVAL; |
1262 | if (cca_check_secaescipherkey(debug_info, 3, key, 0, 1)) |
1263 | return -EINVAL; |
1264 | } else { |
1265 | DEBUG_ERR("%s unknown CCA internal token version %d\n" , |
1266 | __func__, hdr->version); |
1267 | return -EINVAL; |
1268 | } |
1269 | } else if (hdr->type == TOKTYPE_CCA_INTERNAL_PKA) { |
1270 | /* CCA ECC (private) key */ |
1271 | if (keylen < sizeof(struct eccprivkeytoken)) |
1272 | return -EINVAL; |
1273 | if (cca_check_sececckeytoken(debug_info, 3, key, keylen, 1)) |
1274 | return -EINVAL; |
1275 | } else if (hdr->type == TOKTYPE_NON_CCA) { |
1276 | return pkey_nonccatok2pkey(key, keylen, |
1277 | protkey, protkeylen, protkeytype); |
1278 | } else { |
1279 | DEBUG_ERR("%s unknown/unsupported blob type %d\n" , |
1280 | __func__, hdr->type); |
1281 | return -EINVAL; |
1282 | } |
1283 | |
1284 | /* simple try all apqns from the list */ |
1285 | for (rc = -ENODEV, i = 0; rc && i < nr_apqns; i++) { |
1286 | card = apqns[i].card; |
1287 | dom = apqns[i].domain; |
1288 | if (hdr->type == TOKTYPE_NON_CCA && |
1289 | (hdr->version == TOKVER_EP11_AES_WITH_HEADER || |
1290 | hdr->version == TOKVER_EP11_ECC_WITH_HEADER) && |
1291 | is_ep11_keyblob(key + sizeof(struct ep11kblob_header))) |
1292 | rc = ep11_kblob2protkey(card, dom, key, keylen: hdr->len, |
1293 | protkey, protkeylen, |
1294 | protkeytype); |
1295 | else if (hdr->type == TOKTYPE_NON_CCA && |
1296 | hdr->version == TOKVER_EP11_AES && |
1297 | is_ep11_keyblob(key)) |
1298 | rc = ep11_kblob2protkey(card, dom, key, keylen: hdr->len, |
1299 | protkey, protkeylen, |
1300 | protkeytype); |
1301 | else if (hdr->type == TOKTYPE_CCA_INTERNAL && |
1302 | hdr->version == TOKVER_CCA_AES) |
1303 | rc = cca_sec2protkey(cardnr: card, domain: dom, seckey: key, protkey, |
1304 | protkeylen, protkeytype); |
1305 | else if (hdr->type == TOKTYPE_CCA_INTERNAL && |
1306 | hdr->version == TOKVER_CCA_VLSC) |
1307 | rc = cca_cipher2protkey(cardnr: card, domain: dom, ckey: key, protkey, |
1308 | protkeylen, protkeytype); |
1309 | else if (hdr->type == TOKTYPE_CCA_INTERNAL_PKA) |
1310 | rc = cca_ecc2protkey(cardnr: card, domain: dom, key, protkey, |
1311 | protkeylen, protkeytype); |
1312 | else |
1313 | return -EINVAL; |
1314 | } |
1315 | |
1316 | return rc; |
1317 | } |
1318 | |
1319 | /* |
1320 | * File io functions |
1321 | */ |
1322 | |
1323 | static void *_copy_key_from_user(void __user *ukey, size_t keylen) |
1324 | { |
1325 | if (!ukey || keylen < MINKEYBLOBBUFSIZE || keylen > KEYBLOBBUFSIZE) |
1326 | return ERR_PTR(error: -EINVAL); |
1327 | |
1328 | return memdup_user(ukey, keylen); |
1329 | } |
1330 | |
1331 | static void *_copy_apqns_from_user(void __user *uapqns, size_t nr_apqns) |
1332 | { |
1333 | if (!uapqns || nr_apqns == 0) |
1334 | return NULL; |
1335 | |
1336 | return memdup_user(uapqns, nr_apqns * sizeof(struct pkey_apqn)); |
1337 | } |
1338 | |
1339 | static long pkey_unlocked_ioctl(struct file *filp, unsigned int cmd, |
1340 | unsigned long arg) |
1341 | { |
1342 | int rc; |
1343 | |
1344 | switch (cmd) { |
1345 | case PKEY_GENSECK: { |
1346 | struct pkey_genseck __user *ugs = (void __user *)arg; |
1347 | struct pkey_genseck kgs; |
1348 | |
1349 | if (copy_from_user(to: &kgs, from: ugs, n: sizeof(kgs))) |
1350 | return -EFAULT; |
1351 | rc = cca_genseckey(cardnr: kgs.cardnr, domain: kgs.domain, |
1352 | keybitsize: kgs.keytype, seckey: kgs.seckey.seckey); |
1353 | DEBUG_DBG("%s cca_genseckey()=%d\n" , __func__, rc); |
1354 | if (rc) |
1355 | break; |
1356 | if (copy_to_user(to: ugs, from: &kgs, n: sizeof(kgs))) |
1357 | return -EFAULT; |
1358 | break; |
1359 | } |
1360 | case PKEY_CLR2SECK: { |
1361 | struct pkey_clr2seck __user *ucs = (void __user *)arg; |
1362 | struct pkey_clr2seck kcs; |
1363 | |
1364 | if (copy_from_user(to: &kcs, from: ucs, n: sizeof(kcs))) |
1365 | return -EFAULT; |
1366 | rc = cca_clr2seckey(cardnr: kcs.cardnr, domain: kcs.domain, keybitsize: kcs.keytype, |
1367 | clrkey: kcs.clrkey.clrkey, seckey: kcs.seckey.seckey); |
1368 | DEBUG_DBG("%s cca_clr2seckey()=%d\n" , __func__, rc); |
1369 | if (rc) |
1370 | break; |
1371 | if (copy_to_user(to: ucs, from: &kcs, n: sizeof(kcs))) |
1372 | return -EFAULT; |
1373 | memzero_explicit(s: &kcs, count: sizeof(kcs)); |
1374 | break; |
1375 | } |
1376 | case PKEY_SEC2PROTK: { |
1377 | struct pkey_sec2protk __user *usp = (void __user *)arg; |
1378 | struct pkey_sec2protk ksp; |
1379 | |
1380 | if (copy_from_user(to: &ksp, from: usp, n: sizeof(ksp))) |
1381 | return -EFAULT; |
1382 | ksp.protkey.len = sizeof(ksp.protkey.protkey); |
1383 | rc = cca_sec2protkey(cardnr: ksp.cardnr, domain: ksp.domain, |
1384 | seckey: ksp.seckey.seckey, protkey: ksp.protkey.protkey, |
1385 | protkeylen: &ksp.protkey.len, protkeytype: &ksp.protkey.type); |
1386 | DEBUG_DBG("%s cca_sec2protkey()=%d\n" , __func__, rc); |
1387 | if (rc) |
1388 | break; |
1389 | if (copy_to_user(to: usp, from: &ksp, n: sizeof(ksp))) |
1390 | return -EFAULT; |
1391 | break; |
1392 | } |
1393 | case PKEY_CLR2PROTK: { |
1394 | struct pkey_clr2protk __user *ucp = (void __user *)arg; |
1395 | struct pkey_clr2protk kcp; |
1396 | |
1397 | if (copy_from_user(to: &kcp, from: ucp, n: sizeof(kcp))) |
1398 | return -EFAULT; |
1399 | kcp.protkey.len = sizeof(kcp.protkey.protkey); |
1400 | rc = pkey_clr2protkey(keytype: kcp.keytype, clrkey: kcp.clrkey.clrkey, |
1401 | protkey: kcp.protkey.protkey, |
1402 | protkeylen: &kcp.protkey.len, protkeytype: &kcp.protkey.type); |
1403 | DEBUG_DBG("%s pkey_clr2protkey()=%d\n" , __func__, rc); |
1404 | if (rc) |
1405 | break; |
1406 | if (copy_to_user(to: ucp, from: &kcp, n: sizeof(kcp))) |
1407 | return -EFAULT; |
1408 | memzero_explicit(s: &kcp, count: sizeof(kcp)); |
1409 | break; |
1410 | } |
1411 | case PKEY_FINDCARD: { |
1412 | struct pkey_findcard __user *ufc = (void __user *)arg; |
1413 | struct pkey_findcard kfc; |
1414 | |
1415 | if (copy_from_user(to: &kfc, from: ufc, n: sizeof(kfc))) |
1416 | return -EFAULT; |
1417 | rc = cca_findcard(key: kfc.seckey.seckey, |
1418 | pcardnr: &kfc.cardnr, pdomain: &kfc.domain, verify: 1); |
1419 | DEBUG_DBG("%s cca_findcard()=%d\n" , __func__, rc); |
1420 | if (rc < 0) |
1421 | break; |
1422 | if (copy_to_user(to: ufc, from: &kfc, n: sizeof(kfc))) |
1423 | return -EFAULT; |
1424 | break; |
1425 | } |
1426 | case PKEY_SKEY2PKEY: { |
1427 | struct pkey_skey2pkey __user *usp = (void __user *)arg; |
1428 | struct pkey_skey2pkey ksp; |
1429 | |
1430 | if (copy_from_user(to: &ksp, from: usp, n: sizeof(ksp))) |
1431 | return -EFAULT; |
1432 | ksp.protkey.len = sizeof(ksp.protkey.protkey); |
1433 | rc = pkey_skey2pkey(key: ksp.seckey.seckey, protkey: ksp.protkey.protkey, |
1434 | protkeylen: &ksp.protkey.len, protkeytype: &ksp.protkey.type); |
1435 | DEBUG_DBG("%s pkey_skey2pkey()=%d\n" , __func__, rc); |
1436 | if (rc) |
1437 | break; |
1438 | if (copy_to_user(to: usp, from: &ksp, n: sizeof(ksp))) |
1439 | return -EFAULT; |
1440 | break; |
1441 | } |
1442 | case PKEY_VERIFYKEY: { |
1443 | struct pkey_verifykey __user *uvk = (void __user *)arg; |
1444 | struct pkey_verifykey kvk; |
1445 | |
1446 | if (copy_from_user(to: &kvk, from: uvk, n: sizeof(kvk))) |
1447 | return -EFAULT; |
1448 | rc = pkey_verifykey(seckey: &kvk.seckey, pcardnr: &kvk.cardnr, pdomain: &kvk.domain, |
1449 | pkeysize: &kvk.keysize, pattributes: &kvk.attributes); |
1450 | DEBUG_DBG("%s pkey_verifykey()=%d\n" , __func__, rc); |
1451 | if (rc) |
1452 | break; |
1453 | if (copy_to_user(to: uvk, from: &kvk, n: sizeof(kvk))) |
1454 | return -EFAULT; |
1455 | break; |
1456 | } |
1457 | case PKEY_GENPROTK: { |
1458 | struct pkey_genprotk __user *ugp = (void __user *)arg; |
1459 | struct pkey_genprotk kgp; |
1460 | |
1461 | if (copy_from_user(to: &kgp, from: ugp, n: sizeof(kgp))) |
1462 | return -EFAULT; |
1463 | kgp.protkey.len = sizeof(kgp.protkey.protkey); |
1464 | rc = pkey_genprotkey(keytype: kgp.keytype, protkey: kgp.protkey.protkey, |
1465 | protkeylen: &kgp.protkey.len, protkeytype: &kgp.protkey.type); |
1466 | DEBUG_DBG("%s pkey_genprotkey()=%d\n" , __func__, rc); |
1467 | if (rc) |
1468 | break; |
1469 | if (copy_to_user(to: ugp, from: &kgp, n: sizeof(kgp))) |
1470 | return -EFAULT; |
1471 | break; |
1472 | } |
1473 | case PKEY_VERIFYPROTK: { |
1474 | struct pkey_verifyprotk __user *uvp = (void __user *)arg; |
1475 | struct pkey_verifyprotk kvp; |
1476 | |
1477 | if (copy_from_user(to: &kvp, from: uvp, n: sizeof(kvp))) |
1478 | return -EFAULT; |
1479 | rc = pkey_verifyprotkey(protkey: kvp.protkey.protkey, |
1480 | protkeylen: kvp.protkey.len, protkeytype: kvp.protkey.type); |
1481 | DEBUG_DBG("%s pkey_verifyprotkey()=%d\n" , __func__, rc); |
1482 | break; |
1483 | } |
1484 | case PKEY_KBLOB2PROTK: { |
1485 | struct pkey_kblob2pkey __user *utp = (void __user *)arg; |
1486 | struct pkey_kblob2pkey ktp; |
1487 | u8 *kkey; |
1488 | |
1489 | if (copy_from_user(to: &ktp, from: utp, n: sizeof(ktp))) |
1490 | return -EFAULT; |
1491 | kkey = _copy_key_from_user(ukey: ktp.key, keylen: ktp.keylen); |
1492 | if (IS_ERR(ptr: kkey)) |
1493 | return PTR_ERR(ptr: kkey); |
1494 | ktp.protkey.len = sizeof(ktp.protkey.protkey); |
1495 | rc = pkey_keyblob2pkey(kkey, ktp.keylen, ktp.protkey.protkey, |
1496 | &ktp.protkey.len, &ktp.protkey.type); |
1497 | DEBUG_DBG("%s pkey_keyblob2pkey()=%d\n" , __func__, rc); |
1498 | memzero_explicit(s: kkey, count: ktp.keylen); |
1499 | kfree(objp: kkey); |
1500 | if (rc) |
1501 | break; |
1502 | if (copy_to_user(to: utp, from: &ktp, n: sizeof(ktp))) |
1503 | return -EFAULT; |
1504 | break; |
1505 | } |
1506 | case PKEY_GENSECK2: { |
1507 | struct pkey_genseck2 __user *ugs = (void __user *)arg; |
1508 | size_t klen = KEYBLOBBUFSIZE; |
1509 | struct pkey_genseck2 kgs; |
1510 | struct pkey_apqn *apqns; |
1511 | u8 *kkey; |
1512 | |
1513 | if (copy_from_user(to: &kgs, from: ugs, n: sizeof(kgs))) |
1514 | return -EFAULT; |
1515 | apqns = _copy_apqns_from_user(uapqns: kgs.apqns, nr_apqns: kgs.apqn_entries); |
1516 | if (IS_ERR(ptr: apqns)) |
1517 | return PTR_ERR(ptr: apqns); |
1518 | kkey = kzalloc(size: klen, GFP_KERNEL); |
1519 | if (!kkey) { |
1520 | kfree(objp: apqns); |
1521 | return -ENOMEM; |
1522 | } |
1523 | rc = pkey_genseckey2(apqns, nr_apqns: kgs.apqn_entries, |
1524 | ktype: kgs.type, ksize: kgs.size, kflags: kgs.keygenflags, |
1525 | keybuf: kkey, keybufsize: &klen); |
1526 | DEBUG_DBG("%s pkey_genseckey2()=%d\n" , __func__, rc); |
1527 | kfree(objp: apqns); |
1528 | if (rc) { |
1529 | kfree(objp: kkey); |
1530 | break; |
1531 | } |
1532 | if (kgs.key) { |
1533 | if (kgs.keylen < klen) { |
1534 | kfree(objp: kkey); |
1535 | return -EINVAL; |
1536 | } |
1537 | if (copy_to_user(to: kgs.key, from: kkey, n: klen)) { |
1538 | kfree(objp: kkey); |
1539 | return -EFAULT; |
1540 | } |
1541 | } |
1542 | kgs.keylen = klen; |
1543 | if (copy_to_user(to: ugs, from: &kgs, n: sizeof(kgs))) |
1544 | rc = -EFAULT; |
1545 | kfree(objp: kkey); |
1546 | break; |
1547 | } |
1548 | case PKEY_CLR2SECK2: { |
1549 | struct pkey_clr2seck2 __user *ucs = (void __user *)arg; |
1550 | size_t klen = KEYBLOBBUFSIZE; |
1551 | struct pkey_clr2seck2 kcs; |
1552 | struct pkey_apqn *apqns; |
1553 | u8 *kkey; |
1554 | |
1555 | if (copy_from_user(to: &kcs, from: ucs, n: sizeof(kcs))) |
1556 | return -EFAULT; |
1557 | apqns = _copy_apqns_from_user(uapqns: kcs.apqns, nr_apqns: kcs.apqn_entries); |
1558 | if (IS_ERR(ptr: apqns)) |
1559 | return PTR_ERR(ptr: apqns); |
1560 | kkey = kzalloc(size: klen, GFP_KERNEL); |
1561 | if (!kkey) { |
1562 | kfree(objp: apqns); |
1563 | return -ENOMEM; |
1564 | } |
1565 | rc = pkey_clr2seckey2(apqns, nr_apqns: kcs.apqn_entries, |
1566 | ktype: kcs.type, ksize: kcs.size, kflags: kcs.keygenflags, |
1567 | clrkey: kcs.clrkey.clrkey, keybuf: kkey, keybufsize: &klen); |
1568 | DEBUG_DBG("%s pkey_clr2seckey2()=%d\n" , __func__, rc); |
1569 | kfree(objp: apqns); |
1570 | if (rc) { |
1571 | kfree(objp: kkey); |
1572 | break; |
1573 | } |
1574 | if (kcs.key) { |
1575 | if (kcs.keylen < klen) { |
1576 | kfree(objp: kkey); |
1577 | return -EINVAL; |
1578 | } |
1579 | if (copy_to_user(to: kcs.key, from: kkey, n: klen)) { |
1580 | kfree(objp: kkey); |
1581 | return -EFAULT; |
1582 | } |
1583 | } |
1584 | kcs.keylen = klen; |
1585 | if (copy_to_user(to: ucs, from: &kcs, n: sizeof(kcs))) |
1586 | rc = -EFAULT; |
1587 | memzero_explicit(s: &kcs, count: sizeof(kcs)); |
1588 | kfree(objp: kkey); |
1589 | break; |
1590 | } |
1591 | case PKEY_VERIFYKEY2: { |
1592 | struct pkey_verifykey2 __user *uvk = (void __user *)arg; |
1593 | struct pkey_verifykey2 kvk; |
1594 | u8 *kkey; |
1595 | |
1596 | if (copy_from_user(to: &kvk, from: uvk, n: sizeof(kvk))) |
1597 | return -EFAULT; |
1598 | kkey = _copy_key_from_user(ukey: kvk.key, keylen: kvk.keylen); |
1599 | if (IS_ERR(ptr: kkey)) |
1600 | return PTR_ERR(ptr: kkey); |
1601 | rc = pkey_verifykey2(key: kkey, keylen: kvk.keylen, |
1602 | cardnr: &kvk.cardnr, domain: &kvk.domain, |
1603 | ktype: &kvk.type, ksize: &kvk.size, flags: &kvk.flags); |
1604 | DEBUG_DBG("%s pkey_verifykey2()=%d\n" , __func__, rc); |
1605 | kfree(objp: kkey); |
1606 | if (rc) |
1607 | break; |
1608 | if (copy_to_user(to: uvk, from: &kvk, n: sizeof(kvk))) |
1609 | return -EFAULT; |
1610 | break; |
1611 | } |
1612 | case PKEY_KBLOB2PROTK2: { |
1613 | struct pkey_kblob2pkey2 __user *utp = (void __user *)arg; |
1614 | struct pkey_apqn *apqns = NULL; |
1615 | struct pkey_kblob2pkey2 ktp; |
1616 | u8 *kkey; |
1617 | |
1618 | if (copy_from_user(to: &ktp, from: utp, n: sizeof(ktp))) |
1619 | return -EFAULT; |
1620 | apqns = _copy_apqns_from_user(uapqns: ktp.apqns, nr_apqns: ktp.apqn_entries); |
1621 | if (IS_ERR(ptr: apqns)) |
1622 | return PTR_ERR(ptr: apqns); |
1623 | kkey = _copy_key_from_user(ukey: ktp.key, keylen: ktp.keylen); |
1624 | if (IS_ERR(ptr: kkey)) { |
1625 | kfree(objp: apqns); |
1626 | return PTR_ERR(ptr: kkey); |
1627 | } |
1628 | ktp.protkey.len = sizeof(ktp.protkey.protkey); |
1629 | rc = pkey_keyblob2pkey2(apqns, nr_apqns: ktp.apqn_entries, |
1630 | key: kkey, keylen: ktp.keylen, |
1631 | protkey: ktp.protkey.protkey, protkeylen: &ktp.protkey.len, |
1632 | protkeytype: &ktp.protkey.type); |
1633 | DEBUG_DBG("%s pkey_keyblob2pkey2()=%d\n" , __func__, rc); |
1634 | kfree(objp: apqns); |
1635 | memzero_explicit(s: kkey, count: ktp.keylen); |
1636 | kfree(objp: kkey); |
1637 | if (rc) |
1638 | break; |
1639 | if (copy_to_user(to: utp, from: &ktp, n: sizeof(ktp))) |
1640 | return -EFAULT; |
1641 | break; |
1642 | } |
1643 | case PKEY_APQNS4K: { |
1644 | struct pkey_apqns4key __user *uak = (void __user *)arg; |
1645 | struct pkey_apqn *apqns = NULL; |
1646 | struct pkey_apqns4key kak; |
1647 | size_t nr_apqns, len; |
1648 | u8 *kkey; |
1649 | |
1650 | if (copy_from_user(to: &kak, from: uak, n: sizeof(kak))) |
1651 | return -EFAULT; |
1652 | nr_apqns = kak.apqn_entries; |
1653 | if (nr_apqns) { |
1654 | apqns = kmalloc_array(nr_apqns, |
1655 | sizeof(struct pkey_apqn), |
1656 | GFP_KERNEL); |
1657 | if (!apqns) |
1658 | return -ENOMEM; |
1659 | } |
1660 | kkey = _copy_key_from_user(ukey: kak.key, keylen: kak.keylen); |
1661 | if (IS_ERR(ptr: kkey)) { |
1662 | kfree(objp: apqns); |
1663 | return PTR_ERR(ptr: kkey); |
1664 | } |
1665 | rc = pkey_apqns4key(key: kkey, keylen: kak.keylen, flags: kak.flags, |
1666 | apqns, nr_apqns: &nr_apqns); |
1667 | DEBUG_DBG("%s pkey_apqns4key()=%d\n" , __func__, rc); |
1668 | kfree(objp: kkey); |
1669 | if (rc && rc != -ENOSPC) { |
1670 | kfree(objp: apqns); |
1671 | break; |
1672 | } |
1673 | if (!rc && kak.apqns) { |
1674 | if (nr_apqns > kak.apqn_entries) { |
1675 | kfree(objp: apqns); |
1676 | return -EINVAL; |
1677 | } |
1678 | len = nr_apqns * sizeof(struct pkey_apqn); |
1679 | if (len) { |
1680 | if (copy_to_user(to: kak.apqns, from: apqns, n: len)) { |
1681 | kfree(objp: apqns); |
1682 | return -EFAULT; |
1683 | } |
1684 | } |
1685 | } |
1686 | kak.apqn_entries = nr_apqns; |
1687 | if (copy_to_user(to: uak, from: &kak, n: sizeof(kak))) |
1688 | rc = -EFAULT; |
1689 | kfree(objp: apqns); |
1690 | break; |
1691 | } |
1692 | case PKEY_APQNS4KT: { |
1693 | struct pkey_apqns4keytype __user *uat = (void __user *)arg; |
1694 | struct pkey_apqn *apqns = NULL; |
1695 | struct pkey_apqns4keytype kat; |
1696 | size_t nr_apqns, len; |
1697 | |
1698 | if (copy_from_user(to: &kat, from: uat, n: sizeof(kat))) |
1699 | return -EFAULT; |
1700 | nr_apqns = kat.apqn_entries; |
1701 | if (nr_apqns) { |
1702 | apqns = kmalloc_array(nr_apqns, |
1703 | sizeof(struct pkey_apqn), |
1704 | GFP_KERNEL); |
1705 | if (!apqns) |
1706 | return -ENOMEM; |
1707 | } |
1708 | rc = pkey_apqns4keytype(ktype: kat.type, cur_mkvp: kat.cur_mkvp, alt_mkvp: kat.alt_mkvp, |
1709 | flags: kat.flags, apqns, nr_apqns: &nr_apqns); |
1710 | DEBUG_DBG("%s pkey_apqns4keytype()=%d\n" , __func__, rc); |
1711 | if (rc && rc != -ENOSPC) { |
1712 | kfree(objp: apqns); |
1713 | break; |
1714 | } |
1715 | if (!rc && kat.apqns) { |
1716 | if (nr_apqns > kat.apqn_entries) { |
1717 | kfree(objp: apqns); |
1718 | return -EINVAL; |
1719 | } |
1720 | len = nr_apqns * sizeof(struct pkey_apqn); |
1721 | if (len) { |
1722 | if (copy_to_user(to: kat.apqns, from: apqns, n: len)) { |
1723 | kfree(objp: apqns); |
1724 | return -EFAULT; |
1725 | } |
1726 | } |
1727 | } |
1728 | kat.apqn_entries = nr_apqns; |
1729 | if (copy_to_user(to: uat, from: &kat, n: sizeof(kat))) |
1730 | rc = -EFAULT; |
1731 | kfree(objp: apqns); |
1732 | break; |
1733 | } |
1734 | case PKEY_KBLOB2PROTK3: { |
1735 | struct pkey_kblob2pkey3 __user *utp = (void __user *)arg; |
1736 | u32 protkeylen = PROTKEYBLOBBUFSIZE; |
1737 | struct pkey_apqn *apqns = NULL; |
1738 | struct pkey_kblob2pkey3 ktp; |
1739 | u8 *kkey, *protkey; |
1740 | |
1741 | if (copy_from_user(to: &ktp, from: utp, n: sizeof(ktp))) |
1742 | return -EFAULT; |
1743 | apqns = _copy_apqns_from_user(uapqns: ktp.apqns, nr_apqns: ktp.apqn_entries); |
1744 | if (IS_ERR(ptr: apqns)) |
1745 | return PTR_ERR(ptr: apqns); |
1746 | kkey = _copy_key_from_user(ukey: ktp.key, keylen: ktp.keylen); |
1747 | if (IS_ERR(ptr: kkey)) { |
1748 | kfree(objp: apqns); |
1749 | return PTR_ERR(ptr: kkey); |
1750 | } |
1751 | protkey = kmalloc(size: protkeylen, GFP_KERNEL); |
1752 | if (!protkey) { |
1753 | kfree(objp: apqns); |
1754 | kfree(objp: kkey); |
1755 | return -ENOMEM; |
1756 | } |
1757 | rc = pkey_keyblob2pkey3(apqns, nr_apqns: ktp.apqn_entries, |
1758 | key: kkey, keylen: ktp.keylen, |
1759 | protkey, protkeylen: &protkeylen, protkeytype: &ktp.pkeytype); |
1760 | DEBUG_DBG("%s pkey_keyblob2pkey3()=%d\n" , __func__, rc); |
1761 | kfree(objp: apqns); |
1762 | memzero_explicit(s: kkey, count: ktp.keylen); |
1763 | kfree(objp: kkey); |
1764 | if (rc) { |
1765 | kfree(objp: protkey); |
1766 | break; |
1767 | } |
1768 | if (ktp.pkey && ktp.pkeylen) { |
1769 | if (protkeylen > ktp.pkeylen) { |
1770 | kfree(objp: protkey); |
1771 | return -EINVAL; |
1772 | } |
1773 | if (copy_to_user(to: ktp.pkey, from: protkey, n: protkeylen)) { |
1774 | kfree(objp: protkey); |
1775 | return -EFAULT; |
1776 | } |
1777 | } |
1778 | kfree(objp: protkey); |
1779 | ktp.pkeylen = protkeylen; |
1780 | if (copy_to_user(to: utp, from: &ktp, n: sizeof(ktp))) |
1781 | return -EFAULT; |
1782 | break; |
1783 | } |
1784 | default: |
1785 | /* unknown/unsupported ioctl cmd */ |
1786 | return -ENOTTY; |
1787 | } |
1788 | |
1789 | return rc; |
1790 | } |
1791 | |
1792 | /* |
1793 | * Sysfs and file io operations |
1794 | */ |
1795 | |
1796 | /* |
1797 | * Sysfs attribute read function for all protected key binary attributes. |
1798 | * The implementation can not deal with partial reads, because a new random |
1799 | * protected key blob is generated with each read. In case of partial reads |
1800 | * (i.e. off != 0 or count < key blob size) -EINVAL is returned. |
1801 | */ |
1802 | static ssize_t pkey_protkey_aes_attr_read(u32 keytype, bool is_xts, char *buf, |
1803 | loff_t off, size_t count) |
1804 | { |
1805 | struct protaeskeytoken protkeytoken; |
1806 | struct pkey_protkey protkey; |
1807 | int rc; |
1808 | |
1809 | if (off != 0 || count < sizeof(protkeytoken)) |
1810 | return -EINVAL; |
1811 | if (is_xts) |
1812 | if (count < 2 * sizeof(protkeytoken)) |
1813 | return -EINVAL; |
1814 | |
1815 | memset(&protkeytoken, 0, sizeof(protkeytoken)); |
1816 | protkeytoken.type = TOKTYPE_NON_CCA; |
1817 | protkeytoken.version = TOKVER_PROTECTED_KEY; |
1818 | protkeytoken.keytype = keytype; |
1819 | |
1820 | protkey.len = sizeof(protkey.protkey); |
1821 | rc = pkey_genprotkey(keytype: protkeytoken.keytype, |
1822 | protkey: protkey.protkey, protkeylen: &protkey.len, protkeytype: &protkey.type); |
1823 | if (rc) |
1824 | return rc; |
1825 | |
1826 | protkeytoken.len = protkey.len; |
1827 | memcpy(&protkeytoken.protkey, &protkey.protkey, protkey.len); |
1828 | |
1829 | memcpy(buf, &protkeytoken, sizeof(protkeytoken)); |
1830 | |
1831 | if (is_xts) { |
1832 | /* xts needs a second protected key, reuse protkey struct */ |
1833 | protkey.len = sizeof(protkey.protkey); |
1834 | rc = pkey_genprotkey(keytype: protkeytoken.keytype, |
1835 | protkey: protkey.protkey, protkeylen: &protkey.len, protkeytype: &protkey.type); |
1836 | if (rc) |
1837 | return rc; |
1838 | |
1839 | protkeytoken.len = protkey.len; |
1840 | memcpy(&protkeytoken.protkey, &protkey.protkey, protkey.len); |
1841 | |
1842 | memcpy(buf + sizeof(protkeytoken), &protkeytoken, |
1843 | sizeof(protkeytoken)); |
1844 | |
1845 | return 2 * sizeof(protkeytoken); |
1846 | } |
1847 | |
1848 | return sizeof(protkeytoken); |
1849 | } |
1850 | |
1851 | static ssize_t protkey_aes_128_read(struct file *filp, |
1852 | struct kobject *kobj, |
1853 | struct bin_attribute *attr, |
1854 | char *buf, loff_t off, |
1855 | size_t count) |
1856 | { |
1857 | return pkey_protkey_aes_attr_read(PKEY_KEYTYPE_AES_128, false, buf, |
1858 | off, count); |
1859 | } |
1860 | |
1861 | static ssize_t protkey_aes_192_read(struct file *filp, |
1862 | struct kobject *kobj, |
1863 | struct bin_attribute *attr, |
1864 | char *buf, loff_t off, |
1865 | size_t count) |
1866 | { |
1867 | return pkey_protkey_aes_attr_read(PKEY_KEYTYPE_AES_192, false, buf, |
1868 | off, count); |
1869 | } |
1870 | |
1871 | static ssize_t protkey_aes_256_read(struct file *filp, |
1872 | struct kobject *kobj, |
1873 | struct bin_attribute *attr, |
1874 | char *buf, loff_t off, |
1875 | size_t count) |
1876 | { |
1877 | return pkey_protkey_aes_attr_read(PKEY_KEYTYPE_AES_256, false, buf, |
1878 | off, count); |
1879 | } |
1880 | |
1881 | static ssize_t protkey_aes_128_xts_read(struct file *filp, |
1882 | struct kobject *kobj, |
1883 | struct bin_attribute *attr, |
1884 | char *buf, loff_t off, |
1885 | size_t count) |
1886 | { |
1887 | return pkey_protkey_aes_attr_read(PKEY_KEYTYPE_AES_128, true, buf, |
1888 | off, count); |
1889 | } |
1890 | |
1891 | static ssize_t protkey_aes_256_xts_read(struct file *filp, |
1892 | struct kobject *kobj, |
1893 | struct bin_attribute *attr, |
1894 | char *buf, loff_t off, |
1895 | size_t count) |
1896 | { |
1897 | return pkey_protkey_aes_attr_read(PKEY_KEYTYPE_AES_256, true, buf, |
1898 | off, count); |
1899 | } |
1900 | |
1901 | static BIN_ATTR_RO(protkey_aes_128, sizeof(struct protaeskeytoken)); |
1902 | static BIN_ATTR_RO(protkey_aes_192, sizeof(struct protaeskeytoken)); |
1903 | static BIN_ATTR_RO(protkey_aes_256, sizeof(struct protaeskeytoken)); |
1904 | static BIN_ATTR_RO(protkey_aes_128_xts, 2 * sizeof(struct protaeskeytoken)); |
1905 | static BIN_ATTR_RO(protkey_aes_256_xts, 2 * sizeof(struct protaeskeytoken)); |
1906 | |
1907 | static struct bin_attribute *protkey_attrs[] = { |
1908 | &bin_attr_protkey_aes_128, |
1909 | &bin_attr_protkey_aes_192, |
1910 | &bin_attr_protkey_aes_256, |
1911 | &bin_attr_protkey_aes_128_xts, |
1912 | &bin_attr_protkey_aes_256_xts, |
1913 | NULL |
1914 | }; |
1915 | |
1916 | static struct attribute_group protkey_attr_group = { |
1917 | .name = "protkey" , |
1918 | .bin_attrs = protkey_attrs, |
1919 | }; |
1920 | |
1921 | /* |
1922 | * Sysfs attribute read function for all secure key ccadata binary attributes. |
1923 | * The implementation can not deal with partial reads, because a new random |
1924 | * protected key blob is generated with each read. In case of partial reads |
1925 | * (i.e. off != 0 or count < key blob size) -EINVAL is returned. |
1926 | */ |
1927 | static ssize_t pkey_ccadata_aes_attr_read(u32 keytype, bool is_xts, char *buf, |
1928 | loff_t off, size_t count) |
1929 | { |
1930 | struct pkey_seckey *seckey = (struct pkey_seckey *)buf; |
1931 | int rc; |
1932 | |
1933 | if (off != 0 || count < sizeof(struct secaeskeytoken)) |
1934 | return -EINVAL; |
1935 | if (is_xts) |
1936 | if (count < 2 * sizeof(struct secaeskeytoken)) |
1937 | return -EINVAL; |
1938 | |
1939 | rc = cca_genseckey(cardnr: -1, domain: -1, keybitsize: keytype, seckey: seckey->seckey); |
1940 | if (rc) |
1941 | return rc; |
1942 | |
1943 | if (is_xts) { |
1944 | seckey++; |
1945 | rc = cca_genseckey(cardnr: -1, domain: -1, keybitsize: keytype, seckey: seckey->seckey); |
1946 | if (rc) |
1947 | return rc; |
1948 | |
1949 | return 2 * sizeof(struct secaeskeytoken); |
1950 | } |
1951 | |
1952 | return sizeof(struct secaeskeytoken); |
1953 | } |
1954 | |
1955 | static ssize_t ccadata_aes_128_read(struct file *filp, |
1956 | struct kobject *kobj, |
1957 | struct bin_attribute *attr, |
1958 | char *buf, loff_t off, |
1959 | size_t count) |
1960 | { |
1961 | return pkey_ccadata_aes_attr_read(PKEY_KEYTYPE_AES_128, false, buf, |
1962 | off, count); |
1963 | } |
1964 | |
1965 | static ssize_t ccadata_aes_192_read(struct file *filp, |
1966 | struct kobject *kobj, |
1967 | struct bin_attribute *attr, |
1968 | char *buf, loff_t off, |
1969 | size_t count) |
1970 | { |
1971 | return pkey_ccadata_aes_attr_read(PKEY_KEYTYPE_AES_192, false, buf, |
1972 | off, count); |
1973 | } |
1974 | |
1975 | static ssize_t ccadata_aes_256_read(struct file *filp, |
1976 | struct kobject *kobj, |
1977 | struct bin_attribute *attr, |
1978 | char *buf, loff_t off, |
1979 | size_t count) |
1980 | { |
1981 | return pkey_ccadata_aes_attr_read(PKEY_KEYTYPE_AES_256, false, buf, |
1982 | off, count); |
1983 | } |
1984 | |
1985 | static ssize_t ccadata_aes_128_xts_read(struct file *filp, |
1986 | struct kobject *kobj, |
1987 | struct bin_attribute *attr, |
1988 | char *buf, loff_t off, |
1989 | size_t count) |
1990 | { |
1991 | return pkey_ccadata_aes_attr_read(PKEY_KEYTYPE_AES_128, true, buf, |
1992 | off, count); |
1993 | } |
1994 | |
1995 | static ssize_t ccadata_aes_256_xts_read(struct file *filp, |
1996 | struct kobject *kobj, |
1997 | struct bin_attribute *attr, |
1998 | char *buf, loff_t off, |
1999 | size_t count) |
2000 | { |
2001 | return pkey_ccadata_aes_attr_read(PKEY_KEYTYPE_AES_256, true, buf, |
2002 | off, count); |
2003 | } |
2004 | |
2005 | static BIN_ATTR_RO(ccadata_aes_128, sizeof(struct secaeskeytoken)); |
2006 | static BIN_ATTR_RO(ccadata_aes_192, sizeof(struct secaeskeytoken)); |
2007 | static BIN_ATTR_RO(ccadata_aes_256, sizeof(struct secaeskeytoken)); |
2008 | static BIN_ATTR_RO(ccadata_aes_128_xts, 2 * sizeof(struct secaeskeytoken)); |
2009 | static BIN_ATTR_RO(ccadata_aes_256_xts, 2 * sizeof(struct secaeskeytoken)); |
2010 | |
2011 | static struct bin_attribute *ccadata_attrs[] = { |
2012 | &bin_attr_ccadata_aes_128, |
2013 | &bin_attr_ccadata_aes_192, |
2014 | &bin_attr_ccadata_aes_256, |
2015 | &bin_attr_ccadata_aes_128_xts, |
2016 | &bin_attr_ccadata_aes_256_xts, |
2017 | NULL |
2018 | }; |
2019 | |
2020 | static struct attribute_group ccadata_attr_group = { |
2021 | .name = "ccadata" , |
2022 | .bin_attrs = ccadata_attrs, |
2023 | }; |
2024 | |
2025 | #define CCACIPHERTOKENSIZE (sizeof(struct cipherkeytoken) + 80) |
2026 | |
2027 | /* |
2028 | * Sysfs attribute read function for all secure key ccacipher binary attributes. |
2029 | * The implementation can not deal with partial reads, because a new random |
2030 | * secure key blob is generated with each read. In case of partial reads |
2031 | * (i.e. off != 0 or count < key blob size) -EINVAL is returned. |
2032 | */ |
2033 | static ssize_t pkey_ccacipher_aes_attr_read(enum pkey_key_size keybits, |
2034 | bool is_xts, char *buf, loff_t off, |
2035 | size_t count) |
2036 | { |
2037 | size_t keysize = CCACIPHERTOKENSIZE; |
2038 | u32 nr_apqns, *apqns = NULL; |
2039 | int i, rc, card, dom; |
2040 | |
2041 | if (off != 0 || count < CCACIPHERTOKENSIZE) |
2042 | return -EINVAL; |
2043 | if (is_xts) |
2044 | if (count < 2 * CCACIPHERTOKENSIZE) |
2045 | return -EINVAL; |
2046 | |
2047 | /* build a list of apqns able to generate an cipher key */ |
2048 | rc = cca_findcard2(apqns: &apqns, nr_apqns: &nr_apqns, cardnr: 0xFFFF, domain: 0xFFFF, |
2049 | ZCRYPT_CEX6, mktype: 0, cur_mkvp: 0, old_mkvp: 0, verify: 0); |
2050 | if (rc) |
2051 | return rc; |
2052 | |
2053 | memset(buf, 0, is_xts ? 2 * keysize : keysize); |
2054 | |
2055 | /* simple try all apqns from the list */ |
2056 | for (i = 0, rc = -ENODEV; i < nr_apqns; i++) { |
2057 | card = apqns[i] >> 16; |
2058 | dom = apqns[i] & 0xFFFF; |
2059 | rc = cca_gencipherkey(cardnr: card, domain: dom, keybitsize: keybits, keygenflags: 0, keybuf: buf, keybufsize: &keysize); |
2060 | if (rc == 0) |
2061 | break; |
2062 | } |
2063 | if (rc) |
2064 | return rc; |
2065 | |
2066 | if (is_xts) { |
2067 | keysize = CCACIPHERTOKENSIZE; |
2068 | buf += CCACIPHERTOKENSIZE; |
2069 | rc = cca_gencipherkey(cardnr: card, domain: dom, keybitsize: keybits, keygenflags: 0, keybuf: buf, keybufsize: &keysize); |
2070 | if (rc == 0) |
2071 | return 2 * CCACIPHERTOKENSIZE; |
2072 | } |
2073 | |
2074 | return CCACIPHERTOKENSIZE; |
2075 | } |
2076 | |
2077 | static ssize_t ccacipher_aes_128_read(struct file *filp, |
2078 | struct kobject *kobj, |
2079 | struct bin_attribute *attr, |
2080 | char *buf, loff_t off, |
2081 | size_t count) |
2082 | { |
2083 | return pkey_ccacipher_aes_attr_read(PKEY_SIZE_AES_128, false, buf, |
2084 | off, count); |
2085 | } |
2086 | |
2087 | static ssize_t ccacipher_aes_192_read(struct file *filp, |
2088 | struct kobject *kobj, |
2089 | struct bin_attribute *attr, |
2090 | char *buf, loff_t off, |
2091 | size_t count) |
2092 | { |
2093 | return pkey_ccacipher_aes_attr_read(PKEY_SIZE_AES_192, false, buf, |
2094 | off, count); |
2095 | } |
2096 | |
2097 | static ssize_t ccacipher_aes_256_read(struct file *filp, |
2098 | struct kobject *kobj, |
2099 | struct bin_attribute *attr, |
2100 | char *buf, loff_t off, |
2101 | size_t count) |
2102 | { |
2103 | return pkey_ccacipher_aes_attr_read(PKEY_SIZE_AES_256, false, buf, |
2104 | off, count); |
2105 | } |
2106 | |
2107 | static ssize_t ccacipher_aes_128_xts_read(struct file *filp, |
2108 | struct kobject *kobj, |
2109 | struct bin_attribute *attr, |
2110 | char *buf, loff_t off, |
2111 | size_t count) |
2112 | { |
2113 | return pkey_ccacipher_aes_attr_read(PKEY_SIZE_AES_128, true, buf, |
2114 | off, count); |
2115 | } |
2116 | |
2117 | static ssize_t ccacipher_aes_256_xts_read(struct file *filp, |
2118 | struct kobject *kobj, |
2119 | struct bin_attribute *attr, |
2120 | char *buf, loff_t off, |
2121 | size_t count) |
2122 | { |
2123 | return pkey_ccacipher_aes_attr_read(PKEY_SIZE_AES_256, true, buf, |
2124 | off, count); |
2125 | } |
2126 | |
2127 | static BIN_ATTR_RO(ccacipher_aes_128, CCACIPHERTOKENSIZE); |
2128 | static BIN_ATTR_RO(ccacipher_aes_192, CCACIPHERTOKENSIZE); |
2129 | static BIN_ATTR_RO(ccacipher_aes_256, CCACIPHERTOKENSIZE); |
2130 | static BIN_ATTR_RO(ccacipher_aes_128_xts, 2 * CCACIPHERTOKENSIZE); |
2131 | static BIN_ATTR_RO(ccacipher_aes_256_xts, 2 * CCACIPHERTOKENSIZE); |
2132 | |
2133 | static struct bin_attribute *ccacipher_attrs[] = { |
2134 | &bin_attr_ccacipher_aes_128, |
2135 | &bin_attr_ccacipher_aes_192, |
2136 | &bin_attr_ccacipher_aes_256, |
2137 | &bin_attr_ccacipher_aes_128_xts, |
2138 | &bin_attr_ccacipher_aes_256_xts, |
2139 | NULL |
2140 | }; |
2141 | |
2142 | static struct attribute_group ccacipher_attr_group = { |
2143 | .name = "ccacipher" , |
2144 | .bin_attrs = ccacipher_attrs, |
2145 | }; |
2146 | |
2147 | /* |
2148 | * Sysfs attribute read function for all ep11 aes key binary attributes. |
2149 | * The implementation can not deal with partial reads, because a new random |
2150 | * secure key blob is generated with each read. In case of partial reads |
2151 | * (i.e. off != 0 or count < key blob size) -EINVAL is returned. |
2152 | * This function and the sysfs attributes using it provide EP11 key blobs |
2153 | * padded to the upper limit of MAXEP11AESKEYBLOBSIZE which is currently |
2154 | * 336 bytes. |
2155 | */ |
2156 | static ssize_t pkey_ep11_aes_attr_read(enum pkey_key_size keybits, |
2157 | bool is_xts, char *buf, loff_t off, |
2158 | size_t count) |
2159 | { |
2160 | size_t keysize = MAXEP11AESKEYBLOBSIZE; |
2161 | u32 nr_apqns, *apqns = NULL; |
2162 | int i, rc, card, dom; |
2163 | |
2164 | if (off != 0 || count < MAXEP11AESKEYBLOBSIZE) |
2165 | return -EINVAL; |
2166 | if (is_xts) |
2167 | if (count < 2 * MAXEP11AESKEYBLOBSIZE) |
2168 | return -EINVAL; |
2169 | |
2170 | /* build a list of apqns able to generate an cipher key */ |
2171 | rc = ep11_findcard2(apqns: &apqns, nr_apqns: &nr_apqns, cardnr: 0xFFFF, domain: 0xFFFF, |
2172 | ZCRYPT_CEX7, |
2173 | minapi: ap_is_se_guest() ? EP11_API_V6 : EP11_API_V4, |
2174 | NULL); |
2175 | if (rc) |
2176 | return rc; |
2177 | |
2178 | memset(buf, 0, is_xts ? 2 * keysize : keysize); |
2179 | |
2180 | /* simple try all apqns from the list */ |
2181 | for (i = 0, rc = -ENODEV; i < nr_apqns; i++) { |
2182 | card = apqns[i] >> 16; |
2183 | dom = apqns[i] & 0xFFFF; |
2184 | rc = ep11_genaeskey(card, dom, keybits, 0, buf, &keysize, |
2185 | PKEY_TYPE_EP11_AES); |
2186 | if (rc == 0) |
2187 | break; |
2188 | } |
2189 | if (rc) |
2190 | return rc; |
2191 | |
2192 | if (is_xts) { |
2193 | keysize = MAXEP11AESKEYBLOBSIZE; |
2194 | buf += MAXEP11AESKEYBLOBSIZE; |
2195 | rc = ep11_genaeskey(card, dom, keybits, 0, buf, &keysize, |
2196 | PKEY_TYPE_EP11_AES); |
2197 | if (rc == 0) |
2198 | return 2 * MAXEP11AESKEYBLOBSIZE; |
2199 | } |
2200 | |
2201 | return MAXEP11AESKEYBLOBSIZE; |
2202 | } |
2203 | |
2204 | static ssize_t ep11_aes_128_read(struct file *filp, |
2205 | struct kobject *kobj, |
2206 | struct bin_attribute *attr, |
2207 | char *buf, loff_t off, |
2208 | size_t count) |
2209 | { |
2210 | return pkey_ep11_aes_attr_read(PKEY_SIZE_AES_128, false, buf, |
2211 | off, count); |
2212 | } |
2213 | |
2214 | static ssize_t ep11_aes_192_read(struct file *filp, |
2215 | struct kobject *kobj, |
2216 | struct bin_attribute *attr, |
2217 | char *buf, loff_t off, |
2218 | size_t count) |
2219 | { |
2220 | return pkey_ep11_aes_attr_read(PKEY_SIZE_AES_192, false, buf, |
2221 | off, count); |
2222 | } |
2223 | |
2224 | static ssize_t ep11_aes_256_read(struct file *filp, |
2225 | struct kobject *kobj, |
2226 | struct bin_attribute *attr, |
2227 | char *buf, loff_t off, |
2228 | size_t count) |
2229 | { |
2230 | return pkey_ep11_aes_attr_read(PKEY_SIZE_AES_256, false, buf, |
2231 | off, count); |
2232 | } |
2233 | |
2234 | static ssize_t ep11_aes_128_xts_read(struct file *filp, |
2235 | struct kobject *kobj, |
2236 | struct bin_attribute *attr, |
2237 | char *buf, loff_t off, |
2238 | size_t count) |
2239 | { |
2240 | return pkey_ep11_aes_attr_read(PKEY_SIZE_AES_128, true, buf, |
2241 | off, count); |
2242 | } |
2243 | |
2244 | static ssize_t ep11_aes_256_xts_read(struct file *filp, |
2245 | struct kobject *kobj, |
2246 | struct bin_attribute *attr, |
2247 | char *buf, loff_t off, |
2248 | size_t count) |
2249 | { |
2250 | return pkey_ep11_aes_attr_read(PKEY_SIZE_AES_256, true, buf, |
2251 | off, count); |
2252 | } |
2253 | |
2254 | static BIN_ATTR_RO(ep11_aes_128, MAXEP11AESKEYBLOBSIZE); |
2255 | static BIN_ATTR_RO(ep11_aes_192, MAXEP11AESKEYBLOBSIZE); |
2256 | static BIN_ATTR_RO(ep11_aes_256, MAXEP11AESKEYBLOBSIZE); |
2257 | static BIN_ATTR_RO(ep11_aes_128_xts, 2 * MAXEP11AESKEYBLOBSIZE); |
2258 | static BIN_ATTR_RO(ep11_aes_256_xts, 2 * MAXEP11AESKEYBLOBSIZE); |
2259 | |
2260 | static struct bin_attribute *ep11_attrs[] = { |
2261 | &bin_attr_ep11_aes_128, |
2262 | &bin_attr_ep11_aes_192, |
2263 | &bin_attr_ep11_aes_256, |
2264 | &bin_attr_ep11_aes_128_xts, |
2265 | &bin_attr_ep11_aes_256_xts, |
2266 | NULL |
2267 | }; |
2268 | |
2269 | static struct attribute_group ep11_attr_group = { |
2270 | .name = "ep11" , |
2271 | .bin_attrs = ep11_attrs, |
2272 | }; |
2273 | |
2274 | static const struct attribute_group *pkey_attr_groups[] = { |
2275 | &protkey_attr_group, |
2276 | &ccadata_attr_group, |
2277 | &ccacipher_attr_group, |
2278 | &ep11_attr_group, |
2279 | NULL, |
2280 | }; |
2281 | |
2282 | static const struct file_operations pkey_fops = { |
2283 | .owner = THIS_MODULE, |
2284 | .open = nonseekable_open, |
2285 | .llseek = no_llseek, |
2286 | .unlocked_ioctl = pkey_unlocked_ioctl, |
2287 | }; |
2288 | |
2289 | static struct miscdevice pkey_dev = { |
2290 | .name = "pkey" , |
2291 | .minor = MISC_DYNAMIC_MINOR, |
2292 | .mode = 0666, |
2293 | .fops = &pkey_fops, |
2294 | .groups = pkey_attr_groups, |
2295 | }; |
2296 | |
2297 | /* |
2298 | * Module init |
2299 | */ |
2300 | static int __init pkey_init(void) |
2301 | { |
2302 | cpacf_mask_t func_mask; |
2303 | |
2304 | /* |
2305 | * The pckmo instruction should be available - even if we don't |
2306 | * actually invoke it. This instruction comes with MSA 3 which |
2307 | * is also the minimum level for the kmc instructions which |
2308 | * are able to work with protected keys. |
2309 | */ |
2310 | if (!cpacf_query(CPACF_PCKMO, &func_mask)) |
2311 | return -ENODEV; |
2312 | |
2313 | /* check for kmc instructions available */ |
2314 | if (!cpacf_query(CPACF_KMC, &func_mask)) |
2315 | return -ENODEV; |
2316 | if (!cpacf_test_func(&func_mask, CPACF_KMC_PAES_128) || |
2317 | !cpacf_test_func(&func_mask, CPACF_KMC_PAES_192) || |
2318 | !cpacf_test_func(&func_mask, CPACF_KMC_PAES_256)) |
2319 | return -ENODEV; |
2320 | |
2321 | pkey_debug_init(); |
2322 | |
2323 | return misc_register(misc: &pkey_dev); |
2324 | } |
2325 | |
2326 | /* |
2327 | * Module exit |
2328 | */ |
2329 | static void __exit pkey_exit(void) |
2330 | { |
2331 | misc_deregister(misc: &pkey_dev); |
2332 | pkey_debug_exit(); |
2333 | } |
2334 | |
2335 | module_cpu_feature_match(S390_CPU_FEATURE_MSA, pkey_init); |
2336 | module_exit(pkey_exit); |
2337 | |