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