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 * struct sig_alg - generic public key signature algorithm 24 * 25 * @sign: Function performs a sign operation as defined by public key 26 * algorithm. Optional. 27 * @verify: Function performs a complete verify operation as defined by 28 * public key algorithm, returning verification status. Optional. 29 * @set_pub_key: Function invokes the algorithm specific set public key 30 * function, which knows how to decode and interpret 31 * the BER encoded public key and parameters. Mandatory. 32 * @set_priv_key: Function invokes the algorithm specific set private key 33 * function, which knows how to decode and interpret 34 * the BER encoded private key and parameters. Optional. 35 * @key_size: Function returns key size. Mandatory. 36 * @digest_size: Function returns maximum digest size. Optional. 37 * @max_size: Function returns maximum signature size. Optional. 38 * @init: Initialize the cryptographic transformation object. 39 * This function is used to initialize the cryptographic 40 * transformation object. This function is called only once at 41 * the instantiation time, right after the transformation context 42 * was allocated. In case the cryptographic hardware has some 43 * special requirements which need to be handled by software, this 44 * function shall check for the precise requirement of the 45 * transformation and put any software fallbacks in place. 46 * @exit: Deinitialize the cryptographic transformation object. This is a 47 * counterpart to @init, used to remove various changes set in 48 * @init. 49 * 50 * @base: Common crypto API algorithm data structure 51 */ 52 struct sig_alg { 53 int (*sign)(struct crypto_sig *tfm, 54 const void *src, unsigned int slen, 55 void *dst, unsigned int dlen); 56 int (*verify)(struct crypto_sig *tfm, 57 const void *src, unsigned int slen, 58 const void *digest, unsigned int dlen); 59 int (*set_pub_key)(struct crypto_sig *tfm, 60 const void *key, unsigned int keylen); 61 int (*set_priv_key)(struct crypto_sig *tfm, 62 const void *key, unsigned int keylen); 63 unsigned int (*key_size)(struct crypto_sig *tfm); 64 unsigned int (*digest_size)(struct crypto_sig *tfm); 65 unsigned int (*max_size)(struct crypto_sig *tfm); 66 int (*init)(struct crypto_sig *tfm); 67 void (*exit)(struct crypto_sig *tfm); 68 69 struct crypto_alg base; 70 }; 71 72 /** 73 * DOC: Generic Public Key Signature API 74 * 75 * The Public Key Signature API is used with the algorithms of type 76 * CRYPTO_ALG_TYPE_SIG (listed as type "sig" in /proc/crypto) 77 */ 78 79 /** 80 * crypto_alloc_sig() - allocate signature tfm handle 81 * @alg_name: is the cra_name / name or cra_driver_name / driver name of the 82 * signing algorithm e.g. "ecdsa" 83 * @type: specifies the type of the algorithm 84 * @mask: specifies the mask for the algorithm 85 * 86 * Allocate a handle for public key signature algorithm. The returned struct 87 * crypto_sig is the handle that is required for any subsequent 88 * API invocation for signature operations. 89 * 90 * Return: allocated handle in case of success; IS_ERR() is true in case 91 * of an error, PTR_ERR() returns the error code. 92 */ 93 struct crypto_sig *crypto_alloc_sig(const char *alg_name, u32 type, u32 mask); 94 95 static inline struct crypto_tfm *crypto_sig_tfm(struct crypto_sig *tfm) 96 { 97 return &tfm->base; 98 } 99 100 static inline struct crypto_sig *__crypto_sig_tfm(struct crypto_tfm *tfm) 101 { 102 return container_of(tfm, struct crypto_sig, base); 103 } 104 105 static inline struct sig_alg *__crypto_sig_alg(struct crypto_alg *alg) 106 { 107 return container_of(alg, struct sig_alg, base); 108 } 109 110 static inline struct sig_alg *crypto_sig_alg(struct crypto_sig *tfm) 111 { 112 return __crypto_sig_alg(crypto_sig_tfm(tfm)->__crt_alg); 113 } 114 115 /** 116 * crypto_free_sig() - free signature tfm handle 117 * 118 * @tfm: signature tfm handle allocated with crypto_alloc_sig() 119 * 120 * If @tfm is a NULL or error pointer, this function does nothing. 121 */ 122 static inline void crypto_free_sig(struct crypto_sig *tfm) 123 { 124 crypto_destroy_tfm(tfm, crypto_sig_tfm(tfm)); 125 } 126 127 /** 128 * crypto_sig_keysize() - Get key size 129 * 130 * Function returns the key size in bytes. 131 * Function assumes that the key is already set in the transformation. If this 132 * function is called without a setkey or with a failed setkey, you may end up 133 * in a NULL dereference. 134 * 135 * @tfm: signature tfm handle allocated with crypto_alloc_sig() 136 */ 137 static inline unsigned int crypto_sig_keysize(struct crypto_sig *tfm) 138 { 139 struct sig_alg *alg = crypto_sig_alg(tfm); 140 141 return alg->key_size(tfm); 142 } 143 144 /** 145 * crypto_sig_digestsize() - Get maximum digest size 146 * 147 * Function returns the maximum digest size in bytes. 148 * Function assumes that the key is already set in the transformation. If this 149 * function is called without a setkey or with a failed setkey, you may end up 150 * in a NULL dereference. 151 * 152 * @tfm: signature tfm handle allocated with crypto_alloc_sig() 153 */ 154 static inline unsigned int crypto_sig_digestsize(struct crypto_sig *tfm) 155 { 156 struct sig_alg *alg = crypto_sig_alg(tfm); 157 158 return alg->digest_size(tfm); 159 } 160 161 /** 162 * crypto_sig_maxsize() - Get maximum signature size 163 * 164 * Function returns the maximum signature size in bytes. 165 * Function assumes that the key is already set in the transformation. If this 166 * function is called without a setkey or with a failed setkey, you may end up 167 * in a NULL dereference. 168 * 169 * @tfm: signature tfm handle allocated with crypto_alloc_sig() 170 */ 171 static inline unsigned int crypto_sig_maxsize(struct crypto_sig *tfm) 172 { 173 struct sig_alg *alg = crypto_sig_alg(tfm); 174 175 return alg->max_size(tfm); 176 } 177 178 /** 179 * crypto_sig_sign() - Invoke signing operation 180 * 181 * Function invokes the specific signing operation for a given algorithm 182 * 183 * @tfm: signature tfm handle allocated with crypto_alloc_sig() 184 * @src: source buffer 185 * @slen: source length 186 * @dst: destination obuffer 187 * @dlen: destination length 188 * 189 * Return: zero on success; error code in case of error 190 */ 191 static inline int crypto_sig_sign(struct crypto_sig *tfm, 192 const void *src, unsigned int slen, 193 void *dst, unsigned int dlen) 194 { 195 struct sig_alg *alg = crypto_sig_alg(tfm); 196 197 return alg->sign(tfm, src, slen, dst, dlen); 198 } 199 200 /** 201 * crypto_sig_verify() - Invoke signature verification 202 * 203 * Function invokes the specific signature verification operation 204 * for a given algorithm. 205 * 206 * @tfm: signature tfm handle allocated with crypto_alloc_sig() 207 * @src: source buffer 208 * @slen: source length 209 * @digest: digest 210 * @dlen: digest length 211 * 212 * Return: zero on verification success; error code in case of error. 213 */ 214 static inline int crypto_sig_verify(struct crypto_sig *tfm, 215 const void *src, unsigned int slen, 216 const void *digest, unsigned int dlen) 217 { 218 struct sig_alg *alg = crypto_sig_alg(tfm); 219 220 return alg->verify(tfm, src, slen, digest, dlen); 221 } 222 223 /** 224 * crypto_sig_set_pubkey() - Invoke set public key operation 225 * 226 * Function invokes the algorithm specific set key function, which knows 227 * how to decode and interpret the encoded key and parameters 228 * 229 * @tfm: tfm handle 230 * @key: BER encoded public key, algo OID, paramlen, BER encoded 231 * parameters 232 * @keylen: length of the key (not including other data) 233 * 234 * Return: zero on success; error code in case of error 235 */ 236 static inline int crypto_sig_set_pubkey(struct crypto_sig *tfm, 237 const void *key, unsigned int keylen) 238 { 239 struct sig_alg *alg = crypto_sig_alg(tfm); 240 241 return alg->set_pub_key(tfm, key, keylen); 242 } 243 244 /** 245 * crypto_sig_set_privkey() - Invoke set private key operation 246 * 247 * Function invokes the algorithm specific set key function, which knows 248 * how to decode and interpret the encoded key and parameters 249 * 250 * @tfm: tfm handle 251 * @key: BER encoded private key, algo OID, paramlen, BER encoded 252 * parameters 253 * @keylen: length of the key (not including other data) 254 * 255 * Return: zero on success; error code in case of error 256 */ 257 static inline int crypto_sig_set_privkey(struct crypto_sig *tfm, 258 const void *key, unsigned int keylen) 259 { 260 struct sig_alg *alg = crypto_sig_alg(tfm); 261 262 return alg->set_priv_key(tfm, key, keylen); 263 } 264 #endif 265