18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0+ */ 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * Copyright IBM Corp. 2019 48c2ecf20Sopenharmony_ci * Author(s): Harald Freudenberger <freude@linux.ibm.com> 58c2ecf20Sopenharmony_ci * 68c2ecf20Sopenharmony_ci * Collection of EP11 misc functions used by zcrypt and pkey 78c2ecf20Sopenharmony_ci */ 88c2ecf20Sopenharmony_ci 98c2ecf20Sopenharmony_ci#ifndef _ZCRYPT_EP11MISC_H_ 108c2ecf20Sopenharmony_ci#define _ZCRYPT_EP11MISC_H_ 118c2ecf20Sopenharmony_ci 128c2ecf20Sopenharmony_ci#include <asm/zcrypt.h> 138c2ecf20Sopenharmony_ci#include <asm/pkey.h> 148c2ecf20Sopenharmony_ci 158c2ecf20Sopenharmony_ci#define EP11_API_V 4 /* highest known and supported EP11 API version */ 168c2ecf20Sopenharmony_ci#define EP11_STRUCT_MAGIC 0x1234 178c2ecf20Sopenharmony_ci#define EP11_BLOB_PKEY_EXTRACTABLE 0x00200000 188c2ecf20Sopenharmony_ci 198c2ecf20Sopenharmony_ci/* 208c2ecf20Sopenharmony_ci * Internal used values for the version field of the key header. 218c2ecf20Sopenharmony_ci * Should match to the enum pkey_key_type in pkey.h. 228c2ecf20Sopenharmony_ci */ 238c2ecf20Sopenharmony_ci#define TOKVER_EP11_AES 0x03 /* EP11 AES key blob (old style) */ 248c2ecf20Sopenharmony_ci#define TOKVER_EP11_AES_WITH_HEADER 0x06 /* EP11 AES key blob with header */ 258c2ecf20Sopenharmony_ci#define TOKVER_EP11_ECC_WITH_HEADER 0x07 /* EP11 ECC key blob with header */ 268c2ecf20Sopenharmony_ci 278c2ecf20Sopenharmony_ci/* inside view of an EP11 secure key blob */ 288c2ecf20Sopenharmony_cistruct ep11keyblob { 298c2ecf20Sopenharmony_ci union { 308c2ecf20Sopenharmony_ci u8 session[32]; 318c2ecf20Sopenharmony_ci /* only used for PKEY_TYPE_EP11: */ 328c2ecf20Sopenharmony_ci struct ep11kblob_header head; 338c2ecf20Sopenharmony_ci }; 348c2ecf20Sopenharmony_ci u8 wkvp[16]; /* wrapping key verification pattern */ 358c2ecf20Sopenharmony_ci u64 attr; /* boolean key attributes */ 368c2ecf20Sopenharmony_ci u64 mode; /* mode bits */ 378c2ecf20Sopenharmony_ci u16 version; /* 0x1234, EP11_STRUCT_MAGIC */ 388c2ecf20Sopenharmony_ci u8 iv[14]; 398c2ecf20Sopenharmony_ci u8 encrypted_key_data[144]; 408c2ecf20Sopenharmony_ci u8 mac[32]; 418c2ecf20Sopenharmony_ci} __packed; 428c2ecf20Sopenharmony_ci 438c2ecf20Sopenharmony_ci/* check ep11 key magic to find out if this is an ep11 key blob */ 448c2ecf20Sopenharmony_cistatic inline bool is_ep11_keyblob(const u8 *key) 458c2ecf20Sopenharmony_ci{ 468c2ecf20Sopenharmony_ci struct ep11keyblob *kb = (struct ep11keyblob *) key; 478c2ecf20Sopenharmony_ci 488c2ecf20Sopenharmony_ci return (kb->version == EP11_STRUCT_MAGIC); 498c2ecf20Sopenharmony_ci} 508c2ecf20Sopenharmony_ci 518c2ecf20Sopenharmony_ci/* 528c2ecf20Sopenharmony_ci * Simple check if the key blob is a valid EP11 AES key blob with header. 538c2ecf20Sopenharmony_ci * If checkcpacfexport is enabled, the key is also checked for the 548c2ecf20Sopenharmony_ci * attributes needed to export this key for CPACF use. 558c2ecf20Sopenharmony_ci * Returns 0 on success or errno value on failure. 568c2ecf20Sopenharmony_ci */ 578c2ecf20Sopenharmony_ciint ep11_check_aes_key_with_hdr(debug_info_t *dbg, int dbflvl, 588c2ecf20Sopenharmony_ci const u8 *key, size_t keylen, int checkcpacfexp); 598c2ecf20Sopenharmony_ci 608c2ecf20Sopenharmony_ci/* 618c2ecf20Sopenharmony_ci * Simple check if the key blob is a valid EP11 ECC key blob with header. 628c2ecf20Sopenharmony_ci * If checkcpacfexport is enabled, the key is also checked for the 638c2ecf20Sopenharmony_ci * attributes needed to export this key for CPACF use. 648c2ecf20Sopenharmony_ci * Returns 0 on success or errno value on failure. 658c2ecf20Sopenharmony_ci */ 668c2ecf20Sopenharmony_ciint ep11_check_ecc_key_with_hdr(debug_info_t *dbg, int dbflvl, 678c2ecf20Sopenharmony_ci const u8 *key, size_t keylen, int checkcpacfexp); 688c2ecf20Sopenharmony_ci 698c2ecf20Sopenharmony_ci/* 708c2ecf20Sopenharmony_ci * Simple check if the key blob is a valid EP11 AES key blob with 718c2ecf20Sopenharmony_ci * the header in the session field (old style EP11 AES key). 728c2ecf20Sopenharmony_ci * If checkcpacfexport is enabled, the key is also checked for the 738c2ecf20Sopenharmony_ci * attributes needed to export this key for CPACF use. 748c2ecf20Sopenharmony_ci * Returns 0 on success or errno value on failure. 758c2ecf20Sopenharmony_ci */ 768c2ecf20Sopenharmony_ciint ep11_check_aes_key(debug_info_t *dbg, int dbflvl, 778c2ecf20Sopenharmony_ci const u8 *key, size_t keylen, int checkcpacfexp); 788c2ecf20Sopenharmony_ci 798c2ecf20Sopenharmony_ci/* EP11 card info struct */ 808c2ecf20Sopenharmony_cistruct ep11_card_info { 818c2ecf20Sopenharmony_ci u32 API_ord_nr; /* API ordinal number */ 828c2ecf20Sopenharmony_ci u16 FW_version; /* Firmware major and minor version */ 838c2ecf20Sopenharmony_ci char serial[16]; /* serial number string (16 ascii, no 0x00 !) */ 848c2ecf20Sopenharmony_ci u64 op_mode; /* card operational mode(s) */ 858c2ecf20Sopenharmony_ci}; 868c2ecf20Sopenharmony_ci 878c2ecf20Sopenharmony_ci/* EP11 domain info struct */ 888c2ecf20Sopenharmony_cistruct ep11_domain_info { 898c2ecf20Sopenharmony_ci char cur_wk_state; /* '0' invalid, '1' valid */ 908c2ecf20Sopenharmony_ci char new_wk_state; /* '0' empty, '1' uncommitted, '2' committed */ 918c2ecf20Sopenharmony_ci u8 cur_wkvp[32]; /* current wrapping key verification pattern */ 928c2ecf20Sopenharmony_ci u8 new_wkvp[32]; /* new wrapping key verification pattern */ 938c2ecf20Sopenharmony_ci u64 op_mode; /* domain operational mode(s) */ 948c2ecf20Sopenharmony_ci}; 958c2ecf20Sopenharmony_ci 968c2ecf20Sopenharmony_ci/* 978c2ecf20Sopenharmony_ci * Provide information about an EP11 card. 988c2ecf20Sopenharmony_ci */ 998c2ecf20Sopenharmony_ciint ep11_get_card_info(u16 card, struct ep11_card_info *info, int verify); 1008c2ecf20Sopenharmony_ci 1018c2ecf20Sopenharmony_ci/* 1028c2ecf20Sopenharmony_ci * Provide information about a domain within an EP11 card. 1038c2ecf20Sopenharmony_ci */ 1048c2ecf20Sopenharmony_ciint ep11_get_domain_info(u16 card, u16 domain, struct ep11_domain_info *info); 1058c2ecf20Sopenharmony_ci 1068c2ecf20Sopenharmony_ci/* 1078c2ecf20Sopenharmony_ci * Generate (random) EP11 AES secure key. 1088c2ecf20Sopenharmony_ci */ 1098c2ecf20Sopenharmony_ciint ep11_genaeskey(u16 card, u16 domain, u32 keybitsize, u32 keygenflags, 1108c2ecf20Sopenharmony_ci u8 *keybuf, size_t *keybufsize); 1118c2ecf20Sopenharmony_ci 1128c2ecf20Sopenharmony_ci/* 1138c2ecf20Sopenharmony_ci * Generate EP11 AES secure key with given clear key value. 1148c2ecf20Sopenharmony_ci */ 1158c2ecf20Sopenharmony_ciint ep11_clr2keyblob(u16 cardnr, u16 domain, u32 keybitsize, u32 keygenflags, 1168c2ecf20Sopenharmony_ci const u8 *clrkey, u8 *keybuf, size_t *keybufsize); 1178c2ecf20Sopenharmony_ci 1188c2ecf20Sopenharmony_ci/* 1198c2ecf20Sopenharmony_ci * Build a list of ep11 apqns meeting the following constrains: 1208c2ecf20Sopenharmony_ci * - apqn is online and is in fact an EP11 apqn 1218c2ecf20Sopenharmony_ci * - if cardnr is not FFFF only apqns with this cardnr 1228c2ecf20Sopenharmony_ci * - if domain is not FFFF only apqns with this domainnr 1238c2ecf20Sopenharmony_ci * - if minhwtype > 0 only apqns with hwtype >= minhwtype 1248c2ecf20Sopenharmony_ci * - if minapi > 0 only apqns with API_ord_nr >= minapi 1258c2ecf20Sopenharmony_ci * - if wkvp != NULL only apqns where the wkvp (EP11_WKVPLEN bytes) matches 1268c2ecf20Sopenharmony_ci * to the first EP11_WKVPLEN bytes of the wkvp of the current wrapping 1278c2ecf20Sopenharmony_ci * key for this domain. When a wkvp is given there will aways be a re-fetch 1288c2ecf20Sopenharmony_ci * of the domain info for the potential apqn - so this triggers an request 1298c2ecf20Sopenharmony_ci * reply to each apqn eligible. 1308c2ecf20Sopenharmony_ci * The array of apqn entries is allocated with kmalloc and returned in *apqns; 1318c2ecf20Sopenharmony_ci * the number of apqns stored into the list is returned in *nr_apqns. One apqn 1328c2ecf20Sopenharmony_ci * entry is simple a 32 bit value with 16 bit cardnr and 16 bit domain nr and 1338c2ecf20Sopenharmony_ci * may be casted to struct pkey_apqn. The return value is either 0 for success 1348c2ecf20Sopenharmony_ci * or a negative errno value. If no apqn meeting the criterias is found, 1358c2ecf20Sopenharmony_ci * -ENODEV is returned. 1368c2ecf20Sopenharmony_ci */ 1378c2ecf20Sopenharmony_ciint ep11_findcard2(u32 **apqns, u32 *nr_apqns, u16 cardnr, u16 domain, 1388c2ecf20Sopenharmony_ci int minhwtype, int minapi, const u8 *wkvp); 1398c2ecf20Sopenharmony_ci 1408c2ecf20Sopenharmony_ci/* 1418c2ecf20Sopenharmony_ci * Derive proteced key from EP11 key blob (AES and ECC keys). 1428c2ecf20Sopenharmony_ci */ 1438c2ecf20Sopenharmony_ciint ep11_kblob2protkey(u16 card, u16 dom, const u8 *key, size_t keylen, 1448c2ecf20Sopenharmony_ci u8 *protkey, u32 *protkeylen, u32 *protkeytype); 1458c2ecf20Sopenharmony_ci 1468c2ecf20Sopenharmony_civoid zcrypt_ep11misc_exit(void); 1478c2ecf20Sopenharmony_ci 1488c2ecf20Sopenharmony_ci#endif /* _ZCRYPT_EP11MISC_H_ */ 149