1 /* SPDX-License-Identifier: GPL-2.0-or-later */
3 * Public Key Signature Algorithm
5 * Copyright (c) 2023 Herbert Xu <herbert@gondor.apana.org.au>
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>
20 #define CRYPTO_ALG_TYPE_SIG_MASK 0x0000000e
22 static const struct crypto_type crypto_sig_type
;
24 static int crypto_sig_init_tfm(struct crypto_tfm
*tfm
)
26 if (tfm
->__crt_alg
->cra_type
!= &crypto_sig_type
)
27 return crypto_init_akcipher_ops_sig(tfm
);
32 static void __maybe_unused
crypto_sig_show(struct seq_file
*m
,
33 struct crypto_alg
*alg
)
35 seq_puts(m
, "type : sig\n");
38 static int __maybe_unused
crypto_sig_report(struct sk_buff
*skb
,
39 struct crypto_alg
*alg
)
41 struct crypto_report_akcipher rsig
= {};
43 strscpy(rsig
.type
, "sig", sizeof(rsig
.type
));
45 return nla_put(skb
, CRYPTOCFGA_REPORT_AKCIPHER
, sizeof(rsig
), &rsig
);
48 static int __maybe_unused
crypto_sig_report_stat(struct sk_buff
*skb
,
49 struct crypto_alg
*alg
)
51 struct crypto_stat_akcipher rsig
= {};
53 strscpy(rsig
.type
, "sig", sizeof(rsig
.type
));
55 return nla_put(skb
, CRYPTOCFGA_STAT_AKCIPHER
, sizeof(rsig
), &rsig
);
58 static const struct crypto_type crypto_sig_type
= {
59 .extsize
= crypto_alg_extsize
,
60 .init_tfm
= crypto_sig_init_tfm
,
62 .show
= crypto_sig_show
,
64 #if IS_ENABLED(CONFIG_CRYPTO_USER)
65 .report
= crypto_sig_report
,
67 #ifdef CONFIG_CRYPTO_STATS
68 .report_stat
= crypto_sig_report_stat
,
70 .maskclear
= ~CRYPTO_ALG_TYPE_MASK
,
71 .maskset
= CRYPTO_ALG_TYPE_SIG_MASK
,
72 .type
= CRYPTO_ALG_TYPE_SIG
,
73 .tfmsize
= offsetof(struct crypto_sig
, base
),
76 struct crypto_sig
*crypto_alloc_sig(const char *alg_name
, u32 type
, u32 mask
)
78 return crypto_alloc_tfm(alg_name
, &crypto_sig_type
, type
, mask
);
80 EXPORT_SYMBOL_GPL(crypto_alloc_sig
);
82 int crypto_sig_maxsize(struct crypto_sig
*tfm
)
84 struct crypto_akcipher
**ctx
= crypto_sig_ctx(tfm
);
86 return crypto_akcipher_maxsize(*ctx
);
88 EXPORT_SYMBOL_GPL(crypto_sig_maxsize
);
90 int crypto_sig_sign(struct crypto_sig
*tfm
,
91 const void *src
, unsigned int slen
,
92 void *dst
, unsigned int dlen
)
94 struct crypto_akcipher
**ctx
= crypto_sig_ctx(tfm
);
95 struct crypto_akcipher_sync_data data
= {
103 return crypto_akcipher_sync_prep(&data
) ?:
104 crypto_akcipher_sync_post(&data
,
105 crypto_akcipher_sign(data
.req
));
107 EXPORT_SYMBOL_GPL(crypto_sig_sign
);
109 int crypto_sig_verify(struct crypto_sig
*tfm
,
110 const void *src
, unsigned int slen
,
111 const void *digest
, unsigned int dlen
)
113 struct crypto_akcipher
**ctx
= crypto_sig_ctx(tfm
);
114 struct crypto_akcipher_sync_data data
= {
122 err
= crypto_akcipher_sync_prep(&data
);
126 memcpy(data
.buf
+ slen
, digest
, dlen
);
128 return crypto_akcipher_sync_post(&data
,
129 crypto_akcipher_verify(data
.req
));
131 EXPORT_SYMBOL_GPL(crypto_sig_verify
);
133 int crypto_sig_set_pubkey(struct crypto_sig
*tfm
,
134 const void *key
, unsigned int keylen
)
136 struct crypto_akcipher
**ctx
= crypto_sig_ctx(tfm
);
138 return crypto_akcipher_set_pub_key(*ctx
, key
, keylen
);
140 EXPORT_SYMBOL_GPL(crypto_sig_set_pubkey
);
142 int crypto_sig_set_privkey(struct crypto_sig
*tfm
,
143 const void *key
, unsigned int keylen
)
145 struct crypto_akcipher
**ctx
= crypto_sig_ctx(tfm
);
147 return crypto_akcipher_set_priv_key(*ctx
, key
, keylen
);
149 EXPORT_SYMBOL_GPL(crypto_sig_set_privkey
);
151 MODULE_LICENSE("GPL");
152 MODULE_DESCRIPTION("Public Key Signature Algorithms");