mirror of
https://github.com/torvalds/linux.git
synced 2026-03-08 06:04:44 +01:00
crypto: s390/phmac - Refuse clear key material by default
This patch exploits the new xflag PKEY_XFLAG_NOCLEARKEY from the pkey
layer. So now by default the phmac refuses the use of clear key
material ("clear key tokens") in the setkey function with
-EINVAL.
With a new kernel module parameter "clrkey" this behavior can be
controlled. By default clrkey is 'N' but for testing purpose on module
load a true value (1, 'Y') may be given to accept clear key tokens.
Note that during selftest clear keys are always used and thus the
xflag PKEY_XFLAG_NOCLEARKEY is NOT set as long as the algorithm is in
a larval state indicated by crypto_ahash_tested() returning false.
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:
parent
2dfca61119
commit
452770a4fa
1 changed files with 20 additions and 9 deletions
|
|
@ -23,6 +23,10 @@
|
|||
static struct crypto_engine *phmac_crypto_engine;
|
||||
#define MAX_QLEN 10
|
||||
|
||||
static bool pkey_clrkey_allowed;
|
||||
module_param_named(clrkey, pkey_clrkey_allowed, bool, 0444);
|
||||
MODULE_PARM_DESC(clrkey, "Allow clear key material (default N)");
|
||||
|
||||
/*
|
||||
* A simple hash walk helper
|
||||
*/
|
||||
|
|
@ -311,10 +315,14 @@ static inline int phmac_tfm_ctx_setkey(struct phmac_tfm_ctx *tfm_ctx,
|
|||
* This function may sleep - don't call in non-sleeping context.
|
||||
*/
|
||||
static inline int convert_key(const u8 *key, unsigned int keylen,
|
||||
struct phmac_protkey *pk)
|
||||
struct phmac_protkey *pk, bool tested)
|
||||
{
|
||||
u32 xflags = PKEY_XFLAG_NOMEMALLOC;
|
||||
int rc, i;
|
||||
|
||||
if (tested && !pkey_clrkey_allowed)
|
||||
xflags |= PKEY_XFLAG_NOCLEARKEY;
|
||||
|
||||
pk->len = sizeof(pk->protkey);
|
||||
|
||||
/*
|
||||
|
|
@ -328,7 +336,7 @@ static inline int convert_key(const u8 *key, unsigned int keylen,
|
|||
}
|
||||
rc = pkey_key2protkey(key, keylen,
|
||||
pk->protkey, &pk->len, &pk->type,
|
||||
PKEY_XFLAG_NOMEMALLOC);
|
||||
xflags);
|
||||
}
|
||||
|
||||
out:
|
||||
|
|
@ -350,7 +358,7 @@ out:
|
|||
* unnecessary additional conversion but never to invalid data on the
|
||||
* hash operation.
|
||||
*/
|
||||
static int phmac_convert_key(struct phmac_tfm_ctx *tfm_ctx)
|
||||
static int phmac_convert_key(struct phmac_tfm_ctx *tfm_ctx, bool tested)
|
||||
{
|
||||
struct phmac_protkey pk;
|
||||
int rc;
|
||||
|
|
@ -359,7 +367,7 @@ static int phmac_convert_key(struct phmac_tfm_ctx *tfm_ctx)
|
|||
tfm_ctx->pk_state = PK_STATE_CONVERT_IN_PROGRESS;
|
||||
spin_unlock_bh(&tfm_ctx->pk_lock);
|
||||
|
||||
rc = convert_key(tfm_ctx->keybuf, tfm_ctx->keylen, &pk);
|
||||
rc = convert_key(tfm_ctx->keybuf, tfm_ctx->keylen, &pk, tested);
|
||||
|
||||
/* update context */
|
||||
spin_lock_bh(&tfm_ctx->pk_lock);
|
||||
|
|
@ -404,6 +412,7 @@ static int phmac_kmac_update(struct ahash_request *req, bool maysleep)
|
|||
struct kmac_sha2_ctx *ctx = &req_ctx->kmac_ctx;
|
||||
struct hash_walk_helper *hwh = &req_ctx->hwh;
|
||||
unsigned int bs = crypto_ahash_blocksize(tfm);
|
||||
bool tested = crypto_ahash_tested(tfm);
|
||||
unsigned int offset, k, n;
|
||||
int rc = 0;
|
||||
|
||||
|
|
@ -444,7 +453,7 @@ static int phmac_kmac_update(struct ahash_request *req, bool maysleep)
|
|||
rc = -EKEYEXPIRED;
|
||||
goto out;
|
||||
}
|
||||
rc = phmac_convert_key(tfm_ctx);
|
||||
rc = phmac_convert_key(tfm_ctx, tested);
|
||||
if (rc)
|
||||
goto out;
|
||||
spin_lock_bh(&tfm_ctx->pk_lock);
|
||||
|
|
@ -480,7 +489,7 @@ static int phmac_kmac_update(struct ahash_request *req, bool maysleep)
|
|||
rc = -EKEYEXPIRED;
|
||||
goto out;
|
||||
}
|
||||
rc = phmac_convert_key(tfm_ctx);
|
||||
rc = phmac_convert_key(tfm_ctx, tested);
|
||||
if (rc)
|
||||
goto out;
|
||||
spin_lock_bh(&tfm_ctx->pk_lock);
|
||||
|
|
@ -517,6 +526,7 @@ static int phmac_kmac_final(struct ahash_request *req, bool maysleep)
|
|||
struct kmac_sha2_ctx *ctx = &req_ctx->kmac_ctx;
|
||||
unsigned int ds = crypto_ahash_digestsize(tfm);
|
||||
unsigned int bs = crypto_ahash_blocksize(tfm);
|
||||
bool tested = crypto_ahash_tested(tfm);
|
||||
unsigned int k, n;
|
||||
int rc = 0;
|
||||
|
||||
|
|
@ -537,7 +547,7 @@ static int phmac_kmac_final(struct ahash_request *req, bool maysleep)
|
|||
rc = -EKEYEXPIRED;
|
||||
goto out;
|
||||
}
|
||||
rc = phmac_convert_key(tfm_ctx);
|
||||
rc = phmac_convert_key(tfm_ctx, tested);
|
||||
if (rc)
|
||||
goto out;
|
||||
spin_lock_bh(&tfm_ctx->pk_lock);
|
||||
|
|
@ -741,11 +751,12 @@ static int phmac_setkey(struct crypto_ahash *tfm,
|
|||
struct phmac_tfm_ctx *tfm_ctx = crypto_ahash_ctx(tfm);
|
||||
unsigned int ds = crypto_ahash_digestsize(tfm);
|
||||
unsigned int bs = crypto_ahash_blocksize(tfm);
|
||||
bool tested = crypto_ahash_tested(tfm);
|
||||
unsigned int tmpkeylen;
|
||||
u8 *tmpkey = NULL;
|
||||
int rc = 0;
|
||||
|
||||
if (!crypto_ahash_tested(tfm)) {
|
||||
if (!tested) {
|
||||
/*
|
||||
* selftest running: key is a raw hmac clear key and needs
|
||||
* to get embedded into a 'clear key token' in order to have
|
||||
|
|
@ -770,7 +781,7 @@ static int phmac_setkey(struct crypto_ahash *tfm,
|
|||
goto out;
|
||||
|
||||
/* convert raw key into protected key */
|
||||
rc = phmac_convert_key(tfm_ctx);
|
||||
rc = phmac_convert_key(tfm_ctx, tested);
|
||||
if (rc)
|
||||
goto out;
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue