From 01641d3eafdb4bcf19db054d5354a8c614ab07e4 Mon Sep 17 00:00:00 2001 From: CentOS Sources Date: Tue, 9 May 2023 05:38:41 +0000 Subject: [PATCH] import gnutls-3.7.6-20.el9_2 --- ...gnutls-3.7.7-aes-cbc-padding-support.patch | 433 ++++++++++++++++++ .../gnutls-3.7.8-clear-session-ticket.patch | 215 +++++++++ SOURCES/gnutls-3.7.8-xts-key-check.patch | 220 +++++++++ SPECS/gnutls.spec | 42 +- 4 files changed, 895 insertions(+), 15 deletions(-) create mode 100644 SOURCES/gnutls-3.7.7-aes-cbc-padding-support.patch create mode 100644 SOURCES/gnutls-3.7.8-clear-session-ticket.patch create mode 100644 SOURCES/gnutls-3.7.8-xts-key-check.patch diff --git a/SOURCES/gnutls-3.7.7-aes-cbc-padding-support.patch b/SOURCES/gnutls-3.7.7-aes-cbc-padding-support.patch new file mode 100644 index 0000000..6273a0d --- /dev/null +++ b/SOURCES/gnutls-3.7.7-aes-cbc-padding-support.patch @@ -0,0 +1,433 @@ +diff --color -ruNp a/doc/Makefile.am b/doc/Makefile.am +--- a/doc/Makefile.am 2022-11-15 14:14:10.632725399 +0100 ++++ b/doc/Makefile.am 2022-11-15 14:14:40.252300863 +0100 +@@ -575,6 +575,7 @@ ENUMS += enums/gnutls_certificate_verifi + ENUMS += enums/gnutls_certificate_verify_flags + ENUMS += enums/gnutls_channel_binding_t + ENUMS += enums/gnutls_cipher_algorithm_t ++ENUMS += enums/gnutls_cipher_flags_t + ENUMS += enums/gnutls_close_request_t + ENUMS += enums/gnutls_compression_method_t + ENUMS += enums/gnutls_credentials_type_t +@@ -882,12 +883,16 @@ FUNCS += functions/gnutls_cipher_decrypt + FUNCS += functions/gnutls_cipher_decrypt.short + FUNCS += functions/gnutls_cipher_decrypt2 + FUNCS += functions/gnutls_cipher_decrypt2.short ++FUNCS += functions/gnutls_cipher_decrypt3 ++FUNCS += functions/gnutls_cipher_decrypt3.short + FUNCS += functions/gnutls_cipher_deinit + FUNCS += functions/gnutls_cipher_deinit.short + FUNCS += functions/gnutls_cipher_encrypt + FUNCS += functions/gnutls_cipher_encrypt.short + FUNCS += functions/gnutls_cipher_encrypt2 + FUNCS += functions/gnutls_cipher_encrypt2.short ++FUNCS += functions/gnutls_cipher_encrypt3 ++FUNCS += functions/gnutls_cipher_encrypt3.short + FUNCS += functions/gnutls_cipher_get + FUNCS += functions/gnutls_cipher_get.short + FUNCS += functions/gnutls_cipher_get_block_size +diff --color -ruNp a/doc/manpages/Makefile.am b/doc/manpages/Makefile.am +--- a/doc/manpages/Makefile.am 2022-11-15 14:14:10.634725438 +0100 ++++ b/doc/manpages/Makefile.am 2022-11-15 14:14:40.254300902 +0100 +@@ -273,9 +273,11 @@ APIMANS += gnutls_check_version.3 + APIMANS += gnutls_cipher_add_auth.3 + APIMANS += gnutls_cipher_decrypt.3 + APIMANS += gnutls_cipher_decrypt2.3 ++APIMANS += gnutls_cipher_decrypt3.3 + APIMANS += gnutls_cipher_deinit.3 + APIMANS += gnutls_cipher_encrypt.3 + APIMANS += gnutls_cipher_encrypt2.3 ++APIMANS += gnutls_cipher_encrypt3.3 + APIMANS += gnutls_cipher_get.3 + APIMANS += gnutls_cipher_get_block_size.3 + APIMANS += gnutls_cipher_get_id.3 +diff --color -ruNp a/lib/crypto-api.c b/lib/crypto-api.c +--- a/lib/crypto-api.c 2022-11-15 14:14:11.036733248 +0100 ++++ b/lib/crypto-api.c 2022-11-15 14:14:40.255300921 +0100 +@@ -413,6 +413,166 @@ gnutls_cipher_decrypt2(gnutls_cipher_hd_ + } + + /** ++ * gnutls_cipher_encrypt3: ++ * @handle: is a #gnutls_cipher_hd_t type ++ * @ptext: the data to encrypt ++ * @ptext_len: the length of data to encrypt ++ * @ctext: the encrypted data ++ * @ctext_len: the length of encrypted data (initially must hold the maximum available size) ++ * @flags: flags for padding ++ * ++ * This function will encrypt the given data using the algorithm ++ * specified by the context. For block ciphers, @ptext_len is ++ * typically a multiple of the block size. If not, the caller can ++ * instruct the function to pad the last block according to @flags. ++ * Currently, the only available padding scheme is ++ * %GNUTLS_CIPHER_PADDING_PKCS7. ++ * ++ * If @ctext is not %NULL, it must hold enough space to store ++ * resulting cipher text. To check the required size, this function ++ * can be called with @ctext set to %NULL. Then @ctext_len will be ++ * updated without performing actual encryption. ++ * ++ * Returns: Zero or a negative error code on error. ++ * ++ * Since: 3.7.7 ++ **/ ++int ++gnutls_cipher_encrypt3(gnutls_cipher_hd_t handle, ++ const void *ptext, size_t ptext_len, ++ void *ctext, size_t *ctext_len, ++ unsigned flags) ++{ ++ api_cipher_hd_st *h = handle; ++ const cipher_entry_st *e = h->ctx_enc.e; ++ int block_size = _gnutls_cipher_get_block_size(e); ++ int ret = 0; ++ ++ if (unlikely(ctext_len == NULL)) { ++ return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST); ++ } ++ ++ if (_gnutls_cipher_type(e) == CIPHER_BLOCK && ++ (flags & GNUTLS_CIPHER_PADDING_PKCS7)) { ++ size_t n, r; ++ uint8_t last_block[MAX_CIPHER_BLOCK_SIZE]; ++ const uint8_t *p = ptext; ++ uint8_t *c = ctext; ++ ++ if (!INT_ADD_OK(ptext_len, block_size, &n)) { ++ return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST); ++ } ++ ++ n = (n / block_size) * block_size; ++ ++ if (!ctext) { ++ *ctext_len = n; ++ return 0; ++ } ++ ++ if (*ctext_len < n) { ++ return gnutls_assert_val(GNUTLS_E_SHORT_MEMORY_BUFFER); ++ } ++ ++ /* Encrypt up to the last complete block */ ++ r = ptext_len % block_size; ++ ++ ret = _gnutls_cipher_encrypt2(&h->ctx_enc, ++ ptext, ptext_len - r, ++ ctext, ptext_len - r); ++ if (ret < 0) { ++ goto error; ++ } ++ ++ /* Encrypt the last block with padding */ ++ gnutls_memset(last_block, block_size - r, sizeof(last_block)); ++ if (r > 0) { ++ memcpy(last_block, &p[ptext_len - r], r); ++ } ++ ret = _gnutls_cipher_encrypt2(&h->ctx_enc, ++ last_block, block_size, ++ &c[ptext_len - r], block_size); ++ if (ret < 0) { ++ goto error; ++ } ++ *ctext_len = n; ++ } else { ++ if (!ctext) { ++ *ctext_len = ptext_len; ++ return 0; ++ } ++ ++ ret = _gnutls_cipher_encrypt2(&h->ctx_enc, ptext, ptext_len, ++ ctext, *ctext_len); ++ if (ret < 0) { ++ goto error; ++ } ++ *ctext_len = ptext_len; ++ } ++ ++ error: ++ if (ret < 0) { ++ _gnutls_switch_fips_state(GNUTLS_FIPS140_OP_ERROR); ++ } else { ++ _gnutls_switch_fips_state(GNUTLS_FIPS140_OP_APPROVED); ++ } ++ return ret; ++} ++ ++/** ++ * gnutls_cipher_decrypt3: ++ * @handle: is a #gnutls_cipher_hd_t type ++ * @ctext: the data to decrypt ++ * @ctext_len: the length of data to decrypt ++ * @ptext: the decrypted data ++ * @ptext_len: the available length for decrypted data ++ * @flags: flags for padding ++ * ++ * This function will decrypt the given data using the algorithm ++ * specified by the context. If @flags is specified, padding for the ++ * decrypted data will be removed accordingly and @ptext_len will be ++ * updated. ++ * ++ * Returns: Zero or a negative error code on error. ++ * ++ * Since: 3.7.7 ++ **/ ++int ++gnutls_cipher_decrypt3(gnutls_cipher_hd_t handle, ++ const void *ctext, size_t ctext_len, ++ void *ptext, size_t *ptext_len, ++ unsigned flags) ++{ ++ api_cipher_hd_st *h = handle; ++ int ret; ++ ++ ret = gnutls_cipher_decrypt2(handle, ++ ctext, ctext_len, ++ ptext, *ptext_len); ++ if (ret < 0) { ++ return ret; ++ } ++ ++ if (_gnutls_cipher_type(h->ctx_enc.e) == CIPHER_BLOCK && ++ (flags & GNUTLS_CIPHER_PADDING_PKCS7)) { ++ uint8_t *p = ptext; ++ uint8_t padding = p[*ptext_len - 1]; ++ if (!padding || padding > _gnutls_cipher_get_block_size(h->ctx_enc.e)) { ++ return gnutls_assert_val(GNUTLS_E_DECRYPTION_FAILED); ++ } ++ /* Check that the prior bytes are all PADDING */ ++ for (size_t i = *ptext_len - padding; i < *ptext_len; i++) { ++ if (padding != p[*ptext_len - 1]) { ++ return gnutls_assert_val(GNUTLS_E_DECRYPTION_FAILED); ++ } ++ } ++ *ptext_len -= padding; ++ } ++ ++ return 0; ++} ++ ++/** + * gnutls_cipher_deinit: + * @handle: is a #gnutls_cipher_hd_t type + * +diff --color -ruNp a/lib/includes/gnutls/crypto.h b/lib/includes/gnutls/crypto.h +--- a/lib/includes/gnutls/crypto.h 2022-05-10 13:57:43.000000000 +0200 ++++ b/lib/includes/gnutls/crypto.h 2022-11-15 14:14:40.256300941 +0100 +@@ -49,6 +49,28 @@ int gnutls_cipher_encrypt2(gnutls_cipher + const void *text, size_t textlen, + void *ciphertext, size_t ciphertextlen); + ++/** ++ * gnutls_cipher_flags_t: ++ * @GNUTLS_CIPHER_PADDING_PKCS7: Flag to indicate PKCS#7 padding ++ * ++ * Enumeration of flags to control block cipher padding, used by ++ * gnutls_cipher_encrypt3() and gnutls_cipher_decrypt3(). ++ * ++ * Since: 3.7.7 ++ */ ++typedef enum gnutls_cipher_flags_t { ++ GNUTLS_CIPHER_PADDING_PKCS7 = 1 ++} gnutls_cipher_flags_t; ++ ++int gnutls_cipher_encrypt3(gnutls_cipher_hd_t handle, ++ const void *ptext, size_t ptext_len, ++ void *ctext, size_t *ctext_len, ++ unsigned flags); ++int gnutls_cipher_decrypt3(gnutls_cipher_hd_t handle, ++ const void *ctext, size_t ctext_len, ++ void *ptext, size_t *ptext_len, ++ unsigned flags); ++ + void gnutls_cipher_set_iv(gnutls_cipher_hd_t handle, void *iv, + size_t ivlen); + +diff --color -ruNp a/lib/libgnutls.map b/lib/libgnutls.map +--- a/lib/libgnutls.map 2022-11-15 14:14:11.142735308 +0100 ++++ b/lib/libgnutls.map 2022-11-15 14:14:40.256300941 +0100 +@@ -1403,6 +1403,8 @@ GNUTLS_3_7_7 + { + global: + gnutls_fips140_run_self_tests; ++ gnutls_cipher_encrypt3; ++ gnutls_cipher_decrypt3; + local: + *; + } GNUTLS_3_7_5; +diff --color -ruNp a/tests/cipher-padding.c b/tests/cipher-padding.c +--- a/tests/cipher-padding.c 1970-01-01 01:00:00.000000000 +0100 ++++ b/tests/cipher-padding.c 2022-11-15 14:14:40.258300980 +0100 +@@ -0,0 +1,160 @@ ++/* ++ * Copyright (C) 2022 Red Hat, Inc. ++ * ++ * Author: Daiki Ueno ++ * ++ * This file is part of GnuTLS. ++ * ++ * The GnuTLS is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU Lesser General Public License ++ * as published by the Free Software Foundation; either version 2.1 of ++ * the License, or (at your option) any later version. ++ * ++ * This library is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public License ++ * along with this program. If not, see ++ * ++ */ ++ ++#include ++ ++#include ++#include ++#include ++#include ++#include "utils.h" ++ ++static void tls_log_func(int level, const char *str) ++{ ++ fprintf(stderr, "<%d>| %s", level, str); ++} ++ ++#define CLAMP(x, b) (((x) + (b)) / (b)) * (b) ++ ++static void ++start(gnutls_cipher_algorithm_t algo, size_t plaintext_size, unsigned int flags) ++{ ++ int ret; ++ gnutls_cipher_hd_t ch; ++ uint8_t key16[64]; ++ uint8_t iv16[32]; ++ uint8_t plaintext[128]; ++ uint8_t ciphertext[128]; ++ size_t block_size; ++ size_t size; ++ gnutls_datum_t key, iv; ++ ++ success("%s %zu %u\n", ++ gnutls_cipher_get_name(algo), plaintext_size, flags); ++ ++ block_size = gnutls_cipher_get_block_size(algo); ++ ++ key.data = key16; ++ key.size = gnutls_cipher_get_key_size(algo); ++ assert(key.size <= sizeof(key16)); ++ ++ iv.data = iv16; ++ iv.size = gnutls_cipher_get_iv_size(algo); ++ assert(iv.size <= sizeof(iv16)); ++ ++ memset(iv.data, 0xff, iv.size); ++ memset(key.data, 0xfe, key.size); ++ memset(plaintext, 0xfa, sizeof(plaintext)); ++ ++ ret = gnutls_cipher_init(&ch, algo, &key, &iv); ++ if (ret < 0) { ++ fail("gnutls_cipher_init failed\n"); ++ } ++ ++ /* Check overflow if PKCS#7 is requested */ ++ if (flags & GNUTLS_CIPHER_PADDING_PKCS7) { ++ ret = gnutls_cipher_encrypt3(ch, ++ plaintext, SIZE_MAX, ++ NULL, &size, ++ flags); ++ if (ret != GNUTLS_E_INVALID_REQUEST) { ++ fail("gnutls_cipher_encrypt3 succeeded\n"); ++ } ++ } ++ ++ /* Get the ciphertext size */ ++ ret = gnutls_cipher_encrypt3(ch, ++ plaintext, plaintext_size, ++ NULL, &size, ++ flags); ++ if (ret < 0) { ++ fail("gnutls_cipher_encrypt3 failed\n"); ++ } ++ ++ if (flags & GNUTLS_CIPHER_PADDING_PKCS7) { ++ if (size <= plaintext_size) { ++ fail("no padding appended\n"); ++ } ++ if (size != CLAMP(plaintext_size, block_size)) { ++ fail("size does not match: %zu (expected %zu)\n", ++ size, CLAMP(plaintext_size, block_size)); ++ } ++ } else { ++ if (size != plaintext_size) { ++ fail("size does not match: %zu (expected %zu)\n", ++ size, plaintext_size); ++ } ++ } ++ ++ /* Encrypt with padding */ ++ ret = gnutls_cipher_encrypt3(ch, ++ plaintext, plaintext_size, ++ ciphertext, &size, ++ flags); ++ if (ret < 0) { ++ fail("gnutls_cipher_encrypt3 failed\n"); ++ } ++ ++ /* Decrypt with padding */ ++ ret = gnutls_cipher_decrypt3(ch, ++ ciphertext, size, ++ ciphertext, &size, ++ flags); ++ if (ret < 0) { ++ fail("gnutls_cipher_encrypt3 failed\n"); ++ } ++ ++ if (size != plaintext_size) { ++ fail("size does not match: %zu (expected %zu)\n", ++ size, plaintext_size); ++ } ++ ++ if (memcmp(ciphertext, plaintext, size) != 0) { ++ fail("plaintext does not match\n"); ++ } ++ ++ gnutls_cipher_deinit(ch); ++} ++ ++void doit(void) { ++ int ret; ++ ++ gnutls_global_set_log_function(tls_log_func); ++ if (debug) { ++ gnutls_global_set_log_level(4711); ++ } ++ ++ ret = global_init(); ++ if (ret < 0) { ++ fail("Cannot initialize library\n"); ++ } ++ ++ start(GNUTLS_CIPHER_AES_128_CBC, 0, GNUTLS_CIPHER_PADDING_PKCS7); ++ start(GNUTLS_CIPHER_AES_128_CBC, 11, GNUTLS_CIPHER_PADDING_PKCS7); ++ start(GNUTLS_CIPHER_AES_128_CBC, 77, GNUTLS_CIPHER_PADDING_PKCS7); ++ start(GNUTLS_CIPHER_AES_128_CBC, 80, GNUTLS_CIPHER_PADDING_PKCS7); ++ ++ start(GNUTLS_CIPHER_AES_128_CBC, 0, 0); ++ start(GNUTLS_CIPHER_AES_128_CBC, 80, 0); ++ ++ gnutls_global_deinit(); ++} +diff --color -ruNp a/tests/Makefile.am b/tests/Makefile.am +--- a/tests/Makefile.am 2022-11-15 14:14:11.144735347 +0100 ++++ b/tests/Makefile.am 2022-11-15 14:14:40.257300960 +0100 +@@ -233,7 +233,7 @@ ctests += mini-record-2 simple gnutls_hm + tls13-without-timeout-func buffer status-request-revoked \ + set_x509_ocsp_multi_cli kdf-api keylog-func handshake-write \ + x509cert-dntypes id-on-xmppAddr tls13-compat-mode ciphersuite-name \ +- x509-upnconstraint xts-key-check pkcs7-verify-double-free \ ++ x509-upnconstraint cipher-padding xts-key-check pkcs7-verify-double-free \ + fips-rsa-sizes tls12-rehandshake-ticket + + ctests += tls-channel-binding diff --git a/SOURCES/gnutls-3.7.8-clear-session-ticket.patch b/SOURCES/gnutls-3.7.8-clear-session-ticket.patch new file mode 100644 index 0000000..5c78c73 --- /dev/null +++ b/SOURCES/gnutls-3.7.8-clear-session-ticket.patch @@ -0,0 +1,215 @@ +diff --color -ruNp a/lib/ext/session_ticket.c b/lib/ext/session_ticket.c +--- a/lib/ext/session_ticket.c 2022-05-10 13:55:00.000000000 +0200 ++++ b/lib/ext/session_ticket.c 2022-11-15 13:30:20.491830382 +0100 +@@ -624,6 +624,12 @@ gnutls_session_ticket_enable_server(gnut + return 0; + } + ++void ++_gnutls_session_ticket_disable_server(gnutls_session_t session) ++{ ++ session->internals.flags |= GNUTLS_NO_TICKETS; ++} ++ + /* + * Return zero if session tickets haven't been enabled. + */ +diff --color -ruNp a/lib/ext/session_ticket.h b/lib/ext/session_ticket.h +--- a/lib/ext/session_ticket.h 2022-02-22 15:34:48.000000000 +0100 ++++ b/lib/ext/session_ticket.h 2022-11-15 13:30:20.491830382 +0100 +@@ -36,5 +36,6 @@ int _gnutls_encrypt_session_ticket(gnutl + int _gnutls_decrypt_session_ticket(gnutls_session_t session, + const gnutls_datum_t *ticket_data, + gnutls_datum_t *state); ++void _gnutls_session_ticket_disable_server(gnutls_session_t session); + + #endif /* GNUTLS_LIB_EXT_SESSION_TICKET_H */ +diff --color -ruNp a/lib/libgnutls.map b/lib/libgnutls.map +--- a/lib/libgnutls.map 2022-11-15 13:12:57.781688194 +0100 ++++ b/lib/libgnutls.map 2022-11-15 13:30:20.492830401 +0100 +@@ -1510,4 +1510,6 @@ GNUTLS_PRIVATE_3_4 { + _gnutls_buffer_clear; + # needed by tests/cipher-alignment + _gnutls_crypto_register_cipher; ++ # needed by tests/tls12-rehandshake-cert-ticket ++ _gnutls_session_ticket_disable_server; + } GNUTLS_3_4; +diff --color -ruNp a/lib/state.c b/lib/state.c +--- a/lib/state.c 2022-05-16 17:10:08.000000000 +0200 ++++ b/lib/state.c 2022-11-15 13:30:20.493830420 +0100 +@@ -545,6 +545,7 @@ void _gnutls_handshake_internal_state_cl + session->internals.tfo.connect_addrlen = 0; + session->internals.tfo.connect_only = 0; + session->internals.early_data_received = 0; ++ session->internals.session_ticket_renew = 0; + } + + /** +diff --color -ruNp a/tests/Makefile.am b/tests/Makefile.am +--- a/tests/Makefile.am 2022-11-15 13:12:58.209696462 +0100 ++++ b/tests/Makefile.am 2022-11-15 13:30:20.494830440 +0100 +@@ -234,7 +234,7 @@ ctests += mini-record-2 simple gnutls_hm + set_x509_ocsp_multi_cli kdf-api keylog-func handshake-write \ + x509cert-dntypes id-on-xmppAddr tls13-compat-mode ciphersuite-name \ + x509-upnconstraint xts-key-check pkcs7-verify-double-free \ +- fips-rsa-sizes ++ fips-rsa-sizes tls12-rehandshake-ticket + + ctests += tls-channel-binding + +diff --color -ruNp a/tests/tls12-rehandshake-ticket.c b/tests/tls12-rehandshake-ticket.c +--- a/tests/tls12-rehandshake-ticket.c 1970-01-01 01:00:00.000000000 +0100 ++++ b/tests/tls12-rehandshake-ticket.c 2022-11-15 13:30:20.495830459 +0100 +@@ -0,0 +1,152 @@ ++/* ++ * Copyright (C) 2022 Red Hat, Inc. ++ * ++ * Author: Daiki Ueno ++ * ++ * This file is part of GnuTLS. ++ * ++ * GnuTLS is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 3 of the License, or ++ * (at your option) any later version. ++ * ++ * GnuTLS is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public License ++ * along with this program. If not, see ++ */ ++ ++#ifdef HAVE_CONFIG_H ++#include ++#endif ++ ++#include ++#include ++#include "cert-common.h" ++ ++#include "utils.h" ++#include "eagain-common.h" ++ ++const char *side = ""; ++ ++static void tls_log_func(int level, const char *str) ++{ ++ fprintf(stderr, "%s|<%d>| %s", side, level, str); ++} ++ ++#define MAX_BUF 1024 ++ ++void _gnutls_session_ticket_disable_server(gnutls_session_t session); ++ ++static void run(void) ++{ ++ char buffer[MAX_BUF + 1]; ++ /* Server stuff. */ ++ gnutls_certificate_credentials_t scred; ++ gnutls_session_t server; ++ gnutls_datum_t session_ticket_key = { NULL, 0 }; ++ int sret; ++ /* Client stuff. */ ++ gnutls_certificate_credentials_t ccred; ++ gnutls_session_t client; ++ int cret; ++ ++ /* General init. */ ++ global_init(); ++ gnutls_global_set_log_function(tls_log_func); ++ if (debug) ++ gnutls_global_set_log_level(9); ++ ++ /* Init server */ ++ assert(gnutls_certificate_allocate_credentials(&scred) >= 0); ++ assert(gnutls_certificate_set_x509_key_mem(scred, ++ &server_ca3_localhost_cert, ++ &server_ca3_key, ++ GNUTLS_X509_FMT_PEM) >= 0); ++ assert(gnutls_certificate_set_x509_trust_mem(scred, ++ &ca3_cert, ++ GNUTLS_X509_FMT_PEM) >= 0); ++ ++ assert(gnutls_init(&server, GNUTLS_SERVER) >= 0); ++ gnutls_certificate_server_set_request(server, GNUTLS_CERT_REQUEST); ++ assert(gnutls_priority_set_direct(server, ++ "NORMAL:-VERS-TLS-ALL:+VERS-TLS1.1:+VERS-TLS1.2", ++ NULL) >= 0); ++ ++ gnutls_credentials_set(server, GNUTLS_CRD_CERTIFICATE, scred); ++ gnutls_transport_set_push_function(server, server_push); ++ gnutls_transport_set_pull_function(server, server_pull); ++ gnutls_transport_set_ptr(server, server); ++ ++ gnutls_session_ticket_key_generate(&session_ticket_key); ++ gnutls_session_ticket_enable_server(server, &session_ticket_key); ++ ++ /* Init client */ ++ assert(gnutls_certificate_allocate_credentials(&ccred) >= 0); ++ assert(gnutls_certificate_set_x509_key_mem ++ (ccred, &cli_ca3_cert_chain, &cli_ca3_key, GNUTLS_X509_FMT_PEM) >= 0); ++ assert(gnutls_certificate_set_x509_trust_mem ++ (ccred, &ca3_cert, GNUTLS_X509_FMT_PEM) >= 0); ++ ++ gnutls_init(&client, GNUTLS_CLIENT); ++ assert(gnutls_priority_set_direct(client, ++ "NORMAL:-VERS-TLS-ALL:+VERS-TLS1.1:+VERS-TLS1.2", ++ NULL) >= 0); ++ ++ assert(gnutls_credentials_set(client, GNUTLS_CRD_CERTIFICATE, ccred) >= 0); ++ ++ gnutls_transport_set_push_function(client, client_push); ++ gnutls_transport_set_pull_function(client, client_pull); ++ gnutls_transport_set_ptr(client, client); ++ ++ HANDSHAKE(client, server); ++ ++ /* Server initiates rehandshake */ ++ switch_side("server"); ++ sret = gnutls_rehandshake(server); ++ if (sret < 0) { ++ fail("Error sending %d byte packet: %s\n", ++ (int)sizeof(buffer), gnutls_strerror(sret)); ++ } else if (debug) ++ success("server: starting rehandshake\n"); ++ ++ /* Stop sending session ticket */ ++ _gnutls_session_ticket_disable_server(server); ++ ++ /* Client gets notified with rehandshake */ ++ switch_side("client"); ++ do { ++ do { ++ cret = gnutls_record_recv(client, buffer, MAX_BUF); ++ } while (cret == GNUTLS_E_AGAIN || cret == GNUTLS_E_INTERRUPTED); ++ } while (cret > 0); ++ ++ if (cret != GNUTLS_E_REHANDSHAKE) { ++ fail("client: Error receiving rehandshake: %s\n", ++ gnutls_strerror(cret)); ++ } ++ ++ HANDSHAKE(client, server); ++ ++ gnutls_bye(client, GNUTLS_SHUT_WR); ++ gnutls_bye(server, GNUTLS_SHUT_WR); ++ ++ gnutls_deinit(client); ++ gnutls_deinit(server); ++ ++ gnutls_certificate_free_credentials(scred); ++ gnutls_certificate_free_credentials(ccred); ++ ++ gnutls_free(session_ticket_key.data); ++ ++ gnutls_global_deinit(); ++ reset_buffers(); ++} ++ ++void doit(void) ++{ ++ run(); ++} diff --git a/SOURCES/gnutls-3.7.8-xts-key-check.patch b/SOURCES/gnutls-3.7.8-xts-key-check.patch new file mode 100644 index 0000000..a922f93 --- /dev/null +++ b/SOURCES/gnutls-3.7.8-xts-key-check.patch @@ -0,0 +1,220 @@ +diff --color -ruNp a/lib/accelerated/x86/aes-xts-x86-aesni.c b/lib/accelerated/x86/aes-xts-x86-aesni.c +--- a/lib/accelerated/x86/aes-xts-x86-aesni.c 2022-03-02 12:38:09.000000000 +0100 ++++ b/lib/accelerated/x86/aes-xts-x86-aesni.c 2022-11-07 14:12:38.476982750 +0100 +@@ -73,7 +73,6 @@ x86_aes_xts_cipher_setkey(void *_ctx, co + /* Check key block according to FIPS-140-2 IG A.9 */ + if (_gnutls_fips_mode_enabled()){ + if (gnutls_memcmp(key, key + (keysize / 2), keysize / 2) == 0) { +- _gnutls_switch_lib_state(LIB_STATE_ERROR); + return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST); + } + } +diff --color -ruNp a/lib/nettle/cipher.c b/lib/nettle/cipher.c +--- a/lib/nettle/cipher.c 2022-11-07 14:10:13.672085930 +0100 ++++ b/lib/nettle/cipher.c 2022-11-07 14:12:38.477982770 +0100 +@@ -448,12 +448,14 @@ _gcm_decrypt(struct nettle_cipher_ctx *c + length, dst, src); + } + +-static void _des_set_key(struct des_ctx *ctx, const uint8_t *key) ++static void ++_des_set_key(struct des_ctx *ctx, const uint8_t *key) + { + des_set_key(ctx, key); + } + +-static void _des3_set_key(struct des3_ctx *ctx, const uint8_t *key) ++static void ++_des3_set_key(struct des3_ctx *ctx, const uint8_t *key) + { + des3_set_key(ctx, key); + } +@@ -477,50 +479,6 @@ _cfb8_decrypt(struct nettle_cipher_ctx * + } + + static void +-_xts_aes128_set_encrypt_key(struct xts_aes128_key *xts_key, +- const uint8_t *key) +-{ +- if (_gnutls_fips_mode_enabled() && +- gnutls_memcmp(key, key + AES128_KEY_SIZE, AES128_KEY_SIZE) == 0) +- _gnutls_switch_lib_state(LIB_STATE_ERROR); +- +- xts_aes128_set_encrypt_key(xts_key, key); +-} +- +-static void +-_xts_aes128_set_decrypt_key(struct xts_aes128_key *xts_key, +- const uint8_t *key) +-{ +- if (_gnutls_fips_mode_enabled() && +- gnutls_memcmp(key, key + AES128_KEY_SIZE, AES128_KEY_SIZE) == 0) +- _gnutls_switch_lib_state(LIB_STATE_ERROR); +- +- xts_aes128_set_decrypt_key(xts_key, key); +-} +- +-static void +-_xts_aes256_set_encrypt_key(struct xts_aes256_key *xts_key, +- const uint8_t *key) +-{ +- if (_gnutls_fips_mode_enabled() && +- gnutls_memcmp(key, key + AES256_KEY_SIZE, AES256_KEY_SIZE) == 0) +- _gnutls_switch_lib_state(LIB_STATE_ERROR); +- +- xts_aes256_set_encrypt_key(xts_key, key); +-} +- +-static void +-_xts_aes256_set_decrypt_key(struct xts_aes256_key *xts_key, +- const uint8_t *key) +-{ +- if (_gnutls_fips_mode_enabled() && +- gnutls_memcmp(key, key + AES256_KEY_SIZE, AES256_KEY_SIZE) == 0) +- _gnutls_switch_lib_state(LIB_STATE_ERROR); +- +- xts_aes256_set_decrypt_key(xts_key, key); +-} +- +-static void + _xts_aes128_encrypt(struct nettle_cipher_ctx *ctx, size_t length, uint8_t * dst, + const uint8_t * src) + { +@@ -1041,8 +999,8 @@ static const struct nettle_cipher_st bui + .ctx_size = sizeof(struct xts_aes128_key), + .encrypt = _xts_aes128_encrypt, + .decrypt = _xts_aes128_decrypt, +- .set_encrypt_key = (nettle_set_key_func*)_xts_aes128_set_encrypt_key, +- .set_decrypt_key = (nettle_set_key_func*)_xts_aes128_set_decrypt_key, ++ .set_encrypt_key = (nettle_set_key_func*)xts_aes128_set_encrypt_key, ++ .set_decrypt_key = (nettle_set_key_func*)xts_aes128_set_decrypt_key, + .max_iv_size = AES_BLOCK_SIZE, + }, + { .algo = GNUTLS_CIPHER_AES_256_XTS, +@@ -1052,8 +1010,8 @@ static const struct nettle_cipher_st bui + .ctx_size = sizeof(struct xts_aes256_key), + .encrypt = _xts_aes256_encrypt, + .decrypt = _xts_aes256_decrypt, +- .set_encrypt_key = (nettle_set_key_func*)_xts_aes256_set_encrypt_key, +- .set_decrypt_key = (nettle_set_key_func*)_xts_aes256_set_decrypt_key, ++ .set_encrypt_key = (nettle_set_key_func*)xts_aes256_set_encrypt_key, ++ .set_decrypt_key = (nettle_set_key_func*)xts_aes256_set_decrypt_key, + .max_iv_size = AES_BLOCK_SIZE, + }, + { .algo = GNUTLS_CIPHER_AES_128_SIV, +@@ -1144,6 +1102,21 @@ wrap_nettle_cipher_setkey(void *_ctx, co + return 0; + } + ++ switch (ctx->cipher->algo) { ++ case GNUTLS_CIPHER_AES_128_XTS: ++ if (_gnutls_fips_mode_enabled() && ++ gnutls_memcmp(key, (char *)key + AES128_KEY_SIZE, AES128_KEY_SIZE) == 0) ++ return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST); ++ break; ++ case GNUTLS_CIPHER_AES_256_XTS: ++ if (_gnutls_fips_mode_enabled() && ++ gnutls_memcmp(key, (char *)key + AES256_KEY_SIZE, AES256_KEY_SIZE) == 0) ++ return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST); ++ break; ++ default: ++ break; ++ } ++ + if (ctx->enc) + ctx->cipher->set_encrypt_key(ctx->ctx_ptr, key); + else +diff --color -ruNp a/tests/Makefile.am b/tests/Makefile.am +--- a/tests/Makefile.am 2022-11-07 14:10:13.836089211 +0100 ++++ b/tests/Makefile.am 2022-11-07 14:12:38.478982790 +0100 +@@ -233,7 +233,7 @@ ctests += mini-record-2 simple gnutls_hm + tls13-without-timeout-func buffer status-request-revoked \ + set_x509_ocsp_multi_cli kdf-api keylog-func handshake-write \ + x509cert-dntypes id-on-xmppAddr tls13-compat-mode ciphersuite-name \ +- x509-upnconstraint pkcs7-verify-double-free \ ++ x509-upnconstraint xts-key-check pkcs7-verify-double-free \ + fips-rsa-sizes + + ctests += tls-channel-binding +diff --color -ruNp a/tests/xts-key-check.c b/tests/xts-key-check.c +--- a/tests/xts-key-check.c 1970-01-01 01:00:00.000000000 +0100 ++++ b/tests/xts-key-check.c 2022-11-07 14:12:38.478982790 +0100 +@@ -0,0 +1,78 @@ ++/* ++ * Copyright (C) 2022 Red Hat, Inc. ++ * ++ * Author: Zoltan Fridrich ++ * ++ * This file is part of GnuTLS. ++ * ++ * GnuTLS is free software: you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License as published by ++ * the Free Software Foundation, either version 3 of the License, or ++ * (at your option) any later version. ++ * ++ * GnuTLS is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with GnuTLS. If not, see . ++ */ ++ ++#ifdef HAVE_CONFIG_H ++#include ++#endif ++ ++#include ++ ++#include "utils.h" ++ ++static void test_xts_check(gnutls_cipher_algorithm_t alg) ++{ ++ int ret; ++ gnutls_cipher_hd_t ctx; ++ gnutls_datum_t key, iv; ++ ++ iv.size = gnutls_cipher_get_iv_size(alg); ++ iv.data = gnutls_malloc(iv.size); ++ if (iv.data == NULL) ++ fail("Error: %s\n", gnutls_strerror(GNUTLS_E_MEMORY_ERROR)); ++ gnutls_memset(iv.data, 0xf0, iv.size); ++ ++ key.size = gnutls_cipher_get_key_size(alg); ++ key.data = gnutls_malloc(key.size); ++ if (key.data == NULL) { ++ gnutls_free(iv.data); ++ fail("Error: %s\n", gnutls_strerror(GNUTLS_E_MEMORY_ERROR)); ++ } ++ gnutls_memset(key.data, 0xf0, key.size); ++ ++ ret = gnutls_cipher_init(&ctx, alg, &key, &iv); ++ if (ret == GNUTLS_E_SUCCESS) { ++ gnutls_cipher_deinit(ctx); ++ gnutls_free(iv.data); ++ gnutls_free(key.data); ++ fail("cipher initialization should fail for key1 == key2\n"); ++ } ++ ++ key.data[0] = 0xff; ++ ++ ret = gnutls_cipher_init(&ctx, alg, &key, &iv); ++ gnutls_free(iv.data); ++ gnutls_free(key.data); ++ ++ if (ret == GNUTLS_E_SUCCESS) ++ gnutls_cipher_deinit(ctx); ++ else ++ fail("cipher initialization should succeed with key1 != key2" ++ "\n%s\n", gnutls_strerror(ret)); ++} ++ ++void doit(void) ++{ ++ if (!gnutls_fips140_mode_enabled()) ++ exit(77); ++ ++ test_xts_check(GNUTLS_CIPHER_AES_128_XTS); ++ test_xts_check(GNUTLS_CIPHER_AES_256_XTS); ++} diff --git a/SPECS/gnutls.spec b/SPECS/gnutls.spec index b20da97..ae6987d 100644 --- a/SPECS/gnutls.spec +++ b/SPECS/gnutls.spec @@ -13,7 +13,7 @@ print(string.sub(hash, 0, 16)) } Version: 3.7.6 -Release: 18%{?dist} +Release: 20%{?dist} # not upstreamed Patch: gnutls-3.6.7-no-now-guile.patch Patch: gnutls-3.2.7-rpath.patch @@ -30,10 +30,13 @@ Patch: gnutls-3.7.6-fips-pkcs12-des-cbc.patch Patch: gnutls-3.7.6-fips-rsa-key-sizes.patch Patch: gnutls-3.7.6-fips-symkey-limit.patch Patch: gnutls-3.7.6-fips-ecdsa-hash-check.patch +Patch: gnutls-3.7.8-xts-key-check.patch +Patch: gnutls-3.7.8-clear-session-ticket.patch +Patch: gnutls-3.7.7-aes-cbc-padding-support.patch +Patch: gnutls-3.7.8-integrity-check.patch Patch: gnutls-3.7.6-fips-service-indicator-test-functions.patch Patch: gnutls-3.7.6-fips-ccm-taglen.patch Patch: gnutls-3.7.6-fips-rsa-pss-saltlen.patch -Patch: gnutls-3.7.8-integrity-check.patch Patch: gnutls-3.7.8-revert-hmac-name.patch Patch: gnutls-3.7.8-rsa-kx-timing.patch Patch: gnutls-3.7.8-fips-pct-dh.patch @@ -203,10 +206,7 @@ This package contains Guile bindings for the library. %endif %prep -# Workaround: to allow building the package under FIPS, do not treat -# errors in the GPG check as fatal, where EdDSA signature verification -# is not allowed: -%{gpgverify} --keyring='%{SOURCE2}' --signature='%{SOURCE1}' --data='%{SOURCE0}' || : +%{gpgverify} --keyring='%{SOURCE2}' --signature='%{SOURCE1}' --data='%{SOURCE0}' %autosetup -p1 -S git @@ -406,22 +406,34 @@ make check %{?_smp_mflags} GNUTLS_SYSTEM_PRIORITY_FILE=/dev/null %endif %changelog +* Tue Mar 14 2023 Daiki Ueno - 3.7.6-20 +- Fix the previous change (#2175214) + +* Fri Mar 10 2023 Daiki Ueno - 3.7.6-19 +- Bump release to ensure el9 package is greater than el9_* packages (#2175214) + * Tue Feb 28 2023 Daiki Ueno - 3.7.6-18 -- Update gnutls-3.7.8-fips-pct-dh.patch to the upstream version (#2168610) +- Update gnutls-3.7.8-fips-pct-dh.patch to the upstream version (#2168143) * Fri Feb 10 2023 Daiki Ueno - 3.7.6-17 -- Fix timing side-channel in TLS RSA key exchange (#2162600) +- Fix timing side-channel in TLS RSA key exchange (#2162601) * Fri Feb 10 2023 Daiki Ueno - 3.7.6-16 -- fips: extend PCT to DH key generation (#2168610) +- fips: extend PCT to DH key generation (#2168143) -* Thu Dec 15 2022 Zoltan Fridrich - 3.7.6-14 -- fips: remove library path checking from FIPS integrity check (#2149638) -- fips: rename hmac file to its previous name (#2149640) +* Thu Dec 15 2022 Zoltan Fridrich - 3.7.6-15 +- fips: rename hmac file to its previous name (#2148269) -* Tue Nov 22 2022 Daiki Ueno - 3.7.6-13 -- cipher: add restriction on CCM tag length under FIPS mode (#2144535) -- nettle: mark non-compliant RSA-PSS salt length to be not-approved (#2144537) +* Tue Nov 22 2022 Daiki Ueno - 3.7.6-14 +- cipher: add restriction on CCM tag length under FIPS mode (#2137807) +- nettle: mark non-compliant RSA-PSS salt length to be not-approved (#2143266) + +* Tue Nov 15 2022 Zoltan Fridrich - 3.7.6-13 +- fips: make XTS key check failure not fatal (#2130971) +- enable source archive verification again (#2127094) +- clear server's session ticket indication at rehandshake (#2136072) +- crypto-api: add block cipher API with automatic padding (#2084161) +- fips: remove library path checking from FIPS integrity check (#2140908) * Tue Sep 27 2022 Daiki Ueno - 3.7.6-12 - fips: mark PBKDF2 with short key and output sizes non-approved