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