1 // SPDX-License-Identifier: GPL-2.0
3 * pkey cca specific code
5 * Copyright IBM Corp. 2024
8 #define KMSG_COMPONENT "pkey"
9 #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
11 #include <linux/init.h>
12 #include <linux/module.h>
13 #include <linux/cpufeature.h>
15 #include "zcrypt_ccamisc.h"
16 #include "pkey_base.h"
18 MODULE_LICENSE("GPL");
19 MODULE_AUTHOR("IBM Corporation");
20 MODULE_DESCRIPTION("s390 protected key CCA handler");
22 #if IS_MODULE(CONFIG_PKEY_CCA)
23 static struct ap_device_id pkey_cca_card_ids
[] = {
24 { .dev_type
= AP_DEVICE_TYPE_CEX4
},
25 { .dev_type
= AP_DEVICE_TYPE_CEX5
},
26 { .dev_type
= AP_DEVICE_TYPE_CEX6
},
27 { .dev_type
= AP_DEVICE_TYPE_CEX7
},
28 { .dev_type
= AP_DEVICE_TYPE_CEX8
},
29 { /* end of list */ },
31 MODULE_DEVICE_TABLE(ap
, pkey_cca_card_ids
);
35 * Check key blob for known and supported CCA key.
37 static bool is_cca_key(const u8
*key
, u32 keylen
)
39 struct keytoken_header
*hdr
= (struct keytoken_header
*)key
;
41 if (keylen
< sizeof(*hdr
))
45 case TOKTYPE_CCA_INTERNAL
:
46 switch (hdr
->version
) {
53 case TOKTYPE_CCA_INTERNAL_PKA
:
60 static bool is_cca_keytype(enum pkey_key_type key_type
)
63 case PKEY_TYPE_CCA_DATA
:
64 case PKEY_TYPE_CCA_CIPHER
:
65 case PKEY_TYPE_CCA_ECC
:
72 static int cca_apqns4key(const u8
*key
, u32 keylen
, u32 flags
,
73 struct pkey_apqn
*apqns
, size_t *nr_apqns
)
75 struct keytoken_header
*hdr
= (struct keytoken_header
*)key
;
76 u32 _nr_apqns
, *_apqns
= NULL
;
80 flags
= PKEY_FLAGS_MATCH_CUR_MKVP
| PKEY_FLAGS_MATCH_ALT_MKVP
;
82 if (keylen
< sizeof(struct keytoken_header
))
85 zcrypt_wait_api_operational();
87 if (hdr
->type
== TOKTYPE_CCA_INTERNAL
) {
88 u64 cur_mkvp
= 0, old_mkvp
= 0;
89 int minhwtype
= ZCRYPT_CEX3C
;
91 if (hdr
->version
== TOKVER_CCA_AES
) {
92 struct secaeskeytoken
*t
= (struct secaeskeytoken
*)key
;
94 if (flags
& PKEY_FLAGS_MATCH_CUR_MKVP
)
96 if (flags
& PKEY_FLAGS_MATCH_ALT_MKVP
)
98 } else if (hdr
->version
== TOKVER_CCA_VLSC
) {
99 struct cipherkeytoken
*t
= (struct cipherkeytoken
*)key
;
101 minhwtype
= ZCRYPT_CEX6
;
102 if (flags
& PKEY_FLAGS_MATCH_CUR_MKVP
)
104 if (flags
& PKEY_FLAGS_MATCH_ALT_MKVP
)
107 /* unknown CCA internal token type */
110 rc
= cca_findcard2(&_apqns
, &_nr_apqns
, 0xFFFF, 0xFFFF,
111 minhwtype
, AES_MK_SET
,
112 cur_mkvp
, old_mkvp
, 1);
116 } else if (hdr
->type
== TOKTYPE_CCA_INTERNAL_PKA
) {
117 struct eccprivkeytoken
*t
= (struct eccprivkeytoken
*)key
;
118 u64 cur_mkvp
= 0, old_mkvp
= 0;
120 if (t
->secid
== 0x20) {
121 if (flags
& PKEY_FLAGS_MATCH_CUR_MKVP
)
123 if (flags
& PKEY_FLAGS_MATCH_ALT_MKVP
)
126 /* unknown CCA internal 2 token type */
129 rc
= cca_findcard2(&_apqns
, &_nr_apqns
, 0xFFFF, 0xFFFF,
130 ZCRYPT_CEX7
, APKA_MK_SET
,
131 cur_mkvp
, old_mkvp
, 1);
136 PKEY_DBF_ERR("%s unknown/unsupported blob type %d version %d\n",
137 __func__
, hdr
->type
, hdr
->version
);
142 if (*nr_apqns
< _nr_apqns
)
145 memcpy(apqns
, _apqns
, _nr_apqns
* sizeof(u32
));
147 *nr_apqns
= _nr_apqns
;
151 pr_debug("rc=%d\n", rc
);
155 static int cca_apqns4type(enum pkey_key_type ktype
,
156 u8 cur_mkvp
[32], u8 alt_mkvp
[32], u32 flags
,
157 struct pkey_apqn
*apqns
, size_t *nr_apqns
)
159 u32 _nr_apqns
, *_apqns
= NULL
;
162 zcrypt_wait_api_operational();
164 if (ktype
== PKEY_TYPE_CCA_DATA
|| ktype
== PKEY_TYPE_CCA_CIPHER
) {
165 u64 cur_mkvp
= 0, old_mkvp
= 0;
166 int minhwtype
= ZCRYPT_CEX3C
;
168 if (flags
& PKEY_FLAGS_MATCH_CUR_MKVP
)
169 cur_mkvp
= *((u64
*)cur_mkvp
);
170 if (flags
& PKEY_FLAGS_MATCH_ALT_MKVP
)
171 old_mkvp
= *((u64
*)alt_mkvp
);
172 if (ktype
== PKEY_TYPE_CCA_CIPHER
)
173 minhwtype
= ZCRYPT_CEX6
;
174 rc
= cca_findcard2(&_apqns
, &_nr_apqns
, 0xFFFF, 0xFFFF,
175 minhwtype
, AES_MK_SET
,
176 cur_mkvp
, old_mkvp
, 1);
180 } else if (ktype
== PKEY_TYPE_CCA_ECC
) {
181 u64 cur_mkvp
= 0, old_mkvp
= 0;
183 if (flags
& PKEY_FLAGS_MATCH_CUR_MKVP
)
184 cur_mkvp
= *((u64
*)cur_mkvp
);
185 if (flags
& PKEY_FLAGS_MATCH_ALT_MKVP
)
186 old_mkvp
= *((u64
*)alt_mkvp
);
187 rc
= cca_findcard2(&_apqns
, &_nr_apqns
, 0xFFFF, 0xFFFF,
188 ZCRYPT_CEX7
, APKA_MK_SET
,
189 cur_mkvp
, old_mkvp
, 1);
194 PKEY_DBF_ERR("%s unknown/unsupported key type %d",
195 __func__
, (int)ktype
);
200 if (*nr_apqns
< _nr_apqns
)
203 memcpy(apqns
, _apqns
, _nr_apqns
* sizeof(u32
));
205 *nr_apqns
= _nr_apqns
;
209 pr_debug("rc=%d\n", rc
);
213 static int cca_key2protkey(const struct pkey_apqn
*apqns
, size_t nr_apqns
,
214 const u8
*key
, u32 keylen
,
215 u8
*protkey
, u32
*protkeylen
, u32
*protkeytype
)
217 struct keytoken_header
*hdr
= (struct keytoken_header
*)key
;
218 struct pkey_apqn
*local_apqns
= NULL
;
221 if (keylen
< sizeof(*hdr
))
224 if (hdr
->type
== TOKTYPE_CCA_INTERNAL
&&
225 hdr
->version
== TOKVER_CCA_AES
) {
226 /* CCA AES data key */
227 if (keylen
< sizeof(struct secaeskeytoken
))
229 if (cca_check_secaeskeytoken(pkey_dbf_info
, 3, key
, 0))
231 } else if (hdr
->type
== TOKTYPE_CCA_INTERNAL
&&
232 hdr
->version
== TOKVER_CCA_VLSC
) {
233 /* CCA AES cipher key */
234 if (keylen
< hdr
->len
)
236 if (cca_check_secaescipherkey(pkey_dbf_info
,
239 } else if (hdr
->type
== TOKTYPE_CCA_INTERNAL_PKA
) {
240 /* CCA ECC (private) key */
241 if (keylen
< sizeof(struct eccprivkeytoken
))
243 if (cca_check_sececckeytoken(pkey_dbf_info
, 3, key
, keylen
, 1))
246 PKEY_DBF_ERR("%s unknown/unsupported blob type %d version %d\n",
247 __func__
, hdr
->type
, hdr
->version
);
251 zcrypt_wait_api_operational();
253 if (!apqns
|| (nr_apqns
== 1 &&
254 apqns
[0].card
== 0xFFFF && apqns
[0].domain
== 0xFFFF)) {
255 nr_apqns
= MAXAPQNSINLIST
;
256 local_apqns
= kmalloc_array(nr_apqns
, sizeof(struct pkey_apqn
),
260 rc
= cca_apqns4key(key
, keylen
, 0, local_apqns
, &nr_apqns
);
266 for (rc
= -ENODEV
, i
= 0; rc
&& i
< nr_apqns
; i
++) {
267 if (hdr
->type
== TOKTYPE_CCA_INTERNAL
&&
268 hdr
->version
== TOKVER_CCA_AES
) {
269 rc
= cca_sec2protkey(apqns
[i
].card
, apqns
[i
].domain
,
271 protkeylen
, protkeytype
);
272 } else if (hdr
->type
== TOKTYPE_CCA_INTERNAL
&&
273 hdr
->version
== TOKVER_CCA_VLSC
) {
274 rc
= cca_cipher2protkey(apqns
[i
].card
, apqns
[i
].domain
,
276 protkeylen
, protkeytype
);
277 } else if (hdr
->type
== TOKTYPE_CCA_INTERNAL_PKA
) {
278 rc
= cca_ecc2protkey(apqns
[i
].card
, apqns
[i
].domain
,
280 protkeylen
, protkeytype
);
289 pr_debug("rc=%d\n", rc
);
294 * Generate CCA secure key.
295 * As of now only CCA AES Data or Cipher secure keys are
297 * keytype is one of the PKEY_KEYTYPE_* constants,
298 * subtype may be 0 or PKEY_TYPE_CCA_DATA or PKEY_TYPE_CCA_CIPHER,
299 * keybitsize is the bit size of the key (may be 0 for
300 * keytype PKEY_KEYTYPE_AES_*).
302 static int cca_gen_key(const struct pkey_apqn
*apqns
, size_t nr_apqns
,
303 u32 keytype
, u32 subtype
,
304 u32 keybitsize
, u32 flags
,
305 u8
*keybuf
, u32
*keybuflen
, u32
*_keyinfo
)
307 struct pkey_apqn
*local_apqns
= NULL
;
310 /* check keytype, subtype, keybitsize */
312 case PKEY_KEYTYPE_AES_128
:
313 case PKEY_KEYTYPE_AES_192
:
314 case PKEY_KEYTYPE_AES_256
:
315 len
= pkey_keytype_aes_to_size(keytype
);
316 if (keybitsize
&& keybitsize
!= 8 * len
) {
317 PKEY_DBF_ERR("%s unknown/unsupported keybitsize %d\n",
318 __func__
, keybitsize
);
321 keybitsize
= 8 * len
;
323 case PKEY_TYPE_CCA_DATA
:
324 case PKEY_TYPE_CCA_CIPHER
:
327 PKEY_DBF_ERR("%s unknown/unsupported subtype %d\n",
333 PKEY_DBF_ERR("%s unknown/unsupported keytype %d\n",
338 zcrypt_wait_api_operational();
340 if (!apqns
|| (nr_apqns
== 1 &&
341 apqns
[0].card
== 0xFFFF && apqns
[0].domain
== 0xFFFF)) {
342 nr_apqns
= MAXAPQNSINLIST
;
343 local_apqns
= kmalloc_array(nr_apqns
, sizeof(struct pkey_apqn
),
347 rc
= cca_apqns4type(subtype
, NULL
, NULL
, 0,
348 local_apqns
, &nr_apqns
);
354 for (rc
= -ENODEV
, i
= 0; rc
&& i
< nr_apqns
; i
++) {
355 if (subtype
== PKEY_TYPE_CCA_CIPHER
) {
356 rc
= cca_gencipherkey(apqns
[i
].card
, apqns
[i
].domain
,
360 /* PKEY_TYPE_CCA_DATA */
361 rc
= cca_genseckey(apqns
[i
].card
, apqns
[i
].domain
,
363 *keybuflen
= (rc
? 0 : SECKEYBLOBSIZE
);
369 pr_debug("rc=%d\n", rc
);
374 * Generate CCA secure key with given clear key value.
375 * As of now only CCA AES Data or Cipher secure keys are
377 * keytype is one of the PKEY_KEYTYPE_* constants,
378 * subtype may be 0 or PKEY_TYPE_CCA_DATA or PKEY_TYPE_CCA_CIPHER,
379 * keybitsize is the bit size of the key (may be 0 for
380 * keytype PKEY_KEYTYPE_AES_*).
382 static int cca_clr2key(const struct pkey_apqn
*apqns
, size_t nr_apqns
,
383 u32 keytype
, u32 subtype
,
384 u32 keybitsize
, u32 flags
,
385 const u8
*clrkey
, u32 clrkeylen
,
386 u8
*keybuf
, u32
*keybuflen
, u32
*_keyinfo
)
388 struct pkey_apqn
*local_apqns
= NULL
;
391 /* check keytype, subtype, clrkeylen, keybitsize */
393 case PKEY_KEYTYPE_AES_128
:
394 case PKEY_KEYTYPE_AES_192
:
395 case PKEY_KEYTYPE_AES_256
:
396 len
= pkey_keytype_aes_to_size(keytype
);
397 if (keybitsize
&& keybitsize
!= 8 * len
) {
398 PKEY_DBF_ERR("%s unknown/unsupported keybitsize %d\n",
399 __func__
, keybitsize
);
402 keybitsize
= 8 * len
;
403 if (clrkeylen
!= len
) {
404 PKEY_DBF_ERR("%s invalid clear key len %d != %d\n",
405 __func__
, clrkeylen
, len
);
409 case PKEY_TYPE_CCA_DATA
:
410 case PKEY_TYPE_CCA_CIPHER
:
413 PKEY_DBF_ERR("%s unknown/unsupported subtype %d\n",
419 PKEY_DBF_ERR("%s unknown/unsupported keytype %d\n",
424 zcrypt_wait_api_operational();
426 if (!apqns
|| (nr_apqns
== 1 &&
427 apqns
[0].card
== 0xFFFF && apqns
[0].domain
== 0xFFFF)) {
428 nr_apqns
= MAXAPQNSINLIST
;
429 local_apqns
= kmalloc_array(nr_apqns
, sizeof(struct pkey_apqn
),
433 rc
= cca_apqns4type(subtype
, NULL
, NULL
, 0,
434 local_apqns
, &nr_apqns
);
440 for (rc
= -ENODEV
, i
= 0; rc
&& i
< nr_apqns
; i
++) {
441 if (subtype
== PKEY_TYPE_CCA_CIPHER
) {
442 rc
= cca_clr2cipherkey(apqns
[i
].card
, apqns
[i
].domain
,
443 keybitsize
, flags
, clrkey
,
446 /* PKEY_TYPE_CCA_DATA */
447 rc
= cca_clr2seckey(apqns
[i
].card
, apqns
[i
].domain
,
448 keybitsize
, clrkey
, keybuf
);
449 *keybuflen
= (rc
? 0 : SECKEYBLOBSIZE
);
455 pr_debug("rc=%d\n", rc
);
459 static int cca_verifykey(const u8
*key
, u32 keylen
,
461 u32
*keytype
, u32
*keybitsize
, u32
*flags
)
463 struct keytoken_header
*hdr
= (struct keytoken_header
*)key
;
464 u32 nr_apqns
, *apqns
= NULL
;
467 if (keylen
< sizeof(*hdr
))
470 zcrypt_wait_api_operational();
472 if (hdr
->type
== TOKTYPE_CCA_INTERNAL
&&
473 hdr
->version
== TOKVER_CCA_AES
) {
474 struct secaeskeytoken
*t
= (struct secaeskeytoken
*)key
;
476 rc
= cca_check_secaeskeytoken(pkey_dbf_info
, 3, key
, 0);
479 *keytype
= PKEY_TYPE_CCA_DATA
;
480 *keybitsize
= t
->bitsize
;
481 rc
= cca_findcard2(&apqns
, &nr_apqns
, *card
, *dom
,
482 ZCRYPT_CEX3C
, AES_MK_SET
,
485 *flags
= PKEY_FLAGS_MATCH_CUR_MKVP
;
487 rc
= cca_findcard2(&apqns
, &nr_apqns
, *card
, *dom
,
488 ZCRYPT_CEX3C
, AES_MK_SET
,
491 *flags
= PKEY_FLAGS_MATCH_ALT_MKVP
;
496 *card
= ((struct pkey_apqn
*)apqns
)->card
;
497 *dom
= ((struct pkey_apqn
*)apqns
)->domain
;
499 } else if (hdr
->type
== TOKTYPE_CCA_INTERNAL
&&
500 hdr
->version
== TOKVER_CCA_VLSC
) {
501 struct cipherkeytoken
*t
= (struct cipherkeytoken
*)key
;
503 rc
= cca_check_secaescipherkey(pkey_dbf_info
, 3, key
, 0, 1);
506 *keytype
= PKEY_TYPE_CCA_CIPHER
;
507 *keybitsize
= PKEY_SIZE_UNKNOWN
;
508 if (!t
->plfver
&& t
->wpllen
== 512)
509 *keybitsize
= PKEY_SIZE_AES_128
;
510 else if (!t
->plfver
&& t
->wpllen
== 576)
511 *keybitsize
= PKEY_SIZE_AES_192
;
512 else if (!t
->plfver
&& t
->wpllen
== 640)
513 *keybitsize
= PKEY_SIZE_AES_256
;
514 rc
= cca_findcard2(&apqns
, &nr_apqns
, *card
, *dom
,
515 ZCRYPT_CEX6
, AES_MK_SET
,
518 *flags
= PKEY_FLAGS_MATCH_CUR_MKVP
;
520 rc
= cca_findcard2(&apqns
, &nr_apqns
, *card
, *dom
,
521 ZCRYPT_CEX6
, AES_MK_SET
,
524 *flags
= PKEY_FLAGS_MATCH_ALT_MKVP
;
529 *card
= ((struct pkey_apqn
*)apqns
)->card
;
530 *dom
= ((struct pkey_apqn
*)apqns
)->domain
;
533 /* unknown/unsupported key blob */
539 pr_debug("rc=%d\n", rc
);
544 * This function provides an alternate but usually slow way
545 * to convert a 'clear key token' with AES key material into
546 * a protected key. This is done via an intermediate step
547 * which creates a CCA AES DATA secure key first and then
548 * derives the protected key from this secure key.
550 static int cca_slowpath_key2protkey(const struct pkey_apqn
*apqns
,
552 const u8
*key
, u32 keylen
,
553 u8
*protkey
, u32
*protkeylen
,
556 const struct keytoken_header
*hdr
= (const struct keytoken_header
*)key
;
557 const struct clearkeytoken
*t
= (const struct clearkeytoken
*)key
;
558 u32 tmplen
, keysize
= 0;
562 if (keylen
< sizeof(*hdr
))
565 if (hdr
->type
== TOKTYPE_NON_CCA
&&
566 hdr
->version
== TOKVER_CLEAR_KEY
)
567 keysize
= pkey_keytype_aes_to_size(t
->keytype
);
568 if (!keysize
|| t
->len
!= keysize
)
571 /* alloc tmp key buffer */
572 tmpbuf
= kmalloc(SECKEYBLOBSIZE
, GFP_ATOMIC
);
576 /* try two times in case of failure */
577 for (i
= 0, rc
= -ENODEV
; i
< 2 && rc
; i
++) {
578 tmplen
= SECKEYBLOBSIZE
;
579 rc
= cca_clr2key(NULL
, 0, t
->keytype
, PKEY_TYPE_CCA_DATA
,
580 8 * keysize
, 0, t
->clearkey
, t
->len
,
581 tmpbuf
, &tmplen
, NULL
);
582 pr_debug("cca_clr2key()=%d\n", rc
);
585 rc
= cca_key2protkey(NULL
, 0, tmpbuf
, tmplen
,
586 protkey
, protkeylen
, protkeytype
);
587 pr_debug("cca_key2protkey()=%d\n", rc
);
591 pr_debug("rc=%d\n", rc
);
595 static struct pkey_handler cca_handler
= {
596 .module
= THIS_MODULE
,
597 .name
= "PKEY CCA handler",
598 .is_supported_key
= is_cca_key
,
599 .is_supported_keytype
= is_cca_keytype
,
600 .key_to_protkey
= cca_key2protkey
,
601 .slowpath_key_to_protkey
= cca_slowpath_key2protkey
,
602 .gen_key
= cca_gen_key
,
603 .clr_to_key
= cca_clr2key
,
604 .verify_key
= cca_verifykey
,
605 .apqns_for_key
= cca_apqns4key
,
606 .apqns_for_keytype
= cca_apqns4type
,
612 static int __init
pkey_cca_init(void)
614 /* register this module as pkey handler for all the cca stuff */
615 return pkey_handler_register(&cca_handler
);
621 static void __exit
pkey_cca_exit(void)
623 /* unregister this module as pkey handler */
624 pkey_handler_unregister(&cca_handler
);
627 module_init(pkey_cca_init
);
628 module_exit(pkey_cca_exit
);