add CBC-MAC and GM OTP, not tested

This commit is contained in:
Zhi Guan
2016-05-15 20:21:51 +02:00
parent 8c0439e7d6
commit 60d14da0cc
81 changed files with 2789 additions and 1401 deletions

View File

@@ -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,

View File

@@ -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

View File

@@ -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(&params);
return SM2_encrypt(&params, 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(&params);
return SM2_decrypt(&params, 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(&params, 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(&params, in, inlen, out, outlen, ec_key);
}

View File

@@ -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;
}