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_POW2(crypto_sig_keysize(ctx->child), 85 sizeof(u64) * BITS_PER_BYTE); 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 = DIV_ROUND_UP_POW2(crypto_sig_keysize(ctx->child), 107 BITS_PER_BYTE); 108 109 /* 110 * Verify takes ECDSA-Sig-Value (described in RFC 5480) as input, 111 * which is actually 2 'key_size'-bit integers encoded in ASN.1. 112 * Account for the ASN.1 encoding overhead here. 113 * 114 * NIST P192/256/384 may prepend a '0' to a coordinate to indicate 115 * a positive integer. NIST P521 never needs it. 116 */ 117 if (strcmp(alg->base.cra_name, "ecdsa-nist-p521") != 0) 118 slen += 1; 119 120 /* Length of encoding the x & y coordinates */ 121 slen = 2 * (slen + 2); 122 123 /* 124 * If coordinate encoding takes at least 128 bytes then an 125 * additional byte for length encoding is needed. 126 */ 127 return 1 + (slen >= 128) + 1 + slen; 128 } 129 130 static unsigned int ecdsa_x962_digest_size(struct crypto_sig *tfm) 131 { 132 struct ecdsa_x962_ctx *ctx = crypto_sig_ctx(tfm); 133 134 return crypto_sig_digestsize(ctx->child); 135 } 136 137 static int ecdsa_x962_set_pub_key(struct crypto_sig *tfm, 138 const void *key, unsigned int keylen) 139 { 140 struct ecdsa_x962_ctx *ctx = crypto_sig_ctx(tfm); 141 142 return crypto_sig_set_pubkey(ctx->child, key, keylen); 143 } 144 145 static int ecdsa_x962_init_tfm(struct crypto_sig *tfm) 146 { 147 struct sig_instance *inst = sig_alg_instance(tfm); 148 struct crypto_sig_spawn *spawn = sig_instance_ctx(inst); 149 struct ecdsa_x962_ctx *ctx = crypto_sig_ctx(tfm); 150 struct crypto_sig *child_tfm; 151 152 child_tfm = crypto_spawn_sig(spawn); 153 if (IS_ERR(child_tfm)) 154 return PTR_ERR(child_tfm); 155 156 ctx->child = child_tfm; 157 158 return 0; 159 } 160 161 static void ecdsa_x962_exit_tfm(struct crypto_sig *tfm) 162 { 163 struct ecdsa_x962_ctx *ctx = crypto_sig_ctx(tfm); 164 165 crypto_free_sig(ctx->child); 166 } 167 168 static void ecdsa_x962_free(struct sig_instance *inst) 169 { 170 struct crypto_sig_spawn *spawn = sig_instance_ctx(inst); 171 172 crypto_drop_sig(spawn); 173 kfree(inst); 174 } 175 176 static int ecdsa_x962_create(struct crypto_template *tmpl, struct rtattr **tb) 177 { 178 struct crypto_sig_spawn *spawn; 179 struct sig_instance *inst; 180 struct sig_alg *ecdsa_alg; 181 u32 mask; 182 int err; 183 184 err = crypto_check_attr_type(tb, CRYPTO_ALG_TYPE_SIG, &mask); 185 if (err) 186 return err; 187 188 inst = kzalloc(sizeof(*inst) + sizeof(*spawn), GFP_KERNEL); 189 if (!inst) 190 return -ENOMEM; 191 192 spawn = sig_instance_ctx(inst); 193 194 err = crypto_grab_sig(spawn, sig_crypto_instance(inst), 195 crypto_attr_alg_name(tb[1]), 0, mask); 196 if (err) 197 goto err_free_inst; 198 199 ecdsa_alg = crypto_spawn_sig_alg(spawn); 200 201 err = -EINVAL; 202 if (strncmp(ecdsa_alg->base.cra_name, "ecdsa", 5) != 0) 203 goto err_free_inst; 204 205 err = crypto_inst_setname(sig_crypto_instance(inst), tmpl->name, 206 &ecdsa_alg->base); 207 if (err) 208 goto err_free_inst; 209 210 inst->alg.base.cra_priority = ecdsa_alg->base.cra_priority; 211 inst->alg.base.cra_ctxsize = sizeof(struct ecdsa_x962_ctx); 212 213 inst->alg.init = ecdsa_x962_init_tfm; 214 inst->alg.exit = ecdsa_x962_exit_tfm; 215 216 inst->alg.verify = ecdsa_x962_verify; 217 inst->alg.key_size = ecdsa_x962_key_size; 218 inst->alg.max_size = ecdsa_x962_max_size; 219 inst->alg.digest_size = ecdsa_x962_digest_size; 220 inst->alg.set_pub_key = ecdsa_x962_set_pub_key; 221 222 inst->free = ecdsa_x962_free; 223 224 err = sig_register_instance(tmpl, inst); 225 if (err) { 226 err_free_inst: 227 ecdsa_x962_free(inst); 228 } 229 return err; 230 } 231 232 struct crypto_template ecdsa_x962_tmpl = { 233 .name = "x962", 234 .create = ecdsa_x962_create, 235 .module = THIS_MODULE, 236 }; 237 238 MODULE_ALIAS_CRYPTO("x962"); 239