]> git.ipfire.org Git - thirdparty/gnutls.git/commitdiff
nettle: expose SIV-GCM through the AEAD interface
authorDaiki Ueno <ueno@gnu.org>
Wed, 6 Sep 2023 05:02:43 +0000 (14:02 +0900)
committerDaiki Ueno <ueno@gnu.org>
Thu, 7 Sep 2023 21:11:03 +0000 (06:11 +0900)
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 <ueno@gnu.org>
devel/libgnutls.abignore
lib/algorithms/ciphers.c
lib/crypto-selftests.c
lib/includes/gnutls/gnutls.h.in
lib/nettle/cipher.c

index a8b55f00b46823ea7f29e1902131a61e6d25118f..c67292f5055c615a264c7c1ac894ede751f2e991 100644 (file)
@@ -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
index 3efe121cb8c24f0e2a3745700769edc092cb13af..c3139352fc7e7ce8810aa65da9c7fb53765c04b3 100644 (file)
@@ -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,
index 2f1def1c0f9dd47331cbb670429c867a8b04c96d..116cc0b6bf05f8972523122bdfb1839881bf1d48 100644 (file)
@@ -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;
index fc64c7a22838f403d383a3c8b52e9194448e9cdc..dc9b4e307857de48d516f7e62c198a26e245f6b4 100644 (file)
@@ -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
         */
index 32e75356fc929e586a373e7fd513cf74ffea4c77..d0979e2402185de703fee8d06832b1aca118e265 100644 (file)
 #include <nettle/cfb.h>
 #include <nettle/xts.h>
 #include <nettle/siv-cmac.h>
+#ifdef HAVE_NETTLE_SIV_GCM_ENCRYPT_MESSAGE
+#include <nettle/siv-gcm.h>
+#else
+#include "backport/siv-gcm.h"
+#endif
 #include <fips.h>
 #include <intprops.h>
 
@@ -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)