Skip to content

Commit 2d956b3

Browse files
committed
PROV: Add DERlib support for ECDSA and EC keys
This replaces crypto/ec/ecdsa_aid.c with new code and generated OIDs Reviewed-by: Matt Caswell <[email protected]> (Merged from openssl#11450)
1 parent 8c55580 commit 2d956b3

File tree

8 files changed

+203
-116
lines changed

8 files changed

+203
-116
lines changed

crypto/ec/build.info

+1-1
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ $COMMON=ec_lib.c ecp_smpl.c ecp_mont.c ecp_nist.c ec_cvt.c ec_mult.c \
5151
ecdsa_ossl.c ecdsa_sign.c ecdsa_vrf.c curve25519.c \
5252
curve448/arch_32/f_impl.c curve448/f_generic.c curve448/scalar.c \
5353
curve448/curve448_tables.c curve448/eddsa.c curve448/curve448.c \
54-
$ECASM ecdsa_aid.c ec_backend.c ecx_backend.c
54+
$ECASM ec_backend.c ecx_backend.c
5555
SOURCE[../../libcrypto]=$COMMON ec_ameth.c ec_pmeth.c ecx_meth.c ecx_key.c \
5656
ec_err.c ecdh_kdf.c eck_prn.c ec_evp_lib.c
5757
SOURCE[../../providers/libfips.a]=$COMMON

crypto/ec/ecdsa_aid.c

-105
This file was deleted.

providers/common/der/EC.asn1

+83
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
-- -------------------------------------------------------------------
2+
-- Taken from RFC 3279, 3 ASN.1 Module
3+
-- (https://www.rfc-editor.org/rfc/rfc3279.html#section-3)
4+
5+
ansi-X9-62 OBJECT IDENTIFIER ::= {
6+
iso(1) member-body(2) us(840) 10045 }
7+
8+
-- Arc for ECDSA signature OIDS
9+
10+
id-ecSigType OBJECT IDENTIFIER ::= { ansi-X9-62 signatures(4) }
11+
12+
-- OID for ECDSA signatures with SHA-1
13+
14+
ecdsa-with-SHA1 OBJECT IDENTIFIER ::= { id-ecSigType 1 }
15+
16+
id-publicKeyType OBJECT IDENTIFIER ::= { ansi-X9-62 keyType(2) }
17+
18+
id-ecPublicKey OBJECT IDENTIFIER ::= { id-publicKeyType 1 }
19+
20+
-- Named Elliptic Curves in ANSI X9.62.
21+
22+
ellipticCurve OBJECT IDENTIFIER ::= { ansi-X9-62 curves(3) }
23+
24+
c-TwoCurve OBJECT IDENTIFIER ::= {
25+
ellipticCurve characteristicTwo(0) }
26+
27+
c2pnb163v1 OBJECT IDENTIFIER ::= { c-TwoCurve 1 }
28+
c2pnb163v2 OBJECT IDENTIFIER ::= { c-TwoCurve 2 }
29+
c2pnb163v3 OBJECT IDENTIFIER ::= { c-TwoCurve 3 }
30+
c2pnb176w1 OBJECT IDENTIFIER ::= { c-TwoCurve 4 }
31+
c2tnb191v1 OBJECT IDENTIFIER ::= { c-TwoCurve 5 }
32+
c2tnb191v2 OBJECT IDENTIFIER ::= { c-TwoCurve 6 }
33+
c2tnb191v3 OBJECT IDENTIFIER ::= { c-TwoCurve 7 }
34+
c2onb191v4 OBJECT IDENTIFIER ::= { c-TwoCurve 8 }
35+
c2onb191v5 OBJECT IDENTIFIER ::= { c-TwoCurve 9 }
36+
c2pnb208w1 OBJECT IDENTIFIER ::= { c-TwoCurve 10 }
37+
c2tnb239v1 OBJECT IDENTIFIER ::= { c-TwoCurve 11 }
38+
c2tnb239v2 OBJECT IDENTIFIER ::= { c-TwoCurve 12 }
39+
c2tnb239v3 OBJECT IDENTIFIER ::= { c-TwoCurve 13 }
40+
c2onb239v4 OBJECT IDENTIFIER ::= { c-TwoCurve 14 }
41+
c2onb239v5 OBJECT IDENTIFIER ::= { c-TwoCurve 15 }
42+
c2pnb272w1 OBJECT IDENTIFIER ::= { c-TwoCurve 16 }
43+
c2pnb304w1 OBJECT IDENTIFIER ::= { c-TwoCurve 17 }
44+
c2tnb359v1 OBJECT IDENTIFIER ::= { c-TwoCurve 18 }
45+
c2pnb368w1 OBJECT IDENTIFIER ::= { c-TwoCurve 19 }
46+
c2tnb431r1 OBJECT IDENTIFIER ::= { c-TwoCurve 20 }
47+
48+
primeCurve OBJECT IDENTIFIER ::= { ellipticCurve prime(1) }
49+
50+
prime192v1 OBJECT IDENTIFIER ::= { primeCurve 1 }
51+
prime192v2 OBJECT IDENTIFIER ::= { primeCurve 2 }
52+
prime192v3 OBJECT IDENTIFIER ::= { primeCurve 3 }
53+
prime239v1 OBJECT IDENTIFIER ::= { primeCurve 4 }
54+
prime239v2 OBJECT IDENTIFIER ::= { primeCurve 5 }
55+
prime239v3 OBJECT IDENTIFIER ::= { primeCurve 6 }
56+
prime256v1 OBJECT IDENTIFIER ::= { primeCurve 7 }
57+
58+
-- -------------------------------------------------------------------
59+
-- Taken from RFC 5758, 3.2. ECDSA Signature Algorithm
60+
-- (https://www.rfc-editor.org/rfc/rfc5758.html#section-3.2)
61+
62+
ecdsa-with-SHA224 OBJECT IDENTIFIER ::= { iso(1) member-body(2)
63+
us(840) ansi-X9-62(10045) signatures(4) ecdsa-with-SHA2(3) 1 }
64+
65+
ecdsa-with-SHA256 OBJECT IDENTIFIER ::= { iso(1) member-body(2)
66+
us(840) ansi-X9-62(10045) signatures(4) ecdsa-with-SHA2(3) 2 }
67+
68+
ecdsa-with-SHA384 OBJECT IDENTIFIER ::= { iso(1) member-body(2)
69+
us(840) ansi-X9-62(10045) signatures(4) ecdsa-with-SHA2(3) 3 }
70+
71+
ecdsa-with-SHA512 OBJECT IDENTIFIER ::= { iso(1) member-body(2)
72+
us(840) ansi-X9-62(10045) signatures(4) ecdsa-with-SHA2(3) 4 }
73+
74+
-- -------------------------------------------------------------------
75+
-- Taken from https://csrc.nist.gov/projects/computer-security-objects-register/algorithm-registration
76+
77+
sigAlgs OBJECT IDENTIFIER ::= { 2 16 840 1 101 3 4 3 }
78+
79+
id-ecdsa-with-sha3-224 OBJECT IDENTIFIER ::= { sigAlgs 9 }
80+
id-ecdsa-with-sha3-256 OBJECT IDENTIFIER ::= { sigAlgs 10 }
81+
id-ecdsa-with-sha3-384 OBJECT IDENTIFIER ::= { sigAlgs 11 }
82+
id-ecdsa-with-sha3-512 OBJECT IDENTIFIER ::= { sigAlgs 12 }
83+

providers/common/der/build.info

+8-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
$FIPSABLE=der_rsa.c der_dsa.c
1+
$FIPSABLE=der_rsa.c der_dsa.c der_ec.c
22

33
SOURCE[../../libfips.a]=$FIPSABLE
44
SOURCE[../../libnonfips.a]=$FIPSABLE
@@ -16,3 +16,10 @@ DEPEND[der_dsa.c]=oids_to_c.pm
1616
DEPEND[der_dsa.o]=../include/prov/der_dsa.h
1717
GENERATE[../include/prov/der_dsa.h]=der_dsa.h.in
1818
DEPEND[../include/prov/der_dsa.h]=oids_to_c.pm
19+
20+
GENERATE[der_ec.c]=der_ec.c.in
21+
DEPEND[der_ec.c]=oids_to_c.pm
22+
23+
DEPEND[der_ec.o]=../include/prov/der_ec.h
24+
GENERATE[../include/prov/der_ec.h]=der_ec.h.in
25+
DEPEND[../include/prov/der_ec.h]=oids_to_c.pm

providers/common/der/der_ec.c.in

+67
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
/*
2+
* Copyright 2020 The OpenSSL Project Authors. All Rights Reserved.
3+
*
4+
* Licensed under the Apache License 2.0 (the "License"). You may not use
5+
* this file except in compliance with the License. You can obtain a copy
6+
* in the file LICENSE in the source distribution or at
7+
* https://www.openssl.org/source/license.html
8+
*/
9+
10+
#include <openssl/bn.h>
11+
#include <openssl/obj_mac.h>
12+
#include "prov/der_ec.h"
13+
14+
/* Well known OIDs precompiled */
15+
{-
16+
$OUT = oids_to_c::process_leaves('providers/common/der/EC.asn1',
17+
{ dir => $config{sourcedir},
18+
filter => \&oids_to_c::filter_to_C });
19+
-}
20+
21+
int DER_w_algorithmIdentifier_EC(WPACKET *pkt, int cont, EC_KEY *ec)
22+
{
23+
return DER_w_begin_sequence(pkt, cont)
24+
/* No parameters (yet?) */
25+
&& DER_w_precompiled(pkt, -1, der_oid_id_ecPublicKey,
26+
sizeof(der_oid_id_ecPublicKey))
27+
&& DER_w_end_sequence(pkt, cont);
28+
}
29+
30+
/* Aliases so we can have a uniform MD_CASE */
31+
#define der_oid_id_ecdsa_with_sha1 der_oid_ecdsa_with_SHA1
32+
#define der_oid_id_ecdsa_with_sha224 der_oid_ecdsa_with_SHA224
33+
#define der_oid_id_ecdsa_with_sha256 der_oid_ecdsa_with_SHA256
34+
#define der_oid_id_ecdsa_with_sha384 der_oid_ecdsa_with_SHA384
35+
#define der_oid_id_ecdsa_with_sha512 der_oid_ecdsa_with_SHA512
36+
37+
#define MD_CASE(name) \
38+
case NID_##name: \
39+
precompiled = der_oid_id_ecdsa_with_##name; \
40+
precompiled_sz = sizeof(der_oid_id_ecdsa_with_##name); \
41+
break;
42+
43+
int DER_w_algorithmIdentifier_ECDSA_with(WPACKET *pkt, int cont,
44+
EC_KEY *ec, int mdnid)
45+
{
46+
const unsigned char *precompiled = NULL;
47+
size_t precompiled_sz = 0;
48+
49+
switch (mdnid) {
50+
MD_CASE(sha1);
51+
MD_CASE(sha224);
52+
MD_CASE(sha256);
53+
MD_CASE(sha384);
54+
MD_CASE(sha512);
55+
MD_CASE(sha3_224);
56+
MD_CASE(sha3_256);
57+
MD_CASE(sha3_384);
58+
MD_CASE(sha3_512);
59+
default:
60+
return 0;
61+
}
62+
63+
return DER_w_begin_sequence(pkt, cont)
64+
/* No parameters (yet?) */
65+
&& DER_w_precompiled(pkt, -1, precompiled, precompiled_sz)
66+
&& DER_w_end_sequence(pkt, cont);
67+
}

providers/common/der/der_ec.h.in

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
/*
2+
* Copyright 2020 The OpenSSL Project Authors. All Rights Reserved.
3+
*
4+
* Licensed under the Apache License 2.0 (the "License"). You may not use
5+
* this file except in compliance with the License. You can obtain a copy
6+
* in the file LICENSE in the source distribution or at
7+
* https://www.openssl.org/source/license.html
8+
*/
9+
10+
#include "internal/der.h"
11+
12+
/* Well known OIDs precompiled */
13+
{-
14+
$OUT = oids_to_c::process_leaves('providers/common/der/EC.asn1',
15+
{ dir => $config{sourcedir},
16+
filter => \&oids_to_c::filter_to_H });
17+
-}
18+
19+
int DER_w_algorithmIdentifier_EC(WPACKET *pkt, int cont, EC_KEY *ec);
20+
int DER_w_algorithmIdentifier_ECDSA_with(WPACKET *pkt, int cont,
21+
EC_KEY *ec, int mdnid);

providers/implementations/signature/build.info

+1
Original file line numberDiff line numberDiff line change
@@ -19,3 +19,4 @@ SOURCE[../../libnonfips.a]=rsa.c
1919

2020
DEPEND[rsa.o]=../../common/include/prov/der_rsa.h
2121
DEPEND[dsa.o]=../../common/include/prov/der_dsa.h
22+
DEPEND[ecdsa.o]=../../common/include/prov/der_ec.h

providers/implementations/signature/ecdsa.c

+22-9
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,12 @@
2323
#include <openssl/err.h>
2424
#include "internal/nelem.h"
2525
#include "internal/sizes.h"
26+
#include "internal/cryptlib.h"
2627
#include "prov/providercommonerr.h"
2728
#include "prov/implementations.h"
2829
#include "prov/provider_ctx.h"
2930
#include "crypto/ec.h"
31+
#include "prov/der_ec.h"
3032

3133
static OSSL_OP_signature_newctx_fn ecdsa_newctx;
3234
static OSSL_OP_signature_sign_init_fn ecdsa_signature_init;
@@ -62,7 +64,8 @@ typedef struct {
6264
char mdname[OSSL_MAX_NAME_SIZE];
6365

6466
/* The Algorithm Identifier of the combined signature algorithm */
65-
unsigned char aid[OSSL_MAX_ALGORITHM_ID_SIZE];
67+
unsigned char aid_buf[OSSL_MAX_ALGORITHM_ID_SIZE];
68+
unsigned char *aid;
6669
size_t aid_len;
6770
size_t mdsize;
6871

@@ -203,28 +206,38 @@ static int ecdsa_digest_signverify_init(void *vctx, const char *mdname,
203206
const char *props, void *ec)
204207
{
205208
PROV_ECDSA_CTX *ctx = (PROV_ECDSA_CTX *)vctx;
206-
size_t algorithmidentifier_len = 0;
207-
const unsigned char *algorithmidentifier;
209+
int md_nid = NID_undef;
210+
WPACKET pkt;
208211

209212
free_md(ctx);
210213

211214
if (!ecdsa_signature_init(vctx, ec))
212215
return 0;
213216

214217
ctx->md = EVP_MD_fetch(ctx->libctx, mdname, props);
215-
algorithmidentifier =
216-
ecdsa_algorithmidentifier_encoding(get_md_nid(ctx->md),
217-
&algorithmidentifier_len);
218-
if (algorithmidentifier == NULL)
218+
if ((md_nid = get_md_nid(ctx->md)) == NID_undef)
219219
goto error;
220220

221221
ctx->mdsize = EVP_MD_size(ctx->md);
222222
ctx->mdctx = EVP_MD_CTX_new();
223223
if (ctx->mdctx == NULL)
224224
goto error;
225225

226-
memcpy(ctx->aid, algorithmidentifier, algorithmidentifier_len);
227-
ctx->aid_len = algorithmidentifier_len;
226+
/*
227+
* TODO(3.0) Should we care about DER writing errors?
228+
* All it really means is that for some reason, there's no
229+
* AlgorithmIdentifier to be had, but the operation itself is
230+
* still valid, just as long as it's not used to construct
231+
* anything that needs an AlgorithmIdentifier.
232+
*/
233+
ctx->aid_len = 0;
234+
if (WPACKET_init_der(&pkt, ctx->aid_buf, sizeof(ctx->aid_buf))
235+
&& DER_w_algorithmIdentifier_ECDSA_with(&pkt, -1, ctx->ec, md_nid)
236+
&& WPACKET_finish(&pkt)) {
237+
WPACKET_get_total_written(&pkt, &ctx->aid_len);
238+
ctx->aid = WPACKET_get_curr(&pkt);
239+
}
240+
WPACKET_cleanup(&pkt);
228241

229242
if (!EVP_DigestInit_ex(ctx->mdctx, ctx->md, NULL))
230243
goto error;

0 commit comments

Comments
 (0)