Browse Source

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 <matt@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/11450)
master
Richard Levitte 2 years ago
parent
commit
2d956b320c
8 changed files with 203 additions and 116 deletions
  1. +1
    -1
      crypto/ec/build.info
  2. +0
    -105
      crypto/ec/ecdsa_aid.c
  3. +83
    -0
      providers/common/der/EC.asn1
  4. +8
    -1
      providers/common/der/build.info
  5. +67
    -0
      providers/common/der/der_ec.c.in
  6. +21
    -0
      providers/common/der/der_ec.h.in
  7. +1
    -0
      providers/implementations/signature/build.info
  8. +22
    -9
      providers/implementations/signature/ecdsa.c

+ 1
- 1
crypto/ec/build.info View File

@ -51,7 +51,7 @@ $COMMON=ec_lib.c ecp_smpl.c ecp_mont.c ecp_nist.c ec_cvt.c ec_mult.c \
ecdsa_ossl.c ecdsa_sign.c ecdsa_vrf.c curve25519.c \
curve448/arch_32/f_impl.c curve448/f_generic.c curve448/scalar.c \
curve448/curve448_tables.c curve448/eddsa.c curve448/curve448.c \
$ECASM ecdsa_aid.c ec_backend.c ecx_backend.c
$ECASM ec_backend.c ecx_backend.c
SOURCE[../../libcrypto]=$COMMON ec_ameth.c ec_pmeth.c ecx_meth.c ecx_key.c \
ec_err.c ecdh_kdf.c eck_prn.c ec_evp_lib.c
SOURCE[../../providers/libfips.a]=$COMMON


+ 0
- 105
crypto/ec/ecdsa_aid.c View File

@ -1,105 +0,0 @@
/*
* 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 <stdlib.h>
#include <openssl/objects.h>
#include "crypto/ec.h"
#define ASN1_SEQUENCE 0x30
#define ASN1_OID 0x06
#define OID_FIRST(a, b) a * 40 + b
#define DER_840() 0x86, 0x48 /* DER encoding of number 840 is 2 bytes */
#define DER_10045() 0xCE, 0x3D /* DER encoding of number 10045 is 2 bytes */
#define SHA1_SZ 7
#define SHA2_SZ 8
#define SHA3_SZ 9
/*
* -- RFC 3279
* ansi-X9-62 OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840) 10045 }
* id-ecSigType OBJECT IDENTIFIER ::= { ansi-X9-62 signatures(4) }
*
* ecdsa-with-SHA1 OBJECT IDENTIFIER ::= { id-ecSigType 1 }
*/
#define ENCODE_ALGORITHMIDENTIFIER_SHA1(name) \
static const unsigned char algorithmidentifier_##name##_der[] = { \
ASN1_SEQUENCE, 2 + SHA1_SZ, \
ASN1_OID, SHA1_SZ, OID_FIRST(1, 2), DER_840(), DER_10045(), 4, 1 \
}
/*
* -- RFC 5758
*
* 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 }
*/
#define ENCODE_ALGORITHMIDENTIFIER_SHA2(name, n) \
static const unsigned char algorithmidentifier_##name##_der[] = { \
ASN1_SEQUENCE, 2 + SHA2_SZ, \
ASN1_OID, SHA2_SZ, OID_FIRST(1, 2), DER_840(), DER_10045(), 4, 3, n \
}
/*
* 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 ::= { sigAlgs 9 }
* id-ecdsa-with-sha3-256 ::= { sigAlgs 10 }
* id-ecdsa-with-sha3-384 ::= { sigAlgs 11 }
* id-ecdsa-with-sha3-512 ::= { sigAlgs 12 }
*/
#define ENCODE_ALGORITHMIDENTIFIER_SHA3(name, n) \
static const unsigned char algorithmidentifier_##name##_der[] = { \
ASN1_SEQUENCE, 2 + SHA3_SZ, \
ASN1_OID, SHA3_SZ, OID_FIRST(2, 16), DER_840(), 1, 101, 3, 4, 3, n \
}
ENCODE_ALGORITHMIDENTIFIER_SHA1(sha1);
ENCODE_ALGORITHMIDENTIFIER_SHA2(sha224, 1);
ENCODE_ALGORITHMIDENTIFIER_SHA2(sha256, 2);
ENCODE_ALGORITHMIDENTIFIER_SHA2(sha384, 3);
ENCODE_ALGORITHMIDENTIFIER_SHA2(sha512, 4);
ENCODE_ALGORITHMIDENTIFIER_SHA3(sha3_224, 9);
ENCODE_ALGORITHMIDENTIFIER_SHA3(sha3_256, 10);
ENCODE_ALGORITHMIDENTIFIER_SHA3(sha3_384, 11);
ENCODE_ALGORITHMIDENTIFIER_SHA3(sha3_512, 12);
/* TODO - Add SHAKE OIDS when they are standardized */
#define MD_CASE(name) \
case NID_##name: \
*len = sizeof(algorithmidentifier_##name##_der); \
return algorithmidentifier_##name##_der
const unsigned char *ecdsa_algorithmidentifier_encoding(int md_nid, size_t *len)
{
switch (md_nid) {
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 NULL;
}
}

+ 83
- 0
providers/common/der/EC.asn1 View File

@ -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 }

+ 8
- 1
providers/common/der/build.info View File

@ -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

+ 67
- 0
providers/common/der/der_ec.c.in View File

@ -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);
}

+ 21
- 0
providers/common/der/der_ec.h.in View File

@ -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);

+ 1
- 0
providers/implementations/signature/build.info View File

@ -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

+ 22
- 9
providers/implementations/signature/ecdsa.c View File

@ -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;


Loading…
Cancel
Save