Add SM9 encapsulate key functions

This commit is contained in:
Zhi Guan
2018-10-05 11:53:13 +08:00
parent eaf4002536
commit a7b96e8024
12 changed files with 5754 additions and 5362 deletions

View File

@@ -10,7 +10,7 @@
*/
/* Serialized OID's */
static const unsigned char so[7876] = {
static const unsigned char so[7905] = {
0x2A,0x86,0x48,0x86,0xF7,0x0D, /* [ 0] OBJ_rsadsi */
0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01, /* [ 6] OBJ_pkcs */
0x2A,0x86,0x48,0x86,0xF7,0x0D,0x02,0x02, /* [ 13] OBJ_md2 */
@@ -1100,9 +1100,12 @@ static const unsigned char so[7876] = {
0x2A,0x81,0x1C,0xCF,0x55,0x01,0x82,0x2E,0x03,0x01, /* [ 7845] OBJ_sm9encrypt_with_sm3_xor */
0x2A,0x81,0x1C,0xCF,0x55,0x01,0x82,0x2E,0x03,0x02, /* [ 7855] OBJ_sm9encrypt_with_sm3_sms4_cbc */
0x2A,0x81,0x1C,0xCF,0x55,0x01,0x82,0x2E,0x03,0x03, /* [ 7865] OBJ_sm9encrypt_with_sm3_sms4_ctr */
0x2A,0x81,0x1C,0xCF,0x55,0x01,0x82,0x2E,0x05, /* [ 7875] OBJ_sm9kdf */
0x2A,0x81,0x1C,0xCF,0x55,0x01,0x82,0x2E,0x05,0x01, /* [ 7884] OBJ_sm9kdf_with_sm3 */
0x2A,0x81,0x1C,0xCF,0x55,0x01,0x82,0x2E,0x05,0x02, /* [ 7894] OBJ_sm9kdf_with_sha256 */
};
#define NUM_NID 1209
#define NUM_NID 1212
static const ASN1_OBJECT nid_objs[NUM_NID] = {
{"UNDEF", "undefined", NID_undef},
{"rsadsi", "RSA Data Security, Inc.", NID_rsadsi, 6, &so[0]},
@@ -2313,9 +2316,12 @@ static const ASN1_OBJECT nid_objs[NUM_NID] = {
{"sm9encrypt-with-sm3-xor", "sm9encrypt-with-sm3-xor", NID_sm9encrypt_with_sm3_xor, 10, &so[7845]},
{"sm9encrypt-with-sm3-sms4-cbc", "sm9encrypt-with-sm3-sms4-cbc", NID_sm9encrypt_with_sm3_sms4_cbc, 10, &so[7855]},
{"sm9encrypt-with-sm3-sms4-ctr", "sm9encrypt-with-sm3-sms4-ctr", NID_sm9encrypt_with_sm3_sms4_ctr, 10, &so[7865]},
{"sm9kdf", "sm9kdf", NID_sm9kdf, 9, &so[7875]},
{"sm9kdf-with-sm3", "sm9kdf-with-sm3", NID_sm9kdf_with_sm3, 10, &so[7884]},
{"sm9kdf-with-sha256", "sm9kdf-with-sha256", NID_sm9kdf_with_sha256, 10, &so[7894]},
};
#define NUM_SN 1198
#define NUM_SN 1201
static const unsigned int sn_objs[NUM_SN] = {
364, /* "AD_DVCS" */
419, /* "AES-128-CBC" */
@@ -3446,6 +3452,9 @@ static const unsigned int sn_objs[NUM_SN] = {
1201, /* "sm9hash1" */
1203, /* "sm9hash1-with-sha256" */
1202, /* "sm9hash1-with-sm3" */
1209, /* "sm9kdf" */
1211, /* "sm9kdf-with-sha256" */
1210, /* "sm9kdf-with-sm3" */
1124, /* "sm9keyagreement" */
1123, /* "sm9sign" */
1205, /* "sm9sign-with-sha256" */
@@ -3517,7 +3526,7 @@ static const unsigned int sn_objs[NUM_SN] = {
1194, /* "zuc-128eia3" */
};
#define NUM_LN 1198
#define NUM_LN 1201
static const unsigned int ln_objs[NUM_LN] = {
363, /* "AD Time Stamping" */
405, /* "ANSI X9.62" */
@@ -4632,6 +4641,9 @@ static const unsigned int ln_objs[NUM_LN] = {
1201, /* "sm9hash1" */
1203, /* "sm9hash1-with-sha256" */
1202, /* "sm9hash1-with-sm3" */
1209, /* "sm9kdf" */
1211, /* "sm9kdf-with-sha256" */
1210, /* "sm9kdf-with-sm3" */
1124, /* "sm9keyagreement" */
1123, /* "sm9sign" */
1205, /* "sm9sign-with-sha256" */
@@ -4719,7 +4731,7 @@ static const unsigned int ln_objs[NUM_LN] = {
1194, /* "zuc-128eia3" */
};
#define NUM_OBJ 1095
#define NUM_OBJ 1098
static const unsigned int obj_objs[NUM_OBJ] = {
0, /* OBJ_undef 0 */
181, /* OBJ_iso 1 */
@@ -5461,6 +5473,7 @@ static const unsigned int obj_objs[NUM_OBJ] = {
1124, /* OBJ_sm9keyagreement 1 2 156 10197 1 302 2 */
1125, /* OBJ_sm9encrypt 1 2 156 10197 1 302 3 */
1201, /* OBJ_sm9hash1 1 2 156 10197 1 302 4 */
1209, /* OBJ_sm9kdf 1 2 156 10197 1 302 5 */
1127, /* OBJ_hmac_sm3 1 2 156 10197 1 401 2 */
1193, /* OBJ_zuc_128eea3 1 2 156 10197 1 800 1 */
1194, /* OBJ_zuc_128eia3 1 2 156 10197 1 800 2 */
@@ -5675,6 +5688,8 @@ static const unsigned int obj_objs[NUM_OBJ] = {
1208, /* OBJ_sm9encrypt_with_sm3_sms4_ctr 1 2 156 10197 1 302 3 3 */
1202, /* OBJ_sm9hash1_with_sm3 1 2 156 10197 1 302 4 1 */
1203, /* OBJ_sm9hash1_with_sha256 1 2 156 10197 1 302 4 2 */
1210, /* OBJ_sm9kdf_with_sm3 1 2 156 10197 1 302 5 1 */
1211, /* OBJ_sm9kdf_with_sha256 1 2 156 10197 1 302 5 2 */
1139, /* OBJ_type1curve 1 2 840 1 114334 1 1 1 */
1140, /* OBJ_type2curve 1 2 840 1 114334 1 1 2 */
1141, /* OBJ_type3curve 1 2 840 1 114334 1 1 3 */

View File

@@ -1206,3 +1206,6 @@ sm9sign_with_sha256 1205
sm9encrypt_with_sm3_xor 1206
sm9encrypt_with_sm3_sms4_cbc 1207
sm9encrypt_with_sm3_sms4_ctr 1208
sm9kdf 1209
sm9kdf_with_sm3 1210
sm9kdf_with_sha256 1211

View File

@@ -1621,8 +1621,11 @@ sm9encrypt 1 : sm9encrypt-with-sm3-xor
sm9encrypt 2 : sm9encrypt-with-sm3-sms4-cbc
sm9encrypt 3 : sm9encrypt-with-sm3-sms4-ctr
sm-scheme 302 4 : sm9hash1
sm-scheme 302 5 : sm9kdf
sm9hash1 1 : sm9hash1-with-sm3
sm9hash1 2 : sm9hash1-with-sha256
sm9kdf 1 : sm9kdf-with-sm3
sm9kdf 2 : sm9kdf-with-sha256
sm-scheme 401 : SM3 : sm3
sm-scheme 401 2 : HMAC-SM3 : hmac-sm3

View File

@@ -1,5 +1,5 @@
/* ====================================================================
* Copyright (c) 2016 The GmSSL Project. All rights reserved.
* Copyright (c) 2016 - 2018 The GmSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -47,9 +47,284 @@
* ====================================================================
*/
#include <string.h>
#include <openssl/evp.h>
#include <openssl/err.h>
#include <openssl/sm2.h>
#include <openssl/sm9.h>
#include "sm9_lcl.h"
int SM9_unwrap_key(int type,
unsigned char *key, size_t keylen,
const unsigned char *enced_key, size_t enced_len,
SM9PrivateKey *sk)
{
int ret = 0;
EC_GROUP *group = NULL;
EC_POINT *C = NULL;
EVP_MD_CTX *md_ctx = NULL;
BN_CTX *bn_ctx = NULL;
point_t de;
fp12_t w;
const BIGNUM *p = SM9_get0_prime();
const EVP_MD *kdf_md;
unsigned char wbuf[384];
unsigned char *out = key;
size_t outlen = keylen;
unsigned char counter[4] = {0, 0, 0, 1};
unsigned char dgst[64];
unsigned int len;
switch (type) {
case NID_sm9kdf_with_sm3:
kdf_md = EVP_sm3();
break;
case NID_sm9kdf_with_sha256:
kdf_md = EVP_sha256();
break;
default:
return 0;
}
/* malloc */
if (!(group = EC_GROUP_new_by_curve_name(NID_sm9bn256v1))
|| !(C = EC_POINT_new(group))
|| !(md_ctx = EVP_MD_CTX_new())
|| !(bn_ctx = BN_CTX_new())) {
SM9err(SM9_F_SM9_UNWRAP_KEY, ERR_R_MALLOC_FAILURE);
goto end;
}
BN_CTX_start(bn_ctx);
if (!point_init(&de, bn_ctx) || !fp12_init(w, bn_ctx)) {
SM9err(SM9_F_SM9_UNWRAP_KEY, ERR_R_MALLOC_FAILURE);
goto end;
}
/* parse C on E(F_p) */
if (!EC_POINT_oct2point(group, C, enced_key, enced_len, bn_ctx)) {
SM9err(SM9_F_SM9_UNWRAP_KEY, ERR_R_MALLOC_FAILURE);
goto end;
}
/* parse de on E'(E_p^2) */
if (!point_from_octets(&de, ASN1_STRING_get0_data(sk->privatePoint), p, bn_ctx)) {
SM9err(SM9_F_SM9_UNWRAP_KEY, ERR_R_MALLOC_FAILURE);
goto end;
}
/* w = e(C, de) */
if (!rate_pairing(w, &de, C, bn_ctx)) {
SM9err(SM9_F_SM9_UNWRAP_KEY, ERR_R_MALLOC_FAILURE);
goto end;
}
if (!fp12_to_bin(w, wbuf)) {
SM9err(SM9_F_SM9_UNWRAP_KEY, ERR_R_MALLOC_FAILURE);
goto end;
}
/* K = KDF(C||w||ID_B, klen) */
while (outlen > 0) {
if (!EVP_DigestInit_ex(md_ctx, kdf_md, NULL)
|| !EVP_DigestUpdate(md_ctx, enced_key + 1, enced_len - 1)
|| !EVP_DigestUpdate(md_ctx, wbuf, sizeof(wbuf))
|| !EVP_DigestUpdate(md_ctx, ASN1_STRING_get0_data(sk->identity), ASN1_STRING_length(sk->identity))
|| !EVP_DigestUpdate(md_ctx, counter, sizeof(counter))
|| !EVP_DigestFinal_ex(md_ctx, dgst, &len)) {
SM9err(SM9_F_SM9_UNWRAP_KEY, ERR_R_EVP_LIB);
goto end;
}
if (len > outlen)
len = outlen;
memcpy(out, dgst, len);
out += len;
outlen -= len;
counter[3]++;
}
ret = 1;
end:
EC_GROUP_free(group);
EC_POINT_free(C);
EVP_MD_CTX_free(md_ctx);
fp12_cleanup(w);
point_cleanup(&de);
if (bn_ctx) {
BN_CTX_end(bn_ctx);
}
BN_CTX_free(bn_ctx);
return ret;
}
int SM9_wrap_key(int type, /* NID_sm9kdf_with_sm3 */
unsigned char *key, size_t keylen,
unsigned char *enced_key, size_t *enced_len,
SM9PublicParameters *mpk, const char *id, size_t idlen)
{
int ret = 0;
EC_GROUP *group = NULL;
EC_POINT *Ppube = NULL;
EC_POINT *C = NULL;
EVP_MD_CTX *md_ctx = NULL;
BN_CTX *bn_ctx = NULL;
BIGNUM *r = NULL;
BIGNUM *h = NULL;
fp12_t w;
const EVP_MD *kdf_md;
const EVP_MD *hash1_md;
const BIGNUM *p = SM9_get0_prime();
const BIGNUM *n = SM9_get0_order();
unsigned char cbuf[65];
unsigned char wbuf[384];
unsigned char dgst[64];
int all;
switch (type) {
case NID_sm9kdf_with_sm3:
kdf_md = EVP_sm3();
break;
case NID_sm9kdf_with_sha256:
kdf_md = EVP_sha256();
break;
default:
SM9err(SM9_F_SM9_WRAP_KEY, SM9_R_INVALID_DIGEST_TYPE);
return 0;
}
if (keylen > EVP_MD_size(kdf_md) * 255) {
SM9err(SM9_F_SM9_WRAP_KEY, SM9_R_INVALID_KEM_KEY_LENGTH);
return 0;
}
if (!(group = EC_GROUP_new_by_curve_name(NID_sm9bn256v1))
|| !(Ppube = EC_POINT_new(group))
|| !(C = EC_POINT_new(group))
|| !(md_ctx = EVP_MD_CTX_new())
|| !(bn_ctx = BN_CTX_new())) {
SM9err(SM9_F_SM9_WRAP_KEY, ERR_R_MALLOC_FAILURE);
goto end;
}
BN_CTX_start(bn_ctx);
if (!(r = BN_CTX_get(bn_ctx)) || !fp12_init(w, bn_ctx)) {
SM9err(SM9_F_SM9_WRAP_KEY, ERR_R_MALLOC_FAILURE);
goto end;
}
/* parse Ppube */
if (!EC_POINT_oct2point(group, Ppube, ASN1_STRING_get0_data(mpk->pointPpub),
ASN1_STRING_length(mpk->pointPpub), bn_ctx)) {
SM9err(SM9_F_SM9_WRAP_KEY, SM9_R_INVALID_POINTPPUB);
goto end;
}
/* g = e(Ppube, P2) */
if (!rate_pairing(w, NULL, Ppube, bn_ctx)) {
SM9err(SM9_F_SM9_WRAP_KEY, SM9_R_RATE_PAIRING_ERROR);
goto end;
}
switch (OBJ_obj2nid(mpk->hash1)) {
case NID_sm9hash1_with_sm3:
hash1_md = EVP_sm3();
break;
case NID_sm9hash1_with_sha256:
hash1_md = EVP_sha256();
break;
default:
SM9err(SM9_F_SM9_WRAP_KEY, ERR_R_SM9_LIB);
goto end;
}
/* parse Q_B = H1(ID_B||hid) * P1 + Ppube */
// we should check mpk->hash1
if (!SM9_hash1(hash1_md, &h, id, idlen, SM9_HID_ENC, n, bn_ctx)
|| !EC_POINT_mul(group, C, h, NULL, NULL, bn_ctx)
|| !EC_POINT_add(group, C, C, Ppube, bn_ctx)) {
ERR_print_errors_fp(stderr);
SM9err(SM9_F_SM9_WRAP_KEY, ERR_R_EC_LIB);
goto end;
}
do {
unsigned char *out = key;
size_t outlen = keylen;
unsigned char counter[4] = {0, 0, 0, 1};
unsigned int len;
/* r = rand([1, n-1]) */
do {
if (!BN_rand_range(r, n)) {
goto end;
}
} while (BN_is_zero(r));
/* C = r * Q_B */
if (!EC_POINT_mul(group, C, NULL, C, r, bn_ctx)
|| EC_POINT_point2oct(group, C, POINT_CONVERSION_UNCOMPRESSED,
cbuf, sizeof(cbuf), bn_ctx) != sizeof(cbuf)) {
SM9err(SM9_F_SM9_WRAP_KEY, ERR_R_EC_LIB);
goto end;
}
/* w = g^r */
if (!fp12_pow(w, w, r, p, bn_ctx) || !fp12_to_bin(w, wbuf)) {
SM9err(SM9_F_SM9_WRAP_KEY, SM9_R_EXTENSION_FIELD_ERROR);
goto end;
}
/* K = KDF(C||w||ID_B, klen) */
while (outlen > 0) {
if (!EVP_DigestInit_ex(md_ctx, kdf_md, NULL)
|| !EVP_DigestUpdate(md_ctx, cbuf + 1, sizeof(cbuf) - 1)
|| !EVP_DigestUpdate(md_ctx, wbuf, sizeof(wbuf))
|| !EVP_DigestUpdate(md_ctx, id, idlen)
|| !EVP_DigestUpdate(md_ctx, counter, sizeof(counter))
|| !EVP_DigestFinal_ex(md_ctx, dgst, &len)) {
SM9err(SM9_F_SM9_WRAP_KEY, ERR_R_EVP_LIB);
goto end;
}
if (len > outlen)
len = outlen;
memcpy(out, dgst, len);
out += len;
outlen -= len;
counter[3]++;
}
all = 0;
for (len = 0; len < keylen; len++) {
all |= key[len];
}
} while (all == 0);
memcpy(enced_key, cbuf, sizeof(cbuf));
*enced_len = sizeof(cbuf);
ret = 1;
end:
EC_GROUP_free(group);
EC_POINT_free(Ppube);
EC_POINT_free(C);
EVP_MD_CTX_free(md_ctx);
if (bn_ctx) {
BN_CTX_end(bn_ctx);
}
BN_free(r);
BN_free(h);
BN_CTX_free(bn_ctx);
OPENSSL_cleanse(cbuf, sizeof(cbuf));
OPENSSL_cleanse(wbuf, sizeof(wbuf));
OPENSSL_cleanse(dgst, sizeof(dgst));
return ret;
}
int SM9_encrypt(int type,
const unsigned char *in, size_t inlen,
unsigned char *out, size_t *outlen,

View File

@@ -42,7 +42,7 @@ static ERR_STRING_DATA SM9_str_functs[] = {
{ERR_FUNC(SM9_F_SM9_SIGNINIT), "SM9_SignInit"},
{ERR_FUNC(SM9_F_SM9_UNWRAP_KEY), "SM9_unwrap_key"},
{ERR_FUNC(SM9_F_SM9_VERIFY), "SM9_verify"},
{ERR_FUNC(SM9_F_SM9_VERIFYFINAL), "SM9_VerifyFInal"},
{ERR_FUNC(SM9_F_SM9_VERIFYFINAL), "SM9_VerifyFinal"},
{ERR_FUNC(SM9_F_SM9_VERIFYINIT), "SM9_VerifyInit"},
{ERR_FUNC(SM9_F_SM9_WRAP_KEY), "SM9_wrap_key"},
{0, NULL}
@@ -56,12 +56,14 @@ static ERR_STRING_DATA SM9_str_reasons[] = {
{ERR_REASON(SM9_R_GENERATE_MAC_FAILURE), "generate mac failure"},
{ERR_REASON(SM9_R_HASH_FAILURE), "hash failure"},
{ERR_REASON(SM9_R_INVALID_CIPHERTEXT), "invalid ciphertext"},
{ERR_REASON(SM9_R_INVALID_DIGEST_TYPE), "invalid digest type"},
{ERR_REASON(SM9_R_INVALID_ENCPARAMETERS), "invalid encparameters"},
{ERR_REASON(SM9_R_INVALID_HASH1), "invalid hash1"},
{ERR_REASON(SM9_R_INVALID_HASH2_DIGEST), "invalid hash2 digest"},
{ERR_REASON(SM9_R_INVALID_ID), "invalid id"},
{ERR_REASON(SM9_R_INVALID_ID_LENGTH), "invalid id length"},
{ERR_REASON(SM9_R_INVALID_INPUT), "invalid input"},
{ERR_REASON(SM9_R_INVALID_KEM_KEY_LENGTH), "invalid kem key length"},
{ERR_REASON(SM9_R_INVALID_KEY_LENGTH), "invalid key length"},
{ERR_REASON(SM9_R_INVALID_MD), "invalid md"},
{ERR_REASON(SM9_R_INVALID_PAIRING_TYPE), "invalid pairing type"},
@@ -74,6 +76,7 @@ static ERR_STRING_DATA SM9_str_reasons[] = {
{ERR_REASON(SM9_R_INVALID_TYPE1CURVE), "invalid type1curve"},
{ERR_REASON(SM9_R_KDF_FAILURE), "kdf failure"},
{ERR_REASON(SM9_R_PAIRING_ERROR), "pairing error"},
{ERR_REASON(SM9_R_RATE_PAIRING_ERROR), "rate pairing error"},
{ERR_REASON(SM9_R_TWIST_CURVE_ERROR), "twist curve error"},
{ERR_REASON(SM9_R_VERIFY_FAILURE), "verify failure"},
{ERR_REASON(SM9_R_ZERO_ID), "zero id"},

View File

@@ -2514,10 +2514,29 @@ int rate_pairing(fp12_t r, const point_t *Q, const EC_POINT *P, BN_CTX *ctx)
xP = BN_CTX_get(ctx);
yP = BN_CTX_get(ctx);
EC_POINT_get_affine_coordinates_GFp(group, P, xP, yP, ctx);
if (!P) {
EC_POINT_get_affine_coordinates_GFp(group,
EC_GROUP_get0_generator(group), xP, yP, ctx);
} else {
EC_POINT_get_affine_coordinates_GFp(group, P, xP, yP, ctx);
}
if (!Q) {
point_t P2;
point_init(&P2, ctx);
point_set_affine_coordinates_bignums(&P2,
SM9_get0_generator2_x0(),
SM9_get0_generator2_x1(),
SM9_get0_generator2_y0(),
SM9_get0_generator2_y1());
rate(r, &P2, xP, yP, a, k, p, ctx);
point_cleanup(&P2);
} else {
rate(r, Q, xP, yP, a, k, p, ctx);
}
rate(r, Q, xP, yP, a, k, p, ctx);
BN_free(xP);
BN_free(yP);
return ret;