mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-08-27 11:19:37 +00:00
![Harald Freudenberger](/assets/img/avatar_default.png)
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>
155 lines
5.5 KiB
C
155 lines
5.5 KiB
C
/* SPDX-License-Identifier: GPL-2.0+ */
|
|
/*
|
|
* Copyright IBM Corp. 2019
|
|
* Author(s): Harald Freudenberger <freude@linux.ibm.com>
|
|
*
|
|
* Collection of EP11 misc functions used by zcrypt and pkey
|
|
*/
|
|
|
|
#ifndef _ZCRYPT_EP11MISC_H_
|
|
#define _ZCRYPT_EP11MISC_H_
|
|
|
|
#include <asm/zcrypt.h>
|
|
#include <asm/pkey.h>
|
|
|
|
#define EP11_API_V 4 /* highest known and supported EP11 API version */
|
|
#define EP11_STRUCT_MAGIC 0x1234
|
|
#define EP11_BLOB_PKEY_EXTRACTABLE 0x00200000
|
|
|
|
/*
|
|
* Internal used values for the version field of the key header.
|
|
* Should match to the enum pkey_key_type in pkey.h.
|
|
*/
|
|
#define TOKVER_EP11_AES 0x03 /* EP11 AES key blob (old style) */
|
|
#define TOKVER_EP11_AES_WITH_HEADER 0x06 /* EP11 AES key blob with header */
|
|
#define TOKVER_EP11_ECC_WITH_HEADER 0x07 /* EP11 ECC key blob with header */
|
|
|
|
/* inside view of an EP11 secure key blob */
|
|
struct ep11keyblob {
|
|
union {
|
|
u8 session[32];
|
|
/* only used for PKEY_TYPE_EP11: */
|
|
struct {
|
|
u8 type; /* 0x00 (TOKTYPE_NON_CCA) */
|
|
u8 res0; /* unused */
|
|
u16 len; /* total length in bytes of this blob */
|
|
u8 version; /* 0x03 (TOKVER_EP11_AES) */
|
|
u8 res1; /* unused */
|
|
u16 keybitlen; /* clear key bit len, 0 for unknown */
|
|
} head;
|
|
};
|
|
u8 wkvp[16]; /* wrapping key verification pattern */
|
|
u64 attr; /* boolean key attributes */
|
|
u64 mode; /* mode bits */
|
|
u16 version; /* 0x1234, EP11_STRUCT_MAGIC */
|
|
u8 iv[14];
|
|
u8 encrypted_key_data[144];
|
|
u8 mac[32];
|
|
} __packed;
|
|
|
|
/* check ep11 key magic to find out if this is an ep11 key blob */
|
|
static inline bool is_ep11_keyblob(const u8 *key)
|
|
{
|
|
struct ep11keyblob *kb = (struct ep11keyblob *) key;
|
|
|
|
return (kb->version == EP11_STRUCT_MAGIC);
|
|
}
|
|
|
|
/*
|
|
* Simple check if the key blob is a valid EP11 AES key blob with header.
|
|
* If checkcpacfexport is enabled, the key is also checked for the
|
|
* attributes needed to export this key for CPACF use.
|
|
* Returns 0 on success or errno value on failure.
|
|
*/
|
|
int ep11_check_aes_key_with_hdr(debug_info_t *dbg, int dbflvl,
|
|
const u8 *key, size_t keylen, int checkcpacfexp);
|
|
|
|
/*
|
|
* Simple check if the key blob is a valid EP11 ECC key blob with header.
|
|
* If checkcpacfexport is enabled, the key is also checked for the
|
|
* attributes needed to export this key for CPACF use.
|
|
* Returns 0 on success or errno value on failure.
|
|
*/
|
|
int ep11_check_ecc_key_with_hdr(debug_info_t *dbg, int dbflvl,
|
|
const u8 *key, size_t keylen, int checkcpacfexp);
|
|
|
|
/*
|
|
* Simple check if the key blob is a valid EP11 AES key blob with
|
|
* the header in the session field (old style EP11 AES key).
|
|
* If checkcpacfexport is enabled, the key is also checked for the
|
|
* attributes needed to export this key for CPACF use.
|
|
* Returns 0 on success or errno value on failure.
|
|
*/
|
|
int ep11_check_aes_key(debug_info_t *dbg, int dbflvl,
|
|
const u8 *key, size_t keylen, int checkcpacfexp);
|
|
|
|
/* EP11 card info struct */
|
|
struct ep11_card_info {
|
|
u32 API_ord_nr; /* API ordinal number */
|
|
u16 FW_version; /* Firmware major and minor version */
|
|
char serial[16]; /* serial number string (16 ascii, no 0x00 !) */
|
|
u64 op_mode; /* card operational mode(s) */
|
|
};
|
|
|
|
/* EP11 domain info struct */
|
|
struct ep11_domain_info {
|
|
char cur_wk_state; /* '0' invalid, '1' valid */
|
|
char new_wk_state; /* '0' empty, '1' uncommitted, '2' committed */
|
|
u8 cur_wkvp[32]; /* current wrapping key verification pattern */
|
|
u8 new_wkvp[32]; /* new wrapping key verification pattern */
|
|
u64 op_mode; /* domain operational mode(s) */
|
|
};
|
|
|
|
/*
|
|
* Provide information about an EP11 card.
|
|
*/
|
|
int ep11_get_card_info(u16 card, struct ep11_card_info *info, int verify);
|
|
|
|
/*
|
|
* Provide information about a domain within an EP11 card.
|
|
*/
|
|
int ep11_get_domain_info(u16 card, u16 domain, struct ep11_domain_info *info);
|
|
|
|
/*
|
|
* Generate (random) EP11 AES secure key.
|
|
*/
|
|
int ep11_genaeskey(u16 card, u16 domain, u32 keybitsize, u32 keygenflags,
|
|
u8 *keybuf, size_t *keybufsize);
|
|
|
|
/*
|
|
* Generate EP11 AES secure key with given clear key value.
|
|
*/
|
|
int ep11_clr2keyblob(u16 cardnr, u16 domain, u32 keybitsize, u32 keygenflags,
|
|
const u8 *clrkey, u8 *keybuf, size_t *keybufsize);
|
|
|
|
/*
|
|
* Build a list of ep11 apqns meeting the following constrains:
|
|
* - apqn is online and is in fact an EP11 apqn
|
|
* - if cardnr is not FFFF only apqns with this cardnr
|
|
* - if domain is not FFFF only apqns with this domainnr
|
|
* - if minhwtype > 0 only apqns with hwtype >= minhwtype
|
|
* - if minapi > 0 only apqns with API_ord_nr >= minapi
|
|
* - if wkvp != NULL only apqns where the wkvp (EP11_WKVPLEN bytes) matches
|
|
* to the first EP11_WKVPLEN bytes of the wkvp of the current wrapping
|
|
* key for this domain. When a wkvp is given there will aways be a re-fetch
|
|
* of the domain info for the potential apqn - so this triggers an request
|
|
* reply to each apqn eligible.
|
|
* The array of apqn entries is allocated with kmalloc and returned in *apqns;
|
|
* the number of apqns stored into the list is returned in *nr_apqns. One apqn
|
|
* entry is simple a 32 bit value with 16 bit cardnr and 16 bit domain nr and
|
|
* may be casted to struct pkey_apqn. The return value is either 0 for success
|
|
* or a negative errno value. If no apqn meeting the criterias is found,
|
|
* -ENODEV is returned.
|
|
*/
|
|
int ep11_findcard2(u32 **apqns, u32 *nr_apqns, u16 cardnr, u16 domain,
|
|
int minhwtype, int minapi, const u8 *wkvp);
|
|
|
|
/*
|
|
* Derive proteced key from EP11 key blob (AES and ECC keys).
|
|
*/
|
|
int ep11_kblob2protkey(u16 card, u16 dom, const u8 *key, size_t keylen,
|
|
u8 *protkey, u32 *protkeylen, u32 *protkeytype);
|
|
|
|
void zcrypt_ep11misc_exit(void);
|
|
|
|
#endif /* _ZCRYPT_EP11MISC_H_ */
|