All of lore.kernel.org
 help / color / mirror / Atom feed
From: Harald Freudenberger <freude@linux.ibm.com>
To: herbert@gondor.apana.org.au, dengler@linux.ibm.com,
	ifranzki@linux.ibm.com
Cc: linux-crypto@vger.kernel.org, linux-s390@vger.kernel.org,
	fcallies@linux.ibm.com
Subject: [PATCH v11 5/6] s390/crypto: Add selftest support for phmac
Date: Thu, 22 May 2025 10:57:54 +0200	[thread overview]
Message-ID: <20250522085755.40732-6-freude@linux.ibm.com> (raw)
In-Reply-To: <20250522085755.40732-1-freude@linux.ibm.com>

Add key preparation code in case of selftest running to the phmac
setkey function:

As long as the CRYPTO_ALG_TESTED flag is not set, all setkey()
invocations are assumed to carry sheer hmac clear key values and thus
need some preparation to work with the phmac implementation. Thus it
is possible to use the already available hmac test vectors implemented
in the testmanager to test the phmac code.

When the CRYPTO_ALG_TESTED flag is set (after larval state) the phmac
code assumes the key material is a blob digestible by the pkey kernel
module which converts the blob into a working key for the phmac code.

Signed-off-by: Harald Freudenberger <freude@linux.ibm.com>
---
 arch/s390/crypto/phmac_s390.c | 143 ++++++++++++++++++++++++++++++++++
 1 file changed, 143 insertions(+)

diff --git a/arch/s390/crypto/phmac_s390.c b/arch/s390/crypto/phmac_s390.c
index b61454dedf0a..b1ca1fcbb927 100644
--- a/arch/s390/crypto/phmac_s390.c
+++ b/arch/s390/crypto/phmac_s390.c
@@ -176,6 +176,114 @@ struct phmac_req_ctx {
 	bool final;
 };
 
+/*
+ * Pkey 'token' struct used to derive a protected key value from a clear key.
+ */
+struct hmac_clrkey_token {
+	u8  type;
+	u8  res0[3];
+	u8  version;
+	u8  res1[3];
+	u32 keytype;
+	u32 len;
+	u8 key[];
+} __packed;
+
+static int hash_key(const u8 *in, unsigned int inlen,
+		    u8 *digest, unsigned int digestsize)
+{
+	unsigned long func;
+	union {
+		struct sha256_paramblock {
+			u32 h[8];
+			u64 mbl;
+		} sha256;
+		struct sha512_paramblock {
+			u64 h[8];
+			u128 mbl;
+		} sha512;
+	} __packed param;
+
+#define PARAM_INIT(x, y, z)		   \
+	param.sha##x.h[0] = SHA##y ## _H0; \
+	param.sha##x.h[1] = SHA##y ## _H1; \
+	param.sha##x.h[2] = SHA##y ## _H2; \
+	param.sha##x.h[3] = SHA##y ## _H3; \
+	param.sha##x.h[4] = SHA##y ## _H4; \
+	param.sha##x.h[5] = SHA##y ## _H5; \
+	param.sha##x.h[6] = SHA##y ## _H6; \
+	param.sha##x.h[7] = SHA##y ## _H7; \
+	param.sha##x.mbl = (z)
+
+	switch (digestsize) {
+	case SHA224_DIGEST_SIZE:
+		func = CPACF_KLMD_SHA_256;
+		PARAM_INIT(256, 224, inlen * 8);
+		break;
+	case SHA256_DIGEST_SIZE:
+		func = CPACF_KLMD_SHA_256;
+		PARAM_INIT(256, 256, inlen * 8);
+		break;
+	case SHA384_DIGEST_SIZE:
+		func = CPACF_KLMD_SHA_512;
+		PARAM_INIT(512, 384, inlen * 8);
+		break;
+	case SHA512_DIGEST_SIZE:
+		func = CPACF_KLMD_SHA_512;
+		PARAM_INIT(512, 512, inlen * 8);
+		break;
+	default:
+		return -EINVAL;
+	}
+
+#undef PARAM_INIT
+
+	cpacf_klmd(func, &param, in, inlen);
+
+	memcpy(digest, &param, digestsize);
+
+	return 0;
+}
+
+/*
+ * make_clrkey_token() - wrap the clear key into a pkey clearkey token.
+ */
+static inline int make_clrkey_token(const u8 *clrkey, size_t clrkeylen,
+				    unsigned int digestsize, u8 *dest)
+{
+	struct hmac_clrkey_token *token = (struct hmac_clrkey_token *)dest;
+	unsigned int blocksize;
+	int rc;
+
+	token->type = 0x00;
+	token->version = 0x02;
+	switch (digestsize) {
+	case SHA224_DIGEST_SIZE:
+	case SHA256_DIGEST_SIZE:
+		token->keytype = PKEY_KEYTYPE_HMAC_512;
+		blocksize = 64;
+		break;
+	case SHA384_DIGEST_SIZE:
+	case SHA512_DIGEST_SIZE:
+		token->keytype = PKEY_KEYTYPE_HMAC_1024;
+		blocksize = 128;
+		break;
+	default:
+		return -EINVAL;
+	}
+	token->len = blocksize;
+
+	if (clrkeylen > blocksize) {
+		rc = hash_key(clrkey, clrkeylen, token->key, digestsize);
+		if (rc)
+			return rc;
+	} else {
+		memcpy(token->key, clrkey, clrkeylen);
+	}
+
+	return 0;
+}
+
 /*
  * phmac_tfm_ctx_setkey() - Set key value into tfm context, maybe construct
  * a clear key token digestible by pkey from a clear key value.
@@ -616,9 +724,32 @@ static int phmac_setkey(struct crypto_ahash *tfm,
 			const u8 *key, unsigned int keylen)
 {
 	struct phmac_tfm_ctx *tfm_ctx = crypto_ahash_ctx(tfm);
+	struct crypto_tfm *tfm_base = crypto_ahash_tfm(tfm);
 	unsigned int ds = crypto_ahash_digestsize(tfm);
+	unsigned int bs = crypto_ahash_blocksize(tfm);
+	unsigned int tmpkeylen;
+	u8 *tmpkey = NULL;
 	int rc = 0;
 
+	if (!(crypto_tfm_alg_get_flags(tfm_base) & CRYPTO_ALG_TESTED)) {
+		/*
+		 * selftest running: key is a raw hmac clear key and needs
+		 * to get embedded into a 'clear key token' in order to have
+		 * it correctly processed by the pkey module.
+		 */
+		tmpkeylen = sizeof(struct hmac_clrkey_token) + bs;
+		tmpkey = kzalloc(tmpkeylen, GFP_KERNEL);
+		if (!tmpkey) {
+			rc = -ENOMEM;
+			goto out;
+		}
+		rc = make_clrkey_token(key, keylen, ds, tmpkey);
+		if (rc)
+			goto out;
+		keylen = tmpkeylen;
+		key = tmpkey;
+	}
+
 	/* copy raw key into tfm context */
 	rc = phmac_tfm_ctx_setkey(tfm_ctx, key, keylen);
 	if (rc)
@@ -661,6 +792,7 @@ static int phmac_setkey(struct crypto_ahash *tfm,
 	}
 
 out:
+	kfree(tmpkey);
 	pr_debug("rc=%d\n", rc);
 	return rc;
 }
@@ -854,6 +986,17 @@ static int __init s390_phmac_init(void)
 	struct phmac_alg *phmac;
 	int i, rc;
 
+	/* for selftest cpacf klmd subfunction is needed */
+	if (!cpacf_query_func(CPACF_KLMD, CPACF_KLMD_SHA_256))
+		return -ENODEV;
+	if (!cpacf_query_func(CPACF_KLMD, CPACF_KLMD_SHA_512))
+		return -ENODEV;
+
+	/* register a simple phmac pseudo misc device */
+	rc = misc_register(&phmac_dev);
+	if (rc)
+		return rc;
+
 	/* with this pseudo device alloc and start a crypto engine */
 	phmac_crypto_engine =
 		crypto_engine_alloc_init_and_set(phmac_dev.this_device,
-- 
2.43.0


  parent reply	other threads:[~2025-05-22  8:58 UTC|newest]

Thread overview: 17+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-05-22  8:57 [PATCH v11 0/6] New s390 specific protected key hmac Harald Freudenberger
2025-05-22  8:57 ` [PATCH v11 1/6] crypto: ahash - make hash walk functions from ahash.c public Harald Freudenberger
2025-05-23 14:58   ` Holger Dengler
2025-05-22  8:57 ` [PATCH v11 2/6] s390/crypto: Add protected key hmac subfunctions for KMAC Harald Freudenberger
2025-05-23 15:00   ` Holger Dengler
2025-05-22  8:57 ` [PATCH v11 3/6] s390/crypto: New s390 specific protected key hash phmac Harald Freudenberger
2025-05-23 14:52   ` Holger Dengler
2025-05-26 14:02     ` Harald Freudenberger
2025-05-22  8:57 ` [PATCH v11 4/6] crypto: api - Add crypto_tfm_alg_get_flags() helper inline function Harald Freudenberger
2025-05-23 15:02   ` Holger Dengler
2025-05-22  8:57 ` Harald Freudenberger [this message]
2025-05-22  9:10   ` [PATCH v11 5/6] s390/crypto: Add selftest support for phmac Herbert Xu
2025-05-26 13:58     ` Harald Freudenberger
2025-05-23 14:55   ` Holger Dengler
2025-05-26 14:06     ` Harald Freudenberger
2025-05-22  8:57 ` [PATCH v11 6/6] crypto: testmgr - Enable phmac selftest Harald Freudenberger
2025-05-23 15:03   ` Holger Dengler

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20250522085755.40732-6-freude@linux.ibm.com \
    --to=freude@linux.ibm.com \
    --cc=dengler@linux.ibm.com \
    --cc=fcallies@linux.ibm.com \
    --cc=herbert@gondor.apana.org.au \
    --cc=ifranzki@linux.ibm.com \
    --cc=linux-crypto@vger.kernel.org \
    --cc=linux-s390@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.