Skip to content

Commit

Permalink
fixup! Add support for integrity-only cipher suites for TLS v1.3
Browse files Browse the repository at this point in the history
  • Loading branch information
rajeev-0 committed Apr 8, 2024
1 parent 32f6179 commit 64c88dc
Show file tree
Hide file tree
Showing 6 changed files with 49 additions and 49 deletions.
17 changes: 12 additions & 5 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,18 @@ OpenSSL Releases
- [OpenSSL 1.0.0](#openssl-100)
- [OpenSSL 0.9.x](#openssl-09x)

OpenSSL 3.4
-----------

### Changes between 3.3 and 3.4 [xx XXX xxxx]

* Added to TLS v1.3 support for integrity-only cipher suites
TLS_SHA256_SHA256 and TLS_SHA384_SHA384, as defined in RFC 9150.

This work was sponsored by Siemens AG.

*Rajeev Ranjan*

OpenSSL 3.3
-----------

Expand Down Expand Up @@ -96,11 +108,6 @@ OpenSSL 3.3

*Richard Levitte*

* Added to TLS v1.3 support for integrity-only cipher suites
TLS_SHA256_SHA256 and TLS_SHA384_SHA384, as defined in RFC 9150.

*Rajeev Ranjan, Siemens AG*

* The BLAKE2s hash algorithm matches BLAKE2b's support
for configurable output length.

Expand Down
3 changes: 1 addition & 2 deletions ssl/record/methods/recmethod_local.h
Original file line number Diff line number Diff line change
Expand Up @@ -295,7 +295,7 @@ struct ossl_record_layer_st
/* cryptographic state */
EVP_CIPHER_CTX *enc_ctx;

/* TLSv1.3 MAC ctx, ony used with NULL cipher*/
/* TLSv1.3 MAC ctx, only used with Integrity-Only cipher*/
EVP_MAC_CTX *mac_ctx;

/* Explicit IV length */
Expand Down Expand Up @@ -337,7 +337,6 @@ struct ossl_record_layer_st

/* TLSv1.3 fields */
/* static IV */
unsigned char iv_intern[EVP_MAX_IV_LENGTH];
unsigned char *iv;
unsigned char *nonce;
int allow_plain_alerts;
Expand Down
40 changes: 20 additions & 20 deletions ssl/record/methods/tls13_meth.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,24 +31,20 @@ static int tls13_set_crypto_state(OSSL_RECORD_LAYER *rl, int level,
int enc = (rl->direction == OSSL_RECORD_DIRECTION_WRITE) ? 1 : 0;

rl->iv = OPENSSL_zalloc(ivlen);
if (rl->iv == NULL)
{
if (rl->iv == NULL) {
ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE);
return OSSL_RECORD_RETURN_FATAL;
}

rl->nonce = OPENSSL_zalloc(ivlen);
if (rl->nonce == NULL)
{
if (rl->nonce == NULL) {
ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE);
return OSSL_RECORD_RETURN_FATAL;
}
memcpy(rl->iv, iv, ivlen);

/* Integrity only */
if (EVP_CIPHER_is_a(ciph, "NULL")
&& mactype == NID_hmac
&& md != NULL) {
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) {
Expand Down Expand Up @@ -105,7 +101,7 @@ static int tls13_cipher(OSSL_RECORD_LAYER *rl, TLS_RL_RECORD *recs,
WPACKET wpkt;
const EVP_CIPHER *cipher;
EVP_MAC_CTX *mac_ctx = NULL;
int mode, ret = 0;
int mode;

if (n_recs != 1) {
/* Should not happen */
Expand Down Expand Up @@ -134,6 +130,7 @@ static int tls13_cipher(OSSL_RECORD_LAYER *rl, TLS_RL_RECORD *recs,
return 1;
}

/* For Integrity Only, ivlen is same as MAC size */
if (rl->mac_ctx != NULL)
ivlen = EVP_MAC_CTX_get_mac_size(rl->mac_ctx);
else
Expand Down Expand Up @@ -179,23 +176,28 @@ static int tls13_cipher(OSSL_RECORD_LAYER *rl, TLS_RL_RECORD *recs,
}

if (rl->mac_ctx != NULL) {
int ret = 0;

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;
goto end_mac;
}

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;
} else if (CRYPTO_memcmp(tag, rec->data + rec->length,
rl->taglen) != 0) {
goto end_mac;
}
ret = 1;
goto end;
end_mac:
EVP_MAC_CTX_free(mac_ctx);
return ret;
}

cipher = EVP_CIPHER_CTX_get0_cipher(ctx);
Expand All @@ -206,9 +208,9 @@ static int tls13_cipher(OSSL_RECORD_LAYER *rl, TLS_RL_RECORD *recs,
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)) {
|| (!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;
}
Expand Down Expand Up @@ -236,11 +238,9 @@ static int tls13_cipher(OSSL_RECORD_LAYER *rl, TLS_RL_RECORD *recs,
return 0;
}
rec->length += rl->taglen;
}
ret = 1;
end:
EVP_MAC_CTX_free(mac_ctx);
return ret;
}

return 1;
}

static int tls13_validate_record_header(OSSL_RECORD_LAYER *rl,
Expand Down
9 changes: 4 additions & 5 deletions ssl/ssl_ciph.c
Original file line number Diff line number Diff line change
Expand Up @@ -524,11 +524,10 @@ int ssl_cipher_get_evp_md_mac(SSL_CTX *ctx, const SSL_CIPHER *sslc,
} else {
const EVP_MD *digest = ctx->ssl_digest_methods[i];

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

*md = digest;
if (mac_pkey_type != NULL)
*mac_pkey_type = ctx->ssl_mac_pkey_id[i];
if (mac_secret_size != NULL)
Expand Down Expand Up @@ -586,7 +585,7 @@ int ssl_cipher_get_evp(SSL_CTX *ctx, const SSL_SESSION *s,
&& (*md != NULL
|| (EVP_CIPHER_get_flags(*enc) & EVP_CIPH_FLAG_AEAD_CIPHER))
&& (c->algorithm_mac == SSL_AEAD
||!mac_pkey_type || *mac_pkey_type != NID_undef)) {
|| mac_pkey_type == NULL || *mac_pkey_type != NID_undef)) {
const EVP_CIPHER *evp = NULL;

if (use_etm
Expand Down
27 changes: 11 additions & 16 deletions ssl/tls13_enc.c
Original file line number Diff line number Diff line change
Expand Up @@ -377,7 +377,8 @@ static int derive_secret_key_and_iv(SSL_CONNECTION *s, const EVP_MD *md,
SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
return 0;
}
*keylen = *ivlen = *taglen = (size_t)mac_mdleni;
*ivlen = *taglen = (size_t)mac_mdleni;
*keylen = s->s3.tmp.new_mac_secret_size;
} else {

*keylen = EVP_CIPHER_get_key_length(ciph);
Expand Down Expand Up @@ -473,15 +474,15 @@ int tls13_change_cipher_state(SSL_CONNECTION *s, int which)
const EVP_CIPHER *cipher = NULL;
int mac_pkey_type = NID_undef;
SSL_CTX *sctx = SSL_CONNECTION_GET_CTX(s);
size_t keylen, ivlen = EVP_MAX_IV_LENGTH, taglen, mac_secret_size;
size_t keylen, ivlen = EVP_MAX_IV_LENGTH, taglen;
EVP_MD_CTX *mdctx = NULL;
int level;
int direction = (which & SSL3_CC_READ) != 0 ? OSSL_RECORD_DIRECTION_READ
: OSSL_RECORD_DIRECTION_WRITE;

if (((which & SSL3_CC_CLIENT) && (which & SSL3_CC_WRITE))
|| ((which & SSL3_CC_SERVER) && (which & SSL3_CC_READ))) {
if (which & SSL3_CC_EARLY) {
EVP_MD_CTX *mdctx = NULL;
long handlen;
void *hdata;
unsigned int hashlenui;
Expand Down Expand Up @@ -537,30 +538,24 @@ int tls13_change_cipher_state(SSL_CONNECTION *s, int which)
if (!ssl_cipher_get_evp_cipher(sctx, sslcipher, &cipher)) {
/* Error is already recorded */
SSLfatal_alert(s, SSL_AD_INTERNAL_ERROR);
EVP_MD_CTX_free(mdctx);
goto err;
}

if (!(EVP_CIPHER_flags(cipher) & EVP_CIPH_FLAG_AEAD_CIPHER)) {
/* Cipher is not AEAD */
if (!ssl_cipher_get_evp_md_mac(sctx, sslcipher, &mac_md,
&mac_pkey_type,
&mac_secret_size)){
EVP_MD_CTX_free(mdctx);
goto err;
}
if (((EVP_CIPHER_flags(cipher) & EVP_CIPH_FLAG_AEAD_CIPHER) == 0)
&& (!ssl_cipher_get_evp_md_mac(sctx, sslcipher, &mac_md,
&mac_pkey_type, NULL))) {
SSLfatal_alert(s, SSL_AD_INTERNAL_ERROR);
goto err;
}

md = ssl_md(sctx, sslcipher->algorithm2);
if (md == NULL || !EVP_DigestInit_ex(mdctx, md, NULL)
|| !EVP_DigestUpdate(mdctx, hdata, handlen)
|| !EVP_DigestFinal_ex(mdctx, hashval, &hashlenui)) {
SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
EVP_MD_CTX_free(mdctx);
goto err;
}
hashlen = hashlenui;
EVP_MD_CTX_free(mdctx);

if (!tls13_hkdf_expand(s, md, insecret,
early_exporter_master_secret,
Expand Down Expand Up @@ -730,10 +725,10 @@ int tls13_change_cipher_state(SSL_CONNECTION *s, int which)
err:
if ((which & SSL3_CC_EARLY) != 0) {
/* We up-refed this so now we need to down ref */
if (!(EVP_CIPHER_flags(cipher) & EVP_CIPH_FLAG_AEAD_CIPHER))
if ((EVP_CIPHER_flags(cipher) & EVP_CIPH_FLAG_AEAD_CIPHER) == 0)
ssl_evp_md_free(mac_md);
EVP_MD_CTX_free(mdctx);
ssl_evp_cipher_free(cipher);

}
OPENSSL_cleanse(key, sizeof(key));
OPENSSL_cleanse(secret, sizeof(secret));
Expand Down
2 changes: 1 addition & 1 deletion test/sslapitest.c
Original file line number Diff line number Diff line change
Expand Up @@ -3905,7 +3905,7 @@ static int early_data_skip_helper(int testtype, int cipher, int idx)
unsigned char buf[20];
size_t readbytes, written;

if (is_fips && (cipher == 4 || cipher == 5 || cipher == 6))
if (is_fips && cipher >= 4 )
return 1;

if (ciphersuites[cipher] == NULL)
Expand Down

0 comments on commit 64c88dc

Please sign in to comment.