From: Daiki Ueno Date: Wed, 6 Sep 2023 05:02:43 +0000 (+0900) Subject: nettle: expose SIV-GCM through the AEAD interface X-Git-Tag: 3.8.2~16^2~1 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=19ea9ac11d686747d3aa395f91c1ec2d8d2c951e;p=thirdparty%2Fgnutls.git nettle: expose SIV-GCM through the AEAD interface This adds a couple of new cipher algorithms GNUTLS_CIPHER_AES_128_SIV_GCM and GNUTLS_CIPHER_AES_256_SIV_GCM, exposing nettle_siv_gcm_aes{128,256}* functions. Signed-off-by: Daiki Ueno --- diff --git a/devel/libgnutls.abignore b/devel/libgnutls.abignore index a8b55f00b4..c67292f505 100644 --- a/devel/libgnutls.abignore +++ b/devel/libgnutls.abignore @@ -84,3 +84,7 @@ name = gnutls_x509_privkey_import_dh_raw [suppress_function] name = gnutls_privkey_derive_secret + +[suppress_type] +name = gnutls_cipher_algorithm_t +changed_enumerators = GNUTLS_CIPHER_AES_128_SIV_GCM, GNUTLS_CIPHER_AES_256_SIV_GCM diff --git a/lib/algorithms/ciphers.c b/lib/algorithms/ciphers.c index 3efe121cb8..c3139352fc 100644 --- a/lib/algorithms/ciphers.c +++ b/lib/algorithms/ciphers.c @@ -308,6 +308,24 @@ static const cipher_entry_st algorithms[] = { .flags = GNUTLS_CIPHER_FLAG_ONLY_AEAD | GNUTLS_CIPHER_FLAG_TAG_PREFIXED, .tagsize = 16 }, + { .name = "AES-128-SIV-GCM", + .id = GNUTLS_CIPHER_AES_128_SIV_GCM, + .blocksize = 16, + .keysize = 32, + .type = CIPHER_AEAD, + .explicit_iv = 12, + .cipher_iv = 12, + .flags = GNUTLS_CIPHER_FLAG_ONLY_AEAD, + .tagsize = 16 }, + { .name = "AES-256-SIV-GCM", + .id = GNUTLS_CIPHER_AES_256_SIV_GCM, + .blocksize = 16, + .keysize = 64, + .type = CIPHER_AEAD, + .explicit_iv = 12, + .cipher_iv = 12, + .flags = GNUTLS_CIPHER_FLAG_ONLY_AEAD, + .tagsize = 16 }, { .name = "GOST28147-TC26Z-CNT", .id = GNUTLS_CIPHER_GOST28147_TC26Z_CNT, .blocksize = 8, diff --git a/lib/crypto-selftests.c b/lib/crypto-selftests.c index 2f1def1c0f..116cc0b6bf 100644 --- a/lib/crypto-selftests.c +++ b/lib/crypto-selftests.c @@ -1251,6 +1251,45 @@ const struct cipher_aead_vectors_st aes256_siv_vectors[] = { { .tag_prepended = 1, } }; +/* From RFC8452, Appendix C.1 */ +const struct cipher_aead_vectors_st aes128_siv_gcm_vectors[] = { { + STR(key, key_size, + "\xf9\x01\xcf\xe8\xa6\x96\x15\xa9\x3f\xdf\x7a\x98\xca\xd4\x81\x79"), + STR(auth, auth_size, + "\x75\x76\xf7\x02\x8e\xc6\xeb\x5e\xa7\xe2\x98\x34\x2a\x94\xd4\xb2" + "\x02\xb3\x70\xef\x97\x68\xec\x65\x61\xc4\xfe\x6b\x7e\x72\x96\xfa" + "\x85\x9c\x21"), + STR(plaintext, plaintext_size, + "\xe4\x2a\x3c\x02\xc2\x5b\x64\x86\x9e\x14\x6d\x7b\x23\x39\x87\xbd" + "\xdf\xc2\x40\x87\x1d"), + .ciphertext = + (uint8_t *)"\x39\x1c\xc3\x28\xd4\x84\xa4\xf4\x64\x06\x18\x1b\xcd\x62\xef\xd9" + "\xb3\xee\x19\x7d\x05", + STR(iv, iv_size, "\x62\x45\x70\x9f\xb1\x88\x53\xf6\x8d\x83\x36\x40"), + .tag_size = 16, + .tag = (void *)"\x2d\x15\x50\x6c\x84\xa9\xed\xd6\x5e\x13\xe9\xd2\x4a\x2a\x6e\x70", +} }; + +/* From RFC8452, Appendix C.2 */ +const struct cipher_aead_vectors_st aes256_siv_gcm_vectors[] = { { + STR(key, key_size, + "\x3c\x53\x5d\xe1\x92\xea\xed\x38\x22\xa2\xfb\xbe\x2c\xa9\xdf\xc8" + "\x82\x55\xe1\x4a\x66\x1b\x8a\xa8\x2c\xc5\x42\x36\x09\x3b\xbc\x23"), + STR(auth, auth_size, + "\x73\x43\x20\xcc\xc9\xd9\xbb\xbb\x19\xcb\x81\xb2\xaf\x4e\xcb\xc3" + "\xe7\x28\x34\x32\x1f\x7a\xa0\xf7\x0b\x72\x82\xb4\xf3\x3d\xf2\x3f" + "\x16\x75\x41"), + STR(plaintext, plaintext_size, + "\xce\xd5\x32\xce\x41\x59\xb0\x35\x27\x7d\x4d\xfb\xb7\xdb\x62\x96" + "\x8b\x13\xcd\x4e\xec"), + .ciphertext = + (uint8_t *)"\x62\x66\x60\xc2\x6e\xa6\x61\x2f\xb1\x7a\xd9\x1e\x8e\x76\x76\x39" + "\xed\xd6\xc9\xfa\xee", + STR(iv, iv_size, "\x68\x80\x89\xe5\x55\x40\xdb\x18\x72\x50\x4e\x1c"), + .tag_size = 16, + .tag = (void *)"\x9d\x6c\x70\x29\x67\x5b\x89\xea\xf4\xba\x1d\xed\x1a\x28\x65\x94", +} }; + const struct cipher_vectors_st chacha20_32_vectors[] = { /* RFC8439 */ { STR(key, key_size, @@ -2685,6 +2724,12 @@ int gnutls_cipher_self_test(unsigned flags, gnutls_cipher_algorithm_t cipher) NON_FIPS_CASE(GNUTLS_CIPHER_AES_256_SIV, test_cipher_aead, aes256_siv_vectors); FALLTHROUGH; + NON_FIPS_CASE(GNUTLS_CIPHER_AES_128_SIV_GCM, test_cipher_aead, + aes128_siv_gcm_vectors); + FALLTHROUGH; + NON_FIPS_CASE(GNUTLS_CIPHER_AES_256_SIV_GCM, test_cipher_aead, + aes256_siv_gcm_vectors); + FALLTHROUGH; NON_FIPS_CASE(GNUTLS_CIPHER_CHACHA20_32, test_cipher, chacha20_32_vectors); FALLTHROUGH; diff --git a/lib/includes/gnutls/gnutls.h.in b/lib/includes/gnutls/gnutls.h.in index fc64c7a228..dc9b4e3078 100644 --- a/lib/includes/gnutls/gnutls.h.in +++ b/lib/includes/gnutls/gnutls.h.in @@ -148,6 +148,8 @@ extern "C" { * the authentication tag while it is prepended to * the cipher text. * @GNUTLS_CIPHER_AES_192_GCM: AES in GCM mode with 192-bit keys (AEAD). + * @GNUTLS_CIPHER_AES_128_SIV_GCM: AES in SIV-GCM mode with 128-bit key. + * @GNUTLS_CIPHER_AES_256_SIV_GCM: AES in SIV-GCM mode with 256-bit key. * * Enumeration of different symmetric encryption algorithms. */ @@ -194,6 +196,8 @@ typedef enum gnutls_cipher_algorithm { GNUTLS_CIPHER_AES_192_GCM = 39, GNUTLS_CIPHER_MAGMA_CTR_ACPKM = 40, GNUTLS_CIPHER_KUZNYECHIK_CTR_ACPKM = 41, + GNUTLS_CIPHER_AES_128_SIV_GCM = 42, + GNUTLS_CIPHER_AES_256_SIV_GCM = 43, /* used only for PGP internals. Ignored in TLS/SSL */ diff --git a/lib/nettle/cipher.c b/lib/nettle/cipher.c index 32e75356fc..d0979e2402 100644 --- a/lib/nettle/cipher.c +++ b/lib/nettle/cipher.c @@ -62,6 +62,11 @@ #include #include #include +#ifdef HAVE_NETTLE_SIV_GCM_ENCRYPT_MESSAGE +#include +#else +#include "backport/siv-gcm.h" +#endif #include #include @@ -357,6 +362,50 @@ static int _siv_cmac_aes256_decrypt_message(struct nettle_cipher_ctx *ctx, dst, src); } +static void _siv_gcm_aes128_encrypt_message(struct nettle_cipher_ctx *ctx, + size_t nonce_size, + const void *nonce, size_t auth_size, + const void *auth, size_t tag_size, + size_t length, uint8_t *dst, + const uint8_t *src) +{ + siv_gcm_aes128_encrypt_message((void *)ctx->ctx_ptr, nonce_size, nonce, + auth_size, auth, length, dst, src); +} + +static int _siv_gcm_aes128_decrypt_message(struct nettle_cipher_ctx *ctx, + size_t nonce_size, const void *nonce, + size_t auth_size, const void *auth, + size_t tag_size, size_t length, + uint8_t *dst, const uint8_t *src) +{ + return siv_gcm_aes128_decrypt_message((void *)ctx->ctx_ptr, nonce_size, + nonce, auth_size, auth, length, + dst, src); +} + +static void _siv_gcm_aes256_encrypt_message(struct nettle_cipher_ctx *ctx, + size_t nonce_size, + const void *nonce, size_t auth_size, + const void *auth, size_t tag_size, + size_t length, uint8_t *dst, + const uint8_t *src) +{ + siv_gcm_aes256_encrypt_message((void *)ctx->ctx_ptr, nonce_size, nonce, + auth_size, auth, length, dst, src); +} + +static int _siv_gcm_aes256_decrypt_message(struct nettle_cipher_ctx *ctx, + size_t nonce_size, const void *nonce, + size_t auth_size, const void *auth, + size_t tag_size, size_t length, + uint8_t *dst, const uint8_t *src) +{ + return siv_gcm_aes256_decrypt_message((void *)ctx->ctx_ptr, nonce_size, + nonce, auth_size, auth, length, + dst, src); +} + static void _chacha_set_nonce(struct chacha_ctx *ctx, size_t length, const uint8_t *nonce) { @@ -1082,6 +1131,38 @@ static const struct nettle_cipher_st builtin_ciphers[] = { (nettle_set_key_func *)siv_cmac_aes256_set_key, .max_iv_size = SIV_DIGEST_SIZE, }, + { + .algo = GNUTLS_CIPHER_AES_128_SIV_GCM, + .block_size = SIV_GCM_BLOCK_SIZE, + .key_size = AES128_KEY_SIZE, + + .ctx_size = sizeof(struct aes128_ctx), + .aead_encrypt = + (aead_encrypt_func)_siv_gcm_aes128_encrypt_message, + .aead_decrypt = + (aead_decrypt_func)_siv_gcm_aes128_decrypt_message, + .set_encrypt_key = + (nettle_set_key_func *)aes128_set_encrypt_key, + .set_decrypt_key = + (nettle_set_key_func *)aes128_set_encrypt_key, + .max_iv_size = SIV_GCM_NONCE_SIZE, + }, + { + .algo = GNUTLS_CIPHER_AES_256_SIV_GCM, + .block_size = SIV_GCM_BLOCK_SIZE, + .key_size = AES256_KEY_SIZE, + + .ctx_size = sizeof(struct aes256_ctx), + .aead_encrypt = + (aead_encrypt_func)_siv_gcm_aes256_encrypt_message, + .aead_decrypt = + (aead_decrypt_func)_siv_gcm_aes256_decrypt_message, + .set_encrypt_key = + (nettle_set_key_func *)aes256_set_encrypt_key, + .set_decrypt_key = + (nettle_set_key_func *)aes256_set_encrypt_key, + .max_iv_size = SIV_GCM_NONCE_SIZE, + }, }; static int wrap_nettle_cipher_exists(gnutls_cipher_algorithm_t algo)