PBKDF2 (PBMAC1) is now supported, according to the specification
proposed in draft-ietf-lamps-pkcs12-pbmac1.
+** libgnutls: SHA3 extendable output functions (XOF) are now supported
+ SHA3 XOF, SHAKE128 and SHAKE256, are now usable through a new
+ public API gnutls_hash_squeeze.
+
** API and ABI modifications:
gnutls_pkcs12_generate_mac3: New function
gnutls_pkcs12_flags_t: New enum
+gnutls_hash_squeeze: New function
* Version 3.8.5 (released 2024-04-04)
[suppress_type]
name = gnutls_mac_algorithm_t
changed_enumerators = GNUTLS_MAC_PBMAC1
+
+[suppress_function]
+name = gnutls_hash_squeeze
gnutls_hash_get_len@GNUTLS_3_4
gnutls_hash_init@GNUTLS_3_4
gnutls_hash_output@GNUTLS_3_4
+gnutls_hash_squeeze@GNUTLS_3_8_6
gnutls_heartbeat_allowed@GNUTLS_3_4
gnutls_heartbeat_enable@GNUTLS_3_4
gnutls_heartbeat_get_timeout@GNUTLS_3_4
FUNCS += functions/gnutls_hash_init.short
FUNCS += functions/gnutls_hash_output
FUNCS += functions/gnutls_hash_output.short
+FUNCS += functions/gnutls_hash_squeeze
+FUNCS += functions/gnutls_hash_squeeze.short
FUNCS += functions/gnutls_heartbeat_allowed
FUNCS += functions/gnutls_heartbeat_allowed.short
FUNCS += functions/gnutls_heartbeat_enable
APIMANS += gnutls_hash_get_len.3
APIMANS += gnutls_hash_init.3
APIMANS += gnutls_hash_output.3
+APIMANS += gnutls_hash_squeeze.3
APIMANS += gnutls_heartbeat_allowed.3
APIMANS += gnutls_heartbeat_enable.3
APIMANS += gnutls_heartbeat_get_timeout.3
{ .name = "SHAKE-128",
.oid = HASH_OID_SHAKE_128,
.id = GNUTLS_MAC_SHAKE_128,
- .block_size = 168 },
+ .block_size = 168,
+ .flags = GNUTLS_MAC_FLAG_XOF },
{ .name = "SHAKE-256",
.oid = HASH_OID_SHAKE_256,
.id = GNUTLS_MAC_SHAKE_256,
- .block_size = 136 },
+ .block_size = 136,
+ .flags = GNUTLS_MAC_FLAG_XOF },
{ .name = "OMAC-MAGMA",
.id = GNUTLS_MAC_MAGMA_OMAC,
.output_size = 8,
return dig;
}
+/**
+ * gnutls_hash_squeeze:
+ * @handle: a #gnutls_hash_hd_t
+ * @output: destination to store the output; must be equal to or larger than @length
+ * @length: length of @output
+ *
+ * This function will extract digest output of @length bytes. The @handle must
+ * be initialized with gnutls_hash_init() as an extended output function (XOF),
+ * such as %GNUTLS_DIG_SHAKE_128 or %GNUTLS_DIG_SHAKE_256.
+ *
+ * This function can be called multiple times. To reset the state of @handle,
+ * call gnutls_hash_deinit() with %NULL as the digest argument.
+ *
+ * Returns: %GNUTLS_E_SUCCESS (0) on success; negative error code otherwise.
+ *
+ * Since: 3.8.6
+ */
+int gnutls_hash_squeeze(gnutls_hash_hd_t handle, void *output, size_t length)
+{
+ return _gnutls_hash_squeeze((digest_hd_st *)handle, output, length);
+}
+
/**
* gnutls_key_generate:
* @key: is a pointer to a #gnutls_datum_t which will contain a newly
},
};
+const struct hash_vectors_st shake128_vectors[] = {
+ {
+ STR(plaintext, plaintext_size, "\xC1\xEC\xFD\xFC"),
+ STR(output, output_size,
+ "\xB5\xEB\x98\x7E\x7C\xBF\xC7\xC9\xD1\x40\xAF\xD2\x0B\x50\x0E\x30"),
+ },
+ {
+ STR(plaintext, plaintext_size, "\xC1\xEC\xFD\xFC"),
+ STR(output, output_size,
+ "\xB5\xEB\x98\x7E\x7C\xBF\xC7\xC9\xD1\x40\xAF\xD2\x0B\x50\x0E\x30"
+ "\xF2\xF7\x11\x88\xBC\xE8\x85\x95\x1F\x22\xFB\xC3\x5D\xE4\x0E\x74"),
+ },
+};
+
+const struct hash_vectors_st shake256_vectors[] = {
+ {
+ STR(plaintext, plaintext_size, "\xC1\xEC\xFD\xFC"),
+ STR(output, output_size,
+ "\xCE\x7F\xBC\x15\x50\x39\x86\xE3\xB8\x45\x30\xD8\x4A\x16\xEF\x64"),
+ },
+ {
+ STR(plaintext, plaintext_size, "\xC1\xEC\xFD\xFC"),
+ STR(output, output_size,
+ "\xCE\x7F\xBC\x15\x50\x39\x86\xE3\xB8\x45\x30\xD8\x4A\x16\xEF\x64"
+ "\x33\x2A\x6E\xA5\x7E\x35\x4E\x9F\x20\x54\xBF\xC2\xAA\x88\x91\xF9"),
+ },
+};
+
const struct hash_vectors_st gostr_94_vectors[] = {
{
STR(plaintext, plaintext_size,
return 0;
}
+static int test_xof(gnutls_digest_algorithm_t dig,
+ const struct hash_vectors_st *vectors, size_t vectors_size,
+ unsigned flags)
+{
+ uint8_t data[2 * HASH_DATA_SIZE];
+ unsigned int i;
+ int ret;
+ gnutls_hash_hd_t hd;
+
+ if (!_gnutls_digest_exists(dig))
+ return 0;
+
+ for (i = 0; i < vectors_size; i++) {
+ ret = gnutls_hash_init(&hd, dig);
+ if (ret < 0) {
+ _gnutls_debug_log("error initializing: %s\n",
+ gnutls_digest_get_name(dig));
+ return gnutls_assert_val(GNUTLS_E_SELF_TEST_ERROR);
+ }
+
+ ret = gnutls_hash(hd, vectors[i].plaintext, 1);
+ if (ret < 0) {
+ gnutls_hash_deinit(hd, NULL);
+ return gnutls_assert_val(GNUTLS_E_SELF_TEST_ERROR);
+ }
+
+ ret = gnutls_hash(hd, &vectors[i].plaintext[1],
+ vectors[i].plaintext_size - 1);
+ if (ret < 0) {
+ gnutls_hash_deinit(hd, NULL);
+ return gnutls_assert_val(GNUTLS_E_SELF_TEST_ERROR);
+ }
+
+ assert(sizeof(data) >= vectors[i].output_size);
+ ret = gnutls_hash_squeeze(hd, data, vectors[i].output_size);
+ if (ret < 0) {
+ gnutls_hash_deinit(hd, NULL);
+ return gnutls_assert_val(GNUTLS_E_SELF_TEST_ERROR);
+ }
+
+ gnutls_hash_deinit(hd, NULL);
+
+ if (memcmp(data, vectors[i].output, vectors[i].output_size) !=
+ 0) {
+ _gnutls_debug_log("%s test vector %d failed!\n",
+ gnutls_digest_get_name(dig), i);
+ return gnutls_assert_val(GNUTLS_E_SELF_TEST_ERROR);
+ }
+ }
+
+ _gnutls_debug_log("%s self check succeeded\n",
+ gnutls_digest_get_name(dig));
+
+ return 0;
+}
+
struct mac_vectors_st {
const uint8_t *key;
unsigned int key_size;
FALLTHROUGH;
CASE(GNUTLS_DIG_SHA3_512, test_digest, sha3_512_vectors);
#endif
+ FALLTHROUGH;
+ CASE(GNUTLS_DIG_SHAKE_128, test_xof, shake128_vectors);
+ FALLTHROUGH;
+ CASE(GNUTLS_DIG_SHAKE_256, test_xof, shake256_vectors);
#if ENABLE_GOST
FALLTHROUGH;
NON_FIPS_CASE(GNUTLS_DIG_GOSTR_94, test_digest,
return gnutls_assert_val(GNUTLS_E_SELF_TEST_ERROR);
}
+ ret = gnutls_digest_self_test(0, GNUTLS_DIG_SHAKE_128);
+ if (ret < 0) {
+ return gnutls_assert_val(GNUTLS_E_SELF_TEST_ERROR);
+ }
+
+ ret = gnutls_digest_self_test(0, GNUTLS_DIG_SHAKE_256);
+ if (ret < 0) {
+ return gnutls_assert_val(GNUTLS_E_SELF_TEST_ERROR);
+ }
+
/* MAC (includes message digest test) */
ret = gnutls_mac_self_test(0, GNUTLS_MAC_SHA1);
if (ret < 0) {
case GNUTLS_MAC_AES_GMAC_128:
case GNUTLS_MAC_AES_GMAC_192:
case GNUTLS_MAC_AES_GMAC_256:
+ /* They are not a MAC algorithm, but go through the same check */
+ case GNUTLS_MAC_SHAKE_128:
+ case GNUTLS_MAC_SHAKE_256:
return true;
default:
return false;
#define GNUTLS_MAC_FLAG_ALLOW_INSECURE_REVERTIBLE \
(1 \
<< 3) /* when checking with _gnutls_digest_is_insecure2, don't treat revertible setting as fatal */
+#define GNUTLS_MAC_FLAG_XOF \
+ (1 << 4) /* this function is an extendable output function (XOF) */
/* This structure is used both for MACs and digests
*/
typedef struct mac_entry_st {
return 0;
}
+int _gnutls_hash_squeeze(digest_hd_st *handle, void *output, size_t length)
+{
+ if (handle->output == NULL)
+ return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
+
+ if (!(handle->e->flags & GNUTLS_MAC_FLAG_XOF))
+ return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
+
+ handle->output(handle->handle, output, length);
+ return 0;
+}
+
/* HMAC interface */
int _gnutls_mac_fast(gnutls_mac_algorithm_t algorithm, const void *key,
int _gnutls_hash_fast(gnutls_digest_algorithm_t algorithm, const void *text,
size_t textlen, void *digest);
+int _gnutls_hash_squeeze(digest_hd_st *handle, void *output, size_t length);
+
#ifdef ENABLE_SSL3
/* helper functions */
int _gnutls_mac_init_ssl3(digest_hd_st *, const mac_entry_st *e, void *key,
int gnutls_hash_fast(gnutls_digest_algorithm_t algorithm, const void *text,
size_t textlen, void *digest);
gnutls_hash_hd_t gnutls_hash_copy(gnutls_hash_hd_t handle);
+int gnutls_hash_squeeze(gnutls_hash_hd_t handle, void *output, size_t length);
/* KDF API */
* @GNUTLS_MAC_SHA3_384: Reserved; unimplemented.
* @GNUTLS_MAC_SHA3_512: Reserved; unimplemented.
* @GNUTLS_MAC_GOST28147_TC26Z_IMIT: The GOST 28147-89 working in IMIT mode with TC26 Z S-box.
- * @GNUTLS_MAC_SHAKE_128: Reserved; unimplemented.
- * @GNUTLS_MAC_SHAKE_256: Reserved; unimplemented.
+ * @GNUTLS_MAC_SHAKE_128: The SHAKE128 extendable output function.
+ * @GNUTLS_MAC_SHAKE_256: The SHAKE256 extendable output function.
* @GNUTLS_MAC_MAGMA_OMAC: GOST R 34.12-2015 (Magma) in OMAC (CMAC) mode.
* @GNUTLS_MAC_KUZNYECHIK_OMAC: GOST R 34.12-2015 (Kuznyechik) in OMAC (CMAC) mode.
*
* @GNUTLS_DIG_GOSTR_94: GOST R 34.11-94 algorithm.
* @GNUTLS_DIG_STREEBOG_256: GOST R 34.11-2001 (Streebog) algorithm, 256 bit.
* @GNUTLS_DIG_STREEBOG_512: GOST R 34.11-2001 (Streebog) algorithm, 512 bit.
- * @GNUTLS_DIG_SHAKE_128: Reserved; unimplemented.
- * @GNUTLS_DIG_SHAKE_256: Reserved; unimplemented.
+ * @GNUTLS_DIG_SHAKE_128: The SHAKE128 extendable output function.
+ * @GNUTLS_DIG_SHAKE_256: The SHAKE256 extendable output function.
*
* Enumeration of different digest (hash) algorithms.
*/
{
global:
gnutls_pkcs12_generate_mac3;
+ gnutls_hash_squeeze;
local:
*;
} GNUTLS_3_8_4;
if NEED_SHAKE_OUTPUT
libcrypto_la_SOURCES += \
backport/md-internal.h \
+ backport/nettle-write.h \
backport/sha3.c \
backport/sha3-internal.h \
backport/sha3-shake.c \
backport/shake128.c \
backport/shake256.c \
+ backport/write-le64.c \
$(NULL)
endif