Skip to content

Commit

Permalink
Add SM2 signature algorithm to default provider
Browse files Browse the repository at this point in the history
Reviewed-by: Richard Levitte <levitte@openssl.org>
Reviewed-by: Matt Caswell <matt@openssl.org>
(Merged from #12536)
  • Loading branch information
InfoHunter authored and mattcaswell committed Sep 22, 2020
1 parent 7ee511d commit d0b79f8
Show file tree
Hide file tree
Showing 21 changed files with 799 additions and 175 deletions.
2 changes: 2 additions & 0 deletions crypto/err/openssl.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1231,6 +1231,8 @@ SM2_F_SM2_COMPUTE_USERID_DIGEST:101:sm2_compute_userid_digest
SM2_F_SM2_COMPUTE_Z_DIGEST:113:sm2_compute_z_digest
SM2_F_SM2_DECRYPT:102:sm2_decrypt
SM2_F_SM2_ENCRYPT:103:sm2_encrypt
SM2_F_SM2_INTERNAL_SIGN:116:
SM2_F_SM2_INTERNAL_VERIFY:117:
SM2_F_SM2_PLAINTEXT_SIZE:104:sm2_plaintext_size
SM2_F_SM2_SIGN:105:sm2_sign
SM2_F_SM2_SIG_GEN:106:sm2_sig_gen
Expand Down
38 changes: 0 additions & 38 deletions crypto/evp/pmeth_gn.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,6 @@
#include "crypto/evp.h"
#include "evp_local.h"

/* TODO(3.0) remove when provider SM2 key generation is implemented */
#ifdef TMP_SM2_HACK
# include <openssl/ec.h>
# include "internal/sizes.h"
#endif

static int gen_init(EVP_PKEY_CTX *ctx, int operation)
{
int ret = 0;
Expand All @@ -39,12 +33,6 @@ static int gen_init(EVP_PKEY_CTX *ctx, int operation)
if (ctx->keymgmt == NULL || ctx->keymgmt->gen_init == NULL)
goto legacy;

/* TODO remove when provider SM2 key generation is implemented */
#ifdef TMP_SM2_HACK
if (ctx->pmeth != NULL && ctx->pmeth->pkey_id == EVP_PKEY_SM2)
goto legacy;
#endif

switch (operation) {
case EVP_PKEY_OP_PARAMGEN:
ctx->op.keymgmt.genctx =
Expand Down Expand Up @@ -214,32 +202,6 @@ int EVP_PKEY_gen(EVP_PKEY_CTX *ctx, EVP_PKEY **ppkey)
*/
(*ppkey)->type = ctx->legacy_keytype;

/* TODO remove when SM2 key have been cleanly separated from EC keys */
#ifdef TMP_SM2_HACK
/*
* Legacy SM2 keys are implemented as EC_KEY with a twist. The legacy
* key generation detects the SM2 curve and "magically" changes the pkey
* id accordingly.
* Since we don't have SM2 in the provider implementation, we need to
* downgrade the generated provider side key to a legacy one under the
* same conditions.
*
* THIS IS AN UGLY BUT TEMPORARY HACK
*/
{
char curve_name[OSSL_MAX_NAME_SIZE] = "";

if (!EVP_PKEY_get_utf8_string_param(*ppkey, OSSL_PKEY_PARAM_GROUP_NAME,
curve_name, sizeof(curve_name),
NULL)
|| strcmp(curve_name, "SM2") != 0)
goto end;
}

if (!evp_pkey_downgrade(*ppkey)
|| !EVP_PKEY_set_alias_type(*ppkey, EVP_PKEY_SM2))
ret = 0;
#endif
goto end;

legacy:
Expand Down
32 changes: 1 addition & 31 deletions crypto/evp/pmeth_lib.c
Original file line number Diff line number Diff line change
Expand Up @@ -175,28 +175,6 @@ static int get_legacy_alg_type_from_keymgmt(const EVP_KEYMGMT *keymgmt)
}
#endif /* FIPS_MODULE */

static int is_legacy_alg(int id, const char *keytype)
{
#ifndef FIPS_MODULE
/* Certain EVP_PKEY keytypes are only available in legacy form */
if (id == -1)
id = evp_pkey_name2type(keytype);

switch (id) {
/*
* TODO(3.0): Remove SM2 when they are converted to have provider
* support
*/
case EVP_PKEY_SM2:
return 1;
default:
return 0;
}
#else
return 0;
#endif
}

static EVP_PKEY_CTX *int_ctx_new(OPENSSL_CTX *libctx,
EVP_PKEY *pkey, ENGINE *e,
const char *keytype, const char *propquery,
Expand Down Expand Up @@ -284,16 +262,8 @@ static EVP_PKEY_CTX *int_ctx_new(OPENSSL_CTX *libctx,
* implementation.
*/
if (e == NULL && keytype != NULL) {
int legacy = is_legacy_alg(id, keytype);

/* This could fail so ignore errors */
if (legacy)
ERR_set_mark();

keymgmt = EVP_KEYMGMT_fetch(libctx, keytype, propquery);
if (legacy)
ERR_pop_to_mark();
else if (keymgmt == NULL)
if (keymgmt == NULL)
return NULL; /* EVP_KEYMGMT_fetch() recorded an error */

#ifndef FIPS_MODULE
Expand Down
2 changes: 1 addition & 1 deletion crypto/sm2/sm2_err.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
* Generated by util/mkerr.pl DO NOT EDIT
* Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved.
* Copyright 1995-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
Expand Down
4 changes: 2 additions & 2 deletions crypto/sm2/sm2_pmeth.c
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ static int pkey_sm2_sign(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen,
return 0;
}

ret = sm2_sign(tbs, tbslen, sig, &sltmp, ec);
ret = sm2_internal_sign(tbs, tbslen, sig, &sltmp, ec);

if (ret <= 0)
return ret;
Expand All @@ -118,7 +118,7 @@ static int pkey_sm2_verify(EVP_PKEY_CTX *ctx,
{
EC_KEY *ec = ctx->pkey->pkey.ec;

return sm2_verify(tbs, tbslen, sig, siglen, ec);
return sm2_internal_verify(tbs, tbslen, sig, siglen, ec);
}

static int pkey_sm2_encrypt(EVP_PKEY_CTX *ctx,
Expand Down
22 changes: 11 additions & 11 deletions crypto/sm2/sm2_sign.c
Original file line number Diff line number Diff line change
Expand Up @@ -418,8 +418,8 @@ int sm2_do_verify(const EC_KEY *key,
return ret;
}

int sm2_sign(const unsigned char *dgst, int dgstlen,
unsigned char *sig, unsigned int *siglen, EC_KEY *eckey)
int sm2_internal_sign(const unsigned char *dgst, int dgstlen,
unsigned char *sig, unsigned int *siglen, EC_KEY *eckey)
{
BIGNUM *e = NULL;
ECDSA_SIG *s = NULL;
Expand All @@ -428,19 +428,19 @@ int sm2_sign(const unsigned char *dgst, int dgstlen,

e = BN_bin2bn(dgst, dgstlen, NULL);
if (e == NULL) {
SM2err(SM2_F_SM2_SIGN, ERR_R_BN_LIB);
SM2err(SM2_F_SM2_INTERNAL_SIGN, ERR_R_BN_LIB);
goto done;
}

s = sm2_sig_gen(eckey, e);
if (s == NULL) {
SM2err(SM2_F_SM2_SIGN, ERR_R_INTERNAL_ERROR);
SM2err(SM2_F_SM2_INTERNAL_SIGN, ERR_R_INTERNAL_ERROR);
goto done;
}

sigleni = i2d_ECDSA_SIG(s, &sig);
if (sigleni < 0) {
SM2err(SM2_F_SM2_SIGN, ERR_R_INTERNAL_ERROR);
SM2err(SM2_F_SM2_INTERNAL_SIGN, ERR_R_INTERNAL_ERROR);
goto done;
}
*siglen = (unsigned int)sigleni;
Expand All @@ -453,8 +453,8 @@ int sm2_sign(const unsigned char *dgst, int dgstlen,
return ret;
}

int sm2_verify(const unsigned char *dgst, int dgstlen,
const unsigned char *sig, int sig_len, EC_KEY *eckey)
int sm2_internal_verify(const unsigned char *dgst, int dgstlen,
const unsigned char *sig, int sig_len, EC_KEY *eckey)
{
ECDSA_SIG *s = NULL;
BIGNUM *e = NULL;
Expand All @@ -465,23 +465,23 @@ int sm2_verify(const unsigned char *dgst, int dgstlen,

s = ECDSA_SIG_new();
if (s == NULL) {
SM2err(SM2_F_SM2_VERIFY, ERR_R_MALLOC_FAILURE);
SM2err(SM2_F_SM2_INTERNAL_VERIFY, ERR_R_MALLOC_FAILURE);
goto done;
}
if (d2i_ECDSA_SIG(&s, &p, sig_len) == NULL) {
SM2err(SM2_F_SM2_VERIFY, SM2_R_INVALID_ENCODING);
SM2err(SM2_F_SM2_INTERNAL_VERIFY, SM2_R_INVALID_ENCODING);
goto done;
}
/* Ensure signature uses DER and doesn't have trailing garbage */
derlen = i2d_ECDSA_SIG(s, &der);
if (derlen != sig_len || memcmp(sig, der, derlen) != 0) {
SM2err(SM2_F_SM2_VERIFY, SM2_R_INVALID_ENCODING);
SM2err(SM2_F_SM2_INTERNAL_VERIFY, SM2_R_INVALID_ENCODING);
goto done;
}

e = BN_bin2bn(dgst, dgstlen, NULL);
if (e == NULL) {
SM2err(SM2_F_SM2_VERIFY, ERR_R_BN_LIB);
SM2err(SM2_F_SM2_INTERNAL_VERIFY, ERR_R_BN_LIB);
goto done;
}

Expand Down
9 changes: 5 additions & 4 deletions include/crypto/sm2.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,14 +45,14 @@ int sm2_do_verify(const EC_KEY *key,
/*
* SM2 signature generation.
*/
int sm2_sign(const unsigned char *dgst, int dgstlen,
unsigned char *sig, unsigned int *siglen, EC_KEY *eckey);
int sm2_internal_sign(const unsigned char *dgst, int dgstlen,
unsigned char *sig, unsigned int *siglen, EC_KEY *eckey);

/*
* SM2 signature verification.
*/
int sm2_verify(const unsigned char *dgst, int dgstlen,
const unsigned char *sig, int siglen, EC_KEY *eckey);
int sm2_internal_verify(const unsigned char *dgst, int dgstlen,
const unsigned char *sig, int siglen, EC_KEY *eckey);

/*
* SM2 encryption
Expand All @@ -74,5 +74,6 @@ int sm2_decrypt(const EC_KEY *key,
const uint8_t *ciphertext,
size_t ciphertext_len, uint8_t *ptext_buf, size_t *ptext_len);

const unsigned char *sm2_algorithmidentifier_encoding(int md_nid, size_t *len);
# endif /* OPENSSL_NO_SM2 */
#endif
8 changes: 5 additions & 3 deletions include/crypto/sm2err.h
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
/*
* Generated by util/mkerr.pl DO NOT EDIT
* Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved.
* Copyright 1995-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
*/

#ifndef OSSL_CRYPTO_SM2ERR_H
# define OSSL_CRYPTO_SM2ERR_H
#ifndef OPENSSL_SM2ERR_H
# define OPENSSL_SM2ERR_H

# include <openssl/opensslconf.h>
# include <openssl/symhacks.h>
Expand Down Expand Up @@ -39,6 +39,8 @@ int ERR_load_SM2_strings(void);
# define SM2_F_SM2_COMPUTE_Z_DIGEST 0
# define SM2_F_SM2_DECRYPT 0
# define SM2_F_SM2_ENCRYPT 0
# define SM2_F_SM2_INTERNAL_SIGN 0
# define SM2_F_SM2_INTERNAL_VERIFY 0
# define SM2_F_SM2_PLAINTEXT_SIZE 0
# define SM2_F_SM2_SIGN 0
# define SM2_F_SM2_SIG_GEN 0
Expand Down
1 change: 1 addition & 0 deletions include/openssl/core_names.h
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,7 @@ extern "C" {
#define OSSL_DIGEST_NAME_SHA3_512 "SHA3-512"
#define OSSL_DIGEST_NAME_KECCAK_KMAC128 "KECCAK-KMAC-128"
#define OSSL_DIGEST_NAME_KECCAK_KMAC256 "KECCAK-KMAC-256"
#define OSSL_DIGEST_NAME_SM3 "SM3"

/* MAC parameters */
#define OSSL_MAC_PARAM_KEY "key" /* octet string */
Expand Down
11 changes: 11 additions & 0 deletions providers/common/der/SM2.asn1
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
oscca OBJECT IDENTIFIER ::= { iso(1) member-body(2) cn(156) 10197 }

sm-scheme OBJECT IDENTIFIER ::= { oscca 1 }

-- OID for SM2 signatures with SM3

sm2-with-SM3 OBJECT IDENTIFIER ::= { sm-scheme 501 }

-- Named Elliptic Curves of SM2

curveSM2 OBJECT IDENTIFIER ::= { sm-scheme 301 }
16 changes: 15 additions & 1 deletion providers/common/der/build.info
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,19 @@ DEPEND[${DER_WRAP_GEN/.c/.o}]=$DER_WRAP_H
GENERATE[$DER_WRAP_H]=der_wrap.h.in
DEPEND[$DER_WRAP_H]=oids_to_c.pm

#----- SM2
$DER_SM2_H=../include/prov/der_sm2.h
$DER_SM2_GEN=der_sm2_gen.c
$DER_SM2_AUX=der_sm2_key.c der_sm2_sig.c

GENERATE[$DER_SM2_GEN]=der_sm2_gen.c.in
DEPEND[$DER_SM2_GEN]=oids_to_c.pm

DEPEND[${DER_SM2_AUX/.c/.o}]=$DER_SM2_H $DER_EC_H
DEPEND[${DER_SM2_GEN/.c/.o}]=$DER_SM2_H
GENERATE[$DER_SM2_H]=der_sm2.h.in
DEPEND[$DER_SM2_H]=oids_to_c.pm

#----- Conclusion

# TODO(3.0) $COMMON should go to libcommon.a, but this currently leads
Expand All @@ -84,7 +97,8 @@ $COMMON=\
$DER_DSA_GEN $DER_DSA_AUX \
$DER_EC_GEN $DER_EC_AUX \
$DER_DIGESTS_GEN \
$DER_WRAP_GEN
$DER_WRAP_GEN \
$DER_SM2_GEN $DER_SM2_AUX

IF[{- !$disabled{ec} -}]
$COMMON = $COMMON $DER_ECX_GEN $DER_ECX_AUX
Expand Down
23 changes: 23 additions & 0 deletions providers/common/der/der_sm2.h.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/*
* 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/SM2.asn1',
{ dir => $config{sourcedir},
filter => \&oids_to_c::filter_to_H });
-}

/* Subject Public Key Info */
int DER_w_algorithmIdentifier_SM2(WPACKET *pkt, int cont, EC_KEY *ec);
/* Signature */
int DER_w_algorithmIdentifier_SM2_with_MD(WPACKET *pkt, int cont,
EC_KEY *ec, int mdnid);
17 changes: 17 additions & 0 deletions providers/common/der/der_sm2_gen.c.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
/*
* 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 "prov/der_sm2.h"

/* Well known OIDs precompiled */
{-
$OUT = oids_to_c::process_leaves('providers/common/der/SM2.asn1',
{ dir => $config{sourcedir},
filter => \&oids_to_c::filter_to_C });
-}
23 changes: 23 additions & 0 deletions providers/common/der/der_sm2_key.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/*
* 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/obj_mac.h>
#include "internal/packet.h"
#include "prov/der_ec.h"
#include "prov/der_sm2.h"

int DER_w_algorithmIdentifier_SM2(WPACKET *pkt, int cont, EC_KEY *ec)
{
return DER_w_begin_sequence(pkt, cont)
/* No parameters (yet?) */
/* It seems SM2 identifier is the same to id_ecPublidKey */
&& DER_w_precompiled(pkt, -1, der_oid_id_ecPublicKey,
sizeof(der_oid_id_ecPublicKey))
&& DER_w_end_sequence(pkt, cont);
}

0 comments on commit d0b79f8

Please sign in to comment.