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