Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

crypto: sig - Add interface for sign/verify

Split out the sign/verify functionality from the existing akcipher
interface. Most algorithms in akcipher either support encryption
and decryption, or signing and verify. Only one supports both.

As a signature algorithm may not support encryption at all, these
two should be spearated.

For now sig is simply a wrapper around akcipher as all algorithms
remain unchanged. This is a first step and allows users to start
allocating sig instead of akcipher.

Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>

+385 -18
+10
crypto/Kconfig
··· 72 72 tristate 73 73 select CRYPTO_ALGAPI2 74 74 75 + config CRYPTO_SIG 76 + tristate 77 + select CRYPTO_SIG2 78 + select CRYPTO_ALGAPI 79 + 80 + config CRYPTO_SIG2 81 + tristate 82 + select CRYPTO_ALGAPI2 83 + 75 84 config CRYPTO_SKCIPHER 76 85 tristate 77 86 select CRYPTO_SKCIPHER2 ··· 152 143 select CRYPTO_ACOMP2 153 144 select CRYPTO_AEAD2 154 145 select CRYPTO_AKCIPHER2 146 + select CRYPTO_SIG2 155 147 select CRYPTO_HASH2 156 148 select CRYPTO_KPP2 157 149 select CRYPTO_RNG2
+1
crypto/Makefile
··· 25 25 obj-$(CONFIG_CRYPTO_HASH2) += crypto_hash.o 26 26 27 27 obj-$(CONFIG_CRYPTO_AKCIPHER2) += akcipher.o 28 + obj-$(CONFIG_CRYPTO_SIG2) += sig.o 28 29 obj-$(CONFIG_CRYPTO_KPP2) += kpp.o 29 30 30 31 dh_generic-y := dh.o
+36 -17
crypto/akcipher.c
··· 18 18 19 19 #include "internal.h" 20 20 21 - struct crypto_akcipher_sync_data { 22 - struct crypto_akcipher *tfm; 23 - const void *src; 24 - void *dst; 25 - unsigned int slen; 26 - unsigned int dlen; 27 - 28 - struct akcipher_request *req; 29 - struct crypto_wait cwait; 30 - struct scatterlist sg; 31 - u8 *buf; 32 - }; 21 + #define CRYPTO_ALG_TYPE_AHASH_MASK 0x0000000e 33 22 34 23 static int __maybe_unused crypto_akcipher_report( 35 24 struct sk_buff *skb, struct crypto_alg *alg) ··· 108 119 .report_stat = crypto_akcipher_report_stat, 109 120 #endif 110 121 .maskclear = ~CRYPTO_ALG_TYPE_MASK, 111 - .maskset = CRYPTO_ALG_TYPE_MASK, 122 + .maskset = CRYPTO_ALG_TYPE_AHASH_MASK, 112 123 .type = CRYPTO_ALG_TYPE_AKCIPHER, 113 124 .tfmsize = offsetof(struct crypto_akcipher, base), 114 125 }; ··· 189 200 } 190 201 EXPORT_SYMBOL_GPL(akcipher_register_instance); 191 202 192 - static int crypto_akcipher_sync_prep(struct crypto_akcipher_sync_data *data) 203 + int crypto_akcipher_sync_prep(struct crypto_akcipher_sync_data *data) 193 204 { 194 205 unsigned int reqsize = crypto_akcipher_reqsize(data->tfm); 195 206 unsigned int mlen = max(data->slen, data->dlen); ··· 212 223 data->buf = buf; 213 224 memcpy(buf, data->src, data->slen); 214 225 215 - sg = &data->sg; 226 + sg = data->sg; 216 227 sg_init_one(sg, buf, mlen); 217 228 akcipher_request_set_crypt(req, sg, sg, data->slen, data->dlen); 218 229 ··· 222 233 223 234 return 0; 224 235 } 236 + EXPORT_SYMBOL_GPL(crypto_akcipher_sync_prep); 225 237 226 - static int crypto_akcipher_sync_post(struct crypto_akcipher_sync_data *data, 227 - int err) 238 + int crypto_akcipher_sync_post(struct crypto_akcipher_sync_data *data, int err) 228 239 { 229 240 err = crypto_wait_req(err, &data->cwait); 230 241 memcpy(data->dst, data->buf, data->dlen); ··· 232 243 kfree_sensitive(data->req); 233 244 return err; 234 245 } 246 + EXPORT_SYMBOL_GPL(crypto_akcipher_sync_post); 235 247 236 248 int crypto_akcipher_sync_encrypt(struct crypto_akcipher *tfm, 237 249 const void *src, unsigned int slen, ··· 270 280 data.dlen; 271 281 } 272 282 EXPORT_SYMBOL_GPL(crypto_akcipher_sync_decrypt); 283 + 284 + static void crypto_exit_akcipher_ops_sig(struct crypto_tfm *tfm) 285 + { 286 + struct crypto_akcipher **ctx = crypto_tfm_ctx(tfm); 287 + 288 + crypto_free_akcipher(*ctx); 289 + } 290 + 291 + int crypto_init_akcipher_ops_sig(struct crypto_tfm *tfm) 292 + { 293 + struct crypto_akcipher **ctx = crypto_tfm_ctx(tfm); 294 + struct crypto_alg *calg = tfm->__crt_alg; 295 + struct crypto_akcipher *akcipher; 296 + 297 + if (!crypto_mod_get(calg)) 298 + return -EAGAIN; 299 + 300 + akcipher = crypto_create_tfm(calg, &crypto_akcipher_type); 301 + if (IS_ERR(akcipher)) { 302 + crypto_mod_put(calg); 303 + return PTR_ERR(akcipher); 304 + } 305 + 306 + *ctx = akcipher; 307 + tfm->exit = crypto_exit_akcipher_ops_sig; 308 + 309 + return 0; 310 + } 311 + EXPORT_SYMBOL_GPL(crypto_init_akcipher_ops_sig); 273 312 274 313 MODULE_LICENSE("GPL"); 275 314 MODULE_DESCRIPTION("Generic public key cipher type");
+20
crypto/internal.h
··· 18 18 #include <linux/numa.h> 19 19 #include <linux/refcount.h> 20 20 #include <linux/rwsem.h> 21 + #include <linux/scatterlist.h> 21 22 #include <linux/sched.h> 22 23 #include <linux/types.h> 23 24 25 + struct akcipher_request; 26 + struct crypto_akcipher; 24 27 struct crypto_instance; 25 28 struct crypto_template; 26 29 ··· 33 30 struct completion completion; 34 31 u32 mask; 35 32 bool test_started; 33 + }; 34 + 35 + struct crypto_akcipher_sync_data { 36 + struct crypto_akcipher *tfm; 37 + const void *src; 38 + void *dst; 39 + unsigned int slen; 40 + unsigned int dlen; 41 + 42 + struct akcipher_request *req; 43 + struct crypto_wait cwait; 44 + struct scatterlist sg[2]; 45 + u8 *buf; 36 46 }; 37 47 38 48 enum { ··· 126 110 const struct crypto_type *frontend, int node); 127 111 void *crypto_clone_tfm(const struct crypto_type *frontend, 128 112 struct crypto_tfm *otfm); 113 + 114 + int crypto_akcipher_sync_prep(struct crypto_akcipher_sync_data *data); 115 + int crypto_akcipher_sync_post(struct crypto_akcipher_sync_data *data, int err); 116 + int crypto_init_akcipher_ops_sig(struct crypto_tfm *tfm); 129 117 130 118 static inline void *crypto_create_tfm(struct crypto_alg *alg, 131 119 const struct crypto_type *frontend)
+159
crypto/sig.c
··· 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 inline struct crypto_sig *__crypto_sig_tfm(struct crypto_tfm *tfm) 25 + { 26 + return container_of(tfm, struct crypto_sig, base); 27 + } 28 + 29 + static int crypto_sig_init_tfm(struct crypto_tfm *tfm) 30 + { 31 + if (tfm->__crt_alg->cra_type != &crypto_sig_type) 32 + return crypto_init_akcipher_ops_sig(tfm); 33 + 34 + return 0; 35 + } 36 + 37 + static void __maybe_unused crypto_sig_show(struct seq_file *m, 38 + struct crypto_alg *alg) 39 + { 40 + seq_puts(m, "type : sig\n"); 41 + } 42 + 43 + static int __maybe_unused crypto_sig_report(struct sk_buff *skb, 44 + struct crypto_alg *alg) 45 + { 46 + struct crypto_report_akcipher rsig = {}; 47 + 48 + strscpy(rsig.type, "sig", sizeof(rsig.type)); 49 + 50 + return nla_put(skb, CRYPTOCFGA_REPORT_AKCIPHER, sizeof(rsig), &rsig); 51 + } 52 + 53 + static int __maybe_unused crypto_sig_report_stat(struct sk_buff *skb, 54 + struct crypto_alg *alg) 55 + { 56 + struct crypto_stat_akcipher rsig = {}; 57 + 58 + strscpy(rsig.type, "sig", sizeof(rsig.type)); 59 + 60 + return nla_put(skb, CRYPTOCFGA_STAT_AKCIPHER, sizeof(rsig), &rsig); 61 + } 62 + 63 + static const struct crypto_type crypto_sig_type = { 64 + .extsize = crypto_alg_extsize, 65 + .init_tfm = crypto_sig_init_tfm, 66 + #ifdef CONFIG_PROC_FS 67 + .show = crypto_sig_show, 68 + #endif 69 + #if IS_ENABLED(CONFIG_CRYPTO_USER) 70 + .report = crypto_sig_report, 71 + #endif 72 + #ifdef CONFIG_CRYPTO_STATS 73 + .report_stat = crypto_sig_report_stat, 74 + #endif 75 + .maskclear = ~CRYPTO_ALG_TYPE_MASK, 76 + .maskset = CRYPTO_ALG_TYPE_SIG_MASK, 77 + .type = CRYPTO_ALG_TYPE_SIG, 78 + .tfmsize = offsetof(struct crypto_sig, base), 79 + }; 80 + 81 + struct crypto_sig *crypto_alloc_sig(const char *alg_name, u32 type, u32 mask) 82 + { 83 + return crypto_alloc_tfm(alg_name, &crypto_sig_type, type, mask); 84 + } 85 + EXPORT_SYMBOL_GPL(crypto_alloc_sig); 86 + 87 + int crypto_sig_maxsize(struct crypto_sig *tfm) 88 + { 89 + struct crypto_akcipher **ctx = crypto_sig_ctx(tfm); 90 + 91 + return crypto_akcipher_maxsize(*ctx); 92 + } 93 + EXPORT_SYMBOL_GPL(crypto_sig_maxsize); 94 + 95 + int crypto_sig_sign(struct crypto_sig *tfm, 96 + const void *src, unsigned int slen, 97 + void *dst, unsigned int dlen) 98 + { 99 + struct crypto_akcipher **ctx = crypto_sig_ctx(tfm); 100 + struct crypto_akcipher_sync_data data = { 101 + .tfm = *ctx, 102 + .src = src, 103 + .dst = dst, 104 + .slen = slen, 105 + .dlen = dlen, 106 + }; 107 + 108 + return crypto_akcipher_sync_prep(&data) ?: 109 + crypto_akcipher_sync_post(&data, 110 + crypto_akcipher_sign(data.req)); 111 + } 112 + EXPORT_SYMBOL_GPL(crypto_sig_sign); 113 + 114 + int crypto_sig_verify(struct crypto_sig *tfm, 115 + const void *src, unsigned int slen, 116 + const void *digest, unsigned int dlen) 117 + { 118 + struct crypto_akcipher **ctx = crypto_sig_ctx(tfm); 119 + struct crypto_akcipher_sync_data data = { 120 + .tfm = *ctx, 121 + .src = src, 122 + .slen = slen, 123 + .dlen = dlen, 124 + }; 125 + int err; 126 + 127 + err = crypto_akcipher_sync_prep(&data); 128 + if (err) 129 + return err; 130 + 131 + sg_init_table(data.sg, 2); 132 + sg_set_buf(&data.sg[0], src, slen); 133 + sg_set_buf(&data.sg[1], digest, dlen); 134 + 135 + return crypto_akcipher_sync_post(&data, 136 + crypto_akcipher_verify(data.req)); 137 + } 138 + EXPORT_SYMBOL_GPL(crypto_sig_verify); 139 + 140 + int crypto_sig_set_pubkey(struct crypto_sig *tfm, 141 + const void *key, unsigned int keylen) 142 + { 143 + struct crypto_akcipher **ctx = crypto_sig_ctx(tfm); 144 + 145 + return crypto_akcipher_set_pub_key(*ctx, key, keylen); 146 + } 147 + EXPORT_SYMBOL_GPL(crypto_sig_set_pubkey); 148 + 149 + int crypto_sig_set_privkey(struct crypto_sig *tfm, 150 + const void *key, unsigned int keylen) 151 + { 152 + struct crypto_akcipher **ctx = crypto_sig_ctx(tfm); 153 + 154 + return crypto_akcipher_set_priv_key(*ctx, key, keylen); 155 + } 156 + EXPORT_SYMBOL_GPL(crypto_sig_set_privkey); 157 + 158 + MODULE_LICENSE("GPL"); 159 + MODULE_DESCRIPTION("Public Key Signature Algorithms");
+17
include/crypto/internal/sig.h
··· 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 + #ifndef _CRYPTO_INTERNAL_SIG_H 8 + #define _CRYPTO_INTERNAL_SIG_H 9 + 10 + #include <crypto/algapi.h> 11 + #include <crypto/sig.h> 12 + 13 + static inline void *crypto_sig_ctx(struct crypto_sig *tfm) 14 + { 15 + return crypto_tfm_ctx(&tfm->base); 16 + } 17 + #endif
+140
include/crypto/sig.h
··· 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 + #ifndef _CRYPTO_SIG_H 8 + #define _CRYPTO_SIG_H 9 + 10 + #include <linux/crypto.h> 11 + 12 + /** 13 + * struct crypto_sig - user-instantiated objects which encapsulate 14 + * algorithms and core processing logic 15 + * 16 + * @base: Common crypto API algorithm data structure 17 + */ 18 + struct crypto_sig { 19 + struct crypto_tfm base; 20 + }; 21 + 22 + /** 23 + * DOC: Generic Public Key Signature API 24 + * 25 + * The Public Key Signature API is used with the algorithms of type 26 + * CRYPTO_ALG_TYPE_SIG (listed as type "sig" in /proc/crypto) 27 + */ 28 + 29 + /** 30 + * crypto_alloc_sig() - allocate signature tfm handle 31 + * @alg_name: is the cra_name / name or cra_driver_name / driver name of the 32 + * signing algorithm e.g. "ecdsa" 33 + * @type: specifies the type of the algorithm 34 + * @mask: specifies the mask for the algorithm 35 + * 36 + * Allocate a handle for public key signature algorithm. The returned struct 37 + * crypto_sig is the handle that is required for any subsequent 38 + * API invocation for signature operations. 39 + * 40 + * Return: allocated handle in case of success; IS_ERR() is true in case 41 + * of an error, PTR_ERR() returns the error code. 42 + */ 43 + struct crypto_sig *crypto_alloc_sig(const char *alg_name, u32 type, u32 mask); 44 + 45 + static inline struct crypto_tfm *crypto_sig_tfm(struct crypto_sig *tfm) 46 + { 47 + return &tfm->base; 48 + } 49 + 50 + /** 51 + * crypto_free_sig() - free signature tfm handle 52 + * 53 + * @tfm: signature tfm handle allocated with crypto_alloc_sig() 54 + * 55 + * If @tfm is a NULL or error pointer, this function does nothing. 56 + */ 57 + static inline void crypto_free_sig(struct crypto_sig *tfm) 58 + { 59 + crypto_destroy_tfm(tfm, crypto_sig_tfm(tfm)); 60 + } 61 + 62 + /** 63 + * crypto_sig_maxsize() - Get len for output buffer 64 + * 65 + * Function returns the dest buffer size required for a given key. 66 + * Function assumes that the key is already set in the transformation. If this 67 + * function is called without a setkey or with a failed setkey, you will end up 68 + * in a NULL dereference. 69 + * 70 + * @tfm: signature tfm handle allocated with crypto_alloc_sig() 71 + */ 72 + int crypto_sig_maxsize(struct crypto_sig *tfm); 73 + 74 + /** 75 + * crypto_sig_sign() - Invoke signing operation 76 + * 77 + * Function invokes the specific signing operation for a given algorithm 78 + * 79 + * @tfm: signature tfm handle allocated with crypto_alloc_sig() 80 + * @src: source buffer 81 + * @slen: source length 82 + * @dst: destinatino obuffer 83 + * @dlen: destination length 84 + * 85 + * Return: zero on success; error code in case of error 86 + */ 87 + int crypto_sig_sign(struct crypto_sig *tfm, 88 + const void *src, unsigned int slen, 89 + void *dst, unsigned int dlen); 90 + 91 + /** 92 + * crypto_sig_verify() - Invoke signature verification 93 + * 94 + * Function invokes the specific signature verification operation 95 + * for a given algorithm. 96 + * 97 + * @tfm: signature tfm handle allocated with crypto_alloc_sig() 98 + * @src: source buffer 99 + * @slen: source length 100 + * @digest: digest 101 + * @dlen: digest length 102 + * 103 + * Return: zero on verification success; error code in case of error. 104 + */ 105 + int crypto_sig_verify(struct crypto_sig *tfm, 106 + const void *src, unsigned int slen, 107 + const void *digest, unsigned int dlen); 108 + 109 + /** 110 + * crypto_sig_set_pubkey() - Invoke set public key operation 111 + * 112 + * Function invokes the algorithm specific set key function, which knows 113 + * how to decode and interpret the encoded key and parameters 114 + * 115 + * @tfm: tfm handle 116 + * @key: BER encoded public key, algo OID, paramlen, BER encoded 117 + * parameters 118 + * @keylen: length of the key (not including other data) 119 + * 120 + * Return: zero on success; error code in case of error 121 + */ 122 + int crypto_sig_set_pubkey(struct crypto_sig *tfm, 123 + const void *key, unsigned int keylen); 124 + 125 + /** 126 + * crypto_sig_set_privkey() - Invoke set private key operation 127 + * 128 + * Function invokes the algorithm specific set key function, which knows 129 + * how to decode and interpret the encoded key and parameters 130 + * 131 + * @tfm: tfm handle 132 + * @key: BER encoded private key, algo OID, paramlen, BER encoded 133 + * parameters 134 + * @keylen: length of the key (not including other data) 135 + * 136 + * Return: zero on success; error code in case of error 137 + */ 138 + int crypto_sig_set_privkey(struct crypto_sig *tfm, 139 + const void *key, unsigned int keylen); 140 + #endif
+2 -1
include/linux/crypto.h
··· 25 25 #define CRYPTO_ALG_TYPE_COMPRESS 0x00000002 26 26 #define CRYPTO_ALG_TYPE_AEAD 0x00000003 27 27 #define CRYPTO_ALG_TYPE_SKCIPHER 0x00000005 28 + #define CRYPTO_ALG_TYPE_AKCIPHER 0x00000006 29 + #define CRYPTO_ALG_TYPE_SIG 0x00000007 28 30 #define CRYPTO_ALG_TYPE_KPP 0x00000008 29 31 #define CRYPTO_ALG_TYPE_ACOMPRESS 0x0000000a 30 32 #define CRYPTO_ALG_TYPE_SCOMPRESS 0x0000000b 31 33 #define CRYPTO_ALG_TYPE_RNG 0x0000000c 32 - #define CRYPTO_ALG_TYPE_AKCIPHER 0x0000000d 33 34 #define CRYPTO_ALG_TYPE_HASH 0x0000000e 34 35 #define CRYPTO_ALG_TYPE_SHASH 0x0000000e 35 36 #define CRYPTO_ALG_TYPE_AHASH 0x0000000f