forked from Minki/linux
46ed5269bf
The upcoming support for the RFC 7919 ffdhe group parameters will be made available in the form of templates like "ffdhe2048(dh)", "ffdhe3072(dh)" and so on. Template instantiations thereof would wrap the inner "dh" kpp_alg and also provide kpp_alg services to the outside again. The primitves needed for providing kpp_alg services from template instances have been introduced with the previous patch. Continue this work now and implement everything needed for enabling template instances to make use of inner KPP algorithms like "dh". More specifically, define a struct crypto_kpp_spawn in close analogy to crypto_skcipher_spawn, crypto_shash_spawn and alike. Implement a crypto_grab_kpp() and crypto_drop_kpp() pair for binding such a spawn to some inner kpp_alg and for releasing it respectively. Template implementations can instantiate transforms from the underlying kpp_alg by means of the new crypto_spawn_kpp(). Finally, provide the crypto_spawn_kpp_alg() helper for accessing a spawn's underlying kpp_alg during template instantiation. Annotate everything with proper kernel-doc comments, even though include/crypto/internal/kpp.h is not considered for the generated docs. Signed-off-by: Nicolai Stange <nstange@suse.de> Reviewed-by: Hannes Reinecke <hare@suse.de> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
145 lines
3.4 KiB
C
145 lines
3.4 KiB
C
// SPDX-License-Identifier: GPL-2.0-or-later
|
|
/*
|
|
* Key-agreement Protocol Primitives (KPP)
|
|
*
|
|
* Copyright (c) 2016, Intel Corporation
|
|
* Authors: Salvatore Benedetto <salvatore.benedetto@intel.com>
|
|
*/
|
|
#include <linux/errno.h>
|
|
#include <linux/kernel.h>
|
|
#include <linux/module.h>
|
|
#include <linux/seq_file.h>
|
|
#include <linux/slab.h>
|
|
#include <linux/string.h>
|
|
#include <linux/crypto.h>
|
|
#include <crypto/algapi.h>
|
|
#include <linux/cryptouser.h>
|
|
#include <linux/compiler.h>
|
|
#include <net/netlink.h>
|
|
#include <crypto/kpp.h>
|
|
#include <crypto/internal/kpp.h>
|
|
#include "internal.h"
|
|
|
|
#ifdef CONFIG_NET
|
|
static int crypto_kpp_report(struct sk_buff *skb, struct crypto_alg *alg)
|
|
{
|
|
struct crypto_report_kpp rkpp;
|
|
|
|
memset(&rkpp, 0, sizeof(rkpp));
|
|
|
|
strscpy(rkpp.type, "kpp", sizeof(rkpp.type));
|
|
|
|
return nla_put(skb, CRYPTOCFGA_REPORT_KPP, sizeof(rkpp), &rkpp);
|
|
}
|
|
#else
|
|
static int crypto_kpp_report(struct sk_buff *skb, struct crypto_alg *alg)
|
|
{
|
|
return -ENOSYS;
|
|
}
|
|
#endif
|
|
|
|
static void crypto_kpp_show(struct seq_file *m, struct crypto_alg *alg)
|
|
__maybe_unused;
|
|
|
|
static void crypto_kpp_show(struct seq_file *m, struct crypto_alg *alg)
|
|
{
|
|
seq_puts(m, "type : kpp\n");
|
|
}
|
|
|
|
static void crypto_kpp_exit_tfm(struct crypto_tfm *tfm)
|
|
{
|
|
struct crypto_kpp *kpp = __crypto_kpp_tfm(tfm);
|
|
struct kpp_alg *alg = crypto_kpp_alg(kpp);
|
|
|
|
alg->exit(kpp);
|
|
}
|
|
|
|
static int crypto_kpp_init_tfm(struct crypto_tfm *tfm)
|
|
{
|
|
struct crypto_kpp *kpp = __crypto_kpp_tfm(tfm);
|
|
struct kpp_alg *alg = crypto_kpp_alg(kpp);
|
|
|
|
if (alg->exit)
|
|
kpp->base.exit = crypto_kpp_exit_tfm;
|
|
|
|
if (alg->init)
|
|
return alg->init(kpp);
|
|
|
|
return 0;
|
|
}
|
|
|
|
static void crypto_kpp_free_instance(struct crypto_instance *inst)
|
|
{
|
|
struct kpp_instance *kpp = kpp_instance(inst);
|
|
|
|
kpp->free(kpp);
|
|
}
|
|
|
|
static const struct crypto_type crypto_kpp_type = {
|
|
.extsize = crypto_alg_extsize,
|
|
.init_tfm = crypto_kpp_init_tfm,
|
|
.free = crypto_kpp_free_instance,
|
|
#ifdef CONFIG_PROC_FS
|
|
.show = crypto_kpp_show,
|
|
#endif
|
|
.report = crypto_kpp_report,
|
|
.maskclear = ~CRYPTO_ALG_TYPE_MASK,
|
|
.maskset = CRYPTO_ALG_TYPE_MASK,
|
|
.type = CRYPTO_ALG_TYPE_KPP,
|
|
.tfmsize = offsetof(struct crypto_kpp, base),
|
|
};
|
|
|
|
struct crypto_kpp *crypto_alloc_kpp(const char *alg_name, u32 type, u32 mask)
|
|
{
|
|
return crypto_alloc_tfm(alg_name, &crypto_kpp_type, type, mask);
|
|
}
|
|
EXPORT_SYMBOL_GPL(crypto_alloc_kpp);
|
|
|
|
int crypto_grab_kpp(struct crypto_kpp_spawn *spawn,
|
|
struct crypto_instance *inst,
|
|
const char *name, u32 type, u32 mask)
|
|
{
|
|
spawn->base.frontend = &crypto_kpp_type;
|
|
return crypto_grab_spawn(&spawn->base, inst, name, type, mask);
|
|
}
|
|
EXPORT_SYMBOL_GPL(crypto_grab_kpp);
|
|
|
|
static void kpp_prepare_alg(struct kpp_alg *alg)
|
|
{
|
|
struct crypto_alg *base = &alg->base;
|
|
|
|
base->cra_type = &crypto_kpp_type;
|
|
base->cra_flags &= ~CRYPTO_ALG_TYPE_MASK;
|
|
base->cra_flags |= CRYPTO_ALG_TYPE_KPP;
|
|
}
|
|
|
|
int crypto_register_kpp(struct kpp_alg *alg)
|
|
{
|
|
struct crypto_alg *base = &alg->base;
|
|
|
|
kpp_prepare_alg(alg);
|
|
return crypto_register_alg(base);
|
|
}
|
|
EXPORT_SYMBOL_GPL(crypto_register_kpp);
|
|
|
|
void crypto_unregister_kpp(struct kpp_alg *alg)
|
|
{
|
|
crypto_unregister_alg(&alg->base);
|
|
}
|
|
EXPORT_SYMBOL_GPL(crypto_unregister_kpp);
|
|
|
|
int kpp_register_instance(struct crypto_template *tmpl,
|
|
struct kpp_instance *inst)
|
|
{
|
|
if (WARN_ON(!inst->free))
|
|
return -EINVAL;
|
|
|
|
kpp_prepare_alg(&inst->alg);
|
|
|
|
return crypto_register_instance(tmpl, kpp_crypto_instance(inst));
|
|
}
|
|
EXPORT_SYMBOL_GPL(kpp_register_instance);
|
|
|
|
MODULE_LICENSE("GPL");
|
|
MODULE_DESCRIPTION("Key-agreement Protocol Primitives");
|