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