Copyright (C) 2013-2019 Nikos Mavrogiannopoulos
See the end for copying conditions.
+* Version 3.8.11 (unreleased)
+
+** libgnutls: MAC algorithms for PSK binders is now configurable
+ The previous implementation assumed HMAC-SHA256 to calculate the
+ PSK binders. With the new gnutls_psk_allocate_client_credentials2()
+ and gnutls_psk_allocate_server_credentials2() functions, the
+ application can use other MAC algorithms such as HMAC-SHA384.
+
+** API and ABI modifications:
+gnutls_psk_allocate_client_credentials2: New function
+gnutls_psk_allocate_server_credentials2: New function
+
* Version 3.8.10 (released 2025-07-08)
** libgnutls: Fix NULL pointer dereference when 2nd Client Hello omits PSK
[suppress_type]
name = gnutls_cipher_algorithm_t
-changed_enumerators = GNUTLS_CIPHER_AES_128_CFB, GNUTLS_CIPHER_AES_192_CFB, GNUTLS_CIPHER_AES_256_CFB
\ No newline at end of file
+changed_enumerators = GNUTLS_CIPHER_AES_128_CFB, GNUTLS_CIPHER_AES_192_CFB, GNUTLS_CIPHER_AES_256_CFB
+
+[suppress_function]
+name = gnutls_psk_allocate_client_credentials2
+
+[suppress_function]
+name = gnutls_psk_allocate_server_credentials2
GNUTLS_3_7_4@GNUTLS_3_7_4
GNUTLS_3_7_5@GNUTLS_3_7_5
GNUTLS_3_7_7@GNUTLS_3_7_7
+GNUTLS_3_8_11@GNUTLS_3_8_11
GNUTLS_3_8_1@GNUTLS_3_8_1
GNUTLS_3_8_2@GNUTLS_3_8_2
GNUTLS_3_8_4@GNUTLS_3_8_4
gnutls_protocol_get_version@GNUTLS_3_4
gnutls_protocol_list@GNUTLS_3_4
gnutls_protocol_set_enabled@GNUTLS_3_7_3
+gnutls_psk_allocate_client_credentials2@GNUTLS_3_8_11
gnutls_psk_allocate_client_credentials@GNUTLS_3_4
+gnutls_psk_allocate_server_credentials2@GNUTLS_3_8_11
gnutls_psk_allocate_server_credentials@GNUTLS_3_4
gnutls_psk_client_get_hint@GNUTLS_3_4
gnutls_psk_format_imported_identity@GNUTLS_3_8_1
FUNCS += functions/gnutls_protocol_set_enabled.short
FUNCS += functions/gnutls_psk_allocate_client_credentials
FUNCS += functions/gnutls_psk_allocate_client_credentials.short
+FUNCS += functions/gnutls_psk_allocate_client_credentials2
+FUNCS += functions/gnutls_psk_allocate_client_credentials2.short
FUNCS += functions/gnutls_psk_allocate_server_credentials
FUNCS += functions/gnutls_psk_allocate_server_credentials.short
+FUNCS += functions/gnutls_psk_allocate_server_credentials2
+FUNCS += functions/gnutls_psk_allocate_server_credentials2.short
FUNCS += functions/gnutls_psk_client_get_hint
FUNCS += functions/gnutls_psk_client_get_hint.short
FUNCS += functions/gnutls_psk_format_imported_identity
APIMANS += gnutls_protocol_list.3
APIMANS += gnutls_protocol_set_enabled.3
APIMANS += gnutls_psk_allocate_client_credentials.3
+APIMANS += gnutls_psk_allocate_client_credentials2.3
APIMANS += gnutls_psk_allocate_server_credentials.3
+APIMANS += gnutls_psk_allocate_server_credentials2.3
APIMANS += gnutls_psk_client_get_hint.3
APIMANS += gnutls_psk_format_imported_identity.3
APIMANS += gnutls_psk_free_client_credentials.3
struct timespec ticket_creation_time = { 0, 0 };
enum binder_type binder_type;
bool refuse_early_data = false;
+ gnutls_mac_algorithm_t mac = GNUTLS_MAC_SHA384;
+retry_binder:
ret = _gnutls13_psk_ext_parser_init(&psk_parser, data, len);
if (ret < 0) {
/* No PSKs advertised by client */
uint8_t ipsk[MAX_HASH_SIZE];
prf = pskcred->binder_algo;
+ if (prf->id == GNUTLS_MAC_UNKNOWN)
+ prf = _gnutls_mac_to_entry(mac);
/* this fails only on configuration errors; as such we always
* return its error code in that case */
if (_gnutls_mac_get_algo_len(prf) != binder_recvd.size ||
gnutls_memcmp(binder_value, binder_recvd.data, binder_recvd.size)) {
+ /*
+ * Older clients will always use SHA256 as binder algorithm
+ * even for SHA384 PSKs, so we need to retry with SHA256
+ * to calculate the correct binder value for those.
+ */
+ if (prf->id == GNUTLS_MAC_UNKNOWN && mac == GNUTLS_MAC_SHA384) {
+ mac = GNUTLS_MAC_SHA256;
+ goto retry_binder;
+ }
gnutls_assert();
ret = GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER;
goto fail;
void gnutls_psk_free_client_credentials(gnutls_psk_client_credentials_t sc);
int gnutls_psk_allocate_client_credentials(gnutls_psk_client_credentials_t *sc);
+int gnutls_psk_allocate_client_credentials2(gnutls_psk_client_credentials_t *sc,
+ gnutls_mac_algorithm_t mac);
+
int gnutls_psk_set_client_credentials(gnutls_psk_client_credentials_t res,
const char *username,
const gnutls_datum_t *key,
void gnutls_psk_free_server_credentials(gnutls_psk_server_credentials_t sc);
int gnutls_psk_allocate_server_credentials(gnutls_psk_server_credentials_t *sc);
+int gnutls_psk_allocate_server_credentials2(gnutls_psk_server_credentials_t *sc,
+ gnutls_mac_algorithm_t mac);
int gnutls_psk_set_server_credentials_file(gnutls_psk_server_credentials_t res,
const char *password_file);
*;
} GNUTLS_3_8_4;
+GNUTLS_3_8_11
+{
+ global:
+ gnutls_psk_allocate_client_credentials2;
+ gnutls_psk_allocate_server_credentials2;
+ local:
+ *;
+} GNUTLS_3_8_6;
+
GNUTLS_FIPS140_3_4 {
global:
gnutls_cipher_self_test;
**/
int gnutls_psk_allocate_client_credentials(gnutls_psk_client_credentials_t *sc)
{
+ /* TLS 1.3 - Default binder HMAC algorithm is SHA-256 */
+ return gnutls_psk_allocate_client_credentials2(sc, GNUTLS_MAC_SHA256);
+}
+
+/**
+ * gnutls_psk_allocate_client_credentials2:
+ * @sc: is a pointer to a #gnutls_psk_client_credentials_t type.
+ * @mac: encryption algorithm to use
+ *
+ * Allocate a gnutls_psk_client_credentials_t structure and initializes
+ * the HMAC binder algorithm to @mac.
+ *
+ * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise
+ * an error code is returned.
+ **/
+int gnutls_psk_allocate_client_credentials2(gnutls_psk_client_credentials_t *sc,
+ gnutls_mac_algorithm_t mac)
+{
+ /* TLS 1.3 - Only SHA-256 and SHA-384 are allowed */
+ if (mac != GNUTLS_MAC_SHA256 && mac != GNUTLS_MAC_SHA384)
+ return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
+
*sc = gnutls_calloc(1, sizeof(psk_client_credentials_st));
if (*sc == NULL)
return GNUTLS_E_MEMORY_ERROR;
- /* TLS 1.3 - Default binder HMAC algorithm is SHA-256 */
- (*sc)->binder_algo = _gnutls_mac_to_entry(GNUTLS_MAC_SHA256);
+ (*sc)->binder_algo = _gnutls_mac_to_entry(mac);
return 0;
}
**/
int gnutls_psk_allocate_server_credentials(gnutls_psk_server_credentials_t *sc)
{
+ /* TLS 1.3 - Default binder HMAC algorithm is SHA-256 */
+ return gnutls_psk_allocate_server_credentials2(sc, GNUTLS_MAC_SHA256);
+}
+
+/**
+ * gnutls_psk_allocate_server_credentials2:
+ * @sc: is a pointer to a #gnutls_psk_server_credentials_t type.
+ * @mac: encryption algorithm to use
+ *
+ * Allocate a gnutls_psk_server_credentials_t structure and initializes
+ * the HMAC binder algorithm to @mac. If @mac is set to GNUTLS_MAC_UNKNOWN
+ * both possible algorithms SHA384 and SHA256 are applied to find a matching
+ * binder value.
+ *
+ * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise
+ * an error code is returned.
+ **/
+int gnutls_psk_allocate_server_credentials2(gnutls_psk_server_credentials_t *sc,
+ gnutls_mac_algorithm_t mac)
+{
+ /*
+ * TLS 1.3 - Only SHA-256 and SHA-384 are allowed;
+ * additionally allow GNUTLS_MAC_UNKNOWN for autodetection.
+ */
+ if (mac != GNUTLS_MAC_SHA256 && mac != GNUTLS_MAC_SHA384 &&
+ mac != GNUTLS_MAC_UNKNOWN)
+ return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
+
*sc = gnutls_calloc(1, sizeof(psk_server_cred_st));
if (*sc == NULL)
return GNUTLS_E_MEMORY_ERROR;
- /* TLS 1.3 - Default binder HMAC algorithm is SHA-256 */
- (*sc)->binder_algo = _gnutls_mac_to_entry(GNUTLS_MAC_SHA256);
+ (*sc)->binder_algo = _gnutls_mac_to_entry(mac);
return 0;
}