mirror of
https://github.com/openssl/openssl.git
synced 2025-03-31 20:10:45 +08:00
Support setting SM2 ID
zero-length ID is allowed, but it's not allowed to skip the ID. Fixes: #6534 Reviewed-by: Tim Hudson <tjh@openssl.org> Reviewed-by: Matt Caswell <matt@openssl.org> (Merged from https://github.com/openssl/openssl/pull/7113)
This commit is contained in:
parent
00433bad41
commit
4803717f5e
@ -1086,6 +1086,7 @@ SM2_F_PKEY_SM2_INIT:111:pkey_sm2_init
|
||||
SM2_F_PKEY_SM2_SIGN:112:pkey_sm2_sign
|
||||
SM2_F_SM2_COMPUTE_MSG_HASH:100:sm2_compute_msg_hash
|
||||
SM2_F_SM2_COMPUTE_USERID_DIGEST:101:sm2_compute_userid_digest
|
||||
SM2_F_SM2_COMPUTE_Z_DIGEST:113:sm2_compute_z_digest
|
||||
SM2_F_SM2_DECRYPT:102:sm2_decrypt
|
||||
SM2_F_SM2_ENCRYPT:103:sm2_encrypt
|
||||
SM2_F_SM2_PLAINTEXT_SIZE:104:sm2_plaintext_size
|
||||
@ -2554,6 +2555,8 @@ RSA_R_WRONG_SIGNATURE_LENGTH:119:wrong signature length
|
||||
SM2_R_ASN1_ERROR:100:asn1 error
|
||||
SM2_R_BAD_SIGNATURE:101:bad signature
|
||||
SM2_R_BUFFER_TOO_SMALL:107:buffer too small
|
||||
SM2_R_DIST_ID_TOO_LARGE:110:dist id too large
|
||||
SM2_R_ID_TOO_LARGE:111:id too large
|
||||
SM2_R_INVALID_CURVE:108:invalid curve
|
||||
SM2_R_INVALID_DIGEST:102:invalid digest
|
||||
SM2_R_INVALID_DIGEST_TYPE:103:invalid digest type
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the OpenSSL license (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
@ -34,9 +34,9 @@ int EVP_MD_CTX_reset(EVP_MD_CTX *ctx)
|
||||
}
|
||||
/*
|
||||
* pctx should be freed by the user of EVP_MD_CTX
|
||||
* if EVP_MD_CTX_FLAG_NEGLECT_PCTX is set
|
||||
* if EVP_MD_CTX_FLAG_KEEP_PKEY_CTX is set
|
||||
*/
|
||||
if (!EVP_MD_CTX_test_flags(ctx, EVP_MD_CTX_FLAG_NEGLECT_PCTX))
|
||||
if (!EVP_MD_CTX_test_flags(ctx, EVP_MD_CTX_FLAG_KEEP_PKEY_CTX))
|
||||
EVP_PKEY_CTX_free(ctx->pctx);
|
||||
#ifndef OPENSSL_NO_ENGINE
|
||||
ENGINE_finish(ctx->engine);
|
||||
@ -229,6 +229,9 @@ int EVP_MD_CTX_copy_ex(EVP_MD_CTX *out, const EVP_MD_CTX *in)
|
||||
EVP_MD_CTX_reset(out);
|
||||
memcpy(out, in, sizeof(*out));
|
||||
|
||||
/* copied EVP_MD_CTX should free the copied EVP_PKEY_CTX */
|
||||
EVP_MD_CTX_clear_flags(out, EVP_MD_CTX_FLAG_KEEP_PKEY_CTX);
|
||||
|
||||
/* Null these variables, since they are getting fixed up
|
||||
* properly below. Anything else may cause a memleak and/or
|
||||
* double free if any of the memory allocations below fail
|
||||
|
@ -464,7 +464,7 @@ void EVP_MD_CTX_set_pkey_ctx(EVP_MD_CTX *ctx, EVP_PKEY_CTX *pctx)
|
||||
{
|
||||
ctx->pctx = pctx;
|
||||
/* make sure pctx is not freed when destroying EVP_MD_CTX */
|
||||
EVP_MD_CTX_set_flags(ctx, EVP_MD_CTX_FLAG_NEGLECT_PCTX);
|
||||
EVP_MD_CTX_set_flags(ctx, EVP_MD_CTX_FLAG_KEEP_PKEY_CTX);
|
||||
}
|
||||
|
||||
void *EVP_MD_CTX_md_data(const EVP_MD_CTX *ctx)
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2006-2016 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 2006-2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the OpenSSL license (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
@ -75,14 +75,13 @@ static int do_sigver_init(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx,
|
||||
return 1;
|
||||
if (!EVP_DigestInit_ex(ctx, type, e))
|
||||
return 0;
|
||||
if (ctx->pctx->pmeth->flags & EVP_PKEY_FLAG_DIGEST_CUSTOM) {
|
||||
/*
|
||||
* This indicates the current algorithm requires
|
||||
* special treatment before hashing the tbs-message.
|
||||
*/
|
||||
if (ctx->pctx->pmeth->digest_custom)
|
||||
return ctx->pctx->pmeth->digest_custom(ctx->pctx, ctx);
|
||||
}
|
||||
/*
|
||||
* This indicates the current algorithm requires
|
||||
* special treatment before hashing the tbs-message.
|
||||
*/
|
||||
if (ctx->pctx->pmeth->digest_custom)
|
||||
return ctx->pctx->pmeth->digest_custom(ctx->pctx, ctx);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -184,9 +183,9 @@ int EVP_DigestVerifyFinal(EVP_MD_CTX *ctx, const unsigned char *sig,
|
||||
else
|
||||
vctx = 0;
|
||||
if (ctx->flags & EVP_MD_CTX_FLAG_FINALISE) {
|
||||
if (vctx) {
|
||||
if (vctx)
|
||||
r = ctx->pctx->pmeth->verifyctx(ctx->pctx, sig, siglen, ctx);
|
||||
} else
|
||||
else
|
||||
r = EVP_DigestFinal_ex(ctx, md, &mdlen);
|
||||
} else {
|
||||
EVP_MD_CTX *tmp_ctx = EVP_MD_CTX_new();
|
||||
@ -196,10 +195,10 @@ int EVP_DigestVerifyFinal(EVP_MD_CTX *ctx, const unsigned char *sig,
|
||||
EVP_MD_CTX_free(tmp_ctx);
|
||||
return -1;
|
||||
}
|
||||
if (vctx) {
|
||||
if (vctx)
|
||||
r = tmp_ctx->pctx->pmeth->verifyctx(tmp_ctx->pctx,
|
||||
sig, siglen, tmp_ctx);
|
||||
} else
|
||||
else
|
||||
r = EVP_DigestFinal_ex(tmp_ctx, md, &mdlen);
|
||||
EVP_MD_CTX_free(tmp_ctx);
|
||||
}
|
||||
|
@ -367,6 +367,7 @@ int EVP_PKEY_CTX_ctrl(EVP_PKEY_CTX *ctx, int keytype, int optype,
|
||||
int cmd, int p1, void *p2)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (!ctx || !ctx->pmeth || !ctx->pmeth->ctrl) {
|
||||
EVPerr(EVP_F_EVP_PKEY_CTX_CTRL, EVP_R_COMMAND_NOT_SUPPORTED);
|
||||
return -2;
|
||||
@ -374,6 +375,10 @@ int EVP_PKEY_CTX_ctrl(EVP_PKEY_CTX *ctx, int keytype, int optype,
|
||||
if ((keytype != -1) && (ctx->pmeth->pkey_id != keytype))
|
||||
return -1;
|
||||
|
||||
/* Skip the operation checks since this is called in a very early stage */
|
||||
if (ctx->pmeth->digest_custom != NULL)
|
||||
goto doit;
|
||||
|
||||
if (ctx->operation == EVP_PKEY_OP_UNDEFINED) {
|
||||
EVPerr(EVP_F_EVP_PKEY_CTX_CTRL, EVP_R_NO_OPERATION_SET);
|
||||
return -1;
|
||||
@ -384,13 +389,13 @@ int EVP_PKEY_CTX_ctrl(EVP_PKEY_CTX *ctx, int keytype, int optype,
|
||||
return -1;
|
||||
}
|
||||
|
||||
doit:
|
||||
ret = ctx->pmeth->ctrl(ctx, cmd, p1, p2);
|
||||
|
||||
if (ret == -2)
|
||||
EVPerr(EVP_F_EVP_PKEY_CTX_CTRL, EVP_R_COMMAND_NOT_SUPPORTED);
|
||||
|
||||
return ret;
|
||||
|
||||
}
|
||||
|
||||
int EVP_PKEY_CTX_ctrl_uint64(EVP_PKEY_CTX *ctx, int keytype, int optype,
|
||||
|
@ -10,6 +10,12 @@
|
||||
#include <openssl/evp.h>
|
||||
#include "internal/refcount.h"
|
||||
|
||||
/*
|
||||
* Don't free up md_ctx->pctx in EVP_MD_CTX_reset, use the reserved flag
|
||||
* values in evp.h
|
||||
*/
|
||||
#define EVP_MD_CTX_FLAG_KEEP_PKEY_CTX 0x0400
|
||||
|
||||
struct evp_pkey_ctx_st {
|
||||
/* Method associated with this operation */
|
||||
const EVP_PKEY_METHOD *pmeth;
|
||||
|
@ -20,15 +20,14 @@
|
||||
/* The default user id as specified in GM/T 0009-2012 */
|
||||
# define SM2_DEFAULT_USERID "1234567812345678"
|
||||
|
||||
int sm2_compute_userid_digest(uint8_t *out,
|
||||
const EVP_MD *digest,
|
||||
const uint8_t *id,
|
||||
const size_t id_len,
|
||||
const EC_KEY *key);
|
||||
int sm2_compute_z_digest(uint8_t *out,
|
||||
const EVP_MD *digest,
|
||||
const uint8_t *id,
|
||||
const size_t id_len,
|
||||
const EC_KEY *key);
|
||||
|
||||
/*
|
||||
* SM2 signature operation. Computes ZA (user id digest) and then signs
|
||||
* H(ZA || msg) using SM2
|
||||
* SM2 signature operation. Computes Z and then signs H(Z || msg) using SM2
|
||||
*/
|
||||
ECDSA_SIG *sm2_do_sign(const EC_KEY *key,
|
||||
const EVP_MD *digest,
|
||||
|
@ -28,7 +28,7 @@ int ERR_load_SM2_strings(void);
|
||||
# define SM2_F_PKEY_SM2_INIT 111
|
||||
# define SM2_F_PKEY_SM2_SIGN 112
|
||||
# define SM2_F_SM2_COMPUTE_MSG_HASH 100
|
||||
# define SM2_F_SM2_COMPUTE_USERID_DIGEST 101
|
||||
# define SM2_F_SM2_COMPUTE_Z_DIGEST 113
|
||||
# define SM2_F_SM2_DECRYPT 102
|
||||
# define SM2_F_SM2_ENCRYPT 103
|
||||
# define SM2_F_SM2_PLAINTEXT_SIZE 104
|
||||
@ -43,13 +43,13 @@ int ERR_load_SM2_strings(void);
|
||||
# define SM2_R_ASN1_ERROR 100
|
||||
# define SM2_R_BAD_SIGNATURE 101
|
||||
# define SM2_R_BUFFER_TOO_SMALL 107
|
||||
# define SM2_R_ID_TOO_LARGE 111
|
||||
# define SM2_R_INVALID_CURVE 108
|
||||
# define SM2_R_INVALID_DIGEST 102
|
||||
# define SM2_R_INVALID_DIGEST_TYPE 103
|
||||
# define SM2_R_INVALID_ENCODING 104
|
||||
# define SM2_R_INVALID_FIELD 105
|
||||
# define SM2_R_NO_PARAMETERS_SET 109
|
||||
# define SM2_R_USER_ID_TOO_LARGE 106
|
||||
|
||||
# endif
|
||||
#endif
|
||||
|
@ -20,8 +20,8 @@ static const ERR_STRING_DATA SM2_str_functs[] = {
|
||||
{ERR_PACK(ERR_LIB_SM2, SM2_F_PKEY_SM2_SIGN, 0), "pkey_sm2_sign"},
|
||||
{ERR_PACK(ERR_LIB_SM2, SM2_F_SM2_COMPUTE_MSG_HASH, 0),
|
||||
"sm2_compute_msg_hash"},
|
||||
{ERR_PACK(ERR_LIB_SM2, SM2_F_SM2_COMPUTE_USERID_DIGEST, 0),
|
||||
"sm2_compute_userid_digest"},
|
||||
{ERR_PACK(ERR_LIB_SM2, SM2_F_SM2_COMPUTE_Z_DIGEST, 0),
|
||||
"sm2_compute_z_digest"},
|
||||
{ERR_PACK(ERR_LIB_SM2, SM2_F_SM2_DECRYPT, 0), "sm2_decrypt"},
|
||||
{ERR_PACK(ERR_LIB_SM2, SM2_F_SM2_ENCRYPT, 0), "sm2_encrypt"},
|
||||
{ERR_PACK(ERR_LIB_SM2, SM2_F_SM2_PLAINTEXT_SIZE, 0), "sm2_plaintext_size"},
|
||||
@ -36,6 +36,7 @@ static const ERR_STRING_DATA SM2_str_reasons[] = {
|
||||
{ERR_PACK(ERR_LIB_SM2, 0, SM2_R_ASN1_ERROR), "asn1 error"},
|
||||
{ERR_PACK(ERR_LIB_SM2, 0, SM2_R_BAD_SIGNATURE), "bad signature"},
|
||||
{ERR_PACK(ERR_LIB_SM2, 0, SM2_R_BUFFER_TOO_SMALL), "buffer too small"},
|
||||
{ERR_PACK(ERR_LIB_SM2, 0, SM2_R_ID_TOO_LARGE), "id too large"},
|
||||
{ERR_PACK(ERR_LIB_SM2, 0, SM2_R_INVALID_CURVE), "invalid curve"},
|
||||
{ERR_PACK(ERR_LIB_SM2, 0, SM2_R_INVALID_DIGEST), "invalid digest"},
|
||||
{ERR_PACK(ERR_LIB_SM2, 0, SM2_R_INVALID_DIGEST_TYPE),
|
||||
@ -43,7 +44,6 @@ static const ERR_STRING_DATA SM2_str_reasons[] = {
|
||||
{ERR_PACK(ERR_LIB_SM2, 0, SM2_R_INVALID_ENCODING), "invalid encoding"},
|
||||
{ERR_PACK(ERR_LIB_SM2, 0, SM2_R_INVALID_FIELD), "invalid field"},
|
||||
{ERR_PACK(ERR_LIB_SM2, 0, SM2_R_NO_PARAMETERS_SET), "no parameters set"},
|
||||
{ERR_PACK(ERR_LIB_SM2, 0, SM2_R_USER_ID_TOO_LARGE), "user id too large"},
|
||||
{0, NULL}
|
||||
};
|
||||
|
||||
|
@ -22,30 +22,34 @@ typedef struct {
|
||||
EC_GROUP *gen_group;
|
||||
/* message digest */
|
||||
const EVP_MD *md;
|
||||
/* Distinguishing Identifier, ISO/IEC 15946-3 */
|
||||
uint8_t *id;
|
||||
size_t id_len;
|
||||
/* id_set indicates if the 'id' field is set (1) or not (0) */
|
||||
int id_set;
|
||||
} SM2_PKEY_CTX;
|
||||
|
||||
static int pkey_sm2_init(EVP_PKEY_CTX *ctx)
|
||||
{
|
||||
SM2_PKEY_CTX *dctx;
|
||||
SM2_PKEY_CTX *smctx;
|
||||
|
||||
if ((dctx = OPENSSL_zalloc(sizeof(*dctx))) == NULL) {
|
||||
if ((smctx = OPENSSL_zalloc(sizeof(*smctx))) == NULL) {
|
||||
SM2err(SM2_F_PKEY_SM2_INIT, ERR_R_MALLOC_FAILURE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
ctx->data = dctx;
|
||||
ctx->data = smctx;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void pkey_sm2_cleanup(EVP_PKEY_CTX *ctx)
|
||||
{
|
||||
SM2_PKEY_CTX *dctx = ctx->data;
|
||||
SM2_PKEY_CTX *smctx = ctx->data;
|
||||
|
||||
if (dctx != NULL) {
|
||||
EC_GROUP_free(dctx->gen_group);
|
||||
OPENSSL_free(dctx);
|
||||
if (smctx != NULL) {
|
||||
EC_GROUP_free(smctx->gen_group);
|
||||
OPENSSL_free(smctx->id);
|
||||
OPENSSL_free(smctx);
|
||||
ctx->data = NULL;
|
||||
}
|
||||
}
|
||||
@ -65,6 +69,16 @@ static int pkey_sm2_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src)
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
if (sctx->id != NULL) {
|
||||
dctx->id = OPENSSL_malloc(sctx->id_len);
|
||||
if (dctx->id == NULL) {
|
||||
pkey_sm2_cleanup(dst);
|
||||
return 0;
|
||||
}
|
||||
memcpy(dctx->id, sctx->id, sctx->id_len);
|
||||
}
|
||||
dctx->id_len = sctx->id_len;
|
||||
dctx->id_set = sctx->id_set;
|
||||
dctx->md = sctx->md;
|
||||
|
||||
return 1;
|
||||
@ -147,7 +161,7 @@ static int pkey_sm2_decrypt(EVP_PKEY_CTX *ctx,
|
||||
|
||||
static int pkey_sm2_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
|
||||
{
|
||||
SM2_PKEY_CTX *dctx = ctx->data;
|
||||
SM2_PKEY_CTX *smctx = ctx->data;
|
||||
EC_GROUP *group;
|
||||
|
||||
switch (type) {
|
||||
@ -157,29 +171,51 @@ static int pkey_sm2_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
|
||||
SM2err(SM2_F_PKEY_SM2_CTRL, SM2_R_INVALID_CURVE);
|
||||
return 0;
|
||||
}
|
||||
EC_GROUP_free(dctx->gen_group);
|
||||
dctx->gen_group = group;
|
||||
EC_GROUP_free(smctx->gen_group);
|
||||
smctx->gen_group = group;
|
||||
return 1;
|
||||
|
||||
case EVP_PKEY_CTRL_EC_PARAM_ENC:
|
||||
if (dctx->gen_group == NULL) {
|
||||
if (smctx->gen_group == NULL) {
|
||||
SM2err(SM2_F_PKEY_SM2_CTRL, SM2_R_NO_PARAMETERS_SET);
|
||||
return 0;
|
||||
}
|
||||
EC_GROUP_set_asn1_flag(dctx->gen_group, p1);
|
||||
EC_GROUP_set_asn1_flag(smctx->gen_group, p1);
|
||||
return 1;
|
||||
|
||||
case EVP_PKEY_CTRL_MD:
|
||||
dctx->md = p2;
|
||||
smctx->md = p2;
|
||||
return 1;
|
||||
|
||||
case EVP_PKEY_CTRL_GET_MD:
|
||||
*(const EVP_MD **)p2 = dctx->md;
|
||||
*(const EVP_MD **)p2 = smctx->md;
|
||||
return 1;
|
||||
|
||||
case EVP_PKEY_CTRL_SET1_ID:
|
||||
OPENSSL_free(smctx->id);
|
||||
if (p1 > 0) {
|
||||
smctx->id = OPENSSL_malloc(p1);
|
||||
if (smctx->id == NULL)
|
||||
return 0;
|
||||
memcpy(smctx->id, p2, p1);
|
||||
} else {
|
||||
/* set null-ID */
|
||||
smctx->id = NULL;
|
||||
}
|
||||
smctx->id_len = (size_t)p1;
|
||||
smctx->id_set = 1;
|
||||
return 1;
|
||||
|
||||
case EVP_PKEY_CTRL_GET1_ID:
|
||||
memcpy(p2, smctx->id, smctx->id_len);
|
||||
return 1;
|
||||
|
||||
case EVP_PKEY_CTRL_GET1_ID_LEN:
|
||||
*(size_t *)p2 = smctx->id_len;
|
||||
return 1;
|
||||
|
||||
default:
|
||||
return -2;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -214,21 +250,21 @@ static int pkey_sm2_ctrl_str(EVP_PKEY_CTX *ctx,
|
||||
static int pkey_sm2_digest_custom(EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx)
|
||||
{
|
||||
uint8_t z[EVP_MAX_MD_SIZE];
|
||||
SM2_PKEY_CTX *sctx = ctx->data;
|
||||
SM2_PKEY_CTX *smctx = ctx->data;
|
||||
EC_KEY *ec = ctx->pkey->pkey.ec;
|
||||
const EVP_MD *md = EVP_MD_CTX_md(mctx);
|
||||
|
||||
if (sctx->id == NULL) {
|
||||
/* XXX:
|
||||
* currently we reject all null-ID for SM2, but this needs
|
||||
* more considerations and discussion since the specifications
|
||||
* on SM2 are not clear on null-ID
|
||||
if (!smctx->id_set) {
|
||||
/*
|
||||
* An ID value must be set. The specifications are not clear whether a
|
||||
* NULL is allowed. We only allow it if set explicitly for maximum
|
||||
* flexibility.
|
||||
*/
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* get hashed prefix of tbs message */
|
||||
if (!sm2_compute_userid_digest(z, md, sctx->id, sctx->id_len, ec))
|
||||
/* get hashed prefix 'z' of tbs message */
|
||||
if (!sm2_compute_z_digest(z, md, smctx->id, smctx->id_len, ec))
|
||||
return 0;
|
||||
|
||||
return EVP_DigestUpdate(mctx, z, EVP_MD_size(md));
|
||||
|
@ -18,11 +18,11 @@
|
||||
#include <openssl/bn.h>
|
||||
#include <string.h>
|
||||
|
||||
int sm2_compute_userid_digest(uint8_t *out,
|
||||
const EVP_MD *digest,
|
||||
const uint8_t *id,
|
||||
const size_t id_len,
|
||||
const EC_KEY *key)
|
||||
int sm2_compute_z_digest(uint8_t *out,
|
||||
const EVP_MD *digest,
|
||||
const uint8_t *id,
|
||||
const size_t id_len,
|
||||
const EC_KEY *key)
|
||||
{
|
||||
int rc = 0;
|
||||
const EC_GROUP *group = EC_KEY_get0_group(key);
|
||||
@ -37,13 +37,13 @@ int sm2_compute_userid_digest(uint8_t *out,
|
||||
BIGNUM *yA = NULL;
|
||||
int p_bytes = 0;
|
||||
uint8_t *buf = NULL;
|
||||
uint16_t entla = 0;
|
||||
uint16_t entl = 0;
|
||||
uint8_t e_byte = 0;
|
||||
|
||||
hash = EVP_MD_CTX_new();
|
||||
ctx = BN_CTX_new();
|
||||
if (hash == NULL || ctx == NULL) {
|
||||
SM2err(SM2_F_SM2_COMPUTE_USERID_DIGEST, ERR_R_MALLOC_FAILURE);
|
||||
SM2err(SM2_F_SM2_COMPUTE_Z_DIGEST, ERR_R_MALLOC_FAILURE);
|
||||
goto done;
|
||||
}
|
||||
|
||||
@ -56,46 +56,50 @@ int sm2_compute_userid_digest(uint8_t *out,
|
||||
yA = BN_CTX_get(ctx);
|
||||
|
||||
if (yA == NULL) {
|
||||
SM2err(SM2_F_SM2_COMPUTE_USERID_DIGEST, ERR_R_MALLOC_FAILURE);
|
||||
SM2err(SM2_F_SM2_COMPUTE_Z_DIGEST, ERR_R_MALLOC_FAILURE);
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (!EVP_DigestInit(hash, digest)) {
|
||||
SM2err(SM2_F_SM2_COMPUTE_USERID_DIGEST, ERR_R_EVP_LIB);
|
||||
SM2err(SM2_F_SM2_COMPUTE_Z_DIGEST, ERR_R_EVP_LIB);
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* Z = SM3(ENTLA || IDA || a || b || xG || yG || xA || yA) */
|
||||
/* Z = h(ENTL || ID || a || b || xG || yG || xA || yA) */
|
||||
|
||||
if (id_len >= (UINT16_MAX / 8)) {
|
||||
/* too large */
|
||||
SM2err(SM2_F_SM2_COMPUTE_USERID_DIGEST, SM2_R_USER_ID_TOO_LARGE);
|
||||
SM2err(SM2_F_SM2_COMPUTE_Z_DIGEST, SM2_R_ID_TOO_LARGE);
|
||||
goto done;
|
||||
}
|
||||
|
||||
entla = (uint16_t)(8 * id_len);
|
||||
entl = (uint16_t)(8 * id_len);
|
||||
|
||||
e_byte = entla >> 8;
|
||||
e_byte = entl >> 8;
|
||||
if (!EVP_DigestUpdate(hash, &e_byte, 1)) {
|
||||
SM2err(SM2_F_SM2_COMPUTE_USERID_DIGEST, ERR_R_EVP_LIB);
|
||||
SM2err(SM2_F_SM2_COMPUTE_Z_DIGEST, ERR_R_EVP_LIB);
|
||||
goto done;
|
||||
}
|
||||
e_byte = entla & 0xFF;
|
||||
if (!EVP_DigestUpdate(hash, &e_byte, 1)
|
||||
|| !EVP_DigestUpdate(hash, id, id_len)) {
|
||||
SM2err(SM2_F_SM2_COMPUTE_USERID_DIGEST, ERR_R_EVP_LIB);
|
||||
e_byte = entl & 0xFF;
|
||||
if (!EVP_DigestUpdate(hash, &e_byte, 1)) {
|
||||
SM2err(SM2_F_SM2_COMPUTE_Z_DIGEST, ERR_R_EVP_LIB);
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (id_len > 0 && !EVP_DigestUpdate(hash, id, id_len)) {
|
||||
SM2err(SM2_F_SM2_COMPUTE_Z_DIGEST, ERR_R_EVP_LIB);
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (!EC_GROUP_get_curve(group, p, a, b, ctx)) {
|
||||
SM2err(SM2_F_SM2_COMPUTE_USERID_DIGEST, ERR_R_EC_LIB);
|
||||
SM2err(SM2_F_SM2_COMPUTE_Z_DIGEST, ERR_R_EC_LIB);
|
||||
goto done;
|
||||
}
|
||||
|
||||
p_bytes = BN_num_bytes(p);
|
||||
buf = OPENSSL_zalloc(p_bytes);
|
||||
if (buf == NULL) {
|
||||
SM2err(SM2_F_SM2_COMPUTE_USERID_DIGEST, ERR_R_MALLOC_FAILURE);
|
||||
SM2err(SM2_F_SM2_COMPUTE_Z_DIGEST, ERR_R_MALLOC_FAILURE);
|
||||
goto done;
|
||||
}
|
||||
|
||||
@ -118,7 +122,7 @@ int sm2_compute_userid_digest(uint8_t *out,
|
||||
|| BN_bn2binpad(yA, buf, p_bytes) < 0
|
||||
|| !EVP_DigestUpdate(hash, buf, p_bytes)
|
||||
|| !EVP_DigestFinal(hash, out, NULL)) {
|
||||
SM2err(SM2_F_SM2_COMPUTE_USERID_DIGEST, ERR_R_INTERNAL_ERROR);
|
||||
SM2err(SM2_F_SM2_COMPUTE_Z_DIGEST, ERR_R_INTERNAL_ERROR);
|
||||
goto done;
|
||||
}
|
||||
|
||||
@ -139,7 +143,7 @@ static BIGNUM *sm2_compute_msg_hash(const EVP_MD *digest,
|
||||
{
|
||||
EVP_MD_CTX *hash = EVP_MD_CTX_new();
|
||||
const int md_size = EVP_MD_size(digest);
|
||||
uint8_t *za = NULL;
|
||||
uint8_t *z = NULL;
|
||||
BIGNUM *e = NULL;
|
||||
|
||||
if (md_size < 0) {
|
||||
@ -147,32 +151,32 @@ static BIGNUM *sm2_compute_msg_hash(const EVP_MD *digest,
|
||||
goto done;
|
||||
}
|
||||
|
||||
za = OPENSSL_zalloc(md_size);
|
||||
if (hash == NULL || za == NULL) {
|
||||
z = OPENSSL_zalloc(md_size);
|
||||
if (hash == NULL || z == NULL) {
|
||||
SM2err(SM2_F_SM2_COMPUTE_MSG_HASH, ERR_R_MALLOC_FAILURE);
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (!sm2_compute_userid_digest(za, digest, id, id_len, key)) {
|
||||
if (!sm2_compute_z_digest(z, digest, id, id_len, key)) {
|
||||
/* SM2err already called */
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (!EVP_DigestInit(hash, digest)
|
||||
|| !EVP_DigestUpdate(hash, za, md_size)
|
||||
|| !EVP_DigestUpdate(hash, z, md_size)
|
||||
|| !EVP_DigestUpdate(hash, msg, msg_len)
|
||||
/* reuse za buffer to hold H(ZA || M) */
|
||||
|| !EVP_DigestFinal(hash, za, NULL)) {
|
||||
/* reuse z buffer to hold H(Z || M) */
|
||||
|| !EVP_DigestFinal(hash, z, NULL)) {
|
||||
SM2err(SM2_F_SM2_COMPUTE_MSG_HASH, ERR_R_EVP_LIB);
|
||||
goto done;
|
||||
}
|
||||
|
||||
e = BN_bin2bn(za, md_size, NULL);
|
||||
e = BN_bin2bn(z, md_size, NULL);
|
||||
if (e == NULL)
|
||||
SM2err(SM2_F_SM2_COMPUTE_MSG_HASH, ERR_R_INTERNAL_ERROR);
|
||||
|
||||
done:
|
||||
OPENSSL_free(za);
|
||||
OPENSSL_free(z);
|
||||
EVP_MD_CTX_free(hash);
|
||||
return e;
|
||||
}
|
||||
|
@ -1429,6 +1429,19 @@ void EC_KEY_METHOD_get_verify(const EC_KEY_METHOD *meth,
|
||||
EVP_PKEY_OP_DERIVE, \
|
||||
EVP_PKEY_CTRL_GET_EC_KDF_UKM, 0, (void *)(p))
|
||||
|
||||
/* SM2 will skip the operation check so no need to pass operation here */
|
||||
# define EVP_PKEY_CTX_set1_id(ctx, id, id_len) \
|
||||
EVP_PKEY_CTX_ctrl(ctx, -1, -1, \
|
||||
EVP_PKEY_CTRL_SET1_ID, (int)id_len, (void*)(id))
|
||||
|
||||
# define EVP_PKEY_CTX_get1_id(ctx, id) \
|
||||
EVP_PKEY_CTX_ctrl(ctx, -1, -1, \
|
||||
EVP_PKEY_CTRL_GET1_ID, 0, (void*)(id))
|
||||
|
||||
# define EVP_PKEY_CTX_get1_id_len(ctx, id_len) \
|
||||
EVP_PKEY_CTX_ctrl(ctx, -1, -1, \
|
||||
EVP_PKEY_CTRL_GET1_ID_LEN, 0, (void*)(id_len))
|
||||
|
||||
# define EVP_PKEY_CTRL_EC_PARAMGEN_CURVE_NID (EVP_PKEY_ALG_CTRL + 1)
|
||||
# define EVP_PKEY_CTRL_EC_PARAM_ENC (EVP_PKEY_ALG_CTRL + 2)
|
||||
# define EVP_PKEY_CTRL_EC_ECDH_COFACTOR (EVP_PKEY_ALG_CTRL + 3)
|
||||
@ -1439,6 +1452,9 @@ void EC_KEY_METHOD_get_verify(const EC_KEY_METHOD *meth,
|
||||
# define EVP_PKEY_CTRL_GET_EC_KDF_OUTLEN (EVP_PKEY_ALG_CTRL + 8)
|
||||
# define EVP_PKEY_CTRL_EC_KDF_UKM (EVP_PKEY_ALG_CTRL + 9)
|
||||
# define EVP_PKEY_CTRL_GET_EC_KDF_UKM (EVP_PKEY_ALG_CTRL + 10)
|
||||
# define EVP_PKEY_CTRL_SET1_ID (EVP_PKEY_ALG_CTRL + 11)
|
||||
# define EVP_PKEY_CTRL_GET1_ID (EVP_PKEY_ALG_CTRL + 12)
|
||||
# define EVP_PKEY_CTRL_GET1_ID_LEN (EVP_PKEY_ALG_CTRL + 13)
|
||||
/* KDF types */
|
||||
# define EVP_PKEY_ECDH_KDF_NONE 1
|
||||
# define EVP_PKEY_ECDH_KDF_X9_62 2
|
||||
|
@ -180,9 +180,7 @@ int (*EVP_MD_meth_get_ctrl(const EVP_MD *md))(EVP_MD_CTX *ctx, int cmd,
|
||||
* if the following flag is set.
|
||||
*/
|
||||
# define EVP_MD_CTX_FLAG_FINALISE 0x0200
|
||||
|
||||
/* Don't free up ctx->pctx in EVP_MD_CTX_reset */
|
||||
# define EVP_MD_CTX_FLAG_NEGLECT_PCTX 0x0400
|
||||
/* NOTE: 0x0400 is reserved for internal usage in evp_int.h */
|
||||
|
||||
EVP_CIPHER *EVP_CIPHER_meth_new(int cipher_type, int block_size, int key_len);
|
||||
EVP_CIPHER *EVP_CIPHER_meth_dup(const EVP_CIPHER *cipher);
|
||||
@ -1325,8 +1323,6 @@ void EVP_PKEY_asn1_set_security_bits(EVP_PKEY_ASN1_METHOD *ameth,
|
||||
* Method handles all operations: don't assume any digest related defaults.
|
||||
*/
|
||||
# define EVP_PKEY_FLAG_SIGCTX_CUSTOM 4
|
||||
/* Do a customized hashing process */
|
||||
# define EVP_PKEY_FLAG_DIGEST_CUSTOM 8
|
||||
|
||||
const EVP_PKEY_METHOD *EVP_PKEY_meth_find(int type);
|
||||
EVP_PKEY_METHOD *EVP_PKEY_meth_new(int id, int flags);
|
||||
|
@ -16,6 +16,7 @@
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/rsa.h>
|
||||
#include <openssl/x509.h>
|
||||
#include <openssl/pem.h>
|
||||
#include "testutil.h"
|
||||
#include "internal/nelem.h"
|
||||
#include "internal/evp_int.h"
|
||||
@ -530,6 +531,7 @@ static int test_EVP_SM2(void)
|
||||
EVP_PKEY *params = NULL;
|
||||
EVP_PKEY_CTX *pctx = NULL;
|
||||
EVP_PKEY_CTX *kctx = NULL;
|
||||
EVP_PKEY_CTX *sctx = NULL;
|
||||
size_t sig_len = 0;
|
||||
unsigned char *sig = NULL;
|
||||
EVP_MD_CTX *md_ctx = NULL;
|
||||
@ -542,6 +544,8 @@ static int test_EVP_SM2(void)
|
||||
uint8_t plaintext[8];
|
||||
size_t ptext_len = sizeof(plaintext);
|
||||
|
||||
uint8_t sm2_id[] = {1, 2, 3, 4, 'l', 'e', 't', 't', 'e', 'r'};
|
||||
|
||||
pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_EC, NULL);
|
||||
if (!TEST_ptr(pctx))
|
||||
goto done;
|
||||
@ -574,6 +578,15 @@ static int test_EVP_SM2(void)
|
||||
if (!TEST_ptr(md_ctx_verify = EVP_MD_CTX_new()))
|
||||
goto done;
|
||||
|
||||
if (!TEST_ptr(sctx = EVP_PKEY_CTX_new(pkey, NULL)))
|
||||
goto done;
|
||||
|
||||
EVP_MD_CTX_set_pkey_ctx(md_ctx, sctx);
|
||||
EVP_MD_CTX_set_pkey_ctx(md_ctx_verify, sctx);
|
||||
|
||||
if (!TEST_int_gt(EVP_PKEY_CTX_set1_id(sctx, sm2_id, sizeof(sm2_id)), 0))
|
||||
goto done;
|
||||
|
||||
if (!TEST_true(EVP_DigestSignInit(md_ctx, NULL, EVP_sm3(), NULL, pkey)))
|
||||
goto done;
|
||||
|
||||
@ -631,6 +644,7 @@ static int test_EVP_SM2(void)
|
||||
done:
|
||||
EVP_PKEY_CTX_free(pctx);
|
||||
EVP_PKEY_CTX_free(kctx);
|
||||
EVP_PKEY_CTX_free(sctx);
|
||||
EVP_PKEY_CTX_free(cctx);
|
||||
EVP_PKEY_free(pkey);
|
||||
EVP_PKEY_free(params);
|
||||
|
@ -413,3 +413,6 @@ SSLv23_method define
|
||||
SSLv23_server_method define
|
||||
X509_STORE_set_lookup_crls_cb define
|
||||
X509_STORE_set_verify_func define
|
||||
EVP_PKEY_CTX_set1_id define
|
||||
EVP_PKEY_CTX_get1_id define
|
||||
EVP_PKEY_CTX_get1_id_len define
|
||||
|
Loading…
x
Reference in New Issue
Block a user