From 13a3651f293d00ef5985279c77b214f74f8a1029 Mon Sep 17 00:00:00 2001 From: Zhi Guan Date: Fri, 20 May 2022 11:33:31 +0800 Subject: [PATCH] Update SM9 --- include/gmssl/sm9.h | 92 +++++- src/sm9_key.c | 746 ++++++++++++++++++++++++++++++++++++++++++++ src/sm9_lib.c | 3 + tests/sm9test.c | 10 +- 4 files changed, 845 insertions(+), 6 deletions(-) diff --git a/include/gmssl/sm9.h b/include/gmssl/sm9.h index af74e2a4..718e5f7e 100644 --- a/include/gmssl/sm9.h +++ b/include/gmssl/sm9.h @@ -335,6 +335,47 @@ typedef struct { } 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 { ks INTEGER, @@ -346,25 +387,45 @@ typedef struct { sm9_fn_t ks; } 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_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_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 { ds BIT STRING, -- uncompressed octets of ECPoint Ppubs BIT STRING -- uncompressed octets of twisted point } + +SM9的用户私钥和椭圆曲线的就没有任何关系了。 */ typedef struct { sm9_twist_point_t Ppubs; sm9_point_t ds; } SM9_SIGN_KEY; +// algorithm,parameters = sm9sign, 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_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_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_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_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_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 { @@ -422,8 +491,13 @@ typedef struct { sm9_twist_point_t de; } SM9_ENC_KEY; +// algorithm,parameters = sm9encrypt, 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_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_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_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, 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, @@ -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, 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 } # endif diff --git a/src/sm9_key.c b/src/sm9_key.c index 1a25231b..2e27b57c 100644 --- a/src/sm9_key.c +++ b/src/sm9_key.c @@ -50,9 +50,14 @@ #include #include #include +#include #include #include +#include +#include #include +#include +#include #include @@ -444,3 +449,744 @@ int sm9_enc_master_key_extract_key(SM9_ENC_MASTER_KEY *msk, const char *id, size 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; +} diff --git a/src/sm9_lib.c b/src/sm9_lib.c index 5da96d38..5b3db422 100644 --- a/src/sm9_lib.c +++ b/src/sm9_lib.c @@ -139,6 +139,8 @@ int sm9_sign_finish(SM9_SIGN_CTX *ctx, const SM9_SIGN_KEY *key, uint8_t *sig, si return 1; } +#define hex_r "00033C8616B06704813203DFD00965022ED15975C662337AED648835DC4B1CBE" + int sm9_do_sign(const SM9_SIGN_KEY *key, const SM3_CTX *sm3_ctx, SM9_SIGNATURE *sig) { 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 { // A2: rand r in [1, N-1] sm9_fn_rand(r); + //sm9_bn_from_hex(r, hex_r); // A3: w = g^r sm9_fp12_pow(g, g, r); diff --git a/tests/sm9test.c b/tests/sm9test.c index 1dbc664f..c15fdfae 100644 --- a/tests/sm9test.c +++ b/tests/sm9test.c @@ -518,7 +518,7 @@ int test_sm9_sign() { 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); - 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_sign_init(&ctx); @@ -527,7 +527,7 @@ int test_sm9_sign() { sm9_verify_init(&ctx); 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__); return 1; @@ -557,11 +557,11 @@ int test_sm9_encrypt() { uint8_t IDB[3] = {0x42, 0x6F, 0x62}; 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; - if (sm9_encrypt(&msk, 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_encrypt(&msk, (char *)IDB, sizeof(IDB), data, sizeof(data), out, &outlen) < 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; printf("%s() ok\n", __FUNCTION__);