s390/pkey: Support new xflag PKEY_XFLAG_NOCLEARKEY

Introduce a new xflag PKEY_XFLAG_NOCLEARKEY which when given refuses
the conversion of "clear key tokens" to protected key material.

Some algorithms (PAES, PHMAC) have the need to construct "clear key
tokens" to be used during selftest. But in general these algorithms
should only support clear key material for testing purpose. So now the
algorithm implementation can signal via xflag PKEY_XFLAG_NOCLEARKEY
that a conversion of clear key material to protected key is not
acceptable and thus the pkey layer (usually one of the handler
modules) refuses clear key material with -EINVAL.

Signed-off-by: Harald Freudenberger <freude@linux.ibm.com>
Reviewed-by: Holger Dengler <dengler@linux.ibm.com>
Reviewed-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
This commit is contained in:
Harald Freudenberger 2026-01-15 13:00:24 +01:00 committed by Herbert Xu
parent cf0840cc7f
commit 2dfca61119
4 changed files with 26 additions and 4 deletions

View file

@ -21,7 +21,8 @@
* @param keylen size of the key blob in bytes
* @param protkey pointer to buffer receiving the protected key
* @param xflags additional execution flags (see PKEY_XFLAG_* definitions below)
* As of now the only supported flag is PKEY_XFLAG_NOMEMALLOC.
* As of now the only supported flags are PKEY_XFLAG_NOMEMALLOC
* and PKEY_XFLAG_NOCLEARKEY.
* @return 0 on success, negative errno value on failure
*/
int pkey_key2protkey(const u8 *key, u32 keylen,
@ -38,4 +39,9 @@ int pkey_key2protkey(const u8 *key, u32 keylen,
*/
#define PKEY_XFLAG_NOMEMALLOC 0x0001
/*
* Do not accept a clear key token as source for a protected key.
*/
#define PKEY_XFLAG_NOCLEARKEY 0x0002
#endif /* _KAPI_PKEY_H */

View file

@ -390,6 +390,11 @@ static int cca_clr2key(const struct pkey_apqn *apqns, size_t nr_apqns,
int i, len, rc;
u32 xflags;
if (pflags & PKEY_XFLAG_NOCLEARKEY) {
PKEY_DBF_ERR("%s clear key but xflag NOCLEARKEY\n", __func__);
return -EINVAL;
}
xflags = pflags & PKEY_XFLAG_NOMEMALLOC ? ZCRYPT_XFLAG_NOMEMALLOC : 0;
/* check keytype, subtype, clrkeylen, keybitsize */

View file

@ -358,6 +358,11 @@ static int ep11_clr2key(const struct pkey_apqn *apqns, size_t nr_apqns,
int i, len, rc;
u32 xflags;
if (pflags & PKEY_XFLAG_NOCLEARKEY) {
PKEY_DBF_ERR("%s clear key but xflag NOCLEARKEY\n", __func__);
return -EINVAL;
}
xflags = pflags & PKEY_XFLAG_NOMEMALLOC ? ZCRYPT_XFLAG_NOMEMALLOC : 0;
/* check keytype, subtype, clrkeylen, keybitsize */

View file

@ -215,7 +215,8 @@ out:
}
static int pckmo_key2protkey(const u8 *key, u32 keylen,
u8 *protkey, u32 *protkeylen, u32 *protkeytype)
u8 *protkey, u32 *protkeylen, u32 *protkeytype,
u32 xflags)
{
struct keytoken_header *hdr = (struct keytoken_header *)key;
int rc = -EINVAL;
@ -266,6 +267,11 @@ static int pckmo_key2protkey(const u8 *key, u32 keylen,
struct clearkeytoken *t = (struct clearkeytoken *)key;
u32 keysize;
if (xflags & PKEY_XFLAG_NOCLEARKEY) {
PKEY_DBF_ERR("%s clear key token but xflag NOCLEARKEY\n",
__func__);
goto out;
}
if (keylen < sizeof(*t) ||
keylen < sizeof(*t) + t->len)
goto out;
@ -406,10 +412,10 @@ static int pkey_pckmo_key2protkey(const struct pkey_apqn *_apqns,
size_t _nr_apqns,
const u8 *key, u32 keylen,
u8 *protkey, u32 *protkeylen, u32 *keyinfo,
u32 _xflags __always_unused)
u32 xflags)
{
return pckmo_key2protkey(key, keylen,
protkey, protkeylen, keyinfo);
protkey, protkeylen, keyinfo, xflags);
}
static int pkey_pckmo_gen_key(const struct pkey_apqn *_apqns, size_t _nr_apqns,