Commit 8fcc231c authored by Harald Freudenberger's avatar Harald Freudenberger Committed by Vasily Gorbik

s390/pkey: Introduce pkey base with handler registry and handler modules

Introduce pkey base kernel code with a simple pkey handler registry.
Regroup the pkey code into these kernel modules:
- pkey is the pkey api supporting the ioctls, sysfs and in-kernel api.
  Also the pkey base code which offers the handler registry and
  handler wrapping invocation functions is integrated there. This
  module is automatically loaded in via CPU feature if the MSA feature
  is available.
- pkey-cca is the CCA related handler code kernel module a offering
  CCA specific implementation for pkey. This module is loaded in
  via MODULE_DEVICE_TABLE when a CEX[4-8] card becomes available.
- pkey-ep11 is the EP11 related handler code kernel module offering an
  EP11 specific implementation for pkey. This module is loaded in via
  MODULE_DEVICE_TABLE when a CEX[4-8] card becomes available.
- pkey-pckmo is the PCKMO related handler code kernel module. This
  module is loaded in via CPU feature if the MSA feature is available,
  but on init a check for availability of the pckmo instruction is
  performed.

The handler modules register via a pkey_handler struct at the pkey
base code and the pkey customer (that is currently the pkey api code
fetches a handler via pkey handler registry functions and calls the
unified handler functions via the pkey base handler functions.

As a result the pkey-cca, pkey-ep11 and pkey-pckmo modules get
independent from each other and it becomes possible to write new
handlers which offer another kind of implementation without implicit
dependencies to other handler implementations and/or kernel device
drivers.

For each of these 4 kernel modules there is an individual Kconfig
entry: CONFIG_PKEY for the base and api, CONFIG_PKEY_CCA for the PKEY
CCA support handler, CONFIG_PKEY_EP11 for the EP11 support handler and
CONFIG_PKEY_PCKMO for the pckmo support. The both CEX related handler
modules (PKEY CCA and PKEY EP11) have a dependency to the zcrypt api
of the zcrypt device driver.
Signed-off-by: default avatarHarald Freudenberger <freude@linux.ibm.com>
Reviewed-by: default avatarHolger Dengler <dengler@linux.ibm.com>
Signed-off-by: default avatarVasily Gorbik <gor@linux.ibm.com>
parent ea88e171
......@@ -797,6 +797,9 @@ CONFIG_CRYPTO_CHACHA_S390=m
CONFIG_CRYPTO_HMAC_S390=m
CONFIG_ZCRYPT=m
CONFIG_PKEY=m
CONFIG_PKEY_CCA=m
CONFIG_PKEY_EP11=m
CONFIG_PKEY_PCKMO=m
CONFIG_CRYPTO_PAES_S390=m
CONFIG_CRYPTO_DEV_VIRTIO=m
CONFIG_SYSTEM_BLACKLIST_KEYRING=y
......
......@@ -784,6 +784,9 @@ CONFIG_CRYPTO_CHACHA_S390=m
CONFIG_CRYPTO_HMAC_S390=m
CONFIG_ZCRYPT=m
CONFIG_PKEY=m
CONFIG_PKEY_CCA=m
CONFIG_PKEY_EP11=m
CONFIG_PKEY_PCKMO=m
CONFIG_CRYPTO_PAES_S390=m
CONFIG_CRYPTO_DEV_VIRTIO=m
CONFIG_SYSTEM_BLACKLIST_KEYRING=y
......
......@@ -50,6 +50,7 @@ enum pkey_key_type {
PKEY_TYPE_CCA_ECC = (__u32) 0x1f,
PKEY_TYPE_EP11_AES = (__u32) 6,
PKEY_TYPE_EP11_ECC = (__u32) 7,
PKEY_TYPE_PROTKEY = (__u32) 8,
};
/* the newer ioctls use a pkey_key_size enum for key size information */
......
......@@ -21,7 +21,7 @@ config CRYPTO_DEV_PADLOCK
(so called VIA PadLock ACE, Advanced Cryptography Engine)
that provides instructions for very fast cryptographic
operations with supported algorithms.
The instructions are used only when the CPU supports them.
Otherwise software encryption is used.
......@@ -78,18 +78,79 @@ config ZCRYPT
config PKEY
tristate "Kernel API for protected key handling"
depends on S390
depends on ZCRYPT
help
With this option enabled the pkey kernel module provides an API
With this option enabled the pkey kernel modules provide an API
for creation and handling of protected keys. Other parts of the
kernel or userspace applications may use these functions.
The protected key support is distributed into:
- A pkey base and API kernel module (pkey.ko) which offers the
infrastructure for the pkey handler kernel modules, the ioctl
and the sysfs API and the in-kernel API to the crypto cipher
implementations using protected key.
- A pkey pckmo kernel module (pkey-pckmo.ko) which is automatically
loaded when pckmo support (that is generation of protected keys
from clear key values) is available.
- A pkey CCA kernel module (pkey-cca.ko) which is automatically
loaded when a CEX crypto card is available.
- A pkey EP11 kernel module (pkey-ep11.ko) which is automatically
loaded when a CEX crypto card is available.
Select this option if you want to enable the kernel and userspace
API for proteced key handling.
API for protected key handling.
config PKEY_CCA
tristate "PKEY CCA support handler"
depends on PKEY
depends on ZCRYPT
help
This is the CCA support handler for deriving protected keys
from CCA (secure) keys. Also this handler provides an alternate
way to make protected keys from clear key values.
The PKEY CCA support handler needs a Crypto Express card (CEX)
in CCA mode.
If you have selected the PKEY option then you should also enable
this option unless you are sure you never need to derive protected
keys from CCA key material.
config PKEY_EP11
tristate "PKEY EP11 support handler"
depends on PKEY
depends on ZCRYPT
help
This is the EP11 support handler for deriving protected keys
from EP11 (secure) keys. Also this handler provides an alternate
way to make protected keys from clear key values.
The PKEY EP11 support handler needs a Crypto Express card (CEX)
in EP11 mode.
If you have selected the PKEY option then you should also enable
this option unless you are sure you never need to derive protected
keys from EP11 key material.
config PKEY_PCKMO
tristate "PKEY PCKMO support handler"
depends on PKEY
help
This is the PCKMO support handler for deriving protected keys
from clear key values via invoking the PCKMO instruction.
The PCKMO instruction can be enabled and disabled in the crypto
settings at the LPAR profile. This handler checks for availability
during initialization and if build as a kernel module unloads
itself if PCKMO is disabled.
The PCKMO way of deriving protected keys from clear key material
is especially used during self test of protected key ciphers like
PAES but the CCA and EP11 handler provide alternate ways to
generate protected keys from clear key values.
Please note that creation of protected keys from secure keys
requires to have at least one CEX card in coprocessor mode
available at runtime.
If you have selected the PKEY option then you should also enable
this option unless you are sure you never need to derive protected
keys from clear key values directly via PCKMO.
config CRYPTO_PAES_S390
tristate "PAES cipher algorithms"
......
......@@ -13,10 +13,22 @@ obj-$(CONFIG_ZCRYPT) += zcrypt.o
# adapter drivers depend on ap.o and zcrypt.o
obj-$(CONFIG_ZCRYPT) += zcrypt_cex4.o
# pkey kernel module
pkey-objs := pkey_api.o pkey_cca.o pkey_ep11.o pkey_pckmo.o pkey_sysfs.o
# pkey base and api module
pkey-objs := pkey_base.o pkey_api.o pkey_sysfs.o
obj-$(CONFIG_PKEY) += pkey.o
# pkey cca handler module
pkey-cca-objs := pkey_cca.o
obj-$(CONFIG_PKEY_CCA) += pkey-cca.o
# pkey ep11 handler module
pkey-ep11-objs := pkey_ep11.o
obj-$(CONFIG_PKEY_EP11) += pkey-ep11.o
# pkey pckmo handler module
pkey-pckmo-objs := pkey_pckmo.o
obj-$(CONFIG_PKEY_PCKMO) += pkey-pckmo.o
# adjunct processor matrix
vfio_ap-objs := vfio_ap_drv.o vfio_ap_ops.o
obj-$(CONFIG_VFIO_AP) += vfio_ap.o
This diff is collapsed.
// SPDX-License-Identifier: GPL-2.0
/*
* pkey base: debug feature, pkey handler registry
*
* Copyright IBM Corp. 2024
*/
#define KMSG_COMPONENT "pkey"
#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
#include <linux/cpufeature.h>
#include <linux/init.h>
#include <linux/list.h>
#include <linux/module.h>
#include <linux/rculist.h>
#include "pkey_base.h"
MODULE_LICENSE("GPL");
MODULE_AUTHOR("IBM Corporation");
MODULE_DESCRIPTION("s390 protected key base and api");
/*
* pkey debug feature
*/
debug_info_t *pkey_dbf_info;
EXPORT_SYMBOL(pkey_dbf_info);
/*
* pkey handler registry
*/
static DEFINE_SPINLOCK(handler_list_write_lock);
static LIST_HEAD(handler_list);
int pkey_handler_register(struct pkey_handler *handler)
{
const struct pkey_handler *h;
if (!handler ||
!handler->is_supported_key ||
!handler->is_supported_keytype)
return -EINVAL;
if (!try_module_get(handler->module))
return -ENXIO;
spin_lock(&handler_list_write_lock);
rcu_read_lock();
list_for_each_entry_rcu(h, &handler_list, list) {
if (h == handler) {
rcu_read_unlock();
spin_unlock(&handler_list_write_lock);
module_put(handler->module);
return -EEXIST;
}
}
rcu_read_unlock();
list_add_rcu(&handler->list, &handler_list);
spin_unlock(&handler_list_write_lock);
synchronize_rcu();
module_put(handler->module);
PKEY_DBF_INFO("%s pkey handler '%s' registered\n", __func__,
handler->name ?: "<no name>");
return 0;
}
EXPORT_SYMBOL(pkey_handler_register);
int pkey_handler_unregister(struct pkey_handler *handler)
{
spin_lock(&handler_list_write_lock);
list_del_rcu(&handler->list);
INIT_LIST_HEAD_RCU(&handler->list);
spin_unlock(&handler_list_write_lock);
synchronize_rcu();
PKEY_DBF_INFO("%s pkey handler '%s' unregistered\n", __func__,
handler->name ?: "<no name>");
return 0;
}
EXPORT_SYMBOL(pkey_handler_unregister);
/*
* Handler invocation functions.
*/
const struct pkey_handler *pkey_handler_get_keybased(const u8 *key, u32 keylen)
{
const struct pkey_handler *h;
rcu_read_lock();
list_for_each_entry_rcu(h, &handler_list, list) {
if (!try_module_get(h->module))
continue;
if (h->is_supported_key(key, keylen)) {
rcu_read_unlock();
return h;
}
module_put(h->module);
}
rcu_read_unlock();
return NULL;
}
EXPORT_SYMBOL(pkey_handler_get_keybased);
const struct pkey_handler *pkey_handler_get_keytypebased(enum pkey_key_type kt)
{
const struct pkey_handler *h;
rcu_read_lock();
list_for_each_entry_rcu(h, &handler_list, list) {
if (!try_module_get(h->module))
continue;
if (h->is_supported_keytype(kt)) {
rcu_read_unlock();
return h;
}
module_put(h->module);
}
rcu_read_unlock();
return NULL;
}
EXPORT_SYMBOL(pkey_handler_get_keytypebased);
void pkey_handler_put(const struct pkey_handler *handler)
{
const struct pkey_handler *h;
if (!handler)
return;
rcu_read_lock();
list_for_each_entry_rcu(h, &handler_list, list) {
if (h == handler) {
module_put(h->module);
break;
}
}
rcu_read_unlock();
}
EXPORT_SYMBOL(pkey_handler_put);
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)
{
const struct pkey_handler *h;
int rc = -ENODEV;
h = pkey_handler_get_keybased(key, keylen);
if (h && h->key_to_protkey) {
rc = h->key_to_protkey(apqns, nr_apqns, key, keylen,
protkey, protkeylen,
protkeytype);
}
pkey_handler_put(h);
return rc;
}
EXPORT_SYMBOL(pkey_handler_key_to_protkey);
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)
{
const struct pkey_handler *h;
int rc = -ENODEV;
h = pkey_handler_get_keytypebased(keysubtype);
if (h && h->gen_key) {
rc = h->gen_key(apqns, nr_apqns, keytype, keysubtype,
keybitsize, flags,
keybuf, keybuflen, keyinfo);
}
pkey_handler_put(h);
return rc;
}
EXPORT_SYMBOL(pkey_handler_gen_key);
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)
{
const struct pkey_handler *h;
int rc = -ENODEV;
h = pkey_handler_get_keytypebased(keysubtype);
if (h && h->clr_to_key) {
rc = h->clr_to_key(apqns, nr_apqns, keytype, keysubtype,
keybitsize, flags, clrkey, clrkeylen,
keybuf, keybuflen, keyinfo);
}
pkey_handler_put(h);
return rc;
}
EXPORT_SYMBOL(pkey_handler_clr_to_key);
int pkey_handler_verify_key(const u8 *key, u32 keylen,
u16 *card, u16 *dom,
u32 *keytype, u32 *keybitsize, u32 *flags)
{
const struct pkey_handler *h;
int rc = -ENODEV;
h = pkey_handler_get_keybased(key, keylen);
if (h && h->verify_key) {
rc = h->verify_key(key, keylen, card, dom,
keytype, keybitsize, flags);
}
pkey_handler_put(h);
return rc;
}
EXPORT_SYMBOL(pkey_handler_verify_key);
int pkey_handler_apqns_for_key(const u8 *key, u32 keylen, u32 flags,
struct pkey_apqn *apqns, size_t *nr_apqns)
{
const struct pkey_handler *h;
int rc = -ENODEV;
h = pkey_handler_get_keybased(key, keylen);
if (h && h->apqns_for_key)
rc = h->apqns_for_key(key, keylen, flags, apqns, nr_apqns);
pkey_handler_put(h);
return rc;
}
EXPORT_SYMBOL(pkey_handler_apqns_for_key);
int pkey_handler_apqns_for_keytype(enum pkey_key_type keysubtype,
u8 cur_mkvp[32], u8 alt_mkvp[32], u32 flags,
struct pkey_apqn *apqns, size_t *nr_apqns)
{
const struct pkey_handler *h;
int rc = -ENODEV;
h = pkey_handler_get_keytypebased(keysubtype);
if (h && h->apqns_for_keytype) {
rc = h->apqns_for_keytype(keysubtype,
cur_mkvp, alt_mkvp, flags,
apqns, nr_apqns);
}
pkey_handler_put(h);
return rc;
}
EXPORT_SYMBOL(pkey_handler_apqns_for_keytype);
/*
* Module init
*/
static int __init pkey_init(void)
{
int rc;
/* init debug feature */
pkey_dbf_info = debug_register("pkey", 1, 1, 5 * sizeof(long));
debug_register_view(pkey_dbf_info, &debug_sprintf_view);
debug_set_level(pkey_dbf_info, 4);
/* the handler registry does not need any init */
rc = pkey_api_init();
if (rc)
debug_unregister(pkey_dbf_info);
return rc;
}
/*
* Module exit
*/
static void __exit pkey_exit(void)
{
pkey_api_exit();
}
module_cpu_feature_match(S390_CPU_FEATURE_MSA, pkey_init);
module_exit(pkey_exit);
......@@ -86,84 +86,84 @@ static inline u32 pkey_aes_bitsize_to_keytype(u32 keybitsize)
}
/*
* pkey_cca.c:
* pkey_api.c:
*/
bool pkey_is_cca_key(const u8 *key, u32 keylen);
bool pkey_is_cca_keytype(enum pkey_key_type);
int pkey_cca_key2protkey(u16 card, u16 dom,
const u8 *key, u32 keylen,
u8 *protkey, u32 *protkeylen, u32 *protkeytype);
int pkey_cca_gen_key(u16 card, u16 dom,
u32 keytype, u32 keysubtype,
u32 keybitsize, u32 flags,
u8 *keybuf, u32 *keybuflen, u32 *_keyinfo);
int pkey_cca_clr2key(u16 card, u16 dom,
u32 keytype, u32 keysubtype,
u32 keybitsize, u32 flags,
const u8 *clrkey, u32 clrkeylen,
u8 *keybuf, u32 *keybuflen, u32 *_keyinfo);
int pkey_cca_verifykey(const u8 *key, u32 keylen,
u16 *card, u16 *dom,
u32 *keytype, u32 *keybitsize, u32 *flags);
int pkey_cca_apqns4key(const u8 *key, u32 keylen, u32 flags,
struct pkey_apqn *apqns, size_t *nr_apqns);
int pkey_cca_apqns4type(enum pkey_key_type ktype,
u8 cur_mkvp[32], u8 alt_mkvp[32], u32 flags,
struct pkey_apqn *apqns, size_t *nr_apqns);
int __init pkey_api_init(void);
void __exit pkey_api_exit(void);
/*
* pkey_ep11.c:
* pkey_sysfs.c:
*/
bool pkey_is_ep11_key(const u8 *key, u32 keylen);
bool pkey_is_ep11_keytype(enum pkey_key_type);
int pkey_ep11_key2protkey(u16 card, u16 dom,
const u8 *key, u32 keylen,
u8 *protkey, u32 *protkeylen, u32 *protkeytype);
int pkey_ep11_gen_key(u16 card, u16 dom,
u32 keytype, u32 keysubtype,
u32 keybitsize, u32 flags,
u8 *keybuf, u32 *keybuflen, u32 *_keyinfo);
int pkey_ep11_clr2key(u16 card, u16 dom,
u32 keytype, u32 keysubtype,
u32 keybitsize, u32 flags,
const u8 *clrkey, u32 clrkeylen,
u8 *keybuf, u32 *keybuflen, u32 *_keyinfo);
int pkey_ep11_verifykey(const u8 *key, u32 keylen,
u16 *card, u16 *dom,
u32 *keytype, u32 *keybitsize, u32 *flags);
int pkey_ep11_apqns4key(const u8 *key, u32 keylen, u32 flags,
struct pkey_apqn *apqns, size_t *nr_apqns);
int pkey_ep11_apqns4type(enum pkey_key_type ktype,
u8 cur_mkvp[32], u8 alt_mkvp[32], u32 flags,
struct pkey_apqn *apqns, size_t *nr_apqns);
extern const struct attribute_group *pkey_attr_groups[];
/*
* pkey_pckmo.c:
* pkey handler registry
*/
bool pkey_is_pckmo_key(const u8 *key, u32 keylen);
int pkey_pckmo_key2protkey(u16 _card, u16 _dom,
const u8 *key, u32 keylen,
u8 *protkey, u32 *protkeylen, u32 *protkeytype);
int pkey_pckmo_gen_key(u16 _card, u16 _dom,
u32 keytype, u32 _keysubtype,
u32 _keybitsize, u32 _flags,
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);
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);
int pkey_pckmo_clr2key(u16 _card, u16 _dom,
u32 keytype, u32 _keysubtype,
u32 _keybitsize, u32 _flags,
const u8 *clrkey, u32 clrkeylen,
u8 *keybuf, u32 *keybuflen, u32 *keyinfo);
int pkey_pckmo_verifykey(const u8 *key, u32 keylen,
u16 *_card, u16 *_dom,
u32 *keytype, u32 *_keybitsize, u32 *_flags);
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);
int (*verify_key)(const u8 *key, u32 keylen,
u16 *card, u16 *dom,
u32 *keytype, u32 *keybitsize, u32 *flags);
int (*apqns_for_key)(const u8 *key, u32 keylen, u32 flags,
struct pkey_apqn *apqns, size_t *nr_apqns);
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);
/* 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);
/*
* pkey_sysfs.c:
* invocation function for the registered pkey handlers
*/
extern const struct attribute_group *pkey_attr_groups[];
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);
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);
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);
int pkey_handler_verify_key(const u8 *key, u32 keylen,
u16 *card, u16 *dom,
u32 *keytype, u32 *keybitsize, u32 *flags);
int pkey_handler_apqns_for_key(const u8 *key, u32 keylen, u32 flags,
struct pkey_apqn *apqns, size_t *nr_apqns);
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);
#endif /* _PKEY_BASE_H_ */
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -8,7 +8,6 @@
#define KMSG_COMPONENT "pkey"
#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
#include <asm/pkey.h>
#include <linux/sysfs.h>
#include "zcrypt_api.h"
......@@ -42,10 +41,10 @@ static ssize_t pkey_protkey_aes_attr_read(u32 keytype, bool is_xts, char *buf,
protkeytoken.keytype = keytype;
protkey.len = sizeof(protkey.protkey);
rc = pkey_pckmo_gen_key(0, 0,
protkeytoken.keytype, 0, 0, 0,
protkey.protkey, &protkey.len,
&protkey.type);
rc = pkey_handler_gen_key(NULL, 0, keytype,
PKEY_TYPE_PROTKEY, 0, 0,
protkey.protkey, &protkey.len,
&protkey.type);
if (rc)
return rc;
......@@ -57,10 +56,10 @@ static ssize_t pkey_protkey_aes_attr_read(u32 keytype, bool is_xts, char *buf,
if (is_xts) {
/* xts needs a second protected key, reuse protkey struct */
protkey.len = sizeof(protkey.protkey);
rc = pkey_pckmo_gen_key(0, 0,
protkeytoken.keytype, 0, 0, 0,
protkey.protkey, &protkey.len,
&protkey.type);
rc = pkey_handler_gen_key(NULL, 0, keytype,
PKEY_TYPE_PROTKEY, 0, 0,
protkey.protkey, &protkey.len,
&protkey.type);
if (rc)
return rc;
......@@ -166,18 +165,18 @@ static ssize_t pkey_ccadata_aes_attr_read(u32 keytype, bool is_xts, char *buf,
return -EINVAL;
buflen = sizeof(seckey->seckey);
rc = pkey_cca_gen_key(-1, -1, keytype,
PKEY_TYPE_CCA_DATA, 0, 0,
seckey->seckey, &buflen, NULL);
rc = pkey_handler_gen_key(NULL, 0, keytype,
PKEY_TYPE_CCA_DATA, 0, 0,
seckey->seckey, &buflen, NULL);
if (rc)
return rc;
if (is_xts) {
seckey++;
buflen = sizeof(seckey->seckey);
rc = pkey_cca_gen_key(-1, -1, keytype,
PKEY_TYPE_CCA_DATA, 0, 0,
seckey->seckey, &buflen, NULL);
rc = pkey_handler_gen_key(NULL, 0, keytype,
PKEY_TYPE_CCA_DATA, 0, 0,
seckey->seckey, &buflen, NULL);
if (rc)
return rc;
......@@ -270,9 +269,7 @@ static ssize_t pkey_ccacipher_aes_attr_read(enum pkey_key_size keybits,
size_t count)
{
u32 keysize = CCACIPHERTOKENSIZE;
struct pkey_apqn *apqns = NULL;
int i, rc, card, dom;
size_t nr_apqns;
int rc;
if (off != 0 || count < CCACIPHERTOKENSIZE)
return -EINVAL;
......@@ -280,51 +277,27 @@ static ssize_t pkey_ccacipher_aes_attr_read(enum pkey_key_size keybits,
if (count < 2 * CCACIPHERTOKENSIZE)
return -EINVAL;
nr_apqns = MAXAPQNSINLIST;
apqns = kmalloc_array(nr_apqns, sizeof(struct pkey_apqn), GFP_KERNEL);
if (!apqns)
return -ENOMEM;
/* build a list of apqns able to generate an cipher key */
rc = pkey_cca_apqns4type(PKEY_TYPE_CCA_CIPHER,
NULL, NULL, 0,
apqns, &nr_apqns);
if (rc) {
kfree(apqns);
return rc;
}
memset(buf, 0, is_xts ? 2 * keysize : keysize);
/* simple try all apqns from the list */
for (i = 0, rc = -ENODEV; rc && i < nr_apqns; i++) {
card = apqns[i].card;
dom = apqns[i].domain;
rc = pkey_cca_gen_key(card, dom,
pkey_aes_bitsize_to_keytype(keybits),
PKEY_TYPE_CCA_CIPHER, keybits, 0,
buf, &keysize, NULL);
}
if (rc) {
kfree(apqns);
rc = pkey_handler_gen_key(NULL, 0,
pkey_aes_bitsize_to_keytype(keybits),
PKEY_TYPE_CCA_CIPHER, keybits, 0,
buf, &keysize, NULL);
if (rc)
return rc;
}
if (is_xts) {
keysize = CCACIPHERTOKENSIZE;
buf += CCACIPHERTOKENSIZE;
rc = pkey_cca_gen_key(card, dom,
pkey_aes_bitsize_to_keytype(keybits),
PKEY_TYPE_CCA_CIPHER, keybits, 0,
buf, &keysize, NULL);
kfree(apqns);
rc = pkey_handler_gen_key(NULL, 0,
pkey_aes_bitsize_to_keytype(keybits),
PKEY_TYPE_CCA_CIPHER, keybits, 0,
buf, &keysize, NULL);
if (rc)
return rc;
return 2 * CCACIPHERTOKENSIZE;
}
kfree(apqns);
return CCACIPHERTOKENSIZE;
}
......@@ -412,9 +385,7 @@ static ssize_t pkey_ep11_aes_attr_read(enum pkey_key_size keybits,
size_t count)
{
u32 keysize = MAXEP11AESKEYBLOBSIZE;
struct pkey_apqn *apqns = NULL;
int i, rc, card, dom;
size_t nr_apqns;
int rc;
if (off != 0 || count < MAXEP11AESKEYBLOBSIZE)
return -EINVAL;
......@@ -422,51 +393,27 @@ static ssize_t pkey_ep11_aes_attr_read(enum pkey_key_size keybits,
if (count < 2 * MAXEP11AESKEYBLOBSIZE)
return -EINVAL;
nr_apqns = MAXAPQNSINLIST;
apqns = kmalloc_array(nr_apqns, sizeof(struct pkey_apqn), GFP_KERNEL);
if (!apqns)
return -ENOMEM;
/* build a list of apqns able to generate an EP11 AES key */
rc = pkey_ep11_apqns4type(PKEY_TYPE_EP11_AES,
NULL, NULL, 0,
apqns, &nr_apqns);
if (rc) {
kfree(apqns);
return rc;
}
memset(buf, 0, is_xts ? 2 * keysize : keysize);
/* simple try all apqns from the list */
for (i = 0, rc = -ENODEV; rc && i < nr_apqns; i++) {
card = apqns[i].card;
dom = apqns[i].domain;
rc = pkey_ep11_gen_key(card, dom,
pkey_aes_bitsize_to_keytype(keybits),
PKEY_TYPE_EP11_AES, keybits, 0,
buf, &keysize, NULL);
}
if (rc) {
kfree(apqns);
rc = pkey_handler_gen_key(NULL, 0,
pkey_aes_bitsize_to_keytype(keybits),
PKEY_TYPE_EP11_AES, keybits, 0,
buf, &keysize, NULL);
if (rc)
return rc;
}
if (is_xts) {
keysize = MAXEP11AESKEYBLOBSIZE;
buf += MAXEP11AESKEYBLOBSIZE;
rc = pkey_ep11_gen_key(card, dom,
pkey_aes_bitsize_to_keytype(keybits),
PKEY_TYPE_EP11_AES, keybits, 0,
buf, &keysize, NULL);
kfree(apqns);
rc = pkey_handler_gen_key(NULL, 0,
pkey_aes_bitsize_to_keytype(keybits),
PKEY_TYPE_EP11_AES, keybits, 0,
buf, &keysize, NULL);
if (rc)
return rc;
return 2 * MAXEP11AESKEYBLOBSIZE;
}
kfree(apqns);
return MAXEP11AESKEYBLOBSIZE;
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment