Skip to content

Commit

Permalink
ssl_ciph.c: update ssl_cipher_get_evp_md_mac
Browse files Browse the repository at this point in the history
  • Loading branch information
rajeev-0 committed Mar 7, 2024
1 parent 099cff0 commit 0d60029
Show file tree
Hide file tree
Showing 5 changed files with 101 additions and 107 deletions.
175 changes: 82 additions & 93 deletions ssl/record/methods/tls13_meth.c
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,28 @@ static int tls13_set_crypto_state(OSSL_RECORD_LAYER *rl, int level,
}
memcpy(rl->iv, iv, ivlen);

/* Integrity only */
if (EVP_CIPHER_is_a(ciph, "NULL")
&& mactype == NID_hmac
&& md != NULL) {
mac = EVP_MAC_fetch(rl->libctx, "HMAC", rl->propq);
if (mac == NULL
|| (mac_ctx = rl->mac_ctx = EVP_MAC_CTX_new(mac)) == NULL) {
EVP_MAC_free(mac);
ERR_raise(ERR_LIB_SSL, ERR_R_INTERNAL_ERROR);
return OSSL_RECORD_RETURN_FATAL;
}
EVP_MAC_free(mac);
*p++ = OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_DIGEST,
(char *)EVP_MD_name(md), 0);
*p = OSSL_PARAM_construct_end();
if (!EVP_MAC_init(mac_ctx, key, keylen, params)) {
ERR_raise(ERR_LIB_SSL, ERR_R_INTERNAL_ERROR);
return OSSL_RECORD_RETURN_FATAL;
}
goto end;
}

ciph_ctx = rl->enc_ctx = EVP_CIPHER_CTX_new();
if (ciph_ctx == NULL) {
ERR_raise(ERR_LIB_SSL, ERR_R_INTERNAL_ERROR);
Expand All @@ -63,26 +85,7 @@ static int tls13_set_crypto_state(OSSL_RECORD_LAYER *rl, int level,
ERR_raise(ERR_LIB_SSL, ERR_R_INTERNAL_ERROR);
return OSSL_RECORD_RETURN_FATAL;
}

/* Integrity only SSL cipher */
if (md != NULL) {
mac = EVP_MAC_fetch(rl->libctx, "HMAC", rl->propq);
if (mac == NULL
|| (mac_ctx = rl->mac_ctx = EVP_MAC_CTX_new(mac)) == NULL) {
EVP_MAC_free(mac);
ERR_raise(ERR_LIB_SSL, ERR_R_INTERNAL_ERROR);
return OSSL_RECORD_RETURN_FATAL;
}

*p++ = OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_DIGEST,
(char *)EVP_MD_name(md), 0);
*p = OSSL_PARAM_construct_end();
if (!EVP_MAC_init(mac_ctx, key, keylen, params)){
ERR_raise(ERR_LIB_SSL, ERR_R_INTERNAL_ERROR);
return OSSL_RECORD_RETURN_FATAL;
}
}

end:
return OSSL_RECORD_RETURN_SUCCESS;
}

Expand All @@ -101,9 +104,8 @@ static int tls13_cipher(OSSL_RECORD_LAYER *rl, TLS_RL_RECORD *recs,
TLS_RL_RECORD *rec = &recs[0];
WPACKET wpkt;
const EVP_CIPHER *cipher;
EVP_MAC_CTX *mac_ctx;
int mode;
int only_mac = 0; /* set for MAC only, no encryption */
EVP_MAC_CTX *mac_ctx = NULL;
int mode, ret = 0;

if (n_recs != 1) {
/* Should not happen */
Expand All @@ -115,35 +117,25 @@ static int tls13_cipher(OSSL_RECORD_LAYER *rl, TLS_RL_RECORD *recs,
staticiv = rl->iv;
nonce = rl->nonce;

cipher = EVP_CIPHER_CTX_get0_cipher(ctx);
if (cipher == NULL) {
if (ctx == NULL && rl->mac_ctx == NULL) {
RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
return 0;
}
mode = EVP_CIPHER_get_mode(cipher);
only_mac = EVP_CIPHER_is_a(cipher, "NULL");

/*
* If we're sending an alert and ctx != NULL then we must be forcing
* plaintext alerts. If we're reading and ctx != NULL then we allow
* plaintext alerts at certain points in the handshake. If we've got this
* far then we have already validated that a plaintext alert is ok here.
*/
if (ctx == NULL || rec->type == SSL3_RT_ALERT) {
if (rec->type == SSL3_RT_ALERT) {
memmove(rec->data, rec->input, rec->length);
rec->input = rec->data;
return 1;
}

if (only_mac)
{
if ((mac_ctx = EVP_MAC_CTX_dup(rl->mac_ctx)) == NULL)
{
RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
return 0;
}
ivlen = EVP_MAC_CTX_get_mac_size(mac_ctx);
}
if (rl->mac_ctx != NULL)
ivlen = EVP_MAC_CTX_get_mac_size(rl->mac_ctx);
else
ivlen = EVP_CIPHER_CTX_get_iv_length(ctx);

Expand Down Expand Up @@ -173,24 +165,6 @@ static int tls13_cipher(OSSL_RECORD_LAYER *rl, TLS_RL_RECORD *recs,
return 0;
}

if (only_mac) {
if (!EVP_MAC_update(mac_ctx, nonce, ivlen))
{
RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
return 0;
}
} else {
if (EVP_CipherInit_ex(ctx, NULL, NULL, NULL, nonce, sending) <= 0
|| (!sending
&& EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG,
rl->taglen,
rec->data + rec->length) <= 0))
{
RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
return 0;
}
}

/* Set up the AAD */
if (!WPACKET_init_static_len(&wpkt, recheader, sizeof(recheader), 0)
|| !WPACKET_put_bytes_u8(&wpkt, rec->type)
Expand All @@ -204,54 +178,69 @@ static int tls13_cipher(OSSL_RECORD_LAYER *rl, TLS_RL_RECORD *recs,
return 0;
}

if (rl->mac_ctx != NULL) {
if ((mac_ctx = EVP_MAC_CTX_dup(rl->mac_ctx)) == NULL
|| !EVP_MAC_update(mac_ctx, nonce, ivlen)
|| !EVP_MAC_update(mac_ctx, recheader, sizeof(recheader))
|| !EVP_MAC_update(mac_ctx, rec->input, rec->length)
|| !EVP_MAC_final(mac_ctx, tag, &taglen, rl->taglen)) {
RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
goto end;
}

if (sending) {
memcpy(rec->data + rec->length, tag, rl->taglen);
rec->length += rl->taglen;
} else if (CRYPTO_memcmp(tag, rec->data + rec->length, rl->taglen) != 0) {
goto end;
}
ret = 1;
goto end;
}

cipher = EVP_CIPHER_CTX_get0_cipher(ctx);
if (cipher == NULL) {
RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
return 0;
}
mode = EVP_CIPHER_get_mode(cipher);

if (EVP_CipherInit_ex(ctx, NULL, NULL, NULL, nonce, sending) <= 0
|| (!sending && EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG,
rl->taglen,
rec->data + rec->length) <= 0)) {
RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
return 0;
}

/*
* For CCM we must explicitly set the total plaintext length before we add
* any AAD.
*/
if (only_mac && (!EVP_MAC_update(mac_ctx, recheader, sizeof(recheader))
|| !EVP_MAC_update(mac_ctx, rec->input, rec->length)
|| !EVP_MAC_final(mac_ctx, tag,
&taglen, rl->taglen)))
{
RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
return 0;
}
if ((mode == EVP_CIPH_CCM_MODE && EVP_CipherUpdate(ctx, NULL, &lenu, NULL,
(unsigned int)rec->length) <= 0) ||
EVP_CipherUpdate(ctx, NULL, &lenu, recheader,
sizeof(recheader)) <= 0 ||
EVP_CipherUpdate(ctx, rec->data, &lenu, rec->input,
(unsigned int)rec->length) <= 0 ||
EVP_CipherFinal_ex(ctx, rec->data + lenu, &lenf) <= 0 ||
(size_t)(lenu + lenf) != rec->length)
{
if ((mode == EVP_CIPH_CCM_MODE
&& EVP_CipherUpdate(ctx, NULL, &lenu, NULL,
(unsigned int)rec->length) <= 0)
|| EVP_CipherUpdate(ctx, NULL, &lenu, recheader,
sizeof(recheader)) <= 0
|| EVP_CipherUpdate(ctx, rec->data, &lenu, rec->input,
(unsigned int)rec->length) <= 0
|| EVP_CipherFinal_ex(ctx, rec->data + lenu, &lenf) <= 0
|| (size_t)(lenu + lenf) != rec->length) {
return 0;
}
if (sending) {
/* Add the tag */
if (only_mac) {
memcpy(rec->data + rec->length, tag, rl->taglen);
} else {
if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_GET_TAG, rl->taglen,
rec->data + rec->length) <= 0)
{
RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
return 0;
}
if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_GET_TAG, rl->taglen,
rec->data + rec->length) <= 0) {
RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
return 0;
}
rec->length += rl->taglen;
} else {
if (only_mac) {
if (CRYPTO_memcmp(tag, rec->data + rec->length, rl->taglen) != 0)
{
RLAYERfatal(rl, SSL_AD_BAD_RECORD_MAC,
SSL_R_DECRYPTION_FAILED_OR_BAD_RECORD_MAC);
return 0;
}
}
}

return 1;
}
ret = 1;
end:
EVP_MAC_CTX_free(mac_ctx);
return ret;
}

static int tls13_validate_record_header(OSSL_RECORD_LAYER *rl,
Expand Down
10 changes: 5 additions & 5 deletions ssl/s3_lib.c
Original file line number Diff line number Diff line change
Expand Up @@ -117,16 +117,16 @@ static SSL_CIPHER tls13_ciphers[] = {
{
1,
TLS1_3_RFC_SHA256_SHA256,
TLS1_3_RFC_SHA256_SHA256, /* RFC name */
TLS1_3_CK_SHA256_SHA256, /* id */
TLS1_3_RFC_SHA256_SHA256,
TLS1_3_CK_SHA256_SHA256,
SSL_kANY,
SSL_aANY,
SSL_eNULL, /* algorithm_enc */
SSL_SHA256, /* algorithm_mac */
SSL_eNULL,
SSL_SHA256,
TLS1_3_VERSION, TLS1_3_VERSION,
0, 0,
SSL_NOT_DEFAULT | SSL_STRONG_NONE,
SSL_HANDSHAKE_MAC_SHA256, /* algorithm2 */
SSL_HANDSHAKE_MAC_SHA256,
0,
256,
}, {
Expand Down
14 changes: 7 additions & 7 deletions ssl/ssl_ciph.c
Original file line number Diff line number Diff line change
Expand Up @@ -482,7 +482,8 @@ static int load_builtin_compressions(void)
int ssl_cipher_get_evp_cipher(SSL_CTX *ctx, const SSL_CIPHER *sslc,
const EVP_CIPHER **enc)
{
int i = ssl_cipher_info_lookup(ssl_cipher_table_cipher, sslc->algorithm_enc);
int i = ssl_cipher_info_lookup(ssl_cipher_table_cipher,
sslc->algorithm_enc);

if (i == -1) {
*enc = NULL;
Expand Down Expand Up @@ -513,28 +514,26 @@ int ssl_cipher_get_evp_md_mac(SSL_CTX *ctx, const SSL_CIPHER *sslc,
int *mac_pkey_type, size_t *mac_secret_size)
{
int i = ssl_cipher_info_lookup(ssl_cipher_table_mac, sslc->algorithm_mac);

if (i == -1) {
*md = NULL;
if (mac_pkey_type != NULL)
*mac_pkey_type = NID_undef;
if (mac_secret_size != NULL)
*mac_secret_size = 0;
if (sslc->algorithm_mac == SSL_AEAD)
mac_pkey_type = NULL;
} else {
const EVP_MD *digest = ctx->ssl_digest_methods[i];

if (digest == NULL
|| !ssl_evp_md_up_ref(digest)) {
return 0;
}
*md = digest;
*md = ctx->ssl_digest_methods[i];
if (mac_pkey_type != NULL)
*mac_pkey_type = ctx->ssl_mac_pkey_id[i];
if (mac_secret_size != NULL)
*mac_secret_size = ctx->ssl_mac_secret_size[i];
}

return 1;
}

Expand Down Expand Up @@ -584,9 +583,10 @@ int ssl_cipher_get_evp(SSL_CTX *ctx, const SSL_SESSION *s,
}

if ((*enc != NULL)
&& (*md != NULL
&& (*md != NULL
|| (EVP_CIPHER_get_flags(*enc) & EVP_CIPH_FLAG_AEAD_CIPHER))
&& (!mac_pkey_type || *mac_pkey_type != NID_undef)) {
&& (c->algorithm_mac == SSL_AEAD
||!mac_pkey_type || *mac_pkey_type != NID_undef)) {
const EVP_CIPHER *evp = NULL;

if (use_etm
Expand Down
4 changes: 2 additions & 2 deletions ssl/tls13_enc.c
Original file line number Diff line number Diff line change
Expand Up @@ -720,8 +720,8 @@ int tls13_change_cipher_state(SSL_CONNECTION *s, int which)
if (!ssl_set_new_record_layer(s, s->version,
direction,
level, secret, hashlen, key, keylen, iv,
ivlen, NULL, 0, cipher, taglen, NID_undef,
mac_md, NULL, md)) {
ivlen, NULL, 0, cipher, taglen,
mac_pkey_type, mac_md, NULL, md)) {
/* SSLfatal already called */
goto err;
}
Expand Down
5 changes: 5 additions & 0 deletions test/sslapitest.c
Original file line number Diff line number Diff line change
Expand Up @@ -3879,6 +3879,8 @@ static const char *ciphersuites[] = {
"TLS_AES_128_CCM_SHA256",
#if !defined(OPENSSL_NO_CHACHA) && !defined(OPENSSL_NO_POLY1305)
"TLS_CHACHA20_POLY1305_SHA256",
#else
NULL,
#endif
#if !defined(OPENSSL_NO_TLS1_3_INTEGRITY_ONLY_CIPHERS)
"TLS_SHA256_SHA256",
Expand Down Expand Up @@ -3906,6 +3908,9 @@ static int early_data_skip_helper(int testtype, int cipher, int idx)
if (is_fips && (cipher == 4 || cipher == 5 || cipher == 6))
return 1;

if (ciphersuites[cipher] == NULL)
return 1;

if (!TEST_true(create_ssl_ctx_pair(libctx, TLS_server_method(),
TLS_client_method(),
TLS1_VERSION, 0,
Expand Down

0 comments on commit 0d60029

Please sign in to comment.