1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * ECDSA X9.62 signature encoding 4 * 5 * Copyright (c) 2021 IBM Corporation 6 * Copyright (c) 2024 Intel Corporation 7 */ 8 9 #include <linux/asn1_decoder.h> 10 #include <linux/err.h> 11 #include <linux/module.h> 12 #include <crypto/algapi.h> 13 #include <crypto/sig.h> 14 #include <crypto/internal/ecc.h> 15 #include <crypto/internal/sig.h> 16 17 #include "ecdsasignature.asn1.h" 18 19 struct ecdsa_x962_ctx { 20 struct crypto_sig *child; 21 }; 22 23 struct ecdsa_x962_signature_ctx { 24 struct ecdsa_raw_sig sig; 25 unsigned int ndigits; 26 }; 27 28 /* Get the r and s components of a signature from the X.509 certificate. */ 29 static int ecdsa_get_signature_rs(u64 *dest, size_t hdrlen, unsigned char tag, 30 const void *value, size_t vlen, 31 unsigned int ndigits) 32 { 33 size_t bufsize = ndigits * sizeof(u64); 34 const char *d = value; 35 36 if (!value || !vlen || vlen > bufsize + 1) 37 return -EINVAL; 38 39 /* 40 * vlen may be 1 byte larger than bufsize due to a leading zero byte 41 * (necessary if the most significant bit of the integer is set). 42 */ 43 if (vlen > bufsize) { 44 /* skip over leading zeros that make 'value' a positive int */ 45 if (*d == 0) { 46 vlen -= 1; 47 d++; 48 } else { 49 return -EINVAL; 50 } 51 } 52 53 ecc_digits_from_bytes(d, vlen, dest, ndigits); 54 55 return 0; 56 } 57 58 int ecdsa_get_signature_r(void *context, size_t hdrlen, unsigned char tag, 59 const void *value, size_t vlen) 60 { 61 struct ecdsa_x962_signature_ctx *sig_ctx = context; 62 63 return ecdsa_get_signature_rs(sig_ctx->sig.r, hdrlen, tag, value, vlen, 64 sig_ctx->ndigits); 65 } 66 67 int ecdsa_get_signature_s(void *context, size_t hdrlen, unsigned char tag, 68 const void *value, size_t vlen) 69 { 70 struct ecdsa_x962_signature_ctx *sig_ctx = context; 71 72 return ecdsa_get_signature_rs(sig_ctx->sig.s, hdrlen, tag, value, vlen, 73 sig_ctx->ndigits); 74 } 75 76 static int ecdsa_x962_verify(struct crypto_sig *tfm, 77 const void *src, unsigned int slen, 78 const void *digest, unsigned int dlen) 79 { 80 struct ecdsa_x962_ctx *ctx = crypto_sig_ctx(tfm); 81 struct ecdsa_x962_signature_ctx sig_ctx; 82 int err; 83 84 sig_ctx.ndigits = DIV_ROUND_UP(crypto_sig_keysize(ctx->child), 85 sizeof(u64)); 86 87 err = asn1_ber_decoder(&ecdsasignature_decoder, &sig_ctx, src, slen); 88 if (err < 0) 89 return err; 90 91 return crypto_sig_verify(ctx->child, &sig_ctx.sig, sizeof(sig_ctx.sig), 92 digest, dlen); 93 } 94 95 static unsigned int ecdsa_x962_key_size(struct crypto_sig *tfm) 96 { 97 struct ecdsa_x962_ctx *ctx = crypto_sig_ctx(tfm); 98 99 return crypto_sig_keysize(ctx->child); 100 } 101 102 static unsigned int ecdsa_x962_max_size(struct crypto_sig *tfm) 103 { 104 struct ecdsa_x962_ctx *ctx = crypto_sig_ctx(tfm); 105 struct sig_alg *alg = crypto_sig_alg(ctx->child); 106 int slen = crypto_sig_keysize(ctx->child); 107 108 /* 109 * Verify takes ECDSA-Sig-Value (described in RFC 5480) as input, 110 * which is actually 2 'key_size'-bit integers encoded in ASN.1. 111 * Account for the ASN.1 encoding overhead here. 112 * 113 * NIST P192/256/384 may prepend a '0' to a coordinate to indicate 114 * a positive integer. NIST P521 never needs it. 115 */ 116 if (strcmp(alg->base.cra_name, "ecdsa-nist-p521") != 0) 117 slen += 1; 118 119 /* Length of encoding the x & y coordinates */ 120 slen = 2 * (slen + 2); 121 122 /* 123 * If coordinate encoding takes at least 128 bytes then an 124 * additional byte for length encoding is needed. 125 */ 126 return 1 + (slen >= 128) + 1 + slen; 127 } 128 129 static unsigned int ecdsa_x962_digest_size(struct crypto_sig *tfm) 130 { 131 struct ecdsa_x962_ctx *ctx = crypto_sig_ctx(tfm); 132 133 return crypto_sig_digestsize(ctx->child); 134 } 135 136 static int ecdsa_x962_set_pub_key(struct crypto_sig *tfm, 137 const void *key, unsigned int keylen) 138 { 139 struct ecdsa_x962_ctx *ctx = crypto_sig_ctx(tfm); 140 141 return crypto_sig_set_pubkey(ctx->child, key, keylen); 142 } 143 144 static int ecdsa_x962_init_tfm(struct crypto_sig *tfm) 145 { 146 struct sig_instance *inst = sig_alg_instance(tfm); 147 struct crypto_sig_spawn *spawn = sig_instance_ctx(inst); 148 struct ecdsa_x962_ctx *ctx = crypto_sig_ctx(tfm); 149 struct crypto_sig *child_tfm; 150 151 child_tfm = crypto_spawn_sig(spawn); 152 if (IS_ERR(child_tfm)) 153 return PTR_ERR(child_tfm); 154 155 ctx->child = child_tfm; 156 157 return 0; 158 } 159 160 static void ecdsa_x962_exit_tfm(struct crypto_sig *tfm) 161 { 162 struct ecdsa_x962_ctx *ctx = crypto_sig_ctx(tfm); 163 164 crypto_free_sig(ctx->child); 165 } 166 167 static void ecdsa_x962_free(struct sig_instance *inst) 168 { 169 struct crypto_sig_spawn *spawn = sig_instance_ctx(inst); 170 171 crypto_drop_sig(spawn); 172 kfree(inst); 173 } 174 175 static int ecdsa_x962_create(struct crypto_template *tmpl, struct rtattr **tb) 176 { 177 struct crypto_sig_spawn *spawn; 178 struct sig_instance *inst; 179 struct sig_alg *ecdsa_alg; 180 u32 mask; 181 int err; 182 183 err = crypto_check_attr_type(tb, CRYPTO_ALG_TYPE_SIG, &mask); 184 if (err) 185 return err; 186 187 inst = kzalloc(sizeof(*inst) + sizeof(*spawn), GFP_KERNEL); 188 if (!inst) 189 return -ENOMEM; 190 191 spawn = sig_instance_ctx(inst); 192 193 err = crypto_grab_sig(spawn, sig_crypto_instance(inst), 194 crypto_attr_alg_name(tb[1]), 0, mask); 195 if (err) 196 goto err_free_inst; 197 198 ecdsa_alg = crypto_spawn_sig_alg(spawn); 199 200 err = -EINVAL; 201 if (strncmp(ecdsa_alg->base.cra_name, "ecdsa", 5) != 0) 202 goto err_free_inst; 203 204 err = crypto_inst_setname(sig_crypto_instance(inst), tmpl->name, 205 &ecdsa_alg->base); 206 if (err) 207 goto err_free_inst; 208 209 inst->alg.base.cra_priority = ecdsa_alg->base.cra_priority; 210 inst->alg.base.cra_ctxsize = sizeof(struct ecdsa_x962_ctx); 211 212 inst->alg.init = ecdsa_x962_init_tfm; 213 inst->alg.exit = ecdsa_x962_exit_tfm; 214 215 inst->alg.verify = ecdsa_x962_verify; 216 inst->alg.key_size = ecdsa_x962_key_size; 217 inst->alg.max_size = ecdsa_x962_max_size; 218 inst->alg.digest_size = ecdsa_x962_digest_size; 219 inst->alg.set_pub_key = ecdsa_x962_set_pub_key; 220 221 inst->free = ecdsa_x962_free; 222 223 err = sig_register_instance(tmpl, inst); 224 if (err) { 225 err_free_inst: 226 ecdsa_x962_free(inst); 227 } 228 return err; 229 } 230 231 struct crypto_template ecdsa_x962_tmpl = { 232 .name = "x962", 233 .create = ecdsa_x962_create, 234 .module = THIS_MODULE, 235 }; 236 237 MODULE_ALIAS_CRYPTO("x962"); 238