mirror of
https://github.com/guanzhi/GmSSL.git
synced 2026-06-19 19:33:38 +08:00
Move TLS1.2/TLCP common functions to tls.c
This commit is contained in:
@@ -411,13 +411,10 @@ int tls_cbc_encrypt(const HMAC_CTX *hmac_ctx, const BLOCK_CIPHER_KEY *enc_key,
|
||||
int tls_cbc_decrypt(const HMAC_CTX *hmac_ctx, const BLOCK_CIPHER_KEY *dec_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);
|
||||
int tls_record_encrypt(const HMAC_CTX *hmac_ctx, const BLOCK_CIPHER_KEY *cbc_key,
|
||||
int tls_record_cbc_encrypt(const HMAC_CTX *hmac_ctx, const BLOCK_CIPHER_KEY *cbc_key,
|
||||
const uint8_t seq_num[8], const uint8_t *in, size_t inlen,
|
||||
uint8_t *out, size_t *outlen);
|
||||
int tls_record_decrypt(const HMAC_CTX *hmac_ctx, const BLOCK_CIPHER_KEY *cbc_key,
|
||||
const uint8_t seq_num[8], const uint8_t *in, size_t inlen,
|
||||
uint8_t *out, size_t *outlen);
|
||||
int tls12_record_cbc_encrypt(const HMAC_CTX *hmac_ctx, const BLOCK_CIPHER_KEY *cbc_key,
|
||||
int tls_record_cbc_decrypt(const HMAC_CTX *hmac_ctx, const BLOCK_CIPHER_KEY *cbc_key,
|
||||
const uint8_t seq_num[8], const uint8_t *in, size_t inlen,
|
||||
uint8_t *out, size_t *outlen);
|
||||
int tls12_gcm_encrypt(const BLOCK_CIPHER_KEY *key, const uint8_t fixed_iv[4],
|
||||
@@ -426,10 +423,21 @@ int tls12_gcm_encrypt(const BLOCK_CIPHER_KEY *key, const uint8_t fixed_iv[4],
|
||||
int tls12_record_gcm_encrypt(const BLOCK_CIPHER_KEY *key, const uint8_t fixed_iv[4],
|
||||
const uint8_t seq_num[8], const uint8_t *in, size_t inlen,
|
||||
uint8_t *out, size_t *outlen);
|
||||
int tls12_record_gcm_decrypt(const BLOCK_CIPHER_KEY *key, const uint8_t fixed_iv[4],
|
||||
const uint8_t seq_num[8], const uint8_t *in, size_t inlen,
|
||||
uint8_t *out, size_t *outlen);
|
||||
int tls12_record_decrypt(int cipher_suite, const HMAC_CTX *hmac_ctx,
|
||||
const BLOCK_CIPHER_KEY *key, const uint8_t fixed_iv[4],
|
||||
const uint8_t seq_num[8], const uint8_t *in, size_t inlen,
|
||||
uint8_t *out, size_t *outlen);
|
||||
int tlcp_record_encrypt(int cipher_suite,
|
||||
const HMAC_CTX *hmac_ctx, const BLOCK_CIPHER_KEY *key, const uint8_t fixed_iv[4],
|
||||
const uint8_t seq_num[8], const uint8_t *in, size_t inlen,
|
||||
uint8_t *out, size_t *outlen);
|
||||
int tlcp_record_decrypt(int cipher_suite,
|
||||
const HMAC_CTX *hmac_ctx, const BLOCK_CIPHER_KEY *key, const uint8_t fixed_iv[4],
|
||||
const uint8_t seq_num[8], const uint8_t *in, size_t inlen,
|
||||
uint8_t *out, size_t *outlen);
|
||||
|
||||
int tls_seq_num_incr(uint8_t seq_num[8]);
|
||||
void tls_seq_num_reset(uint8_t seq_num[8]);
|
||||
|
||||
222
src/tlcp.c
222
src/tlcp.c
@@ -25,18 +25,86 @@
|
||||
|
||||
|
||||
|
||||
static const int tlcp_ciphers[] = { TLS_cipher_ecc_sm4_cbc_sm3 };
|
||||
static const int tlcp_ciphers[] = {
|
||||
TLS_cipher_ecc_sm4_cbc_sm3,
|
||||
TLS_cipher_ecc_sm4_gcm_sm3,
|
||||
};
|
||||
static const size_t tlcp_ciphers_count = sizeof(tlcp_ciphers)/sizeof(tlcp_ciphers[0]);
|
||||
|
||||
|
||||
int tlcp_record_print(FILE *fp, int format, int indent, const uint8_t *record, size_t recordlen)
|
||||
{
|
||||
// 目前只支持TLCP的ECC公钥加密套件,因此不论用哪个套件解析都是一样的
|
||||
// 目前只支持TLCP的ECC公钥加密套件,因此不论用CBC/GCM哪个套件解析都是一样的
|
||||
// 如果未来支持ECDHE套件,可以将函数改为宏,直接传入 (conn->cipher_suite << 8)
|
||||
format |= tlcp_ciphers[0] << 8;
|
||||
return tls_record_print(fp, record, recordlen, format, indent);
|
||||
}
|
||||
|
||||
static int tlcp_cipher_suite_get(int cipher_suite, const BLOCK_CIPHER **cipher, const DIGEST **digest)
|
||||
{
|
||||
switch (cipher_suite) {
|
||||
case TLS_cipher_ecc_sm4_cbc_sm3:
|
||||
case TLS_cipher_ecc_sm4_gcm_sm3:
|
||||
*cipher = BLOCK_CIPHER_sm4();
|
||||
*digest = DIGEST_sm3();
|
||||
break;
|
||||
default:
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int tlcp_record_encrypt(int cipher_suite,
|
||||
const HMAC_CTX *hmac_ctx, const BLOCK_CIPHER_KEY *key, const uint8_t fixed_iv[4],
|
||||
const uint8_t seq_num[8], const uint8_t *in, size_t inlen,
|
||||
uint8_t *out, size_t *outlen)
|
||||
{
|
||||
switch (cipher_suite) {
|
||||
case TLS_cipher_ecc_sm4_cbc_sm3:
|
||||
if (tls_record_cbc_encrypt(hmac_ctx, key, seq_num, in, inlen, out, outlen) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
case TLS_cipher_ecc_sm4_gcm_sm3:
|
||||
if (tls12_record_gcm_encrypt(key, fixed_iv, seq_num, in, inlen, out, outlen) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int tlcp_record_decrypt(int cipher_suite,
|
||||
const HMAC_CTX *hmac_ctx, const BLOCK_CIPHER_KEY *key, const uint8_t fixed_iv[4],
|
||||
const uint8_t seq_num[8], const uint8_t *in, size_t inlen,
|
||||
uint8_t *out, size_t *outlen)
|
||||
{
|
||||
switch (cipher_suite) {
|
||||
case TLS_cipher_ecc_sm4_cbc_sm3:
|
||||
if (tls_record_cbc_decrypt(hmac_ctx, key, seq_num, in, inlen, out, outlen) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
case TLS_cipher_ecc_sm4_gcm_sm3:
|
||||
if (tls12_record_gcm_decrypt(key, fixed_iv, seq_num, in, inlen, out, outlen) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
ServerKeyExchange
|
||||
@@ -194,7 +262,12 @@ int tlcp_send_client_hello(TLS_CONNECT *conn)
|
||||
uint8_t *pexts = exts;
|
||||
size_t extslen = 0;
|
||||
|
||||
if (digest_init(&conn->dgst_ctx, DIGEST_sm3()) != 1) {
|
||||
if (!conn->ctx->cipher_suites_cnt) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
if (tlcp_cipher_suite_get(conn->ctx->cipher_suites[0], &conn->cipher, &conn->digest) != 1
|
||||
|| digest_init(&conn->dgst_ctx, conn->digest) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
@@ -364,6 +437,11 @@ int tlcp_recv_server_hello(TLS_CONNECT *conn)
|
||||
return -1;
|
||||
}
|
||||
conn->cipher_suite = cipher_suite;
|
||||
if (tlcp_cipher_suite_get(conn->cipher_suite, &conn->cipher, &conn->digest) != 1) {
|
||||
error_print();
|
||||
tls_send_alert(conn, TLS_alert_internal_error);
|
||||
return -1;
|
||||
}
|
||||
|
||||
while (extslen) {
|
||||
int ext_type;
|
||||
@@ -963,7 +1041,8 @@ int tlcp_send_client_finished(TLS_CONNECT *conn)
|
||||
tls_handshake_digest_print(stderr, 0, 0, "client Finished", &conn->dgst_ctx);
|
||||
|
||||
|
||||
if (tls_record_encrypt(&conn->client_write_mac_ctx, &conn->client_write_key,
|
||||
if (tlcp_record_encrypt(conn->cipher_suite,
|
||||
&conn->client_write_mac_ctx, &conn->client_write_key, conn->client_write_iv,
|
||||
conn->client_seq_num, conn->plain_record, conn->plain_recordlen,
|
||||
conn->record, &conn->recordlen) != 1) {
|
||||
|
||||
@@ -1014,7 +1093,8 @@ int tlcp_recv_server_finished(TLS_CONNECT *conn)
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (tls_record_decrypt(&conn->server_write_mac_ctx, &conn->server_write_key,
|
||||
if (tlcp_record_decrypt(conn->cipher_suite,
|
||||
&conn->server_write_mac_ctx, &conn->server_write_key, conn->server_write_iv,
|
||||
conn->server_seq_num, conn->record, conn->recordlen,
|
||||
conn->plain_record, &conn->plain_recordlen) != 1) {
|
||||
error_print();
|
||||
@@ -1241,6 +1321,7 @@ int tlcp_recv_client_hello(TLS_CONNECT *conn)
|
||||
|
||||
switch (conn->cipher_suite) {
|
||||
case TLS_cipher_ecc_sm4_cbc_sm3:
|
||||
case TLS_cipher_ecc_sm4_gcm_sm3:
|
||||
conn->signature_algorithms[0] = TLS_sig_sm2sig_sm3;
|
||||
conn->ecdh_named_curve = 0;
|
||||
break;
|
||||
@@ -1348,6 +1429,12 @@ int tlcp_recv_client_hello(TLS_CONNECT *conn)
|
||||
}
|
||||
}
|
||||
|
||||
if (tlcp_cipher_suite_get(conn->cipher_suite, &conn->cipher, &conn->digest) != 1) {
|
||||
error_print();
|
||||
tls_send_alert(conn, TLS_alert_internal_error);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (server_name) {
|
||||
if (tls_server_name_from_bytes(&host_name, &host_name_len, server_name, server_name_len) != 1) {
|
||||
error_print();
|
||||
@@ -1374,7 +1461,7 @@ int tlcp_recv_client_hello(TLS_CONNECT *conn)
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (digest_init(&conn->dgst_ctx, DIGEST_sm3()) != 1
|
||||
if (digest_init(&conn->dgst_ctx, conn->digest) != 1
|
||||
|| digest_update(&conn->dgst_ctx, conn->record + 5, conn->recordlen - 5) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
@@ -1650,14 +1737,31 @@ static int tlcp_generate_master_secret(TLS_CONNECT *conn)
|
||||
|
||||
static int tlcp_generate_key_block(TLS_CONNECT *conn)
|
||||
{
|
||||
size_t key_block_len;
|
||||
|
||||
if (!conn) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
switch (conn->cipher_suite) {
|
||||
case TLS_cipher_ecc_sm4_gcm_sm3:
|
||||
if (!conn->cipher) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
key_block_len = conn->cipher->key_size * 2 + 8;
|
||||
break;
|
||||
case TLS_cipher_ecc_sm4_cbc_sm3:
|
||||
key_block_len = 96;
|
||||
break;
|
||||
default:
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
if (tls_prf(conn->master_secret, 48, "key expansion",
|
||||
conn->server_random, 32,
|
||||
conn->client_random, 32,
|
||||
96, conn->key_block) != 1) {
|
||||
key_block_len, conn->key_block) != 1) {
|
||||
error_print();
|
||||
tls_send_alert(conn, TLS_alert_internal_error);
|
||||
return -1;
|
||||
@@ -1671,31 +1775,84 @@ static int tlcp_generate_record_keys(TLS_CONNECT *conn)
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
if (hmac_init(&conn->client_write_mac_ctx, DIGEST_sm3(), conn->key_block, 32) != 1
|
||||
|| hmac_init(&conn->server_write_mac_ctx, DIGEST_sm3(), conn->key_block + 32, 32) != 1) {
|
||||
switch (conn->cipher_suite) {
|
||||
case TLS_cipher_ecc_sm4_gcm_sm3:
|
||||
{
|
||||
size_t keylen;
|
||||
|
||||
if (!conn->cipher) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
keylen = conn->cipher->key_size;
|
||||
|
||||
memset(conn->client_write_iv, 0, sizeof(conn->client_write_iv));
|
||||
memset(conn->server_write_iv, 0, sizeof(conn->server_write_iv));
|
||||
memcpy(conn->client_write_iv, conn->key_block + keylen * 2, 4);
|
||||
memcpy(conn->server_write_iv, conn->key_block + keylen * 2 + 4, 4);
|
||||
|
||||
if (block_cipher_set_encrypt_key(&conn->client_write_key, conn->cipher, conn->key_block) != 1
|
||||
|| block_cipher_set_encrypt_key(&conn->server_write_key, conn->cipher, conn->key_block + keylen) != 1) {
|
||||
error_print();
|
||||
tls_send_alert(conn, TLS_alert_internal_error);
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case TLS_cipher_ecc_sm4_cbc_sm3:
|
||||
if (hmac_init(&conn->client_write_mac_ctx, conn->digest, conn->key_block, 32) != 1
|
||||
|| hmac_init(&conn->server_write_mac_ctx, conn->digest, conn->key_block + 32, 32) != 1) {
|
||||
error_print();
|
||||
tls_send_alert(conn, TLS_alert_internal_error);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (conn->is_client) {
|
||||
if (block_cipher_set_encrypt_key(&conn->client_write_key, conn->cipher, conn->key_block + 64) != 1
|
||||
|| block_cipher_set_decrypt_key(&conn->server_write_key, conn->cipher, conn->key_block + 80) != 1) {
|
||||
error_print();
|
||||
tls_send_alert(conn, TLS_alert_internal_error);
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
if (block_cipher_set_decrypt_key(&conn->client_write_key, conn->cipher, conn->key_block + 64) != 1
|
||||
|| block_cipher_set_encrypt_key(&conn->server_write_key, conn->cipher, conn->key_block + 80) != 1) {
|
||||
error_print();
|
||||
tls_send_alert(conn, TLS_alert_internal_error);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
error_print();
|
||||
tls_send_alert(conn, TLS_alert_internal_error);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (conn->is_client) {
|
||||
if (block_cipher_set_encrypt_key(&conn->client_write_key, BLOCK_CIPHER_sm4(), conn->key_block + 64) != 1
|
||||
|| block_cipher_set_decrypt_key(&conn->server_write_key, BLOCK_CIPHER_sm4(), conn->key_block + 80) != 1) {
|
||||
error_print();
|
||||
tls_send_alert(conn, TLS_alert_internal_error);
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
if (block_cipher_set_decrypt_key(&conn->client_write_key, BLOCK_CIPHER_sm4(), conn->key_block + 64) != 1
|
||||
|| block_cipher_set_encrypt_key(&conn->server_write_key, BLOCK_CIPHER_sm4(), conn->key_block + 80) != 1) {
|
||||
error_print();
|
||||
tls_send_alert(conn, TLS_alert_internal_error);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void tlcp_secrets_print(TLS_CONNECT *conn)
|
||||
{
|
||||
if (conn->cipher_suite == TLS_cipher_ecc_sm4_gcm_sm3) {
|
||||
size_t keylen = conn->cipher->key_size;
|
||||
|
||||
format_bytes(stderr, 0, 4, "pre_master_secret", conn->pre_master_secret, 48);
|
||||
format_bytes(stderr, 0, 4, "client_random", conn->client_random, 32);
|
||||
format_bytes(stderr, 0, 4, "server_random", conn->server_random, 32);
|
||||
format_bytes(stderr, 0, 4, "master_secret", conn->master_secret, 48);
|
||||
format_bytes(stderr, 0, 4, "client_write_key", conn->key_block, keylen);
|
||||
format_bytes(stderr, 0, 4, "server_write_key", conn->key_block + keylen, keylen);
|
||||
format_bytes(stderr, 0, 4, "client_write_iv", conn->client_write_iv, 4);
|
||||
format_bytes(stderr, 0, 4, "server_write_iv", conn->server_write_iv, 4);
|
||||
} else {
|
||||
tls_secrets_print(stderr,
|
||||
conn->pre_master_secret, 48,
|
||||
conn->client_random, conn->server_random,
|
||||
conn->master_secret,
|
||||
conn->key_block, 96,
|
||||
0, 4);
|
||||
}
|
||||
}
|
||||
|
||||
int tlcp_generate_keys(TLS_CONNECT *conn)
|
||||
{
|
||||
tls_trace("generate secrets\n");
|
||||
@@ -1709,12 +1866,7 @@ int tlcp_generate_keys(TLS_CONNECT *conn)
|
||||
tls_seq_num_reset(conn->client_seq_num);
|
||||
tls_seq_num_reset(conn->server_seq_num);
|
||||
|
||||
tls_secrets_print(stderr,
|
||||
conn->pre_master_secret, 48,
|
||||
conn->client_random, conn->server_random,
|
||||
conn->master_secret,
|
||||
conn->key_block, 96,
|
||||
0, 4);
|
||||
tlcp_secrets_print(conn);
|
||||
|
||||
return 1;
|
||||
}
|
||||
@@ -1874,7 +2026,8 @@ int tlcp_recv_client_finished(TLS_CONNECT *conn)
|
||||
tls_send_alert(conn, TLS_alert_unexpected_message);
|
||||
return -1;
|
||||
}
|
||||
if (tls_record_decrypt(&conn->client_write_mac_ctx, &conn->client_write_key,
|
||||
if (tlcp_record_decrypt(conn->cipher_suite,
|
||||
&conn->client_write_mac_ctx, &conn->client_write_key, conn->client_write_iv,
|
||||
conn->client_seq_num, conn->record, conn->recordlen,
|
||||
conn->plain_record, &conn->plain_recordlen) != 1) {
|
||||
error_print();
|
||||
@@ -1931,7 +2084,8 @@ int tlcp_send_server_finished(TLS_CONNECT *conn)
|
||||
}
|
||||
tlcp_record_print(stderr, 0, 0, conn->plain_record, conn->plain_recordlen);
|
||||
|
||||
if (tls_record_encrypt(&conn->server_write_mac_ctx, &conn->server_write_key,
|
||||
if (tlcp_record_encrypt(conn->cipher_suite,
|
||||
&conn->server_write_mac_ctx, &conn->server_write_key, conn->server_write_iv,
|
||||
conn->server_seq_num, conn->plain_record, conn->plain_recordlen,
|
||||
conn->record, &conn->recordlen) != 1) {
|
||||
error_print();
|
||||
|
||||
23
src/tls.c
23
src/tls.c
@@ -439,7 +439,7 @@ int tls_cbc_decrypt(const HMAC_CTX *inited_hmac_ctx, const BLOCK_CIPHER_KEY *dec
|
||||
return 1;
|
||||
}
|
||||
|
||||
int tls_record_encrypt(const HMAC_CTX *hmac_ctx, const BLOCK_CIPHER_KEY *cbc_key,
|
||||
int tls_record_cbc_encrypt(const HMAC_CTX *hmac_ctx, const BLOCK_CIPHER_KEY *cbc_key,
|
||||
const uint8_t seq_num[8], const uint8_t *in, size_t inlen,
|
||||
uint8_t *out, size_t *outlen)
|
||||
{
|
||||
@@ -459,7 +459,7 @@ int tls_record_encrypt(const HMAC_CTX *hmac_ctx, const BLOCK_CIPHER_KEY *cbc_key
|
||||
return 1;
|
||||
}
|
||||
|
||||
int tls_record_decrypt(const HMAC_CTX *hmac_ctx, const BLOCK_CIPHER_KEY *cbc_key,
|
||||
int tls_record_cbc_decrypt(const HMAC_CTX *hmac_ctx, const BLOCK_CIPHER_KEY *cbc_key,
|
||||
const uint8_t seq_num[8], const uint8_t *in, size_t inlen,
|
||||
uint8_t *out, size_t *outlen)
|
||||
{
|
||||
@@ -1849,7 +1849,7 @@ static int tls_encrypt_send(TLS_CONNECT *conn, int record_type, const uint8_t *i
|
||||
break;
|
||||
case TLS_cipher_ecdhe_sm4_cbc_sm3:
|
||||
case TLS_cipher_ecdhe_ecdsa_with_aes_128_cbc_sha256:
|
||||
if (tls12_record_cbc_encrypt(hmac_ctx, enc_key, seq_num,
|
||||
if (tls_record_cbc_encrypt(hmac_ctx, enc_key, seq_num,
|
||||
conn->databuf, tls_record_length(conn->databuf),
|
||||
conn->record, &recordlen) != 1) {
|
||||
error_print();
|
||||
@@ -1860,8 +1860,15 @@ static int tls_encrypt_send(TLS_CONNECT *conn, int record_type, const uint8_t *i
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
} else if (conn->protocol == TLS_protocol_tlcp) {
|
||||
if (tlcp_record_encrypt(conn->cipher_suite, hmac_ctx, enc_key, fixed_iv, seq_num,
|
||||
conn->databuf, tls_record_length(conn->databuf),
|
||||
conn->record, &recordlen) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
if (tls_record_encrypt(hmac_ctx, enc_key, seq_num,
|
||||
if (tls_record_cbc_encrypt(hmac_ctx, enc_key, seq_num,
|
||||
conn->databuf, tls_record_length(conn->databuf),
|
||||
conn->record, &recordlen) != 1) {
|
||||
error_print();
|
||||
@@ -1916,8 +1923,14 @@ int tls_decrypt_recv(TLS_CONNECT *conn)
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
} else if (conn->protocol == TLS_protocol_tlcp) {
|
||||
if (tlcp_record_decrypt(conn->cipher_suite, hmac_ctx, dec_key, fixed_iv, seq_num,
|
||||
record, recordlen, conn->databuf, &conn->datalen) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
if (tls_record_decrypt(hmac_ctx, dec_key, seq_num,
|
||||
if (tls_record_cbc_decrypt(hmac_ctx, dec_key, seq_num,
|
||||
record, recordlen,
|
||||
conn->databuf, &conn->datalen) != 1) {
|
||||
error_print();
|
||||
|
||||
222
src/tls12.c
222
src/tls12.c
@@ -14,7 +14,6 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#include <gmssl/rand.h>
|
||||
#include <gmssl/x509.h>
|
||||
#include <gmssl/error.h>
|
||||
#include <gmssl/sm2.h>
|
||||
@@ -43,180 +42,6 @@ int tls12_record_print(FILE *fp, const uint8_t *record, size_t recordlen, int f
|
||||
return tls_record_print(fp, record, recordlen, format, indent);
|
||||
}
|
||||
|
||||
// 这里主要的问题是我们没有 cbc_encrypt_blocks 这个函数啊
|
||||
|
||||
|
||||
void cbc_encrypt_blocks(const BLOCK_CIPHER_KEY *key, uint8_t iv[16],
|
||||
const uint8_t *in, size_t nblocks, uint8_t *out)
|
||||
{
|
||||
const uint8_t *piv = iv;
|
||||
|
||||
while (nblocks--) {
|
||||
size_t i;
|
||||
for (i = 0; i < 16; i++) {
|
||||
out[i] = in[i] ^ piv[i];
|
||||
}
|
||||
block_cipher_encrypt(key, out, out);
|
||||
piv = out;
|
||||
in += 16;
|
||||
out += 16;
|
||||
}
|
||||
|
||||
memcpy(iv, piv, 16);
|
||||
}
|
||||
|
||||
void cbc_decrypt_blocks(const BLOCK_CIPHER_KEY *key, uint8_t iv[16],
|
||||
const uint8_t *in, size_t nblocks, uint8_t *out)
|
||||
{
|
||||
const uint8_t *piv = iv;
|
||||
|
||||
while (nblocks--) {
|
||||
size_t i;
|
||||
block_cipher_decrypt(key, in, out);
|
||||
for (i = 0; i < 16; i++) {
|
||||
out[i] ^= piv[i];
|
||||
}
|
||||
piv = in;
|
||||
in += 16;
|
||||
out += 16;
|
||||
}
|
||||
|
||||
memcpy(iv, piv, 16);
|
||||
}
|
||||
|
||||
|
||||
// 这个函数只有在哈希函数为HASH256时才是正确的
|
||||
int tls12_cbc_encrypt(const HMAC_CTX *inited_hmac_ctx, const BLOCK_CIPHER_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)
|
||||
{
|
||||
HMAC_CTX hmac_ctx;
|
||||
uint8_t last_blocks[32 + 16] = {0};
|
||||
uint8_t iv[16];
|
||||
uint8_t *mac, *padding;
|
||||
size_t maclen;
|
||||
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();
|
||||
return -1;
|
||||
}
|
||||
if ((((size_t)header[3]) << 8) + header[4] != inlen) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
|
||||
rem = (inlen + 32) % 16;
|
||||
memcpy(last_blocks, in + inlen - rem, rem);
|
||||
mac = last_blocks + rem;
|
||||
|
||||
memcpy(&hmac_ctx, inited_hmac_ctx, sizeof(HMAC_CTX));
|
||||
hmac_update(&hmac_ctx, seq_num, 8);
|
||||
hmac_update(&hmac_ctx, header, 5);
|
||||
hmac_update(&hmac_ctx, in, inlen);
|
||||
hmac_finish(&hmac_ctx, mac, &maclen);
|
||||
|
||||
padding = mac + 32;
|
||||
padding_len = 16 - rem - 1;
|
||||
for (i = 0; i <= padding_len; i++) {
|
||||
padding[i] = (uint8_t)padding_len;
|
||||
}
|
||||
|
||||
if (rand_bytes(iv, 16) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
memcpy(out, iv, 16);
|
||||
out += 16;
|
||||
|
||||
if (inlen >= 16) {
|
||||
cbc_encrypt_blocks(enc_key, iv, in, inlen/16, out);
|
||||
out += inlen - rem;
|
||||
}
|
||||
cbc_encrypt_blocks(enc_key, iv, last_blocks, sizeof(last_blocks)/16, out);
|
||||
|
||||
*outlen = 16 + inlen - rem + sizeof(last_blocks);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int tls12_cbc_decrypt(const HMAC_CTX *inited_hmac_ctx, const BLOCK_CIPHER_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)
|
||||
{
|
||||
HMAC_CTX hmac_ctx;
|
||||
uint8_t iv[16];
|
||||
const uint8_t *padding;
|
||||
const uint8_t *mac;
|
||||
uint8_t header[5];
|
||||
int padding_len;
|
||||
uint8_t hmac[32];
|
||||
size_t hmaclen;
|
||||
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_msg("invalid tls cbc ciphertext length %zu\n", inlen);
|
||||
return -1;
|
||||
}
|
||||
|
||||
memcpy(iv, in, 16);
|
||||
|
||||
format_bytes(stderr, 0, 0, "itls12_cbc_decrypt: iv", iv, 16);
|
||||
|
||||
|
||||
in += 16;
|
||||
inlen -= 16;
|
||||
|
||||
cbc_decrypt_blocks(dec_key, iv, in, inlen/16, out);
|
||||
|
||||
format_bytes(stderr, 0, 0, "cbc_decrypt out", out, inlen);
|
||||
|
||||
|
||||
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_puts("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] = (uint8_t)((*outlen) >> 8);
|
||||
header[4] = (uint8_t)(*outlen);
|
||||
mac = padding - 32;
|
||||
|
||||
memcpy(&hmac_ctx, inited_hmac_ctx, sizeof(HMAC_CTX));
|
||||
hmac_update(&hmac_ctx, seq_num, 8);
|
||||
hmac_update(&hmac_ctx, header, 5);
|
||||
hmac_update(&hmac_ctx, out, *outlen);
|
||||
hmac_finish(&hmac_ctx, hmac, &hmaclen);
|
||||
|
||||
if (gmssl_secure_memcmp(mac, hmac, sizeof(hmac)) != 0) {
|
||||
error_puts("tls ciphertext mac check failure\n");
|
||||
return -1;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int tls12_gcm_encrypt(const BLOCK_CIPHER_KEY *key, const uint8_t fixed_iv[4],
|
||||
const uint8_t seq_num[8], const uint8_t header[5],
|
||||
const uint8_t *in, size_t inlen, uint8_t *out, size_t *outlen)
|
||||
@@ -259,26 +84,6 @@ int tls12_gcm_encrypt(const BLOCK_CIPHER_KEY *key, const uint8_t fixed_iv[4],
|
||||
return 1;
|
||||
}
|
||||
|
||||
int tls12_record_cbc_encrypt(const HMAC_CTX *hmac_ctx, const BLOCK_CIPHER_KEY *cbc_key,
|
||||
const uint8_t seq_num[8], const uint8_t *in, size_t inlen,
|
||||
uint8_t *out, size_t *outlen)
|
||||
{
|
||||
if (tls12_cbc_encrypt(hmac_ctx, cbc_key, seq_num, in,
|
||||
in + 5, inlen - 5,
|
||||
out + 5, outlen) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
|
||||
out[0] = in[0];
|
||||
out[1] = in[1];
|
||||
out[2] = in[2];
|
||||
out[3] = (uint8_t)((*outlen) >> 8);
|
||||
out[4] = (uint8_t)(*outlen);
|
||||
(*outlen) += 5;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int tls12_record_gcm_encrypt(const BLOCK_CIPHER_KEY *key, const uint8_t fixed_iv[4],
|
||||
const uint8_t seq_num[8], const uint8_t *in, size_t inlen,
|
||||
uint8_t *out, size_t *outlen)
|
||||
@@ -343,28 +148,7 @@ static int tls12_gcm_decrypt(const BLOCK_CIPHER_KEY *key, const uint8_t fixed_iv
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int tls12_record_cbc_decrypt(const HMAC_CTX *hmac_ctx, const BLOCK_CIPHER_KEY *cbc_key,
|
||||
const uint8_t seq_num[8], const uint8_t *in, size_t inlen,
|
||||
uint8_t *out, size_t *outlen)
|
||||
{
|
||||
if (tls12_cbc_decrypt(hmac_ctx, cbc_key, seq_num, in,
|
||||
in + 5, inlen - 5,
|
||||
out + 5, outlen) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
|
||||
out[0] = in[0];
|
||||
out[1] = in[1];
|
||||
out[2] = in[2];
|
||||
out[3] = (uint8_t)((*outlen) >> 8);
|
||||
out[4] = (uint8_t)(*outlen);
|
||||
(*outlen) += 5;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int tls12_record_gcm_decrypt(const BLOCK_CIPHER_KEY *key, const uint8_t fixed_iv[4],
|
||||
int tls12_record_gcm_decrypt(const BLOCK_CIPHER_KEY *key, const uint8_t fixed_iv[4],
|
||||
const uint8_t seq_num[8], const uint8_t *in, size_t inlen,
|
||||
uint8_t *out, size_t *outlen)
|
||||
{
|
||||
@@ -400,7 +184,7 @@ static int tls12_record_encrypt(int cipher_suite,
|
||||
break;
|
||||
case TLS_cipher_ecdhe_sm4_cbc_sm3:
|
||||
case TLS_cipher_ecdhe_ecdsa_with_aes_128_cbc_sha256:
|
||||
if (tls12_record_cbc_encrypt(hmac_ctx, key, seq_num, in, inlen, out, outlen) != 1) {
|
||||
if (tls_record_cbc_encrypt(hmac_ctx, key, seq_num, in, inlen, out, outlen) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
@@ -427,7 +211,7 @@ int tls12_record_decrypt(int cipher_suite, const HMAC_CTX *hmac_ctx,
|
||||
break;
|
||||
case TLS_cipher_ecdhe_sm4_cbc_sm3:
|
||||
case TLS_cipher_ecdhe_ecdsa_with_aes_128_cbc_sha256:
|
||||
if (tls12_record_cbc_decrypt(hmac_ctx, key, seq_num, in, inlen, out, outlen) != 1) {
|
||||
if (tls_record_cbc_decrypt(hmac_ctx, key, seq_num, in, inlen, out, outlen) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -95,8 +95,12 @@ int tls_cipher_suite_from_name(const char *name)
|
||||
return TLS_cipher_aes_128_gcm_sha256;
|
||||
} else if (!strcmp(name, "TLS_ECDHE_SM4_CBC_SM3")) {
|
||||
return TLS_cipher_ecdhe_sm4_cbc_sm3;
|
||||
} else if (!strcmp(name, "TLS_ECDHE_SM4_GCM_SM3")) {
|
||||
return TLS_cipher_ecdhe_sm4_gcm_sm3;
|
||||
} else if (!strcmp(name, "TLS_ECC_SM4_CBC_SM3")) {
|
||||
return TLS_cipher_ecc_sm4_cbc_sm3;
|
||||
} else if (!strcmp(name, "TLS_ECC_SM4_GCM_SM3")) {
|
||||
return TLS_cipher_ecc_sm4_gcm_sm3;
|
||||
} else if (!strcmp(name, "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256")) {
|
||||
return TLS_cipher_ecdhe_ecdsa_with_aes_128_cbc_sha256;
|
||||
} else if (!strcmp(name, "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256")) {
|
||||
|
||||
@@ -9,6 +9,10 @@
|
||||
|
||||
"Examples\n"
|
||||
"\n"
|
||||
"Supported cipher suites:\n"
|
||||
" TLS_ECC_SM4_GCM_SM3\n"
|
||||
" TLS_ECC_SM4_CBC_SM3\n"
|
||||
"\n"
|
||||
" gmssl tlcp_client -host www.pbc.gov.cn -get / -outcerts certs.pem\n"
|
||||
"\n"
|
||||
" gmssl tlcp_client -host www.pbc.gov.cn -port 443\n"
|
||||
@@ -35,4 +39,3 @@
|
||||
"\n"
|
||||
" gmssl tlcp_server -port 443 -cert double_certs.pem -key signkey.pem -pass 1234 -ex_key enckey.pem -ex_pass 1234\n"
|
||||
" gmssl tlcp_client -host 127.0.0.1 -cacert rootcacert.pem\n"
|
||||
|
||||
|
||||
@@ -52,7 +52,10 @@ int tlcp_server_main(int argc , char **argv)
|
||||
size_t encpasses_cnt = 0;
|
||||
char *cacertfile = NULL;
|
||||
|
||||
int server_ciphers[] = { TLS_cipher_ecc_sm4_cbc_sm3, };
|
||||
int server_ciphers[] = {
|
||||
TLS_cipher_ecc_sm4_gcm_sm3,
|
||||
TLS_cipher_ecc_sm4_cbc_sm3,
|
||||
};
|
||||
|
||||
TLS_CTX ctx;
|
||||
TLS_CONNECT conn;
|
||||
|
||||
Reference in New Issue
Block a user