mirror of
https://github.com/guanzhi/GmSSL.git
synced 2026-05-07 00:46:17 +08:00
Update SM9
This commit is contained in:
@@ -335,6 +335,47 @@ typedef struct {
|
|||||||
} SM9_TWIST_POINT;
|
} SM9_TWIST_POINT;
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
SM9私钥如何存储:
|
||||||
|
|
||||||
|
可以用PrivateKeyInfo, EncryptedPrivateKeyInfo 来存储SM9的主密钥
|
||||||
|
这需要SM9签名、加密等方案的OID,并且需要区分主密钥和用户私钥
|
||||||
|
否则无法通过AlgorithmIdentifier来区分
|
||||||
|
|
||||||
|
SM9的主密钥和EC密钥类型很像,都是一个大整数和一个曲线点。
|
||||||
|
但是SM9的主密钥存在KeyUsage这个特性,签名和加密的格式并不一样。
|
||||||
|
是否将其整合在一个ASN.1对象中呢?
|
||||||
|
|
||||||
|
主密钥、用户密钥、签名、加密,这用一个OID来区分还是2个OID来区分?
|
||||||
|
|
||||||
|
|
||||||
|
PrivateKeyInfo ::= SEQUENCE {
|
||||||
|
version Version { v1(0) },
|
||||||
|
privateKeyAlgorithm AlgorithmIdentifier,
|
||||||
|
privateKey OCTET STRING, -- DER-encoding of ECPrivateKey
|
||||||
|
attributes [0] IMPLICIT SET OF Attribute OPTIONAL }
|
||||||
|
|
||||||
|
这里privateKeyAlgorithm只有一个值,因此必须为上述提供4个不同OID
|
||||||
|
|
||||||
|
主公钥其实是无所谓的,
|
||||||
|
|
||||||
|
SM9 OIDs from GM/T 0006-2012
|
||||||
|
|
||||||
|
1.2.156.10197.1.302 sm9
|
||||||
|
1.2.156.10197.1.302.1 sm9sign
|
||||||
|
1.2.156.10197.1.302.2 sm9keyagreement
|
||||||
|
1.2.156.10197.1.302.3 sm9encrypt
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define PEM_SM9_SIGN_MASTER_KEY "ENCRYPTED SM9 SIGN MASTER KEY"
|
||||||
|
#define PEM_SM9_SIGN_MASTER_PUBLIC_KEY "SM9 SIGN MASTER PUBLIC KEY"
|
||||||
|
#define PEM_SM9_SIGN_PRIVATE_KEY "ENCRYPTED SM9 SIGN PRIVATE KEY"
|
||||||
|
#define PEM_SM9_ENC_MASTER_KEY "ENCRYPTED SM9 ENC MASTER KEY"
|
||||||
|
#define PEM_SM9_ENC_MASTER_PUBLIC_KEY "SM9 ENC MASTER PUBLIC KEY"
|
||||||
|
#define PEM_SM9_ENC_PRIVATE_KEY "ENCRYPTED SM9 ENC PRIVATE KEY"
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
SM9SignMasterKey ::= SEQUENCE {
|
SM9SignMasterKey ::= SEQUENCE {
|
||||||
ks INTEGER,
|
ks INTEGER,
|
||||||
@@ -346,25 +387,45 @@ typedef struct {
|
|||||||
sm9_fn_t ks;
|
sm9_fn_t ks;
|
||||||
} SM9_SIGN_MASTER_KEY;
|
} SM9_SIGN_MASTER_KEY;
|
||||||
|
|
||||||
|
// algorthm,parameters = sm9,sm9sign
|
||||||
int sm9_sign_master_key_to_der(const SM9_SIGN_MASTER_KEY *msk, uint8_t **out, size_t *outlen);
|
int sm9_sign_master_key_to_der(const SM9_SIGN_MASTER_KEY *msk, uint8_t **out, size_t *outlen);
|
||||||
int sm9_sign_master_key_from_der(SM9_SIGN_MASTER_KEY *msk, const uint8_t **in, size_t *inlen);
|
int sm9_sign_master_key_from_der(SM9_SIGN_MASTER_KEY *msk, const uint8_t **in, size_t *inlen);
|
||||||
|
int sm9_sign_master_key_info_encrypt_to_der(const SM9_SIGN_MASTER_KEY *msk, const char *pass, uint8_t **out, size_t *outlen);
|
||||||
|
int sm9_sign_master_key_info_decrypt_from_der(SM9_SIGN_MASTER_KEY *msk, const char *pass, const uint8_t **in, size_t *inlen);
|
||||||
|
int sm9_sign_master_key_info_encrypt_to_pem(const SM9_SIGN_MASTER_KEY *msk, const char *pass, FILE *fp);
|
||||||
|
int sm9_sign_master_key_info_decrypt_from_pem(SM9_SIGN_MASTER_KEY *msk, const char *pass, FILE *fp);
|
||||||
|
|
||||||
|
/*
|
||||||
|
SM9SignMasterPublicKey ::= SEQUENCE {
|
||||||
|
Ppubs BIT STRING, -- uncompressed octets of twisted point
|
||||||
|
}
|
||||||
|
*/
|
||||||
int sm9_sign_master_public_key_to_der(const SM9_SIGN_MASTER_KEY *mpk, uint8_t **out, size_t *outlen);
|
int sm9_sign_master_public_key_to_der(const SM9_SIGN_MASTER_KEY *mpk, uint8_t **out, size_t *outlen);
|
||||||
int sm9_sign_master_public_key_from_der(SM9_SIGN_MASTER_KEY *mpk, const uint8_t **in, size_t *inlen);
|
int sm9_sign_master_public_key_from_der(SM9_SIGN_MASTER_KEY *mpk, const uint8_t **in, size_t *inlen);
|
||||||
|
int sm9_sign_master_public_key_to_pem(const SM9_SIGN_MASTER_KEY *mpk, FILE *fp);
|
||||||
|
int sm9_sign_master_public_key_from_pem(SM9_SIGN_MASTER_KEY *mpk, FILE *fp);
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
SM9SignPrivateKey ::= SEQUENCE {
|
SM9SignPrivateKey ::= SEQUENCE {
|
||||||
ds BIT STRING, -- uncompressed octets of ECPoint
|
ds BIT STRING, -- uncompressed octets of ECPoint
|
||||||
Ppubs BIT STRING -- uncompressed octets of twisted point
|
Ppubs BIT STRING -- uncompressed octets of twisted point
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SM9的用户私钥和椭圆曲线的就没有任何关系了。
|
||||||
*/
|
*/
|
||||||
typedef struct {
|
typedef struct {
|
||||||
sm9_twist_point_t Ppubs;
|
sm9_twist_point_t Ppubs;
|
||||||
sm9_point_t ds;
|
sm9_point_t ds;
|
||||||
} SM9_SIGN_KEY;
|
} SM9_SIGN_KEY;
|
||||||
|
|
||||||
|
// algorithm,parameters = sm9sign,<null>
|
||||||
int sm9_sign_key_to_der(const SM9_SIGN_KEY *key, uint8_t **out, size_t *outlen);
|
int sm9_sign_key_to_der(const SM9_SIGN_KEY *key, uint8_t **out, size_t *outlen);
|
||||||
int sm9_sign_key_from_der(SM9_SIGN_KEY *key, const uint8_t **in, size_t *inlen);
|
int sm9_sign_key_from_der(SM9_SIGN_KEY *key, const uint8_t **in, size_t *inlen);
|
||||||
|
int sm9_sign_key_info_encrypt_to_der(const SM9_SIGN_KEY *key, const char *pass, uint8_t **out, size_t *outlen);
|
||||||
|
int sm9_sign_key_info_decrypt_from_der(SM9_SIGN_KEY *key, const char *pass, const uint8_t **in, size_t *inlen);
|
||||||
|
int sm9_sign_key_info_encrypt_to_pem(const SM9_SIGN_KEY *key, const char *pass, FILE *fp);
|
||||||
|
int sm9_sign_key_info_decrypt_from_pem(SM9_SIGN_KEY *key, const char *pass, FILE *fp);
|
||||||
|
|
||||||
int sm9_sign_master_key_generate(SM9_SIGN_MASTER_KEY *master);
|
int sm9_sign_master_key_generate(SM9_SIGN_MASTER_KEY *master);
|
||||||
int sm9_sign_master_key_extract_key(SM9_SIGN_MASTER_KEY *master, const char *id, size_t idlen, SM9_SIGN_KEY *key);
|
int sm9_sign_master_key_extract_key(SM9_SIGN_MASTER_KEY *master, const char *id, size_t idlen, SM9_SIGN_KEY *key);
|
||||||
@@ -406,10 +467,18 @@ typedef struct {
|
|||||||
sm9_fn_t ke;
|
sm9_fn_t ke;
|
||||||
} SM9_ENC_MASTER_KEY;
|
} SM9_ENC_MASTER_KEY;
|
||||||
|
|
||||||
|
// algorithm,parameters = sm9,sm9encrypt
|
||||||
int sm9_enc_master_key_to_der(const SM9_ENC_MASTER_KEY *msk, uint8_t **out, size_t *outlen);
|
int sm9_enc_master_key_to_der(const SM9_ENC_MASTER_KEY *msk, uint8_t **out, size_t *outlen);
|
||||||
int sm9_enc_master_key_from_der(SM9_ENC_MASTER_KEY *msk, const uint8_t **in, size_t *inlen);
|
int sm9_enc_master_key_from_der(SM9_ENC_MASTER_KEY *msk, const uint8_t **in, size_t *inlen);
|
||||||
|
int sm9_enc_master_key_info_encrypt_to_der(const SM9_ENC_MASTER_KEY *msk, const char *pass, uint8_t **out, size_t *outlen);
|
||||||
|
int sm9_enc_master_key_info_decrypt_from_der(SM9_ENC_MASTER_KEY *msk, const char *pass, const uint8_t **in, size_t *inlen);
|
||||||
|
int sm9_enc_master_key_info_encrypt_to_pem(const SM9_ENC_MASTER_KEY *msk, const char *pass, FILE *fp);
|
||||||
|
int sm9_enc_master_key_info_decrypt_from_pem(SM9_ENC_MASTER_KEY *msk, const char *pass, FILE *fp);
|
||||||
|
|
||||||
int sm9_enc_master_public_key_to_der(const SM9_ENC_MASTER_KEY *mpk, uint8_t **out, size_t *outlen);
|
int sm9_enc_master_public_key_to_der(const SM9_ENC_MASTER_KEY *mpk, uint8_t **out, size_t *outlen);
|
||||||
int sm9_enc_master_public_key_from_der(SM9_ENC_MASTER_KEY *mpk, const uint8_t **in, size_t *inlen);
|
int sm9_enc_master_public_key_from_der(SM9_ENC_MASTER_KEY *mpk, const uint8_t **in, size_t *inlen);
|
||||||
|
int sm9_enc_master_public_key_to_pem(const SM9_ENC_MASTER_KEY *mpk, FILE *fp);
|
||||||
|
int sm9_enc_master_public_key_from_pem(SM9_ENC_MASTER_KEY *mpk, FILE *fp);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
SM9EncPrivateKey ::= SEQUENCE {
|
SM9EncPrivateKey ::= SEQUENCE {
|
||||||
@@ -422,8 +491,13 @@ typedef struct {
|
|||||||
sm9_twist_point_t de;
|
sm9_twist_point_t de;
|
||||||
} SM9_ENC_KEY;
|
} SM9_ENC_KEY;
|
||||||
|
|
||||||
|
// algorithm,parameters = sm9encrypt,<null>
|
||||||
int sm9_enc_key_to_der(const SM9_ENC_KEY *key, uint8_t **out, size_t *outlen);
|
int sm9_enc_key_to_der(const SM9_ENC_KEY *key, uint8_t **out, size_t *outlen);
|
||||||
int sm9_enc_key_from_der(SM9_ENC_KEY *key, const uint8_t **in, size_t *inlen);
|
int sm9_enc_key_from_der(SM9_ENC_KEY *key, const uint8_t **in, size_t *inlen);
|
||||||
|
int sm9_enc_key_info_encrypt_to_der(const SM9_ENC_KEY *key, const char *pass, uint8_t **out, size_t *outlen);
|
||||||
|
int sm9_enc_key_info_decrypt_from_der(SM9_ENC_KEY *key, const char *pass, const uint8_t **in, size_t *inlen);
|
||||||
|
int sm9_enc_key_info_encrypt_to_pem(const SM9_ENC_KEY *key, const char *pass, FILE *fp);
|
||||||
|
int sm9_enc_key_info_decrypt_from_pem(SM9_ENC_KEY *key, const char *pass, FILE *fp);
|
||||||
|
|
||||||
int sm9_enc_master_key_generate(SM9_ENC_MASTER_KEY *master);
|
int sm9_enc_master_key_generate(SM9_ENC_MASTER_KEY *master);
|
||||||
int sm9_enc_master_key_extract_key(SM9_ENC_MASTER_KEY *master, const char *id, size_t idlen, SM9_ENC_KEY *key);
|
int sm9_enc_master_key_extract_key(SM9_ENC_MASTER_KEY *master, const char *id, size_t idlen, SM9_ENC_KEY *key);
|
||||||
@@ -444,6 +518,7 @@ int sm9_ciphertext_from_der(sm9_point_t *C1, const uint8_t **c2, size_t *c2len,
|
|||||||
|
|
||||||
int sm9_kem_encrypt(const SM9_ENC_MASTER_KEY *mpk, const char *id, size_t idlen, size_t klen, uint8_t *kbuf, sm9_point_t *C);
|
int sm9_kem_encrypt(const SM9_ENC_MASTER_KEY *mpk, const char *id, size_t idlen, size_t klen, uint8_t *kbuf, sm9_point_t *C);
|
||||||
int sm9_kem_decrypt(const SM9_ENC_KEY *key, const char *id, size_t idlen, const sm9_point_t *C, size_t klen, uint8_t *kbuf);
|
int sm9_kem_decrypt(const SM9_ENC_KEY *key, const char *id, size_t idlen, const sm9_point_t *C, size_t klen, uint8_t *kbuf);
|
||||||
|
|
||||||
int sm9_do_encrypt(const SM9_ENC_MASTER_KEY *mpk, const char *id, size_t idlen,
|
int sm9_do_encrypt(const SM9_ENC_MASTER_KEY *mpk, const char *id, size_t idlen,
|
||||||
const uint8_t *in, size_t inlen, sm9_point_t *C1, uint8_t *c2, uint8_t c3[SM3_HMAC_SIZE]);
|
const uint8_t *in, size_t inlen, sm9_point_t *C1, uint8_t *c2, uint8_t c3[SM3_HMAC_SIZE]);
|
||||||
int sm9_do_decrypt(const SM9_ENC_KEY *key, const char *id, size_t idlen,
|
int sm9_do_decrypt(const SM9_ENC_KEY *key, const char *id, size_t idlen,
|
||||||
@@ -453,6 +528,21 @@ int sm9_encrypt(const SM9_ENC_MASTER_KEY *mpk, const char *id, size_t idlen,
|
|||||||
int sm9_decrypt(const SM9_ENC_KEY *key, const char *id, size_t idlen,
|
int sm9_decrypt(const SM9_ENC_KEY *key, const char *id, size_t idlen,
|
||||||
const uint8_t *in, size_t inlen, uint8_t *out, size_t *outlen);
|
const uint8_t *in, size_t inlen, uint8_t *out, size_t *outlen);
|
||||||
|
|
||||||
|
|
||||||
|
int sm9_fn_print(FILE *fp, int fmt, int ind, const char *label, const sm9_fn_t a);
|
||||||
|
int sm9_point_print(FILE *fp, int fmt, int ind, const char *label, const sm9_point_t *P);
|
||||||
|
int sm9_twist_point_print(FILE *fp, int fmt, int ind, const char *label, const sm9_twist_point_t *P);
|
||||||
|
|
||||||
|
int sm9_sign_master_key_print(FILE *fp, int fmt, int ind, const char *label, const SM9_SIGN_MASTER_KEY *msk);
|
||||||
|
int sm9_sign_master_public_key_print(FILE *fp, int fmt, int ind, const char *label, const SM9_SIGN_MASTER_KEY *mpk);
|
||||||
|
int sm9_sign_key_print(FILE *fp, int fmt, int ind, const char *label, const SM9_SIGN_KEY *key);
|
||||||
|
int sm9_enc_master_key_print(FILE *fp, int fmt, int ind, const char *label, const SM9_ENC_MASTER_KEY *msk);
|
||||||
|
int sm9_enc_master_public_key_print(FILE *fp, int fmt, int ind, const char *label, const SM9_ENC_MASTER_KEY *mpk);
|
||||||
|
int sm9_enc_key_print(FILE *fp, int fmt, int ind, const char *label, const SM9_ENC_KEY *key);
|
||||||
|
int sm9_signature_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *sig, size_t siglen);
|
||||||
|
int sm9_ciphertext_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *a, size_t alen);
|
||||||
|
|
||||||
|
|
||||||
# ifdef __cplusplus
|
# ifdef __cplusplus
|
||||||
}
|
}
|
||||||
# endif
|
# endif
|
||||||
|
|||||||
746
src/sm9_key.c
746
src/sm9_key.c
@@ -50,9 +50,14 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <gmssl/sm3.h>
|
#include <gmssl/sm3.h>
|
||||||
|
#include <gmssl/sm4.h>
|
||||||
#include <gmssl/sm9.h>
|
#include <gmssl/sm9.h>
|
||||||
#include <gmssl/mem.h>
|
#include <gmssl/mem.h>
|
||||||
|
#include <gmssl/oid.h>
|
||||||
|
#include <gmssl/rand.h>
|
||||||
#include <gmssl/asn1.h>
|
#include <gmssl/asn1.h>
|
||||||
|
#include <gmssl/pkcs8.h>
|
||||||
|
#include <gmssl/pbkdf2.h>
|
||||||
#include <gmssl/error.h>
|
#include <gmssl/error.h>
|
||||||
|
|
||||||
|
|
||||||
@@ -444,3 +449,744 @@ int sm9_enc_master_key_extract_key(SM9_ENC_MASTER_KEY *msk, const char *id, size
|
|||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#define OID_SM9 oid_sm_algors,302
|
||||||
|
static uint32_t oid_sm9[] = { OID_SM9 };
|
||||||
|
static uint32_t oid_sm9sign[] = { OID_SM9,1 };
|
||||||
|
static uint32_t oid_sm9keyagreement[] = { OID_SM9,2 };
|
||||||
|
static uint32_t oid_sm9encrypt[] = { OID_SM9,3 };
|
||||||
|
|
||||||
|
static const ASN1_OID_INFO sm9_oids[] = {
|
||||||
|
{ OID_sm9, "sm9", oid_sm9, sizeof(oid_sm9)/sizeof(int) },
|
||||||
|
{ OID_sm9sign, "sm9sign", oid_sm9sign, sizeof(oid_sm9sign)/sizeof(int) },
|
||||||
|
{ OID_sm9keyagreement, "sm9keyagreement", oid_sm9keyagreement, sizeof(oid_sm9keyagreement)/sizeof(int) },
|
||||||
|
{ OID_sm9encrypt, "sm9encrypt", oid_sm9encrypt, sizeof(oid_sm9encrypt)/sizeof(int) },
|
||||||
|
};
|
||||||
|
|
||||||
|
static const int sm9_oids_count = sizeof(sm9_oids)/sizeof(sm9_oids[0]);
|
||||||
|
|
||||||
|
|
||||||
|
const char *sm9_oid_name(int oid)
|
||||||
|
{
|
||||||
|
const ASN1_OID_INFO *info;
|
||||||
|
if (!(info = asn1_oid_info_from_oid(sm9_oids, sm9_oids_count, oid))) {
|
||||||
|
error_print();
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
return info->name;
|
||||||
|
}
|
||||||
|
|
||||||
|
int sm9_oid_from_name(const char *name)
|
||||||
|
{
|
||||||
|
const ASN1_OID_INFO *info;
|
||||||
|
if (!(info = asn1_oid_info_from_name(sm9_oids, sm9_oids_count, name))) {
|
||||||
|
error_print();
|
||||||
|
return OID_undef;
|
||||||
|
}
|
||||||
|
return info->oid;
|
||||||
|
}
|
||||||
|
|
||||||
|
int sm9_oid_to_der(int oid, uint8_t **out, size_t *outlen)
|
||||||
|
{
|
||||||
|
const ASN1_OID_INFO *info;
|
||||||
|
if (!(info = asn1_oid_info_from_oid(sm9_oids, sm9_oids_count, oid))) {
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (asn1_object_identifier_to_der(info->nodes, info->nodes_cnt, out, outlen) != 1) {
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int sm9_oid_from_der(int *oid, const uint8_t **in, size_t *inlen)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
const ASN1_OID_INFO *info;
|
||||||
|
|
||||||
|
if ((ret = asn1_oid_info_from_der(&info, sm9_oids, sm9_oids_count, in, inlen)) != 1) {
|
||||||
|
if (ret < 0) error_print();
|
||||||
|
else *oid = -1;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
*oid = info->oid;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int sm9_algor_to_der(int alg, int params, uint8_t **out, size_t *outlen)
|
||||||
|
{
|
||||||
|
size_t len = 0;
|
||||||
|
if (sm9_oid_to_der(alg, NULL, &len) != 1
|
||||||
|
|| sm9_oid_to_der(params, NULL, &len) < 0
|
||||||
|
|| asn1_sequence_header_to_der(len, out, outlen) != 1
|
||||||
|
|| sm9_oid_to_der(alg, out, outlen) != 1
|
||||||
|
|| sm9_oid_to_der(params, out, outlen) < 0) {
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int sm9_algor_from_der(int *alg, int *params, const uint8_t **in, size_t *inlen)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
const uint8_t *d;
|
||||||
|
size_t dlen;
|
||||||
|
|
||||||
|
if ((ret = asn1_sequence_from_der(&d, &dlen, in, inlen)) != 1) {
|
||||||
|
if (ret < 0) error_print();
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
if (sm9_oid_from_der(alg, &d, &dlen) != 1
|
||||||
|
|| sm9_oid_from_der(params, &d, &dlen) < 0
|
||||||
|
|| asn1_length_is_zero(dlen) != 1) {
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int sm9_private_key_info_to_der(int alg, int params, const uint8_t *prikey, size_t prikey_len,
|
||||||
|
uint8_t **out, size_t *outlen)
|
||||||
|
{
|
||||||
|
size_t len = 0;
|
||||||
|
if (asn1_int_to_der(PKCS8_private_key_info_version, NULL, &len) != 1
|
||||||
|
|| sm9_algor_to_der(alg, params, NULL, &len) != 1
|
||||||
|
|| asn1_octet_string_to_der(prikey, prikey_len, NULL, &len) != 1
|
||||||
|
|| asn1_sequence_header_to_der(len, out, outlen) != 1
|
||||||
|
|| asn1_int_to_der(PKCS8_private_key_info_version, out, outlen) != 1
|
||||||
|
|| sm9_algor_to_der(alg, params, out, outlen) != 1
|
||||||
|
|| asn1_octet_string_to_der(prikey, prikey_len, out, outlen) != 1) {
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int sm9_private_key_info_from_der(int *alg, int *params, const uint8_t **prikey, size_t *prikey_len,
|
||||||
|
const uint8_t **in, size_t *inlen)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
const uint8_t *d;
|
||||||
|
size_t dlen;
|
||||||
|
int ver;
|
||||||
|
|
||||||
|
if ((ret = asn1_sequence_from_der(&d, &dlen, in, inlen)) != 1) {
|
||||||
|
if (ret < 0) error_print();
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
if (asn1_int_from_der(&ver, &d, &dlen) != 1
|
||||||
|
|| sm9_algor_from_der(alg, params, &d, &dlen) != 1
|
||||||
|
|| asn1_octet_string_from_der(prikey, prikey_len, &d, &dlen) != 1
|
||||||
|
|| asn1_length_is_zero(dlen) != 1) {
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (ver != PKCS8_private_key_info_version) {
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int sm9_private_key_info_encrypt_to_der(int alg, int params, const uint8_t *prikey, size_t prikey_len,
|
||||||
|
const char *pass, uint8_t **out, size_t *outlen)
|
||||||
|
{
|
||||||
|
int ret = -1;
|
||||||
|
uint8_t pkey_info[1024];
|
||||||
|
uint8_t *p = pkey_info;
|
||||||
|
size_t pkey_info_len = 0;
|
||||||
|
uint8_t salt[16];
|
||||||
|
int iter = 65536;
|
||||||
|
uint8_t iv[16];
|
||||||
|
uint8_t key[16];
|
||||||
|
SM4_KEY sm4_key;
|
||||||
|
uint8_t enced_pkey_info[2480];
|
||||||
|
size_t enced_pkey_info_len;
|
||||||
|
|
||||||
|
if (sm9_private_key_info_to_der(alg, params, prikey, prikey_len, &p, &pkey_info_len) != 1
|
||||||
|
|| rand_bytes(salt, sizeof(salt)) != 1
|
||||||
|
|| rand_bytes(iv, sizeof(iv)) != 1
|
||||||
|
|| pbkdf2_hmac_sm3_genkey(pass, strlen(pass), salt, sizeof(salt), iter, sizeof(key), key) != 1) {
|
||||||
|
error_print();
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
sm4_set_encrypt_key(&sm4_key, key);
|
||||||
|
if (sm4_cbc_padding_encrypt(&sm4_key, iv, pkey_info, pkey_info_len, enced_pkey_info, &enced_pkey_info_len) != 1
|
||||||
|
|| pkcs8_enced_private_key_info_to_der(salt, sizeof(salt), iter, sizeof(key),
|
||||||
|
OID_hmac_sm3, OID_sm4_cbc, iv, sizeof(iv),
|
||||||
|
enced_pkey_info, enced_pkey_info_len, out, outlen) != 1) {
|
||||||
|
error_print();
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
ret = 1;
|
||||||
|
end:
|
||||||
|
gmssl_secure_clear(pkey_info, sizeof(pkey_info));
|
||||||
|
gmssl_secure_clear(salt, sizeof(salt));
|
||||||
|
gmssl_secure_clear(iv, sizeof(iv));
|
||||||
|
gmssl_secure_clear(key, sizeof(key));
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 这里私钥我们必须要提供一个buffer
|
||||||
|
static int sm9_private_key_info_decrypt_from_der(int *alg, int *params, uint8_t *prikey, size_t *prikey_len,
|
||||||
|
const char *pass, const uint8_t **in, size_t *inlen)
|
||||||
|
{
|
||||||
|
int ret = -1;
|
||||||
|
const uint8_t *salt;
|
||||||
|
size_t saltlen;
|
||||||
|
int iter;
|
||||||
|
int keylen;
|
||||||
|
int prf;
|
||||||
|
int cipher;
|
||||||
|
const uint8_t *iv;
|
||||||
|
size_t ivlen;
|
||||||
|
uint8_t key[16];
|
||||||
|
SM4_KEY sm4_key;
|
||||||
|
const uint8_t *enced_pkey_info;
|
||||||
|
size_t enced_pkey_info_len;
|
||||||
|
uint8_t pkey_info[256]; // 这是一个比较大的缓冲空间
|
||||||
|
const uint8_t *cp = pkey_info;
|
||||||
|
size_t pkey_info_len;
|
||||||
|
const uint8_t *cp_prikey;
|
||||||
|
|
||||||
|
if (pkcs8_enced_private_key_info_from_der(&salt, &saltlen, &iter, &keylen, &prf,
|
||||||
|
&cipher, &iv, &ivlen, &enced_pkey_info, &enced_pkey_info_len, in, inlen) != 1
|
||||||
|
|| asn1_check(keylen == -1 || keylen == 16) != 1
|
||||||
|
|| asn1_check(prf == - 1 || prf == OID_hmac_sm3) != 1
|
||||||
|
|| asn1_check(cipher == OID_sm4_cbc) != 1
|
||||||
|
|| asn1_check(ivlen == 16) != 1
|
||||||
|
|| asn1_length_le(enced_pkey_info_len, sizeof(pkey_info)) != 1) {
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (pbkdf2_genkey(DIGEST_sm3(), pass, strlen(pass), salt, saltlen, iter, sizeof(key), key) != 1) {
|
||||||
|
error_print();
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
sm4_set_decrypt_key(&sm4_key, key);
|
||||||
|
if (sm4_cbc_padding_decrypt(&sm4_key, iv, enced_pkey_info, enced_pkey_info_len,
|
||||||
|
pkey_info, &pkey_info_len) != 1
|
||||||
|
|| sm9_private_key_info_from_der(alg, params, &cp_prikey, prikey_len, // 注意这里的是const uint8_t *,必须拷贝到外面
|
||||||
|
&cp, &pkey_info_len) != 1
|
||||||
|
|| asn1_length_is_zero(pkey_info_len) != 1) {
|
||||||
|
error_print();
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
memcpy(prikey, cp_prikey, *prikey_len);
|
||||||
|
ret = 1;
|
||||||
|
end:
|
||||||
|
gmssl_secure_clear(&sm4_key, sizeof(sm4_key));
|
||||||
|
gmssl_secure_clear(key, sizeof(key));
|
||||||
|
gmssl_secure_clear(pkey_info, sizeof(pkey_info));
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int sm9_sign_master_key_info_encrypt_to_der(const SM9_SIGN_MASTER_KEY *msk, const char *pass, uint8_t **out, size_t *outlen)
|
||||||
|
{
|
||||||
|
uint8_t buf[1024];
|
||||||
|
uint8_t *p = buf;
|
||||||
|
size_t len = 0;
|
||||||
|
|
||||||
|
if (sm9_sign_master_key_to_der(msk, &p, &len) != 1
|
||||||
|
|| sm9_private_key_info_encrypt_to_der(OID_sm9, OID_sm9sign, buf, len, pass, out, outlen) != 1) {
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int sm9_sign_master_key_info_decrypt_from_der(SM9_SIGN_MASTER_KEY *msk, const char *pass, const uint8_t **in, size_t *inlen)
|
||||||
|
{
|
||||||
|
int ret = -1;
|
||||||
|
int alg, params;
|
||||||
|
uint8_t prikey[512];
|
||||||
|
size_t prikey_len;
|
||||||
|
const uint8_t *cp = prikey;
|
||||||
|
|
||||||
|
if (sm9_private_key_info_decrypt_from_der(&alg, ¶ms, prikey, &prikey_len, pass, in, inlen) != 1) {
|
||||||
|
error_print();
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
if (alg != OID_sm9) {
|
||||||
|
error_print();
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
if (params != OID_sm9sign) {
|
||||||
|
error_print();
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
if (sm9_sign_master_key_from_der(msk, &cp, &prikey_len) != 1
|
||||||
|
|| asn1_length_is_zero(prikey_len) != 1) {
|
||||||
|
error_print();
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
ret = 1;
|
||||||
|
end:
|
||||||
|
gmssl_secure_clear(prikey, sizeof(prikey));
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int sm9_sign_master_key_info_encrypt_to_pem(const SM9_SIGN_MASTER_KEY *msk, const char *pass, FILE *fp)
|
||||||
|
{
|
||||||
|
uint8_t buf[1024];
|
||||||
|
uint8_t *p = buf;
|
||||||
|
size_t len = 0;
|
||||||
|
|
||||||
|
if (sm9_sign_master_key_info_encrypt_to_der(msk, pass, &p, &len) != 1) {
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (pem_write(fp, PEM_SM9_SIGN_MASTER_KEY, buf, len) != 1) {
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int sm9_sign_master_key_info_decrypt_from_pem(SM9_SIGN_MASTER_KEY *msk, const char *pass, FILE *fp)
|
||||||
|
{
|
||||||
|
uint8_t buf[512];
|
||||||
|
const uint8_t *cp = buf;
|
||||||
|
size_t len;
|
||||||
|
|
||||||
|
if (pem_read(fp, PEM_SM9_SIGN_MASTER_KEY, buf, &len, sizeof(buf)) != 1
|
||||||
|
|| sm9_sign_master_key_info_decrypt_from_der(msk, pass, &cp, &len) != 1
|
||||||
|
|| asn1_length_is_zero(len) != 1) {
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int sm9_sign_master_public_key_to_pem(const SM9_SIGN_MASTER_KEY *mpk, FILE *fp)
|
||||||
|
{
|
||||||
|
uint8_t buf[1024];
|
||||||
|
uint8_t *p = buf;
|
||||||
|
size_t len = 0;
|
||||||
|
|
||||||
|
if (sm9_sign_master_public_key_to_der(mpk, &p, &len) != 1) {
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (pem_write(fp, PEM_SM9_SIGN_MASTER_PUBLIC_KEY, buf, len) != 1) {
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int sm9_sign_master_public_key_from_pem(SM9_SIGN_MASTER_KEY *mpk, FILE *fp)
|
||||||
|
{
|
||||||
|
uint8_t buf[512];
|
||||||
|
const uint8_t *cp = buf;
|
||||||
|
size_t len;
|
||||||
|
|
||||||
|
if (pem_read(fp, PEM_SM9_SIGN_MASTER_PUBLIC_KEY, buf, &len, sizeof(buf)) != 1
|
||||||
|
|| sm9_sign_master_public_key_from_der(mpk, &cp, &len) != 1
|
||||||
|
|| asn1_length_is_zero(len) != 1) {
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int sm9_sign_key_info_encrypt_to_der(const SM9_SIGN_KEY *key, const char *pass, uint8_t **out, size_t *outlen)
|
||||||
|
{
|
||||||
|
uint8_t buf[1024];
|
||||||
|
uint8_t *p = buf;
|
||||||
|
size_t len = 0;
|
||||||
|
|
||||||
|
if (sm9_sign_key_to_der(key, &p, &len) != 1
|
||||||
|
|| sm9_private_key_info_encrypt_to_der(OID_sm9sign, -1, buf, len, pass, out, outlen) != 1) {
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int sm9_sign_key_info_decrypt_from_der(SM9_SIGN_KEY *key, const char *pass, const uint8_t **in, size_t *inlen)
|
||||||
|
{
|
||||||
|
int ret = -1;
|
||||||
|
int alg, params;
|
||||||
|
uint8_t prikey[512];
|
||||||
|
size_t prikey_len;
|
||||||
|
const uint8_t *cp = prikey;
|
||||||
|
|
||||||
|
if (sm9_private_key_info_decrypt_from_der(&alg, ¶ms, prikey, &prikey_len, pass, in, inlen) != 1) {
|
||||||
|
error_print();
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
if (alg != OID_sm9sign) {
|
||||||
|
error_print();
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
if (params != -1) {
|
||||||
|
error_print();
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
if (sm9_sign_key_from_der(key, &cp, &prikey_len) != 1
|
||||||
|
|| asn1_length_is_zero(prikey_len) != 1) {
|
||||||
|
error_print();
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
ret = 1;
|
||||||
|
end:
|
||||||
|
gmssl_secure_clear(prikey, sizeof(prikey));
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int sm9_sign_key_info_encrypt_to_pem(const SM9_SIGN_KEY *key, const char *pass, FILE *fp)
|
||||||
|
{
|
||||||
|
uint8_t buf[1024];
|
||||||
|
uint8_t *p = buf;
|
||||||
|
size_t len = 0;
|
||||||
|
|
||||||
|
if (sm9_sign_key_info_encrypt_to_der(key, pass, &p, &len) != 1) {
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (pem_write(fp, PEM_SM9_SIGN_PRIVATE_KEY, buf, len) != 1) {
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int sm9_sign_key_info_decrypt_from_pem(SM9_SIGN_KEY *key, const char *pass, FILE *fp)
|
||||||
|
{
|
||||||
|
uint8_t buf[512];
|
||||||
|
const uint8_t *cp = buf;
|
||||||
|
size_t len;
|
||||||
|
|
||||||
|
if (pem_read(fp, PEM_SM9_SIGN_PRIVATE_KEY, buf, &len, sizeof(buf)) != 1
|
||||||
|
|| sm9_sign_key_info_decrypt_from_der(key, pass, &cp, &len) != 1
|
||||||
|
|| asn1_length_is_zero(len) != 1) {
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int sm9_enc_master_key_info_encrypt_to_der(const SM9_ENC_MASTER_KEY *msk, const char *pass, uint8_t **out, size_t *outlen)
|
||||||
|
{
|
||||||
|
uint8_t buf[1024];
|
||||||
|
uint8_t *p = buf;
|
||||||
|
size_t len = 0;
|
||||||
|
|
||||||
|
if (sm9_enc_master_key_to_der(msk, &p, &len) != 1
|
||||||
|
|| sm9_private_key_info_encrypt_to_der(OID_sm9, OID_sm9encrypt, buf, len, pass, out, outlen) != 1) {
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int sm9_enc_master_key_info_decrypt_from_der(SM9_ENC_MASTER_KEY *msk, const char *pass, const uint8_t **in, size_t *inlen)
|
||||||
|
{
|
||||||
|
int ret = -1;
|
||||||
|
int alg, params;
|
||||||
|
uint8_t prikey[512];
|
||||||
|
size_t prikey_len;
|
||||||
|
const uint8_t *cp = prikey;
|
||||||
|
|
||||||
|
if (sm9_private_key_info_decrypt_from_der(&alg, ¶ms, prikey, &prikey_len, pass, in, inlen) != 1) {
|
||||||
|
error_print();
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
if (alg != OID_sm9) {
|
||||||
|
error_print();
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
if (params != OID_sm9encrypt) {
|
||||||
|
error_print();
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
if (sm9_enc_master_key_from_der(msk, &cp, &prikey_len) != 1
|
||||||
|
|| asn1_length_is_zero(prikey_len) != 1) {
|
||||||
|
error_print();
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
ret = 1;
|
||||||
|
end:
|
||||||
|
gmssl_secure_clear(prikey, sizeof(prikey));
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int sm9_enc_master_key_info_encrypt_to_pem(const SM9_ENC_MASTER_KEY *msk, const char *pass, FILE *fp)
|
||||||
|
{
|
||||||
|
uint8_t buf[1024];
|
||||||
|
uint8_t *p = buf;
|
||||||
|
size_t len = 0;
|
||||||
|
|
||||||
|
if (sm9_enc_master_key_info_encrypt_to_der(msk, pass, &p, &len) != 1) {
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (pem_write(fp, PEM_SM9_ENC_MASTER_KEY, buf, len) != 1) {
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int sm9_enc_master_key_info_decrypt_from_pem(SM9_ENC_MASTER_KEY *msk, const char *pass, FILE *fp)
|
||||||
|
{
|
||||||
|
uint8_t buf[512];
|
||||||
|
const uint8_t *cp = buf;
|
||||||
|
size_t len;
|
||||||
|
|
||||||
|
if (pem_read(fp, PEM_SM9_ENC_MASTER_KEY, buf, &len, sizeof(buf)) != 1
|
||||||
|
|| sm9_enc_master_key_info_decrypt_from_der(msk, pass, &cp, &len) != 1
|
||||||
|
|| asn1_length_is_zero(len) != 1) {
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int sm9_enc_master_public_key_to_pem(const SM9_ENC_MASTER_KEY *mpk, FILE *fp)
|
||||||
|
{
|
||||||
|
uint8_t buf[1024];
|
||||||
|
uint8_t *p = buf;
|
||||||
|
size_t len = 0;
|
||||||
|
|
||||||
|
if (sm9_enc_master_public_key_to_der(mpk, &p, &len) != 1) {
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (pem_write(fp, PEM_SM9_ENC_MASTER_PUBLIC_KEY, buf, len) != 1) {
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int sm9_enc_master_public_key_from_pem(SM9_ENC_MASTER_KEY *mpk, FILE *fp)
|
||||||
|
{
|
||||||
|
uint8_t buf[512];
|
||||||
|
const uint8_t *cp = buf;
|
||||||
|
size_t len;
|
||||||
|
|
||||||
|
if (pem_read(fp, PEM_SM9_ENC_MASTER_PUBLIC_KEY, buf, &len, sizeof(buf)) != 1
|
||||||
|
|| sm9_enc_master_public_key_from_der(mpk, &cp, &len) != 1
|
||||||
|
|| asn1_length_is_zero(len) != 1) {
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int sm9_enc_key_info_encrypt_to_der(const SM9_ENC_KEY *key, const char *pass, uint8_t **out, size_t *outlen)
|
||||||
|
{
|
||||||
|
uint8_t buf[1024];
|
||||||
|
uint8_t *p = buf;
|
||||||
|
size_t len = 0;
|
||||||
|
|
||||||
|
if (sm9_enc_key_to_der(key, &p, &len) != 1
|
||||||
|
|| sm9_private_key_info_encrypt_to_der(OID_sm9encrypt, -1, buf, len, pass, out, outlen) != 1) {
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int sm9_enc_key_info_decrypt_from_der(SM9_ENC_KEY *key, const char *pass, const uint8_t **in, size_t *inlen)
|
||||||
|
{
|
||||||
|
int ret = -1;
|
||||||
|
int alg, params;
|
||||||
|
uint8_t prikey[512];
|
||||||
|
size_t prikey_len;
|
||||||
|
const uint8_t *cp = prikey;
|
||||||
|
|
||||||
|
if (sm9_private_key_info_decrypt_from_der(&alg, ¶ms, prikey, &prikey_len, pass, in, inlen) != 1) {
|
||||||
|
error_print();
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
if (alg != OID_sm9encrypt) {
|
||||||
|
error_print();
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
if (params != -1) {
|
||||||
|
error_print();
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
if (sm9_enc_key_from_der(key, &cp, &prikey_len) != 1
|
||||||
|
|| asn1_length_is_zero(prikey_len) != 1) {
|
||||||
|
error_print();
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
ret = 1;
|
||||||
|
end:
|
||||||
|
gmssl_secure_clear(prikey, sizeof(prikey));
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int sm9_enc_key_info_encrypt_to_pem(const SM9_ENC_KEY *key, const char *pass, FILE *fp)
|
||||||
|
{
|
||||||
|
uint8_t buf[1024];
|
||||||
|
uint8_t *p = buf;
|
||||||
|
size_t len = 0;
|
||||||
|
|
||||||
|
if (sm9_enc_key_info_encrypt_to_der(key, pass, &p, &len) != 1) {
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (pem_write(fp, PEM_SM9_ENC_PRIVATE_KEY, buf, len) != 1) {
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int sm9_enc_key_info_decrypt_from_pem(SM9_ENC_KEY *key, const char *pass, FILE *fp)
|
||||||
|
{
|
||||||
|
uint8_t buf[512];
|
||||||
|
const uint8_t *cp = buf;
|
||||||
|
size_t len;
|
||||||
|
|
||||||
|
if (pem_read(fp, PEM_SM9_ENC_PRIVATE_KEY, buf, &len, sizeof(buf)) != 1
|
||||||
|
|| sm9_enc_key_info_decrypt_from_der(key, pass, &cp, &len) != 1
|
||||||
|
|| asn1_length_is_zero(len) != 1) {
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int sm9_fn_print(FILE *fp, int fmt, int ind, const char *label, const sm9_fn_t a)
|
||||||
|
{
|
||||||
|
uint8_t buf[32];
|
||||||
|
sm9_fn_to_bytes(a, buf);
|
||||||
|
format_bytes(fp, fmt, ind, label, buf, sizeof(buf));
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int sm9_point_print(FILE *fp, int fmt, int ind, const char *label, const sm9_point_t *P)
|
||||||
|
{
|
||||||
|
uint8_t buf[65];
|
||||||
|
sm9_point_to_uncompressed_octets(P, buf);
|
||||||
|
format_bytes(fp, fmt, ind, label, buf, sizeof(buf));
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int sm9_twist_point_print(FILE *fp, int fmt, int ind, const char *label, const sm9_twist_point_t *P)
|
||||||
|
{
|
||||||
|
uint8_t buf[129];
|
||||||
|
sm9_twist_point_to_uncompressed_octets(P, buf);
|
||||||
|
format_bytes(fp, fmt, ind, label, buf, sizeof(buf));
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int sm9_sign_master_key_print(FILE *fp, int fmt, int ind, const char *label, const SM9_SIGN_MASTER_KEY *msk)
|
||||||
|
{
|
||||||
|
format_print(fp, fmt, ind, "%s\n", label);
|
||||||
|
ind += 4;
|
||||||
|
sm9_fn_print(fp, fmt, ind, "ks", msk->ks);
|
||||||
|
sm9_twist_point_print(fp, fmt, ind, "Ppubs", &msk->Ppubs);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int sm9_sign_master_public_key_print(FILE *fp, int fmt, int ind, const char *label, const SM9_SIGN_MASTER_KEY *mpk)
|
||||||
|
{
|
||||||
|
format_print(fp, fmt, ind, "%s\n", label);
|
||||||
|
ind += 4;
|
||||||
|
sm9_twist_point_print(fp, fmt, ind, "Ppubs", &mpk->Ppubs);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int sm9_sign_key_print(FILE *fp, int fmt, int ind, const char *label, const SM9_SIGN_KEY *key)
|
||||||
|
{
|
||||||
|
format_print(fp, fmt, ind, "%s\n", label);
|
||||||
|
ind += 4;
|
||||||
|
sm9_point_print(fp, fmt, ind, "ds", &key->ds);
|
||||||
|
sm9_twist_point_print(fp, fmt, ind, "Ppubs", &key->Ppubs);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int sm9_enc_master_key_print(FILE *fp, int fmt, int ind, const char *label, const SM9_ENC_MASTER_KEY *msk)
|
||||||
|
{
|
||||||
|
format_print(fp, fmt, ind, "%s\n", label);
|
||||||
|
ind += 4;
|
||||||
|
sm9_fn_print(fp, fmt, ind, "ke", msk->ke);
|
||||||
|
sm9_point_print(fp, fmt, ind, "Ppube", &msk->Ppube);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int sm9_enc_master_public_key_print(FILE *fp, int fmt, int ind, const char *label, const SM9_ENC_MASTER_KEY *mpk)
|
||||||
|
{
|
||||||
|
format_print(fp, fmt, ind, "%s\n", label);
|
||||||
|
ind += 4;
|
||||||
|
sm9_point_print(fp, fmt, ind, "Ppube", &mpk->Ppube);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int sm9_enc_key_print(FILE *fp, int fmt, int ind, const char *label, const SM9_ENC_KEY *key)
|
||||||
|
{
|
||||||
|
format_print(fp, fmt, ind, "%s\n", label);
|
||||||
|
ind += 4;
|
||||||
|
sm9_twist_point_print(fp, fmt, ind, "de", &key->de);
|
||||||
|
sm9_point_print(fp, fmt, ind, "Ppube", &key->Ppube);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int sm9_signature_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *sig, size_t siglen)
|
||||||
|
{
|
||||||
|
const uint8_t *d;
|
||||||
|
size_t dlen;
|
||||||
|
const uint8_t *p;
|
||||||
|
size_t len;
|
||||||
|
|
||||||
|
if (asn1_sequence_from_der(&d, &dlen, &sig, &siglen) != 1
|
||||||
|
|| asn1_length_is_zero(siglen) != 1) {
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
format_print(fp, fmt, ind, "%s\n", label);
|
||||||
|
ind += 4;
|
||||||
|
if (asn1_octet_string_from_der(&p, &len, &d, &dlen) != 1) goto err;
|
||||||
|
format_bytes(fp, fmt, ind, "h", p, len);
|
||||||
|
if (asn1_bit_octets_from_der(&p, &len, &d, &dlen) != 1) goto err;
|
||||||
|
format_bytes(fp, fmt, ind, "S", p, len);
|
||||||
|
if (asn1_length_is_zero(dlen) != 1) goto err;
|
||||||
|
return 1;
|
||||||
|
err:
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int sm9_ciphertext_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *a, size_t alen)
|
||||||
|
{
|
||||||
|
const uint8_t *d;
|
||||||
|
size_t dlen;
|
||||||
|
int val;
|
||||||
|
const uint8_t *p;
|
||||||
|
size_t len;
|
||||||
|
|
||||||
|
if (asn1_sequence_from_der(&d, &dlen, &a, &alen) != 1
|
||||||
|
|| asn1_length_is_zero(alen) != 1) {
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
format_print(fp, fmt, ind, "%s\n", label);
|
||||||
|
ind += 4;
|
||||||
|
|
||||||
|
if (asn1_int_from_der(&val, &d, &dlen) != 1) goto err;
|
||||||
|
format_print(fp, fmt, ind, "EnType: %d\n", val);
|
||||||
|
if (asn1_bit_octets_from_der(&p, &len, &d, &dlen) != 1) goto err;
|
||||||
|
format_bytes(fp, fmt, ind, "C1", p, len);
|
||||||
|
if (asn1_octet_string_from_der(&p, &len, &d, &dlen) != 1) goto err;
|
||||||
|
format_bytes(fp, fmt, ind, "C3", p, len);
|
||||||
|
if (asn1_octet_string_from_der(&p, &len, &d, &dlen) != 1) goto err;
|
||||||
|
format_bytes(fp, fmt, ind, "CipherText", p, len);
|
||||||
|
if (asn1_length_is_zero(dlen) != 1) goto err;
|
||||||
|
return 1;
|
||||||
|
err:
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|||||||
@@ -139,6 +139,8 @@ int sm9_sign_finish(SM9_SIGN_CTX *ctx, const SM9_SIGN_KEY *key, uint8_t *sig, si
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define hex_r "00033C8616B06704813203DFD00965022ED15975C662337AED648835DC4B1CBE"
|
||||||
|
|
||||||
int sm9_do_sign(const SM9_SIGN_KEY *key, const SM3_CTX *sm3_ctx, SM9_SIGNATURE *sig)
|
int sm9_do_sign(const SM9_SIGN_KEY *key, const SM3_CTX *sm3_ctx, SM9_SIGNATURE *sig)
|
||||||
{
|
{
|
||||||
sm9_fn_t r;
|
sm9_fn_t r;
|
||||||
@@ -156,6 +158,7 @@ int sm9_do_sign(const SM9_SIGN_KEY *key, const SM3_CTX *sm3_ctx, SM9_SIGNATURE *
|
|||||||
do {
|
do {
|
||||||
// A2: rand r in [1, N-1]
|
// A2: rand r in [1, N-1]
|
||||||
sm9_fn_rand(r);
|
sm9_fn_rand(r);
|
||||||
|
//sm9_bn_from_hex(r, hex_r);
|
||||||
|
|
||||||
// A3: w = g^r
|
// A3: w = g^r
|
||||||
sm9_fp12_pow(g, g, r);
|
sm9_fp12_pow(g, g, r);
|
||||||
|
|||||||
@@ -518,7 +518,7 @@ int test_sm9_sign() {
|
|||||||
uint8_t IDA[5] = {0x41, 0x6C, 0x69, 0x63, 0x65};
|
uint8_t IDA[5] = {0x41, 0x6C, 0x69, 0x63, 0x65};
|
||||||
|
|
||||||
sm9_bn_from_hex(mpk.ks, hex_ks); sm9_twist_point_mul_generator(&(mpk.Ppubs), mpk.ks);
|
sm9_bn_from_hex(mpk.ks, hex_ks); sm9_twist_point_mul_generator(&(mpk.Ppubs), mpk.ks);
|
||||||
if (sm9_sign_master_key_extract_key(&mpk, IDA, sizeof(IDA), &key) < 0) goto err; ++j;
|
if (sm9_sign_master_key_extract_key(&mpk, (char *)IDA, sizeof(IDA), &key) < 0) goto err; ++j;
|
||||||
sm9_point_from_hex(&ds, hex_ds); if (!sm9_point_equ(&(key.ds), &ds)) goto err; ++j;
|
sm9_point_from_hex(&ds, hex_ds); if (!sm9_point_equ(&(key.ds), &ds)) goto err; ++j;
|
||||||
|
|
||||||
sm9_sign_init(&ctx);
|
sm9_sign_init(&ctx);
|
||||||
@@ -527,7 +527,7 @@ int test_sm9_sign() {
|
|||||||
|
|
||||||
sm9_verify_init(&ctx);
|
sm9_verify_init(&ctx);
|
||||||
sm9_verify_update(&ctx, data, sizeof(data));
|
sm9_verify_update(&ctx, data, sizeof(data));
|
||||||
if (sm9_verify_finish(&ctx, sig, siglen, &mpk, IDA, sizeof(IDA)) < 0) goto err; ++j;
|
if (sm9_verify_finish(&ctx, sig, siglen, &mpk, (char *)IDA, sizeof(IDA)) < 0) goto err; ++j;
|
||||||
|
|
||||||
printf("%s() ok\n", __FUNCTION__);
|
printf("%s() ok\n", __FUNCTION__);
|
||||||
return 1;
|
return 1;
|
||||||
@@ -557,11 +557,11 @@ int test_sm9_encrypt() {
|
|||||||
uint8_t IDB[3] = {0x42, 0x6F, 0x62};
|
uint8_t IDB[3] = {0x42, 0x6F, 0x62};
|
||||||
|
|
||||||
sm9_bn_from_hex(msk.ke, hex_ke); sm9_point_mul_generator(&(msk.Ppube), msk.ke);
|
sm9_bn_from_hex(msk.ke, hex_ke); sm9_point_mul_generator(&(msk.Ppube), msk.ke);
|
||||||
if (sm9_enc_master_key_extract_key(&msk, IDB, sizeof(IDB), &key) < 0) goto err; ++j;
|
if (sm9_enc_master_key_extract_key(&msk, (char *)IDB, sizeof(IDB), &key) < 0) goto err; ++j;
|
||||||
sm9_twist_point_from_hex(&de, hex_de); if (!sm9_twist_point_equ(&(key.de), &de)) goto err; ++j;
|
sm9_twist_point_from_hex(&de, hex_de); if (!sm9_twist_point_equ(&(key.de), &de)) goto err; ++j;
|
||||||
|
|
||||||
if (sm9_encrypt(&msk, IDB, sizeof(IDB), data, sizeof(data), out, &outlen) < 0) goto err; ++j;
|
if (sm9_encrypt(&msk, (char *)IDB, sizeof(IDB), data, sizeof(data), out, &outlen) < 0) goto err; ++j;
|
||||||
if (sm9_decrypt(&key, IDB, sizeof(IDB), out, outlen, dec, &declen) < 0) goto err; ++j;
|
if (sm9_decrypt(&key, (char *)IDB, sizeof(IDB), out, outlen, dec, &declen) < 0) goto err; ++j;
|
||||||
if (memcmp(data, dec, sizeof(data)) != 0) goto err; ++j;
|
if (memcmp(data, dec, sizeof(data)) != 0) goto err; ++j;
|
||||||
|
|
||||||
printf("%s() ok\n", __FUNCTION__);
|
printf("%s() ok\n", __FUNCTION__);
|
||||||
|
|||||||
Reference in New Issue
Block a user