File Index
Files and directories
Sign in
FILE

ecdsa-p1363.c

File preview with syntax highlighting.

linux-6.19.14/crypto/ecdsa-p1363.c C
  1// SPDX-License-Identifier: GPL-2.0
  2/*
  3 * ECDSA P1363 signature encoding
  4 *
  5 * Copyright (c) 2024 Intel Corporation
  6 */
  7
  8#include <linux/err.h>
  9#include <linux/module.h>
 10#include <crypto/algapi.h>
 11#include <crypto/sig.h>
 12#include <crypto/internal/ecc.h>
 13#include <crypto/internal/sig.h>
 14
 15struct ecdsa_p1363_ctx {
 16	struct crypto_sig *child;
 17};
 18
 19static int ecdsa_p1363_verify(struct crypto_sig *tfm,
 20			      const void *src, unsigned int slen,
 21			      const void *digest, unsigned int dlen)
 22{
 23	struct ecdsa_p1363_ctx *ctx = crypto_sig_ctx(tfm);
 24	unsigned int keylen = DIV_ROUND_UP_POW2(crypto_sig_keysize(ctx->child),
 25						BITS_PER_BYTE);
 26	unsigned int ndigits = DIV_ROUND_UP_POW2(keylen, sizeof(u64));
 27	struct ecdsa_raw_sig sig;
 28
 29	if (slen != 2 * keylen)
 30		return -EINVAL;
 31
 32	ecc_digits_from_bytes(src, keylen, sig.r, ndigits);
 33	ecc_digits_from_bytes(src + keylen, keylen, sig.s, ndigits);
 34
 35	return crypto_sig_verify(ctx->child, &sig, sizeof(sig), digest, dlen);
 36}
 37
 38static unsigned int ecdsa_p1363_key_size(struct crypto_sig *tfm)
 39{
 40	struct ecdsa_p1363_ctx *ctx = crypto_sig_ctx(tfm);
 41
 42	return crypto_sig_keysize(ctx->child);
 43}
 44
 45static unsigned int ecdsa_p1363_max_size(struct crypto_sig *tfm)
 46{
 47	struct ecdsa_p1363_ctx *ctx = crypto_sig_ctx(tfm);
 48
 49	return 2 * DIV_ROUND_UP_POW2(crypto_sig_keysize(ctx->child),
 50				     BITS_PER_BYTE);
 51}
 52
 53static unsigned int ecdsa_p1363_digest_size(struct crypto_sig *tfm)
 54{
 55	struct ecdsa_p1363_ctx *ctx = crypto_sig_ctx(tfm);
 56
 57	return crypto_sig_digestsize(ctx->child);
 58}
 59
 60static int ecdsa_p1363_set_pub_key(struct crypto_sig *tfm,
 61				   const void *key, unsigned int keylen)
 62{
 63	struct ecdsa_p1363_ctx *ctx = crypto_sig_ctx(tfm);
 64
 65	return crypto_sig_set_pubkey(ctx->child, key, keylen);
 66}
 67
 68static int ecdsa_p1363_init_tfm(struct crypto_sig *tfm)
 69{
 70	struct sig_instance *inst = sig_alg_instance(tfm);
 71	struct crypto_sig_spawn *spawn = sig_instance_ctx(inst);
 72	struct ecdsa_p1363_ctx *ctx = crypto_sig_ctx(tfm);
 73	struct crypto_sig *child_tfm;
 74
 75	child_tfm = crypto_spawn_sig(spawn);
 76	if (IS_ERR(child_tfm))
 77		return PTR_ERR(child_tfm);
 78
 79	ctx->child = child_tfm;
 80
 81	return 0;
 82}
 83
 84static void ecdsa_p1363_exit_tfm(struct crypto_sig *tfm)
 85{
 86	struct ecdsa_p1363_ctx *ctx = crypto_sig_ctx(tfm);
 87
 88	crypto_free_sig(ctx->child);
 89}
 90
 91static void ecdsa_p1363_free(struct sig_instance *inst)
 92{
 93	struct crypto_sig_spawn *spawn = sig_instance_ctx(inst);
 94
 95	crypto_drop_sig(spawn);
 96	kfree(inst);
 97}
 98
 99static int ecdsa_p1363_create(struct crypto_template *tmpl, struct rtattr **tb)
100{
101	struct crypto_sig_spawn *spawn;
102	struct sig_instance *inst;
103	struct sig_alg *ecdsa_alg;
104	u32 mask;
105	int err;
106
107	err = crypto_check_attr_type(tb, CRYPTO_ALG_TYPE_SIG, &mask);
108	if (err)
109		return err;
110
111	inst = kzalloc(sizeof(*inst) + sizeof(*spawn), GFP_KERNEL);
112	if (!inst)
113		return -ENOMEM;
114
115	spawn = sig_instance_ctx(inst);
116
117	err = crypto_grab_sig(spawn, sig_crypto_instance(inst),
118			      crypto_attr_alg_name(tb[1]), 0, mask);
119	if (err)
120		goto err_free_inst;
121
122	ecdsa_alg = crypto_spawn_sig_alg(spawn);
123
124	err = -EINVAL;
125	if (strncmp(ecdsa_alg->base.cra_name, "ecdsa", 5) != 0)
126		goto err_free_inst;
127
128	err = crypto_inst_setname(sig_crypto_instance(inst), tmpl->name,
129				  &ecdsa_alg->base);
130	if (err)
131		goto err_free_inst;
132
133	inst->alg.base.cra_priority = ecdsa_alg->base.cra_priority;
134	inst->alg.base.cra_ctxsize = sizeof(struct ecdsa_p1363_ctx);
135
136	inst->alg.init = ecdsa_p1363_init_tfm;
137	inst->alg.exit = ecdsa_p1363_exit_tfm;
138
139	inst->alg.verify = ecdsa_p1363_verify;
140	inst->alg.key_size = ecdsa_p1363_key_size;
141	inst->alg.max_size = ecdsa_p1363_max_size;
142	inst->alg.digest_size = ecdsa_p1363_digest_size;
143	inst->alg.set_pub_key = ecdsa_p1363_set_pub_key;
144
145	inst->free = ecdsa_p1363_free;
146
147	err = sig_register_instance(tmpl, inst);
148	if (err) {
149err_free_inst:
150		ecdsa_p1363_free(inst);
151	}
152	return err;
153}
154
155struct crypto_template ecdsa_p1363_tmpl = {
156	.name = "p1363",
157	.create = ecdsa_p1363_create,
158	.module = THIS_MODULE,
159};
160
161MODULE_ALIAS_CRYPTO("p1363");
~/ Read-only file preview.