| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182 |
- /* SPDX-License-Identifier: GPL-2.0-or-later */
- /*
- * Public Key Signature Algorithm
- *
- * Copyright (c) 2023 Herbert Xu <herbert@gondor.apana.org.au>
- */
- #include <crypto/internal/sig.h>
- #include <linux/cryptouser.h>
- #include <linux/kernel.h>
- #include <linux/module.h>
- #include <linux/seq_file.h>
- #include <linux/string.h>
- #include <net/netlink.h>
- #include "internal.h"
- static void crypto_sig_exit_tfm(struct crypto_tfm *tfm)
- {
- struct crypto_sig *sig = __crypto_sig_tfm(tfm);
- struct sig_alg *alg = crypto_sig_alg(sig);
- alg->exit(sig);
- }
- static int crypto_sig_init_tfm(struct crypto_tfm *tfm)
- {
- struct crypto_sig *sig = __crypto_sig_tfm(tfm);
- struct sig_alg *alg = crypto_sig_alg(sig);
- if (alg->exit)
- sig->base.exit = crypto_sig_exit_tfm;
- if (alg->init)
- return alg->init(sig);
- return 0;
- }
- static void crypto_sig_free_instance(struct crypto_instance *inst)
- {
- struct sig_instance *sig = sig_instance(inst);
- sig->free(sig);
- }
- static void __maybe_unused crypto_sig_show(struct seq_file *m,
- struct crypto_alg *alg)
- {
- seq_puts(m, "type : sig\n");
- }
- static int __maybe_unused crypto_sig_report(struct sk_buff *skb,
- struct crypto_alg *alg)
- {
- struct crypto_report_sig rsig = {};
- strscpy(rsig.type, "sig", sizeof(rsig.type));
- return nla_put(skb, CRYPTOCFGA_REPORT_SIG, sizeof(rsig), &rsig);
- }
- static const struct crypto_type crypto_sig_type = {
- .extsize = crypto_alg_extsize,
- .init_tfm = crypto_sig_init_tfm,
- .free = crypto_sig_free_instance,
- #ifdef CONFIG_PROC_FS
- .show = crypto_sig_show,
- #endif
- #if IS_ENABLED(CONFIG_CRYPTO_USER)
- .report = crypto_sig_report,
- #endif
- .maskclear = ~CRYPTO_ALG_TYPE_MASK,
- .maskset = CRYPTO_ALG_TYPE_MASK,
- .type = CRYPTO_ALG_TYPE_SIG,
- .tfmsize = offsetof(struct crypto_sig, base),
- .algsize = offsetof(struct sig_alg, base),
- };
- struct crypto_sig *crypto_alloc_sig(const char *alg_name, u32 type, u32 mask)
- {
- return crypto_alloc_tfm(alg_name, &crypto_sig_type, type, mask);
- }
- EXPORT_SYMBOL_GPL(crypto_alloc_sig);
- static int sig_default_sign(struct crypto_sig *tfm,
- const void *src, unsigned int slen,
- void *dst, unsigned int dlen)
- {
- return -ENOSYS;
- }
- static int sig_default_verify(struct crypto_sig *tfm,
- const void *src, unsigned int slen,
- const void *dst, unsigned int dlen)
- {
- return -ENOSYS;
- }
- static int sig_default_set_key(struct crypto_sig *tfm,
- const void *key, unsigned int keylen)
- {
- return -ENOSYS;
- }
- static unsigned int sig_default_size(struct crypto_sig *tfm)
- {
- return DIV_ROUND_UP_POW2(crypto_sig_keysize(tfm), BITS_PER_BYTE);
- }
- static int sig_prepare_alg(struct sig_alg *alg)
- {
- struct crypto_alg *base = &alg->base;
- if (!alg->sign)
- alg->sign = sig_default_sign;
- if (!alg->verify)
- alg->verify = sig_default_verify;
- if (!alg->set_priv_key)
- alg->set_priv_key = sig_default_set_key;
- if (!alg->set_pub_key)
- return -EINVAL;
- if (!alg->key_size)
- return -EINVAL;
- if (!alg->max_size)
- alg->max_size = sig_default_size;
- if (!alg->digest_size)
- alg->digest_size = sig_default_size;
- base->cra_type = &crypto_sig_type;
- base->cra_flags &= ~CRYPTO_ALG_TYPE_MASK;
- base->cra_flags |= CRYPTO_ALG_TYPE_SIG;
- return 0;
- }
- int crypto_register_sig(struct sig_alg *alg)
- {
- struct crypto_alg *base = &alg->base;
- int err;
- err = sig_prepare_alg(alg);
- if (err)
- return err;
- return crypto_register_alg(base);
- }
- EXPORT_SYMBOL_GPL(crypto_register_sig);
- void crypto_unregister_sig(struct sig_alg *alg)
- {
- crypto_unregister_alg(&alg->base);
- }
- EXPORT_SYMBOL_GPL(crypto_unregister_sig);
- int sig_register_instance(struct crypto_template *tmpl,
- struct sig_instance *inst)
- {
- int err;
- if (WARN_ON(!inst->free))
- return -EINVAL;
- err = sig_prepare_alg(&inst->alg);
- if (err)
- return err;
- return crypto_register_instance(tmpl, sig_crypto_instance(inst));
- }
- EXPORT_SYMBOL_GPL(sig_register_instance);
- int crypto_grab_sig(struct crypto_sig_spawn *spawn,
- struct crypto_instance *inst,
- const char *name, u32 type, u32 mask)
- {
- spawn->base.frontend = &crypto_sig_type;
- return crypto_grab_spawn(&spawn->base, inst, name, type, mask);
- }
- EXPORT_SYMBOL_GPL(crypto_grab_sig);
- MODULE_LICENSE("GPL");
- MODULE_DESCRIPTION("Public Key Signature Algorithms");
|