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 const struct crypto_type crypto_sig_type
= {
49 .extsize
= crypto_alg_extsize
,
50 .init_tfm
= crypto_sig_init_tfm
,
52 .show
= crypto_sig_show
,
54 #if IS_ENABLED(CONFIG_CRYPTO_USER)
55 .report
= crypto_sig_report
,
57 .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
),
63 struct crypto_sig
*crypto_alloc_sig(const char *alg_name
, u32 type
, u32 mask
)
65 return crypto_alloc_tfm(alg_name
, &crypto_sig_type
, type
, mask
);
67 EXPORT_SYMBOL_GPL(crypto_alloc_sig
);
69 int crypto_sig_maxsize(struct crypto_sig
*tfm
)
71 struct crypto_akcipher
**ctx
= crypto_sig_ctx(tfm
);
73 return crypto_akcipher_maxsize(*ctx
);
75 EXPORT_SYMBOL_GPL(crypto_sig_maxsize
);
77 int crypto_sig_sign(struct crypto_sig
*tfm
,
78 const void *src
, unsigned int slen
,
79 void *dst
, unsigned int dlen
)
81 struct crypto_akcipher
**ctx
= crypto_sig_ctx(tfm
);
82 struct crypto_akcipher_sync_data data
= {
90 return crypto_akcipher_sync_prep(&data
) ?:
91 crypto_akcipher_sync_post(&data
,
92 crypto_akcipher_sign(data
.req
));
94 EXPORT_SYMBOL_GPL(crypto_sig_sign
);
96 int crypto_sig_verify(struct crypto_sig
*tfm
,
97 const void *src
, unsigned int slen
,
98 const void *digest
, unsigned int dlen
)
100 struct crypto_akcipher
**ctx
= crypto_sig_ctx(tfm
);
101 struct crypto_akcipher_sync_data data
= {
109 err
= crypto_akcipher_sync_prep(&data
);
113 memcpy(data
.buf
+ slen
, digest
, dlen
);
115 return crypto_akcipher_sync_post(&data
,
116 crypto_akcipher_verify(data
.req
));
118 EXPORT_SYMBOL_GPL(crypto_sig_verify
);
120 int crypto_sig_set_pubkey(struct crypto_sig
*tfm
,
121 const void *key
, unsigned int keylen
)
123 struct crypto_akcipher
**ctx
= crypto_sig_ctx(tfm
);
125 return crypto_akcipher_set_pub_key(*ctx
, key
, keylen
);
127 EXPORT_SYMBOL_GPL(crypto_sig_set_pubkey
);
129 int crypto_sig_set_privkey(struct crypto_sig
*tfm
,
130 const void *key
, unsigned int keylen
)
132 struct crypto_akcipher
**ctx
= crypto_sig_ctx(tfm
);
134 return crypto_akcipher_set_priv_key(*ctx
, key
, keylen
);
136 EXPORT_SYMBOL_GPL(crypto_sig_set_privkey
);
138 MODULE_LICENSE("GPL");
139 MODULE_DESCRIPTION("Public Key Signature Algorithms");