162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0+ */ 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * Copyright IBM Corp. 2019 462306a36Sopenharmony_ci * Author(s): Harald Freudenberger <freude@linux.ibm.com> 562306a36Sopenharmony_ci * 662306a36Sopenharmony_ci * Collection of EP11 misc functions used by zcrypt and pkey 762306a36Sopenharmony_ci */ 862306a36Sopenharmony_ci 962306a36Sopenharmony_ci#ifndef _ZCRYPT_EP11MISC_H_ 1062306a36Sopenharmony_ci#define _ZCRYPT_EP11MISC_H_ 1162306a36Sopenharmony_ci 1262306a36Sopenharmony_ci#include <asm/zcrypt.h> 1362306a36Sopenharmony_ci#include <asm/pkey.h> 1462306a36Sopenharmony_ci 1562306a36Sopenharmony_ci#define EP11_API_V1 1 /* min EP11 API, default if no higher api required */ 1662306a36Sopenharmony_ci#define EP11_API_V4 4 /* supported EP11 API for the ep11misc cprbs */ 1762306a36Sopenharmony_ci#define EP11_API_V6 6 /* min EP11 API for some cprbs in SE environment */ 1862306a36Sopenharmony_ci#define EP11_STRUCT_MAGIC 0x1234 1962306a36Sopenharmony_ci#define EP11_BLOB_PKEY_EXTRACTABLE 0x00200000 2062306a36Sopenharmony_ci 2162306a36Sopenharmony_ci/* 2262306a36Sopenharmony_ci * Internal used values for the version field of the key header. 2362306a36Sopenharmony_ci * Should match to the enum pkey_key_type in pkey.h. 2462306a36Sopenharmony_ci */ 2562306a36Sopenharmony_ci#define TOKVER_EP11_AES 0x03 /* EP11 AES key blob (old style) */ 2662306a36Sopenharmony_ci#define TOKVER_EP11_AES_WITH_HEADER 0x06 /* EP11 AES key blob with header */ 2762306a36Sopenharmony_ci#define TOKVER_EP11_ECC_WITH_HEADER 0x07 /* EP11 ECC key blob with header */ 2862306a36Sopenharmony_ci 2962306a36Sopenharmony_ci/* inside view of an EP11 secure key blob */ 3062306a36Sopenharmony_cistruct ep11keyblob { 3162306a36Sopenharmony_ci union { 3262306a36Sopenharmony_ci u8 session[32]; 3362306a36Sopenharmony_ci /* only used for PKEY_TYPE_EP11: */ 3462306a36Sopenharmony_ci struct ep11kblob_header head; 3562306a36Sopenharmony_ci }; 3662306a36Sopenharmony_ci u8 wkvp[16]; /* wrapping key verification pattern */ 3762306a36Sopenharmony_ci u64 attr; /* boolean key attributes */ 3862306a36Sopenharmony_ci u64 mode; /* mode bits */ 3962306a36Sopenharmony_ci u16 version; /* 0x1234, EP11_STRUCT_MAGIC */ 4062306a36Sopenharmony_ci u8 iv[14]; 4162306a36Sopenharmony_ci u8 encrypted_key_data[144]; 4262306a36Sopenharmony_ci u8 mac[32]; 4362306a36Sopenharmony_ci} __packed; 4462306a36Sopenharmony_ci 4562306a36Sopenharmony_ci/* check ep11 key magic to find out if this is an ep11 key blob */ 4662306a36Sopenharmony_cistatic inline bool is_ep11_keyblob(const u8 *key) 4762306a36Sopenharmony_ci{ 4862306a36Sopenharmony_ci struct ep11keyblob *kb = (struct ep11keyblob *)key; 4962306a36Sopenharmony_ci 5062306a36Sopenharmony_ci return (kb->version == EP11_STRUCT_MAGIC); 5162306a36Sopenharmony_ci} 5262306a36Sopenharmony_ci 5362306a36Sopenharmony_ci/* 5462306a36Sopenharmony_ci * For valid ep11 keyblobs, returns a reference to the wrappingkey verification 5562306a36Sopenharmony_ci * pattern. Otherwise NULL. 5662306a36Sopenharmony_ci */ 5762306a36Sopenharmony_ciconst u8 *ep11_kb_wkvp(const u8 *kblob, size_t kbloblen); 5862306a36Sopenharmony_ci 5962306a36Sopenharmony_ci/* 6062306a36Sopenharmony_ci * Simple check if the key blob is a valid EP11 AES key blob with header. 6162306a36Sopenharmony_ci * If checkcpacfexport is enabled, the key is also checked for the 6262306a36Sopenharmony_ci * attributes needed to export this key for CPACF use. 6362306a36Sopenharmony_ci * Returns 0 on success or errno value on failure. 6462306a36Sopenharmony_ci */ 6562306a36Sopenharmony_ciint ep11_check_aes_key_with_hdr(debug_info_t *dbg, int dbflvl, 6662306a36Sopenharmony_ci const u8 *key, size_t keylen, int checkcpacfexp); 6762306a36Sopenharmony_ci 6862306a36Sopenharmony_ci/* 6962306a36Sopenharmony_ci * Simple check if the key blob is a valid EP11 ECC key blob with header. 7062306a36Sopenharmony_ci * If checkcpacfexport is enabled, the key is also checked for the 7162306a36Sopenharmony_ci * attributes needed to export this key for CPACF use. 7262306a36Sopenharmony_ci * Returns 0 on success or errno value on failure. 7362306a36Sopenharmony_ci */ 7462306a36Sopenharmony_ciint ep11_check_ecc_key_with_hdr(debug_info_t *dbg, int dbflvl, 7562306a36Sopenharmony_ci const u8 *key, size_t keylen, int checkcpacfexp); 7662306a36Sopenharmony_ci 7762306a36Sopenharmony_ci/* 7862306a36Sopenharmony_ci * Simple check if the key blob is a valid EP11 AES key blob with 7962306a36Sopenharmony_ci * the header in the session field (old style EP11 AES key). 8062306a36Sopenharmony_ci * If checkcpacfexport is enabled, the key is also checked for the 8162306a36Sopenharmony_ci * attributes needed to export this key for CPACF use. 8262306a36Sopenharmony_ci * Returns 0 on success or errno value on failure. 8362306a36Sopenharmony_ci */ 8462306a36Sopenharmony_ciint ep11_check_aes_key(debug_info_t *dbg, int dbflvl, 8562306a36Sopenharmony_ci const u8 *key, size_t keylen, int checkcpacfexp); 8662306a36Sopenharmony_ci 8762306a36Sopenharmony_ci/* EP11 card info struct */ 8862306a36Sopenharmony_cistruct ep11_card_info { 8962306a36Sopenharmony_ci u32 API_ord_nr; /* API ordinal number */ 9062306a36Sopenharmony_ci u16 FW_version; /* Firmware major and minor version */ 9162306a36Sopenharmony_ci char serial[16]; /* serial number string (16 ascii, no 0x00 !) */ 9262306a36Sopenharmony_ci u64 op_mode; /* card operational mode(s) */ 9362306a36Sopenharmony_ci}; 9462306a36Sopenharmony_ci 9562306a36Sopenharmony_ci/* EP11 domain info struct */ 9662306a36Sopenharmony_cistruct ep11_domain_info { 9762306a36Sopenharmony_ci char cur_wk_state; /* '0' invalid, '1' valid */ 9862306a36Sopenharmony_ci char new_wk_state; /* '0' empty, '1' uncommitted, '2' committed */ 9962306a36Sopenharmony_ci u8 cur_wkvp[32]; /* current wrapping key verification pattern */ 10062306a36Sopenharmony_ci u8 new_wkvp[32]; /* new wrapping key verification pattern */ 10162306a36Sopenharmony_ci u64 op_mode; /* domain operational mode(s) */ 10262306a36Sopenharmony_ci}; 10362306a36Sopenharmony_ci 10462306a36Sopenharmony_ci/* 10562306a36Sopenharmony_ci * Provide information about an EP11 card. 10662306a36Sopenharmony_ci */ 10762306a36Sopenharmony_ciint ep11_get_card_info(u16 card, struct ep11_card_info *info, int verify); 10862306a36Sopenharmony_ci 10962306a36Sopenharmony_ci/* 11062306a36Sopenharmony_ci * Provide information about a domain within an EP11 card. 11162306a36Sopenharmony_ci */ 11262306a36Sopenharmony_ciint ep11_get_domain_info(u16 card, u16 domain, struct ep11_domain_info *info); 11362306a36Sopenharmony_ci 11462306a36Sopenharmony_ci/* 11562306a36Sopenharmony_ci * Generate (random) EP11 AES secure key. 11662306a36Sopenharmony_ci */ 11762306a36Sopenharmony_ciint ep11_genaeskey(u16 card, u16 domain, u32 keybitsize, u32 keygenflags, 11862306a36Sopenharmony_ci u8 *keybuf, size_t *keybufsize, u32 keybufver); 11962306a36Sopenharmony_ci 12062306a36Sopenharmony_ci/* 12162306a36Sopenharmony_ci * Generate EP11 AES secure key with given clear key value. 12262306a36Sopenharmony_ci */ 12362306a36Sopenharmony_ciint ep11_clr2keyblob(u16 cardnr, u16 domain, u32 keybitsize, u32 keygenflags, 12462306a36Sopenharmony_ci const u8 *clrkey, u8 *keybuf, size_t *keybufsize, 12562306a36Sopenharmony_ci u32 keytype); 12662306a36Sopenharmony_ci 12762306a36Sopenharmony_ci/* 12862306a36Sopenharmony_ci * Build a list of ep11 apqns meeting the following constrains: 12962306a36Sopenharmony_ci * - apqn is online and is in fact an EP11 apqn 13062306a36Sopenharmony_ci * - if cardnr is not FFFF only apqns with this cardnr 13162306a36Sopenharmony_ci * - if domain is not FFFF only apqns with this domainnr 13262306a36Sopenharmony_ci * - if minhwtype > 0 only apqns with hwtype >= minhwtype 13362306a36Sopenharmony_ci * - if minapi > 0 only apqns with API_ord_nr >= minapi 13462306a36Sopenharmony_ci * - if wkvp != NULL only apqns where the wkvp (EP11_WKVPLEN bytes) matches 13562306a36Sopenharmony_ci * to the first EP11_WKVPLEN bytes of the wkvp of the current wrapping 13662306a36Sopenharmony_ci * key for this domain. When a wkvp is given there will always be a re-fetch 13762306a36Sopenharmony_ci * of the domain info for the potential apqn - so this triggers an request 13862306a36Sopenharmony_ci * reply to each apqn eligible. 13962306a36Sopenharmony_ci * The array of apqn entries is allocated with kmalloc and returned in *apqns; 14062306a36Sopenharmony_ci * the number of apqns stored into the list is returned in *nr_apqns. One apqn 14162306a36Sopenharmony_ci * entry is simple a 32 bit value with 16 bit cardnr and 16 bit domain nr and 14262306a36Sopenharmony_ci * may be casted to struct pkey_apqn. The return value is either 0 for success 14362306a36Sopenharmony_ci * or a negative errno value. If no apqn meeting the criteria is found, 14462306a36Sopenharmony_ci * -ENODEV is returned. 14562306a36Sopenharmony_ci */ 14662306a36Sopenharmony_ciint ep11_findcard2(u32 **apqns, u32 *nr_apqns, u16 cardnr, u16 domain, 14762306a36Sopenharmony_ci int minhwtype, int minapi, const u8 *wkvp); 14862306a36Sopenharmony_ci 14962306a36Sopenharmony_ci/* 15062306a36Sopenharmony_ci * Derive proteced key from EP11 key blob (AES and ECC keys). 15162306a36Sopenharmony_ci */ 15262306a36Sopenharmony_ciint ep11_kblob2protkey(u16 card, u16 dom, const u8 *key, size_t keylen, 15362306a36Sopenharmony_ci u8 *protkey, u32 *protkeylen, u32 *protkeytype); 15462306a36Sopenharmony_ci 15562306a36Sopenharmony_civoid zcrypt_ep11misc_exit(void); 15662306a36Sopenharmony_ci 15762306a36Sopenharmony_ci#endif /* _ZCRYPT_EP11MISC_H_ */ 158