1 /* SPDX-License-Identifier: GPL-2.0-or-later */ 2 /* 3 * Public Key Signature Algorithm 4 * 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 0x0000000e 21 22 static const struct crypto_type crypto_sig_type; 23 24 static 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 32 static 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 38 static 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 48 static int __maybe_unused crypto_sig_report_stat(struct sk_buff *skb, 49 struct crypto_alg *alg) 50 { 51 struct crypto_stat_akcipher rsig = {}; 52 53 strscpy(rsig.type, "sig", sizeof(rsig.type)); 54 55 return nla_put(skb, CRYPTOCFGA_STAT_AKCIPHER, sizeof(rsig), &rsig); 56 } 57 58 static const struct crypto_type crypto_sig_type = { 59 .extsize = crypto_alg_extsize, 60 .init_tfm = crypto_sig_init_tfm, 61 #ifdef CONFIG_PROC_FS 62 .show = crypto_sig_show, 63 #endif 64 #if IS_ENABLED(CONFIG_CRYPTO_USER) 65 .report = crypto_sig_report, 66 #endif 67 #ifdef CONFIG_CRYPTO_STATS 68 .report_stat = crypto_sig_report_stat, 69 #endif 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), 74 }; 75 76 struct crypto_sig *crypto_alloc_sig(const char *alg_name, u32 type, u32 mask) 77 { 78 return crypto_alloc_tfm(alg_name, &crypto_sig_type, type, mask); 79 } 80 EXPORT_SYMBOL_GPL(crypto_alloc_sig); 81 82 int crypto_sig_maxsize(struct crypto_sig *tfm) 83 { 84 struct crypto_akcipher **ctx = crypto_sig_ctx(tfm); 85 86 return crypto_akcipher_maxsize(*ctx); 87 } 88 EXPORT_SYMBOL_GPL(crypto_sig_maxsize); 89 90 int crypto_sig_sign(struct crypto_sig *tfm, 91 const void *src, unsigned int slen, 92 void *dst, unsigned int dlen) 93 { 94 struct crypto_akcipher **ctx = crypto_sig_ctx(tfm); 95 struct crypto_akcipher_sync_data data = { 96 .tfm = *ctx, 97 .src = src, 98 .dst = dst, 99 .slen = slen, 100 .dlen = dlen, 101 }; 102 103 return crypto_akcipher_sync_prep(&data) ?: 104 crypto_akcipher_sync_post(&data, 105 crypto_akcipher_sign(data.req)); 106 } 107 EXPORT_SYMBOL_GPL(crypto_sig_sign); 108 109 int crypto_sig_verify(struct crypto_sig *tfm, 110 const void *src, unsigned int slen, 111 const void *digest, unsigned int dlen) 112 { 113 struct crypto_akcipher **ctx = crypto_sig_ctx(tfm); 114 struct crypto_akcipher_sync_data data = { 115 .tfm = *ctx, 116 .src = src, 117 .slen = slen, 118 .dlen = dlen, 119 }; 120 int err; 121 122 err = crypto_akcipher_sync_prep(&data); 123 if (err) 124 return err; 125 126 memcpy(data.buf + slen, digest, dlen); 127 128 return crypto_akcipher_sync_post(&data, 129 crypto_akcipher_verify(data.req)); 130 } 131 EXPORT_SYMBOL_GPL(crypto_sig_verify); 132 133 int crypto_sig_set_pubkey(struct crypto_sig *tfm, 134 const void *key, unsigned int keylen) 135 { 136 struct crypto_akcipher **ctx = crypto_sig_ctx(tfm); 137 138 return crypto_akcipher_set_pub_key(*ctx, key, keylen); 139 } 140 EXPORT_SYMBOL_GPL(crypto_sig_set_pubkey); 141 142 int crypto_sig_set_privkey(struct crypto_sig *tfm, 143 const void *key, unsigned int keylen) 144 { 145 struct crypto_akcipher **ctx = crypto_sig_ctx(tfm); 146 147 return crypto_akcipher_set_priv_key(*ctx, key, keylen); 148 } 149 EXPORT_SYMBOL_GPL(crypto_sig_set_privkey); 150 151 MODULE_LICENSE("GPL"); 152 MODULE_DESCRIPTION("Public Key Signature Algorithms"); 153