2021-01-29 21:28:51

by Saulo Alessandre de Lima

[permalink] [raw]
Subject: [PATCH v2 0/4] ecdsa: this patch implement signature verification

From: Saulo Alessandre <[email protected]>

Why ECDSA on kernel:

I work on Brazilian Supreme Electoral Court [http://www.tse.jus.br], we are
using ECDSA for module and elf32 binaries verification including shared
libraries on about 450k T-DRE voting machines [5].

This is the first part of our try to contribution, we pretend to share the
elf32 signature mechanism and elf32 kernel verification and start to work
on elf64 verification too.

We have an team of about 12 techs, between cryptologist, developers,
testers, managers, staff and the coffee machine :). Recently we receive
authorization to share this codes.

Somes advantages from ECDSA are:
. is more secure against current methos of cracking [2];
. gives optimal security with shorter key lenghts [2];

First, comparing key size RSA vs ECDSA we have:

Table 1: Comparable key sizes table. ref [3]
|----------+-----+--------+
|Security in bits |
|----------+-----+--------+
|Symmetric | ECC | RSA |
| 80 | 163 | 1.024 |
| 112 | 233 | 2.240 |
| 128 | 283 | 3.072 |
| 192 | 409 | 7.680 |
| 256 | 571 | 15.360 |
|----------+-----+--------+

So, We need a bigger key in RSA to have the same security against ECDSA.
This can be see on [1] too.

Second, comparing speed performance RSA vs ECDSA we have:

Table 2: Signature performance table. ref: [3]
|-------------+------+------+
| Key Length | Time (s) |
|-----+-------+------+------+
| ECC | RSA | ECC | RSA |
|-----+-------+------+------+
| 163 | 1024 | 0.15 | 0.01 |
| 233 | 2240 | 0.34 | 0.15 |
| 283 | 3072 | 0.59 | 0.21 |
| 409 | 7680 | 1.18 | 1.53 |
| 571 | 15360 | 3.07 | 9.20 |
|-----+-------+------+------+

Table 3: Signature verification performance table. ref: [3]
|-------------+------+------+
| Key Length | Time (s) |
|-----+-------+------+------+
| ECC | RSA | ECC | RSA |
|-----+-------+------+------+
| 163 | 1024 | 0.23 | 0.01 |
| 233 | 2240 | 0.51 | 0.01 |
| 283 | 3072 | 0.86 | 0.01 |
| 409 | 7680 | 1.80 | 0.01 |
| 571 | 15360 | 4.53 | 0.03 |
|-----+-------+------+------+

On tables 2 and 3, we can see that ECDSA is more fast for strong key
signatures and very slow for verification when comparable to RSA.
Although something is not so fast to check, it pays off in safety.

References:
[1] - https://www.ecrypt.eu.org/csa/documents/D5.4-FinalAlgKeySizeProt.pdf
[2] - https://sectigostore.com/blog/ecdsa-vs-rsa-everything-you-need-to-know/
[3] - http://nicj.net/files/performance_comparison_of_elliptic_curve_and_rsa_digital_signatures.pdf
[4] - Mathematical-routines-for-the-NIST-prime-elliptic-curves.pdf [google it]
[5] - https://www.researchgate.net/publication/221046512_T-DRE_a_hardware_trusted_computing_base_for_direct_recording_electronic_vote_machines

---
Saulo Alessandre (4):
ecdsa: add params to ecdsa algo
ecdsa: prepare akcipher and x509 parser to use incoming ecdsa
ecdsa: change ecc.c and ecc.h to support ecdsa
ecdsa: implements ecdsa signature verification

Documentation/admin-guide/module-signing.rst | 10 +
crypto/Kconfig | 12 +
crypto/Makefile | 7 +
crypto/asymmetric_keys/pkcs7_parser.c | 7 +-
crypto/asymmetric_keys/pkcs7_verify.c | 5 +-
crypto/asymmetric_keys/public_key.c | 30 +-
crypto/asymmetric_keys/x509_cert_parser.c | 37 +-
crypto/ecc.c | 338 +++++++++---
crypto/ecc.h | 59 ++-
crypto/ecc_curve_defs.h | 82 +++
crypto/ecdsa.c | 509 +++++++++++++++++++
crypto/ecdsa_params.asn1 | 1 +
crypto/ecdsa_signature.asn1 | 6 +
crypto/testmgr.c | 17 +-
crypto/testmgr.h | 78 +++
include/crypto/ecdh.h | 2 +
include/linux/oid_registry.h | 12 +
lib/oid_registry.c | 100 ++++
18 files changed, 1201 insertions(+), 111 deletions(-)
create mode 100644 crypto/ecdsa.c
create mode 100644 crypto/ecdsa_params.asn1
create mode 100644 crypto/ecdsa_signature.asn1

--
2.25.1


2021-01-29 21:28:52

by Saulo Alessandre de Lima

[permalink] [raw]
Subject: [PATCH v2 4/4] ecdsa: implements ecdsa signature verification

From: Saulo Alessandre <[email protected]>

* Documentation/admin-guide/module-signing.rst
- Documents how to generate certificate and signature for (ECDSA).

* crypto/Kconfig
- ECDSA added into kernel Public-key cryptography section.

* crypto/Makefile
- add ECDSA objects and asn1 params to compile.

* crypto/ecdsa.c
- Elliptical Curve DSA verify implementation

* crypto/ecdsa_params.asn1
- Elliptical Curve DSA verify definitions

* crypto/ecdsa_signature.asn1
- Elliptical Curve DSA asn.1 parameters

* crypto/testmgr.c
- test_akcipher_one - modified to reflect the real code call for nist code;
- alg_test_descs - added ecdsa vector for test;

* crypto/testmgr.h
- ecdsa_tv_template - added to test ecdsa implementation;
---
Documentation/admin-guide/module-signing.rst | 10 +
crypto/Kconfig | 12 +
crypto/Makefile | 7 +
crypto/ecdsa.c | 509 +++++++++++++++++++
crypto/ecdsa_params.asn1 | 1 +
crypto/ecdsa_signature.asn1 | 6 +
crypto/testmgr.c | 17 +-
crypto/testmgr.h | 78 +++
8 files changed, 638 insertions(+), 2 deletions(-)
create mode 100644 crypto/ecdsa.c
create mode 100644 crypto/ecdsa_params.asn1
create mode 100644 crypto/ecdsa_signature.asn1

diff --git a/Documentation/admin-guide/module-signing.rst b/Documentation/admin-guide/module-signing.rst
index 7d7c7c8a545c..00ee487de84d 100644
--- a/Documentation/admin-guide/module-signing.rst
+++ b/Documentation/admin-guide/module-signing.rst
@@ -174,6 +174,16 @@ The full pathname for the resulting kernel_key.pem file can then be specified
in the ``CONFIG_MODULE_SIG_KEY`` option, and the certificate and key therein will
be used instead of an autogenerated keypair.

+It is also possible use the key private/public files using the ecdsa
+alghorithm that is more fast than rsa. For this, configure ``CONFIG_CRYPTO_ECDSA``
+and for generate key and certificate use the openssl commands.
+
+ openssl ecparam -gnenkey <prime256v1|secp384r1|secp521r1> \
+ -name -noout -out kernel_key.pem
+ openssl req -new -key kernel_key.pem -x509 -nodes -days 36500 -out kernel_key.x509
+
+To sign with ecdsa use the same way or manually using scripts/sign-file.
+

=========================
Public keys in the kernel
diff --git a/crypto/Kconfig b/crypto/Kconfig
index 9779c7f7531f..79bec162d9dd 100644
--- a/crypto/Kconfig
+++ b/crypto/Kconfig
@@ -224,6 +224,18 @@ config CRYPTO_RSA
help
Generic implementation of the RSA public key algorithm.

+config CRYPTO_ECDSA
+ tristate "ECDSA algorithm"
+ select CRYPTO_AKCIPHER
+ select CRYPTO_MANAGER
+ select MPILIB
+ select ASN1
+ help
+ Generic implementation of the ECDSA eliptical curve public key algorithm.
+ FIPS 186-3, Digital Signature Standard using Mathematical routines for
+ the NIST prime elliptic curves April 05, 2010. Compatible with openssl
+ command line tools.
+
config CRYPTO_DH
tristate "Diffie-Hellman algorithm"
select CRYPTO_KPP
diff --git a/crypto/Makefile b/crypto/Makefile
index cf23affb1678..0e0b33106c82 100644
--- a/crypto/Makefile
+++ b/crypto/Makefile
@@ -176,6 +176,13 @@ ecdh_generic-y += ecdh.o
ecdh_generic-y += ecdh_helper.o
obj-$(CONFIG_CRYPTO_ECDH) += ecdh_generic.o

+$(obj)/ecdsa_signature.asn1.o: $(obj)/ecdsa_signature.asn1.c $(obj)/ecdsa_signature.asn1.h
+$(obj)/ecdsa_params.asn1.o: $(obj)/ecdsa_params.asn1.c $(obj)/ecdsa_params.asn1.h
+clean-files += ecdsa_signature.asn1.c ecdsa_signature.asn1.h
+clean-files += ecdsa_params.asn1.c ecdsa_params.asn1.h
+ecdsa_generic-y := ecdsa_signature.asn1.o ecdsa_params.asn1.o ecdsa.o
+obj-$(CONFIG_CRYPTO_ECDSA) += ecdsa_generic.o
+
$(obj)/ecrdsa_params.asn1.o: $(obj)/ecrdsa_params.asn1.c $(obj)/ecrdsa_params.asn1.h
$(obj)/ecrdsa_pub_key.asn1.o: $(obj)/ecrdsa_pub_key.asn1.c $(obj)/ecrdsa_pub_key.asn1.h
$(obj)/ecrdsa.o: $(obj)/ecrdsa_params.asn1.h $(obj)/ecrdsa_pub_key.asn1.h
diff --git a/crypto/ecdsa.c b/crypto/ecdsa.c
new file mode 100644
index 000000000000..f33258c21db2
--- /dev/null
+++ b/crypto/ecdsa.c
@@ -0,0 +1,509 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Elliptic Curve Digital Signature Algorithm for Cryptographic API
+ *
+ * Copyright (c) 2019 Saulo Alessandre <[email protected]>
+ *
+ * References:
+ * Mathematical routines for the NIST prime elliptic curves April 05, 2010
+ * Technical Guideline TR-03111 - Elliptic Curve Cryptography
+ * FIPS 186-3, Digital Signature Standard
+ *
+ * this code is strongly embased on the ecrdsa code, written by
+ * Vitaly Chikunov <[email protected]>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ */
+
+#include <crypto/internal/akcipher.h>
+#include <crypto/akcipher.h>
+#include "crypto/public_key.h"
+#include <linux/module.h>
+#include <linux/crypto.h>
+#include <linux/scatterlist.h>
+#include <linux/oid_registry.h>
+#include <asm/unaligned.h>
+#include "ecc.h"
+#include "ecc_curve_defs.h"
+#include "ecdsa_signature.asn1.h"
+#include "ecdsa_params.asn1.h"
+
+#define MAX_DIGEST_SIZE 64
+
+#define ECDSA_MAX_BITS 521
+#define ECDSA_MAX_SIG_SIZE 140
+#define ECDSA_MAX_DIGITS 9
+
+struct ecdsa_ctx {
+ enum OID algo_oid; /* overall public key oid */
+ enum OID curve_oid; /* parameter */
+ enum OID digest_oid; /* parameter */
+ const struct ecc_curve *curve; /* curve from oid */
+ unsigned int digest_len; /* parameter (bytes) */
+ const char *digest; /* digest name from oid */
+ unsigned int key_len; /* @key length (bytes) */
+ const char *key; /* raw public key */
+ struct ecc_point pub_key;
+ u64 _pubp[2][ECDSA_MAX_DIGITS]; /* point storage for @pub_key */
+};
+
+struct ecdsa_sig_ctx {
+ u64 r[ECDSA_MAX_DIGITS];
+ u64 s[ECDSA_MAX_DIGITS];
+ int sig_size;
+ u8 ndigits;
+};
+
+static int check_digest_len(int len)
+{
+ switch (len) {
+ case 32:
+ case 48:
+ case 64:
+ return 0;
+ default:
+ return -1;
+ }
+}
+
+static inline void ecc_swap_digits(const u64 *in, u64 *out,
+ unsigned int ndigits)
+{
+ const __be64 *src = (__force __be64 *) in;
+ int i;
+
+ for (i = 0; i < ndigits; i++)
+ out[i] = be64_to_cpu(src[ndigits - 1 - i]);
+}
+
+static int ecdsa_parse_sig_rs(struct ecdsa_sig_ctx *ctx, u64 *rs,
+ size_t hdrlen, unsigned char tag,
+ const void *value, size_t vlen)
+{
+ u8 ndigits;
+ // skip byte 0 if exists
+ const void *idx = value;
+
+ if (*(u8 *) idx == 0x0) {
+ idx++;
+ vlen--;
+ }
+ ndigits = vlen / 8;
+ if (ndigits == ctx->ndigits)
+ ecc_swap_digits((const u64 *)idx, rs, ndigits);
+ else {
+ u8 nvalue[ECDSA_MAX_SIG_SIZE];
+ const u8 start = (ctx->ndigits * 8) - vlen;
+
+ memset(nvalue, 0, start);
+ memcpy(nvalue + start, idx, vlen);
+ ecc_swap_digits((const u64 *)nvalue, rs, ctx->ndigits);
+ vlen = ctx->ndigits * 8;
+ }
+ ctx->sig_size += vlen;
+ return 0;
+}
+
+int ecdsa_parse_sig_r(void *context, size_t hdrlen, unsigned char tag,
+ const void *value, size_t vlen)
+{
+ struct ecdsa_sig_ctx *ctx = context;
+
+ return ecdsa_parse_sig_rs(ctx, ctx->r, hdrlen, tag, value, vlen);
+}
+
+int ecdsa_parse_sig_s(void *context, size_t hdrlen, unsigned char tag,
+ const void *value, size_t vlen)
+{
+ struct ecdsa_sig_ctx *ctx = context;
+
+ return ecdsa_parse_sig_rs(ctx, ctx->s, hdrlen, tag, value, vlen);
+}
+
+#define ASN_TAG_SIZE 5
+
+static int ecdsa_verify(struct akcipher_request *req, enum OID oid)
+{
+ struct crypto_akcipher *tfm = crypto_akcipher_reqtfm(req);
+ struct ecdsa_ctx *ctx = akcipher_tfm_ctx(tfm);
+ struct ecdsa_sig_ctx ctx_sig;
+ u8 sig[ECDSA_MAX_SIG_SIZE];
+ u8 digest[MAX_DIGEST_SIZE];
+ u16 ndigits = ctx->pub_key.ndigits;
+ u16 min_digits;
+ u64 _r[ECDSA_MAX_DIGITS]; /* ecc_point x */
+ u64 _s[ECDSA_MAX_DIGITS]; /* ecc_point y and temp s^{-1} */
+ u64 e[ECDSA_MAX_DIGITS]; /* h \mod q */
+ u64 v[ECDSA_MAX_DIGITS]; /* s^{-1}e \mod q */
+ u64 u[ECDSA_MAX_DIGITS]; /* s^{-1}r \mod q */
+ struct ecc_point cc = ECC_POINT_INIT(_r, _s, ndigits); /* reuse r, s */
+ struct scatterlist *sgl_s, *sgl_d;
+ int err;
+ int i;
+
+ if (lookup_oid_digest_info(oid, &ctx->digest, &ctx->digest_len,
+ &ctx->digest_oid))
+ return -ENOPKG;
+
+ min_digits =
+ (ndigits < ctx->digest_len / 8) ? ndigits : ctx->digest_len / 8;
+
+ if (!ctx->curve || !ctx->digest || !req->src || !ctx->pub_key.x)
+ return -EBADMSG;
+ if (check_digest_len(req->dst_len)) {
+ pr_err("%s: invalid source digest size %d\n",
+ __func__, req->dst_len);
+ return -EBADMSG;
+ }
+ if (check_digest_len(ctx->digest_len)) {
+ pr_err("%s: invalid context digest size %d\n",
+ __func__, ctx->digest_len);
+ return -EBADMSG;
+ }
+
+ sgl_s = req->src;
+ sgl_d = (((void *)req->src) + sizeof(struct scatterlist));
+
+ if (ctx->pub_key.ndigits != ctx->curve->g.ndigits ||
+ WARN_ON(sgl_s->length > sizeof(sig)) ||
+ WARN_ON(sgl_d->length > sizeof(digest))) {
+ pr_err("%s: invalid curve size g(%d) pub(%d)\n",
+ __func__,
+ ctx->curve->g.ndigits, ctx->pub_key.ndigits);
+ return -EBADMSG;
+ }
+ sg_copy_to_buffer(sgl_s, sg_nents_for_len(sgl_s, sgl_s->length),
+ sig, sizeof(sig));
+ sg_copy_to_buffer(sgl_d, sg_nents_for_len(sgl_d, sgl_d->length),
+ digest, sizeof(digest));
+
+ ctx_sig.sig_size = 0;
+ ctx_sig.ndigits = ndigits;
+ err =
+ asn1_ber_decoder(&ecdsa_signature_decoder, &ctx_sig, sig,
+ sgl_s->length);
+ if (err < 0)
+ return err;
+
+ /* Step 1: verify that 0 < r < q, 0 < s < q */
+ if (vli_is_zero(ctx_sig.r, ndigits) ||
+ vli_cmp(ctx_sig.r, ctx->curve->n, ndigits) == 1 ||
+ vli_is_zero(ctx_sig.s, ndigits) ||
+ vli_cmp(ctx_sig.s, ctx->curve->n, ndigits) == 1)
+ return -EKEYREJECTED;
+
+ /* need truncate digest */
+ for (i = min_digits; i < ndigits; i++)
+ e[i] = 0;
+ /* Step 2: calculate hash (h) of the message (passed as input) */
+ /* Step 3: calculate e = h \mod q */
+ vli_from_be64(e, digest, min_digits);
+ if (vli_cmp(e, ctx->curve->n, ndigits) == 1)
+ vli_sub(e, e, ctx->curve->n, ndigits);
+ if (vli_is_zero(e, ndigits))
+ e[0] = 1;
+
+ /* Step 4: calculate _s = s^{-1} \mod q */
+ vli_mod_inv(_s, ctx_sig.s, ctx->curve->n, ndigits);
+ /* Step 5: calculate u = s^{-1} * e \mod q */
+ vli_mod_mult_slow(u, _s, e, ctx->curve->n, ndigits);
+ /* Step 6: calculate v = s^{-1} * r \mod q */
+ vli_mod_mult_slow(v, _s, ctx_sig.r, ctx->curve->n, ndigits);
+ /* Step 7: calculate cc = (x0, y0) = uG + vP */
+ ecc_point_mult_shamir(&cc, u, &ctx->curve->g, v, &ctx->pub_key,
+ ctx->curve);
+ /* v = x0 mod q */
+ vli_mod_slow(v, cc.x, ctx->curve->n, ndigits);
+
+ /* Step 9: if X0 == r signature is valid */
+ if (vli_cmp(v, ctx_sig.r, ndigits) == 0)
+ return 0;
+
+ return -EKEYREJECTED;
+}
+
+static int ecdsa_verify_256(struct akcipher_request *req)
+{
+ return ecdsa_verify(req, OID_id_ecdsa_with_sha256);
+}
+
+static int ecdsa_verify_384(struct akcipher_request *req)
+{
+ return ecdsa_verify(req, OID_id_ecdsa_with_sha384);
+}
+
+static int ecdsa_verify_512(struct akcipher_request *req)
+{
+ return ecdsa_verify(req, OID_id_ecdsa_with_sha512);
+}
+
+static const struct ecc_curve *get_curve_by_oid(enum OID oid)
+{
+ switch (oid) {
+ case OID_id_secp192r1:
+ return &nist_p192;
+ case OID_id_secp256r1:
+ return &nist_p256;
+ case OID_id_secp384r1:
+ return &nist_p384;
+ case OID_id_secp521r1:
+ return &nist_p521;
+ default:
+ return NULL;
+ }
+}
+
+int ecdsa_param_curve(void *context, size_t hdrlen, unsigned char tag,
+ const void *value, size_t vlen)
+{
+ struct ecdsa_ctx *ctx = context;
+
+ ctx->curve_oid = look_up_OID(value, vlen);
+ if (!ctx->curve_oid)
+ return -EINVAL;
+ ctx->curve = get_curve_by_oid(ctx->curve_oid);
+
+ return 0;
+}
+
+/* Optional. If present should match expected digest algo OID. */
+int ecdsa_param_digest(void *context, size_t hdrlen, unsigned char tag,
+ const void *value, size_t vlen)
+{
+ struct ecdsa_ctx *ctx = context;
+ int digest_oid = look_up_OID(value, vlen);
+
+ if (digest_oid != ctx->digest_oid)
+ return -EINVAL;
+
+ return 0;
+}
+
+int ecdsa_parse_pub_key(void *context, size_t hdrlen, unsigned char tag,
+ const void *value, size_t vlen)
+{
+ struct ecdsa_ctx *ctx = context;
+
+ ctx->key = value;
+ ctx->key_len = vlen;
+ return 0;
+}
+
+static u8 *pkey_unpack_u32(u32 *dst, void *src)
+{
+ memcpy(dst, src, sizeof(*dst));
+ return src + sizeof(*dst);
+}
+
+static inline void copy4be8(u64 *out, const u8 *in, u32 size)
+{
+ int i;
+ u8 *dst = (u8 *) out;
+
+ *out = 0;
+ for (i = 0; i < size; i++) {
+ *dst = in[size - i - 1];
+ dst++;
+ }
+}
+
+static void convert4be(u64 *out, const u8 *in, u32 size)
+{
+ int i;
+
+ while (*in == 0 && size > 0) {
+ in++;
+ size--;
+ }
+ in = in + size;
+ /* convert from BE */
+ for (i = 0; i < size; i += 8) {
+ const u32 count = size - i;
+ const u32 limit = count >= 8 ? 8 : count;
+ const u8 *part = in - limit;
+
+ if (limit == 8)
+ *out = get_unaligned_be64(part);
+ else
+ copy4be8(out, part, limit);
+ out++;
+ in -= limit;
+ }
+}
+
+/* Parse BER encoded subjectPublicKey. */
+static int ecdsa_set_pub_key(struct crypto_akcipher *tfm, const void *key,
+ unsigned int keylen)
+{
+ struct ecdsa_ctx *ctx = akcipher_tfm_ctx(tfm);
+ unsigned int ndigits;
+ u32 algo, paramlen;
+ u8 *params;
+ int err;
+ const u8 nist_type = *(u8 *) key;
+ u8 half_pub;
+
+ /* Key parameters is in the key after keylen. */
+ params = (u8 *) key + keylen;
+ params = pkey_unpack_u32(&algo, params);
+ params = pkey_unpack_u32(&paramlen, params);
+
+ ctx->algo_oid = algo;
+
+ /* Parse SubjectPublicKeyInfo.AlgorithmIdentifier.parameters. */
+ err = asn1_ber_decoder(&ecdsa_params_decoder, ctx, params, paramlen);
+ if (err < 0)
+ return err;
+ ctx->key = key;
+ ctx->key_len = keylen;
+ if (!ctx->curve)
+ return -ENOPKG;
+
+ /*
+ * Accepts only uncompressed it's not accepted
+ */
+ if (nist_type != NIST_UNPACKED_KEY_ID)
+ return -ENOPKG;
+ /* Skip nist type octet */
+ ctx->key++;
+ ctx->key_len--;
+ if (ctx->key_len != NISTP256_PACKED_KEY_SIZE
+ && ctx->key_len != NISTP384_PACKED_KEY_SIZE
+ && ctx->key_len != NISTP521_PACKED_KEY_SIZE)
+ return -ENOPKG;
+ ndigits = ctx->key_len / sizeof(u64) / 2;
+ if (ndigits * 2 * sizeof(u64) < ctx->key_len)
+ ndigits++;
+ half_pub = ctx->key_len / 2;
+ /*
+ * Sizes of key_len and curve should match each other.
+ */
+ if (ctx->curve->g.ndigits != ndigits)
+ return -ENOPKG;
+ ctx->pub_key = ECC_POINT_INIT(ctx->_pubp[0], ctx->_pubp[1], ndigits);
+ /*
+ * X509 stores key.x and key.y as BE
+ */
+ if (ndigits != 9) {
+ vli_from_be64(ctx->pub_key.x, ctx->key, ndigits);
+ vli_from_be64(ctx->pub_key.y, ctx->key + half_pub, ndigits);
+ } else {
+ convert4be(ctx->pub_key.x, ctx->key, half_pub);
+ convert4be(ctx->pub_key.y, ctx->key + half_pub, half_pub);
+ }
+ err = ecc_is_pubkey_valid_partial(ctx->curve, &ctx->pub_key);
+ if (err)
+ return -EKEYREJECTED;
+
+ return 0;
+}
+
+static unsigned int ecdsa_max_size(struct crypto_akcipher *tfm)
+{
+ struct ecdsa_ctx *ctx = akcipher_tfm_ctx(tfm);
+
+ /*
+ * Verify doesn't need any output, so it's just informational
+ * for keyctl to determine the key bit size.
+ */
+ return ctx->pub_key.ndigits * sizeof(u64);
+}
+
+static void ecdsa_exit_tfm(struct crypto_akcipher *tfm)
+{
+}
+
+//static const struct s_ecdsa_template {
+// const char *name;
+// enum OID oid;
+// size_t size;
+// int (*ecdsa_verify)(struct akcipher_request *req);
+//} ecdsa_templates[] = {
+// {"ecdsa(sha256)", OID_id_ecdsa_with_sha256, ecdsa_verify},
+// {"ecdsa(sha384)", OID_id_ecdsa_with_sha384, ecdsa_verify},
+// {"ecdsa(sha512)", OID_id_ecdsa_with_sha512, ecdsa_verify},
+// NULL
+//};
+
+static struct akcipher_alg ecdsa_alg256 = {
+ .verify = ecdsa_verify_256,
+ .set_pub_key = ecdsa_set_pub_key,
+ .max_size = ecdsa_max_size,
+ .exit = ecdsa_exit_tfm,
+ .base = {
+ .cra_name = "ecdsa(sha256)",
+ .cra_driver_name = "ecdsa-generic",
+ .cra_priority = 100,
+ .cra_module = THIS_MODULE,
+ .cra_ctxsize = sizeof(struct ecdsa_ctx),
+ },
+};
+
+static struct akcipher_alg ecdsa_alg384 = {
+ .verify = ecdsa_verify_384,
+ .set_pub_key = ecdsa_set_pub_key,
+ .max_size = ecdsa_max_size,
+ .exit = ecdsa_exit_tfm,
+ .base = {
+ .cra_name = "ecdsa(sha384)",
+ .cra_driver_name = "ecdsa-generic",
+ .cra_priority = 100,
+ .cra_module = THIS_MODULE,
+ .cra_ctxsize = sizeof(struct ecdsa_ctx),
+ },
+};
+
+static struct akcipher_alg ecdsa_alg512 = {
+ .verify = ecdsa_verify_512,
+ .set_pub_key = ecdsa_set_pub_key,
+ .max_size = ecdsa_max_size,
+ .exit = ecdsa_exit_tfm,
+ .base = {
+ .cra_name = "ecdsa(sha512)",
+ .cra_driver_name = "ecdsa-generic",
+ .cra_priority = 100,
+ .cra_module = THIS_MODULE,
+ .cra_ctxsize = sizeof(struct ecdsa_ctx),
+ },
+};
+
+static int __init ecdsa_mod_init(void)
+{
+ int result;
+
+ result = crypto_register_akcipher(&ecdsa_alg256);
+ if (result)
+ goto out256;
+ result = crypto_register_akcipher(&ecdsa_alg384);
+ if (result)
+ goto out384;
+ result = crypto_register_akcipher(&ecdsa_alg512);
+ if (result)
+ goto out512;
+ return 0;
+
+out512:
+ crypto_unregister_akcipher(&ecdsa_alg384);
+out384:
+ crypto_unregister_akcipher(&ecdsa_alg256);
+out256:
+ return result;
+}
+
+static void __exit ecdsa_mod_fini(void)
+{
+ crypto_unregister_akcipher(&ecdsa_alg256);
+ crypto_unregister_akcipher(&ecdsa_alg384);
+ crypto_unregister_akcipher(&ecdsa_alg512);
+}
+
+subsys_initcall(ecdsa_mod_init);
+module_exit(ecdsa_mod_fini);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Saulo Alessandre <[email protected]>");
+MODULE_DESCRIPTION("EC-DSA generic algorithm");
+MODULE_ALIAS_CRYPTO("ecdsa-generic");
diff --git a/crypto/ecdsa_params.asn1 b/crypto/ecdsa_params.asn1
new file mode 100644
index 000000000000..f683aec27bd4
--- /dev/null
+++ b/crypto/ecdsa_params.asn1
@@ -0,0 +1 @@
+EcdsaCurve ::= OBJECT IDENTIFIER ({ ecdsa_param_curve })
diff --git a/crypto/ecdsa_signature.asn1 b/crypto/ecdsa_signature.asn1
new file mode 100644
index 000000000000..378e73913865
--- /dev/null
+++ b/crypto/ecdsa_signature.asn1
@@ -0,0 +1,6 @@
+EcdsaSignature ::= SEQUENCE {
+ signatureR INTEGER ({ ecdsa_parse_sig_r }),
+ signatureS INTEGER ({ ecdsa_parse_sig_s })
+}
+
+EcdsaPubKey ::= BIT STRING ({ ecdsa_parse_pub_key })
diff --git a/crypto/testmgr.c b/crypto/testmgr.c
index 1a4103b1b202..3e8a6cf084de 100644
--- a/crypto/testmgr.c
+++ b/crypto/testmgr.c
@@ -3992,8 +3992,15 @@ static int test_akcipher_one(struct crypto_akcipher *tfm,
memcpy(xbuf[0], m, m_size);

sg_init_table(src_tab, 3);
- sg_set_buf(&src_tab[0], xbuf[0], 8);
- sg_set_buf(&src_tab[1], xbuf[0] + 8, m_size - 8);
+ if (vecs->algo == OID_id_ecdsa_with_sha256 ||
+ vecs->algo == OID_id_ecdsa_with_sha384 ||
+ vecs->algo == OID_id_ecdsa_with_sha512) {
+ sg_set_buf(&src_tab[0], xbuf[0], m_size);
+ sg_set_buf(&src_tab[1], xbuf[1], c_size);
+ } else {
+ sg_set_buf(&src_tab[0], xbuf[0], 8);
+ sg_set_buf(&src_tab[1], xbuf[0] + 8, m_size - 8);
+ }
if (vecs->siggen_sigver_test) {
if (WARN_ON(c_size > PAGE_SIZE))
goto free_all;
@@ -4916,6 +4923,12 @@ static const struct alg_test_desc alg_test_descs[] = {
.suite = {
.kpp = __VECS(ecdh_tv_template)
}
+ }, {
+ .alg = "ecdsa",
+ .test = alg_test_akcipher,
+ .suite = {
+ .akcipher = __VECS(ecdsa_tv_template)
+ }
}, {
.alg = "ecrdsa",
.test = alg_test_akcipher,
diff --git a/crypto/testmgr.h b/crypto/testmgr.h
index 99aca08263d2..ad31d8deb3d7 100644
--- a/crypto/testmgr.h
+++ b/crypto/testmgr.h
@@ -566,6 +566,84 @@ static const struct akcipher_testvec rsa_tv_template[] = {
}
};

+/*
+ * EC-DSA test vectors
+ */
+static const struct akcipher_testvec ecdsa_tv_template[] = {
+ {
+ .key =
+ "\x04\x9c\x9e\x45\xe5\x61\xf4\x3d\xf8\x8f\xea\xdf\xce\x9a\xd5\x2a"
+ "\x9e\x7e\x8a\x0a\xef\xff\xad\x9c\x2e\x87\x8e\xa0\xa9\x40\x0a\x3d"
+ "\x7f\x01\x85\x8d\xd6\x36\xcf\x84\x56\x59\xb8\xd8\x3d\x20\x78\xe7"
+ "\xaf\x35\xa8\xeb\x89\x37\x0e\x52\xa7\x71\x81\x2f\x64\xbb\x1d\x6c"
+ "\x04",
+ .key_len = 65,
+ /*
+ * m is SHA256 hash of following message:
+ * "\x49\x41\xbe\x0a\x0c\xc9\xf6\x35\x51\xe4\x27\x56\x13\x71\x4b\xd0"
+ * "\x36\x92\x84\x89\x1b\xf8\x56\x4a\x72\x61\x14\x69\x4f\x5e\x98\xa5"
+ * "\x80\x5a\x37\x51\x1f\xd8\xf5\xb5\x63\xfc\xf4\xb1\xbb\x4d\x33\xa3"
+ * "\x1e\xb9\x75\x8b\x9c\xda\x7e\x6d\x3a\x77\x85\xf7\xfc\x4e\xe7\x64"
+ * "\x43\x10\x19\xa0\x59\xae\xe0\xad\x4b\xd3\xc4\x45\xf7\xb1\xc2\xc1"
+ * "\x65\x01\x41\x39\x5b\x45\x47\xed\x2b\x51\xed\xe3\xd0\x09\x10\xd2"
+ * "\x39\x6c\x4a\x3f\xe5\xd2\x20\xe6\xb0\x71\x7d\x5b\xed\x26\x60\xf1"
+ * "\xb4\x73\xd1\xdb\x7d\xc4\x19\x91\xee\xf6\x32\x76\xf2\x19\x7d\xb7"
+ */
+ .m =
+ "\x3e\xc8\xa1\x26\x20\x54\x44\x52\x48\x0d\xe5\x66\xf3\xb3\xf5\x04"
+ "\xbe\x10\xa8\x48\x94\x22\x2d\xdd\xba\x7a\xb4\x76\x8d\x79\x98\x89",
+ .m_size = 32,
+ .params = /* ecdsaWithSHA512 */
+ //"\x06\x08\x2a\x86\x48\xce\x3d\x04\x03\x04",
+ "\x06\x08\x2A\x86\x48\xCE\x3D\x03\x01\x07",
+ .param_len = 10,
+ .c =
+ "\x30\x44\x02\x20\x2b\xf7\x53\x42\xc2\x80\x52\xca\x9f\x54\x5e\x52"
+ "\xe2\x46\xa4\x83\xf4\x00\x59\x1e\x88\xd4\x7a\x88\x96\xb7\xee\xc7"
+ "\xbf\x2c\x1e\xd0\x02\x20\x46\x58\x95\x5f\x39\x75\x35\xaa\x73\x7d"
+ "\xe3\x87\x18\xad\x6d\x60\xd0\xc3\xb7\x21\x10\xeb\x77\x7b\x5a\xd4"
+ "\x52\x05\xc0\xfe\xa8\x46",
+ .c_size = 70,
+ .algo = OID_id_ecdsa_with_sha256,
+ .public_key_vec = true,
+ .siggen_sigver_test = true,
+ },
+ {
+ .key =
+ "\x04\xee\x89\x69\x41\xa0\x10\xfe\x56\xbc\x50\x37\x6d\xa1\xfe"
+ "\x89\xa6\x34\xaf\x0a\x97\x7c\x7a\x5c\x13\x5f\xea\x5f\x36\x07"
+ "\x82\xd4\x4b\x09\x97\xd4\xf9\x91\xb9\x0e\x06\xd4\x3d\xd3\x87"
+ "\xc3\x1b\x00\x93\xc8\x0f\x8a\x45\xa9\xb7\x3d\xa0\xbf\xe3\xb3"
+ "\x0f\x9a\xf0\xbd\x70\x62\x16\x40\xc3\x83\x56\x25\xc3\x0f\x85"
+ "\xa2\xd3\x88\x89\xbd\x5b\x92\x27\x3f\x95\x77\xd0\xc1\x49\x07"
+ "\xe2\xa5\xd7\xb2\x5b\xba\xea",
+ .key_len = 97,
+ /*
+ * m is SHA256 hash of same previous message:
+ * "\x49\x41\xbe\x0a ... \xf2\x19\x7d\xb7"
+ */
+ .m =
+ "\x3e\xc8\xa1\x26\x20\x54\x44\x52\x48\x0d\xe5\x66\xf3\xb3\xf5\x04"
+ "\xbe\x10\xa8\x48\x94\x22\x2d\xdd\xba\x7a\xb4\x76\x8d\x79\x98\x89",
+ .m_size = 32,
+ .params = /* ecdsaWithSHA512 */
+ "\x06\x05\x2B\x81\x04\x00\x22",
+ .param_len = 7,
+ .c =
+ "\x30\x64\x02\x30\x4f\xd3\xe8\x98\xcb\x6b\x82\x4b\x41\x2d\x3b\x85"
+ "\xde\x07\x19\xc4\x64\x2b\xd9\x80\x00\x50\xa8\x79\x48\x07\x75\xb6"
+ "\x56\x66\xb9\x89\x0b\xab\x89\x18\x4c\xe9\x21\x38\x4e\xe0\x70\x9d"
+ "\x80\x76\x8a\x2b\x02\x30\x5f\x01\xc5\x0b\x6e\x72\x42\x2e\x79\xee"
+ "\x42\x15\xe0\x16\xf5\x38\x90\x49\x44\x7f\xca\x29\xdf\x0d\xce\x5b"
+ "\xeb\x7f\xef\x2a\x51\xef\x52\x6e\x14\xa6\x25\xe5\xfb\x7b\x66\xea"
+ "\x07\x3f\x4c\x17\xd0\xfc",
+ .c_size = 102,
+ .algo = OID_id_ecdsa_with_sha256,
+ .public_key_vec = true,
+ .siggen_sigver_test = true,
+ },
+};
+
/*
* EC-RDSA test vectors are generated by gost-engine.
*/
--
2.25.1

2021-01-29 21:30:11

by Saulo Alessandre de Lima

[permalink] [raw]
Subject: [PATCH v2 1/4] ecdsa: add params to ecdsa algo

From: Saulo Alessandre <[email protected]>

* crypto/ecc_curve_defs.h
- nist_p384_(x,y,p,n,z,b) and nist_p384 added curve params added;
- nist_p521_(x,y,p,n,z,b) and nist_p521 added curve params added;

* include/crypto/ecdh.h
- ECC_CURVE_NIST_P384, ECC_CURVE_NIST_P521 - added new curves

* lib/oid_registry.c
- lookup_oid_sign_info - added to return sign algo name;
- lookup_oid_digest_info - added to return hash algo name, len and
generic OID

* include/linux/oid_registry.h
- OID_undef - added to reflect a zeroed structure as undefined
- OID_id_secp(192r1,256r1), OID_id_ecdsa_with_sha(256,384,512),
OID_id_secp(384r1,521r1) - added oid types for ecdsa algo;
- lookup_oid_sign_info, lookup_oid_digest_info - added to get hash,
sig info;
---
crypto/ecc_curve_defs.h | 82 ++++++++++++++++++++++++++++
include/crypto/ecdh.h | 2 +
include/linux/oid_registry.h | 12 +++++
lib/oid_registry.c | 100 +++++++++++++++++++++++++++++++++++
4 files changed, 196 insertions(+)

diff --git a/crypto/ecc_curve_defs.h b/crypto/ecc_curve_defs.h
index 69be6c7d228f..3d97761021b7 100644
--- a/crypto/ecc_curve_defs.h
+++ b/crypto/ecc_curve_defs.h
@@ -54,4 +54,86 @@ static struct ecc_curve nist_p256 = {
.b = nist_p256_b
};

+/* NIST P-384 */
+static u64 nist_p384_g_x[] = { 0x3A545E3872760AB7ull, 0x5502F25DBF55296Cull,
+ 0x59F741E082542A38ull, 0x6E1D3B628BA79B98ull,
+ 0x8Eb1C71EF320AD74ull, 0xAA87CA22BE8B0537ull };
+static u64 nist_p384_g_y[] = { 0x7A431D7C90EA0E5Full, 0x0A60B1CE1D7E819Dull,
+ 0xE9DA3113B5F0B8C0ull, 0xF8F41DBD289A147Cull,
+ 0x5D9E98BF9292DC29ull, 0x3617DE4A96262C6Full };
+static u64 nist_p384_p[] = { 0x00000000FFFFFFFFull, 0xFFFFFFFF00000000ull,
+ 0xFFFFFFFFFFFFFFFEull, 0xFFFFFFFFFFFFFFFFull,
+ 0xFFFFFFFFFFFFFFFFull, 0xFFFFFFFFFFFFFFFFull };
+static u64 nist_p384_n[] = { 0xECEC196ACCC52973ull, 0x581A0DB248B0A77Aull,
+ 0xC7634D81F4372DDFull, 0xFFFFFFFFFFFFFFFFull,
+ 0xFFFFFFFFFFFFFFFFull, 0xFFFFFFFFFFFFFFFFull };
+static u64 nist_p384_a[] = { 0x00000000FFFFFFFCull, 0xFFFFFFFF00000000ull,
+ 0xFFFFFFFFFFFFFFFEull, 0xFFFFFFFFFFFFFFFFull,
+ 0xFFFFFFFFFFFFFFFFull, 0xFFFFFFFFFFFFFFFFull };
+static u64 nist_p384_b[] = { 0x2a85c8edd3ec2aefull, 0xc656398d8a2ed19dull,
+ 0x0314088f5013875aull, 0x181d9c6efe814112ull,
+ 0x988e056be3f82d19ull, 0xb3312fa7e23ee7e4ull };
+static struct ecc_curve nist_p384 = {
+ .name = "nist_384",
+ .g = {
+ .x = nist_p384_g_x,
+ .y = nist_p384_g_y,
+ .ndigits = 6,
+ },
+ .p = nist_p384_p,
+ .n = nist_p384_n,
+ .a = nist_p384_a,
+ .b = nist_p384_b
+};
+
+/* NIST P-521 */
+static u64 nist_p521_g_x[] = { 0xF97E7E31C2E5BD66ull, 0x3348B3C1856A429Bull,
+ 0xFE1DC127A2FFA8DEull, 0xA14B5E77EFE75928ull,
+ 0xF828AF606B4D3DBAull, 0x9C648139053FB521ull,
+ 0x9E3ECB662395B442ull, 0x858E06B70404E9CDull,
+ 0x00000000000000C6ull };
+static u64 nist_p521_g_y[] = { 0x88BE94769FD16650ull, 0x353C7086A272C240ull,
+ 0xC550B9013FAD0761ull, 0x97EE72995EF42640ull,
+ 0x17AFBD17273E662Cull, 0x98F54449579B4468ull,
+ 0x5C8A5FB42C7D1BD9ull, 0x39296A789A3BC004ull,
+ 0x0000000000000118ull };
+static u64 nist_p521_p[] = { 0xFFFFFFFFFFFFFFFFull, 0xFFFFFFFFFFFFFFFFull,
+ 0xFFFFFFFFFFFFFFFFull, 0xFFFFFFFFFFFFFFFFull,
+ 0xFFFFFFFFFFFFFFFFull, 0xFFFFFFFFFFFFFFFFull,
+ 0xFFFFFFFFFFFFFFFFull, 0xFFFFFFFFFFFFFFFFull,
+ 0x00000000000001FFull };
+static u64 nist_p521_n[] = { 0xBB6FB71E91386409ull, 0x3BB5C9B8899C47AEull,
+ 0x7FCC0148F709A5D0ull, 0x51868783BF2F966Bull,
+ 0xFFFFFFFFFFFFFFFAull, 0xFFFFFFFFFFFFFFFFull,
+ 0xFFFFFFFFFFFFFFFFull, 0xFFFFFFFFFFFFFFFFull,
+ 0x00000000000001FFull };
+static u64 nist_p521_a[] = { 0xFFFFFFFFFFFFFFFCull, 0xFFFFFFFFFFFFFFFFull,
+ 0xFFFFFFFFFFFFFFFFull, 0xFFFFFFFFFFFFFFFFull,
+ 0xFFFFFFFFFFFFFFFFull, 0xFFFFFFFFFFFFFFFFull,
+ 0xFFFFFFFFFFFFFFFFull, 0xFFFFFFFFFFFFFFFFull,
+ 0x00000000000001FFull };
+static u64 nist_p521_b[] = { 0xEF451FD46B503F00ull, 0x3573DF883D2C34F1ull,
+ 0x1652C0BD3BB1BF07ull, 0x56193951EC7E937Bull,
+ 0xB8B489918EF109E1ull, 0xA2DA725B99B315F3ull,
+ 0x929A21A0B68540EEull, 0x953EB9618E1C9A1Full,
+ 0x0000000000000051ull };
+
+static struct ecc_curve nist_p521 = {
+ .name = "nist_521",
+ .g = {
+ .x = nist_p521_g_x,
+ .y = nist_p521_g_y,
+ .ndigits = 9,
+ },
+ .p = nist_p521_p,
+ .n = nist_p521_n,
+ .a = nist_p521_a,
+ .b = nist_p521_b
+};
+
+#define NIST_UNPACKED_KEY_ID 0x04
+#define NISTP256_PACKED_KEY_SIZE 64
+#define NISTP384_PACKED_KEY_SIZE 96
+#define NISTP521_PACKED_KEY_SIZE 132
+
#endif
diff --git a/include/crypto/ecdh.h b/include/crypto/ecdh.h
index a5b805b5526d..6c7333f82b9c 100644
--- a/include/crypto/ecdh.h
+++ b/include/crypto/ecdh.h
@@ -25,6 +25,8 @@
/* Curves IDs */
#define ECC_CURVE_NIST_P192 0x0001
#define ECC_CURVE_NIST_P256 0x0002
+#define ECC_CURVE_NIST_P384 0x0003
+#define ECC_CURVE_NIST_P521 0x0004

/**
* struct ecdh - define an ECDH private key
diff --git a/include/linux/oid_registry.h b/include/linux/oid_registry.h
index 4462ed2c18cd..7871c574b56a 100644
--- a/include/linux/oid_registry.h
+++ b/include/linux/oid_registry.h
@@ -17,9 +17,15 @@
* build_OID_registry.pl to generate the data for look_up_OID().
*/
enum OID {
+ OID__undef, /* 1.0 */
OID_id_dsa_with_sha1, /* 1.2.840.10030.4.3 */
OID_id_dsa, /* 1.2.840.10040.4.1 */
+ OID_id_secp192r1, /* 1.2.840.10045.3.1.1 */
+ OID_id_secp256r1, /* 1.2.840.10045.3.1.7 */
OID_id_ecdsa_with_sha1, /* 1.2.840.10045.4.1 */
+ OID_id_ecdsa_with_sha256, /* 1.2.840.10045.4.3.2 */
+ OID_id_ecdsa_with_sha384, /* 1.2.840.10045.4.3.3 */
+ OID_id_ecdsa_with_sha512, /* 1.2.840.10045.4.3.4 */
OID_id_ecPublicKey, /* 1.2.840.10045.2.1 */

/* PKCS#1 {iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) pkcs-1(1)} */
@@ -58,6 +64,8 @@ enum OID {

OID_certAuthInfoAccess, /* 1.3.6.1.5.5.7.1.1 */
OID_sha1, /* 1.3.14.3.2.26 */
+ OID_id_secp384r1, /* 1.3.132.0.34 */
+ OID_id_secp521r1, /* 1.3.132.0.35 */
OID_sha256, /* 2.16.840.1.101.3.4.2.1 */
OID_sha384, /* 2.16.840.1.101.3.4.2.2 */
OID_sha512, /* 2.16.840.1.101.3.4.2.3 */
@@ -119,5 +127,9 @@ enum OID {
extern enum OID look_up_OID(const void *data, size_t datasize);
extern int sprint_oid(const void *, size_t, char *, size_t);
extern int sprint_OID(enum OID, char *, size_t);
+extern int lookup_oid_sign_info(enum OID oid,
+ const char **sign_algo);
+extern int lookup_oid_digest_info(enum OID oid,
+ const char **hash_algo, u32 *hash_len, enum OID *oid_algo);

#endif /* _LINUX_OID_REGISTRY_H */
diff --git a/lib/oid_registry.c b/lib/oid_registry.c
index f7ad43f28579..aea941dd93ba 100644
--- a/lib/oid_registry.c
+++ b/lib/oid_registry.c
@@ -92,6 +92,106 @@ enum OID look_up_OID(const void *data, size_t datasize)
}
EXPORT_SYMBOL_GPL(look_up_OID);

+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wswitch"
+int lookup_oid_sign_info(enum OID oid, const char **sign_algo)
+{
+ int ret = -1;
+
+ if (sign_algo) {
+ switch (oid) {
+ case OID_md4WithRSAEncryption:
+ case OID_sha1WithRSAEncryption:
+ case OID_sha256WithRSAEncryption:
+ case OID_sha384WithRSAEncryption:
+ case OID_sha512WithRSAEncryption:
+ case OID_sha224WithRSAEncryption:
+ if (sign_algo)
+ *sign_algo = "rsa";
+ ret = 0;
+ break;
+ case OID_id_ecdsa_with_sha1:
+ case OID_id_ecdsa_with_sha256:
+ case OID_id_ecdsa_with_sha384:
+ case OID_id_ecdsa_with_sha512:
+ if (sign_algo)
+ *sign_algo = "ecdsa";
+ ret = 0;
+ break;
+ }
+ }
+ return ret;
+}
+EXPORT_SYMBOL_GPL(lookup_oid_sign_info);
+
+int lookup_oid_digest_info(enum OID oid,
+ const char **digest_algo, u32 *digest_len,
+ enum OID *digest_oid)
+{
+ int ret = 0;
+
+ switch (oid) {
+ case OID_md4WithRSAEncryption:
+ if (digest_algo)
+ *digest_algo = "md4";
+ if (digest_oid)
+ *digest_oid = OID_md4;
+ if (digest_len)
+ *digest_len = 16;
+ break;
+ case OID_sha1WithRSAEncryption:
+ case OID_id_ecdsa_with_sha1:
+ if (digest_algo)
+ *digest_algo = "sha1";
+ if (digest_oid)
+ *digest_oid = OID_sha1;
+ if (digest_len)
+ *digest_len = 20;
+ break;
+ case OID_sha224WithRSAEncryption:
+ if (digest_algo)
+ *digest_algo = "sha224";
+ if (digest_oid)
+ *digest_oid = OID_sha224;
+ if (digest_len)
+ *digest_len = 28;
+ break;
+ case OID_sha256WithRSAEncryption:
+ case OID_id_ecdsa_with_sha256:
+ if (digest_algo)
+ *digest_algo = "sha256";
+ if (digest_oid)
+ *digest_oid = OID_sha256;
+ if (digest_len)
+ *digest_len = 32;
+ break;
+ case OID_sha384WithRSAEncryption:
+ case OID_id_ecdsa_with_sha384:
+ if (digest_algo)
+ *digest_algo = "sha384";
+ if (digest_oid)
+ *digest_oid = OID_sha384;
+ if (digest_len)
+ *digest_len = 48;
+ break;
+ case OID_sha512WithRSAEncryption:
+ case OID_id_ecdsa_with_sha512:
+ if (digest_algo)
+ *digest_algo = "sha512";
+ if (digest_oid)
+ *digest_oid = OID_sha512;
+ if (digest_len)
+ *digest_len = 64;
+ break;
+ default:
+ ret = -1;
+ }
+ return ret;
+}
+EXPORT_SYMBOL_GPL(lookup_oid_digest_info);
+
+#pragma GCC diagnostic pop
+
/*
* sprint_OID - Print an Object Identifier into a buffer
* @data: The encoded OID to print
--
2.25.1

2021-02-02 05:15:24

by Herbert Xu

[permalink] [raw]
Subject: Re: [PATCH v2 4/4] ecdsa: implements ecdsa signature verification

On Fri, Jan 29, 2021 at 06:25:35PM -0300, Saulo Alessandre wrote:
> From: Saulo Alessandre <[email protected]>
>
> * Documentation/admin-guide/module-signing.rst
> - Documents how to generate certificate and signature for (ECDSA).
>
> * crypto/Kconfig
> - ECDSA added into kernel Public-key cryptography section.
>
> * crypto/Makefile
> - add ECDSA objects and asn1 params to compile.
>
> * crypto/ecdsa.c
> - Elliptical Curve DSA verify implementation
>
> * crypto/ecdsa_params.asn1
> - Elliptical Curve DSA verify definitions
>
> * crypto/ecdsa_signature.asn1
> - Elliptical Curve DSA asn.1 parameters
>
> * crypto/testmgr.c
> - test_akcipher_one - modified to reflect the real code call for nist code;
> - alg_test_descs - added ecdsa vector for test;
>
> * crypto/testmgr.h
> - ecdsa_tv_template - added to test ecdsa implementation;
> ---
> Documentation/admin-guide/module-signing.rst | 10 +
> crypto/Kconfig | 12 +
> crypto/Makefile | 7 +
> crypto/ecdsa.c | 509 +++++++++++++++++++
> crypto/ecdsa_params.asn1 | 1 +
> crypto/ecdsa_signature.asn1 | 6 +
> crypto/testmgr.c | 17 +-
> crypto/testmgr.h | 78 +++
> 8 files changed, 638 insertions(+), 2 deletions(-)
> create mode 100644 crypto/ecdsa.c
> create mode 100644 crypto/ecdsa_params.asn1
> create mode 100644 crypto/ecdsa_signature.asn1

Please join the existing thread on this:

https://lore.kernel.org/linux-crypto/[email protected]/

Thanks,
--
Email: Herbert Xu <[email protected]>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt

2021-02-03 15:55:23

by Vitaly Chikunov

[permalink] [raw]
Subject: Re: [PATCH v2 4/4] ecdsa: implements ecdsa signature verification

Herbert,

On Tue, Feb 02, 2021 at 04:10:03PM +1100, Herbert Xu wrote:
> On Fri, Jan 29, 2021 at 06:25:35PM -0300, Saulo Alessandre wrote:
> > From: Saulo Alessandre <[email protected]>
> >
> > * Documentation/admin-guide/module-signing.rst
> > - Documents how to generate certificate and signature for (ECDSA).
> >
> > * crypto/Kconfig
> > - ECDSA added into kernel Public-key cryptography section.
> >
> > * crypto/Makefile
> > - add ECDSA objects and asn1 params to compile.
> >
> > * crypto/ecdsa.c
> > - Elliptical Curve DSA verify implementation
> >
> > * crypto/ecdsa_params.asn1
> > - Elliptical Curve DSA verify definitions
> >
> > * crypto/ecdsa_signature.asn1
> > - Elliptical Curve DSA asn.1 parameters
> >
> > * crypto/testmgr.c
> > - test_akcipher_one - modified to reflect the real code call for nist code;
> > - alg_test_descs - added ecdsa vector for test;
> >
> > * crypto/testmgr.h
> > - ecdsa_tv_template - added to test ecdsa implementation;
> > ---
> > Documentation/admin-guide/module-signing.rst | 10 +
> > crypto/Kconfig | 12 +
> > crypto/Makefile | 7 +
> > crypto/ecdsa.c | 509 +++++++++++++++++++
> > crypto/ecdsa_params.asn1 | 1 +
> > crypto/ecdsa_signature.asn1 | 6 +
> > crypto/testmgr.c | 17 +-
> > crypto/testmgr.h | 78 +++
> > 8 files changed, 638 insertions(+), 2 deletions(-)
> > create mode 100644 crypto/ecdsa.c
> > create mode 100644 crypto/ecdsa_params.asn1
> > create mode 100644 crypto/ecdsa_signature.asn1
>
> Please join the existing thread on this:
>
> https://lore.kernel.org/linux-crypto/[email protected]/

Thanks for the invitation, I'm didn't receive this thread - is
there a temporary problem with the [email protected] list?
I re-checked my subscription and it seems valid.

Thanks,


>
> Thanks,
> --
> Email: Herbert Xu <[email protected]>
> Home Page: http://gondor.apana.org.au/~herbert/
> PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt

2021-02-04 05:44:46

by Herbert Xu

[permalink] [raw]
Subject: Re: [PATCH v2 4/4] ecdsa: implements ecdsa signature verification

On Wed, Feb 03, 2021 at 06:34:06PM +0300, Vitaly Chikunov wrote:
>
> Thanks for the invitation, I'm didn't receive this thread - is
> there a temporary problem with the [email protected] list?
> I re-checked my subscription and it seems valid.

There was a problem between vger and gmail (and possibly others)
recently.

Cheers,
--
Email: Herbert Xu <[email protected]>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt