]> git.ipfire.org Git - thirdparty/gnutls.git/commitdiff
nettle: utilize nettle_cbc_aes*_encrypt for performance
authorDaiki Ueno <ueno@gnu.org>
Wed, 15 May 2024 01:17:41 +0000 (10:17 +0900)
committerDaiki Ueno <ueno@gnu.org>
Wed, 15 May 2024 07:34:31 +0000 (16:34 +0900)
While CBC encryption is inherently slow for lack of parallelisim,
Nettle >= 3.8 provides specialized AES-CBC encryption functions to
improve performance by avoiding multiple calls to block cipher
initialization. This patch makes GnuTLS use those functions if
available.

Here are the results of benchmark:

* GNUTLS_CPUID_OVERRIDE=0x1, without nettle_cbc_aes*_encrypt:

  Checking cipher-MAC combinations, payload size: 16384
          AES-128-CBC-SHA1 0.90 GB/sec
          AES-128-CBC-SHA256 0.88 GB/sec

  Checking ciphers, payload size: 16384
               AES-128-CBC 1.56 GB/sec

* GNUTLS_CPUID_OVERRIDE=0x1, with nettle_cbc_aes*_encrypt:

  Checking cipher-MAC combinations, payload size: 16384
          AES-128-CBC-SHA1 1.08 GB/sec
          AES-128-CBC-SHA256 1.05 GB/sec

  Checking ciphers, payload size: 16384
               AES-128-CBC 2.16 GB/sec

* GNUTLS_CPUID_OVERRIDE unset:

  Checking cipher-MAC combinations, payload size: 16384
          AES-128-CBC-SHA1 1.13 GB/sec
          AES-128-CBC-SHA256 1.05 GB/sec

  Checking ciphers, payload size: 16384
               AES-128-CBC 2.24 GB/sec

Signed-off-by: Daiki Ueno <ueno@gnu.org>
configure.ac
lib/nettle/cipher.c

index 934377eba1f7c444b1653ccfa8f5844855a71ba5..6e34a999e655557eaea2f8c63a222c88f6aa5a0b 100644 (file)
@@ -792,6 +792,12 @@ AC_CHECK_FUNCS(nettle_rsa_oaep_sha256_encrypt)
 LIBS=$save_LIBS
 AM_CONDITIONAL([NEED_RSA_OAEP], [test "$ac_cv_func_nettle_rsa_oaep_sha256_encrypt" != yes])
 
+# Check for specialized AES-CBC encryption
+save_LIBS=$LIBS
+LIBS="$LIBS $NETTLE_LIBS"
+AC_CHECK_FUNCS(nettle_cbc_aes128_encrypt)
+LIBS=$save_LIBS
+
 # Check sonames of the linked libraries needed for FIPS selftests.
 save_CFLAGS=$CFLAGS
 CFLAGS="$CFLAGS $GMP_CFLAGS"
index edc1c37e8407d267c5e74a992264fb22448693c3..f5db2e504dff39790914d5b7d1ec06f56d3c18c1 100644 (file)
@@ -501,6 +501,31 @@ static void _xts_aes256_decrypt(struct nettle_cipher_ctx *ctx, size_t length,
        xts_aes256_decrypt_message(ctx->ctx_ptr, ctx->iv, length, dst, src);
 }
 
+#ifdef HAVE_NETTLE_CBC_AES128_ENCRYPT
+
+static void _cbc_aes128_encrypt(struct nettle_cipher_ctx *ctx, size_t length,
+                               uint8_t *dst, const uint8_t *src)
+{
+       assert((length % ctx->cipher->block_size) == 0);
+       cbc_aes128_encrypt(ctx->ctx_ptr, ctx->iv, length, dst, src);
+}
+
+static void _cbc_aes192_encrypt(struct nettle_cipher_ctx *ctx, size_t length,
+                               uint8_t *dst, const uint8_t *src)
+{
+       assert((length % ctx->cipher->block_size) == 0);
+       cbc_aes192_encrypt(ctx->ctx_ptr, ctx->iv, length, dst, src);
+}
+
+static void _cbc_aes256_encrypt(struct nettle_cipher_ctx *ctx, size_t length,
+                               uint8_t *dst, const uint8_t *src)
+{
+       assert((length % ctx->cipher->block_size) == 0);
+       cbc_aes256_encrypt(ctx->ctx_ptr, ctx->iv, length, dst, src);
+}
+
+#endif /* HAVE_NETTLE_CBC_AES128_ENCRYPT */
+
 static const struct nettle_cipher_st builtin_ciphers[] = {
        {
                .algo = GNUTLS_CIPHER_AES_128_GCM,
@@ -659,7 +684,11 @@ static const struct nettle_cipher_st builtin_ciphers[] = {
 
                .ctx_size = sizeof(
                        struct CBC_CTX(struct aes128_ctx, AES_BLOCK_SIZE)),
+#ifdef HAVE_NETTLE_CBC_AES128_ENCRYPT
+               .encrypt = _cbc_aes128_encrypt,
+#else
                .encrypt = _cbc_encrypt,
+#endif
                .decrypt = _cbc_decrypt,
                .set_encrypt_key =
                        (nettle_set_key_func *)aes128_set_encrypt_key,
@@ -676,7 +705,11 @@ static const struct nettle_cipher_st builtin_ciphers[] = {
 
                .ctx_size = sizeof(
                        struct CBC_CTX(struct aes192_ctx, AES_BLOCK_SIZE)),
+#ifdef HAVE_NETTLE_CBC_AES128_ENCRYPT
+               .encrypt = _cbc_aes192_encrypt,
+#else
                .encrypt = _cbc_encrypt,
+#endif
                .decrypt = _cbc_decrypt,
                .set_encrypt_key =
                        (nettle_set_key_func *)aes192_set_encrypt_key,
@@ -693,7 +726,11 @@ static const struct nettle_cipher_st builtin_ciphers[] = {
 
                .ctx_size = sizeof(
                        struct CBC_CTX(struct aes256_ctx, AES_BLOCK_SIZE)),
+#ifdef HAVE_NETTLE_CBC_AES128_ENCRYPT
+               .encrypt = _cbc_aes256_encrypt,
+#else
                .encrypt = _cbc_encrypt,
+#endif
                .decrypt = _cbc_decrypt,
                .set_encrypt_key =
                        (nettle_set_key_func *)aes256_set_encrypt_key,