brintos

brintos / linux-shallow public Read only

0
0
Text · 3.4 KiB · 7645bed Raw
140 lines · c
1/* SPDX-License-Identifier: GPL-2.0-or-later */2/*3 * Public Key Signature Algorithm4 *5 * Copyright (c) 2023 Herbert Xu <herbert@gondor.apana.org.au>6 */7 8#include <crypto/akcipher.h>9#include <crypto/internal/sig.h>10#include <linux/cryptouser.h>11#include <linux/kernel.h>12#include <linux/module.h>13#include <linux/scatterlist.h>14#include <linux/seq_file.h>15#include <linux/string.h>16#include <net/netlink.h>17 18#include "internal.h"19 20#define CRYPTO_ALG_TYPE_SIG_MASK	0x0000000e21 22static const struct crypto_type crypto_sig_type;23 24static int crypto_sig_init_tfm(struct crypto_tfm *tfm)25{26	if (tfm->__crt_alg->cra_type != &crypto_sig_type)27		return crypto_init_akcipher_ops_sig(tfm);28 29	return 0;30}31 32static void __maybe_unused crypto_sig_show(struct seq_file *m,33					   struct crypto_alg *alg)34{35	seq_puts(m, "type         : sig\n");36}37 38static int __maybe_unused crypto_sig_report(struct sk_buff *skb,39					    struct crypto_alg *alg)40{41	struct crypto_report_akcipher rsig = {};42 43	strscpy(rsig.type, "sig", sizeof(rsig.type));44 45	return nla_put(skb, CRYPTOCFGA_REPORT_AKCIPHER, sizeof(rsig), &rsig);46}47 48static const struct crypto_type crypto_sig_type = {49	.extsize = crypto_alg_extsize,50	.init_tfm = crypto_sig_init_tfm,51#ifdef CONFIG_PROC_FS52	.show = crypto_sig_show,53#endif54#if IS_ENABLED(CONFIG_CRYPTO_USER)55	.report = crypto_sig_report,56#endif57	.maskclear = ~CRYPTO_ALG_TYPE_MASK,58	.maskset = CRYPTO_ALG_TYPE_SIG_MASK,59	.type = CRYPTO_ALG_TYPE_SIG,60	.tfmsize = offsetof(struct crypto_sig, base),61};62 63struct crypto_sig *crypto_alloc_sig(const char *alg_name, u32 type, u32 mask)64{65	return crypto_alloc_tfm(alg_name, &crypto_sig_type, type, mask);66}67EXPORT_SYMBOL_GPL(crypto_alloc_sig);68 69int crypto_sig_maxsize(struct crypto_sig *tfm)70{71	struct crypto_akcipher **ctx = crypto_sig_ctx(tfm);72 73	return crypto_akcipher_maxsize(*ctx);74}75EXPORT_SYMBOL_GPL(crypto_sig_maxsize);76 77int crypto_sig_sign(struct crypto_sig *tfm,78		    const void *src, unsigned int slen,79		    void *dst, unsigned int dlen)80{81	struct crypto_akcipher **ctx = crypto_sig_ctx(tfm);82	struct crypto_akcipher_sync_data data = {83		.tfm = *ctx,84		.src = src,85		.dst = dst,86		.slen = slen,87		.dlen = dlen,88	};89 90	return crypto_akcipher_sync_prep(&data) ?:91	       crypto_akcipher_sync_post(&data,92					 crypto_akcipher_sign(data.req));93}94EXPORT_SYMBOL_GPL(crypto_sig_sign);95 96int crypto_sig_verify(struct crypto_sig *tfm,97		      const void *src, unsigned int slen,98		      const void *digest, unsigned int dlen)99{100	struct crypto_akcipher **ctx = crypto_sig_ctx(tfm);101	struct crypto_akcipher_sync_data data = {102		.tfm = *ctx,103		.src = src,104		.slen = slen,105		.dlen = dlen,106	};107	int err;108 109	err = crypto_akcipher_sync_prep(&data);110	if (err)111		return err;112 113	memcpy(data.buf + slen, digest, dlen);114 115	return crypto_akcipher_sync_post(&data,116					 crypto_akcipher_verify(data.req));117}118EXPORT_SYMBOL_GPL(crypto_sig_verify);119 120int crypto_sig_set_pubkey(struct crypto_sig *tfm,121			  const void *key, unsigned int keylen)122{123	struct crypto_akcipher **ctx = crypto_sig_ctx(tfm);124 125	return crypto_akcipher_set_pub_key(*ctx, key, keylen);126}127EXPORT_SYMBOL_GPL(crypto_sig_set_pubkey);128 129int crypto_sig_set_privkey(struct crypto_sig *tfm,130			  const void *key, unsigned int keylen)131{132	struct crypto_akcipher **ctx = crypto_sig_ctx(tfm);133 134	return crypto_akcipher_set_priv_key(*ctx, key, keylen);135}136EXPORT_SYMBOL_GPL(crypto_sig_set_privkey);137 138MODULE_LICENSE("GPL");139MODULE_DESCRIPTION("Public Key Signature Algorithms");140