Add sm9 and paillier pem support

This commit is contained in:
Zhi Guan
2018-11-16 15:26:30 +08:00
parent 5baad7e043
commit 9a999ae907
38 changed files with 7956 additions and 6992 deletions

View File

@@ -1,3 +1,4 @@
LIBS=../../libcrypto
SOURCE[../../libcrypto]=sm9_lib.c sm9_err.c sm9_asn1.c sm9_params.c \
sm9_setup.c sm9_keygen.c sm9_sign.c sm9_enc.c sm9_exch.c sm9_rate.c
sm9_setup.c sm9_keygen.c sm9_sign.c sm9_enc.c sm9_exch.c sm9_rate.c \
sm9_ameth.c

411
crypto/sm9/sm9_ameth.c Normal file
View File

@@ -0,0 +1,411 @@
/* ====================================================================
* Copyright (c) 2015 - 2018 The GmSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the GmSSL Project.
* (http://gmssl.org/)"
*
* 4. The name "GmSSL Project" must not be used to endorse or promote
* products derived from this software without prior written
* permission. For written permission, please contact
* guanzhi1980@gmail.com.
*
* 5. Products derived from this software may not be called "GmSSL"
* nor may "GmSSL" appear in their names without prior written
* permission of the GmSSL Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the GmSSL Project
* (http://gmssl.org/)"
*
* THIS SOFTWARE IS PROVIDED BY THE GmSSL PROJECT ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GmSSL PROJECT OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*/
#include <stdio.h>
#include <openssl/sm9.h>
#include <openssl/err.h>
#include <openssl/evp.h>
#include <openssl/x509.h>
#include <openssl/asn1t.h>
#include <openssl/objects.h>
#include "internal/cryptlib.h"
#include "internal/asn1_int.h"
#include "internal/evp_int.h"
#include "sm9_lcl.h"
static int sm9_params_encode(X509_PUBKEY *pubkey, const EVP_PKEY *pkey)
{
unsigned char *penc = NULL;
int penclen;
if ((penclen = i2d_SM9PublicParameters(pkey->pkey.sm9_master, &penc)) <= 0) {
return 0;
}
printf("penclen = %d\n", penclen);
printf("penc == NULL: %d\n", penc == NULL);
printf("%lu\n", OBJ_nid2obj(EVP_PKEY_SM9_MASTER));
OPENSSL_assert(pubkey);
if (X509_PUBKEY_set0_param(pubkey, OBJ_nid2obj(EVP_PKEY_SM9_MASTER),
V_ASN1_NULL, NULL, penc, penclen)) {
return 1;
}
OPENSSL_free(penc);
return 0;
}
static int sm9_params_decode(EVP_PKEY *pkey, X509_PUBKEY *pubkey)
{
const unsigned char *cp;
int len;
SM9PublicParameters *sm9_params = NULL;
if (!X509_PUBKEY_get0_param(NULL, &cp, &len, NULL, pubkey)) {
return 0;
}
if (!(sm9_params = d2i_SM9PublicParameters(NULL, &cp, len))) {
SM9err(SM9_F_SM9_PARAMS_DECODE, ERR_R_SM9_LIB);
return 0;
}
EVP_PKEY_assign_SM9PublicParameters(pkey, sm9_params);
return 1;
}
static int sm9_params_cmp(const EVP_PKEY *a, const EVP_PKEY *b)
{
/*
if (OBJ_cmp(a->pkey.sm9_master->pairing, b->pkey.sm9_master->pairing) != 0
|| OBJ_cmp(a->pkey.sm9_master->scheme, b->pkey.sm9_master->scheme) != 0
|| OBJ_cmp(a->pkey.sm9_master->hash1, b->pkey.sm9_master->hash1) != 0
|| ASN1_OCTET_STRING_cmp(a->pkey.sm9_master->pointPpub,
b->pkey.sm9_master->pointPpub) != 0) {
return 0;
}
*/
return 1;
}
static int do_sm9_master_print(BIO *bp, const SM9MasterSecret *x, int off, int priv)
{
return -2;
}
static int sm9_params_print(BIO *bp, const EVP_PKEY *pkey, int indent,
ASN1_PCTX *ctx)
{
return do_sm9_master_print(bp, pkey->pkey.sm9_master, indent, 0);
}
static int sm9_master_print(BIO *bp, const EVP_PKEY *pkey, int indent,
ASN1_PCTX *ctx)
{
return do_sm9_master_print(bp, pkey->pkey.sm9_master, indent, 1);
}
static int sm9_master_decode(EVP_PKEY *pkey, const PKCS8_PRIV_KEY_INFO *p8)
{
const unsigned char *p;
int pklen;
SM9MasterSecret *sm9_master;
if (!PKCS8_pkey_get0(NULL, &p, &pklen, NULL, p8))
return 0;
if (!(sm9_master = d2i_SM9MasterSecret(NULL, &p, pklen))) {
SM9err(SM9_F_SM9_MASTER_DECODE, ERR_R_SM9_LIB);
return 0;
}
EVP_PKEY_assign_SM9MasterSecret(pkey, sm9_master);
return 1;
}
static int sm9_master_encode(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pkey)
{
unsigned char *rk = NULL;
int rklen;
fprintf(stderr, "%s %d: %s\n", __FILE__, __LINE__, __FUNCTION__);
if ((rklen = i2d_SM9MasterSecret(pkey->pkey.sm9_master, &rk)) <= 0) {
SM9err(SM9_F_SM9_MASTER_ENCODE, ERR_R_MALLOC_FAILURE);
return 0;
}
if (!PKCS8_pkey_set0(p8, OBJ_nid2obj(EVP_PKEY_SM9_MASTER), 0,
V_ASN1_NULL, NULL, rk, rklen)) {
SM9err(SM9_F_SM9_MASTER_ENCODE, ERR_R_MALLOC_FAILURE);
return 0;
}
return 1;
}
static int int_sm9_size(const EVP_PKEY *pkey)
{
return 32 * 12;
}
static int sm9_bits(const EVP_PKEY *pkey)
{
return 256 * 12;
}
static int sm9_security_bits(const EVP_PKEY *pkey)
{
return 256/2;
}
static void int_sm9_master_free(EVP_PKEY *pkey)
{
SM9MasterSecret_free(pkey->pkey.sm9_master);
}
static int sm9_master_pkey_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2)
{
return -2;
}
static int old_sm9_master_decode(EVP_PKEY *pkey,
const unsigned char **pder, int derlen)
{
SM9MasterSecret *sm9_master;
if ((sm9_master = d2i_SM9MasterSecret(NULL, pder, derlen)) == NULL) {
SM9err(SM9_F_OLD_SM9_MASTER_DECODE, SM9_R_DECODE_ERROR);
return 0;
}
EVP_PKEY_assign_SM9MasterSecret(pkey, sm9_master);
return 1;
}
static int old_sm9_master_encode(const EVP_PKEY *pkey, unsigned char **pder)
{
fprintf(stderr, "%s %d: %s\n", __FILE__, __LINE__, __FUNCTION__);
return i2d_SM9MasterSecret(pkey->pkey.sm9_master, pder);
}
const EVP_PKEY_ASN1_METHOD sm9_master_asn1_meth = {
EVP_PKEY_SM9_MASTER, /* pkey_id */
EVP_PKEY_SM9_MASTER, /* pkey_base_id */
0, /* pkey_flags */
"SM9 MASTER", /* pem_str */
"GmSSL SM9 algorithm", /* info */
sm9_params_decode, /* pub_decode */
sm9_params_encode, /* pub_encode */
sm9_params_cmp, /* pub_cmp */
sm9_params_print, /* pub_print */
sm9_master_decode, /* priv_decode */
sm9_master_encode, /* priv_encode */
sm9_master_print, /* priv_print */
int_sm9_size, /* pkey_size */
sm9_bits, /* pkey_bits */
sm9_security_bits, /* pkey_security_bits */
NULL, /* param_decode */
NULL, /* param_encode */
NULL, /* param_missing */
NULL, /* param_copy */
NULL, /* param_cmp */
NULL, /* param_print */
NULL, /* sig_print */
int_sm9_master_free, /* pkey_free */
sm9_master_pkey_ctrl, /* pkey_ctrl */
old_sm9_master_decode, /* old_priv_decode */
old_sm9_master_encode, /* old_priv_encode */
NULL, /* item_verify */
NULL, /* item_sign */
};
static int sm9_pub_encode(X509_PUBKEY *pubkey, const EVP_PKEY *pkey)
{
unsigned char *penc = NULL;
int penclen;
if ((penclen = i2d_SM9PublicKey(pkey->pkey.sm9, &penc)) <= 0) {
return 0;
}
if (X509_PUBKEY_set0_param(pubkey, OBJ_nid2obj(EVP_PKEY_SM9),
V_ASN1_NULL, NULL, penc, penclen)) {
return 1;
}
OPENSSL_free(penc);
return 0;
}
static int sm9_pub_decode(EVP_PKEY *pkey, X509_PUBKEY *pubkey)
{
const unsigned char *cp;
int len;
SM9PublicKey *sm9 = NULL;
if (!X509_PUBKEY_get0_param(NULL, &cp, &len, NULL, pubkey)) {
return 0;
}
if (!(sm9 = d2i_SM9PublicKey(NULL, &cp, len))) {
SM9err(SM9_F_SM9_PUB_DECODE, ERR_R_SM9_LIB);
return 0;
}
EVP_PKEY_assign_SM9PublicKey(pkey, sm9);
return 1;
}
static int sm9_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b)
{
const SM9PublicKey *ax = a->pkey.sm9;
const SM9PublicKey *bx = b->pkey.sm9;
if (OBJ_cmp(ax->pairing, bx->pairing)
|| OBJ_cmp(ax->scheme, bx->scheme)
|| OBJ_cmp(ax->hash1, bx->hash1)
/* FIXME: decode point then compare to support point compression */
|| ASN1_OCTET_STRING_cmp(ax->pointPpub, bx->pointPpub)
|| ASN1_OCTET_STRING_cmp(ax->identity, bx->identity)
|| ASN1_OCTET_STRING_cmp(ax->publicPoint, bx->publicPoint)) {
return 0;
}
return 1;
}
static int do_sm9_print(BIO *bp, const SM9PrivateKey *x, int off, int priv)
{
return -2;
}
static int sm9_pub_print(BIO *bp, const EVP_PKEY *pkey, int indent,
ASN1_PCTX *ctx)
{
return do_sm9_print(bp, pkey->pkey.sm9, indent, 0);
}
static int sm9_priv_print(BIO *bp, const EVP_PKEY *pkey, int indent,
ASN1_PCTX *ctx)
{
return do_sm9_print(bp, pkey->pkey.sm9, indent, 1);
}
static int sm9_priv_decode(EVP_PKEY *pkey, const PKCS8_PRIV_KEY_INFO *p8)
{
const unsigned char *p;
int pklen;
SM9PrivateKey *sm9;
if (!PKCS8_pkey_get0(NULL, &p, &pklen, NULL, p8))
return 0;
if (!(sm9 = d2i_SM9PrivateKey(NULL, &p, pklen))) {
SM9err(SM9_F_SM9_PRIV_DECODE, ERR_R_SM9_LIB);
return 0;
}
EVP_PKEY_assign_SM9PrivateKey(pkey, sm9);
return 1;
}
static int sm9_priv_encode(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pkey)
{
unsigned char *rk = NULL;
int rklen;
/*
fprintf(stderr, "%s %d: %s\n", __FILE__, __LINE__, __FUNCTION__);
fprintf(stderr, "%s %s: %d\n", __FILE__, __LINE__, pkey->pkey.sm9->privatePoint != NULL);
*/
if ((rklen = i2d_SM9PrivateKey(pkey->pkey.sm9, &rk)) <= 0) {
SM9err(SM9_F_SM9_PRIV_ENCODE, ERR_R_MALLOC_FAILURE);
return 0;
}
if (!PKCS8_pkey_set0(p8, OBJ_nid2obj(EVP_PKEY_SM9), 0,
V_ASN1_NULL, NULL, rk, rklen)) {
SM9err(SM9_F_SM9_PRIV_ENCODE, ERR_R_MALLOC_FAILURE);
return 0;
}
return 1;
}
static void int_sm9_free(EVP_PKEY *pkey)
{
SM9PrivateKey_free(pkey->pkey.sm9);
}
static int sm9_pkey_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2)
{
return -2;
}
static int old_sm9_priv_decode(EVP_PKEY *pkey,
const unsigned char **pder, int derlen)
{
SM9PrivateKey *sm9;
if ((sm9 = d2i_SM9PrivateKey(NULL, pder, derlen)) == NULL) {
SM9err(SM9_F_OLD_SM9_PRIV_DECODE, SM9_R_DECODE_ERROR);
return 0;
}
EVP_PKEY_assign_SM9PrivateKey(pkey, sm9);
return 1;
}
static int old_sm9_priv_encode(const EVP_PKEY *pkey, unsigned char **pder)
{
fprintf(stderr, "%s %d: %s\n", __FILE__, __LINE__, __FUNCTION__);
return i2d_SM9PrivateKey(pkey->pkey.sm9, pder);
}
const EVP_PKEY_ASN1_METHOD sm9_asn1_meth = {
EVP_PKEY_SM9, /* pkey_id */
EVP_PKEY_SM9, /* pkey_base_id */
0, /* pkey_flags */
"SM9", /* pem_str */
"GmSSL SM9 algorithm", /* info */
sm9_pub_decode, /* pub_decode */
sm9_pub_encode, /* pub_encode */
sm9_pub_cmp, /* pub_cmp */
sm9_pub_print, /* pub_print */
sm9_priv_decode, /* priv_decode */
sm9_priv_encode, /* priv_encode */
sm9_priv_print, /* priv_print */
int_sm9_size, /* pkey_size */
sm9_bits, /* pkey_bits */
sm9_security_bits, /* pkey_security_bits */
NULL, /* param_decode */
NULL, /* param_encode */
NULL, /* param_missing */
NULL, /* param_copy */
NULL, /* param_cmp */
NULL, /* param_print */
NULL, /* sig_print */
int_sm9_free, /* pkey_free */
sm9_pkey_ctrl, /* pkey_ctrl */
old_sm9_priv_decode, /* old_priv_decode */
old_sm9_priv_encode, /* old_priv_encode */
NULL, /* item_verify */
NULL, /* item_sign */
};

View File

@@ -55,47 +55,76 @@
#include <openssl/sm9.h>
#include "sm9_lcl.h"
ASN1_SEQUENCE(SM9MasterSecret) = {
ASN1_SIMPLE(SM9MasterSecret, pairing, ASN1_OBJECT),
ASN1_SIMPLE(SM9MasterSecret, scheme, ASN1_OBJECT),
ASN1_SIMPLE(SM9MasterSecret, hash1, ASN1_OBJECT),
ASN1_SIMPLE(SM9MasterSecret, pointPpub, ASN1_OCTET_STRING),
ASN1_SIMPLE(SM9MasterSecret, masterSecret, BIGNUM)
} ASN1_SEQUENCE_END(SM9MasterSecret)
IMPLEMENT_ASN1_FUNCTIONS(SM9MasterSecret)
IMPLEMENT_ASN1_DUP_FUNCTION(SM9MasterSecret)
static int sm9_master_key_cb(int operation, ASN1_VALUE **pval,
const ASN1_ITEM *it, void *exarg)
{
if (operation == ASN1_OP_NEW_PRE) {
*pval = (ASN1_VALUE *)SM9_MASTER_KEY_new();
if (*pval)
return 2;
return 0;
} else if (operation == ASN1_OP_FREE_PRE) {
SM9_MASTER_KEY_free((SM9_MASTER_KEY *)*pval);
*pval = NULL;
return 2;
}
return 1;
}
ASN1_SEQUENCE(SM9PublicParameters) = {
ASN1_SIMPLE(SM9PublicParameters, pairing, ASN1_OBJECT),
ASN1_SIMPLE(SM9PublicParameters, scheme, ASN1_OBJECT),
ASN1_SIMPLE(SM9PublicParameters, hash1, ASN1_OBJECT),
ASN1_SIMPLE(SM9PublicParameters, pointPpub, ASN1_OCTET_STRING)
} ASN1_SEQUENCE_END(SM9PublicParameters)
IMPLEMENT_ASN1_FUNCTIONS(SM9PublicParameters)
IMPLEMENT_ASN1_DUP_FUNCTION(SM9PublicParameters)
ASN1_SEQUENCE_cb(SM9MasterSecret, sm9_master_key_cb) = {
ASN1_SIMPLE(SM9_MASTER_KEY, pairing, ASN1_OBJECT),
ASN1_SIMPLE(SM9_MASTER_KEY, scheme, ASN1_OBJECT),
ASN1_SIMPLE(SM9_MASTER_KEY, hash1, ASN1_OBJECT),
ASN1_SIMPLE(SM9_MASTER_KEY, pointPpub, ASN1_OCTET_STRING),
ASN1_SIMPLE(SM9_MASTER_KEY, masterSecret, BIGNUM)
} ASN1_SEQUENCE_END_cb(SM9_MASTER_KEY, SM9MasterSecret)
IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(SM9_MASTER_KEY,SM9MasterSecret,SM9MasterSecret)
ASN1_SEQUENCE(SM9PrivateKey) = {
ASN1_SIMPLE(SM9PrivateKey, pairing, ASN1_OBJECT),
ASN1_SIMPLE(SM9PrivateKey, scheme, ASN1_OBJECT),
ASN1_SIMPLE(SM9PrivateKey, hash1, ASN1_OBJECT),
ASN1_SIMPLE(SM9PrivateKey, pointPpub, ASN1_OCTET_STRING),
ASN1_SIMPLE(SM9PrivateKey, identity, ASN1_OCTET_STRING),
ASN1_SIMPLE(SM9PrivateKey, publicPoint, ASN1_OCTET_STRING),
ASN1_SIMPLE(SM9PrivateKey, privatePoint, ASN1_OCTET_STRING)
} ASN1_SEQUENCE_END(SM9PrivateKey)
IMPLEMENT_ASN1_FUNCTIONS(SM9PrivateKey)
IMPLEMENT_ASN1_DUP_FUNCTION(SM9PrivateKey)
ASN1_SEQUENCE_cb(SM9PublicParameters, sm9_master_key_cb) = {
ASN1_SIMPLE(SM9_MASTER_KEY, pairing, ASN1_OBJECT),
ASN1_SIMPLE(SM9_MASTER_KEY, scheme, ASN1_OBJECT),
ASN1_SIMPLE(SM9_MASTER_KEY, hash1, ASN1_OBJECT),
ASN1_SIMPLE(SM9_MASTER_KEY, pointPpub, ASN1_OCTET_STRING)
} ASN1_SEQUENCE_END_cb(SM9_MASTER_KEY, SM9PublicParameters)
IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(SM9_MASTER_KEY,SM9PublicParameters,SM9PublicParameters)
ASN1_SEQUENCE(SM9PublicKey) = {
ASN1_SIMPLE(SM9PublicKey, pairing, ASN1_OBJECT),
ASN1_SIMPLE(SM9PublicKey, scheme, ASN1_OBJECT),
ASN1_SIMPLE(SM9PublicKey, hash1, ASN1_OBJECT),
ASN1_SIMPLE(SM9PublicKey, pointPpub, ASN1_OCTET_STRING),
ASN1_SIMPLE(SM9PublicKey, identity, ASN1_OCTET_STRING),
ASN1_SIMPLE(SM9PublicKey, publicPoint, ASN1_OCTET_STRING)
} ASN1_SEQUENCE_END(SM9PublicKey)
IMPLEMENT_ASN1_FUNCTIONS(SM9PublicKey)
IMPLEMENT_ASN1_DUP_FUNCTION(SM9PublicKey)
static int sm9_key_cb(int operation, ASN1_VALUE **pval,
const ASN1_ITEM *it, void *exarg)
{
if (operation == ASN1_OP_NEW_PRE) {
*pval = (ASN1_VALUE *)SM9_KEY_new();
if (*pval)
return 2;
return 0;
} else if (operation == ASN1_OP_FREE_PRE) {
SM9_KEY_free((SM9_KEY *)*pval);
*pval = NULL;
return 2;
}
return 1;
}
ASN1_SEQUENCE_cb(SM9PrivateKey, sm9_key_cb) = {
ASN1_SIMPLE(SM9_KEY, pairing, ASN1_OBJECT),
ASN1_SIMPLE(SM9_KEY, scheme, ASN1_OBJECT),
ASN1_SIMPLE(SM9_KEY, hash1, ASN1_OBJECT),
ASN1_SIMPLE(SM9_KEY, pointPpub, ASN1_OCTET_STRING),
ASN1_SIMPLE(SM9_KEY, identity, ASN1_OCTET_STRING),
ASN1_SIMPLE(SM9_KEY, publicPoint, ASN1_OCTET_STRING),
ASN1_SIMPLE(SM9_KEY, privatePoint, ASN1_OCTET_STRING)
} ASN1_SEQUENCE_END_cb(SM9_KEY, SM9PrivateKey)
IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(SM9_KEY,SM9PrivateKey,SM9PrivateKey)
ASN1_SEQUENCE_cb(SM9PublicKey, sm9_key_cb) = {
ASN1_SIMPLE(SM9_KEY, pairing, ASN1_OBJECT),
ASN1_SIMPLE(SM9_KEY, scheme, ASN1_OBJECT),
ASN1_SIMPLE(SM9_KEY, hash1, ASN1_OBJECT),
ASN1_SIMPLE(SM9_KEY, pointPpub, ASN1_OCTET_STRING),
ASN1_SIMPLE(SM9_KEY, identity, ASN1_OCTET_STRING),
ASN1_SIMPLE(SM9_KEY, publicPoint, ASN1_OCTET_STRING)
} ASN1_SEQUENCE_END_cb(SM9_KEY, SM9PublicKey)
IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(SM9_KEY,SM9PublicKey,SM9PublicKey)
ASN1_SEQUENCE(SM9Ciphertext) = {
ASN1_SIMPLE(SM9Ciphertext, pointC1, ASN1_OCTET_STRING),

View File

@@ -19,6 +19,8 @@
# define ERR_REASON(reason) ERR_PACK(ERR_LIB_SM9,0,reason)
static ERR_STRING_DATA SM9_str_functs[] = {
{ERR_FUNC(SM9_F_OLD_SM9_MASTER_DECODE), "old_sm9_master_decode"},
{ERR_FUNC(SM9_F_OLD_SM9_PRIV_DECODE), "old_sm9_priv_decode"},
{ERR_FUNC(SM9_F_SM9CIPHERTEXT_CHECK), "SM9Ciphertext_check"},
{ERR_FUNC(SM9_F_SM9ENCPARAMETERS_DECRYPT), "SM9EncParameters_decrypt"},
{ERR_FUNC(SM9_F_SM9ENCPARAMETERS_ENCRYPT), "SM9EncParameters_encrypt"},
@@ -40,6 +42,16 @@ static ERR_STRING_DATA SM9_str_functs[] = {
{ERR_FUNC(SM9_F_SM9_GENERATE_KEY_EXCHANGE), "SM9_generate_key_exchange"},
{ERR_FUNC(SM9_F_SM9_GENERATE_MASTER_SECRET),
"SM9_generate_master_secret"},
{ERR_FUNC(SM9_F_SM9_KEY_NEW), "SM9_KEY_new"},
{ERR_FUNC(SM9_F_SM9_MASTER_DECODE), "sm9_master_decode"},
{ERR_FUNC(SM9_F_SM9_MASTER_ENCODE), "sm9_master_encode"},
{ERR_FUNC(SM9_F_SM9_MASTER_KEY_EXTRACT_KEY),
"SM9_MASTER_KEY_extract_key"},
{ERR_FUNC(SM9_F_SM9_MASTER_KEY_NEW), "SM9_MASTER_KEY_new"},
{ERR_FUNC(SM9_F_SM9_PARAMS_DECODE), "sm9_params_decode"},
{ERR_FUNC(SM9_F_SM9_PRIV_DECODE), "sm9_priv_decode"},
{ERR_FUNC(SM9_F_SM9_PRIV_ENCODE), "sm9_priv_encode"},
{ERR_FUNC(SM9_F_SM9_PUB_DECODE), "sm9_pub_decode"},
{ERR_FUNC(SM9_F_SM9_SIGN), "SM9_sign"},
{ERR_FUNC(SM9_F_SM9_SIGNFINAL), "SM9_SignFinal"},
{ERR_FUNC(SM9_F_SM9_SIGNINIT), "SM9_SignInit"},
@@ -53,6 +65,7 @@ static ERR_STRING_DATA SM9_str_functs[] = {
static ERR_STRING_DATA SM9_str_reasons[] = {
{ERR_REASON(SM9_R_BUFFER_TOO_SMALL), "buffer too small"},
{ERR_REASON(SM9_R_DECODE_ERROR), "decode error"},
{ERR_REASON(SM9_R_DIGEST_FAILURE), "digest failure"},
{ERR_REASON(SM9_R_EC_LIB), "ec lib"},
{ERR_REASON(SM9_R_EXTENSION_FIELD_ERROR), "extension field error"},
@@ -80,6 +93,7 @@ static ERR_STRING_DATA SM9_str_reasons[] = {
{ERR_REASON(SM9_R_INVALID_SIGNATURE_FORMAT), "invalid signature format"},
{ERR_REASON(SM9_R_INVALID_TYPE1CURVE), "invalid type1curve"},
{ERR_REASON(SM9_R_KDF_FAILURE), "kdf failure"},
{ERR_REASON(SM9_R_NO_MASTER_SECRET), "no master secret"},
{ERR_REASON(SM9_R_PAIRING_ERROR), "pairing error"},
{ERR_REASON(SM9_R_RATE_PAIRING_ERROR), "rate pairing error"},
{ERR_REASON(SM9_R_TWIST_CURVE_ERROR), "twist curve error"},

View File

@@ -54,30 +54,6 @@
#include <openssl/bn_hash.h>
#include "sm9_lcl.h"
#if 0
int SM9_hash1(const EVP_MD *md, BIGNUM **r,
const char *id, size_t idlen,
unsigned char hid,
const BIGNUM *range,
BN_CTX *ctx)
{
unsigned char *buf;
if (!(buf = OPENSSL_malloc(idlen + 1))) {
return 0;
}
memcpy(buf, id, idlen);
buf[idlen] = hid;
if (!BN_hash_to_range(md, r, buf, idlen + 1, range, ctx)) {
OPENSSL_free(buf);
return 0;
}
OPENSSL_free(buf);
return 1;
}
#endif
int SM9_hash1(const EVP_MD *md, BIGNUM **r, const char *id, size_t idlen,
unsigned char hid, const BIGNUM *n, BN_CTX *ctx)
@@ -130,12 +106,12 @@ end:
return ret;
}
SM9PrivateKey *SM9_extract_private_key(SM9MasterSecret *msk,
const char *id, size_t idlen)
SM9_KEY *SM9_MASTER_KEY_extract_key(SM9_MASTER_KEY *master,
const char *id, size_t idlen, int priv)
{
SM9PrivateKey *ret = NULL;
SM9PrivateKey *sk = NULL;
EC_GROUP *group = NULL;
const BIGNUM *p = SM9_get0_prime();
const BIGNUM *n = SM9_get0_order();
int scheme;
@@ -148,24 +124,24 @@ SM9PrivateKey *SM9_extract_private_key(SM9MasterSecret *msk,
size_t len = sizeof(buf);
/* check args */
if (!msk || !id) {
SM9err(SM9_F_SM9_EXTRACT_PRIVATE_KEY,
if (!master || !id) {
SM9err(SM9_F_SM9_MASTER_KEY_EXTRACT_KEY,
ERR_R_PASSED_NULL_PARAMETER);
return NULL;
}
if (strlen(id) != idlen || idlen <= 0 || idlen > SM9_MAX_ID_LENGTH) {
SM9err(SM9_F_SM9_EXTRACT_PRIVATE_KEY,
SM9err(SM9_F_SM9_MASTER_KEY_EXTRACT_KEY,
SM9_R_INVALID_ID);
return NULL;
}
/* check pairing */
if (OBJ_obj2nid(msk->pairing) != NID_sm9bn256v1) {
if (OBJ_obj2nid(master->pairing) != NID_sm9bn256v1) {
return NULL;
}
/* check scheme */
scheme = OBJ_obj2nid(msk->scheme);
scheme = OBJ_obj2nid(master->scheme);
switch (scheme) {
case NID_sm9sign:
hid = SM9_HID_SIGN;
@@ -180,9 +156,14 @@ SM9PrivateKey *SM9_extract_private_key(SM9MasterSecret *msk,
return NULL;
}
/* check if master */
if (priv && master->masterSecret == NULL) {
SM9err(SM9_F_SM9_MASTER_KEY_EXTRACT_KEY, SM9_R_NO_MASTER_SECRET);
return NULL;
}
/* check hash1 and set hash1 md */
switch (OBJ_obj2nid(msk->hash1)) {
switch (OBJ_obj2nid(master->hash1)) {
case NID_sm9hash1_with_sm3:
md = EVP_sm3();
break;
@@ -190,102 +171,140 @@ SM9PrivateKey *SM9_extract_private_key(SM9MasterSecret *msk,
md = EVP_sha256();
break;
default:
SM9err(SM9_F_SM9_EXTRACT_PRIVATE_KEY, SM9_R_INVALID_HASH1);
SM9err(SM9_F_SM9_MASTER_KEY_EXTRACT_KEY, SM9_R_INVALID_HASH1);
return NULL;
}
/* malloc */
if (!(sk = SM9PrivateKey_new())
|| !(group = EC_GROUP_new_by_curve_name(NID_sm9bn256v1))
|| !(ctx = BN_CTX_new())) {
SM9err(SM9_F_SM9_EXTRACT_PRIVATE_KEY,
SM9err(SM9_F_SM9_MASTER_KEY_EXTRACT_KEY,
ERR_R_MALLOC_FAILURE);
goto end;
}
BN_CTX_start(ctx);
/* t1 = H1(ID||hid) + msk (mod n) */
if (!(sk->pairing = master->pairing)
|| !(sk->scheme = master->scheme)
|| !(sk->hash1 = master->hash1)
|| !(sk->pointPpub = ASN1_OCTET_STRING_dup(master->pointPpub))
|| !(sk->identity = ASN1_OCTET_STRING_new())
|| !ASN1_OCTET_STRING_set(sk->identity, (unsigned char *)id, idlen)
|| !(sk->publicPoint = ASN1_OCTET_STRING_new())
|| !(sk->privatePoint = ASN1_OCTET_STRING_new())) {
SM9err(SM9_F_SM9_MASTER_KEY_EXTRACT_KEY, ERR_R_ASN1_LIB);
goto end;
}
/* h1 = H1(id||HID) */
if (!SM9_hash1(md, &t, id, idlen, hid, n, ctx)) {
SM9err(SM9_F_SM9_EXTRACT_PRIVATE_KEY, ERR_R_SM9_LIB);
SM9err(SM9_F_SM9_MASTER_KEY_EXTRACT_KEY, ERR_R_SM9_LIB);
goto end;
}
if (!BN_mod_add(t, t, msk->masterSecret, n, ctx)) {
SM9err(SM9_F_SM9_EXTRACT_PRIVATE_KEY, ERR_R_BN_LIB);
goto end;
}
/* if t1 is zero, return failed */
if (BN_is_zero(t)) {
SM9err(SM9_F_SM9_EXTRACT_PRIVATE_KEY, SM9_R_ZERO_ID);
goto end;
}
/* t2 = msk * t1^-1 (mod n) */
if (!BN_mod_inverse(t, t, n, ctx)) {
SM9err(SM9_F_SM9_EXTRACT_PRIVATE_KEY, ERR_R_BN_LIB);
goto end;
}
if (!BN_mod_mul(t, msk->masterSecret, t, n, ctx)) {
SM9err(SM9_F_SM9_EXTRACT_PRIVATE_KEY, ERR_R_BN_LIB);
goto end;
}
/* generate ds or de */
/* generate (Ppubs, ds) or (Ppube, de) */
if (scheme == NID_sm9sign) {
EC_GROUP *group = NULL;
EC_POINT *ds = NULL;
/* ds = t2 * P1 */
if (!(group = EC_GROUP_new_by_curve_name(NID_sm9bn256v1))
|| !(ds = EC_POINT_new(group))
|| !EC_POINT_mul(group, ds, t, NULL, NULL, ctx)
|| !(len = EC_POINT_point2oct(group, ds, point_form, buf, len, ctx))) {
EC_GROUP_free(group);
EC_POINT_free(ds);
/* publicPoint = h1 * P2 + Ppubs */
point_t Ppubs;
point_t point;
if (!point_init(&point, ctx)
|| !point_init(&Ppubs, ctx)
|| ASN1_STRING_length(master->pointPpub) != sizeof(buf)
|| !point_from_octets(&Ppubs, ASN1_STRING_get0_data(master->pointPpub), p, ctx)
|| !point_mul_generator(&point, t, p, ctx)
|| !point_add(&point, &point, &Ppubs, p, ctx)
|| !point_to_octets(&point, buf, ctx)
|| !ASN1_OCTET_STRING_set(sk->publicPoint, buf, sizeof(buf))) {
SM9err(SM9_F_SM9_MASTER_KEY_EXTRACT_KEY, ERR_R_SM9_LIB);
point_cleanup(&Ppubs);
point_cleanup(&point);
goto end;
}
EC_GROUP_free(group);
EC_POINT_free(ds);
point_cleanup(&Ppubs);
point_cleanup(&point);
} else {
point_t de;
/* de = t2 * P2 */
if (!point_init(&de, ctx)
|| !point_mul_generator(&de, t, p, ctx)
|| !point_to_octets(&de, buf, ctx)) {
point_cleanup(&de);
/* publicPoint = h1 * P1 + Ppube */
EC_POINT *Ppube = NULL;
EC_POINT *point = NULL;
if (!(group = EC_GROUP_new_by_curve_name(NID_sm9bn256v1))
|| !(point = EC_POINT_new(group))
|| !(Ppube = EC_POINT_new(group))
|| !EC_POINT_oct2point(group, Ppube,
ASN1_STRING_get0_data(master->pointPpub),
ASN1_STRING_length(master->pointPpub), ctx)
|| !EC_POINT_mul(group, point, t, NULL, NULL, ctx)
|| !EC_POINT_add(group, point, point, Ppube, ctx)
|| !(len = EC_POINT_point2oct(group, point, point_form, buf, len, ctx))
|| !ASN1_OCTET_STRING_set(sk->publicPoint, buf, len)) {
SM9err(SM9_F_SM9_MASTER_KEY_EXTRACT_KEY, ERR_R_SM9_LIB);
EC_POINT_free(Ppube);
EC_POINT_free(point);
goto end;
}
EC_POINT_free(Ppube);
EC_POINT_free(point);
}
if (priv) {
/* t1 = H1(ID||hid) + master (mod n) */
if (!BN_mod_add(t, t, master->masterSecret, n, ctx)) {
SM9err(SM9_F_SM9_MASTER_KEY_EXTRACT_KEY, ERR_R_BN_LIB);
goto end;
}
point_cleanup(&de);
/* if t1 is zero, return failed */
if (BN_is_zero(t)) {
SM9err(SM9_F_SM9_MASTER_KEY_EXTRACT_KEY, SM9_R_ZERO_ID);
goto end;
}
}
/* t2 = master * t1^-1 (mod n) */
if (!BN_mod_inverse(t, t, n, ctx)) {
SM9err(SM9_F_SM9_MASTER_KEY_EXTRACT_KEY, ERR_R_BN_LIB);
goto end;
}
if (!BN_mod_mul(t, master->masterSecret, t, n, ctx)) {
SM9err(SM9_F_SM9_MASTER_KEY_EXTRACT_KEY, ERR_R_BN_LIB);
goto end;
}
ASN1_OBJECT_free(sk->pairing);
ASN1_OBJECT_free(sk->scheme);
ASN1_OBJECT_free(sk->hash1);
sk->pairing = NULL;
sk->scheme = NULL;
sk->hash1 = NULL;
if (!(sk->pairing = msk->pairing)
|| !(sk->scheme = msk->scheme)
|| !(sk->hash1 = msk->hash1)
|| !ASN1_STRING_copy(sk->pointPpub, msk->pointPpub)
|| !ASN1_STRING_set(sk->identity, id, idlen)
/* FIXME: create publicPoint */
|| !ASN1_STRING_set(sk->privatePoint, buf, len)) {
SM9err(SM9_F_SM9_EXTRACT_PRIVATE_KEY, ERR_R_ASN1_LIB);
goto end;
if (scheme == NID_sm9sign) {
/* ds = t2 * P1 */
EC_POINT *ds = NULL;
if (!(ds = EC_POINT_new(group))
|| !EC_POINT_mul(group, ds, t, NULL, NULL, ctx)
|| !(len = EC_POINT_point2oct(group, ds, point_form, buf, len, ctx))
|| !ASN1_OCTET_STRING_set(sk->privatePoint, buf, len)) {
SM9err(SM9_F_SM9_MASTER_KEY_EXTRACT_KEY, ERR_R_SM9_LIB);
EC_POINT_free(ds);
goto end;
}
EC_POINT_free(ds);
} else {
/* de = t2 * P2 */
point_t de;
if (!point_init(&de, ctx)
|| !point_mul_generator(&de, t, p, ctx)
|| !point_to_octets(&de, buf, ctx)
|| !ASN1_OCTET_STRING_set(sk->privatePoint, buf, sizeof(buf))) {
SM9err(SM9_F_SM9_MASTER_KEY_EXTRACT_KEY, ERR_R_SM9_LIB);
point_cleanup(&de);
goto end;
}
point_cleanup(&de);
}
}
ret = sk;
sk = NULL;
end:
EC_GROUP_free(group);
if (ctx) {
BN_CTX_end(ctx);
}
@@ -295,133 +314,16 @@ end:
return ret;
}
SM9PublicKey *SM9_extract_public_key(SM9PublicParameters *mpk,
SM9PublicKey *SM9_extract_public_key(SM9PublicParameters *master,
const char *id, size_t idlen)
{
SM9PublicKey *ret = NULL;
SM9PublicKey *pk = NULL;
BN_CTX *ctx = NULL;
BIGNUM *h1 = NULL;
int scheme;
unsigned char hid;
const EVP_MD *md;
const BIGNUM *p = SM9_get0_prime();
const BIGNUM *n = SM9_get0_order();
int point_form = POINT_CONVERSION_UNCOMPRESSED;
unsigned char buf[129];
size_t len = sizeof(buf);
return SM9_MASTER_KEY_extract_key(master, id, idlen, 0);
}
if (!(pk = SM9PublicKey_new())
|| !(ctx = BN_CTX_new())) {
goto end;
}
/* check pairing */
if (OBJ_obj2nid(mpk->pairing) != NID_sm9bn256v1) {
goto end;
}
/* check scheme and set hash1 hid */
scheme = OBJ_obj2nid(mpk->scheme);
switch (scheme) {
case NID_sm9sign:
hid = SM9_HID_SIGN;
break;
case NID_sm9encrypt:
hid = SM9_HID_ENC;
break;
case NID_sm9keyagreement:
hid = SM9_HID_EXCH;
break;
default:
goto end;
}
/* check hash1 and set hash1 md */
switch (OBJ_obj2nid(mpk->hash1)) {
case NID_sm9hash1_with_sm3:
md = EVP_sm3();
break;
case NID_sm9hash1_with_sha256:
md = EVP_sha256();
break;
default:
goto end;
}
/* h1 = H1(ID || hid) in [1, n-1] */
if (!SM9_hash1(md, &h1, id, idlen, hid, n, ctx)) {
goto end;
}
if (scheme == NID_sm9sign) {
/* publicPoint = h1 * P2 + Ppubs */
point_t point;
point_t Ppubs;
if (!point_init(&point, ctx)
|| !point_init(&Ppubs, ctx)
|| ASN1_STRING_length(mpk->pointPpub) != sizeof(buf)
|| !point_from_octets(&Ppubs, ASN1_STRING_get0_data(mpk->pointPpub), p, ctx)
|| !point_mul_generator(&point, h1, p, ctx)
|| !point_add(&point, &point, &Ppubs, p, ctx)
|| !point_to_octets(&point, buf, ctx)) {
point_cleanup(&point);
point_cleanup(&Ppubs);
goto end;
}
point_cleanup(&point);
point_cleanup(&Ppubs);
} else if (OBJ_obj2nid(mpk->scheme) == NID_sm9encrypt) {
/* publicPoint = h1 * P1 + Ppube */
EC_GROUP *group = NULL;
EC_POINT *point = NULL;
EC_POINT *Ppube = NULL;
if (!(group = EC_GROUP_new_by_curve_name(NID_sm9bn256v1))
|| !(point = EC_POINT_new(group))
|| !(Ppube = EC_POINT_new(group))
|| !EC_POINT_oct2point(group, Ppube,
ASN1_STRING_get0_data(mpk->pointPpub),
ASN1_STRING_length(mpk->pointPpub), ctx)
|| !EC_POINT_mul(group, point, h1, NULL, NULL, ctx)
|| !EC_POINT_add(group, point, point, Ppube, ctx)
|| !(len = EC_POINT_point2oct(group, point, point_form, buf, len, ctx))) {
EC_GROUP_free(group);
EC_POINT_free(point);
EC_POINT_free(Ppube);
goto end;
}
EC_GROUP_free(group);
EC_POINT_free(point);
EC_POINT_free(Ppube);
}
/* init object */
ASN1_OBJECT_free(pk->pairing);
ASN1_OBJECT_free(pk->scheme);
ASN1_OBJECT_free(pk->hash1);
pk->pairing = NULL;
pk->scheme = NULL;
pk->hash1 = NULL;
if (!(pk->pairing = OBJ_dup(mpk->pairing))
|| !(pk->scheme = OBJ_dup(mpk->scheme))
|| !(pk->hash1 = OBJ_dup(mpk->hash1))
|| !ASN1_STRING_copy(pk->pointPpub, mpk->pointPpub)
|| !ASN1_STRING_set(pk->publicPoint, buf, len)
|| !ASN1_STRING_set(pk->identity, id, idlen)) {
goto end;
}
ret = pk;
pk = NULL;
end:
SM9PublicKey_free(pk);
return ret;
SM9PrivateKey *SM9_extract_private_key(SM9MasterSecret *master,
const char *id, size_t idlen)
{
return SM9_MASTER_KEY_extract_key(master, id, idlen, 1);
}
SM9PublicKey *SM9PrivateKey_get_public_key(SM9PrivateKey *sk)

View File

@@ -52,6 +52,7 @@
#include <openssl/err.h>
#include <openssl/sm9.h>
#include "e_os.h"
/* private key extract algorithms */
#define SM9_HID_SIGN 0x01
@@ -86,38 +87,38 @@ extern "C" {
#endif
struct SM9MasterSecret_st {
struct SM9_MASTER_KEY_st {
/* public */
ASN1_OBJECT *pairing;
ASN1_OBJECT *scheme;
ASN1_OBJECT *hash1;
ASN1_OCTET_STRING *pointPpub;
/* private */
BIGNUM *masterSecret;
int references;
int flags;
CRYPTO_EX_DATA ex_data;
CRYPTO_RWLOCK *lock;
};
struct SM9PublicParameters_st {
ASN1_OBJECT *pairing;
ASN1_OBJECT *scheme;
ASN1_OBJECT *hash1;
ASN1_OCTET_STRING *pointPpub;
};
struct SM9PrivateKey_st {
struct SM9_KEY_st {
/* public */
ASN1_OBJECT *pairing;
ASN1_OBJECT *scheme;
ASN1_OBJECT *hash1;
ASN1_OCTET_STRING *pointPpub;
ASN1_OCTET_STRING *identity;
ASN1_OCTET_STRING *publicPoint;
/* private */
ASN1_OCTET_STRING *privatePoint;
};
struct SM9PublicKey_st {
ASN1_OBJECT *pairing;
ASN1_OBJECT *scheme;
ASN1_OBJECT *hash1;
ASN1_OCTET_STRING *pointPpub;
ASN1_OCTET_STRING *identity;
ASN1_OCTET_STRING *publicPoint;
int references;
int flags;
CRYPTO_EX_DATA ex_data;
CRYPTO_RWLOCK *lock;
};
struct SM9Ciphertext_st {

View File

@@ -50,9 +50,60 @@
#include <string.h>
#include <openssl/err.h>
#include <openssl/sm9.h>
#include <openssl/crypto.h>
#include <openssl/bn_hash.h>
#include "sm9_lcl.h"
SM9_MASTER_KEY *SM9_MASTER_KEY_new(void)
{
SM9_MASTER_KEY *ret = NULL;
if (!(ret = OPENSSL_zalloc(sizeof(*ret)))) {
SM9err(SM9_F_SM9_MASTER_KEY_NEW, ERR_R_MALLOC_FAILURE);
return NULL;
}
return ret;
}
void SM9_MASTER_KEY_free(SM9_MASTER_KEY *key)
{
if (key) {
ASN1_OBJECT_free(key->pairing);
ASN1_OBJECT_free(key->scheme);
ASN1_OBJECT_free(key->hash1);
ASN1_OCTET_STRING_free(key->pointPpub);
BN_clear_free(key->masterSecret);
}
OPENSSL_clear_free(key, sizeof(*key));
}
SM9_KEY *SM9_KEY_new(void)
{
SM9_KEY *ret = NULL;
if (!(ret = OPENSSL_zalloc(sizeof(*ret)))) {
SM9err(SM9_F_SM9_KEY_NEW, ERR_R_MALLOC_FAILURE);
return NULL;
}
return ret;
}
void SM9_KEY_free(SM9_KEY *key)
{
if (key) {
ASN1_OBJECT_free(key->pairing);
ASN1_OBJECT_free(key->scheme);
ASN1_OBJECT_free(key->hash1);
ASN1_OCTET_STRING_free(key->pointPpub);
ASN1_OCTET_STRING_free(key->identity);
ASN1_OCTET_STRING_free(key->publicPoint);
}
OPENSSL_clear_free(key, sizeof(*key));
}
int SM9PrivateKey_get_gmtls_public_key(SM9PublicParameters *mpk,
SM9PrivateKey *sk, unsigned char pub_key[1024])
{
@@ -99,32 +150,26 @@ int SM9_DigestInit(EVP_MD_CTX *ctx, unsigned char prefix,
return 1;
}
#if 0
int SM9_DigestFinal(EVP_MD_CTX *ctx1, BIGNUM *h, const BIGNUM *n_1)
int SM9_MASTER_KEY_up_ref(SM9_MASTER_KEY *msk)
{
int ret = 0;
EVP_MD_CTX *ctx2 = NULL;
const unsigned char ct1[4] = {0x00, 0x00, 0x00, 0x01};
const unsigned char ct2[4] = {0x00, 0x00, 0x00, 0x02};
unsigned char Ha[EVP_MAX_MD_SIZE * 2];
unsigned int len = 0;
int i;
if (!(ctx2 = EVP_MD_CTX_new())
|| !EVP_MD_CTX_copy(ctx2, ctx1)
|| !EVP_DigestUpdate(ctx1, ct1, sizeof(ct))
|| !EVP_DigestUpdate(ctx2, ct2, sizeof(ct2))
|| !EVP_DigestFinal_ex(ctx1, Ha, &len)
|| !EVP_DigestFinal_ex(ctx2, Ha + len, &len)
|| !BN_bin2bn(Ha, 40, h)
|| !BN_mod(h, h, n_1, bn_ctx)
|| !BN_add_word(h, 1)) {
ERR_print_errors_fp(stderr);
goto end;
}
if (CRYPTO_atomic_add(&msk->references, 1, &i, msk->lock) <= 0)
return 0;
ret = 1;
end:
EVP_MD_CTX_free(ctx2);
return ret;
REF_PRINT_COUNT("SM9_MASTER_KEY", msk);
REF_ASSERT_ISNT(i < 2);
return ((i > 1) ? 1 : 0);
}
int SM9_KEY_up_ref(SM9_KEY *sk)
{
int i;
if (CRYPTO_atomic_add(&sk->references, 1, &i, sk->lock) <= 0)
return 0;
REF_PRINT_COUNT("SM9_KEY", sk);
REF_ASSERT_ISNT(i < 2);
return ((i > 1) ? 1 : 0);
}
#endif

151
crypto/sm9/sm9_prn.c Normal file
View File

@@ -0,0 +1,151 @@
/* ====================================================================
* Copyright (c) 2016 The GmSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the GmSSL Project.
* (http://gmssl.org/)"
*
* 4. The name "GmSSL Project" must not be used to endorse or promote
* products derived from this software without prior written
* permission. For written permission, please contact
* guanzhi1980@gmail.com.
*
* 5. Products derived from this software may not be called "GmSSL"
* nor may "GmSSL" appear in their names without prior written
* permission of the GmSSL Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the GmSSL Project
* (http://gmssl.org/)"
*
* THIS SOFTWARE IS PROVIDED BY THE GmSSL PROJECT ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GmSSL PROJECT OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*/
#include <string.h>
#include <openssl/err.h>
#include <openssl/sm9.h>
#include <openssl/bn_hash.h>
#include "sm9_lcl.h"
int SM9PrivateKey_get_gmtls_public_key(SM9PublicParameters *mpk,
SM9PrivateKey *sk, unsigned char pub_key[1024])
{
return 0;
}
int SM9PublicKey_get_gmtls_encoded(SM9PublicParameters *mpk,
SM9PublicKey *pk, unsigned char encoded[1024])
{
return 0;
}
int SM9_hash2(const EVP_MD *md, BIGNUM **r,
const unsigned char *data, size_t datalen,
const unsigned char *elem, size_t elemlen,
const BIGNUM *range, BN_CTX *ctx)
{
unsigned char *buf;
if (!(buf = OPENSSL_malloc(datalen + elemlen))) {
return 0;
}
memcpy(buf, data, datalen);
memcpy(buf + datalen, elem, elemlen);
if (!BN_hash_to_range(md, r, buf, datalen + elemlen, range, ctx)) {
OPENSSL_free(buf);
return 0;
}
OPENSSL_free(buf);
return 1;
}
int SM9_DigestInit(EVP_MD_CTX *ctx, unsigned char prefix,
const EVP_MD *md, ENGINE *impl)
{
if (!EVP_DigestInit_ex(ctx, md, impl)
|| !EVP_DigestUpdate(ctx, &prefix, 1)) {
ERR_print_errors_fp(stderr);
return 0;
}
return 1;
}
//FIXME: implement this !!!
int SM9MasterSecret_up_ref(SM9MasterSecret *msk)
{
return 1;
}
int SM9PublicParameters_up_ref(SM9PublicParameters *mpk)
{
return 1;
}
int SM9PrivateKey_up_ref(SM9PrivateKey *sk)
{
return 1;
}
int SM9PublicKey_up_ref(SM9PublicKey *pk)
{
return 1;
}
#if 0
int SM9_DigestFinal(EVP_MD_CTX *ctx1, BIGNUM *h, const BIGNUM *n_1)
{
int ret = 0;
EVP_MD_CTX *ctx2 = NULL;
const unsigned char ct1[4] = {0x00, 0x00, 0x00, 0x01};
const unsigned char ct2[4] = {0x00, 0x00, 0x00, 0x02};
unsigned char Ha[EVP_MAX_MD_SIZE * 2];
unsigned int len = 0;
if (!(ctx2 = EVP_MD_CTX_new())
|| !EVP_MD_CTX_copy(ctx2, ctx1)
|| !EVP_DigestUpdate(ctx1, ct1, sizeof(ct))
|| !EVP_DigestUpdate(ctx2, ct2, sizeof(ct2))
|| !EVP_DigestFinal_ex(ctx1, Ha, &len)
|| !EVP_DigestFinal_ex(ctx2, Ha + len, &len)
|| !BN_bin2bn(Ha, 40, h)
|| !BN_mod(h, h, n_1, bn_ctx)
|| !BN_add_word(h, 1)) {
ERR_print_errors_fp(stderr);
goto end;
}
ret = 1;
end:
EVP_MD_CTX_free(ctx2);
return ret;
}
#endif

View File

@@ -73,7 +73,6 @@ SM9MasterSecret *SM9_generate_master_secret(int pairing, int scheme, int hash1)
/* set pairing type */
switch (pairing) {
case NID_sm9bn256v1:
ASN1_OBJECT_free(msk->pairing);
if (!(msk->pairing = OBJ_nid2obj(pairing))) {
SM9err(SM9_F_SM9_GENERATE_MASTER_SECRET, ERR_R_OBJ_LIB);
goto end;
@@ -89,7 +88,6 @@ SM9MasterSecret *SM9_generate_master_secret(int pairing, int scheme, int hash1)
case NID_sm9sign:
case NID_sm9encrypt:
case NID_sm9keyagreement:
ASN1_OBJECT_free(msk->scheme);
if (!(msk->scheme = OBJ_nid2obj(scheme))) {
SM9err(SM9_F_SM9_GENERATE_MASTER_SECRET, ERR_R_OBJ_LIB);
goto end;
@@ -104,7 +102,6 @@ SM9MasterSecret *SM9_generate_master_secret(int pairing, int scheme, int hash1)
switch (hash1) {
case NID_sm9hash1_with_sm3:
case NID_sm9hash1_with_sha256:
ASN1_OBJECT_free(msk->hash1);
if (!(msk->hash1 = OBJ_nid2obj(hash1))) {
SM9err(SM9_F_SM9_GENERATE_MASTER_SECRET, ERR_R_OBJ_LIB);
goto end;
@@ -117,6 +114,11 @@ SM9MasterSecret *SM9_generate_master_secret(int pairing, int scheme, int hash1)
/* generate master secret k = rand(1, n - 1) */
do {
if (!(msk->masterSecret = BN_new())) {
SM9err(SM9_F_SM9_GENERATE_MASTER_SECRET, ERR_R_MALLOC_FAILURE);
goto end;
}
if (!BN_rand_range(msk->masterSecret, n)) {
SM9err(SM9_F_SM9_GENERATE_MASTER_SECRET, ERR_R_BN_LIB);
goto end;
@@ -165,6 +167,10 @@ SM9MasterSecret *SM9_generate_master_secret(int pairing, int scheme, int hash1)
goto end;
}
if (!(msk->pointPpub = ASN1_OCTET_STRING_new())) {
SM9err(SM9_F_SM9_GENERATE_MASTER_SECRET, ERR_R_MALLOC_FAILURE);
goto end;
}
if (!ASN1_OCTET_STRING_set(msk->pointPpub, buf, (int)len)) {
ERR_print_errors_fp(stderr);
goto end;
@@ -193,17 +199,10 @@ SM9PublicParameters *SM9_extract_public_parameters(SM9MasterSecret *msk)
return NULL;
}
ASN1_OBJECT_free(mpk->pairing);
ASN1_OBJECT_free(mpk->scheme);
ASN1_OBJECT_free(mpk->hash1);
mpk->pairing = NULL;
mpk->scheme = NULL;
mpk->hash1 = NULL;
if (!(mpk->pairing = OBJ_dup(msk->pairing))
|| !(mpk->scheme = OBJ_dup(msk->scheme))
|| !(mpk->hash1 = OBJ_dup(msk->hash1))
|| !ASN1_STRING_copy(mpk->pointPpub, msk->pointPpub)) {
|| !(mpk->pointPpub = ASN1_OCTET_STRING_dup(msk->pointPpub))) {
SM9err(SM9_F_SM9_EXTRACT_PUBLIC_PARAMETERS, ERR_R_MALLOC_FAILURE);
goto end;
}
@@ -211,7 +210,7 @@ SM9PublicParameters *SM9_extract_public_parameters(SM9MasterSecret *msk)
ret = mpk;
mpk = NULL;
end:
end:
SM9PublicParameters_free(mpk);
return ret;
}