xref: /openbmc/linux/crypto/kpp.c (revision 1ac731c529cd4d6adbce134754b51ff7d822b145)
12874c5fdSThomas Gleixner // SPDX-License-Identifier: GPL-2.0-or-later
24e5f2c40SSalvatore Benedetto /*
34e5f2c40SSalvatore Benedetto  * Key-agreement Protocol Primitives (KPP)
44e5f2c40SSalvatore Benedetto  *
54e5f2c40SSalvatore Benedetto  * Copyright (c) 2016, Intel Corporation
64e5f2c40SSalvatore Benedetto  * Authors: Salvatore Benedetto <salvatore.benedetto@intel.com>
74e5f2c40SSalvatore Benedetto  */
8e2950bf1SHerbert Xu 
9e2950bf1SHerbert Xu #include <crypto/internal/kpp.h>
10e2950bf1SHerbert Xu #include <linux/cryptouser.h>
114e5f2c40SSalvatore Benedetto #include <linux/errno.h>
124e5f2c40SSalvatore Benedetto #include <linux/kernel.h>
134e5f2c40SSalvatore Benedetto #include <linux/module.h>
144e5f2c40SSalvatore Benedetto #include <linux/seq_file.h>
154e5f2c40SSalvatore Benedetto #include <linux/string.h>
164e5f2c40SSalvatore Benedetto #include <net/netlink.h>
17e2950bf1SHerbert Xu 
184e5f2c40SSalvatore Benedetto #include "internal.h"
194e5f2c40SSalvatore Benedetto 
crypto_kpp_report(struct sk_buff * skb,struct crypto_alg * alg)20c0f9e01dSHerbert Xu static int __maybe_unused crypto_kpp_report(
21c0f9e01dSHerbert Xu 	struct sk_buff *skb, struct crypto_alg *alg)
224e5f2c40SSalvatore Benedetto {
234e5f2c40SSalvatore Benedetto 	struct crypto_report_kpp rkpp;
244e5f2c40SSalvatore Benedetto 
2537db69e0SEric Biggers 	memset(&rkpp, 0, sizeof(rkpp));
264e5f2c40SSalvatore Benedetto 
2737db69e0SEric Biggers 	strscpy(rkpp.type, "kpp", sizeof(rkpp.type));
284e5f2c40SSalvatore Benedetto 
2937db69e0SEric Biggers 	return nla_put(skb, CRYPTOCFGA_REPORT_KPP, sizeof(rkpp), &rkpp);
304e5f2c40SSalvatore Benedetto }
314e5f2c40SSalvatore Benedetto 
324e5f2c40SSalvatore Benedetto static void crypto_kpp_show(struct seq_file *m, struct crypto_alg *alg)
33d8c34b94SGideon Israel Dsouza 	__maybe_unused;
344e5f2c40SSalvatore Benedetto 
crypto_kpp_show(struct seq_file * m,struct crypto_alg * alg)354e5f2c40SSalvatore Benedetto static void crypto_kpp_show(struct seq_file *m, struct crypto_alg *alg)
364e5f2c40SSalvatore Benedetto {
374e5f2c40SSalvatore Benedetto 	seq_puts(m, "type         : kpp\n");
384e5f2c40SSalvatore Benedetto }
394e5f2c40SSalvatore Benedetto 
crypto_kpp_exit_tfm(struct crypto_tfm * tfm)404e5f2c40SSalvatore Benedetto static void crypto_kpp_exit_tfm(struct crypto_tfm *tfm)
414e5f2c40SSalvatore Benedetto {
424e5f2c40SSalvatore Benedetto 	struct crypto_kpp *kpp = __crypto_kpp_tfm(tfm);
434e5f2c40SSalvatore Benedetto 	struct kpp_alg *alg = crypto_kpp_alg(kpp);
444e5f2c40SSalvatore Benedetto 
454e5f2c40SSalvatore Benedetto 	alg->exit(kpp);
464e5f2c40SSalvatore Benedetto }
474e5f2c40SSalvatore Benedetto 
crypto_kpp_init_tfm(struct crypto_tfm * tfm)484e5f2c40SSalvatore Benedetto static int crypto_kpp_init_tfm(struct crypto_tfm *tfm)
494e5f2c40SSalvatore Benedetto {
504e5f2c40SSalvatore Benedetto 	struct crypto_kpp *kpp = __crypto_kpp_tfm(tfm);
514e5f2c40SSalvatore Benedetto 	struct kpp_alg *alg = crypto_kpp_alg(kpp);
524e5f2c40SSalvatore Benedetto 
534e5f2c40SSalvatore Benedetto 	if (alg->exit)
544e5f2c40SSalvatore Benedetto 		kpp->base.exit = crypto_kpp_exit_tfm;
554e5f2c40SSalvatore Benedetto 
564e5f2c40SSalvatore Benedetto 	if (alg->init)
574e5f2c40SSalvatore Benedetto 		return alg->init(kpp);
584e5f2c40SSalvatore Benedetto 
594e5f2c40SSalvatore Benedetto 	return 0;
604e5f2c40SSalvatore Benedetto }
614e5f2c40SSalvatore Benedetto 
crypto_kpp_free_instance(struct crypto_instance * inst)621038fd78SNicolai Stange static void crypto_kpp_free_instance(struct crypto_instance *inst)
631038fd78SNicolai Stange {
641038fd78SNicolai Stange 	struct kpp_instance *kpp = kpp_instance(inst);
651038fd78SNicolai Stange 
661038fd78SNicolai Stange 	kpp->free(kpp);
671038fd78SNicolai Stange }
681038fd78SNicolai Stange 
crypto_kpp_report_stat(struct sk_buff * skb,struct crypto_alg * alg)69e2950bf1SHerbert Xu static int __maybe_unused crypto_kpp_report_stat(
70e2950bf1SHerbert Xu 	struct sk_buff *skb, struct crypto_alg *alg)
71e2950bf1SHerbert Xu {
72e2950bf1SHerbert Xu 	struct kpp_alg *kpp = __crypto_kpp_alg(alg);
73e2950bf1SHerbert Xu 	struct crypto_istat_kpp *istat;
74e2950bf1SHerbert Xu 	struct crypto_stat_kpp rkpp;
75e2950bf1SHerbert Xu 
76e2950bf1SHerbert Xu 	istat = kpp_get_stat(kpp);
77e2950bf1SHerbert Xu 
78e2950bf1SHerbert Xu 	memset(&rkpp, 0, sizeof(rkpp));
79e2950bf1SHerbert Xu 
80e2950bf1SHerbert Xu 	strscpy(rkpp.type, "kpp", sizeof(rkpp.type));
81e2950bf1SHerbert Xu 
82e2950bf1SHerbert Xu 	rkpp.stat_setsecret_cnt = atomic64_read(&istat->setsecret_cnt);
83e2950bf1SHerbert Xu 	rkpp.stat_generate_public_key_cnt =
84e2950bf1SHerbert Xu 		atomic64_read(&istat->generate_public_key_cnt);
85e2950bf1SHerbert Xu 	rkpp.stat_compute_shared_secret_cnt =
86e2950bf1SHerbert Xu 		atomic64_read(&istat->compute_shared_secret_cnt);
87e2950bf1SHerbert Xu 	rkpp.stat_err_cnt = atomic64_read(&istat->err_cnt);
88e2950bf1SHerbert Xu 
89e2950bf1SHerbert Xu 	return nla_put(skb, CRYPTOCFGA_STAT_KPP, sizeof(rkpp), &rkpp);
90e2950bf1SHerbert Xu }
91e2950bf1SHerbert Xu 
924e5f2c40SSalvatore Benedetto static const struct crypto_type crypto_kpp_type = {
934e5f2c40SSalvatore Benedetto 	.extsize = crypto_alg_extsize,
944e5f2c40SSalvatore Benedetto 	.init_tfm = crypto_kpp_init_tfm,
951038fd78SNicolai Stange 	.free = crypto_kpp_free_instance,
964e5f2c40SSalvatore Benedetto #ifdef CONFIG_PROC_FS
974e5f2c40SSalvatore Benedetto 	.show = crypto_kpp_show,
984e5f2c40SSalvatore Benedetto #endif
99*b8969a1bSOndrej Mosnacek #if IS_ENABLED(CONFIG_CRYPTO_USER)
1004e5f2c40SSalvatore Benedetto 	.report = crypto_kpp_report,
101c0f9e01dSHerbert Xu #endif
102e2950bf1SHerbert Xu #ifdef CONFIG_CRYPTO_STATS
103e2950bf1SHerbert Xu 	.report_stat = crypto_kpp_report_stat,
104e2950bf1SHerbert Xu #endif
1054e5f2c40SSalvatore Benedetto 	.maskclear = ~CRYPTO_ALG_TYPE_MASK,
1064e5f2c40SSalvatore Benedetto 	.maskset = CRYPTO_ALG_TYPE_MASK,
1074e5f2c40SSalvatore Benedetto 	.type = CRYPTO_ALG_TYPE_KPP,
1084e5f2c40SSalvatore Benedetto 	.tfmsize = offsetof(struct crypto_kpp, base),
1094e5f2c40SSalvatore Benedetto };
1104e5f2c40SSalvatore Benedetto 
crypto_alloc_kpp(const char * alg_name,u32 type,u32 mask)1114e5f2c40SSalvatore Benedetto struct crypto_kpp *crypto_alloc_kpp(const char *alg_name, u32 type, u32 mask)
1124e5f2c40SSalvatore Benedetto {
1134e5f2c40SSalvatore Benedetto 	return crypto_alloc_tfm(alg_name, &crypto_kpp_type, type, mask);
1144e5f2c40SSalvatore Benedetto }
1154e5f2c40SSalvatore Benedetto EXPORT_SYMBOL_GPL(crypto_alloc_kpp);
1164e5f2c40SSalvatore Benedetto 
crypto_grab_kpp(struct crypto_kpp_spawn * spawn,struct crypto_instance * inst,const char * name,u32 type,u32 mask)11746ed5269SNicolai Stange int crypto_grab_kpp(struct crypto_kpp_spawn *spawn,
11846ed5269SNicolai Stange 		    struct crypto_instance *inst,
11946ed5269SNicolai Stange 		    const char *name, u32 type, u32 mask)
12046ed5269SNicolai Stange {
12146ed5269SNicolai Stange 	spawn->base.frontend = &crypto_kpp_type;
12246ed5269SNicolai Stange 	return crypto_grab_spawn(&spawn->base, inst, name, type, mask);
12346ed5269SNicolai Stange }
12446ed5269SNicolai Stange EXPORT_SYMBOL_GPL(crypto_grab_kpp);
12546ed5269SNicolai Stange 
crypto_has_kpp(const char * alg_name,u32 type,u32 mask)1269e2f284eSHannes Reinecke int crypto_has_kpp(const char *alg_name, u32 type, u32 mask)
1279e2f284eSHannes Reinecke {
1289e2f284eSHannes Reinecke 	return crypto_type_has_alg(alg_name, &crypto_kpp_type, type, mask);
1299e2f284eSHannes Reinecke }
1309e2f284eSHannes Reinecke EXPORT_SYMBOL_GPL(crypto_has_kpp);
1319e2f284eSHannes Reinecke 
kpp_prepare_alg(struct kpp_alg * alg)1324e5f2c40SSalvatore Benedetto static void kpp_prepare_alg(struct kpp_alg *alg)
1334e5f2c40SSalvatore Benedetto {
134e2950bf1SHerbert Xu 	struct crypto_istat_kpp *istat = kpp_get_stat(alg);
1354e5f2c40SSalvatore Benedetto 	struct crypto_alg *base = &alg->base;
1364e5f2c40SSalvatore Benedetto 
1374e5f2c40SSalvatore Benedetto 	base->cra_type = &crypto_kpp_type;
1384e5f2c40SSalvatore Benedetto 	base->cra_flags &= ~CRYPTO_ALG_TYPE_MASK;
1394e5f2c40SSalvatore Benedetto 	base->cra_flags |= CRYPTO_ALG_TYPE_KPP;
140e2950bf1SHerbert Xu 
141e2950bf1SHerbert Xu 	if (IS_ENABLED(CONFIG_CRYPTO_STATS))
142e2950bf1SHerbert Xu 		memset(istat, 0, sizeof(*istat));
1434e5f2c40SSalvatore Benedetto }
1444e5f2c40SSalvatore Benedetto 
crypto_register_kpp(struct kpp_alg * alg)1454e5f2c40SSalvatore Benedetto int crypto_register_kpp(struct kpp_alg *alg)
1464e5f2c40SSalvatore Benedetto {
1474e5f2c40SSalvatore Benedetto 	struct crypto_alg *base = &alg->base;
1484e5f2c40SSalvatore Benedetto 
1494e5f2c40SSalvatore Benedetto 	kpp_prepare_alg(alg);
1504e5f2c40SSalvatore Benedetto 	return crypto_register_alg(base);
1514e5f2c40SSalvatore Benedetto }
1524e5f2c40SSalvatore Benedetto EXPORT_SYMBOL_GPL(crypto_register_kpp);
1534e5f2c40SSalvatore Benedetto 
crypto_unregister_kpp(struct kpp_alg * alg)1544e5f2c40SSalvatore Benedetto void crypto_unregister_kpp(struct kpp_alg *alg)
1554e5f2c40SSalvatore Benedetto {
1564e5f2c40SSalvatore Benedetto 	crypto_unregister_alg(&alg->base);
1574e5f2c40SSalvatore Benedetto }
1584e5f2c40SSalvatore Benedetto EXPORT_SYMBOL_GPL(crypto_unregister_kpp);
1594e5f2c40SSalvatore Benedetto 
kpp_register_instance(struct crypto_template * tmpl,struct kpp_instance * inst)1601038fd78SNicolai Stange int kpp_register_instance(struct crypto_template *tmpl,
1611038fd78SNicolai Stange 			  struct kpp_instance *inst)
1621038fd78SNicolai Stange {
1631038fd78SNicolai Stange 	if (WARN_ON(!inst->free))
1641038fd78SNicolai Stange 		return -EINVAL;
1651038fd78SNicolai Stange 
1661038fd78SNicolai Stange 	kpp_prepare_alg(&inst->alg);
1671038fd78SNicolai Stange 
1681038fd78SNicolai Stange 	return crypto_register_instance(tmpl, kpp_crypto_instance(inst));
1691038fd78SNicolai Stange }
1701038fd78SNicolai Stange EXPORT_SYMBOL_GPL(kpp_register_instance);
1711038fd78SNicolai Stange 
1724e5f2c40SSalvatore Benedetto MODULE_LICENSE("GPL");
1734e5f2c40SSalvatore Benedetto MODULE_DESCRIPTION("Key-agreement Protocol Primitives");
174