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 int ecdsa_x962_set_pub_key(struct crypto_sig *tfm, 103 const void *key, unsigned int keylen) 104 { 105 struct ecdsa_x962_ctx *ctx = crypto_sig_ctx(tfm); 106 107 return crypto_sig_set_pubkey(ctx->child, key, keylen); 108 } 109 110 static int ecdsa_x962_init_tfm(struct crypto_sig *tfm) 111 { 112 struct sig_instance *inst = sig_alg_instance(tfm); 113 struct crypto_sig_spawn *spawn = sig_instance_ctx(inst); 114 struct ecdsa_x962_ctx *ctx = crypto_sig_ctx(tfm); 115 struct crypto_sig *child_tfm; 116 117 child_tfm = crypto_spawn_sig(spawn); 118 if (IS_ERR(child_tfm)) 119 return PTR_ERR(child_tfm); 120 121 ctx->child = child_tfm; 122 123 return 0; 124 } 125 126 static void ecdsa_x962_exit_tfm(struct crypto_sig *tfm) 127 { 128 struct ecdsa_x962_ctx *ctx = crypto_sig_ctx(tfm); 129 130 crypto_free_sig(ctx->child); 131 } 132 133 static void ecdsa_x962_free(struct sig_instance *inst) 134 { 135 struct crypto_sig_spawn *spawn = sig_instance_ctx(inst); 136 137 crypto_drop_sig(spawn); 138 kfree(inst); 139 } 140 141 static int ecdsa_x962_create(struct crypto_template *tmpl, struct rtattr **tb) 142 { 143 struct crypto_sig_spawn *spawn; 144 struct sig_instance *inst; 145 struct sig_alg *ecdsa_alg; 146 u32 mask; 147 int err; 148 149 err = crypto_check_attr_type(tb, CRYPTO_ALG_TYPE_SIG, &mask); 150 if (err) 151 return err; 152 153 inst = kzalloc(sizeof(*inst) + sizeof(*spawn), GFP_KERNEL); 154 if (!inst) 155 return -ENOMEM; 156 157 spawn = sig_instance_ctx(inst); 158 159 err = crypto_grab_sig(spawn, sig_crypto_instance(inst), 160 crypto_attr_alg_name(tb[1]), 0, mask); 161 if (err) 162 goto err_free_inst; 163 164 ecdsa_alg = crypto_spawn_sig_alg(spawn); 165 166 err = -EINVAL; 167 if (strncmp(ecdsa_alg->base.cra_name, "ecdsa", 5) != 0) 168 goto err_free_inst; 169 170 err = crypto_inst_setname(sig_crypto_instance(inst), tmpl->name, 171 &ecdsa_alg->base); 172 if (err) 173 goto err_free_inst; 174 175 inst->alg.base.cra_priority = ecdsa_alg->base.cra_priority; 176 inst->alg.base.cra_ctxsize = sizeof(struct ecdsa_x962_ctx); 177 178 inst->alg.init = ecdsa_x962_init_tfm; 179 inst->alg.exit = ecdsa_x962_exit_tfm; 180 181 inst->alg.verify = ecdsa_x962_verify; 182 inst->alg.key_size = ecdsa_x962_key_size; 183 inst->alg.set_pub_key = ecdsa_x962_set_pub_key; 184 185 inst->free = ecdsa_x962_free; 186 187 err = sig_register_instance(tmpl, inst); 188 if (err) { 189 err_free_inst: 190 ecdsa_x962_free(inst); 191 } 192 return err; 193 } 194 195 struct crypto_template ecdsa_x962_tmpl = { 196 .name = "x962", 197 .create = ecdsa_x962_create, 198 .module = THIS_MODULE, 199 }; 200 201 MODULE_ALIAS_CRYPTO("x962"); 202