summaryrefslogtreecommitdiff
path: root/providers
diff options
context:
space:
mode:
Diffstat (limited to 'providers')
-rw-r--r--providers/common/der/EC.asn183
-rw-r--r--providers/common/der/build.info9
-rw-r--r--providers/common/der/der_ec.c.in67
-rw-r--r--providers/common/der/der_ec.h.in21
-rw-r--r--providers/implementations/signature/build.info1
-rw-r--r--providers/implementations/signature/ecdsa.c31
6 files changed, 202 insertions, 10 deletions
diff --git a/providers/common/der/EC.asn1 b/providers/common/der/EC.asn1
new file mode 100644
index 0000000000..d55a69273f
--- /dev/null
+++ b/providers/common/der/EC.asn1
@@ -0,0 +1,83 @@
+-- -------------------------------------------------------------------
+-- Taken from RFC 3279, 3 ASN.1 Module
+-- (https://www.rfc-editor.org/rfc/rfc3279.html#section-3)
+
+ansi-X9-62 OBJECT IDENTIFIER ::= {
+ iso(1) member-body(2) us(840) 10045 }
+
+-- Arc for ECDSA signature OIDS
+
+id-ecSigType OBJECT IDENTIFIER ::= { ansi-X9-62 signatures(4) }
+
+-- OID for ECDSA signatures with SHA-1
+
+ecdsa-with-SHA1 OBJECT IDENTIFIER ::= { id-ecSigType 1 }
+
+id-publicKeyType OBJECT IDENTIFIER ::= { ansi-X9-62 keyType(2) }
+
+id-ecPublicKey OBJECT IDENTIFIER ::= { id-publicKeyType 1 }
+
+-- Named Elliptic Curves in ANSI X9.62.
+
+ellipticCurve OBJECT IDENTIFIER ::= { ansi-X9-62 curves(3) }
+
+c-TwoCurve OBJECT IDENTIFIER ::= {
+ ellipticCurve characteristicTwo(0) }
+
+c2pnb163v1 OBJECT IDENTIFIER ::= { c-TwoCurve 1 }
+c2pnb163v2 OBJECT IDENTIFIER ::= { c-TwoCurve 2 }
+c2pnb163v3 OBJECT IDENTIFIER ::= { c-TwoCurve 3 }
+c2pnb176w1 OBJECT IDENTIFIER ::= { c-TwoCurve 4 }
+c2tnb191v1 OBJECT IDENTIFIER ::= { c-TwoCurve 5 }
+c2tnb191v2 OBJECT IDENTIFIER ::= { c-TwoCurve 6 }
+c2tnb191v3 OBJECT IDENTIFIER ::= { c-TwoCurve 7 }
+c2onb191v4 OBJECT IDENTIFIER ::= { c-TwoCurve 8 }
+c2onb191v5 OBJECT IDENTIFIER ::= { c-TwoCurve 9 }
+c2pnb208w1 OBJECT IDENTIFIER ::= { c-TwoCurve 10 }
+c2tnb239v1 OBJECT IDENTIFIER ::= { c-TwoCurve 11 }
+c2tnb239v2 OBJECT IDENTIFIER ::= { c-TwoCurve 12 }
+c2tnb239v3 OBJECT IDENTIFIER ::= { c-TwoCurve 13 }
+c2onb239v4 OBJECT IDENTIFIER ::= { c-TwoCurve 14 }
+c2onb239v5 OBJECT IDENTIFIER ::= { c-TwoCurve 15 }
+c2pnb272w1 OBJECT IDENTIFIER ::= { c-TwoCurve 16 }
+c2pnb304w1 OBJECT IDENTIFIER ::= { c-TwoCurve 17 }
+c2tnb359v1 OBJECT IDENTIFIER ::= { c-TwoCurve 18 }
+c2pnb368w1 OBJECT IDENTIFIER ::= { c-TwoCurve 19 }
+c2tnb431r1 OBJECT IDENTIFIER ::= { c-TwoCurve 20 }
+
+primeCurve OBJECT IDENTIFIER ::= { ellipticCurve prime(1) }
+
+prime192v1 OBJECT IDENTIFIER ::= { primeCurve 1 }
+prime192v2 OBJECT IDENTIFIER ::= { primeCurve 2 }
+prime192v3 OBJECT IDENTIFIER ::= { primeCurve 3 }
+prime239v1 OBJECT IDENTIFIER ::= { primeCurve 4 }
+prime239v2 OBJECT IDENTIFIER ::= { primeCurve 5 }
+prime239v3 OBJECT IDENTIFIER ::= { primeCurve 6 }
+prime256v1 OBJECT IDENTIFIER ::= { primeCurve 7 }
+
+-- -------------------------------------------------------------------
+-- Taken from RFC 5758, 3.2. ECDSA Signature Algorithm
+-- (https://www.rfc-editor.org/rfc/rfc5758.html#section-3.2)
+
+ecdsa-with-SHA224 OBJECT IDENTIFIER ::= { iso(1) member-body(2)
+ us(840) ansi-X9-62(10045) signatures(4) ecdsa-with-SHA2(3) 1 }
+
+ecdsa-with-SHA256 OBJECT IDENTIFIER ::= { iso(1) member-body(2)
+ us(840) ansi-X9-62(10045) signatures(4) ecdsa-with-SHA2(3) 2 }
+
+ecdsa-with-SHA384 OBJECT IDENTIFIER ::= { iso(1) member-body(2)
+ us(840) ansi-X9-62(10045) signatures(4) ecdsa-with-SHA2(3) 3 }
+
+ecdsa-with-SHA512 OBJECT IDENTIFIER ::= { iso(1) member-body(2)
+ us(840) ansi-X9-62(10045) signatures(4) ecdsa-with-SHA2(3) 4 }
+
+-- -------------------------------------------------------------------
+-- Taken from https://csrc.nist.gov/projects/computer-security-objects-register/algorithm-registration
+
+sigAlgs OBJECT IDENTIFIER ::= { 2 16 840 1 101 3 4 3 }
+
+id-ecdsa-with-sha3-224 OBJECT IDENTIFIER ::= { sigAlgs 9 }
+id-ecdsa-with-sha3-256 OBJECT IDENTIFIER ::= { sigAlgs 10 }
+id-ecdsa-with-sha3-384 OBJECT IDENTIFIER ::= { sigAlgs 11 }
+id-ecdsa-with-sha3-512 OBJECT IDENTIFIER ::= { sigAlgs 12 }
+
diff --git a/providers/common/der/build.info b/providers/common/der/build.info
index c560a7084d..eda763ea8e 100644
--- a/providers/common/der/build.info
+++ b/providers/common/der/build.info
@@ -1,4 +1,4 @@
-$FIPSABLE=der_rsa.c der_dsa.c
+$FIPSABLE=der_rsa.c der_dsa.c der_ec.c
SOURCE[../../libfips.a]=$FIPSABLE
SOURCE[../../libnonfips.a]=$FIPSABLE
@@ -16,3 +16,10 @@ DEPEND[der_dsa.c]=oids_to_c.pm
DEPEND[der_dsa.o]=../include/prov/der_dsa.h
GENERATE[../include/prov/der_dsa.h]=der_dsa.h.in
DEPEND[../include/prov/der_dsa.h]=oids_to_c.pm
+
+GENERATE[der_ec.c]=der_ec.c.in
+DEPEND[der_ec.c]=oids_to_c.pm
+
+DEPEND[der_ec.o]=../include/prov/der_ec.h
+GENERATE[../include/prov/der_ec.h]=der_ec.h.in
+DEPEND[../include/prov/der_ec.h]=oids_to_c.pm
diff --git a/providers/common/der/der_ec.c.in b/providers/common/der/der_ec.c.in
new file mode 100644
index 0000000000..a617651e4e
--- /dev/null
+++ b/providers/common/der/der_ec.c.in
@@ -0,0 +1,67 @@
+/*
+ * Copyright 2020 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the Apache License 2.0 (the "License"). You may not use
+ * this file except in compliance with the License. You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include <openssl/bn.h>
+#include <openssl/obj_mac.h>
+#include "prov/der_ec.h"
+
+/* Well known OIDs precompiled */
+{-
+ $OUT = oids_to_c::process_leaves('providers/common/der/EC.asn1',
+ { dir => $config{sourcedir},
+ filter => \&oids_to_c::filter_to_C });
+-}
+
+int DER_w_algorithmIdentifier_EC(WPACKET *pkt, int cont, EC_KEY *ec)
+{
+ return DER_w_begin_sequence(pkt, cont)
+ /* No parameters (yet?) */
+ && DER_w_precompiled(pkt, -1, der_oid_id_ecPublicKey,
+ sizeof(der_oid_id_ecPublicKey))
+ && DER_w_end_sequence(pkt, cont);
+}
+
+/* Aliases so we can have a uniform MD_CASE */
+#define der_oid_id_ecdsa_with_sha1 der_oid_ecdsa_with_SHA1
+#define der_oid_id_ecdsa_with_sha224 der_oid_ecdsa_with_SHA224
+#define der_oid_id_ecdsa_with_sha256 der_oid_ecdsa_with_SHA256
+#define der_oid_id_ecdsa_with_sha384 der_oid_ecdsa_with_SHA384
+#define der_oid_id_ecdsa_with_sha512 der_oid_ecdsa_with_SHA512
+
+#define MD_CASE(name) \
+ case NID_##name: \
+ precompiled = der_oid_id_ecdsa_with_##name; \
+ precompiled_sz = sizeof(der_oid_id_ecdsa_with_##name); \
+ break;
+
+int DER_w_algorithmIdentifier_ECDSA_with(WPACKET *pkt, int cont,
+ EC_KEY *ec, int mdnid)
+{
+ const unsigned char *precompiled = NULL;
+ size_t precompiled_sz = 0;
+
+ switch (mdnid) {
+ MD_CASE(sha1);
+ MD_CASE(sha224);
+ MD_CASE(sha256);
+ MD_CASE(sha384);
+ MD_CASE(sha512);
+ MD_CASE(sha3_224);
+ MD_CASE(sha3_256);
+ MD_CASE(sha3_384);
+ MD_CASE(sha3_512);
+ default:
+ return 0;
+ }
+
+ return DER_w_begin_sequence(pkt, cont)
+ /* No parameters (yet?) */
+ && DER_w_precompiled(pkt, -1, precompiled, precompiled_sz)
+ && DER_w_end_sequence(pkt, cont);
+}
diff --git a/providers/common/der/der_ec.h.in b/providers/common/der/der_ec.h.in
new file mode 100644
index 0000000000..24f153cd8f
--- /dev/null
+++ b/providers/common/der/der_ec.h.in
@@ -0,0 +1,21 @@
+/*
+ * Copyright 2020 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the Apache License 2.0 (the "License"). You may not use
+ * this file except in compliance with the License. You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include "internal/der.h"
+
+/* Well known OIDs precompiled */
+{-
+ $OUT = oids_to_c::process_leaves('providers/common/der/EC.asn1',
+ { dir => $config{sourcedir},
+ filter => \&oids_to_c::filter_to_H });
+-}
+
+int DER_w_algorithmIdentifier_EC(WPACKET *pkt, int cont, EC_KEY *ec);
+int DER_w_algorithmIdentifier_ECDSA_with(WPACKET *pkt, int cont,
+ EC_KEY *ec, int mdnid);
diff --git a/providers/implementations/signature/build.info b/providers/implementations/signature/build.info
index c53673409f..dbe0876a0e 100644
--- a/providers/implementations/signature/build.info
+++ b/providers/implementations/signature/build.info
@@ -19,3 +19,4 @@ SOURCE[../../libnonfips.a]=rsa.c
DEPEND[rsa.o]=../../common/include/prov/der_rsa.h
DEPEND[dsa.o]=../../common/include/prov/der_dsa.h
+DEPEND[ecdsa.o]=../../common/include/prov/der_ec.h
diff --git a/providers/implementations/signature/ecdsa.c b/providers/implementations/signature/ecdsa.c
index 733c0a23a5..e05830f500 100644
--- a/providers/implementations/signature/ecdsa.c
+++ b/providers/implementations/signature/ecdsa.c
@@ -23,10 +23,12 @@
#include <openssl/err.h>
#include "internal/nelem.h"
#include "internal/sizes.h"
+#include "internal/cryptlib.h"
#include "prov/providercommonerr.h"
#include "prov/implementations.h"
#include "prov/provider_ctx.h"
#include "crypto/ec.h"
+#include "prov/der_ec.h"
static OSSL_OP_signature_newctx_fn ecdsa_newctx;
static OSSL_OP_signature_sign_init_fn ecdsa_signature_init;
@@ -62,7 +64,8 @@ typedef struct {
char mdname[OSSL_MAX_NAME_SIZE];
/* The Algorithm Identifier of the combined signature algorithm */
- unsigned char aid[OSSL_MAX_ALGORITHM_ID_SIZE];
+ unsigned char aid_buf[OSSL_MAX_ALGORITHM_ID_SIZE];
+ unsigned char *aid;
size_t aid_len;
size_t mdsize;
@@ -203,8 +206,8 @@ static int ecdsa_digest_signverify_init(void *vctx, const char *mdname,
const char *props, void *ec)
{
PROV_ECDSA_CTX *ctx = (PROV_ECDSA_CTX *)vctx;
- size_t algorithmidentifier_len = 0;
- const unsigned char *algorithmidentifier;
+ int md_nid = NID_undef;
+ WPACKET pkt;
free_md(ctx);
@@ -212,10 +215,7 @@ static int ecdsa_digest_signverify_init(void *vctx, const char *mdname,
return 0;
ctx->md = EVP_MD_fetch(ctx->libctx, mdname, props);
- algorithmidentifier =
- ecdsa_algorithmidentifier_encoding(get_md_nid(ctx->md),
- &algorithmidentifier_len);
- if (algorithmidentifier == NULL)
+ if ((md_nid = get_md_nid(ctx->md)) == NID_undef)
goto error;
ctx->mdsize = EVP_MD_size(ctx->md);
@@ -223,8 +223,21 @@ static int ecdsa_digest_signverify_init(void *vctx, const char *mdname,
if (ctx->mdctx == NULL)
goto error;
- memcpy(ctx->aid, algorithmidentifier, algorithmidentifier_len);
- ctx->aid_len = algorithmidentifier_len;
+ /*
+ * TODO(3.0) Should we care about DER writing errors?
+ * All it really means is that for some reason, there's no
+ * AlgorithmIdentifier to be had, but the operation itself is
+ * still valid, just as long as it's not used to construct
+ * anything that needs an AlgorithmIdentifier.
+ */
+ ctx->aid_len = 0;
+ if (WPACKET_init_der(&pkt, ctx->aid_buf, sizeof(ctx->aid_buf))
+ && DER_w_algorithmIdentifier_ECDSA_with(&pkt, -1, ctx->ec, md_nid)
+ && WPACKET_finish(&pkt)) {
+ WPACKET_get_total_written(&pkt, &ctx->aid_len);
+ ctx->aid = WPACKET_get_curr(&pkt);
+ }
+ WPACKET_cleanup(&pkt);
if (!EVP_DigestInit_ex(ctx->mdctx, ctx->md, NULL))
goto error;