]> git.ipfire.org Git - thirdparty/gnutls.git/commitdiff
lib: add support for AES-192-GCM
authorDmitry Baryshkov <dbaryshkov@gmail.com>
Tue, 26 May 2020 21:34:02 +0000 (00:34 +0300)
committerDmitry Baryshkov <dbaryshkov@gmail.com>
Tue, 26 May 2020 21:36:00 +0000 (00:36 +0300)
Add support for AES-192 in GCM mode.

Signed-off-by: Dmitry Baryshkov <dbaryshkov@gmail.com>
18 files changed:
NEWS
devel/libgnutls-latest-x86_64.abi
lib/accelerated/aarch64/aarch64-common.c
lib/accelerated/aarch64/aes-gcm-aarch64.c
lib/accelerated/cryptodev-gcm.c
lib/accelerated/x86/aes-gcm-x86-aesni.c
lib/accelerated/x86/aes-gcm-x86-pclmul-avx.c
lib/accelerated/x86/aes-gcm-x86-pclmul.c
lib/accelerated/x86/aes-gcm-x86-ssse3.c
lib/accelerated/x86/x86-common.c
lib/algorithms/ciphers.c
lib/crypto-selftests.c
lib/fips.h
lib/includes/gnutls/gnutls.h.in
lib/nettle/cipher.c
tests/aead-cipher-vec.c
tests/slow/cipher-api-test.c
tests/slow/cipher-openssl-compat.c

diff --git a/NEWS b/NEWS
index 834cd629dde3462ca18956ff6ad05187c8aebde5..8f81bd3dc45712bfa99d4ba73302fce15c758be0 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -10,6 +10,7 @@ See the end for copying conditions.
 ** API and ABI modifications:
 GNUTLS_CIPHER_AES_128_SIV: Added
 GNUTLS_CIPHER_AES_256_SIV: Added
+GNUTLS_CIPHER_AES_192_GCM: Added
 gnutls_pkcs7_print_signature_info: Added
 
 * Version 3.6.13 (released 2020-03-31)
index 8e5e7879506b49f4c2230123515a3faddef9ff7f..4f8d92b32da0499f7f6f53a57fdce7f179de321c 100644 (file)
       <enumerator name='GNUTLS_CIPHER_CHACHA20_32' value='36'/>
       <enumerator name='GNUTLS_CIPHER_AES_128_SIV' value='37'/>
       <enumerator name='GNUTLS_CIPHER_AES_256_SIV' value='38'/>
+      <enumerator name='GNUTLS_CIPHER_AES_192_GCM' value='39'/>
       <enumerator name='GNUTLS_CIPHER_IDEA_PGP_CFB' value='200'/>
       <enumerator name='GNUTLS_CIPHER_3DES_PGP_CFB' value='201'/>
       <enumerator name='GNUTLS_CIPHER_CAST5_PGP_CFB' value='202'/>
index 38cff360b6d41019b29ea1ea109f715f697449be..82cd8715fed2ad710c12b3d7a4326b467b80ef8e 100644 (file)
@@ -205,6 +205,14 @@ void _register_aarch64_crypto(unsigned capabilities)
                                        gnutls_assert();
                                }
 
+                       ret =
+                           gnutls_crypto_single_cipher_register
+                           (GNUTLS_CIPHER_AES_192_GCM, 90,
+                            &_gnutls_aes_gcm_aarch64, 0);
+                       if (ret < 0) {
+                                       gnutls_assert();
+                               }
+
                        ret =
                            gnutls_crypto_single_cipher_register
                            (GNUTLS_CIPHER_AES_256_GCM, 90,
index c88fe9759fe11da803f2a0fcbbf83e6ddfd41870..01f22136a65b3c420a229cd418889b5e33bd04dd 100644 (file)
@@ -83,6 +83,7 @@ aes_gcm_cipher_init(gnutls_cipher_algorithm_t algorithm, void **_ctx,
 {
        /* we use key size to distinguish */
        if (algorithm != GNUTLS_CIPHER_AES_128_GCM &&
+           algorithm != GNUTLS_CIPHER_AES_192_GCM &&
            algorithm != GNUTLS_CIPHER_AES_256_GCM)
                return GNUTLS_E_INVALID_REQUEST;
 
index bd9f1a025d40066f382aa9cf7aa15824f1948f0e..876756094e3a6447e6dd8b7ad6af9d1be963f0c4 100644 (file)
@@ -69,6 +69,7 @@ static void aes_gcm_deinit(void *_ctx)
 
 static const int cipher_map[] = {
        [GNUTLS_CIPHER_AES_128_GCM] = CRYPTO_AES_GCM,
+       [GNUTLS_CIPHER_AES_192_GCM] = CRYPTO_AES_GCM,
        [GNUTLS_CIPHER_AES_256_GCM] = CRYPTO_AES_GCM,
 };
 
index e5110ef528b5bebcdbc00ecaafc476ba65c7b6f1..6c1bb1f6fd5a168cb0bd6ac77aecda934b72be73 100644 (file)
@@ -60,6 +60,14 @@ static void x86_aes128_set_encrypt_key(void *_ctx,
        aesni_set_encrypt_key(key, 16*8, ctx);
 }
 
+static void x86_aes192_set_encrypt_key(void *_ctx,
+                                       const uint8_t * key)
+{
+       AES_KEY *ctx = _ctx;
+
+       aesni_set_encrypt_key(key, 24*8, ctx);
+}
+
 static void x86_aes256_set_encrypt_key(void *_ctx,
                                        const uint8_t * key)
 {
@@ -74,6 +82,7 @@ aes_gcm_cipher_init(gnutls_cipher_algorithm_t algorithm, void **_ctx,
 {
        /* we use key size to distinguish */
        if (algorithm != GNUTLS_CIPHER_AES_128_GCM &&
+           algorithm != GNUTLS_CIPHER_AES_192_GCM &&
            algorithm != GNUTLS_CIPHER_AES_256_GCM)
                return GNUTLS_E_INVALID_REQUEST;
 
@@ -94,6 +103,9 @@ aes_gcm_cipher_setkey(void *_ctx, const void *key, size_t length)
        if (length == 16) {
                GCM_SET_KEY(ctx, x86_aes128_set_encrypt_key, x86_aes_encrypt,
                            key);
+       } else if (length == 24) {
+               GCM_SET_KEY(ctx, x86_aes192_set_encrypt_key, x86_aes_encrypt,
+                           key);
        } else if (length == 32) {
                GCM_SET_KEY(ctx, x86_aes256_set_encrypt_key, x86_aes_encrypt,
                            key);
index 747a89492156ac3e156617e266a7783ac704b2b3..3b4140acb2e144b536e31f4d343bc3ac3cc3ed1d 100644 (file)
@@ -81,6 +81,7 @@ aes_gcm_cipher_init(gnutls_cipher_algorithm_t algorithm, void **_ctx,
 {
        /* we use key size to distinguish */
        if (algorithm != GNUTLS_CIPHER_AES_128_GCM &&
+           algorithm != GNUTLS_CIPHER_AES_192_GCM &&
            algorithm != GNUTLS_CIPHER_AES_256_GCM)
                return GNUTLS_E_INVALID_REQUEST;
 
index 2225b933763699ccbb1dd8f1113e50cf55d441a5..dc1e68dfe87beb64099c8124167df6e394b0e654 100644 (file)
@@ -81,6 +81,7 @@ aes_gcm_cipher_init(gnutls_cipher_algorithm_t algorithm, void **_ctx,
 {
        /* we use key size to distinguish */
        if (algorithm != GNUTLS_CIPHER_AES_128_GCM &&
+           algorithm != GNUTLS_CIPHER_AES_192_GCM &&
            algorithm != GNUTLS_CIPHER_AES_256_GCM)
                return GNUTLS_E_INVALID_REQUEST;
 
index 5580cc2214e7cf76408beaf251056baadd782774..f6b14681c9256ccd15b3ca91d2a131ebab819328 100644 (file)
@@ -69,6 +69,14 @@ static void x86_aes_128_set_encrypt_key(void *_ctx,
        vpaes_set_encrypt_key(key, 16*8, ctx);
 }
 
+static void x86_aes_192_set_encrypt_key(void *_ctx,
+                                   const uint8_t * key)
+{
+       AES_KEY *ctx = _ctx;
+
+       vpaes_set_encrypt_key(key, 24*8, ctx);
+}
+
 static void x86_aes_256_set_encrypt_key(void *_ctx,
                                    const uint8_t * key)
 {
@@ -83,6 +91,7 @@ aes_gcm_cipher_init(gnutls_cipher_algorithm_t algorithm, void **_ctx,
 {
        /* we use key size to distinguish */
        if (algorithm != GNUTLS_CIPHER_AES_128_GCM &&
+           algorithm != GNUTLS_CIPHER_AES_192_GCM &&
            algorithm != GNUTLS_CIPHER_AES_256_GCM)
                return GNUTLS_E_INVALID_REQUEST;
 
@@ -103,6 +112,9 @@ aes_gcm_cipher_setkey(void *_ctx, const void *key, size_t keysize)
        if (keysize == 16) {
                GCM_SET_KEY(ctx, x86_aes_128_set_encrypt_key, x86_aes_encrypt,
                            key);
+       } else if (keysize == 24) {
+               GCM_SET_KEY(ctx, x86_aes_192_set_encrypt_key, x86_aes_encrypt,
+                           key);
        } else if (keysize == 32) {
                GCM_SET_KEY(ctx, x86_aes_256_set_encrypt_key, x86_aes_encrypt,
                            key);
index 459397c118ba2fb3bc95e611807177668f51b11c..3845c6b4c916ee0586aaefe30b77660573502412 100644 (file)
@@ -560,6 +560,14 @@ void register_x86_intel_crypto(unsigned capabilities)
                                gnutls_assert();
                        }
 
+               ret =
+                   gnutls_crypto_single_cipher_register
+                   (GNUTLS_CIPHER_AES_192_GCM, 90,
+                    &_gnutls_aes_gcm_x86_ssse3, 0);
+                       if (ret < 0) {
+                               gnutls_assert();
+                       }
+
                ret =
                    gnutls_crypto_single_cipher_register
                    (GNUTLS_CIPHER_AES_256_GCM, 90,
@@ -753,6 +761,14 @@ void register_x86_intel_crypto(unsigned capabilities)
                                        gnutls_assert();
                                }
 
+                               ret =
+                                   gnutls_crypto_single_cipher_register
+                                   (GNUTLS_CIPHER_AES_192_GCM, 80,
+                                    &_gnutls_aes_gcm_pclmul_avx, 0);
+                               if (ret < 0) {
+                                       gnutls_assert();
+                               }
+
                                ret =
                                    gnutls_crypto_single_cipher_register
                                    (GNUTLS_CIPHER_AES_256_GCM, 80,
@@ -771,6 +787,14 @@ void register_x86_intel_crypto(unsigned capabilities)
                                        gnutls_assert();
                                }
 
+                               ret =
+                                   gnutls_crypto_single_cipher_register
+                                   (GNUTLS_CIPHER_AES_192_GCM, 80,
+                                    &_gnutls_aes_gcm_pclmul, 0);
+                               if (ret < 0) {
+                                       gnutls_assert();
+                               }
+
                                ret =
                                    gnutls_crypto_single_cipher_register
                                    (GNUTLS_CIPHER_AES_256_GCM, 80,
@@ -790,6 +814,14 @@ void register_x86_intel_crypto(unsigned capabilities)
                                gnutls_assert();
                        }
 
+                       ret =
+                           gnutls_crypto_single_cipher_register
+                           (GNUTLS_CIPHER_AES_192_GCM, 80,
+                            &_gnutls_aes_gcm_x86_aesni, 0);
+                       if (ret < 0) {
+                               gnutls_assert();
+                       }
+
                        ret =
                            gnutls_crypto_single_cipher_register
                            (GNUTLS_CIPHER_AES_256_GCM, 80,
index 59dc7ea7fb3003c6ca8983676440f2896f95cd11..d57c1d5dba0f89813c7ae22da281596c337ee0e2 100644 (file)
@@ -69,6 +69,15 @@ static const cipher_entry_st algorithms[] = {
          .explicit_iv = 8,
          .cipher_iv = 12,
          .tagsize = 16},
+       { .name = "AES-192-GCM",
+         .id = GNUTLS_CIPHER_AES_192_GCM,
+         .blocksize = 16,
+         .keysize = 24,
+         .type = CIPHER_AEAD,
+         .implicit_iv = 4,
+         .explicit_iv = 8,
+         .cipher_iv = 12,
+         .tagsize = 16},
        { .name = "AES-256-GCM",
          .id = GNUTLS_CIPHER_AES_256_GCM,
          .blocksize = 16,
index f904b029b233940860c9991133d3a779f93b3c2d..86bff3f98ee5c533c3133c7228c241c743fbf146 100644 (file)
@@ -141,6 +141,27 @@ const struct cipher_aead_vectors_st aes128_gcm_vectors[] = {
         "\x5b\xc9\x4f\xbc\x32\x21\xa5\xdb\x94\xfa\xe9\x5a\xe7\x12\x1a\x47"}
 };
 
+const struct cipher_aead_vectors_st aes192_gcm_vectors[] = {
+       {
+        .compat_apis = 1,
+        STR(key, key_size,
+            "\xfe\xff\xe9\x92\x86\x65\x73\x1c\x6d\x6a\x8f\x94\x67\x30\x83\x08\xfe\xff\xe9\x92\x86\x65\x73\x1c"),
+        .auth = NULL,
+        .auth_size = 0,
+        STR(plaintext, plaintext_size,
+            "\xd9\x31\x32\x25\xf8\x84\x06\xe5\xa5\x59\x09\xc5\xaf\xf5\x26\x9a\x86\xa7\xa9\x53\x15\x34\xf7\xda\x2e\x4c\x30\x3d\x8a\x31\x8a\x72\x1c\x3c\x0c\x95\x95\x68\x09\x53\x2f\xcf\x0e\x24\x49\xa6\xb5\x25\xb1\x6a\xed\xf5\xaa\x0d\xe6\x57\xba\x63\x7b\x39\x1a\xaf\xd2\x55"),
+        .ciphertext =
+        (uint8_t *)
+        "\x39\x80\xca\x0b\x3c\x00\xe8\x41\xeb\x06\xfa\xc4\x87\x2a\x27\x57\x85\x9e\x1c\xea\xa6\xef\xd9\x84\x62\x85\x93\xb4\x0c\xa1\xe1\x9c\x7d\x77\x3d\x00\xc1\x44\xc5\x25\xac\x61\x9d\x18\xc8\x4a\x3f\x47\x18\xe2\x44\x8b\x2f\xe3\x24\xd9\xcc\xda\x27\x10\xac\xad\xe2\x56",
+        STR(iv, iv_size,
+            "\xca\xfe\xba\xbe\xfa\xce\xdb\xad\xde\xca\xf8\x88"),
+        .tag_size = 16,
+        .tag =
+        (void *)
+        "\x99\x24\xa7\xc8\x58\x73\x36\xbf\xb1\x18\x02\x4d\xb8\x67\x4a\x14"},
+
+};
+
 const struct cipher_aead_vectors_st aes256_gcm_vectors[] = {
        {
         .compat_apis = 1,
@@ -1991,6 +2012,9 @@ int gnutls_cipher_self_test(unsigned flags, gnutls_cipher_algorithm_t cipher)
                CASE(GNUTLS_CIPHER_AES_128_GCM, test_cipher_aead,
                     aes128_gcm_vectors);
                FALLTHROUGH;
+               CASE(GNUTLS_CIPHER_AES_192_GCM, test_cipher_aead,
+                    aes192_gcm_vectors);
+               FALLTHROUGH;
                CASE(GNUTLS_CIPHER_AES_256_GCM, test_cipher_aead,
                     aes256_gcm_vectors);
                FALLTHROUGH;
index 1464c9595bc6152fe2f9555e19a713b9105a3b76..f76f24da75afc034f94913acc69c4de54e4370be 100644 (file)
@@ -138,6 +138,7 @@ static unsigned is_cipher_algo_forbidden(gnutls_cipher_algorithm_t algo)
                        case GNUTLS_CIPHER_AES_256_CBC:
                        case GNUTLS_CIPHER_AES_192_CBC:
                        case GNUTLS_CIPHER_AES_128_GCM:
+                       case GNUTLS_CIPHER_AES_192_GCM:
                        case GNUTLS_CIPHER_AES_256_GCM:
                        case GNUTLS_CIPHER_AES_128_CCM:
                        case GNUTLS_CIPHER_AES_256_CCM:
index 7d9870996ace8c02df38a991e1cfdced3655ad5c..264da238a099d96801a59beea836bf7893885b0e 100644 (file)
@@ -143,6 +143,7 @@ extern "C" {
  *                             the AEAD interface, and the IV plays a role as
  *                             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).
  *
  * Enumeration of different symmetric encryption algorithms.
  */
@@ -186,6 +187,7 @@ typedef enum gnutls_cipher_algorithm {
        GNUTLS_CIPHER_CHACHA20_32 = 36,
        GNUTLS_CIPHER_AES_128_SIV = 37,
        GNUTLS_CIPHER_AES_256_SIV = 38,
+       GNUTLS_CIPHER_AES_192_GCM = 39,
 
        /* used only for PGP internals. Ignored in TLS/SSL
         */
index 70a6509f2bdad82c3f13df03e3fb490434284fbb..69ed70213d971a725c49ee191cd29d46a6f46f8d 100644 (file)
@@ -481,6 +481,23 @@ static const struct nettle_cipher_st builtin_ciphers[] = {
           .set_iv = (setiv_func)gcm_aes128_set_iv,
           .max_iv_size = GCM_IV_SIZE,
        },
+       {  .algo = GNUTLS_CIPHER_AES_192_GCM,
+          .block_size = AES_BLOCK_SIZE,
+          .key_size = AES192_KEY_SIZE,
+          .encrypt_block = (nettle_cipher_func*)aes192_encrypt,
+          .decrypt_block = (nettle_cipher_func*)aes192_decrypt,
+
+          .ctx_size = sizeof(struct gcm_aes192_ctx),
+          .encrypt = _gcm_encrypt,
+          .decrypt = _gcm_decrypt,
+          .set_encrypt_key = (nettle_set_key_func*)gcm_aes192_set_key,
+          .set_decrypt_key = (nettle_set_key_func*)gcm_aes192_set_key,
+
+          .tag = (nettle_hash_digest_func*)gcm_aes192_digest,
+          .auth = (nettle_hash_update_func*)gcm_aes192_update,
+          .set_iv = (setiv_func)gcm_aes192_set_iv,
+          .max_iv_size = GCM_IV_SIZE,
+       },
        {  .algo = GNUTLS_CIPHER_AES_256_GCM,
           .block_size = AES_BLOCK_SIZE,
           .key_size = AES256_KEY_SIZE,
@@ -1030,6 +1047,7 @@ wrap_nettle_cipher_setiv(void *_ctx, const void *iv, size_t iv_size)
 
        switch (ctx->cipher->algo) {
        case GNUTLS_CIPHER_AES_128_GCM:
+       case GNUTLS_CIPHER_AES_192_GCM:
        case GNUTLS_CIPHER_AES_256_GCM:
                FIPS_RULE(iv_size < GCM_IV_SIZE, GNUTLS_E_INVALID_REQUEST, "access to short GCM nonce size\n");
                break;
index 10e3db86266b54bd723c799cc48dd1e0c2d8da36..fba9010d9ec12fa6ee6686b5d5fbbef451008fdc 100644 (file)
@@ -116,6 +116,7 @@ doit(void)
        }
 
        start("aes-128-gcm", GNUTLS_CIPHER_AES_128_GCM);
+       start("aes-192-gcm", GNUTLS_CIPHER_AES_192_GCM);
        start("aes-256-gcm", GNUTLS_CIPHER_AES_256_GCM);
        start("aes-128-ccm", GNUTLS_CIPHER_AES_128_CCM);
        if (!gnutls_fips140_mode_enabled())
index a29963aa5a2697ae261293c92ce658e07ccedd88..17872b7a431a4e79c615b84872f34424ae3837c9 100644 (file)
@@ -266,8 +266,10 @@ void start(const char *name, int algo, unsigned aead)
 void doit(void)
 {
        start("aes128-gcm", GNUTLS_CIPHER_AES_128_GCM, 1);
+       start("aes192-gcm", GNUTLS_CIPHER_AES_192_GCM, 1);
        start("aes256-gcm", GNUTLS_CIPHER_AES_256_GCM, 1);
        start("aes128-cbc", GNUTLS_CIPHER_AES_128_CBC, 0);
+       start("aes192-cbc", GNUTLS_CIPHER_AES_192_CBC, 0);
        start("aes256-cbc", GNUTLS_CIPHER_AES_256_CBC, 0);
        start("3des-cbc", GNUTLS_CIPHER_3DES_CBC, 0);
        if (!gnutls_fips140_mode_enabled()) {
index 64adf25a450f8f3cf5fbb3fdcff76efb087ef0be..3d55131e52ed78517fb64af89cd744bd77d3ae57 100644 (file)
@@ -195,6 +195,7 @@ void doit(void)
 
        /* ciphers */
        cipher_test("aes-128-gcm", GNUTLS_CIPHER_AES_128_GCM, 16);
+       cipher_test("aes-192-gcm", GNUTLS_CIPHER_AES_192_GCM, 16);
        cipher_test("aes-256-gcm", GNUTLS_CIPHER_AES_256_GCM, 16);
 #if OPENSSL_VERSION_NUMBER >= 0x10100000L
        if (!gnutls_fips140_mode_enabled()) {