root/drivers/s390/crypto/pkey_base.h
/* 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_ */