201 lines · 4.9 KB · C
RawDownload
// SPDX-License-Identifier: GPL-2.0-or-later/* * crypto_sig wrapper around ML-DSA library. */#include <linux/init.h>#include <linux/module.h>#include <crypto/internal/sig.h>#include <crypto/mldsa.h> struct crypto_mldsa_ctx {	u8 pk[MAX(MAX(MLDSA44_PUBLIC_KEY_SIZE,		      MLDSA65_PUBLIC_KEY_SIZE),		  MLDSA87_PUBLIC_KEY_SIZE)];	unsigned int pk_len;	enum mldsa_alg strength;	bool key_set;}; static int crypto_mldsa_sign(struct crypto_sig *tfm,			     const void *msg, unsigned int msg_len,			     void *sig, unsigned int sig_len){	return -EOPNOTSUPP;} static int crypto_mldsa_verify(struct crypto_sig *tfm,			       const void *sig, unsigned int sig_len,			       const void *msg, unsigned int msg_len){	const struct crypto_mldsa_ctx *ctx = crypto_sig_ctx(tfm); 	if (unlikely(!ctx->key_set))		return -EINVAL; 	return mldsa_verify(ctx->strength, sig, sig_len, msg, msg_len,			    ctx->pk, ctx->pk_len);} static unsigned int crypto_mldsa_key_size(struct crypto_sig *tfm){	struct crypto_mldsa_ctx *ctx = crypto_sig_ctx(tfm); 	switch (ctx->strength) {	case MLDSA44:		return MLDSA44_PUBLIC_KEY_SIZE;	case MLDSA65:		return MLDSA65_PUBLIC_KEY_SIZE;	case MLDSA87:		return MLDSA87_PUBLIC_KEY_SIZE;	default:		WARN_ON_ONCE(1);		return 0;	}} static int crypto_mldsa_set_pub_key(struct crypto_sig *tfm,				    const void *key, unsigned int keylen){	struct crypto_mldsa_ctx *ctx = crypto_sig_ctx(tfm);	unsigned int expected_len = crypto_mldsa_key_size(tfm); 	if (keylen != expected_len)		return -EINVAL; 	ctx->pk_len = keylen;	memcpy(ctx->pk, key, keylen);	ctx->key_set = true;	return 0;} static int crypto_mldsa_set_priv_key(struct crypto_sig *tfm,				     const void *key, unsigned int keylen){	return -EOPNOTSUPP;} static unsigned int crypto_mldsa_max_size(struct crypto_sig *tfm){	struct crypto_mldsa_ctx *ctx = crypto_sig_ctx(tfm); 	switch (ctx->strength) {	case MLDSA44:		return MLDSA44_SIGNATURE_SIZE;	case MLDSA65:		return MLDSA65_SIGNATURE_SIZE;	case MLDSA87:		return MLDSA87_SIGNATURE_SIZE;	default:		WARN_ON_ONCE(1);		return 0;	}} static int crypto_mldsa44_alg_init(struct crypto_sig *tfm){	struct crypto_mldsa_ctx *ctx = crypto_sig_ctx(tfm); 	ctx->strength = MLDSA44;	ctx->key_set = false;	return 0;} static int crypto_mldsa65_alg_init(struct crypto_sig *tfm){	struct crypto_mldsa_ctx *ctx = crypto_sig_ctx(tfm); 	ctx->strength = MLDSA65;	ctx->key_set = false;	return 0;} static int crypto_mldsa87_alg_init(struct crypto_sig *tfm){	struct crypto_mldsa_ctx *ctx = crypto_sig_ctx(tfm); 	ctx->strength = MLDSA87;	ctx->key_set = false;	return 0;} static void crypto_mldsa_alg_exit(struct crypto_sig *tfm){} static struct sig_alg crypto_mldsa_algs[] = {	{		.sign			= crypto_mldsa_sign,		.verify			= crypto_mldsa_verify,		.set_pub_key		= crypto_mldsa_set_pub_key,		.set_priv_key		= crypto_mldsa_set_priv_key,		.key_size		= crypto_mldsa_key_size,		.max_size		= crypto_mldsa_max_size,		.init			= crypto_mldsa44_alg_init,		.exit			= crypto_mldsa_alg_exit,		.base.cra_name		= "mldsa44",		.base.cra_driver_name	= "mldsa44-lib",		.base.cra_ctxsize	= sizeof(struct crypto_mldsa_ctx),		.base.cra_module	= THIS_MODULE,		.base.cra_priority	= 5000,	}, {		.sign			= crypto_mldsa_sign,		.verify			= crypto_mldsa_verify,		.set_pub_key		= crypto_mldsa_set_pub_key,		.set_priv_key		= crypto_mldsa_set_priv_key,		.key_size		= crypto_mldsa_key_size,		.max_size		= crypto_mldsa_max_size,		.init			= crypto_mldsa65_alg_init,		.exit			= crypto_mldsa_alg_exit,		.base.cra_name		= "mldsa65",		.base.cra_driver_name	= "mldsa65-lib",		.base.cra_ctxsize	= sizeof(struct crypto_mldsa_ctx),		.base.cra_module	= THIS_MODULE,		.base.cra_priority	= 5000,	}, {		.sign			= crypto_mldsa_sign,		.verify			= crypto_mldsa_verify,		.set_pub_key		= crypto_mldsa_set_pub_key,		.set_priv_key		= crypto_mldsa_set_priv_key,		.key_size		= crypto_mldsa_key_size,		.max_size		= crypto_mldsa_max_size,		.init			= crypto_mldsa87_alg_init,		.exit			= crypto_mldsa_alg_exit,		.base.cra_name		= "mldsa87",		.base.cra_driver_name	= "mldsa87-lib",		.base.cra_ctxsize	= sizeof(struct crypto_mldsa_ctx),		.base.cra_module	= THIS_MODULE,		.base.cra_priority	= 5000,	},}; static int __init mldsa_init(void){	int ret, i; 	for (i = 0; i < ARRAY_SIZE(crypto_mldsa_algs); i++) {		ret = crypto_register_sig(&crypto_mldsa_algs[i]);		if (ret < 0)			goto error;	}	return 0; error:	pr_err("Failed to register (%d)\n", ret);	for (i--; i >= 0; i--)		crypto_unregister_sig(&crypto_mldsa_algs[i]);	return ret;}module_init(mldsa_init); static void mldsa_exit(void){	for (int i = 0; i < ARRAY_SIZE(crypto_mldsa_algs); i++)		crypto_unregister_sig(&crypto_mldsa_algs[i]);}module_exit(mldsa_exit); MODULE_LICENSE("GPL");MODULE_DESCRIPTION("Crypto API support for ML-DSA signature verification");MODULE_ALIAS_CRYPTO("mldsa44");MODULE_ALIAS_CRYPTO("mldsa65");MODULE_ALIAS_CRYPTO("mldsa87");