Contributors: 4
Author Tokens Token Proportion Commits Commit Proportion
Harald Freudenberger 918 88.87% 21 80.77%
Ingo Franzki 111 10.75% 3 11.54%
Martin Schwidefsky 3 0.29% 1 3.85%
Gustavo A. R. Silva 1 0.10% 1 3.85%
Total 1033 26


/* SPDX-License-Identifier: GPL-2.0+ */
/*
 * Copyright IBM Corp. 2024
 *
 * Pkey base: debug feature, defines and structs
 * common to all pkey code.
 */

#ifndef _PKEY_BASE_H_
#define _PKEY_BASE_H_

#include <linux/types.h>
#include <asm/debug.h>
#include <asm/pkey.h>

/*
 * pkey debug feature
 */

extern debug_info_t *pkey_dbf_info;

#define PKEY_DBF_INFO(...) debug_sprintf_event(pkey_dbf_info, 5, ##__VA_ARGS__)
#define PKEY_DBF_WARN(...) debug_sprintf_event(pkey_dbf_info, 4, ##__VA_ARGS__)
#define PKEY_DBF_ERR(...)  debug_sprintf_event(pkey_dbf_info, 3, ##__VA_ARGS__)

/*
 * common defines and common structs
 */

#define KEYBLOBBUFSIZE 8192	/* key buffer size used for internal processing */
#define MINKEYBLOBBUFSIZE (sizeof(struct keytoken_header))
#define PROTKEYBLOBBUFSIZE 256	/* protected key buffer size used internal */
#define MAXAPQNSINLIST 64	/* max 64 apqns within a apqn list */
#define AES_WK_VP_SIZE 32	/* Size of WK VP block appended to a prot key */

/* inside view of a generic protected key token */
struct protkeytoken {
	u8  type;     /* 0x00 for PAES specific key tokens */
	u8  res0[3];
	u8  version;  /* should be 0x01 for protected key token */
	u8  res1[3];
	u32 keytype;  /* key type, one of the PKEY_KEYTYPE values */
	u32 len;      /* bytes actually stored in protkey[] */
	u8  protkey[]; /* the protected key blob */
} __packed;

/* inside view of a protected AES key token */
struct protaeskeytoken {
	u8  type;     /* 0x00 for PAES specific key tokens */
	u8  res0[3];
	u8  version;  /* should be 0x01 for protected key token */
	u8  res1[3];
	u32 keytype;  /* key type, one of the PKEY_KEYTYPE values */
	u32 len;      /* bytes actually stored in protkey[] */
	u8  protkey[MAXPROTKEYSIZE]; /* the protected key blob */
} __packed;

/* inside view of a clear key token (type 0x00 version 0x02) */
struct clearkeytoken {
	u8  type;	/* 0x00 for PAES specific key tokens */
	u8  res0[3];
	u8  version;	/* 0x02 for clear key token */
	u8  res1[3];
	u32 keytype;	/* key type, one of the PKEY_KEYTYPE_* values */
	u32 len;	/* bytes actually stored in clearkey[] */
	u8  clearkey[]; /* clear key value */
} __packed;

/* helper function which translates the PKEY_KEYTYPE_AES_* to their keysize */
static inline u32 pkey_keytype_aes_to_size(u32 keytype)
{
	switch (keytype) {
	case PKEY_KEYTYPE_AES_128:
		return 16;
	case PKEY_KEYTYPE_AES_192:
		return 24;
	case PKEY_KEYTYPE_AES_256:
		return 32;
	default:
		return 0;
	}
}

/* helper function which translates AES key bit size into PKEY_KEYTYPE_AES_* */
static inline u32 pkey_aes_bitsize_to_keytype(u32 keybitsize)
{
	switch (keybitsize) {
	case 128:
		return PKEY_KEYTYPE_AES_128;
	case 192:
		return PKEY_KEYTYPE_AES_192;
	case 256:
		return PKEY_KEYTYPE_AES_256;
	default:
		return 0;
	}
}

/*
 * helper function which translates the PKEY_KEYTYPE_*
 * to the protected key size minus the WK VP length
 */
static inline u32 pkey_keytype_to_size(u32 keytype)
{
	switch (keytype) {
	case PKEY_KEYTYPE_AES_128:
		return 16;
	case PKEY_KEYTYPE_AES_192:
		return 24;
	case PKEY_KEYTYPE_AES_256:
		return 32;
	case PKEY_KEYTYPE_ECC_P256:
		return 32;
	case PKEY_KEYTYPE_ECC_P384:
		return 48;
	case PKEY_KEYTYPE_ECC_P521:
		return 80;
	case PKEY_KEYTYPE_ECC_ED25519:
		return 32;
	case PKEY_KEYTYPE_ECC_ED448:
		return 54;
	case PKEY_KEYTYPE_AES_XTS_128:
		return 32;
	case PKEY_KEYTYPE_AES_XTS_256:
		return 64;
	case PKEY_KEYTYPE_HMAC_512:
		return 64;
	case PKEY_KEYTYPE_HMAC_1024:
		return 128;
	default:
		return 0;
	}
}

/*
 * pkey_api.c:
 */
int __init pkey_api_init(void);
void __exit pkey_api_exit(void);

/*
 * pkey_sysfs.c:
 */

extern const struct attribute_group *pkey_attr_groups[];

/*
 * pkey handler registry
 */

struct pkey_handler {
	struct module *module;
	const char *name;
	/*
	 * is_supported_key() and is_supported_keytype() are called
	 * within an rcu_read_lock() scope and thus must not sleep!
	 */
	bool (*is_supported_key)(const u8 *key, u32 keylen);
	bool (*is_supported_keytype)(enum pkey_key_type);
	int (*key_to_protkey)(const struct pkey_apqn *apqns, size_t nr_apqns,
			      const u8 *key, u32 keylen,
			      u8 *protkey, u32 *protkeylen, u32 *protkeytype,
			      u32 xflags);
	int (*slowpath_key_to_protkey)(const struct pkey_apqn *apqns,
				       size_t nr_apqns,
				       const u8 *key, u32 keylen,
				       u8 *protkey, u32 *protkeylen,
				       u32 *protkeytype, u32 xflags);
	int (*gen_key)(const struct pkey_apqn *apqns, size_t nr_apqns,
		       u32 keytype, u32 keysubtype,
		       u32 keybitsize, u32 flags,
		       u8 *keybuf, u32 *keybuflen, u32 *keyinfo, u32 xflags);
	int (*clr_to_key)(const struct pkey_apqn *apqns, size_t nr_apqns,
			  u32 keytype, u32 keysubtype,
			  u32 keybitsize, u32 flags,
			  const u8 *clrkey, u32 clrkeylen,
			  u8 *keybuf, u32 *keybuflen, u32 *keyinfo, u32 xflags);
	int (*verify_key)(const u8 *key, u32 keylen,
			  u16 *card, u16 *dom,
			  u32 *keytype, u32 *keybitsize, u32 *flags,
			  u32 xflags);
	int (*apqns_for_key)(const u8 *key, u32 keylen, u32 flags,
			     struct pkey_apqn *apqns, size_t *nr_apqns,
			     u32 xflags);
	int (*apqns_for_keytype)(enum pkey_key_type ktype,
				 u8 cur_mkvp[32], u8 alt_mkvp[32], u32 flags,
				 struct pkey_apqn *apqns, size_t *nr_apqns,
				 u32 xflags);
	/* used internal by pkey base */
	struct list_head list;
};

int pkey_handler_register(struct pkey_handler *handler);
int pkey_handler_unregister(struct pkey_handler *handler);

/*
 * invocation function for the registered pkey handlers
 */

const struct pkey_handler *pkey_handler_get_keybased(const u8 *key, u32 keylen);
const struct pkey_handler *pkey_handler_get_keytypebased(enum pkey_key_type kt);
void pkey_handler_put(const struct pkey_handler *handler);

int pkey_handler_key_to_protkey(const struct pkey_apqn *apqns, size_t nr_apqns,
				const u8 *key, u32 keylen,
				u8 *protkey, u32 *protkeylen, u32 *protkeytype,
				u32 xflags);
int pkey_handler_slowpath_key_to_protkey(const struct pkey_apqn *apqns,
					 size_t nr_apqns,
					 const u8 *key, u32 keylen,
					 u8 *protkey, u32 *protkeylen,
					 u32 *protkeytype, u32 xflags);
int pkey_handler_gen_key(const struct pkey_apqn *apqns, size_t nr_apqns,
			 u32 keytype, u32 keysubtype,
			 u32 keybitsize, u32 flags,
			 u8 *keybuf, u32 *keybuflen, u32 *keyinfo, u32 xflags);
int pkey_handler_clr_to_key(const struct pkey_apqn *apqns, size_t nr_apqns,
			    u32 keytype, u32 keysubtype,
			    u32 keybitsize, u32 flags,
			    const u8 *clrkey, u32 clrkeylen,
			    u8 *keybuf, u32 *keybuflen, u32 *keyinfo,
			    u32 xflags);
int pkey_handler_verify_key(const u8 *key, u32 keylen,
			    u16 *card, u16 *dom,
			    u32 *keytype, u32 *keybitsize, u32 *flags,
			    u32 xflags);
int pkey_handler_apqns_for_key(const u8 *key, u32 keylen, u32 flags,
			       struct pkey_apqn *apqns, size_t *nr_apqns,
			       u32 xflags);
int pkey_handler_apqns_for_keytype(enum pkey_key_type ktype,
				   u8 cur_mkvp[32], u8 alt_mkvp[32], u32 flags,
				   struct pkey_apqn *apqns, size_t *nr_apqns,
				   u32 xflags);

/*
 * Unconditional try to load all handler modules
 */
void pkey_handler_request_modules(void);

#endif /* _PKEY_BASE_H_ */