remove old api

This commit is contained in:
Zhi Guan
2021-07-31 22:07:25 +08:00
parent f7b4533cdd
commit 2ecba70472
30 changed files with 1025 additions and 953 deletions

View File

@@ -135,6 +135,11 @@ int gcm_decrypt(const BLOCK_CIPHER_KEY *key, const uint8_t *iv, size_t ivlen,
const uint8_t *aad, size_t aadlen, const uint8_t *in, size_t inlen,
const uint8_t *tag, size_t taglen, uint8_t *out)
{
if (key->cipher == BLOCK_CIPHER_sm4()) {
sm4_gcm_decrypt(&(key->u.sm4_key), iv, ivlen, aad, aadlen, in, inlen, tag, taglen, out);
} else if (key->cipher == BLOCK_CIPHER_aes128()) {
aes_gcm_decrypt(&(key->u.aes_key), iv, ivlen, aad, aadlen, in, inlen, tag, taglen, out);
}
error_print();
return -1;
}

View File

@@ -85,7 +85,7 @@ void gf128_print_bits(gf128_t a)
{
int i;
for (i = 0; i < 128; i++) {
printf("%d", (int)(a % 2));
printf("%d", a % 2);
a >>= 1;
}
printf("\n");

View File

@@ -48,23 +48,13 @@
#include <string.h>
#include <gmssl/hmac.h>
#include <gmssl/error.h>
#define IPAD 0x36
#define OPAD 0x5C
int hmac_ctx_init(HMAC_CTX *ctx)
{
memset(ctx, 0, sizeof(HMAC_CTX));
return 1;
}
void hmac_ctx_cleanup(HMAC_CTX *ctx)
{
memset(ctx, 0, sizeof(HMAC_CTX));
}
int hmac_init(HMAC_CTX *ctx, const DIGEST *digest, const unsigned char *key, size_t keylen)
{
uint8_t i_key[DIGEST_MAX_BLOCK_SIZE] = {0};
@@ -73,7 +63,8 @@ int hmac_init(HMAC_CTX *ctx, const DIGEST *digest, const unsigned char *key, siz
int i;
if (!ctx || !digest || !key || !keylen) {
return 0;
error_print();
return -1;
}
ctx->digest = digest;
@@ -107,34 +98,45 @@ int hmac_init(HMAC_CTX *ctx, const DIGEST *digest, const unsigned char *key, siz
int hmac_update(HMAC_CTX *ctx, const unsigned char *data, size_t datalen)
{
if (!ctx || (!data && datalen != 0)) {
return 0;
error_print();
return -1;
}
return digest_update(&ctx->digest_ctx, data, datalen);
if (digest_update(&ctx->digest_ctx, data, datalen) != 1) {
error_print();
return -1;
}
return 1;
}
int hmac_finish(HMAC_CTX *ctx, unsigned char *mac, size_t *maclen)
{
int ret = 0;
size_t i;
size_t blocksize;
if (!digest_finish(&ctx->digest_ctx, mac, maclen)) {
if (digest_finish(&ctx->digest_ctx, mac, maclen) != 1) {
error_print();
return -1;
}
memcpy(&ctx->digest_ctx, &ctx->o_ctx, sizeof(DIGEST_CTX));
if (!digest_update(&ctx->digest_ctx, mac, *maclen)
|| !digest_finish(&ctx->digest_ctx, mac, maclen)) {
goto end;
if (digest_update(&ctx->digest_ctx, mac, *maclen) != 1
|| digest_finish(&ctx->digest_ctx, mac, maclen) != 1) {
error_print();
return -1;
}
ret = 1;
end:
return ret;
return 1;
}
int hmac_reset(HMAC_CTX *ctx)
int hmac_finish_and_verify(HMAC_CTX *ctx, const uint8_t *mac, size_t maclen)
{
memcpy(&ctx->digest_ctx, &ctx->i_ctx, sizeof(DIGEST_CTX));
uint8_t hmac[64];
size_t hmaclen;
if (hmac_finish(ctx, hmac, &hmaclen) != 1) {
error_print();
return -1;
}
if (maclen != hmaclen
|| memcmp(hmac, mac, maclen) != 0) {
error_print();
return -1;
}
return 1;
}
@@ -145,14 +147,14 @@ int hmac(const DIGEST *digest, const unsigned char *key, size_t keylen,
int ret = 0;
HMAC_CTX ctx;
if (!hmac_ctx_init(&ctx)
|| !hmac_init(&ctx, digest, key, keylen)
|| !hmac_update(&ctx, data, datalen)
|| !hmac_finish(&ctx, mac, maclen)) {
if (hmac_init(&ctx, digest, key, keylen) != 1
|| hmac_update(&ctx, data, datalen) != 1
|| hmac_finish(&ctx, mac, maclen) != 1) {
goto end;
}
ret = 1;
end:
hmac_ctx_cleanup(&ctx);
memset(&ctx, 0, sizeof(ctx));
return ret;
}

View File

@@ -129,13 +129,14 @@ int pbkdf2_genkey(const DIGEST *digest,
size_t outlen, uint8_t *out)
{
HMAC_CTX ctx;
HMAC_CTX ctx_tmpl;
uint32_t iter = 1;
uint8_t iter_be[4];
uint8_t tmp_block[64];
uint8_t key_block[64];
size_t len;
hmac_init(&ctx, digest, (uint8_t *)pass, passlen);
hmac_init(&ctx_tmpl, digest, (uint8_t *)pass, passlen);
while (outlen > 0) {
int i;
@@ -143,16 +144,16 @@ int pbkdf2_genkey(const DIGEST *digest,
PUTU32(iter_be, iter);
iter++;
ctx = ctx_tmpl;
hmac_update(&ctx, salt, saltlen);
hmac_update(&ctx, iter_be, sizeof(iter_be));
hmac_finish(&ctx, tmp_block, &len);
hmac_reset(&ctx);
memcpy(key_block, tmp_block, len);
for (i = 1; i < count; i++) {
ctx = ctx_tmpl;
hmac_update(&ctx, tmp_block, len);
hmac_finish(&ctx, tmp_block, &len);
hmac_reset(&ctx);
memxor(key_block, tmp_block, len);
}

View File

@@ -67,7 +67,7 @@ void sm4_cbc_decrypt(const SM4_KEY *key, const uint8_t iv[16],
const uint8_t *in, size_t nblocks, uint8_t *out)
{
while (nblocks--) {
sm4_decrypt(key, in, out);
sm4_encrypt(key, in, out);
memxor(out, iv, 16);
iv = in;
in += 16;

View File

@@ -83,7 +83,7 @@ static uint32_t CK[32] = {
x4 = x0 ^ L32_(x4); \
*(rk + 31 - i) = x4
void sm4_set_encrypt_key(SM4_KEY *key, const unsigned char user_key[16])
void sm4_set_encrypt_key(SM4_KEY *key, const uint8_t user_key[16])
{
uint32_t *rk = key->rk;
uint32_t x0, x1, x2, x3, x4;
@@ -100,7 +100,7 @@ void sm4_set_encrypt_key(SM4_KEY *key, const unsigned char user_key[16])
x0 = x1 = x2 = x3 = x4 = 0;
}
void sm4_set_decrypt_key(SM4_KEY *key, const unsigned char user_key[16])
void sm4_set_decrypt_key(SM4_KEY *key, const uint8_t user_key[16])
{
uint32_t *rk = key->rk;
uint32_t x0, x1, x2, x3, x4;

224
src/tls.c
View File

@@ -322,7 +322,118 @@ int tls_record_length(const uint8_t *record)
}
int tls_cbc_encrypt(const SM3_HMAC_CTX *inited_hmac_ctx, const SM4_KEY *enc_key,
const uint8_t seq_num[8], const uint8_t header[5],
const uint8_t *in, size_t inlen, uint8_t *out, size_t *outlen)
{
SM3_HMAC_CTX hmac_ctx;
uint8_t last_blocks[32 + 16] = {0};
uint8_t *mac, *padding, *iv;
int rem, padding_len;
int i;
if (!inited_hmac_ctx || !enc_key || !seq_num || !header || (!in && inlen) || !out || !outlen) {
error_print();
return -1;
}
if (inlen > (1 << 14)) {
error_print("invalid tls record data length %zu\n", inlen);
return -1;
}
rem = (inlen + 32) % 16;
memcpy(last_blocks, in + inlen - rem, rem);
mac = last_blocks + rem;
memcpy(&hmac_ctx, inited_hmac_ctx, sizeof(SM3_HMAC_CTX));
sm3_hmac_update(&hmac_ctx, seq_num, 8);
sm3_hmac_update(&hmac_ctx, header, 5);
sm3_hmac_update(&hmac_ctx, in, inlen);
sm3_hmac_finish(&hmac_ctx, mac);
padding = mac + 32;
padding_len = 16 - rem - 1;
for (i = 0; i <= padding_len; i++) {
padding[i] = padding_len;
}
iv = out;
if (rand_bytes(iv, 16) != 1) {
error_print();
return -1;
}
out += 16;
if (inlen >= 16) {
sm4_cbc_encrypt(enc_key, iv, in, inlen/16, out);
out += inlen - rem;
iv = out - 16;
}
sm4_cbc_encrypt(enc_key, iv, last_blocks, sizeof(last_blocks)/16, out);
*outlen = 16 + inlen - rem + sizeof(last_blocks);
return 1;
}
int tls_cbc_decrypt(const SM3_HMAC_CTX *inited_hmac_ctx, const SM4_KEY *dec_key,
const uint8_t seq_num[8], const uint8_t enced_header[5],
const uint8_t *in, size_t inlen, uint8_t *out, size_t *outlen)
{
SM3_HMAC_CTX hmac_ctx;
const uint8_t *iv;
const uint8_t *padding;
const uint8_t *mac;
uint8_t header[5];
int padding_len;
int i;
if (!inited_hmac_ctx || !dec_key || !seq_num || !enced_header || !in || !inlen || !out || !outlen) {
error_print();
return -1;
}
if (inlen % 16
|| inlen < (16 + 0 + 32 + 16) // iv + data + mac + padding
|| inlen > (16 + (1<<14) + 32 + 256)) {
error_print("invalid tls cbc ciphertext length %zu\n", inlen);
return -1;
}
iv = in;
in += 16;
inlen -= 16;
sm4_cbc_decrypt(dec_key, iv, in, inlen/16, out);
padding_len = out[inlen - 1];
padding = out + inlen - padding_len - 1;
if (padding < out + 32) {
error_print();
return -1;
}
for (i = 0; i < padding_len; i++) {
if (padding[i] != padding_len) {
error_print("tls ciphertext cbc-padding check failure");
return -1;
}
}
*outlen = inlen - 32 - padding_len - 1;
header[0] = enced_header[0];
header[1] = enced_header[1];
header[2] = enced_header[2];
header[3] = (*outlen) >> 8;
header[4] = (*outlen);
mac = padding - 32;
memcpy(&hmac_ctx, inited_hmac_ctx, sizeof(SM3_HMAC_CTX));
sm3_hmac_update(&hmac_ctx, seq_num, 8);
sm3_hmac_update(&hmac_ctx, header, 5);
sm3_hmac_update(&hmac_ctx, out, *outlen);
if (sm3_hmac_finish_and_verify(&hmac_ctx, mac) != 1) {
error_print("tls ciphertext mac check failure");
return -1;
}
return 1;
}
// 这个函数应该是处理的这个函数是不应该用的通常我们在加密的时候header 明文数据是分离的但是输出的record是一个
int tls_record_encrypt(const SM3_HMAC_CTX *hmac_ctx, const SM4_KEY *cbc_key,
@@ -378,6 +489,62 @@ int tls_random_generate(uint8_t random[32])
return 1;
}
int tls_prf(const uint8_t *secret, size_t secretlen, const char *label,
const uint8_t *seed, size_t seedlen,
const uint8_t *more, size_t morelen,
size_t outlen, uint8_t *out)
{
SM3_HMAC_CTX inited_hmac_ctx;
SM3_HMAC_CTX hmac_ctx;
uint8_t A[32];
uint8_t hmac[32];
size_t len;
if (!secret || !secretlen || !label || !seed || !seedlen
|| (!more && morelen) || !outlen || !out) {
error_print();
return -1;
}
sm3_hmac_init(&inited_hmac_ctx, secret, secretlen);
memcpy(&hmac_ctx, &inited_hmac_ctx, sizeof(SM3_HMAC_CTX));
sm3_hmac_update(&hmac_ctx, (uint8_t *)label, strlen(label));
sm3_hmac_update(&hmac_ctx, seed, seedlen);
sm3_hmac_update(&hmac_ctx, more, morelen);
sm3_hmac_finish(&hmac_ctx, A);
memcpy(&hmac_ctx, &inited_hmac_ctx, sizeof(SM3_HMAC_CTX));
sm3_hmac_update(&hmac_ctx, A, sizeof(A));
sm3_hmac_update(&hmac_ctx, (uint8_t *)label, strlen(label));
sm3_hmac_update(&hmac_ctx, seed, seedlen);
sm3_hmac_update(&hmac_ctx, more, morelen);
sm3_hmac_finish(&hmac_ctx, hmac);
len = outlen < sizeof(hmac) ? outlen : sizeof(hmac);
memcpy(out, hmac, len);
out += len;
outlen -= len;
while (outlen) {
memcpy(&hmac_ctx, &inited_hmac_ctx, sizeof(SM3_HMAC_CTX));
sm3_hmac_update(&hmac_ctx, A, sizeof(A));
sm3_hmac_finish(&hmac_ctx, A);
memcpy(&hmac_ctx, &inited_hmac_ctx, sizeof(SM3_HMAC_CTX));
sm3_hmac_update(&hmac_ctx, A, sizeof(A));
sm3_hmac_update(&hmac_ctx, (uint8_t *)label, strlen(label));
sm3_hmac_update(&hmac_ctx, seed, seedlen);
sm3_hmac_update(&hmac_ctx, more, morelen);
sm3_hmac_finish(&hmac_ctx, hmac);
len = outlen < sizeof(hmac) ? outlen : sizeof(hmac);
memcpy(out, hmac, len);
out += len;
outlen -= len;
}
return 1;
}
int tls_pre_master_secret_generate(uint8_t pre_master_secret[48], int version)
{
@@ -396,6 +563,63 @@ int tls_pre_master_secret_generate(uint8_t pre_master_secret[48], int version)
int tls_sign_server_ecdh_params(const SM2_KEY *server_sign_key,
const uint8_t client_random[32], const uint8_t server_random[32],
int curve, const SM2_POINT *point, uint8_t *sig, size_t *siglen)
{
uint8_t server_ecdh_params[69];
SM2_SIGN_CTX sign_ctx;
if (!server_sign_key || !client_random || !server_random
|| curve != TLS_curve_sm2p256v1 || !point || !sig || !siglen) {
error_print();
return -1;
}
server_ecdh_params[0] = TLS_curve_type_named_curve;
server_ecdh_params[1] = curve >> 8;
server_ecdh_params[2] = curve;
server_ecdh_params[3] = 65;
sm2_point_to_uncompressed_octets(point, server_ecdh_params + 4);
sm2_sign_init(&sign_ctx, server_sign_key, SM2_DEFAULT_ID);
sm2_sign_update(&sign_ctx, client_random, 32);
sm2_sign_update(&sign_ctx, server_random, 32);
sm2_sign_update(&sign_ctx, server_ecdh_params, 69);
sm2_sign_finish(&sign_ctx, sig, siglen);
return 1;
}
int tls_verify_server_ecdh_params(const SM2_KEY *server_sign_key,
const uint8_t client_random[32], const uint8_t server_random[32],
int curve, const SM2_POINT *point, const uint8_t *sig, size_t siglen)
{
int ret;
uint8_t server_ecdh_params[69];
SM2_SIGN_CTX verify_ctx;
if (!server_sign_key || !client_random || !server_random
|| curve != TLS_curve_sm2p256v1 || !point || !sig || !siglen
|| siglen > TLS_MAX_SIGNATURE_SIZE) {
error_print();
return -1;
}
server_ecdh_params[0] = TLS_curve_type_named_curve;
server_ecdh_params[1] = curve >> 8;
server_ecdh_params[2] = curve;
server_ecdh_params[3] = 65;
sm2_point_to_uncompressed_octets(point, server_ecdh_params + 4);
sm2_verify_init(&verify_ctx, server_sign_key, SM2_DEFAULT_ID);
sm2_verify_update(&verify_ctx, client_random, 32);
sm2_verify_update(&verify_ctx, server_random, 32);
sm2_verify_update(&verify_ctx, server_ecdh_params, 69);
ret = sm2_verify_finish(&verify_ctx, sig, siglen);
if (ret != 1) error_print();
return ret;
}
// handshakes

View File

@@ -65,45 +65,66 @@
#include <gmssl/pem.h>
#include <gmssl/tls.h>
#include <gmssl/digest.h>
#include <gmssl/block_cipher.h>
#include <gmssl/gcm.h>
#include <gmssl/hmac.h>
#include <gmssl/hkdf.h>
#include "mem.h"
int tls13_gcm_encrypt(const BLOCK_CIPHER_KEY *enc_key,
const uint8_t iv[12], size_t padding_len,
/*
struct {
opaque content[TLSPlaintext.length];
ContentType type;
uint8 zeros[length_of_padding];
} TLSInnerPlaintext;
struct {
ContentType opaque_type = application_data; // 23
ProtocolVersion legacy_record_version = 0x0303; // TLS v1.2
uint16 length;
opaque encrypted_record[TLSCiphertext.length];
} TLSCiphertext;
*/
int tls13_gcm_encrypt(const BLOCK_CIPHER_KEY *key, const uint8_t iv[12],
const uint8_t seq_num[8], int record_type,
const uint8_t *in, size_t inlen, uint8_t *out, size_t *outlen)
const uint8_t *in, size_t inlen, size_t padding_len, // TLSInnerPlaintext.content
uint8_t *out, size_t *outlen) // TLSCiphertext.encrypted_record
{
uint8_t nonce[12];
uint8_t *mbuf = malloc(inlen + 256);
uint8_t aad[5];
uint8_t *gmac;
uint8_t *mbuf = malloc(inlen + 256); // FIXME: update gcm_encrypt API
size_t mlen, clen;
// nonce = (zeros|seq_num) xor (iv)
nonce[0] = nonce[1] = nonce[2] = 0;
memcpy(nonce + 3, seq_num, 8);
gmssl_memxor(nonce, nonce, iv, 12);
// TLSInnerPlaintext
memcpy(mbuf, in, inlen);
mbuf[inlen] = record_type;
memset(mbuf + inlen + 1, 0, padding_len);
mlen = inlen + 1 + padding_len;
clen = mlen + 16;
clen = mlen + GHASH_SIZE;
// aad = TLSCiphertext header
aad[0] = TLS_record_application_data;
aad[1] = 3;
aad[2] = 3;
aad[1] = TLS_version_tls12_major;
aad[2] = TLS_version_tls12_minor;
aad[3] = clen >> 8;
aad[4] = clen;
gmac = out + mlen;
gcm_encrypt(enc_key, nonce, sizeof(nonce), aad, sizeof(aad), mbuf, mlen, out, 16, gmac);
if (gcm_encrypt(key, nonce, sizeof(nonce), aad, sizeof(aad), mbuf, mlen, out, 16, gmac) != 1) {
error_print();
return -1;
}
return 1;
}
int tls13_gcm_decrypt(const BLOCK_CIPHER_KEY *sm4_key, const uint8_t iv[12],
int tls13_gcm_decrypt(const BLOCK_CIPHER_KEY *key, const uint8_t iv[12],
const uint8_t seq_num[8], const uint8_t *in, size_t inlen,
int *record_type, uint8_t *out, size_t *outlen)
{
@@ -113,62 +134,335 @@ int tls13_gcm_decrypt(const BLOCK_CIPHER_KEY *sm4_key, const uint8_t iv[12],
const uint8_t *gmac;
size_t i;
// nonce = (zeros|seq_num) xor (iv)
nonce[0] = nonce[1] = nonce[2] = 0;
memcpy(nonce + 3, seq_num, 8);
gmssl_memxor(nonce, nonce, iv, 12);
// aad = TLSCiphertext header
aad[0] = TLS_record_application_data;
aad[1] = 3;
aad[2] = 3;
aad[1] = TLS_version_tls12_major;
aad[2] = TLS_version_tls12_minor;
aad[3] = inlen >> 8;
aad[4] = inlen;
mlen = inlen - 16;
if (inlen < GHASH_SIZE) {
error_print();
return -1;
}
mlen = inlen - GHASH_SIZE;
gmac = in + mlen;
return -1;
}
int tls13_record_encrypt(const BLOCK_CIPHER_KEY *key, const uint8_t iv[12],
const uint8_t seq_num[8], const uint8_t *in, size_t inlen, size_t padding_len,
uint8_t *out, size_t *outlen)
{
if (tls13_gcm_encrypt(key, iv, padding_len,
seq_num, in[0], in + 5, inlen - 5, out + 5, outlen) != 1) {
if (gcm_decrypt(key, iv, 12, aad, 5, in, mlen, gmac, GHASH_SIZE, out) != 1) {
error_print();
return -1;
}
out[0] = TLS_record_application_data;
out[1] = in[1];
out[2] = in[2];
out[3] = (*outlen) >> 8;
out[4] = (*outlen);
(*outlen) += 5;
// remove padding, get record_type
*record_type = 0;
while (mlen--) {
if (out[mlen] != 0) {
*record_type = out[mlen];
break;
}
}
if (!tls_record_type_name(*record_type)) {
error_print();
return -1;
}
return 1;
}
int tls13_record_encrypt(const BLOCK_CIPHER_KEY *key, const uint8_t iv[12],
const uint8_t seq_num[8], const uint8_t *record, size_t recordlen, size_t padding_len,
uint8_t *enced_record, size_t *enced_recordlen)
{
if (tls13_gcm_encrypt(key, iv,
seq_num, record[0], record + 5, recordlen - 5, padding_len,
enced_record + 5, enced_recordlen) != 1) {
error_print();
return -1;
}
enced_record[0] = TLS_record_application_data;
enced_record[1] = TLS_version_tls12_major;
enced_record[2] = TLS_version_tls12_minor;
enced_record[3] = (*enced_recordlen) >> 8;
enced_record[4] = (*enced_recordlen);
(*enced_recordlen) += 5;
return 1;
}
int tls13_record_decrypt(const BLOCK_CIPHER_KEY *key, const uint8_t iv[12],
const uint8_t seq_num[8], const uint8_t *in, size_t inlen,
uint8_t *out, size_t *outlen)
const uint8_t seq_num[8], const uint8_t *enced_record, size_t enced_recordlen,
uint8_t *record, size_t *recordlen)
{
int record_type;
if (tls13_gcm_decrypt(key, iv, seq_num, in + 5, inlen - 5,
&record_type, out + 5, outlen) != 1) {
if (tls13_gcm_decrypt(key, iv,
seq_num, enced_record + 5, enced_recordlen - 5,
&record_type, record + 5, recordlen) != 1) {
error_print();
return -1;
}
record[0] = record_type;
record[1] = TLS_version_tls12_major;
record[2] = TLS_version_tls12_minor;
record[3] = (*recordlen) >> 8;
record[4] = (*recordlen);
(*recordlen) += 5;
return 1;
}
int tls13_send(TLS_CONNECT *conn, const uint8_t *data, size_t datalen, size_t padding_len)
{
const BLOCK_CIPHER_KEY *key;
const uint8_t *iv;
uint8_t *seq_num;
uint8_t *record = conn->record;
size_t recordlen;
tls_trace("<<<< [ApplicationData]\n");
if (conn->is_client) {
key = &conn->client_write_key;
iv = conn->client_write_iv;
seq_num = conn->client_seq_num;
} else {
key = &conn->server_write_key;
iv = conn->server_write_iv;
seq_num = conn->server_seq_num;
}
if (tls13_gcm_encrypt(key, iv,
seq_num, TLS_record_application_data, data, datalen, padding_len,
record + 5, &recordlen) != 1) {
error_print();
return -1;
}
out[0] = record_type;
out[1] = in[1];
out[2] = in[2];
out[3] = (*outlen) >> 8;
out[4] = (*outlen);
record[0] = TLS_record_application_data;
record[1] = TLS_version_tls12 >> 8;
record[2] = TLS_version_tls12 & 0xff;
record[3] = recordlen >> 8;
record[4] = recordlen;
recordlen += 5;
tls_record_send(record, recordlen, conn->sock);
tls_seq_num_incr(seq_num);
return 1;
}
int tls13_recv(TLS_CONNECT *conn, uint8_t *data, size_t *datalen)
{
int record_type;
uint8_t *record = conn->record;
size_t recordlen;
const BLOCK_CIPHER_KEY *key;
const uint8_t *iv;
uint8_t *seq_num;
tls_trace(">>>> [ApplicationData]\n");
if (conn->is_client) {
key = &conn->client_write_key;
iv = conn->client_write_iv;
seq_num = conn->client_seq_num;
} else {
key = &conn->server_write_key;
iv = conn->server_write_iv;
seq_num = conn->server_seq_num;
}
if (tls12_record_recv(record, &recordlen, conn->sock) != 1) {
error_print();
return -1;
}
if (record[0] != TLS_record_application_data) {
error_print();
return -1;
}
if (tls13_gcm_decrypt(key, iv,
seq_num, record + 5, recordlen - 5,
&record_type, data, datalen) != 1) {
error_print();
return -1;
}
tls_seq_num_incr(seq_num);
if (record_type != TLS_record_application_data) {
error_print();
return -1;
}
return 1;
}
/*
HKDF-Expand-Label(Secret, Label, Context, Length) =
HKDF-Expand(Secret, HkdfLabel, Length);
HkdfLabel = struct {
uint16 length = Length;
opaque label<7..255> = "tls13 " + Label;
opaque context<0..255> = Context; }
Derive-Secret(Secret, Label, Messages) =
HKDF-Expand-Label(Secret, Label, Hash(Messages), Hash.length)
*/
int tls13_hkdf_extract(const DIGEST *digest, const uint8_t salt[32], const uint8_t in[32], uint8_t out[32])
{
size_t dgstlen;
if (hkdf_extract(digest, salt, 32, in, 32, out, &dgstlen) != 1
|| dgstlen != 32) {
error_print();
return -1;
}
return 1;
}
int tls13_hkdf_expand_label(const DIGEST *digest, const uint8_t secret[32],
const char *label, const uint8_t *context, size_t context_len,
size_t outlen, uint8_t *out)
{
uint8_t label_len;
uint8_t hkdf_label[2 + 256 + 256];
uint8_t *p = hkdf_label;
size_t hkdf_label_len = 0;
label_len = strlen("tls13") + strlen(label);
tls_uint16_to_bytes((uint16_t)outlen, &p, &hkdf_label_len);
tls_uint8_to_bytes(label_len, &p, &hkdf_label_len);
tls_array_to_bytes((uint8_t *)"tls13", strlen("tls13"), &p, &hkdf_label_len);
tls_array_to_bytes((uint8_t *)label, strlen(label), &p, &hkdf_label_len);
tls_uint8array_to_bytes(context, context_len, &p, &hkdf_label_len);
hkdf_expand(digest, secret, 32, hkdf_label, hkdf_label_len, outlen, out);
return 1;
}
int tls13_derive_secret(const uint8_t secret[32], const char *label, const DIGEST_CTX *dgst_ctx, uint8_t out[32])
{
DIGEST_CTX ctx = *dgst_ctx;
uint8_t dgst[64];
size_t dgstlen;
if (digest_finish(&ctx, dgst, &dgstlen) != 1
|| tls13_hkdf_expand_label(dgst_ctx->digest, secret, label, dgst, 32, dgstlen, out) != 1) {
error_print();
return -1;
}
return 1;
}
/*
data to be signed in certificate_verify:
- A string that consists of octet 32 (0x20) repeated 64 times
- The context string
- A single 0 byte which serves as the separator
- The content to be signed
*/
int tls13_sign(const SM2_KEY *key, const DIGEST_CTX *dgst_ctx, uint8_t *sig, size_t *siglen, int is_server)
{
uint8_t client_context_str[] = "TLS 1.3, client CertificateVerify";
uint8_t server_context_str[] = "TLS 1.3, server CertificateVerify";
SM2_SIGN_CTX sm2_ctx;
DIGEST_CTX temp_dgst_ctx;
uint8_t prefix[64];
uint8_t *context_str = is_server ? server_context_str : client_context_str;
size_t context_str_len = sizeof(client_context_str);
uint8_t dgst[64];
size_t dgstlen;
memset(prefix, 0x20, 64);
temp_dgst_ctx = *dgst_ctx;
digest_finish(&temp_dgst_ctx, dgst, &dgstlen);
sm2_sign_init(&sm2_ctx, key, SM2_DEFAULT_ID);
sm2_sign_update(&sm2_ctx, prefix, 64);
sm2_sign_update(&sm2_ctx, context_str, context_str_len);
sm2_sign_update(&sm2_ctx, dgst, dgstlen);
sm2_sign_finish(&sm2_ctx, sig, siglen);
return 1;
}
int tls13_verify(const SM2_KEY *key, const DIGEST_CTX *dgst_ctx, const uint8_t *sig, size_t siglen, int is_server)
{
uint8_t client_context_str[] = "TLS 1.3, client CertificateVerify";
uint8_t server_context_str[] = "TLS 1.3, server CertificateVerify";
int ret;
SM2_SIGN_CTX sm2_ctx;
DIGEST_CTX temp_dgst_ctx;
uint8_t prefix[64];
uint8_t dgst[64];
size_t dgstlen;
memset(prefix, 0x20, 64);
temp_dgst_ctx = *dgst_ctx;
digest_finish(&temp_dgst_ctx, dgst, &dgstlen);
sm2_verify_init(&sm2_ctx, key, SM2_DEFAULT_ID);
sm2_verify_update(&sm2_ctx, prefix, 64);
sm2_verify_update(&sm2_ctx, is_server ? server_context_str : client_context_str, sizeof(server_context_str));
sm2_verify_update(&sm2_ctx, dgst, dgstlen);
ret = sm2_verify_finish(&sm2_ctx, sig, siglen);
return ret;
}
/*
verify_data in Finished
finished_key =
HKDF-Expand-Label(BaseKey, "finished", "", Hash.length)
Structure of this message:
struct {
opaque verify_data[Hash.length];
} Finished;
The verify_data value is computed as follows:
verify_data =
HMAC(finished_key,
Transcript-Hash(Handshake Context,
Certificate*, CertificateVerify*))
*/
int tls13_compute_verify_data(const uint8_t *handshake_traffic_secret,
const DIGEST_CTX *dgst_ctx, uint8_t *verify_data, size_t *verify_data_len)
{
DIGEST_CTX temp_dgst_ctx;
uint8_t dgst[64];
size_t dgstlen;
uint8_t finished_key[64];
size_t finished_key_len;
temp_dgst_ctx = *dgst_ctx;
digest_finish(&temp_dgst_ctx, dgst, &dgstlen);
finished_key_len = dgstlen;
tls13_hkdf_expand_label(dgst_ctx->digest, handshake_traffic_secret,
"finished", NULL, 0, finished_key_len, finished_key);
hmac(dgst_ctx->digest, finished_key, finished_key_len, dgst, dgstlen, verify_data, verify_data_len);
return 1;
}
/*
Handshakes
*/
int tls_ext_supported_versions_to_bytes(const int *versions, size_t versions_count,
uint8_t **out, size_t *outlen)
{
@@ -597,56 +891,6 @@ int tls13_record_get_handshake_encrypted_extensions(const uint8_t *record)
return 1;
}
int tls13_sign(const SM2_KEY *key, const DIGEST_CTX *dgst_ctx, uint8_t *sig, size_t *siglen, int is_server)
{
uint8_t client_context_str[] = "TLS 1.3, client CertificateVerify";
uint8_t server_context_str[] = "TLS 1.3, server CertificateVerify";
SM2_SIGN_CTX sm2_ctx;
DIGEST_CTX temp_dgst_ctx;
uint8_t prefix[64];
uint8_t *context_str = is_server ? server_context_str : client_context_str;
size_t context_str_len = sizeof(client_context_str);
uint8_t dgst[64];
size_t dgstlen;
memset(prefix, 0x20, 64);
temp_dgst_ctx = *dgst_ctx;
digest_finish(&temp_dgst_ctx, dgst, &dgstlen);
sm2_sign_init(&sm2_ctx, key, SM2_DEFAULT_ID);
sm2_sign_update(&sm2_ctx, prefix, 64);
sm2_sign_update(&sm2_ctx, context_str, context_str_len);
sm2_sign_update(&sm2_ctx, dgst, dgstlen);
sm2_sign_finish(&sm2_ctx, sig, siglen);
return 1;
}
int tls13_verify(const SM2_KEY *key, const DIGEST_CTX *dgst_ctx, const uint8_t *sig, size_t siglen, int is_server)
{
uint8_t client_context_str[] = "TLS 1.3, client CertificateVerify";
uint8_t server_context_str[] = "TLS 1.3, server CertificateVerify";
int ret;
SM2_SIGN_CTX sm2_ctx;
DIGEST_CTX temp_dgst_ctx;
uint8_t prefix[64];
uint8_t dgst[64];
size_t dgstlen;
memset(prefix, 0x20, 64);
temp_dgst_ctx = *dgst_ctx;
digest_finish(&temp_dgst_ctx, dgst, &dgstlen);
sm2_verify_init(&sm2_ctx, key, SM2_DEFAULT_ID);
sm2_verify_update(&sm2_ctx, prefix, 64);
sm2_verify_update(&sm2_ctx, is_server ? server_context_str : client_context_str, sizeof(server_context_str));
sm2_verify_update(&sm2_ctx, dgst, dgstlen);
ret = sm2_verify_finish(&sm2_ctx, sig, siglen);
return ret;
}
/*
ClientHello.Extensions.signature_algorithms 列出客户端支持的签名+哈希算法
@@ -814,26 +1058,6 @@ int tls13_record_get_handshake_certificate(const uint8_t *record, uint8_t *data,
}
int tls13_compute_verify_data(const uint8_t *handshake_traffic_secret,
const DIGEST_CTX *dgst_ctx, uint8_t *verify_data, size_t *verify_data_len)
{
DIGEST_CTX temp_dgst_ctx;
uint8_t dgst[64];
size_t dgstlen;
uint8_t finished_key[64];
size_t finished_key_len;
temp_dgst_ctx = *dgst_ctx;
digest_finish(&temp_dgst_ctx, dgst, &dgstlen);
finished_key_len = dgstlen;
tls13_hkdf_expand_label(dgst_ctx->digest, handshake_traffic_secret,
"finished", NULL, 0, finished_key_len, finished_key);
hmac(dgst_ctx->digest, finished_key, finished_key_len, dgst, dgstlen, verify_data, verify_data_len);
return 1;
}
@@ -1839,95 +2063,3 @@ int tls13_accept(TLS_CONNECT *conn, int port,
tls_trace("Connection Established!\n\n");
return 1;
}
int tls13_send(TLS_CONNECT *conn, const uint8_t *data, size_t datalen, size_t padding_len)
{
const BLOCK_CIPHER_KEY *key;
const uint8_t *iv;
uint8_t *seq_num;
uint8_t *record = conn->record;
size_t recordlen;
tls_trace("<<<< [ApplicationData]\n");
if (conn->is_client) {
key = &conn->client_write_key;
iv = conn->client_write_iv;
seq_num = conn->client_seq_num;
} else {
key = &conn->server_write_key;
iv = conn->server_write_iv;
seq_num = conn->server_seq_num;
}
if (tls13_gcm_encrypt(key, iv, padding_len,
seq_num, TLS_record_application_data, data, datalen,
record + 5, &recordlen) != 1) {
error_print();
return -1;
}
record[0] = TLS_record_application_data;
record[1] = TLS_version_tls12 >> 8;
record[2] = TLS_version_tls12 & 0xff;
record[3] = recordlen >> 8;
record[4] = recordlen;
recordlen += 5;
tls_record_send(record, recordlen, conn->sock);
tls_seq_num_incr(seq_num);
return 1;
}
int tls13_recv(TLS_CONNECT *conn, uint8_t *data, size_t *datalen)
{
int record_type;
uint8_t *record = conn->record;
size_t recordlen;
const BLOCK_CIPHER_KEY *key;
const uint8_t *iv;
uint8_t *seq_num;
tls_trace(">>>> [ApplicationData]\n");
if (conn->is_client) {
key = &conn->client_write_key;
iv = conn->client_write_iv;
seq_num = conn->client_seq_num;
} else {
key = &conn->server_write_key;
iv = conn->server_write_iv;
seq_num = conn->server_seq_num;
}
if (tls12_record_recv(record, &recordlen, conn->sock) != 1) {
error_print();
return -1;
}
if (record[0] != TLS_record_application_data) {
error_print();
return -1;
}
if (tls13_gcm_decrypt(key, iv,
seq_num, record + 5, recordlen - 5,
&record_type, data, datalen) != 1) {
error_print();
return -1;
}
tls_seq_num_incr(seq_num);
if (record_type != TLS_record_application_data) {
error_print();
return -1;
}
return 1;
}

View File

@@ -1,347 +0,0 @@
/*
* Copyright (c) 2021 - 2021 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
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the GmSSL Project.
* (http://gmssl.org/)"
*
* 4. The name "GmSSL Project" must not be used to endorse or promote
* products derived from this software without prior written
* permission. For written permission, please contact
* guanzhi1980@gmail.com.
*
* 5. Products derived from this software may not be called "GmSSL"
* nor may "GmSSL" appear in their names without prior written
* permission of the GmSSL Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the GmSSL Project
* (http://gmssl.org/)"
*
* THIS SOFTWARE IS PROVIDED BY THE GmSSL PROJECT ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GmSSL PROJECT OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <time.h>
#include <gmssl/tls.h>
#include <gmssl/x509.h>
#include <gmssl/rand.h>
#include <gmssl/error.h>
#include <gmssl/digest.h>
#include <gmssl/hkdf.h>
#include "mem.h"
int tls_prf(const uint8_t *secret, size_t secretlen, const char *label,
const uint8_t *seed, size_t seedlen,
const uint8_t *more, size_t morelen,
size_t outlen, uint8_t *out)
{
SM3_HMAC_CTX inited_hmac_ctx;
SM3_HMAC_CTX hmac_ctx;
uint8_t A[32];
uint8_t hmac[32];
size_t len;
if (!secret || !secretlen || !label || !seed || !seedlen
|| (!more && morelen) || !outlen || !out) {
error_print();
return -1;
}
sm3_hmac_init(&inited_hmac_ctx, secret, secretlen);
memcpy(&hmac_ctx, &inited_hmac_ctx, sizeof(SM3_HMAC_CTX));
sm3_hmac_update(&hmac_ctx, (uint8_t *)label, strlen(label));
sm3_hmac_update(&hmac_ctx, seed, seedlen);
sm3_hmac_update(&hmac_ctx, more, morelen);
sm3_hmac_finish(&hmac_ctx, A);
memcpy(&hmac_ctx, &inited_hmac_ctx, sizeof(SM3_HMAC_CTX));
sm3_hmac_update(&hmac_ctx, A, sizeof(A));
sm3_hmac_update(&hmac_ctx, (uint8_t *)label, strlen(label));
sm3_hmac_update(&hmac_ctx, seed, seedlen);
sm3_hmac_update(&hmac_ctx, more, morelen);
sm3_hmac_finish(&hmac_ctx, hmac);
len = outlen < sizeof(hmac) ? outlen : sizeof(hmac);
memcpy(out, hmac, len);
out += len;
outlen -= len;
while (outlen) {
memcpy(&hmac_ctx, &inited_hmac_ctx, sizeof(SM3_HMAC_CTX));
sm3_hmac_update(&hmac_ctx, A, sizeof(A));
sm3_hmac_finish(&hmac_ctx, A);
memcpy(&hmac_ctx, &inited_hmac_ctx, sizeof(SM3_HMAC_CTX));
sm3_hmac_update(&hmac_ctx, A, sizeof(A));
sm3_hmac_update(&hmac_ctx, (uint8_t *)label, strlen(label));
sm3_hmac_update(&hmac_ctx, seed, seedlen);
sm3_hmac_update(&hmac_ctx, more, morelen);
sm3_hmac_finish(&hmac_ctx, hmac);
len = outlen < sizeof(hmac) ? outlen : sizeof(hmac);
memcpy(out, hmac, len);
out += len;
outlen -= len;
}
return 1;
}
/*
HKDF-Expand-Label(Secret, Label, Context, Length) =
HKDF-Expand(Secret, HkdfLabel, Length);
HkdfLabel = struct {
uint16 length = Length;
opaque label<7..255> = "tls13 " + Label;
opaque context<0..255> = Context; }
Derive-Secret(Secret, Label, Messages) =
HKDF-Expand-Label(Secret, Label, Hash(Messages), Hash.length)
*/
int tls13_hkdf_extract(const DIGEST *digest, const uint8_t salt[32], const uint8_t in[32], uint8_t out[32])
{
size_t dgstlen;
if (hkdf_extract(digest, salt, 32, in, 32, out, &dgstlen) != 1
|| dgstlen != 32) {
error_print();
return -1;
}
return 1;
}
int tls13_hkdf_expand_label(const DIGEST *digest, const uint8_t secret[32],
const char *label, const uint8_t *context, size_t context_len,
size_t outlen, uint8_t *out)
{
uint8_t label_len;
uint8_t hkdf_label[2 + 256 + 256];
uint8_t *p = hkdf_label;
size_t hkdf_label_len = 0;
label_len = strlen("tls13") + strlen(label);
tls_uint16_to_bytes((uint16_t)outlen, &p, &hkdf_label_len);
tls_uint8_to_bytes(label_len, &p, &hkdf_label_len);
tls_array_to_bytes((uint8_t *)"tls13", strlen("tls13"), &p, &hkdf_label_len);
tls_array_to_bytes((uint8_t *)label, strlen(label), &p, &hkdf_label_len);
tls_uint8array_to_bytes(context, context_len, &p, &hkdf_label_len);
hkdf_expand(digest, secret, 32, hkdf_label, hkdf_label_len, outlen, out);
return 1;
}
int tls13_derive_secret(const uint8_t secret[32], const char *label, const DIGEST_CTX *dgst_ctx, uint8_t out[32])
{
DIGEST_CTX ctx = *dgst_ctx;
uint8_t dgst[64];
size_t dgstlen;
if (digest_finish(&ctx, dgst, &dgstlen) != 1
|| tls13_hkdf_expand_label(dgst_ctx->digest, secret, label, dgst, 32, dgstlen, out) != 1) {
error_print();
return -1;
}
return 1;
}
int tls_cbc_encrypt(const SM3_HMAC_CTX *inited_hmac_ctx, const SM4_KEY *enc_key,
const uint8_t seq_num[8], const uint8_t header[5],
const uint8_t *in, size_t inlen, uint8_t *out, size_t *outlen)
{
SM3_HMAC_CTX hmac_ctx;
uint8_t last_blocks[32 + 16] = {0};
uint8_t *mac, *padding, *iv;
int rem, padding_len;
int i;
if (!inited_hmac_ctx || !enc_key || !seq_num || !header || (!in && inlen) || !out || !outlen) {
error_print();
return -1;
}
if (inlen > (1 << 14)) {
error_print("invalid tls record data length %zu\n", inlen);
return -1;
}
rem = (inlen + 32) % 16;
memcpy(last_blocks, in + inlen - rem, rem);
mac = last_blocks + rem;
memcpy(&hmac_ctx, inited_hmac_ctx, sizeof(SM3_HMAC_CTX));
sm3_hmac_update(&hmac_ctx, seq_num, 8);
sm3_hmac_update(&hmac_ctx, header, 5);
sm3_hmac_update(&hmac_ctx, in, inlen);
sm3_hmac_finish(&hmac_ctx, mac);
padding = mac + 32;
padding_len = 16 - rem - 1;
for (i = 0; i <= padding_len; i++) {
padding[i] = padding_len;
}
iv = out;
if (rand_bytes(iv, 16) != 1) {
error_print();
return -1;
}
out += 16;
if (inlen >= 16) {
sm4_cbc_encrypt(enc_key, iv, in, inlen/16, out);
out += inlen - rem;
iv = out - 16;
}
sm4_cbc_encrypt(enc_key, iv, last_blocks, sizeof(last_blocks)/16, out);
*outlen = 16 + inlen - rem + sizeof(last_blocks);
return 1;
}
int tls_cbc_decrypt(const SM3_HMAC_CTX *inited_hmac_ctx, const SM4_KEY *dec_key,
const uint8_t seq_num[8], const uint8_t enced_header[5],
const uint8_t *in, size_t inlen, uint8_t *out, size_t *outlen)
{
SM3_HMAC_CTX hmac_ctx;
const uint8_t *iv;
const uint8_t *padding;
const uint8_t *mac;
uint8_t header[5];
int padding_len;
int i;
if (!inited_hmac_ctx || !dec_key || !seq_num || !enced_header || !in || !inlen || !out || !outlen) {
error_print();
return -1;
}
if (inlen % 16
|| inlen < (16 + 0 + 32 + 16) // iv + data + mac + padding
|| inlen > (16 + (1<<14) + 32 + 256)) {
error_print("invalid tls cbc ciphertext length %zu\n", inlen);
return -1;
}
iv = in;
in += 16;
inlen -= 16;
sm4_cbc_decrypt(dec_key, iv, in, inlen/16, out);
padding_len = out[inlen - 1];
padding = out + inlen - padding_len - 1;
if (padding < out + 32) {
error_print();
return -1;
}
for (i = 0; i < padding_len; i++) {
if (padding[i] != padding_len) {
error_print("tls ciphertext cbc-padding check failure");
return -1;
}
}
*outlen = inlen - 32 - padding_len - 1;
header[0] = enced_header[0];
header[1] = enced_header[1];
header[2] = enced_header[2];
header[3] = (*outlen) >> 8;
header[4] = (*outlen);
mac = padding - 32;
memcpy(&hmac_ctx, inited_hmac_ctx, sizeof(SM3_HMAC_CTX));
sm3_hmac_update(&hmac_ctx, seq_num, 8);
sm3_hmac_update(&hmac_ctx, header, 5);
sm3_hmac_update(&hmac_ctx, out, *outlen);
if (sm3_hmac_finish_and_verify(&hmac_ctx, mac) != 1) {
error_print("tls ciphertext mac check failure");
return -1;
}
return 1;
}
int tls_sign_server_ecdh_params(const SM2_KEY *server_sign_key,
const uint8_t client_random[32], const uint8_t server_random[32],
int curve, const SM2_POINT *point, uint8_t *sig, size_t *siglen)
{
uint8_t server_ecdh_params[69];
SM2_SIGN_CTX sign_ctx;
if (!server_sign_key || !client_random || !server_random
|| curve != TLS_curve_sm2p256v1 || !point || !sig || !siglen) {
error_print();
return -1;
}
server_ecdh_params[0] = TLS_curve_type_named_curve;
server_ecdh_params[1] = curve >> 8;
server_ecdh_params[2] = curve;
server_ecdh_params[3] = 65;
sm2_point_to_uncompressed_octets(point, server_ecdh_params + 4);
sm2_sign_init(&sign_ctx, server_sign_key, SM2_DEFAULT_ID);
sm2_sign_update(&sign_ctx, client_random, 32);
sm2_sign_update(&sign_ctx, server_random, 32);
sm2_sign_update(&sign_ctx, server_ecdh_params, 69);
sm2_sign_finish(&sign_ctx, sig, siglen);
return 1;
}
int tls_verify_server_ecdh_params(const SM2_KEY *server_sign_key,
const uint8_t client_random[32], const uint8_t server_random[32],
int curve, const SM2_POINT *point, const uint8_t *sig, size_t siglen)
{
int ret;
uint8_t server_ecdh_params[69];
SM2_SIGN_CTX verify_ctx;
if (!server_sign_key || !client_random || !server_random
|| curve != TLS_curve_sm2p256v1 || !point || !sig || !siglen
|| siglen > TLS_MAX_SIGNATURE_SIZE) {
error_print();
return -1;
}
server_ecdh_params[0] = TLS_curve_type_named_curve;
server_ecdh_params[1] = curve >> 8;
server_ecdh_params[2] = curve;
server_ecdh_params[3] = 65;
sm2_point_to_uncompressed_octets(point, server_ecdh_params + 4);
sm2_verify_init(&verify_ctx, server_sign_key, SM2_DEFAULT_ID);
sm2_verify_update(&verify_ctx, client_random, 32);
sm2_verify_update(&verify_ctx, server_random, 32);
sm2_verify_update(&verify_ctx, server_ecdh_params, 69);
ret = sm2_verify_finish(&verify_ctx, sig, siglen);
if (ret != 1) error_print();
return ret;
}