mirror of
https://github.com/guanzhi/GmSSL.git
synced 2026-08-15 10:33:42 +08:00
add CBC-MAC and GM OTP, not tested
This commit is contained in:
@@ -60,6 +60,7 @@
|
||||
#include <openssl/x509.h>
|
||||
#include <openssl/asn1.h>
|
||||
#include <openssl/ecdsa.h>
|
||||
#include <openssl/sm3.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@@ -68,7 +69,9 @@ extern "C" {
|
||||
|
||||
#define SM2_MAX_ID_BITS 65535
|
||||
#define SM2_MAX_ID_LENGTH (SM2_MAX_ID_BITS/8)
|
||||
#define SM2_DEFAULT_ID "1234567812345678"
|
||||
#define SM2_DEFAULT_ID_GMT09 "1234567812345678"
|
||||
#define SM2_DEFAULT_ID_GMSSL "anonym@gmssl.org"
|
||||
#define SM2_DEFAULT_ID SM2_DEFAULT_ID_GMSSL
|
||||
#define SM2_DEFAULT_POINT_CONVERSION_FORM POINT_CONVERSION_UNCOMPRESSED
|
||||
|
||||
|
||||
@@ -78,6 +81,14 @@ int SM2_compute_id_digest(const EVP_MD *md, unsigned char *dgst,
|
||||
unsigned int *dgstlen, EC_KEY *ec_key);
|
||||
|
||||
|
||||
|
||||
typedef struct sm2_enc_params_st {
|
||||
EVP_MD *kdf_md;
|
||||
EVP_MD *mac_md;
|
||||
int mactag_size;
|
||||
point_conversion_form_t point_form;
|
||||
} SM2_ENC_PARAMS;
|
||||
|
||||
typedef struct sm2_ciphertext_value_st {
|
||||
EC_POINT *ephem_point;
|
||||
unsigned char *ciphertext;
|
||||
@@ -103,26 +114,25 @@ int SM2_CIPHERTEXT_VALUE_print(BIO *out, const EC_GROUP *ec_group,
|
||||
const SM2_CIPHERTEXT_VALUE *cv, int indent, unsigned long flags);
|
||||
|
||||
/* FIXME: we should provide optional return value */
|
||||
SM2_CIPHERTEXT_VALUE *SM2_do_encrypt(const EVP_MD *kdf_md, const EVP_MD *mac_md,
|
||||
SM2_CIPHERTEXT_VALUE *SM2_do_encrypt(const SM2_ENC_PARAMS *params,
|
||||
const unsigned char *in, size_t inlen, EC_KEY *ec_key);
|
||||
int SM2_do_decrypt(const EVP_MD *kdf_md, const EVP_MD *mac_md,
|
||||
int SM2_do_decrypt(const SM2_ENC_PARAMS *params,
|
||||
const SM2_CIPHERTEXT_VALUE *cv, unsigned char *out, size_t *outlen,
|
||||
EC_KEY *ec_key);
|
||||
|
||||
int SM2_encrypt_ex(const EVP_MD *kdf_md, const EVP_MD *mac_md,
|
||||
point_conversion_form_t point_form,
|
||||
int SM2_encrypt(const SM2_ENC_PARAMS *params,
|
||||
const unsigned char *in, size_t inlen,
|
||||
unsigned char *out, size_t *outlen, EC_KEY *ec_key);
|
||||
int SM2_decrypt_ex(const EVP_MD *kdf_md, const EVP_MD *mac_md,
|
||||
point_conversion_form_t point_form,
|
||||
int SM2_decrypt(const SM2_ENC_PARAMS *params,
|
||||
const unsigned char *in, size_t inlen,
|
||||
unsigned char *out, size_t *outlen, EC_KEY *ec_key);
|
||||
|
||||
int SM2_encrypt(const unsigned char *in, size_t inlen,
|
||||
int SM2_encrypt_with_recommended(const unsigned char *in, size_t inlen,
|
||||
unsigned char *out, size_t *outlen, EC_KEY *ec_key);
|
||||
int SM2_decrypt(const unsigned char *in, size_t inlen,
|
||||
int SM2_decrypt_with_recommended(const unsigned char *in, size_t inlen,
|
||||
unsigned char *out, size_t *outlen, EC_KEY *ec_key);
|
||||
int SM2_encrypt_elgamal(const unsigned char *in, size_t inlen,
|
||||
unsigned char *out, size_t *outlen, EC_KEY *ec_key);
|
||||
int SM2_decrypt_elgamal(const unsigned char *in, size_t inlen,
|
||||
unsigned char *out, size_t *outlen, EC_KEY *ec_key);
|
||||
|
||||
|
||||
int SM2_compute_message_digest(const EVP_MD *id_md, const EVP_MD *msg_md,
|
||||
const void *msg, size_t msglen, unsigned char *dgst,
|
||||
@@ -130,7 +140,6 @@ int SM2_compute_message_digest(const EVP_MD *id_md, const EVP_MD *msg_md,
|
||||
int SM2_digest(const void *msg, size_t msglen, unsigned char *dgst,
|
||||
unsigned int *dgstlen, EC_KEY *ec_key);
|
||||
|
||||
|
||||
#define SM2_signature_size(ec_key) ECDSA_size(ec_key)
|
||||
int SM2_sign_setup(EC_KEY *ec_key, BN_CTX *ctx, BIGNUM **a, BIGNUM **b);
|
||||
ECDSA_SIG *SM2_do_sign_ex(const unsigned char *dgst, int dgstlen,
|
||||
|
||||
@@ -91,6 +91,7 @@ Default ID = "1234567812345678"
|
||||
|
||||
*/
|
||||
|
||||
#if 0
|
||||
typedef struct SM2CiphertextValue_st {
|
||||
ASN1_INTEGER *xCoordinate;
|
||||
ASN1_INTEGER *yCoordinate;
|
||||
@@ -107,6 +108,22 @@ ASN1_SEQUENCE(SM2CiphertextValue) = {
|
||||
IMPLEMENT_ASN1_FUNCTIONS(SM2CiphertextValue)
|
||||
IMPLEMENT_ASN1_DUP_FUNCTION(SM2CiphertextValue)
|
||||
|
||||
typedef struct SM2EnvelopedKey_st {
|
||||
ASN1_ALGOR *symAlgID;
|
||||
SM2CiphertextValue *symEncryptedKey;
|
||||
ASN1_OCTET_STRING *sm2PublicKey;
|
||||
ASN1_BIT_STRING *sm2EncryptedPrivateKey;
|
||||
} SM2EnvelopedKey;
|
||||
|
||||
/* GmSSL specific */
|
||||
ASN1_SEQUENCE(SM2_CIPHERTEXT_VALUE_ASN1) = {
|
||||
ASN1_SIMPLE(SM2_CIPHERTEXT_VALUE_ASN1, ephem_point, ASN1_OCTET_STRING),
|
||||
ASN1_SIMPLE(SM2_CIPHERTEXT_VALUE_ASN1, ciphertext, ASN1_OCTET_STRING),
|
||||
ASN1_SIMPLE(SM2_CIPHERTEXT_VALUE_ASN1, mactag, ASN1_OCTET_STRING)
|
||||
} ASN1_SEQUENCE_END(SM2_CIPHERTEXT_VALUE)
|
||||
IMPLEMENT_ASN1_FUNCTIONS(SM2_CIPHERTEXT_VALUE_ASN1)
|
||||
IMPLEMENT_ASN1_DUP_FUNCTION(SM2_CIPHERTEXT_VALUE_ASN1)
|
||||
|
||||
|
||||
int i2d_SM2_CIPHERTEXT_VALUE(const SM2_CIPHERTEXT_VALUE *c, unsigned char **out)
|
||||
{
|
||||
@@ -145,4 +162,4 @@ SM2_CIPHERTEXT_VALUE *d2i_SM2_CIPHERTEXT_VALUE(SM2_CIPHERTEXT_VALUE **c,
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -239,8 +239,7 @@ end:
|
||||
return 0;
|
||||
}
|
||||
|
||||
int SM2_encrypt_ex(const EVP_MD *kdf_md, const EVP_MD *mac_md,
|
||||
point_conversion_form_t point_form,
|
||||
int SM2_encrypt(const SM2_ENC_PARAMS *params,
|
||||
const unsigned char *in, size_t inlen,
|
||||
unsigned char *out, size_t *outlen, EC_KEY *ec_key)
|
||||
{
|
||||
@@ -249,7 +248,8 @@ int SM2_encrypt_ex(const EVP_MD *kdf_md, const EVP_MD *mac_md,
|
||||
SM2_CIPHERTEXT_VALUE *cv = NULL;
|
||||
int len;
|
||||
|
||||
if (!(len = SM2_CIPHERTEXT_VALUE_size(ec_group, point_form, inlen, mac_md))) {
|
||||
if (!(len = SM2_CIPHERTEXT_VALUE_size(ec_group,
|
||||
params->point_form, inlen, params->mac_md))) {
|
||||
goto end;
|
||||
}
|
||||
|
||||
@@ -261,10 +261,11 @@ int SM2_encrypt_ex(const EVP_MD *kdf_md, const EVP_MD *mac_md,
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!(cv = SM2_do_encrypt(kdf_md, mac_md, in, inlen, ec_key))) {
|
||||
if (!(cv = SM2_do_encrypt(params, in, inlen, ec_key))) {
|
||||
goto end;
|
||||
}
|
||||
if (!SM2_CIPHERTEXT_VALUE_encode(cv, ec_group, point_form, out, outlen)) {
|
||||
if (!SM2_CIPHERTEXT_VALUE_encode(cv, ec_group,
|
||||
params->point_form, out, outlen)) {
|
||||
goto end;
|
||||
}
|
||||
|
||||
@@ -274,14 +275,14 @@ end:
|
||||
return ret;
|
||||
}
|
||||
|
||||
SM2_CIPHERTEXT_VALUE *SM2_do_encrypt(const EVP_MD *kdf_md, const EVP_MD *mac_md,
|
||||
SM2_CIPHERTEXT_VALUE *SM2_do_encrypt(const SM2_ENC_PARAMS *params,
|
||||
const unsigned char *in, size_t inlen, EC_KEY *ec_key)
|
||||
{
|
||||
int ok = 0;
|
||||
SM2_CIPHERTEXT_VALUE *cv = NULL;
|
||||
const EC_GROUP *ec_group = EC_KEY_get0_group(ec_key);
|
||||
const EC_POINT *pub_key = EC_KEY_get0_public_key(ec_key);
|
||||
KDF_FUNC kdf = KDF_get_x9_63(kdf_md);
|
||||
KDF_FUNC kdf = KDF_get_x9_63(params->kdf_md);
|
||||
EC_POINT *point = NULL;
|
||||
BIGNUM *n = NULL;
|
||||
BIGNUM *h = NULL;
|
||||
@@ -290,6 +291,8 @@ SM2_CIPHERTEXT_VALUE *SM2_do_encrypt(const EVP_MD *kdf_md, const EVP_MD *mac_md,
|
||||
EVP_MD_CTX *md_ctx = NULL;
|
||||
unsigned char buf[(OPENSSL_ECC_MAX_FIELD_BITS + 7)/4 + 1];
|
||||
int nbytes;
|
||||
unsigned char dgst[EVP_MAX_MD_SIZE];
|
||||
unsigned int dgstlen;
|
||||
size_t len;
|
||||
int i;
|
||||
|
||||
@@ -331,16 +334,6 @@ SM2_CIPHERTEXT_VALUE *SM2_do_encrypt(const EVP_MD *kdf_md, const EVP_MD *mac_md,
|
||||
}
|
||||
nbytes = (EC_GROUP_get_degree(ec_group) + 7) / 8;
|
||||
|
||||
|
||||
//OPENSSL_assert(nbytes == BN_num_bytes(n));
|
||||
|
||||
#if 0
|
||||
/* check sm2 curve and md is 256 bits */
|
||||
OPENSSL_assert(nbytes == 32);
|
||||
OPENSSL_assert(EVP_MD_size(kdf_md) == 32);
|
||||
OPENSSL_assert(EVP_MD_size(mac_md) == 32);
|
||||
#endif
|
||||
|
||||
do
|
||||
{
|
||||
/* A1: rand k in [1, n-1] */
|
||||
@@ -395,7 +388,7 @@ SM2_CIPHERTEXT_VALUE *SM2_do_encrypt(const EVP_MD *kdf_md, const EVP_MD *mac_md,
|
||||
}
|
||||
|
||||
/* A7: C3 = Hash(x2 || M || y2) */
|
||||
if (!EVP_DigestInit_ex(md_ctx, mac_md, NULL)) {
|
||||
if (!EVP_DigestInit_ex(md_ctx, params->mac_md, NULL)) {
|
||||
goto end;
|
||||
}
|
||||
if (!EVP_DigestUpdate(md_ctx, buf + 1, nbytes)) {
|
||||
@@ -407,10 +400,16 @@ SM2_CIPHERTEXT_VALUE *SM2_do_encrypt(const EVP_MD *kdf_md, const EVP_MD *mac_md,
|
||||
if (!EVP_DigestUpdate(md_ctx, buf + 1 + nbytes, nbytes)) {
|
||||
goto end;
|
||||
}
|
||||
if (!EVP_DigestFinal_ex(md_ctx, cv->mactag, &cv->mactag_size)) {
|
||||
if (!EVP_DigestFinal_ex(md_ctx, dgst, &dgstlen)) {
|
||||
goto end;
|
||||
}
|
||||
|
||||
/* GmSSL specific: reduce mactag size */
|
||||
if (params->mactag_size > dgstlen) {
|
||||
goto end;
|
||||
}
|
||||
cv->mactag_size = params->mactag_size;
|
||||
memcpy(cv->mactag, dgst, cv->mactag_size);
|
||||
|
||||
ok = 1;
|
||||
|
||||
@@ -430,8 +429,7 @@ end:
|
||||
return cv;
|
||||
}
|
||||
|
||||
int SM2_decrypt_ex(const EVP_MD *kdf_md, const EVP_MD *mac_md,
|
||||
point_conversion_form_t point_form,
|
||||
int SM2_decrypt(const SM2_ENC_PARAMS *params,
|
||||
const unsigned char *in, size_t inlen,
|
||||
unsigned char *out, size_t *outlen, EC_KEY *ec_key)
|
||||
{
|
||||
@@ -440,7 +438,7 @@ int SM2_decrypt_ex(const EVP_MD *kdf_md, const EVP_MD *mac_md,
|
||||
SM2_CIPHERTEXT_VALUE *cv = NULL;
|
||||
int len;
|
||||
|
||||
if (!(len = SM2_CIPHERTEXT_VALUE_size(ec_group, point_form, 0, mac_md))) {
|
||||
if (!(len = SM2_CIPHERTEXT_VALUE_size(ec_group, params->point_form, 0, params->mac_md))) {
|
||||
fprintf(stderr, "%s %d\n", __FILE__, __LINE__);
|
||||
goto end;
|
||||
}
|
||||
@@ -457,11 +455,11 @@ int SM2_decrypt_ex(const EVP_MD *kdf_md, const EVP_MD *mac_md,
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!(cv = SM2_CIPHERTEXT_VALUE_decode(ec_group, point_form, mac_md, in, inlen))) {
|
||||
if (!(cv = SM2_CIPHERTEXT_VALUE_decode(ec_group, params->point_form, params->mac_md, in, inlen))) {
|
||||
fprintf(stderr, "%s %d\n", __FILE__, __LINE__);
|
||||
goto end;
|
||||
}
|
||||
if (!SM2_do_decrypt(kdf_md, mac_md, cv, out, outlen, ec_key)) {
|
||||
if (!SM2_do_decrypt(params, cv, out, outlen, ec_key)) {
|
||||
fprintf(stderr, "%s %d\n", __FILE__, __LINE__);
|
||||
goto end;
|
||||
}
|
||||
@@ -472,14 +470,14 @@ end:
|
||||
return ret;
|
||||
}
|
||||
|
||||
int SM2_do_decrypt(const EVP_MD *kdf_md, const EVP_MD *mac_md,
|
||||
int SM2_do_decrypt(const SM2_ENC_PARAMS *params,
|
||||
const SM2_CIPHERTEXT_VALUE *cv, unsigned char *out, size_t *outlen,
|
||||
EC_KEY *ec_key)
|
||||
{
|
||||
int ret = 0;
|
||||
const EC_GROUP *ec_group = EC_KEY_get0_group(ec_key);
|
||||
const BIGNUM *pri_key = EC_KEY_get0_private_key(ec_key);
|
||||
KDF_FUNC kdf = KDF_get_x9_63(kdf_md);
|
||||
KDF_FUNC kdf = KDF_get_x9_63(params->kdf_md);
|
||||
EC_POINT *point = NULL;
|
||||
BIGNUM *n = NULL;
|
||||
BIGNUM *h = NULL;
|
||||
@@ -488,13 +486,12 @@ int SM2_do_decrypt(const EVP_MD *kdf_md, const EVP_MD *mac_md,
|
||||
unsigned char buf[(OPENSSL_ECC_MAX_FIELD_BITS + 7)/4 + 1];
|
||||
unsigned char mac[EVP_MAX_MD_SIZE];
|
||||
unsigned int maclen;
|
||||
unsigned char dgst[EVP_MAX_MD_SIZE];
|
||||
unsigned int dgstlen;
|
||||
int nbytes;
|
||||
size_t size;
|
||||
int i;
|
||||
|
||||
OPENSSL_assert(kdf_md && mac_md && cv && ec_key);
|
||||
OPENSSL_assert(cv->ephem_point && cv->ciphertext);
|
||||
|
||||
if (!ec_group || !pri_key) {
|
||||
goto end;
|
||||
}
|
||||
@@ -528,14 +525,6 @@ int SM2_do_decrypt(const EVP_MD *kdf_md, const EVP_MD *mac_md,
|
||||
goto end;
|
||||
}
|
||||
nbytes = (EC_GROUP_get_degree(ec_group) + 7) / 8;
|
||||
//OPENSSL_assert(nbytes == BN_num_bytes(n));
|
||||
|
||||
#if 0
|
||||
/* check sm2 curve and md is 256 bits */
|
||||
OPENSSL_assert(nbytes == 32);
|
||||
OPENSSL_assert(EVP_MD_size(kdf_md) == 32);
|
||||
OPENSSL_assert(EVP_MD_size(mac_md) == 32);
|
||||
#endif
|
||||
|
||||
/* B2: check [h]C1 != O */
|
||||
if (!EC_POINT_mul(ec_group, point, NULL, cv->ephem_point, h, bn_ctx)) {
|
||||
@@ -568,7 +557,7 @@ int SM2_do_decrypt(const EVP_MD *kdf_md, const EVP_MD *mac_md,
|
||||
*outlen = cv->ciphertext_size;
|
||||
|
||||
/* B6: check Hash(x2 || M || y2) == C3 */
|
||||
if (!EVP_DigestInit_ex(md_ctx, mac_md, NULL)) {
|
||||
if (!EVP_DigestInit_ex(md_ctx, params->mac_md, NULL)) {
|
||||
goto end;
|
||||
}
|
||||
if (!EVP_DigestUpdate(md_ctx, buf + 1, nbytes)) {
|
||||
@@ -583,8 +572,13 @@ int SM2_do_decrypt(const EVP_MD *kdf_md, const EVP_MD *mac_md,
|
||||
if (!EVP_DigestFinal_ex(md_ctx, mac, &maclen)) {
|
||||
goto end;
|
||||
}
|
||||
if (cv->mactag_size != maclen ||
|
||||
memcmp(cv->mactag, mac, maclen)) {
|
||||
|
||||
/* GmSSL specific */
|
||||
if (params->mactag_size > maclen) {
|
||||
goto end;
|
||||
}
|
||||
if (cv->mactag_size != params->mactag_size ||
|
||||
memcmp(mac, cv->mactag, cv->mactag_size)) {
|
||||
goto end;
|
||||
}
|
||||
|
||||
@@ -599,26 +593,55 @@ end:
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int SM2_encrypt(const unsigned char *in, size_t inlen,
|
||||
unsigned char *out, size_t *outlen, EC_KEY *ec_key)
|
||||
int SM2_ENC_PARAMS_init_with_recommended(SM2_ENC_PARAMS *params)
|
||||
{
|
||||
const EVP_MD *kdf_md = EVP_sm3();
|
||||
const EVP_MD *mac_md = EVP_sm3();
|
||||
point_conversion_form_t point_form = SM2_DEFAULT_POINT_CONVERSION_FORM;
|
||||
|
||||
return SM2_encrypt_ex(kdf_md, mac_md, point_form,
|
||||
in, inlen, out, outlen, ec_key);
|
||||
if (!params) {
|
||||
return 0;
|
||||
}
|
||||
params->kdf_md = EVP_sm3();
|
||||
params->mac_md = EVP_sm3();
|
||||
params->mactag_size = -1;
|
||||
params->point_form = POINT_CONVERSION_UNCOMPRESSED;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int SM2_decrypt(const unsigned char *in, size_t inlen,
|
||||
int SM2_encrypt_with_recommended(const unsigned char *in, size_t inlen,
|
||||
unsigned char *out, size_t *outlen, EC_KEY *ec_key)
|
||||
{
|
||||
const EVP_MD *kdf_md = EVP_sm3();
|
||||
const EVP_MD *mac_md = EVP_sm3();
|
||||
point_conversion_form_t point_form = SM2_DEFAULT_POINT_CONVERSION_FORM;
|
||||
|
||||
return SM2_decrypt_ex(kdf_md, mac_md, point_form,
|
||||
in, inlen, out, outlen, ec_key);
|
||||
SM2_ENC_PARAMS params;
|
||||
SM2_ENC_PARAMS_init_with_recommended(¶ms);
|
||||
return SM2_encrypt(¶ms, in, inlen, out, outlen, ec_key);
|
||||
}
|
||||
|
||||
int SM2_decrypt_with_recommended(const unsigned char *in, size_t inlen,
|
||||
unsigned char *out, size_t *outlen, EC_KEY *ec_key)
|
||||
{
|
||||
SM2_ENC_PARAMS params;
|
||||
SM2_ENC_PARAMS_init_with_recommended(¶ms);
|
||||
return SM2_decrypt(¶ms, in, inlen, out, outlen, ec_key);
|
||||
}
|
||||
|
||||
int SM2_encrypt_elgamal(const unsigned char *in, size_t inlen,
|
||||
unsigned char *out, size_t *outlen, EC_KEY *ec_key)
|
||||
{
|
||||
SM2_ENC_PARAMS params;
|
||||
params.kdf_md = EVP_sm3();
|
||||
params.mac_md = EVP_sm3();
|
||||
params.mactag_size = 0;
|
||||
params.point_form = POINT_CONVERSION_COMPRESSED;
|
||||
return SM2_encrypt(¶ms, in, inlen, out, outlen, ec_key);
|
||||
}
|
||||
|
||||
int SM2_decrypt_elgamal(const unsigned char *in, size_t inlen,
|
||||
unsigned char *out, size_t *outlen, EC_KEY *ec_key)
|
||||
{
|
||||
SM2_ENC_PARAMS params;
|
||||
params.kdf_md = EVP_sm3();
|
||||
params.mac_md = EVP_sm3();
|
||||
params.mactag_size = 0;
|
||||
params.point_form = POINT_CONVERSION_COMPRESSED;
|
||||
return SM2_decrypt(¶ms, in, inlen, out, outlen, ec_key);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -662,3 +662,11 @@ int SM2_KAP_final_check(SM2_KAP_CTX *ctx, const unsigned char *checksum,
|
||||
return 1;
|
||||
}
|
||||
|
||||
int SM2_compute_key(void *out, size_t outlen,
|
||||
const EC_POINT *pub_key, EC_KEY *ecdh,
|
||||
const EC_POINT *pub_key2, EC_KEY *ec_key2,
|
||||
const char *id1, const char *id2, int is_ini)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user