Compare commits

...

4 commits

Author SHA1 Message Date
wllm-rbnt cf9ceb1d07
Merge 594de65d62 into d02412720b 2024-04-24 11:56:27 +08:00
Alexandre Dulaunoy d02412720b
Merge pull request #102 from the-real-tokai/fix-fdatasync-osx
Fix problematic fdatasync() call on macOS
2024-04-23 17:15:07 +02:00
Christian Rosentreter e5f2916b65
Fix problematic fdatasync() call on macOS
The fdatasync call generates a "implicit declaration of function 'fdatasync' is invalid in C99" warning when building for macOS (it's nowhere to be found in the system includes), but linking will eventually work fine because there is an unrelated syscall by the same name (different prototype), so it's not doing what it should. So lets not use it.
2024-04-16 17:49:06 +02:00
William Robinet 594de65d62
Add initial support for openssl 3.x 2023-12-14 16:13:08 +01:00
3 changed files with 110 additions and 69 deletions

View file

@ -54,7 +54,11 @@ static int init_pcap_logger(void *data) {
}
static int deinit_pcap_logger(void) {
fdatasync(pcap_fd);
#if defined(_POSIX_SYNCHRONIZED_IO) && (_POSIX_SYNCHRONIZED_IO > 0)
fdatasync(pcap_fd);
#else
fsync(pcap_fd);
#endif
close(pcap_fd);
return 0;
}

View file

@ -412,42 +412,53 @@ static int tls_check_mac(ssl_rec_decoder *d,
UCHAR *iv,
UINT4 ivlen,
UCHAR *mac) {
HMAC_CTX *hm = HMAC_CTX_new();
if(!hm)
ERETURN(R_NO_MEMORY);
const EVP_MD *md;
UINT4 l;
size_t l;
UCHAR buf[128];
OSSL_PARAM params[2];
EVP_MAC *hmac = EVP_MAC_fetch(NULL, "HMAC", NULL);
EVP_MAC_CTX *mac_ctx = EVP_MAC_CTX_new(hmac);
EVP_MAC_free(hmac);
if(!mac_ctx)
ERETURN(R_NO_MEMORY);
md = EVP_get_digestbyname(digests[d->cs->dig - 0x40]);
HMAC_Init_ex(hm, d->mac_key->data, d->mac_key->len, md, NULL);
if(!md)
ERETURN(R_NOT_FOUND);
params[0] = OSSL_PARAM_construct_utf8_string("digest", digests[d->cs->dig - 0x40], 0);
params[1] = OSSL_PARAM_construct_end();
EVP_MAC_init(mac_ctx, d->mac_key->data, d->mac_key->len, params);
fmt_seq(d->seq, buf);
d->seq++;
HMAC_Update(hm, buf, 8);
EVP_MAC_update(mac_ctx, buf, 8);
buf[0] = ct;
HMAC_Update(hm, buf, 1);
EVP_MAC_update(mac_ctx, buf, 1);
buf[0] = MSB(ver);
buf[1] = LSB(ver);
HMAC_Update(hm, buf, 2);
EVP_MAC_update(mac_ctx, buf, 2);
buf[0] = MSB(datalen);
buf[1] = LSB(datalen);
HMAC_Update(hm, buf, 2);
EVP_MAC_update(mac_ctx, buf, 2);
/* for encrypt-then-mac with an explicit IV */
if(ivlen && iv) {
HMAC_Update(hm, iv, ivlen);
HMAC_Update(hm, data, datalen - ivlen);
EVP_MAC_update(mac_ctx, iv, ivlen);
EVP_MAC_update(mac_ctx, data, datalen - ivlen);
} else
HMAC_Update(hm, data, datalen);
EVP_MAC_update(mac_ctx, data, datalen);
HMAC_Final(hm, buf, &l);
EVP_MAC_final(mac_ctx, buf, &l, sizeof(buf));
if(memcmp(mac, buf, l))
ERETURN(SSL_BAD_MAC);
HMAC_CTX_free(hm);
EVP_MAC_CTX_free(mac_ctx);
return 0;
}

View file

@ -108,7 +108,7 @@ struct ssl_decoder_ {
#ifdef OPENSSL
static int tls_P_hash PROTO_LIST(
(ssl_obj * ssl, Data *secret, Data *seed, const EVP_MD *md, Data *out));
(ssl_obj * ssl, Data *secret, Data *seed, char *md_name, Data *out));
static int tls12_prf PROTO_LIST((ssl_obj * ssl,
Data *secret,
char *usage,
@ -612,9 +612,9 @@ int ssl_process_client_key_exchange(ssl_obj *ssl,
int len) {
#ifdef OPENSSL
int r, _status;
int i;
size_t i;
EVP_PKEY *pk;
const BIGNUM *n;
BIGNUM *n;
/* Remove the master secret if it was there
to force keying material regeneration in
@ -635,12 +635,15 @@ int ssl_process_client_key_exchange(ssl_obj *ssl,
if(EVP_PKEY_id(pk) != EVP_PKEY_RSA)
return -1;
RSA_get0_key(EVP_PKEY_get0_RSA(pk), &n, NULL, NULL);
EVP_PKEY_get_bn_param(pk, "priv", &n);
if((r = r_data_alloc(&d->PMS, BN_num_bytes(n))))
ABORT(r);
i = RSA_private_decrypt(len, msg, d->PMS->data, EVP_PKEY_get0_RSA(pk),
RSA_PKCS1_PADDING);
EVP_PKEY_CTX *ctx = EVP_PKEY_CTX_new(pk, NULL);
EVP_PKEY_decrypt_init(ctx);
EVP_PKEY_decrypt(ctx, d->PMS->data, &i, msg, len);
EVP_PKEY_CTX_free(ctx);
EVP_PKEY_free(pk);
if(i != 48)
ABORT(SSL_BAD_PMS);
@ -678,15 +681,22 @@ abort:
static int tls_P_hash(ssl_obj *ssl,
Data *secret,
Data *seed,
const EVP_MD *md,
char *md_name,
Data *out) {
UCHAR *ptr = out->data;
int left = out->len;
int tocpy;
UCHAR *A;
UCHAR _A[128], tmp[128];
unsigned int A_l, tmp_l;
HMAC_CTX *hm = HMAC_CTX_new();
size_t A_l, tmp_l;
OSSL_PARAM params[2];
EVP_MAC *hmac = EVP_MAC_fetch(NULL, "HMAC", NULL);
EVP_MAC_CTX *mac_ctx = EVP_MAC_CTX_new(hmac);
EVP_MAC_free(hmac);
params[0] = OSSL_PARAM_construct_utf8_string("digest", md_name, 0);
params[1] = OSSL_PARAM_construct_end();
CRDUMPD("P_hash secret", secret);
CRDUMPD("P_hash seed", seed);
@ -695,15 +705,15 @@ static int tls_P_hash(ssl_obj *ssl,
A_l = seed->len;
while(left) {
HMAC_Init_ex(hm, secret->data, secret->len, md, NULL);
HMAC_Update(hm, A, A_l);
HMAC_Final(hm, _A, &A_l);
EVP_MAC_init(mac_ctx, secret->data, secret->len, params);
EVP_MAC_update(mac_ctx, A, A_l);
EVP_MAC_final(mac_ctx, (unsigned char *) &_A, &A_l, sizeof(_A));
A = _A;
HMAC_Init_ex(hm, secret->data, secret->len, md, NULL);
HMAC_Update(hm, A, A_l);
HMAC_Update(hm, seed->data, seed->len);
HMAC_Final(hm, tmp, &tmp_l);
EVP_MAC_init(mac_ctx, secret->data, secret->len, params);
EVP_MAC_update(mac_ctx, A, A_l);
EVP_MAC_update(mac_ctx, seed->data, seed->len);
EVP_MAC_final(mac_ctx, (unsigned char *) &tmp, &tmp_l, sizeof(tmp));
tocpy = MIN(left, tmp_l);
memcpy(ptr, tmp, tocpy);
@ -711,7 +721,7 @@ static int tls_P_hash(ssl_obj *ssl,
left -= tocpy;
}
HMAC_CTX_free(hm);
EVP_MAC_CTX_free(mac_ctx);
CRDUMPD("P_hash out", out);
return 0;
@ -754,9 +764,9 @@ static int tls_prf(ssl_obj *ssl,
memcpy(S1->data, secret->data, S_l);
memcpy(S2->data, secret->data + (secret->len - S_l), S_l);
if((r = tls_P_hash(ssl, S1, seed, EVP_get_digestbyname("MD5"), md5_out)))
if((r = tls_P_hash(ssl, S1, seed, "MD5", md5_out)))
ABORT(r);
if((r = tls_P_hash(ssl, S2, seed, EVP_get_digestbyname("SHA1"), sha_out)))
if((r = tls_P_hash(ssl, S2, seed, "SHA1", sha_out)))
ABORT(r);
for(i = 0; i < out->len; i++)
@ -808,7 +818,7 @@ static int tls12_prf(ssl_obj *ssl,
digests[dgi]));
ERETURN(SSL_BAD_MAC);
}
if((r = tls_P_hash(ssl, secret, seed, md, sha_out)))
if((r = tls_P_hash(ssl, secret, seed, digests[dgi], sha_out)))
ABORT(r);
for(i = 0; i < out->len; i++)
@ -826,15 +836,18 @@ static int ssl3_generate_export_iv(ssl_obj *ssl,
Data *r1,
Data *r2,
Data *out) {
MD5_CTX md5;
UCHAR tmp[16];
unsigned int tmp_len;
MD5_Init(&md5);
MD5_Update(&md5, r1->data, r1->len);
MD5_Update(&md5, r2->data, r2->len);
MD5_Final(tmp, &md5);
EVP_MD_CTX *mdctx;
mdctx = EVP_MD_CTX_new();
EVP_DigestInit(mdctx, EVP_get_digestbyname("MD5"));
EVP_DigestUpdate(mdctx, r1->data, r1->len);
EVP_DigestUpdate(mdctx, r2->data, r2->len);
EVP_DigestFinal_ex(mdctx, tmp, &tmp_len);
EVP_MD_CTX_free(mdctx);
memcpy(out->data, tmp, out->len);
memcpy(out->data, tmp, tmp_len);
return 0;
}
@ -845,12 +858,13 @@ static int ssl3_prf(ssl_obj *ssl,
Data *r1,
Data *r2,
Data *out) {
MD5_CTX md5;
SHA_CTX sha;
EVP_MD_CTX *md5_ctx;
EVP_MD_CTX *sha1_ctx;
Data *rnd1, *rnd2;
int off;
int i = 0, j;
UCHAR buf[20];
unsigned int buf_len;
rnd1 = r1;
rnd2 = r2;
@ -859,12 +873,14 @@ static int ssl3_prf(ssl_obj *ssl,
CRDUMPD("RND1", rnd1);
CRDUMPD("RND2", rnd2);
MD5_Init(&md5);
memset(&sha, 0, sizeof(sha));
SHA1_Init(&sha);
md5_ctx = EVP_MD_CTX_new();
EVP_DigestInit(md5_ctx, EVP_get_digestbyname("MD5"));
sha1_ctx = EVP_MD_CTX_new();
EVP_DigestInit(sha1_ctx, EVP_get_digestbyname("SHA1"));
for(off = 0; off < out->len; off += 16) {
char outbuf[16];
unsigned int outbuf_len;
int tocpy;
i++;
@ -873,38 +889,43 @@ static int ssl3_prf(ssl_obj *ssl,
buf[j] = 64 + i;
}
SHA1_Update(&sha, buf, i);
EVP_DigestUpdate(sha1_ctx, buf, i);
CRDUMP("BUF", buf, i);
if(secret)
SHA1_Update(&sha, secret->data, secret->len);
EVP_DigestUpdate(sha1_ctx, secret->data, secret->len);
CRDUMPD("secret", secret);
if(!strcmp(usage, "client write key") ||
!strcmp(usage, "server write key")) {
SHA1_Update(&sha, rnd2->data, rnd2->len);
EVP_DigestUpdate(sha1_ctx, rnd2->data, rnd2->len);
CRDUMPD("rnd2", rnd2);
SHA1_Update(&sha, rnd1->data, rnd1->len);
EVP_DigestUpdate(sha1_ctx, rnd1->data, rnd1->len);
CRDUMPD("rnd1", rnd1);
} else {
SHA1_Update(&sha, rnd1->data, rnd1->len);
EVP_DigestUpdate(sha1_ctx, rnd1->data, rnd1->len);
CRDUMPD("rnd1", rnd1);
SHA1_Update(&sha, rnd2->data, rnd2->len);
EVP_DigestUpdate(sha1_ctx, rnd2->data, rnd2->len);
CRDUMPD("rnd2", rnd2);
}
SHA1_Final(buf, &sha);
EVP_DigestFinal_ex(sha1_ctx, buf, &buf_len);
EVP_MD_CTX_free(sha1_ctx);
CRDUMP("SHA out", buf, 20);
SHA1_Init(&sha);
sha1_ctx = EVP_MD_CTX_new();
EVP_DigestInit(sha1_ctx, EVP_get_digestbyname("SHA1"));
MD5_Update(&md5, secret->data, secret->len);
MD5_Update(&md5, buf, 20);
MD5_Final((unsigned char *)outbuf, &md5);
EVP_DigestUpdate(md5_ctx, secret->data, secret->len);
EVP_DigestUpdate(md5_ctx, buf, 20);
EVP_DigestFinal_ex(md5_ctx, outbuf, &outbuf_len);
EVP_MD_CTX_free(md5_ctx);
tocpy = MIN(out->len - off, 16);
memcpy(out->data + off, outbuf, tocpy);
CRDUMP("MD5 out", (UCHAR *)outbuf, 16);
MD5_Init(&md5);
md5_ctx = EVP_MD_CTX_new();
EVP_DigestInit(md5_ctx, EVP_get_digestbyname("MD5"));
}
return 0;
@ -914,6 +935,7 @@ static int ssl_generate_keying_material(ssl_obj *ssl, ssl_decoder *d) {
Data *key_block = 0, temp;
UCHAR _iv_c[8], _iv_s[8];
UCHAR _key_c[16], _key_s[16];
unsigned int _key_c_len, _key_s_len;
int needed;
int r, _status;
UCHAR *ptr, *c_wk, *s_wk, *c_mk = NULL, *s_mk = NULL, *c_iv = NULL,
@ -1017,20 +1039,24 @@ static int ssl_generate_keying_material(ssl_obj *ssl, ssl_decoder *d) {
}
if(ssl->version == SSLV3_VERSION) {
MD5_CTX md5;
MD5_Init(&md5);
MD5_Update(&md5, c_wk, ssl->cs->eff_bits / 8);
MD5_Update(&md5, d->client_random->data, d->client_random->len);
MD5_Update(&md5, d->server_random->data, d->server_random->len);
MD5_Final(_key_c, &md5);
EVP_MD_CTX *mdctx;
mdctx = EVP_MD_CTX_new();
EVP_DigestInit(mdctx, EVP_get_digestbyname("MD5"));
EVP_DigestUpdate(mdctx, c_wk, ssl->cs->eff_bits / 8);
EVP_DigestUpdate(mdctx, d->client_random->data, d->client_random->len);
EVP_DigestUpdate(mdctx, d->server_random->data, d->server_random->len);
EVP_DigestFinal_ex(mdctx, _key_c, &_key_c_len);
EVP_MD_CTX_free(mdctx);
c_wk = _key_c;
MD5_Init(&md5);
MD5_Update(&md5, s_wk, ssl->cs->eff_bits / 8);
MD5_Update(&md5, d->server_random->data, d->server_random->len);
MD5_Update(&md5, d->client_random->data, d->client_random->len);
MD5_Final(_key_s, &md5);
mdctx = EVP_MD_CTX_new();
EVP_DigestInit(mdctx, EVP_get_digestbyname("MD5"));
EVP_DigestUpdate(mdctx, s_wk, ssl->cs->eff_bits / 8);
EVP_DigestUpdate(mdctx, d->server_random->data, d->server_random->len);
EVP_DigestUpdate(mdctx, d->client_random->data, d->client_random->len);
EVP_DigestFinal_ex(mdctx, _key_s, &_key_s_len);
EVP_MD_CTX_free(mdctx);
s_wk = _key_s;
} else {
ATTACH_DATA(key_c, _key_c);