Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

s390/pkey: support CCA and EP11 secure ECC private keys

This patch extends the pkey kernel module to support CCA
and EP11 secure ECC (private) keys as source for deriving
ECC protected (private) keys.

There is yet another new ioctl to support this: PKEY_KBLOB2PROTK3
can handle all the old keys plus CCA and EP11 secure ECC keys.
For details see ioctl description in pkey.h.

The CPACF unit currently only supports a subset of 5
different ECC curves (P-256, P-384, P-521, ED25519, ED448) and
so only keys of this curve type can be transformed into
protected keys. However, the pkey and the cca/ep11 low level
functions do not check this but simple pass-through the key
blob to the firmware onto the crypto cards. So most likely
the failure will be a response carrying an error code
resulting in user space errno value EIO instead of EINVAL.

Deriving a protected key from an EP11 ECC secure key
requires a CEX7 in EP11 mode. Deriving a protected key from
an CCA ECC secure key requires a CEX7 in CCA mode.

Together with this new ioctl the ioctls for querying lists
of apqns (PKEY_APQNS4K and PKEY_APQNS4KT) have been extended
to support EP11 and CCA ECC secure key type and key blobs.

Together with this ioctl there comes a new struct ep11kblob_header
which is to be prepended onto the EP11 key blob. See details
in pkey.h for the fields in there. The older EP11 AES key blob
with some info stored in the (unused) session field is also
supported with this new ioctl.

Signed-off-by: Harald Freudenberger <freude@linux.ibm.com>
Reviewed-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>

authored by

Harald Freudenberger and committed by
Vasily Gorbik
fa6999e3 32ca04bb

+821 -98
+62 -15
arch/s390/include/uapi/asm/pkey.h
··· 35 35 #define PKEY_KEYTYPE_AES_128 1 36 36 #define PKEY_KEYTYPE_AES_192 2 37 37 #define PKEY_KEYTYPE_AES_256 3 38 + #define PKEY_KEYTYPE_ECC 4 38 39 39 40 /* the newer ioctls use a pkey_key_type enum for type information */ 40 41 enum pkey_key_type { 41 42 PKEY_TYPE_CCA_DATA = (__u32) 1, 42 43 PKEY_TYPE_CCA_CIPHER = (__u32) 2, 43 44 PKEY_TYPE_EP11 = (__u32) 3, 45 + PKEY_TYPE_CCA_ECC = (__u32) 0x1f, 46 + PKEY_TYPE_EP11_AES = (__u32) 6, 47 + PKEY_TYPE_EP11_ECC = (__u32) 7, 44 48 }; 45 49 46 50 /* the newer ioctls use a pkey_key_size enum for key size information */ ··· 91 87 struct pkey_clrkey { 92 88 __u8 clrkey[MAXCLRKEYSIZE]; /* 16, 24, or 32 byte clear key value */ 93 89 }; 90 + 91 + /* 92 + * EP11 key blobs of type PKEY_TYPE_EP11_AES and PKEY_TYPE_EP11_ECC 93 + * are ep11 blobs prepended by this header: 94 + */ 95 + struct ep11kblob_header { 96 + __u8 type; /* always 0x00 */ 97 + __u8 hver; /* header version, currently needs to be 0x00 */ 98 + __u16 len; /* total length in bytes (including this header) */ 99 + __u8 version; /* PKEY_TYPE_EP11_AES or PKEY_TYPE_EP11_ECC */ 100 + __u8 res0; /* unused */ 101 + __u16 bitlen; /* clear key bit len, 0 for unknown */ 102 + __u8 res1[8]; /* unused */ 103 + } __packed; 94 104 95 105 /* 96 106 * Generate CCA AES secure key. ··· 322 304 #define PKEY_VERIFYKEY2 _IOWR(PKEY_IOCTL_MAGIC, 0x17, struct pkey_verifykey2) 323 305 324 306 /* 325 - * Transform a key blob (of any type) into a protected key, version 2. 307 + * Transform a key blob into a protected key, version 2. 326 308 * There needs to be a list of apqns given with at least one entry in there. 327 309 * All apqns in the list need to be exact apqns, 0xFFFF as ANY card or domain 328 310 * is not supported. The implementation walks through the list of apqns and ··· 331 313 * list is tried until success (return 0) or the end of the list is reached 332 314 * (return -1 with errno ENODEV). You may use the PKEY_APQNS4K ioctl to 333 315 * generate a list of apqns based on the key. 316 + * Deriving ECC protected keys from ECC secure keys is not supported with 317 + * this ioctl, use PKEY_KBLOB2PROTK3 for this purpose. 334 318 */ 335 319 struct pkey_kblob2pkey2 { 336 320 __u8 __user *key; /* in: pointer to key blob */ ··· 346 326 /* 347 327 * Build a list of APQNs based on a key blob given. 348 328 * Is able to find out which type of secure key is given (CCA AES secure 349 - * key, CCA AES cipher key or EP11 AES key) and tries to find all matching 350 - * crypto cards based on the MKVP and maybe other criterias (like CCA AES 351 - * cipher keys need a CEX5C or higher, EP11 keys with BLOB_PKEY_EXTRACTABLE 352 - * need a CEX7 and EP11 api version 4). The list of APQNs is further filtered 353 - * by the key's mkvp which needs to match to either the current mkvp (CCA and 354 - * EP11) or the alternate mkvp (old mkvp, CCA adapters only) of the apqns. The 355 - * flags argument may be used to limit the matching apqns. If the 356 - * PKEY_FLAGS_MATCH_CUR_MKVP is given, only the current mkvp of each apqn is 357 - * compared. Likewise with the PKEY_FLAGS_MATCH_ALT_MKVP. If both are given, it 358 - * is assumed to return apqns where either the current or the alternate mkvp 359 - * matches. At least one of the matching flags needs to be given. 329 + * key, CCA AES cipher key, CCA ECC private key, EP11 AES key, EP11 ECC private 330 + * key) and tries to find all matching crypto cards based on the MKVP and maybe 331 + * other criterias (like CCA AES cipher keys need a CEX5C or higher, EP11 keys 332 + * with BLOB_PKEY_EXTRACTABLE need a CEX7 and EP11 api version 4). The list of 333 + * APQNs is further filtered by the key's mkvp which needs to match to either 334 + * the current mkvp (CCA and EP11) or the alternate mkvp (old mkvp, CCA adapters 335 + * only) of the apqns. The flags argument may be used to limit the matching 336 + * apqns. If the PKEY_FLAGS_MATCH_CUR_MKVP is given, only the current mkvp of 337 + * each apqn is compared. Likewise with the PKEY_FLAGS_MATCH_ALT_MKVP. If both 338 + * are given, it is assumed to return apqns where either the current or the 339 + * alternate mkvp matches. At least one of the matching flags needs to be given. 360 340 * The flags argument for EP11 keys has no further action and is currently 361 341 * ignored (but needs to be given as PKEY_FLAGS_MATCH_CUR_MKVP) as there is only 362 342 * the wkvp from the key to match against the apqn's wkvp. ··· 385 365 * restrict the list by given master key verification patterns. 386 366 * For different key types there may be different ways to match the 387 367 * master key verification patterns. For CCA keys (CCA data key and CCA 388 - * cipher key) the first 8 bytes of cur_mkvp refer to the current mkvp value 389 - * of the apqn and the first 8 bytes of the alt_mkvp refer to the old mkvp. 390 - * The flags argument controls if the apqns current and/or alternate mkvp 368 + * cipher key) the first 8 bytes of cur_mkvp refer to the current AES mkvp value 369 + * of the apqn and the first 8 bytes of the alt_mkvp refer to the old AES mkvp. 370 + * For CCA ECC keys it is similar but the match is against the APKA current/old 371 + * mkvp. The flags argument controls if the apqns current and/or alternate mkvp 391 372 * should match. If the PKEY_FLAGS_MATCH_CUR_MKVP is given, only the current 392 373 * mkvp of each apqn is compared. Likewise with the PKEY_FLAGS_MATCH_ALT_MKVP. 393 374 * If both are given, it is assumed to return apqns where either the ··· 417 396 /* out: # apqns stored into the list */ 418 397 }; 419 398 #define PKEY_APQNS4KT _IOWR(PKEY_IOCTL_MAGIC, 0x1C, struct pkey_apqns4keytype) 399 + 400 + /* 401 + * Transform a key blob into a protected key, version 3. 402 + * The difference to version 2 of this ioctl is that the protected key 403 + * buffer is now explicitly and not within a struct pkey_protkey any more. 404 + * So this ioctl is also able to handle EP11 and CCA ECC secure keys and 405 + * provide ECC protected keys. 406 + * There needs to be a list of apqns given with at least one entry in there. 407 + * All apqns in the list need to be exact apqns, 0xFFFF as ANY card or domain 408 + * is not supported. The implementation walks through the list of apqns and 409 + * tries to send the request to each apqn without any further checking (like 410 + * card type or online state). If the apqn fails, simple the next one in the 411 + * list is tried until success (return 0) or the end of the list is reached 412 + * (return -1 with errno ENODEV). You may use the PKEY_APQNS4K ioctl to 413 + * generate a list of apqns based on the key. 414 + */ 415 + struct pkey_kblob2pkey3 { 416 + __u8 __user *key; /* in: pointer to key blob */ 417 + __u32 keylen; /* in: key blob size */ 418 + struct pkey_apqn __user *apqns; /* in: ptr to list of apqn targets */ 419 + __u32 apqn_entries; /* in: # of apqn target list entries */ 420 + __u32 pkeytype; /* out: prot key type (enum pkey_key_type) */ 421 + __u32 pkeylen; /* in/out: size of pkey buffer/actual len of pkey */ 422 + __u8 __user *pkey; /* in: pkey blob buffer space ptr */ 423 + }; 424 + #define PKEY_KBLOB2PROTK3 _IOWR(PKEY_IOCTL_MAGIC, 0x1D, struct pkey_kblob2pkey3) 420 425 421 426 #endif /* _UAPI_PKEY_H */
+230 -14
drivers/s390/crypto/pkey_api.c
··· 31 31 MODULE_AUTHOR("IBM Corporation"); 32 32 MODULE_DESCRIPTION("s390 protected key interface"); 33 33 34 - #define KEYBLOBBUFSIZE 8192 /* key buffer size used for internal processing */ 35 - #define MAXAPQNSINLIST 64 /* max 64 apqns within a apqn list */ 34 + #define KEYBLOBBUFSIZE 8192 /* key buffer size used for internal processing */ 35 + #define PROTKEYBLOBBUFSIZE 256 /* protected key buffer size used internal */ 36 + #define MAXAPQNSINLIST 64 /* max 64 apqns within a apqn list */ 36 37 37 38 /* mask of available pckmo subfunctions, fetched once at module init */ 38 39 static cpacf_mask_t pckmo_functions; ··· 238 237 for (rc = -ENODEV, i = 0; i < nr_apqns; i++) { 239 238 card = apqns[i] >> 16; 240 239 dom = apqns[i] & 0xFFFF; 241 - rc = ep11_key2protkey(card, dom, key, kb->head.len, 242 - pkey->protkey, &pkey->len, &pkey->type); 240 + pkey->len = sizeof(pkey->protkey); 241 + rc = ep11_kblob2protkey(card, dom, key, kb->head.len, 242 + pkey->protkey, &pkey->len, &pkey->type); 243 243 if (rc == 0) 244 244 break; 245 245 } ··· 451 449 break; 452 450 } 453 451 case TOKVER_EP11_AES: { 454 - if (keylen < MINEP11AESKEYBLOBSIZE) 455 - goto out; 456 452 /* check ep11 key for exportable as protected key */ 457 - rc = ep11_check_aeskeyblob(debug_info, 3, key, 0, 1); 453 + rc = ep11_check_aes_key(debug_info, 3, key, keylen, 1); 458 454 if (rc) 459 455 goto out; 460 456 rc = pkey_ep11key2pkey(key, protkey); 461 457 break; 462 458 } 459 + case TOKVER_EP11_AES_WITH_HEADER: 460 + /* check ep11 key with header for exportable as protected key */ 461 + rc = ep11_check_aes_key_with_hdr(debug_info, 3, key, keylen, 1); 462 + if (rc) 463 + goto out; 464 + rc = pkey_ep11key2pkey(key + sizeof(struct ep11kblob_header), 465 + protkey); 466 + break; 463 467 default: 464 468 DEBUG_ERR("%s unknown/unsupported non-CCA token version %d\n", 465 469 __func__, hdr->version); ··· 727 719 && hdr->version == TOKVER_EP11_AES) { 728 720 struct ep11keyblob *kb = (struct ep11keyblob *)key; 729 721 730 - rc = ep11_check_aeskeyblob(debug_info, 3, key, 0, 1); 722 + rc = ep11_check_aes_key(debug_info, 3, key, keylen, 1); 731 723 if (rc) 732 724 goto out; 733 725 if (ktype) ··· 788 780 if (hdr->version == TOKVER_EP11_AES) { 789 781 if (keylen < sizeof(struct ep11keyblob)) 790 782 return -EINVAL; 791 - if (ep11_check_aeskeyblob(debug_info, 3, key, 0, 1)) 783 + if (ep11_check_aes_key(debug_info, 3, key, keylen, 1)) 792 784 return -EINVAL; 793 785 } else { 794 786 return pkey_nonccatok2pkey(key, keylen, pkey); ··· 814 806 else { /* EP11 AES secure key blob */ 815 807 struct ep11keyblob *kb = (struct ep11keyblob *) key; 816 808 817 - rc = ep11_key2protkey(card, dom, key, kb->head.len, 818 - pkey->protkey, &pkey->len, 819 - &pkey->type); 809 + pkey->len = sizeof(pkey->protkey); 810 + rc = ep11_kblob2protkey(card, dom, key, kb->head.len, 811 + pkey->protkey, &pkey->len, 812 + &pkey->type); 820 813 } 821 814 if (rc == 0) 822 815 break; ··· 836 827 if (keylen < sizeof(struct keytoken_header) || flags == 0) 837 828 return -EINVAL; 838 829 839 - if (hdr->type == TOKTYPE_NON_CCA && hdr->version == TOKVER_EP11_AES) { 830 + if (hdr->type == TOKTYPE_NON_CCA 831 + && (hdr->version == TOKVER_EP11_AES_WITH_HEADER 832 + || hdr->version == TOKVER_EP11_ECC_WITH_HEADER) 833 + && is_ep11_keyblob(key + sizeof(struct ep11kblob_header))) { 834 + int minhwtype = 0, api = 0; 835 + struct ep11keyblob *kb = (struct ep11keyblob *) 836 + (key + sizeof(struct ep11kblob_header)); 837 + 838 + if (flags != PKEY_FLAGS_MATCH_CUR_MKVP) 839 + return -EINVAL; 840 + if (kb->attr & EP11_BLOB_PKEY_EXTRACTABLE) { 841 + minhwtype = ZCRYPT_CEX7; 842 + api = EP11_API_V; 843 + } 844 + rc = ep11_findcard2(&_apqns, &_nr_apqns, 0xFFFF, 0xFFFF, 845 + minhwtype, api, kb->wkvp); 846 + if (rc) 847 + goto out; 848 + } else if (hdr->type == TOKTYPE_NON_CCA 849 + && hdr->version == TOKVER_EP11_AES 850 + && is_ep11_keyblob(key)) { 840 851 int minhwtype = 0, api = 0; 841 852 struct ep11keyblob *kb = (struct ep11keyblob *) key; 842 853 ··· 898 869 cur_mkvp, old_mkvp, 1); 899 870 if (rc) 900 871 goto out; 872 + } else if (hdr->type == TOKTYPE_CCA_INTERNAL_PKA) { 873 + u64 cur_mkvp = 0, old_mkvp = 0; 874 + struct eccprivkeytoken *t = (struct eccprivkeytoken *)key; 875 + 876 + if (t->secid == 0x20) { 877 + if (flags & PKEY_FLAGS_MATCH_CUR_MKVP) 878 + cur_mkvp = t->mkvp; 879 + if (flags & PKEY_FLAGS_MATCH_ALT_MKVP) 880 + old_mkvp = t->mkvp; 881 + } else { 882 + /* unknown cca internal 2 token type */ 883 + return -EINVAL; 884 + } 885 + rc = cca_findcard2(&_apqns, &_nr_apqns, 0xFFFF, 0xFFFF, 886 + ZCRYPT_CEX7, APKA_MK_SET, 887 + cur_mkvp, old_mkvp, 1); 888 + if (rc) 889 + goto out; 901 890 } else 902 891 return -EINVAL; 903 892 ··· 954 907 cur_mkvp, old_mkvp, 1); 955 908 if (rc) 956 909 goto out; 957 - } else if (ktype == PKEY_TYPE_EP11) { 910 + } else if (ktype == PKEY_TYPE_CCA_ECC) { 911 + u64 cur_mkvp = 0, old_mkvp = 0; 912 + 913 + if (flags & PKEY_FLAGS_MATCH_CUR_MKVP) 914 + cur_mkvp = *((u64 *) cur_mkvp); 915 + if (flags & PKEY_FLAGS_MATCH_ALT_MKVP) 916 + old_mkvp = *((u64 *) alt_mkvp); 917 + rc = cca_findcard2(&_apqns, &_nr_apqns, 0xFFFF, 0xFFFF, 918 + ZCRYPT_CEX7, APKA_MK_SET, 919 + cur_mkvp, old_mkvp, 1); 920 + if (rc) 921 + goto out; 922 + 923 + } else if (ktype == PKEY_TYPE_EP11 || 924 + ktype == PKEY_TYPE_EP11_AES || 925 + ktype == PKEY_TYPE_EP11_ECC) { 958 926 u8 *wkvp = NULL; 959 927 960 928 if (flags & PKEY_FLAGS_MATCH_CUR_MKVP) ··· 992 930 993 931 out: 994 932 kfree(_apqns); 933 + return rc; 934 + } 935 + 936 + static int pkey_keyblob2pkey3(const struct pkey_apqn *apqns, size_t nr_apqns, 937 + const u8 *key, size_t keylen, u32 *protkeytype, 938 + u8 *protkey, u32 *protkeylen) 939 + { 940 + int i, card, dom, rc; 941 + struct keytoken_header *hdr = (struct keytoken_header *)key; 942 + 943 + /* check for at least one apqn given */ 944 + if (!apqns || !nr_apqns) 945 + return -EINVAL; 946 + 947 + if (keylen < sizeof(struct keytoken_header)) 948 + return -EINVAL; 949 + 950 + if (hdr->type == TOKTYPE_NON_CCA 951 + && hdr->version == TOKVER_EP11_AES_WITH_HEADER 952 + && is_ep11_keyblob(key + sizeof(struct ep11kblob_header))) { 953 + /* EP11 AES key blob with header */ 954 + if (ep11_check_aes_key_with_hdr(debug_info, 3, key, keylen, 1)) 955 + return -EINVAL; 956 + } else if (hdr->type == TOKTYPE_NON_CCA 957 + && hdr->version == TOKVER_EP11_ECC_WITH_HEADER 958 + && is_ep11_keyblob(key + sizeof(struct ep11kblob_header))) { 959 + /* EP11 ECC key blob with header */ 960 + if (ep11_check_ecc_key_with_hdr(debug_info, 3, key, keylen, 1)) 961 + return -EINVAL; 962 + } else if (hdr->type == TOKTYPE_NON_CCA 963 + && hdr->version == TOKVER_EP11_AES 964 + && is_ep11_keyblob(key)) { 965 + /* EP11 AES key blob with header in session field */ 966 + if (ep11_check_aes_key(debug_info, 3, key, keylen, 1)) 967 + return -EINVAL; 968 + } else if (hdr->type == TOKTYPE_CCA_INTERNAL) { 969 + if (hdr->version == TOKVER_CCA_AES) { 970 + /* CCA AES data key */ 971 + if (keylen != sizeof(struct secaeskeytoken)) 972 + return -EINVAL; 973 + if (cca_check_secaeskeytoken(debug_info, 3, key, 0)) 974 + return -EINVAL; 975 + } else if (hdr->version == TOKVER_CCA_VLSC) { 976 + /* CCA AES cipher key */ 977 + if (keylen < hdr->len || keylen > MAXCCAVLSCTOKENSIZE) 978 + return -EINVAL; 979 + if (cca_check_secaescipherkey(debug_info, 3, key, 0, 1)) 980 + return -EINVAL; 981 + } else { 982 + DEBUG_ERR("%s unknown CCA internal token version %d\n", 983 + __func__, hdr->version); 984 + return -EINVAL; 985 + } 986 + } else if (hdr->type == TOKTYPE_CCA_INTERNAL_PKA) { 987 + /* CCA ECC (private) key */ 988 + if (keylen < sizeof(struct eccprivkeytoken)) 989 + return -EINVAL; 990 + if (cca_check_sececckeytoken(debug_info, 3, key, keylen, 1)) 991 + return -EINVAL; 992 + } else if (hdr->type == TOKTYPE_NON_CCA) { 993 + struct pkey_protkey pkey; 994 + 995 + rc = pkey_nonccatok2pkey(key, keylen, &pkey); 996 + if (rc) 997 + return rc; 998 + memcpy(protkey, pkey.protkey, pkey.len); 999 + *protkeylen = pkey.len; 1000 + *protkeytype = pkey.type; 1001 + return 0; 1002 + } else { 1003 + DEBUG_ERR("%s unknown/unsupported blob type %d\n", 1004 + __func__, hdr->type); 1005 + return -EINVAL; 1006 + } 1007 + 1008 + /* simple try all apqns from the list */ 1009 + for (rc = -ENODEV, i = 0; rc && i < nr_apqns; i++) { 1010 + card = apqns[i].card; 1011 + dom = apqns[i].domain; 1012 + if (hdr->type == TOKTYPE_NON_CCA 1013 + && (hdr->version == TOKVER_EP11_AES_WITH_HEADER 1014 + || hdr->version == TOKVER_EP11_ECC_WITH_HEADER) 1015 + && is_ep11_keyblob(key + sizeof(struct ep11kblob_header))) 1016 + rc = ep11_kblob2protkey(card, dom, key, hdr->len, 1017 + protkey, protkeylen, protkeytype); 1018 + else if (hdr->type == TOKTYPE_NON_CCA 1019 + && hdr->version == TOKVER_EP11_AES 1020 + && is_ep11_keyblob(key)) 1021 + rc = ep11_kblob2protkey(card, dom, key, hdr->len, 1022 + protkey, protkeylen, protkeytype); 1023 + else if (hdr->type == TOKTYPE_CCA_INTERNAL && 1024 + hdr->version == TOKVER_CCA_AES) 1025 + rc = cca_sec2protkey(card, dom, key, protkey, 1026 + protkeylen, protkeytype); 1027 + else if (hdr->type == TOKTYPE_CCA_INTERNAL && 1028 + hdr->version == TOKVER_CCA_VLSC) 1029 + rc = cca_cipher2protkey(card, dom, key, protkey, 1030 + protkeylen, protkeytype); 1031 + else if (hdr->type == TOKTYPE_CCA_INTERNAL_PKA) 1032 + rc = cca_ecc2protkey(card, dom, key, protkey, 1033 + protkeylen, protkeytype); 1034 + else 1035 + return -EINVAL; 1036 + } 1037 + 995 1038 return rc; 996 1039 } 997 1040 ··· 1498 1331 if (copy_to_user(uat, &kat, sizeof(kat))) 1499 1332 rc = -EFAULT; 1500 1333 kfree(apqns); 1334 + break; 1335 + } 1336 + case PKEY_KBLOB2PROTK3: { 1337 + struct pkey_kblob2pkey3 __user *utp = (void __user *) arg; 1338 + struct pkey_kblob2pkey3 ktp; 1339 + struct pkey_apqn *apqns = NULL; 1340 + u32 protkeylen = PROTKEYBLOBBUFSIZE; 1341 + u8 *kkey, *protkey; 1342 + 1343 + if (copy_from_user(&ktp, utp, sizeof(ktp))) 1344 + return -EFAULT; 1345 + apqns = _copy_apqns_from_user(ktp.apqns, ktp.apqn_entries); 1346 + if (IS_ERR(apqns)) 1347 + return PTR_ERR(apqns); 1348 + kkey = _copy_key_from_user(ktp.key, ktp.keylen); 1349 + if (IS_ERR(kkey)) { 1350 + kfree(apqns); 1351 + return PTR_ERR(kkey); 1352 + } 1353 + protkey = kmalloc(protkeylen, GFP_KERNEL); 1354 + if (!protkey) { 1355 + kfree(apqns); 1356 + kfree(kkey); 1357 + return -ENOMEM; 1358 + } 1359 + rc = pkey_keyblob2pkey3(apqns, ktp.apqn_entries, kkey, 1360 + ktp.keylen, &ktp.pkeytype, 1361 + protkey, &protkeylen); 1362 + DEBUG_DBG("%s pkey_keyblob2pkey3()=%d\n", __func__, rc); 1363 + kfree(apqns); 1364 + kfree(kkey); 1365 + if (rc) { 1366 + kfree(protkey); 1367 + break; 1368 + } 1369 + if (ktp.pkey && ktp.pkeylen) { 1370 + if (protkeylen > ktp.pkeylen) { 1371 + kfree(protkey); 1372 + return -EINVAL; 1373 + } 1374 + if (copy_to_user(ktp.pkey, protkey, protkeylen)) { 1375 + kfree(protkey); 1376 + return -EFAULT; 1377 + } 1378 + } 1379 + kfree(protkey); 1380 + ktp.pkeylen = protkeylen; 1381 + if (copy_to_user(utp, &ktp, sizeof(ktp))) 1382 + return -EFAULT; 1501 1383 break; 1502 1384 } 1503 1385 default:
+193
drivers/s390/crypto/zcrypt_ccamisc.c
··· 173 173 EXPORT_SYMBOL(cca_check_secaescipherkey); 174 174 175 175 /* 176 + * Simple check if the token is a valid CCA secure ECC private 177 + * key token. Returns 0 on success or errno value on failure. 178 + */ 179 + int cca_check_sececckeytoken(debug_info_t *dbg, int dbflvl, 180 + const u8 *token, size_t keysize, 181 + int checkcpacfexport) 182 + { 183 + struct eccprivkeytoken *t = (struct eccprivkeytoken *) token; 184 + 185 + #define DBF(...) debug_sprintf_event(dbg, dbflvl, ##__VA_ARGS__) 186 + 187 + if (t->type != TOKTYPE_CCA_INTERNAL_PKA) { 188 + if (dbg) 189 + DBF("%s token check failed, type 0x%02x != 0x%02x\n", 190 + __func__, (int) t->type, TOKTYPE_CCA_INTERNAL_PKA); 191 + return -EINVAL; 192 + } 193 + if (t->len > keysize) { 194 + if (dbg) 195 + DBF("%s token check failed, len %d > keysize %zu\n", 196 + __func__, (int) t->len, keysize); 197 + return -EINVAL; 198 + } 199 + if (t->secid != 0x20) { 200 + if (dbg) 201 + DBF("%s token check failed, secid 0x%02x != 0x20\n", 202 + __func__, (int) t->secid); 203 + return -EINVAL; 204 + } 205 + if (checkcpacfexport && !(t->kutc & 0x01)) { 206 + if (dbg) 207 + DBF("%s token check failed, XPRTCPAC bit is 0\n", 208 + __func__); 209 + return -EINVAL; 210 + } 211 + 212 + #undef DBF 213 + 214 + return 0; 215 + } 216 + EXPORT_SYMBOL(cca_check_sececckeytoken); 217 + 218 + /* 176 219 * Allocate consecutive memory for request CPRB, request param 177 220 * block, reply CPRB and reply param block and fill in values 178 221 * for the common fields. Returns 0 on success or errno value ··· 1339 1296 return rc; 1340 1297 } 1341 1298 EXPORT_SYMBOL(cca_cipher2protkey); 1299 + 1300 + /* 1301 + * Derive protected key from CCA ECC secure private key. 1302 + */ 1303 + int cca_ecc2protkey(u16 cardnr, u16 domain, const u8 *key, 1304 + u8 *protkey, u32 *protkeylen, u32 *protkeytype) 1305 + { 1306 + int rc; 1307 + u8 *mem, *ptr; 1308 + struct CPRBX *preqcblk, *prepcblk; 1309 + struct ica_xcRB xcrb; 1310 + struct aureqparm { 1311 + u8 subfunc_code[2]; 1312 + u16 rule_array_len; 1313 + u8 rule_array[8]; 1314 + struct { 1315 + u16 len; 1316 + u16 tk_blob_len; 1317 + u16 tk_blob_tag; 1318 + u8 tk_blob[66]; 1319 + } vud; 1320 + struct { 1321 + u16 len; 1322 + u16 cca_key_token_len; 1323 + u16 cca_key_token_flags; 1324 + u8 cca_key_token[0]; 1325 + } kb; 1326 + } __packed * preqparm; 1327 + struct aurepparm { 1328 + u8 subfunc_code[2]; 1329 + u16 rule_array_len; 1330 + struct { 1331 + u16 len; 1332 + u16 sublen; 1333 + u16 tag; 1334 + struct cpacfkeyblock { 1335 + u8 version; /* version of this struct */ 1336 + u8 flags[2]; 1337 + u8 algo; 1338 + u8 form; 1339 + u8 pad1[3]; 1340 + u16 keylen; 1341 + u8 key[0]; /* the key (keylen bytes) */ 1342 + u16 keyattrlen; 1343 + u8 keyattr[32]; 1344 + u8 pad2[1]; 1345 + u8 vptype; 1346 + u8 vp[32]; /* verification pattern */ 1347 + } ckb; 1348 + } vud; 1349 + struct { 1350 + u16 len; 1351 + } kb; 1352 + } __packed * prepparm; 1353 + int keylen = ((struct eccprivkeytoken *)key)->len; 1354 + 1355 + /* get already prepared memory for 2 cprbs with param block each */ 1356 + rc = alloc_and_prep_cprbmem(PARMBSIZE, &mem, &preqcblk, &prepcblk); 1357 + if (rc) 1358 + return rc; 1359 + 1360 + /* fill request cprb struct */ 1361 + preqcblk->domain = domain; 1362 + 1363 + /* fill request cprb param block with AU request */ 1364 + preqparm = (struct aureqparm __force *) preqcblk->req_parmb; 1365 + memcpy(preqparm->subfunc_code, "AU", 2); 1366 + preqparm->rule_array_len = 1367 + sizeof(preqparm->rule_array_len) 1368 + + sizeof(preqparm->rule_array); 1369 + memcpy(preqparm->rule_array, "EXPT-SK ", 8); 1370 + /* vud, tk blob */ 1371 + preqparm->vud.len = sizeof(preqparm->vud); 1372 + preqparm->vud.tk_blob_len = sizeof(preqparm->vud.tk_blob) 1373 + + 2 * sizeof(uint16_t); 1374 + preqparm->vud.tk_blob_tag = 0x00C2; 1375 + /* kb, cca token */ 1376 + preqparm->kb.len = keylen + 3 * sizeof(uint16_t); 1377 + preqparm->kb.cca_key_token_len = keylen + 2 * sizeof(uint16_t); 1378 + memcpy(preqparm->kb.cca_key_token, key, keylen); 1379 + /* now fill length of param block into cprb */ 1380 + preqcblk->req_parml = sizeof(struct aureqparm) + keylen; 1381 + 1382 + /* fill xcrb struct */ 1383 + prep_xcrb(&xcrb, cardnr, preqcblk, prepcblk); 1384 + 1385 + /* forward xcrb with request CPRB and reply CPRB to zcrypt dd */ 1386 + rc = zcrypt_send_cprb(&xcrb); 1387 + if (rc) { 1388 + DEBUG_ERR( 1389 + "%s zcrypt_send_cprb (cardnr=%d domain=%d) failed, rc=%d\n", 1390 + __func__, (int) cardnr, (int) domain, rc); 1391 + goto out; 1392 + } 1393 + 1394 + /* check response returncode and reasoncode */ 1395 + if (prepcblk->ccp_rtcode != 0) { 1396 + DEBUG_ERR( 1397 + "%s unwrap secure key failure, card response %d/%d\n", 1398 + __func__, 1399 + (int) prepcblk->ccp_rtcode, 1400 + (int) prepcblk->ccp_rscode); 1401 + rc = -EIO; 1402 + goto out; 1403 + } 1404 + if (prepcblk->ccp_rscode != 0) { 1405 + DEBUG_WARN( 1406 + "%s unwrap secure key warning, card response %d/%d\n", 1407 + __func__, 1408 + (int) prepcblk->ccp_rtcode, 1409 + (int) prepcblk->ccp_rscode); 1410 + } 1411 + 1412 + /* process response cprb param block */ 1413 + ptr = ((u8 *) prepcblk) + sizeof(struct CPRBX); 1414 + prepcblk->rpl_parmb = (u8 __user *) ptr; 1415 + prepparm = (struct aurepparm *) ptr; 1416 + 1417 + /* check the returned keyblock */ 1418 + if (prepparm->vud.ckb.version != 0x02) { 1419 + DEBUG_ERR("%s reply param keyblock version mismatch 0x%02x != 0x02\n", 1420 + __func__, (int) prepparm->vud.ckb.version); 1421 + rc = -EIO; 1422 + goto out; 1423 + } 1424 + if (prepparm->vud.ckb.algo != 0x81) { 1425 + DEBUG_ERR( 1426 + "%s reply param keyblock algo mismatch 0x%02x != 0x81\n", 1427 + __func__, (int) prepparm->vud.ckb.algo); 1428 + rc = -EIO; 1429 + goto out; 1430 + } 1431 + 1432 + /* copy the translated protected key */ 1433 + if (prepparm->vud.ckb.keylen > *protkeylen) { 1434 + DEBUG_ERR("%s prot keylen mismatch %d > buffersize %u\n", 1435 + __func__, prepparm->vud.ckb.keylen, *protkeylen); 1436 + rc = -EIO; 1437 + goto out; 1438 + } 1439 + memcpy(protkey, prepparm->vud.ckb.key, prepparm->vud.ckb.keylen); 1440 + *protkeylen = prepparm->vud.ckb.keylen; 1441 + if (protkeytype) 1442 + *protkeytype = PKEY_KEYTYPE_ECC; 1443 + 1444 + out: 1445 + free_cprbmem(mem, PARMBSIZE, 0); 1446 + return rc; 1447 + } 1448 + EXPORT_SYMBOL(cca_ecc2protkey); 1342 1449 1343 1450 /* 1344 1451 * query cryptographic facility from CCA adapter
+42 -2
drivers/s390/crypto/zcrypt_ccamisc.h
··· 14 14 #include <asm/pkey.h> 15 15 16 16 /* Key token types */ 17 - #define TOKTYPE_NON_CCA 0x00 /* Non-CCA key token */ 18 - #define TOKTYPE_CCA_INTERNAL 0x01 /* CCA internal key token */ 17 + #define TOKTYPE_NON_CCA 0x00 /* Non-CCA key token */ 18 + #define TOKTYPE_CCA_INTERNAL 0x01 /* CCA internal sym key token */ 19 + #define TOKTYPE_CCA_INTERNAL_PKA 0x1f /* CCA internal asym key token */ 19 20 20 21 /* For TOKTYPE_NON_CCA: */ 21 22 #define TOKVER_PROTECTED_KEY 0x01 /* Protected key token */ ··· 94 93 u8 vdata[]; /* variable part data follows */ 95 94 } __packed; 96 95 96 + /* inside view of an CCA secure ECC private key */ 97 + struct eccprivkeytoken { 98 + u8 type; /* 0x1f for internal asym key token */ 99 + u8 version; /* should be 0x00 */ 100 + u16 len; /* total key token length in bytes */ 101 + u8 res1[4]; 102 + u8 secid; /* 0x20 for ECC priv key section marker */ 103 + u8 secver; /* section version */ 104 + u16 seclen; /* section length */ 105 + u8 wtype; /* wrapping method, 0x00 clear, 0x01 AES */ 106 + u8 htype; /* hash method, 0x02 for SHA-256 */ 107 + u8 res2[2]; 108 + u8 kutc; /* key usage and translation control */ 109 + u8 ctype; /* curve type */ 110 + u8 kfs; /* key format and security */ 111 + u8 ksrc; /* key source */ 112 + u16 pbitlen; /* length of prime p in bits */ 113 + u16 ibmadlen; /* IBM associated data length in bytes */ 114 + u64 mkvp; /* master key verification pattern */ 115 + u8 opk[48]; /* encrypted object protection key data */ 116 + u16 adatalen; /* associated data length in bytes */ 117 + u16 fseclen; /* formated section length in bytes */ 118 + u8 more_data[]; /* more data follows */ 119 + } __packed; 120 + 97 121 /* Some defines for the CCA AES cipherkeytoken kmf1 field */ 98 122 #define KMF1_XPRT_SYM 0x8000 99 123 #define KMF1_XPRT_UASY 0x4000 ··· 147 121 int cca_check_secaescipherkey(debug_info_t *dbg, int dbflvl, 148 122 const u8 *token, int keybitsize, 149 123 int checkcpacfexport); 124 + 125 + /* 126 + * Simple check if the token is a valid CCA secure ECC private 127 + * key token. Returns 0 on success or errno value on failure. 128 + */ 129 + int cca_check_sececckeytoken(debug_info_t *dbg, int dbflvl, 130 + const u8 *token, size_t keysize, 131 + int checkcpacfexport); 150 132 151 133 /* 152 134 * Generate (random) CCA AES DATA secure key. ··· 191 157 */ 192 158 int cca_clr2cipherkey(u16 cardnr, u16 domain, u32 keybitsize, u32 keygenflags, 193 159 const u8 *clrkey, u8 *keybuf, size_t *keybufsize); 160 + 161 + /* 162 + * Derive proteced key from CCA ECC secure private key. 163 + */ 164 + int cca_ecc2protkey(u16 cardnr, u16 domain, const u8 *key, 165 + u8 *protkey, u32 *protkeylen, u32 *protkeytype); 194 166 195 167 /* 196 168 * Query cryptographic facility from CCA adapter
+247 -51
drivers/s390/crypto/zcrypt_ep11misc.c
··· 15 15 #include <linux/random.h> 16 16 #include <asm/zcrypt.h> 17 17 #include <asm/pkey.h> 18 + #include <crypto/aes.h> 18 19 19 20 #include "ap_bus.h" 20 21 #include "zcrypt_api.h" ··· 114 113 } 115 114 116 115 /* 117 - * Simple check if the key blob is a valid EP11 secure AES key. 116 + * Simple check if the key blob is a valid EP11 AES key blob with header. 118 117 */ 119 - int ep11_check_aeskeyblob(debug_info_t *dbg, int dbflvl, 120 - const u8 *key, int keybitsize, 121 - int checkcpacfexport) 118 + int ep11_check_aes_key_with_hdr(debug_info_t *dbg, int dbflvl, 119 + const u8 *key, size_t keylen, int checkcpacfexp) 120 + { 121 + struct ep11kblob_header *hdr = (struct ep11kblob_header *) key; 122 + struct ep11keyblob *kb = (struct ep11keyblob *) (key + sizeof(*hdr)); 123 + 124 + #define DBF(...) debug_sprintf_event(dbg, dbflvl, ##__VA_ARGS__) 125 + 126 + if (keylen < sizeof(*hdr) + sizeof(*kb)) { 127 + DBF("%s key check failed, keylen %zu < %zu\n", 128 + __func__, keylen, sizeof(*hdr) + sizeof(*kb)); 129 + return -EINVAL; 130 + } 131 + 132 + if (hdr->type != TOKTYPE_NON_CCA) { 133 + if (dbg) 134 + DBF("%s key check failed, type 0x%02x != 0x%02x\n", 135 + __func__, (int) hdr->type, TOKTYPE_NON_CCA); 136 + return -EINVAL; 137 + } 138 + if (hdr->hver != 0x00) { 139 + if (dbg) 140 + DBF("%s key check failed, header version 0x%02x != 0x00\n", 141 + __func__, (int) hdr->hver); 142 + return -EINVAL; 143 + } 144 + if (hdr->version != TOKVER_EP11_AES_WITH_HEADER) { 145 + if (dbg) 146 + DBF("%s key check failed, version 0x%02x != 0x%02x\n", 147 + __func__, (int) hdr->version, TOKVER_EP11_AES_WITH_HEADER); 148 + return -EINVAL; 149 + } 150 + if (hdr->len > keylen) { 151 + if (dbg) 152 + DBF("%s key check failed, header len %d keylen %zu mismatch\n", 153 + __func__, (int) hdr->len, keylen); 154 + return -EINVAL; 155 + } 156 + if (hdr->len < sizeof(*hdr) + sizeof(*kb)) { 157 + if (dbg) 158 + DBF("%s key check failed, header len %d < %zu\n", 159 + __func__, (int) hdr->len, sizeof(*hdr) + sizeof(*kb)); 160 + return -EINVAL; 161 + } 162 + 163 + if (kb->version != EP11_STRUCT_MAGIC) { 164 + if (dbg) 165 + DBF("%s key check failed, blob magic 0x%04x != 0x%04x\n", 166 + __func__, (int) kb->version, EP11_STRUCT_MAGIC); 167 + return -EINVAL; 168 + } 169 + if (checkcpacfexp && !(kb->attr & EP11_BLOB_PKEY_EXTRACTABLE)) { 170 + if (dbg) 171 + DBF("%s key check failed, PKEY_EXTRACTABLE is off\n", 172 + __func__); 173 + return -EINVAL; 174 + } 175 + 176 + #undef DBF 177 + 178 + return 0; 179 + } 180 + EXPORT_SYMBOL(ep11_check_aes_key_with_hdr); 181 + 182 + /* 183 + * Simple check if the key blob is a valid EP11 ECC key blob with header. 184 + */ 185 + int ep11_check_ecc_key_with_hdr(debug_info_t *dbg, int dbflvl, 186 + const u8 *key, size_t keylen, int checkcpacfexp) 187 + { 188 + struct ep11kblob_header *hdr = (struct ep11kblob_header *) key; 189 + struct ep11keyblob *kb = (struct ep11keyblob *) (key + sizeof(*hdr)); 190 + 191 + #define DBF(...) debug_sprintf_event(dbg, dbflvl, ##__VA_ARGS__) 192 + 193 + if (keylen < sizeof(*hdr) + sizeof(*kb)) { 194 + DBF("%s key check failed, keylen %zu < %zu\n", 195 + __func__, keylen, sizeof(*hdr) + sizeof(*kb)); 196 + return -EINVAL; 197 + } 198 + 199 + if (hdr->type != TOKTYPE_NON_CCA) { 200 + if (dbg) 201 + DBF("%s key check failed, type 0x%02x != 0x%02x\n", 202 + __func__, (int) hdr->type, TOKTYPE_NON_CCA); 203 + return -EINVAL; 204 + } 205 + if (hdr->hver != 0x00) { 206 + if (dbg) 207 + DBF("%s key check failed, header version 0x%02x != 0x00\n", 208 + __func__, (int) hdr->hver); 209 + return -EINVAL; 210 + } 211 + if (hdr->version != TOKVER_EP11_ECC_WITH_HEADER) { 212 + if (dbg) 213 + DBF("%s key check failed, version 0x%02x != 0x%02x\n", 214 + __func__, (int) hdr->version, TOKVER_EP11_ECC_WITH_HEADER); 215 + return -EINVAL; 216 + } 217 + if (hdr->len > keylen) { 218 + if (dbg) 219 + DBF("%s key check failed, header len %d keylen %zu mismatch\n", 220 + __func__, (int) hdr->len, keylen); 221 + return -EINVAL; 222 + } 223 + if (hdr->len < sizeof(*hdr) + sizeof(*kb)) { 224 + if (dbg) 225 + DBF("%s key check failed, header len %d < %zu\n", 226 + __func__, (int) hdr->len, sizeof(*hdr) + sizeof(*kb)); 227 + return -EINVAL; 228 + } 229 + 230 + if (kb->version != EP11_STRUCT_MAGIC) { 231 + if (dbg) 232 + DBF("%s key check failed, blob magic 0x%04x != 0x%04x\n", 233 + __func__, (int) kb->version, EP11_STRUCT_MAGIC); 234 + return -EINVAL; 235 + } 236 + if (checkcpacfexp && !(kb->attr & EP11_BLOB_PKEY_EXTRACTABLE)) { 237 + if (dbg) 238 + DBF("%s key check failed, PKEY_EXTRACTABLE is off\n", 239 + __func__); 240 + return -EINVAL; 241 + } 242 + 243 + #undef DBF 244 + 245 + return 0; 246 + } 247 + EXPORT_SYMBOL(ep11_check_ecc_key_with_hdr); 248 + 249 + /* 250 + * Simple check if the key blob is a valid EP11 AES key blob with 251 + * the header in the session field (old style EP11 AES key). 252 + */ 253 + int ep11_check_aes_key(debug_info_t *dbg, int dbflvl, 254 + const u8 *key, size_t keylen, int checkcpacfexp) 122 255 { 123 256 struct ep11keyblob *kb = (struct ep11keyblob *) key; 124 257 125 258 #define DBF(...) debug_sprintf_event(dbg, dbflvl, ##__VA_ARGS__) 259 + 260 + if (keylen < sizeof(*kb)) { 261 + DBF("%s key check failed, keylen %zu < %zu\n", 262 + __func__, keylen, sizeof(*kb)); 263 + return -EINVAL; 264 + } 126 265 127 266 if (kb->head.type != TOKTYPE_NON_CCA) { 128 267 if (dbg) ··· 276 135 __func__, (int) kb->head.version, TOKVER_EP11_AES); 277 136 return -EINVAL; 278 137 } 138 + if (kb->head.len > keylen) { 139 + if (dbg) 140 + DBF("%s key check failed, header len %d keylen %zu mismatch\n", 141 + __func__, (int) kb->head.len, keylen); 142 + return -EINVAL; 143 + } 144 + if (kb->head.len < sizeof(*kb)) { 145 + if (dbg) 146 + DBF("%s key check failed, header len %d < %zu\n", 147 + __func__, (int) kb->head.len, sizeof(*kb)); 148 + return -EINVAL; 149 + } 150 + 279 151 if (kb->version != EP11_STRUCT_MAGIC) { 280 152 if (dbg) 281 - DBF("%s key check failed, magic 0x%04x != 0x%04x\n", 153 + DBF("%s key check failed, blob magic 0x%04x != 0x%04x\n", 282 154 __func__, (int) kb->version, EP11_STRUCT_MAGIC); 283 155 return -EINVAL; 284 156 } 285 - switch (kb->head.keybitlen) { 286 - case 128: 287 - case 192: 288 - case 256: 289 - break; 290 - default: 157 + if (checkcpacfexp && !(kb->attr & EP11_BLOB_PKEY_EXTRACTABLE)) { 291 158 if (dbg) 292 - DBF("%s key check failed, keybitlen %d invalid\n", 293 - __func__, (int) kb->head.keybitlen); 294 - return -EINVAL; 295 - } 296 - if (keybitsize > 0 && keybitsize != (int) kb->head.keybitlen) { 297 - DBF("%s key check failed, keybitsize %d\n", 298 - __func__, keybitsize); 299 - return -EINVAL; 300 - } 301 - if (checkcpacfexport && !(kb->attr & EP11_BLOB_PKEY_EXTRACTABLE)) { 302 - if (dbg) 303 - DBF("%s key check failed, PKEY_EXTRACTABLE is 0\n", 159 + DBF("%s key check failed, PKEY_EXTRACTABLE is off\n", 304 160 __func__); 305 161 return -EINVAL; 306 162 } 163 + 307 164 #undef DBF 308 165 309 166 return 0; 310 167 } 311 - EXPORT_SYMBOL(ep11_check_aeskeyblob); 168 + EXPORT_SYMBOL(ep11_check_aes_key); 312 169 313 170 /* 314 171 * Allocate and prepare ep11 cprb plus additional payload. ··· 1093 954 u8 data_tag; 1094 955 u8 data_lenfmt; 1095 956 u16 data_len; 1096 - u8 data[512]; 957 + u8 data[1024]; 1097 958 } __packed * rep_pl; 1098 959 struct ep11_cprb *req = NULL, *rep = NULL; 1099 960 struct ep11_target_dev target; ··· 1101 962 struct ep11keyblob *kb; 1102 963 size_t req_pl_size; 1103 964 int api, rc = -ENOMEM; 965 + bool has_header = false; 1104 966 u8 *p; 967 + 968 + /* maybe the session field holds a header with key info */ 969 + kb = (struct ep11keyblob *) key; 970 + if (kb->head.type == TOKTYPE_NON_CCA && 971 + kb->head.version == TOKVER_EP11_AES) { 972 + has_header = true; 973 + keysize = kb->head.len < keysize ? kb->head.len : keysize; 974 + } 1105 975 1106 976 /* request cprb and payload */ 1107 977 req_pl_size = sizeof(struct wk_req_pl) + (iv ? 16 : 0) ··· 1137 989 /* key blob */ 1138 990 p += asn1tag_write(p, 0x04, key, keysize); 1139 991 /* maybe the key argument needs the head data cleaned out */ 1140 - kb = (struct ep11keyblob *)(p - keysize); 1141 - if (kb->head.version == TOKVER_EP11_AES) 992 + if (has_header) { 993 + kb = (struct ep11keyblob *)(p - keysize); 1142 994 memset(&kb->head, 0, sizeof(kb->head)); 995 + } 1143 996 /* empty kek tag */ 1144 997 *p++ = 0x04; 1145 998 *p++ = 0; ··· 1263 1114 } 1264 1115 EXPORT_SYMBOL(ep11_clr2keyblob); 1265 1116 1266 - int ep11_key2protkey(u16 card, u16 dom, const u8 *key, size_t keylen, 1267 - u8 *protkey, u32 *protkeylen, u32 *protkeytype) 1117 + int ep11_kblob2protkey(u16 card, u16 dom, const u8 *keyblob, size_t keybloblen, 1118 + u8 *protkey, u32 *protkeylen, u32 *protkeytype) 1268 1119 { 1269 1120 int rc = -EIO; 1270 1121 u8 *wkbuf = NULL; 1271 - size_t wkbuflen = 256; 1122 + size_t wkbuflen, keylen; 1272 1123 struct wk_info { 1273 1124 u16 version; 1274 1125 u8 res1[16]; ··· 1278 1129 u8 res2[8]; 1279 1130 u8 pkey[0]; 1280 1131 } __packed * wki; 1132 + const u8 *key; 1133 + struct ep11kblob_header *hdr; 1134 + 1135 + /* key with or without header ? */ 1136 + hdr = (struct ep11kblob_header *) keyblob; 1137 + if (hdr->type == TOKTYPE_NON_CCA 1138 + && (hdr->version == TOKVER_EP11_AES_WITH_HEADER 1139 + || hdr->version == TOKVER_EP11_ECC_WITH_HEADER) 1140 + && is_ep11_keyblob(keyblob + sizeof(struct ep11kblob_header))) { 1141 + /* EP11 AES or ECC key with header */ 1142 + key = keyblob + sizeof(struct ep11kblob_header); 1143 + keylen = hdr->len - sizeof(struct ep11kblob_header); 1144 + } else if (hdr->type == TOKTYPE_NON_CCA 1145 + && hdr->version == TOKVER_EP11_AES 1146 + && is_ep11_keyblob(keyblob)) { 1147 + /* EP11 AES key (old style) */ 1148 + key = keyblob; 1149 + keylen = hdr->len; 1150 + } else if (is_ep11_keyblob(keyblob)) { 1151 + /* raw EP11 key blob */ 1152 + key = keyblob; 1153 + keylen = keybloblen; 1154 + } else 1155 + return -EINVAL; 1281 1156 1282 1157 /* alloc temp working buffer */ 1158 + wkbuflen = (keylen + AES_BLOCK_SIZE) & (~(AES_BLOCK_SIZE - 1)); 1283 1159 wkbuf = kmalloc(wkbuflen, GFP_ATOMIC); 1284 1160 if (!wkbuf) 1285 1161 return -ENOMEM; ··· 1321 1147 wki = (struct wk_info *) wkbuf; 1322 1148 1323 1149 /* check struct version and pkey type */ 1324 - if (wki->version != 1 || wki->pkeytype != 1) { 1150 + if (wki->version != 1 || wki->pkeytype < 1 || wki->pkeytype > 5) { 1325 1151 DEBUG_ERR("%s wk info version %d or pkeytype %d mismatch.\n", 1326 1152 __func__, (int) wki->version, (int) wki->pkeytype); 1327 1153 rc = -EIO; 1328 1154 goto out; 1329 1155 } 1330 1156 1331 - /* copy the tanslated protected key */ 1332 - switch (wki->pkeysize) { 1333 - case 16+32: 1334 - /* AES 128 protected key */ 1335 - if (protkeytype) 1336 - *protkeytype = PKEY_KEYTYPE_AES_128; 1157 + /* check protected key type field */ 1158 + switch (wki->pkeytype) { 1159 + case 1: /* AES */ 1160 + switch (wki->pkeysize) { 1161 + case 16+32: 1162 + /* AES 128 protected key */ 1163 + if (protkeytype) 1164 + *protkeytype = PKEY_KEYTYPE_AES_128; 1165 + break; 1166 + case 24+32: 1167 + /* AES 192 protected key */ 1168 + if (protkeytype) 1169 + *protkeytype = PKEY_KEYTYPE_AES_192; 1170 + break; 1171 + case 32+32: 1172 + /* AES 256 protected key */ 1173 + if (protkeytype) 1174 + *protkeytype = PKEY_KEYTYPE_AES_256; 1175 + break; 1176 + default: 1177 + DEBUG_ERR("%s unknown/unsupported AES pkeysize %d\n", 1178 + __func__, (int) wki->pkeysize); 1179 + rc = -EIO; 1180 + goto out; 1181 + } 1337 1182 break; 1338 - case 24+32: 1339 - /* AES 192 protected key */ 1183 + case 3: /* EC-P */ 1184 + case 4: /* EC-ED */ 1185 + case 5: /* EC-BP */ 1340 1186 if (protkeytype) 1341 - *protkeytype = PKEY_KEYTYPE_AES_192; 1187 + *protkeytype = PKEY_KEYTYPE_ECC; 1342 1188 break; 1343 - case 32+32: 1344 - /* AES 256 protected key */ 1345 - if (protkeytype) 1346 - *protkeytype = PKEY_KEYTYPE_AES_256; 1347 - break; 1189 + case 2: /* TDES */ 1348 1190 default: 1349 - DEBUG_ERR("%s unknown/unsupported pkeysize %d\n", 1350 - __func__, (int) wki->pkeysize); 1191 + DEBUG_ERR("%s unknown/unsupported key type %d\n", 1192 + __func__, (int) wki->pkeytype); 1351 1193 rc = -EIO; 1352 1194 goto out; 1353 1195 } 1196 + 1197 + /* copy the tanslated protected key */ 1198 + if (wki->pkeysize > *protkeylen) { 1199 + DEBUG_ERR("%s wk info pkeysize %llu > protkeysize %u\n", 1200 + __func__, wki->pkeysize, *protkeylen); 1201 + rc = -EINVAL; 1202 + goto out; 1203 + } 1354 1204 memcpy(protkey, wki->pkey, wki->pkeysize); 1355 - if (protkeylen) 1356 - *protkeylen = (u32) wki->pkeysize; 1357 - rc = 0; 1205 + *protkeylen = wki->pkeysize; 1358 1206 1359 1207 out: 1360 1208 kfree(wkbuf); 1361 1209 return rc; 1362 1210 } 1363 - EXPORT_SYMBOL(ep11_key2protkey); 1211 + EXPORT_SYMBOL(ep11_kblob2protkey); 1364 1212 1365 1213 int ep11_findcard2(u32 **apqns, u32 *nr_apqns, u16 cardnr, u16 domain, 1366 1214 int minhwtype, int minapi, const u8 *wkvp)
+47 -16
drivers/s390/crypto/zcrypt_ep11misc.h
··· 12 12 #include <asm/zcrypt.h> 13 13 #include <asm/pkey.h> 14 14 15 - #define TOKVER_EP11_AES 0x03 /* EP11 AES key blob */ 16 - 17 15 #define EP11_API_V 4 /* highest known and supported EP11 API version */ 18 - 19 16 #define EP11_STRUCT_MAGIC 0x1234 20 - #define EP11_BLOB_PKEY_EXTRACTABLE 0x200000 17 + #define EP11_BLOB_PKEY_EXTRACTABLE 0x00200000 18 + 19 + /* 20 + * Internal used values for the version field of the key header. 21 + * Should match to the enum pkey_key_type in pkey.h. 22 + */ 23 + #define TOKVER_EP11_AES 0x03 /* EP11 AES key blob (old style) */ 24 + #define TOKVER_EP11_AES_WITH_HEADER 0x06 /* EP11 AES key blob with header */ 25 + #define TOKVER_EP11_ECC_WITH_HEADER 0x07 /* EP11 ECC key blob with header */ 21 26 22 27 /* inside view of an EP11 secure key blob */ 23 28 struct ep11keyblob { 24 29 union { 25 30 u8 session[32]; 31 + /* only used for PKEY_TYPE_EP11: */ 26 32 struct { 27 33 u8 type; /* 0x00 (TOKTYPE_NON_CCA) */ 28 34 u8 res0; /* unused */ 29 35 u16 len; /* total length in bytes of this blob */ 30 - u8 version; /* 0x06 (TOKVER_EP11_AES) */ 36 + u8 version; /* 0x03 (TOKVER_EP11_AES) */ 31 37 u8 res1; /* unused */ 32 38 u16 keybitlen; /* clear key bit len, 0 for unknown */ 33 39 } head; ··· 47 41 u8 mac[32]; 48 42 } __packed; 49 43 44 + /* check ep11 key magic to find out if this is an ep11 key blob */ 45 + static inline bool is_ep11_keyblob(const u8 *key) 46 + { 47 + struct ep11keyblob *kb = (struct ep11keyblob *) key; 48 + 49 + return (kb->version == EP11_STRUCT_MAGIC); 50 + } 51 + 50 52 /* 51 - * Simple check if the key blob is a valid EP11 secure AES key. 52 - * If keybitsize is given, the bitsize of the key is also checked. 53 + * Simple check if the key blob is a valid EP11 AES key blob with header. 53 54 * If checkcpacfexport is enabled, the key is also checked for the 54 55 * attributes needed to export this key for CPACF use. 55 56 * Returns 0 on success or errno value on failure. 56 57 */ 57 - int ep11_check_aeskeyblob(debug_info_t *dbg, int dbflvl, 58 - const u8 *key, int keybitsize, 59 - int checkcpacfexport); 58 + int ep11_check_aes_key_with_hdr(debug_info_t *dbg, int dbflvl, 59 + const u8 *key, size_t keylen, int checkcpacfexp); 60 + 61 + /* 62 + * Simple check if the key blob is a valid EP11 ECC key blob with header. 63 + * If checkcpacfexport is enabled, the key is also checked for the 64 + * attributes needed to export this key for CPACF use. 65 + * Returns 0 on success or errno value on failure. 66 + */ 67 + int ep11_check_ecc_key_with_hdr(debug_info_t *dbg, int dbflvl, 68 + const u8 *key, size_t keylen, int checkcpacfexp); 69 + 70 + /* 71 + * Simple check if the key blob is a valid EP11 AES key blob with 72 + * the header in the session field (old style EP11 AES key). 73 + * If checkcpacfexport is enabled, the key is also checked for the 74 + * attributes needed to export this key for CPACF use. 75 + * Returns 0 on success or errno value on failure. 76 + */ 77 + int ep11_check_aes_key(debug_info_t *dbg, int dbflvl, 78 + const u8 *key, size_t keylen, int checkcpacfexp); 60 79 61 80 /* EP11 card info struct */ 62 81 struct ep11_card_info { ··· 123 92 const u8 *clrkey, u8 *keybuf, size_t *keybufsize); 124 93 125 94 /* 126 - * Derive proteced key from EP11 AES secure key blob. 127 - */ 128 - int ep11_key2protkey(u16 cardnr, u16 domain, const u8 *key, size_t keylen, 129 - u8 *protkey, u32 *protkeylen, u32 *protkeytype); 130 - 131 - /* 132 95 * Build a list of ep11 apqns meeting the following constrains: 133 96 * - apqn is online and is in fact an EP11 apqn 134 97 * - if cardnr is not FFFF only apqns with this cardnr ··· 143 118 */ 144 119 int ep11_findcard2(u32 **apqns, u32 *nr_apqns, u16 cardnr, u16 domain, 145 120 int minhwtype, int minapi, const u8 *wkvp); 121 + 122 + /* 123 + * Derive proteced key from EP11 key blob (AES and ECC keys). 124 + */ 125 + int ep11_kblob2protkey(u16 card, u16 dom, const u8 *key, size_t keylen, 126 + u8 *protkey, u32 *protkeylen, u32 *protkeytype); 146 127 147 128 void zcrypt_ep11misc_exit(void); 148 129