mirror of
https://github.com/guanzhi/GmSSL.git
synced 2026-08-07 21:53:41 +08:00
update
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
#
|
||||
# crypto/ecies/Makefile
|
||||
# crypto/sm2/Makefile
|
||||
#
|
||||
|
||||
DIR= sm2
|
||||
@@ -23,7 +23,7 @@ LIBOBJ= sm2_dgst.o sm2_enc.o
|
||||
|
||||
SRC= $(LIBSRC)
|
||||
|
||||
EXHEADER= sm2_enc.h
|
||||
EXHEADER= sm2.h
|
||||
HEADER= $(EXHEADER)
|
||||
|
||||
ALL= $(GENERAL) $(SRC) $(HEADER)
|
||||
|
||||
89
crypto/sm2/sm2.h
Normal file
89
crypto/sm2/sm2.h
Normal file
@@ -0,0 +1,89 @@
|
||||
#ifndef HEADER_SM2_H
|
||||
#define HEADER_SM2_H
|
||||
|
||||
#include <openssl/ec.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/x509.h>
|
||||
#include <openssl/asn1.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define SM2_DEFAULT_POINT_CONVERSION_FORM 0
|
||||
|
||||
|
||||
typedef struct sm2_ciphertext_value_st {
|
||||
EC_POINT *ephem_point;
|
||||
unsigned char *ciphertext;
|
||||
size_t ciphertext_size;
|
||||
unsigned char mactag[EVP_MAX_MD_SIZE];
|
||||
unsigned int mactag_size;
|
||||
} SM2_CIPHERTEXT_VALUE;
|
||||
|
||||
|
||||
int SM2_compute_za(unsigned char *za, const EVP_MD *md,
|
||||
const void *id, size_t idlen, EC_KEY *ec_key);
|
||||
|
||||
int SM2_compute_digest(unsigned char *dgst, unsigned int *dgstlen,
|
||||
const EVP_MD *za_md, const void *id, size_t idlen, EC_KEY *ec_key,
|
||||
const EVP_MD *msg_md, const void *msg, size_t msglen);
|
||||
|
||||
int SM2_CIPHERTEXT_VALUE_size(const EC_GROUP *ec_group,
|
||||
point_conversion_form_t point_form, size_t mlen,
|
||||
const EVP_MD *mac_md);
|
||||
|
||||
void SM2_CIPHERTEXT_VALUE_free(SM2_CIPHERTEXT_VALUE *cv);
|
||||
|
||||
int SM2_CIPHERTEXT_VALUE_encode(const SM2_CIPHERTEXT_VALUE *cv,
|
||||
const EC_GROUP *ec_group, point_conversion_form_t point_form,
|
||||
unsigned char *buf, size_t *buflen);
|
||||
|
||||
SM2_CIPHERTEXT_VALUE *SM2_CIPHERTEXT_VALUE_decode(const EC_GROUP *ec_group,
|
||||
point_conversion_form_t point_form, const EVP_MD *mac_md,
|
||||
const unsigned char *buf, size_t buflen);
|
||||
|
||||
int SM2_CIPHERTEXT_VALUE_print(BIO *out, const SM2_CIPHERTEXT_VALUE *cv,
|
||||
int indent, unsigned long flags);
|
||||
|
||||
SM2_CIPHERTEXT_VALUE *SM2_do_encrypt(const EVP_MD *kdf_md, const EVP_MD *mac_md,
|
||||
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,
|
||||
const SM2_CIPHERTEXT_VALUE *cv, unsigned char *out, size_t *outlen,
|
||||
EC_KEY *ec_key);
|
||||
|
||||
int SM2_encrypt(const EVP_MD *kdf_md, const EVP_MD *mac_md,
|
||||
point_conversion_form_t point_form, unsigned char *out, size_t *outlen,
|
||||
const unsigned char *in, size_t inlen, EC_KEY *ec_key);
|
||||
|
||||
int SM2_decrypt(const EVP_MD *kdf_md, const EVP_MD *mac_md,
|
||||
point_conversion_form_t point_form, const unsigned char *in,
|
||||
size_t inlen, unsigned char *out, size_t *outlen, EC_KEY *ec_key);
|
||||
|
||||
void ERR_load_SM2_strings(void);
|
||||
|
||||
/* Error codes for the ECIES functions. */
|
||||
|
||||
/* Function codes. */
|
||||
#define SM2_F_SM2_DO_ENCRYPT 100
|
||||
#define SM2_F_SM2_DO_DECRYPT 101
|
||||
#define SM2_F_SM2_CIPHERTEXT_VALUE_FREE 102
|
||||
|
||||
/* Reason codes. */
|
||||
#define SM2_R_BAD_DATA 100
|
||||
#define SM2_R_UNKNOWN_CIPHER_TYPE 101
|
||||
#define SM2_R_ENCRYPT_FAILED 102
|
||||
#define SM2_R_DECRYPT_FAILED 103
|
||||
#define SM2_R_UNKNOWN_MAC_TYPE 104
|
||||
#define SM2_R_GEN_MAC_FAILED 105
|
||||
#define SM2_R_VERIFY_MAC_FAILED 106
|
||||
#define SM2_R_ECDH_FAILED 107
|
||||
#define SM2_R_BUFFER_TOO_SMALL 108
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -5,25 +5,29 @@
|
||||
#include <openssl/bn.h>
|
||||
#include <openssl/ec.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/rand.h>
|
||||
|
||||
|
||||
#define EC_MAX_NBYTES ((OPENSSL_ECC_MAX_FIELD_BITS + 7)/8)
|
||||
|
||||
#define SM2_MAX_ID_LENGTH 4096
|
||||
|
||||
/*
|
||||
* pkdata = a || b || G.x || G.y || P.x || P.y
|
||||
*/
|
||||
static int sm2_get_public_key_data(unsigned char *buf, EC_KEY *ec_key)
|
||||
{
|
||||
int ret = -1;
|
||||
int nbytes = (EC_GROUP_get_degree(ec_group) + 7) / 8;
|
||||
const EC_GROUP *ec_group = EC_KEY_get0_group(ec_key);
|
||||
const EC_POINT *point;
|
||||
int nbytes = (EC_GROUP_get_degree(ec_group) + 7) / 8;
|
||||
unsigned char oct[EC_MAX_NBYTES * 2 + 1];
|
||||
BN_CTX *ctx = NULL;
|
||||
BN_CTX *bn_ctx = NULL;
|
||||
BIGNUM *p = NULL;
|
||||
BIGNUM *x = NULL;
|
||||
BIGNUM *y = NULL;
|
||||
size_t len;
|
||||
|
||||
OPENSSL_assert(ec_key);
|
||||
OPENSSL_assert(nbytes == 256/8);
|
||||
@@ -33,16 +37,16 @@ static int sm2_get_public_key_data(unsigned char *buf, EC_KEY *ec_key)
|
||||
}
|
||||
bzero(buf, nbytes * 6);
|
||||
|
||||
ctx = BN_CTX_new();
|
||||
bn_ctx = BN_CTX_new();
|
||||
p = BN_new();
|
||||
x = BN_new();
|
||||
y = BN_new();
|
||||
if (!ctx || !p || !x || !y) {
|
||||
if (!bn_ctx || !p || !x || !y) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* get curve coefficients a, b */
|
||||
if (!EC_GROUP_get_curve_GFp(ec_group, p, x, y, ctx)) {
|
||||
if (!EC_GROUP_get_curve_GFp(ec_group, p, x, y, bn_ctx)) {
|
||||
goto err;
|
||||
}
|
||||
buf += nbytes;
|
||||
@@ -80,7 +84,7 @@ static int sm2_get_public_key_data(unsigned char *buf, EC_KEY *ec_key)
|
||||
|
||||
ret = (nbytes * 6);
|
||||
err:
|
||||
if (ctx) BN_CTX_free(ctx);
|
||||
if (bn_ctx) BN_CTX_free(bn_ctx);
|
||||
if (p) BN_free(p);
|
||||
if (x) BN_free(x);
|
||||
if (y) BN_free(y);
|
||||
@@ -88,42 +92,42 @@ err:
|
||||
return ret;
|
||||
}
|
||||
|
||||
int SM2_compute_za(unsigned char *za, const EVP_MD *md,
|
||||
const void *id, size_t idlen, EC_KEY *ec_key)
|
||||
int SM2_compute_za(unsigned char *za, unsigned int *zalen,
|
||||
const EVP_MD *md, const void *id, size_t idlen, EC_KEY *ec_key)
|
||||
{
|
||||
int ret = 0;
|
||||
EVP_MD_CTX *ctx = NULL;
|
||||
EVP_MD_CTX *md_ctx = NULL;
|
||||
unsigned char pkdata[EC_MAX_NBYTES * 6];
|
||||
uint16_t idbits;
|
||||
int len;
|
||||
idbits = cpu_to_be16(idlen * 8);
|
||||
|
||||
uint16_t idbits = idlen * 8;
|
||||
int pkdatalen;
|
||||
|
||||
if ((pkdatalen = sm2_get_public_key_data(pkdata, ec_key)) < 0) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (!(ctx = EVP_MD_CTX_create())) {
|
||||
if (!(md_ctx = EVP_MD_CTX_create())) {
|
||||
goto err;
|
||||
}
|
||||
if (!EVP_DigestInit_ex(ctx, md, NULL)) {
|
||||
goto end;
|
||||
if (!EVP_DigestInit_ex(md_ctx, md, NULL)) {
|
||||
goto err;
|
||||
}
|
||||
if (!EVP_DigestUpdate(ctx, &idbits, sizeof(idbits))) {
|
||||
goto end;
|
||||
if (!EVP_DigestUpdate(md_ctx, &idbits, sizeof(idbits))) {
|
||||
goto err;
|
||||
}
|
||||
if (!EVP_DigestUpdate(ctx, id, idlen)) {
|
||||
goto end;
|
||||
if (!EVP_DigestUpdate(md_ctx, id, idlen)) {
|
||||
goto err;
|
||||
}
|
||||
if (!EVP_DigestUpdate(ctx, pkdata, pkdatalen)) {
|
||||
goto end;
|
||||
if (!EVP_DigestUpdate(md_ctx, pkdata, pkdatalen)) {
|
||||
goto err;
|
||||
}
|
||||
if (!EVP_DigestFinal(ctx, za, &zalen)) {
|
||||
if (!EVP_DigestFinal(md_ctx, za, zalen)) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
ret = SM3_DIGEST_LENGTH;
|
||||
ret = 1;
|
||||
|
||||
err:
|
||||
if (ctx) EVP_MD_CTX_destroy(ctx);
|
||||
if (md_ctx) EVP_MD_CTX_destroy(md_ctx);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -133,14 +137,14 @@ int SM2_compute_digest(unsigned char *dgst, unsigned int *dgstlen,
|
||||
{
|
||||
int ret = 0;
|
||||
unsigned char za[EVP_MAX_MD_SIZE];
|
||||
int zalen;
|
||||
unsigned int zalen;
|
||||
EVP_MD_CTX *ctx = NULL;
|
||||
|
||||
/* compute Za */
|
||||
if (idlen > SM2_MAX_ID_LENGTH) {
|
||||
goto err;
|
||||
}
|
||||
if ((zalen = SM2_compute_za(za, za_md, id, idlen, ec_key)) < 0) {
|
||||
if (!SM2_compute_za(za, &zalen, za_md, id, idlen, ec_key)) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
|
||||
@@ -6,10 +6,36 @@
|
||||
#include <openssl/ec.h>
|
||||
#include <openssl/ecdsa.h>
|
||||
#include <openssl/rand.h>
|
||||
#include <oepnssl/kdf.h>
|
||||
#include "sm2_enc.h"
|
||||
#include <openssl/kdf.h>
|
||||
#include "sm2.h"
|
||||
|
||||
void SM2_CIPEHRTEXT_VALUE_free(SM2_CIPHERTEXT_VALUE *cv)
|
||||
int SM2_CIPHERTEXT_VALUE_size(const EC_GROUP *ec_group,
|
||||
point_conversion_form_t point_form, size_t mlen,
|
||||
const EVP_MD *mac_md)
|
||||
{
|
||||
int ret = 0;
|
||||
EC_POINT *point = EC_POINT_new(ec_group);
|
||||
BN_CTX *bn_ctx = BN_CTX_new();
|
||||
size_t len;
|
||||
|
||||
if (!point || !bn_ctx) {
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (!(len = EC_POINT_point2oct(ec_group, point, point_form,
|
||||
NULL, 0, bn_ctx))) {
|
||||
goto end;
|
||||
}
|
||||
len += mlen + EVP_MD_size(mac_md);
|
||||
|
||||
ret = len;
|
||||
end:
|
||||
if (point) EC_POINT_free(point);
|
||||
if (bn_ctx) BN_CTX_free(bn_ctx);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void SM2_CIPHERTEXT_VALUE_free(SM2_CIPHERTEXT_VALUE *cv)
|
||||
{
|
||||
if (cv->ephem_point) EC_POINT_free(cv->ephem_point);
|
||||
if (cv->ciphertext) OPENSSL_free(cv->ciphertext);
|
||||
@@ -17,9 +43,141 @@ void SM2_CIPEHRTEXT_VALUE_free(SM2_CIPHERTEXT_VALUE *cv)
|
||||
OPENSSL_free(cv);
|
||||
}
|
||||
|
||||
SM2_CIPHERTEXT_VALUE *SM2_do_encrypt(
|
||||
const EVP_MD *kdf_md, const EVP_MD *mac_md,
|
||||
const void *in, size_t inlen, const EC_KEY *ec_key);
|
||||
int SM2_CIPHERTEXT_VALUE_encode(const SM2_CIPHERTEXT_VALUE *cv,
|
||||
const EC_GROUP *ec_group, point_conversion_form_t point_form,
|
||||
unsigned char *buf, size_t *buflen)
|
||||
{
|
||||
int ret = 0;
|
||||
BN_CTX *bn_ctx = BN_CTX_new();
|
||||
size_t ptlen, cvlen;
|
||||
|
||||
if (!bn_ctx) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!(ptlen = EC_POINT_point2oct(ec_group, cv->ephem_point,
|
||||
point_form, NULL, 0, bn_ctx))) {
|
||||
goto end;
|
||||
}
|
||||
cvlen = ptlen + cv->ciphertext_size + cv->mactag_size;
|
||||
|
||||
if (!buf) {
|
||||
*buflen = cvlen;
|
||||
ret = 1;
|
||||
goto end;
|
||||
|
||||
} else if (*buflen < cvlen) {
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (!(ptlen = EC_POINT_point2oct(ec_group, cv->ephem_point,
|
||||
point_form, buf, *buflen, bn_ctx))) {
|
||||
goto end;
|
||||
}
|
||||
buf += ptlen;
|
||||
memcpy(buf, cv->ciphertext, cv->ciphertext_size);
|
||||
buf += cv->ciphertext_size;
|
||||
memcpy(buf, cv->mactag, cv->mactag_size);
|
||||
|
||||
*buflen = cvlen;
|
||||
ret = 1;
|
||||
end:
|
||||
if (bn_ctx) BN_CTX_free(bn_ctx);
|
||||
return ret;
|
||||
}
|
||||
|
||||
SM2_CIPHERTEXT_VALUE *SM2_CIPHERTEXT_VALUE_decode(const EC_GROUP *ec_group,
|
||||
point_conversion_form_t point_form, const EVP_MD *mac_md,
|
||||
const unsigned char *buf, size_t buflen)
|
||||
{
|
||||
int ok = 0;
|
||||
SM2_CIPHERTEXT_VALUE *ret = NULL;
|
||||
BN_CTX *bn_ctx = NULL;
|
||||
int len = SM2_CIPHERTEXT_VALUE_size(ec_group, point_form, 0, mac_md);
|
||||
int ptlen = len - EVP_MD_size(mac_md);
|
||||
|
||||
if (!(len = SM2_CIPHERTEXT_VALUE_size(ec_group, point_form, 0, mac_md))) {
|
||||
goto end;
|
||||
}
|
||||
if (buflen <= len) {
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (!(ret = OPENSSL_malloc(sizeof(SM2_CIPHERTEXT_VALUE)))) {
|
||||
goto end;
|
||||
}
|
||||
|
||||
ret->ephem_point = EC_POINT_new(ec_group);
|
||||
ret->ciphertext_size = buflen - len;
|
||||
ret->ciphertext = OPENSSL_malloc(ret->ciphertext_size);
|
||||
if (!ret->ephem_point || !ret->ciphertext) {
|
||||
goto end;
|
||||
}
|
||||
if (!(bn_ctx = BN_CTX_new())) {
|
||||
goto end;
|
||||
}
|
||||
if (!EC_POINT_oct2point(ec_group, ret->ephem_point, buf, len, bn_ctx)) {
|
||||
goto end;
|
||||
}
|
||||
memcpy(ret->ciphertext, buf + ptlen, ret->ciphertext_size);
|
||||
ret->mactag_size = EVP_MD_size(mac_md);
|
||||
memcpy(ret->mactag, buf + buflen - ret->mactag_size, ret->mactag_size);
|
||||
|
||||
ok = 1;
|
||||
|
||||
end:
|
||||
if (!ok && ret) {
|
||||
SM2_CIPHERTEXT_VALUE_free(ret);
|
||||
ret = NULL;
|
||||
}
|
||||
if (bn_ctx) BN_CTX_free(bn_ctx);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int SM2_CIPHERTEXT_VALUE_print(BIO *out, const SM2_CIPHERTEXT_VALUE *cv,
|
||||
int indent, unsigned long flags)
|
||||
{
|
||||
OPENSSL_assert(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int SM2_encrypt(const EVP_MD *kdf_md, const EVP_MD *mac_md,
|
||||
point_conversion_form_t point_form, unsigned char *out, size_t *outlen,
|
||||
const unsigned char *in, size_t inlen, EC_KEY *ec_key)
|
||||
{
|
||||
int ret = 0;
|
||||
const EC_GROUP *ec_group = EC_KEY_get0_group(ec_key);
|
||||
SM2_CIPHERTEXT_VALUE *cv = NULL;
|
||||
int len;
|
||||
|
||||
if (!(len = SM2_CIPHERTEXT_VALUE_size(ec_group, point_form, inlen, mac_md))) {
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (!out) {
|
||||
*outlen = (size_t)len;
|
||||
return 1;
|
||||
|
||||
} else if (*outlen < (size_t)len) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!(cv = SM2_do_encrypt(kdf_md, mac_md, in, inlen, ec_key))) {
|
||||
goto end;
|
||||
}
|
||||
if (!SM2_CIPHERTEXT_VALUE_encode(cv, ec_group, point_form, out, outlen)) {
|
||||
goto end;
|
||||
}
|
||||
|
||||
ret = 1;
|
||||
end:
|
||||
if (cv) SM2_CIPHERTEXT_VALUE_free(cv);
|
||||
return ret;
|
||||
}
|
||||
|
||||
SM2_CIPHERTEXT_VALUE *SM2_do_encrypt(const EVP_MD *kdf_md, const EVP_MD *mac_md,
|
||||
const unsigned char *in, size_t inlen, EC_KEY *ec_key)
|
||||
{
|
||||
int ok = 0;
|
||||
SM2_CIPHERTEXT_VALUE *cv = NULL;
|
||||
@@ -34,25 +192,26 @@ SM2_CIPHERTEXT_VALUE *SM2_do_encrypt(
|
||||
EVP_MD_CTX *md_ctx = NULL;
|
||||
unsigned char buf[(OPENSSL_ECC_MAX_FIELD_BITS + 7)/4 + 1];
|
||||
int nbytes;
|
||||
size_t len;
|
||||
int i;
|
||||
|
||||
if (!ec_group || !pub_key) {
|
||||
goto err;
|
||||
goto end;
|
||||
}
|
||||
if (!kdf) {
|
||||
goto err;
|
||||
goto end;
|
||||
}
|
||||
|
||||
/* init ciphertext_value */
|
||||
if (!(cv = OPENSSL_malloc(sizeof(SM2_CIPHERTEXT_VALUE)))) {
|
||||
goto err;
|
||||
goto end;
|
||||
}
|
||||
bzero(cv, sizeof(SM2_CIPHERTEXT_VALUE));
|
||||
cv->ephem_point = EC_POINT_new(ec_group);
|
||||
cv->ciphertext = OPENSSL_malloc(inlen);
|
||||
cv->ciphertext_size = inlen;
|
||||
if (!cv->ephem_point || !cv->ciphertext) {
|
||||
goto err;
|
||||
goto end;
|
||||
}
|
||||
|
||||
point = EC_POINT_new(ec_group);
|
||||
@@ -62,17 +221,17 @@ SM2_CIPHERTEXT_VALUE *SM2_do_encrypt(
|
||||
bn_ctx = BN_CTX_new();
|
||||
md_ctx = EVP_MD_CTX_create();
|
||||
if (!point || !n || !h || !k || !bn_ctx || !md_ctx) {
|
||||
goto err;
|
||||
goto end;
|
||||
}
|
||||
|
||||
/* init ec domain parameters */
|
||||
if (!EC_GROUP_get_order(ec_group, n, bn_ctx)) {
|
||||
goto err;
|
||||
goto end;
|
||||
}
|
||||
if (!EC_GROUP_get_cofactor(ec_group, h, bn_ctx)) {
|
||||
goto err;
|
||||
goto end;
|
||||
}
|
||||
nbytes = (EC_GROPU_get_degree(ec_group) + 7) / 8;
|
||||
nbytes = (EC_GROUP_get_degree(ec_group) + 7) / 8;
|
||||
OPENSSL_assert(nbytes == BN_num_bytes(n));
|
||||
|
||||
/* check sm2 curve and md is 256 bits */
|
||||
@@ -89,24 +248,24 @@ SM2_CIPHERTEXT_VALUE *SM2_do_encrypt(
|
||||
|
||||
/* A2: C1 = [k]G = (x1, y1) */
|
||||
if (!EC_POINT_mul(ec_group, cv->ephem_point, k, NULL, NULL, bn_ctx)) {
|
||||
goto err;
|
||||
goto end;
|
||||
}
|
||||
|
||||
/* A3: check [h]P_B != O */
|
||||
if (!EC_POINT_mul(ec_group, point, NULL, pub_key, h, bn_ctx)) {
|
||||
goto err;
|
||||
goto end;
|
||||
}
|
||||
if (EC_POINT_is_at_infinity(ec_group, point)) {
|
||||
goto err;
|
||||
goto end;
|
||||
}
|
||||
|
||||
/* A4: compute ECDH [k]P_B = (x2, y2) */
|
||||
if (!EC_POINT_mul(ec_group, point, NULL, pub_key, k, bn_ctx)) {
|
||||
goto err;
|
||||
goto end;
|
||||
}
|
||||
if (!(len = EC_POINT_point2oct(ec_group, point,
|
||||
POINT_CONVERSION_UNCOMPRESSED, buf, sizeof(buf), bn_ctx))) {
|
||||
goto err;
|
||||
goto end;
|
||||
}
|
||||
OPENSSL_assert(len == nbytes * 2 + 1);
|
||||
|
||||
@@ -134,24 +293,24 @@ SM2_CIPHERTEXT_VALUE *SM2_do_encrypt(
|
||||
|
||||
/* A7: C3 = Hash(x2 || M || y2) */
|
||||
if (!EVP_DigestInit_ex(md_ctx, mac_md, NULL)) {
|
||||
goto err;
|
||||
goto end;
|
||||
}
|
||||
if (!EVP_DigestUpdate(md_ctx, buf + 1, nbytes)) {
|
||||
goto err;
|
||||
goto end;
|
||||
}
|
||||
if (!EVP_DigestUpdate(md_ctx, in, inlen)) {
|
||||
goto err;
|
||||
goto end;
|
||||
}
|
||||
if (!EVP_DigestUpdate(md_ctx, buf + 1 + nbytes, nbytes)) {
|
||||
goto err;
|
||||
goto end;
|
||||
}
|
||||
if (!EVP_DigestFinal_ex(md_ctx, cv->mactag, &cv->mactag_size)) {
|
||||
goto err;
|
||||
goto end;
|
||||
}
|
||||
|
||||
ok = 1;
|
||||
|
||||
err:
|
||||
end:
|
||||
if (!ok && cv) {
|
||||
SM2_CIPHERTEXT_VALUE_free(cv);
|
||||
cv = NULL;
|
||||
@@ -166,12 +325,47 @@ err:
|
||||
return cv;
|
||||
}
|
||||
|
||||
|
||||
int SM2_do_decrypt(const SM2_CIPHERTEXT_VALUE *cv,
|
||||
const EVP_MD *kdf_md, const EVP_MD *mac_md,
|
||||
unsigned char *out, size_t *outlen, EC_KEY *ec_key)
|
||||
int SM2_decrypt(const EVP_MD *kdf_md, const EVP_MD *mac_md,
|
||||
point_conversion_form_t point_form, const unsigned char *in,
|
||||
size_t inlen, unsigned char *out, size_t *outlen, EC_KEY *ec_key)
|
||||
{
|
||||
int ret = 0
|
||||
int ret = 0;
|
||||
const EC_GROUP *ec_group = EC_KEY_get0_group(ec_key);
|
||||
SM2_CIPHERTEXT_VALUE *cv = NULL;
|
||||
int len;
|
||||
|
||||
if (!(len = SM2_CIPHERTEXT_VALUE_size(ec_group, point_form, 0, mac_md))) {
|
||||
goto end;
|
||||
}
|
||||
if (inlen <= len) {
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (!out) {
|
||||
*outlen = inlen - len;
|
||||
return 1;
|
||||
} else if (outlen < inlen - len) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!(cv = SM2_CIPHERTEXT_VALUE_decode(ec_group, point_form, mac_md, in, inlen))) {
|
||||
goto end;
|
||||
}
|
||||
if (!SM2_do_decrypt(kdf_md, mac_md, cv, out, outlen, ec_key)) {
|
||||
goto end;
|
||||
}
|
||||
|
||||
ret = 1;
|
||||
end:
|
||||
if (cv) SM2_CIPHERTEXT_VALUE_free(cv);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int SM2_do_decrypt(const EVP_MD *kdf_md, const EVP_MD *mac_md,
|
||||
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);
|
||||
@@ -182,14 +376,16 @@ int SM2_do_decrypt(const SM2_CIPHERTEXT_VALUE *cv,
|
||||
EVP_MD_CTX *md_ctx = NULL;
|
||||
unsigned char buf[(OPENSSL_ECC_MAX_FIELD_BITS + 7)/4 + 1];
|
||||
unsigned char mac[EVP_MAX_MD_SIZE];
|
||||
unsigned int maclen;
|
||||
int nbytes;
|
||||
size_t size;
|
||||
int i;
|
||||
|
||||
if (!ec_group || !pub_key) {
|
||||
goto err;
|
||||
if (!ec_group || !pri_key) {
|
||||
goto end;
|
||||
}
|
||||
if (!kdf) {
|
||||
goto err;
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (!out) {
|
||||
@@ -197,7 +393,7 @@ int SM2_do_decrypt(const SM2_CIPHERTEXT_VALUE *cv,
|
||||
return 1;
|
||||
}
|
||||
if (*outlen < cv->ciphertext_size) {
|
||||
goto err;
|
||||
goto end;
|
||||
}
|
||||
|
||||
/* init vars */
|
||||
@@ -207,17 +403,17 @@ int SM2_do_decrypt(const SM2_CIPHERTEXT_VALUE *cv,
|
||||
bn_ctx = BN_CTX_new();
|
||||
md_ctx = EVP_MD_CTX_create();
|
||||
if (!point || !n || !h || !bn_ctx || !md_ctx) {
|
||||
goto err;
|
||||
goto end;
|
||||
}
|
||||
|
||||
/* init ec domain parameters */
|
||||
if (!EC_GROUP_get_order(ec_group, n, bn_ctx)) {
|
||||
goto err;
|
||||
goto end;
|
||||
}
|
||||
if (!EC_GROUP_get_cofactor(ec_group, h, bn_ctx)) {
|
||||
goto err;
|
||||
goto end;
|
||||
}
|
||||
nbytes = (EC_GROPU_get_degree(ec_group) + 7) / 8;
|
||||
nbytes = (EC_GROUP_get_degree(ec_group) + 7) / 8;
|
||||
OPENSSL_assert(nbytes == BN_num_bytes(n));
|
||||
|
||||
/* check sm2 curve and md is 256 bits */
|
||||
@@ -227,23 +423,23 @@ int SM2_do_decrypt(const SM2_CIPHERTEXT_VALUE *cv,
|
||||
|
||||
/* B2: check [h]C1 != O */
|
||||
if (!EC_POINT_mul(ec_group, point, NULL, cv->ephem_point, h, bn_ctx)) {
|
||||
goto err;
|
||||
goto end;
|
||||
}
|
||||
if (EC_POINT_is_at_infinity(ec_group, point)) {
|
||||
goto err;
|
||||
goto end;
|
||||
}
|
||||
|
||||
/* B3: compute ECDH [d]C1 = (x2, y2) */
|
||||
if (!EC_POINT_mul(ec_group, point, NULL, cv->ephem_point, pri_key, bn_ctx)) {
|
||||
goto err;
|
||||
goto end;
|
||||
}
|
||||
if (!(len = EC_POINT_point2oct(ec_group, point,
|
||||
if (!(size = EC_POINT_point2oct(ec_group, point,
|
||||
POINT_CONVERSION_UNCOMPRESSED, buf, sizeof(buf), bn_ctx))) {
|
||||
goto err;
|
||||
goto end;
|
||||
}
|
||||
|
||||
/* B4: compute t = KDF(x2 || y2, clen) */
|
||||
kdf(buf - 1, len - 1, out, outlen);
|
||||
kdf(buf - 1, size - 1, out, outlen);
|
||||
|
||||
|
||||
/* B5: compute M = C2 xor t */
|
||||
@@ -253,26 +449,27 @@ int SM2_do_decrypt(const SM2_CIPHERTEXT_VALUE *cv,
|
||||
|
||||
/* B6: check Hash(x2 || M || y2) == C3 */
|
||||
if (!EVP_DigestInit_ex(md_ctx, mac_md, NULL)) {
|
||||
goto err;
|
||||
goto end;
|
||||
}
|
||||
if (!EVP_DigestUpdate(md_ctx, buf + 1, nbytes)) {
|
||||
goto err;
|
||||
goto end;
|
||||
}
|
||||
if (!EVP_DigestUpdate(md_ctx, out, *outlen)) {
|
||||
goto err;
|
||||
goto end;
|
||||
}
|
||||
if (!EVP_DigestUpdate(md_ctx, buf + 1 + nbytes, nbytes)) {
|
||||
goto err;
|
||||
goto end;
|
||||
}
|
||||
if (!EVP_DigestFinal_ex(md_ctx, mac, &maclen)) {
|
||||
goto err;
|
||||
goto end;
|
||||
}
|
||||
if (cv->mactag_size != maclen || memcmp(cv->mactag, mac, maclen)) {
|
||||
goto err;
|
||||
if (cv->mactag_size != maclen ||
|
||||
memcmp(cv->mactag, mac, maclen)) {
|
||||
goto end;
|
||||
}
|
||||
|
||||
ret = 1;
|
||||
err:
|
||||
end:
|
||||
if (point) EC_POINT_free(point);
|
||||
if (n) BN_free(n);
|
||||
if (h) BN_free(h);
|
||||
|
||||
@@ -1,59 +0,0 @@
|
||||
#ifndef HEADER_SM2_ENC_H
|
||||
#define HEADER_SM2_ENC_H
|
||||
|
||||
#include <openssl/ec.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/x509.h>
|
||||
#include <openssl/asn1.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
typedef struct sm2_ciphertext_value_st {
|
||||
EC_POINT *ephem_point;
|
||||
unsigned char *ciphertext;
|
||||
size_t ciphertext_size;
|
||||
unsigned char mactag[EVP_MAX_MD_SIZE];
|
||||
size_t mactag_size;
|
||||
} SM2_CIPHERTEXT_VALUE;
|
||||
|
||||
|
||||
SM2_CIPHERTEXT_VALUE *SM2_do_encrypt(
|
||||
const EVP_MD *kdf_md, const EVP_MD *mac_md,
|
||||
const void *in, size_t inlen, const EC_KEY *pub_key);
|
||||
|
||||
int SM2_do_decrypt(const SM2_CIPHERTEXT_VALUE *cv,
|
||||
const EVP_MD *kdf_md, const EVP_MD *mac_md,
|
||||
unsigned char *out, size_t *outlen, EC_KEY *pri_key);
|
||||
|
||||
void SM2_CIPHERTEXT_VALUE_free(SM2_CIPHERTEXT_VALUE *cv);
|
||||
|
||||
|
||||
void ERR_load_SM2_strings(void);
|
||||
|
||||
/* Error codes for the ECIES functions. */
|
||||
|
||||
/* Function codes. */
|
||||
#define SM2_F_SM2_DO_ENCRYPT 100
|
||||
#define SM2_F_SM2_DO_DECRYPT 101
|
||||
#define SM2_F_SM2_CIPHERTEXT_VALUE_FREE 102
|
||||
|
||||
/* Reason codes. */
|
||||
#define SM2_R_BAD_DATA 100
|
||||
#define SM2_R_UNKNOWN_CIPHER_TYPE 101
|
||||
#define SM2_R_ENCRYPT_FAILED 102
|
||||
#define SM2_R_DECRYPT_FAILED 103
|
||||
#define SM2_R_UNKNOWN_MAC_TYPE 104
|
||||
#define SM2_R_GEN_MAC_FAILED 105
|
||||
#define SM2_R_VERIFY_MAC_FAILED 106
|
||||
#define SM2_R_ECDH_FAILED 107
|
||||
#define SM2_R_BUFFER_TOO_SMALL 108
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
41
crypto/sm2/sm2_err.c
Normal file
41
crypto/sm2/sm2_err.c
Normal file
@@ -0,0 +1,41 @@
|
||||
#include <stdio.h>
|
||||
#include <openssl/err.h>
|
||||
#include "sm2.h"
|
||||
|
||||
#ifndef OPENSSL_NO_ERR
|
||||
|
||||
#define ERR_FUNC(func) ERR_PACK(ERR_LIB_ECIES,func,0)
|
||||
#define ERR_REASON(reason) ERR_PACK(ERR_LIB_ECIES,0,reason)
|
||||
|
||||
|
||||
static ERR_STRING_DATA SM2_str_functs[] = {
|
||||
{ERR_FUNC(ECIES_F_ECIES_DO_ENCRYPT), "ECIES_do_encrypt"},
|
||||
{ERR_FUNC(ECIES_F_ECIES_DO_DECRYPT), "ECIES_do_decrypt"},
|
||||
{0,NULL}
|
||||
};
|
||||
|
||||
static ERR_STRING_DATA SM2_str_reasons[] = {
|
||||
{ERR_REASON(ECIES_R_BAD_DATA), "bad data"},
|
||||
{ERR_REASON(ECIES_R_UNKNOWN_CIPHER_TYPE),"unknown cipher type"},
|
||||
{ERR_REASON(ECIES_R_ENCRYPT_FAILED), "encrypt failed"},
|
||||
{ERR_REASON(ECIES_R_DECRYPT_FAILED), "decrypt failed"},
|
||||
{ERR_REASON(ECIES_R_UNKNOWN_MAC_TYPE), "unknown MAC type"},
|
||||
{ERR_REASON(ECIES_R_GEN_MAC_FAILED), "MAC generation failed"},
|
||||
{ERR_REASON(ECIES_R_VERIFY_MAC_FAILED), "MAC verification failed"},
|
||||
{ERR_REASON(ECIES_R_ECDH_FAILED), "ECDH failed"},
|
||||
{ERR_REASON(ECIES_R_BUFFER_TOO_SMALL), "buffer too small"},
|
||||
{0,NULL}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
void ERR_load_ECIES_strings(void)
|
||||
{
|
||||
#ifndef OPENSSL_NO_ERR
|
||||
|
||||
if (ERR_func_error_string(ECIES_str_functs[0].error) == NULL) {
|
||||
ERR_load_strings(0,ECIES_str_functs);
|
||||
ERR_load_strings(0,ECIES_str_reasons);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
Reference in New Issue
Block a user