]> git.ipfire.org Git - thirdparty/chrony.git/commitdiff
siv: add support for AES-GCM-SIV in gnutls
authorMiroslav Lichvar <mlichvar@redhat.com>
Tue, 12 Sep 2023 08:18:01 +0000 (10:18 +0200)
committerMiroslav Lichvar <mlichvar@redhat.com>
Tue, 12 Sep 2023 08:31:36 +0000 (10:31 +0200)
Add support for AES-128-GCM-SIV in the current development code of
gnutls. There doesn't seem to be an API to get the cipher's minimum and
maximum nonce length and it doesn't check for invalid lengths. Hardcode
and check the limits in chrony for now.

configure
siv_gnutls.c

index 81bb4b8e6c4b716423e615bdb163c5c56cef5d7c..e18560feca6ada8b0319e3ce4648220c6782b54e 100755 (executable)
--- a/configure
+++ b/configure
@@ -1012,6 +1012,13 @@ if [ $feat_ntp = "1" ] && [ $feat_nts = "1" ] && [ $try_gnutls = "1" ]; then
       then
         EXTRA_OBJECTS="$EXTRA_OBJECTS siv_gnutls.o"
         add_def HAVE_SIV
+        if [ $try_aes_gcm_siv = "1" ] && test_code 'AES-GCM-SIV in gnutls' \
+          'gnutls/crypto.h' "$test_cflags" "$test_link $LIBS" '
+            return gnutls_aead_cipher_init((void *)1, GNUTLS_CIPHER_AES_128_SIV_GCM,
+                                           (void *)2);'
+        then
+          add_def HAVE_GNUTLS_SIV_GCM
+        fi
         if test_code 'gnutls_aead_cipher_set_key()' 'gnutls/crypto.h' \
           "$test_cflags" "$test_link $LIBS" '
             return gnutls_aead_cipher_set_key((void *)1, (void *)2);'
index 95387f0d4cd4f1264760ae81f8edd794e25343e6..04628eb7697ca175cbc5cc7fc3808fe838025766 100644 (file)
@@ -37,6 +37,8 @@
 struct SIV_Instance_Record {
   gnutls_cipher_algorithm_t algorithm;
   gnutls_aead_cipher_hd_t cipher;
+  int min_nonce_length;
+  int max_nonce_length;
 };
 
 /* ================================================== */
@@ -81,6 +83,10 @@ get_cipher_algorithm(SIV_Algorithm algorithm)
   switch (algorithm) {
     case AEAD_AES_SIV_CMAC_256:
       return GNUTLS_CIPHER_AES_128_SIV;
+#if HAVE_GNUTLS_SIV_GCM
+    case AEAD_AES_128_GCM_SIV:
+      return GNUTLS_CIPHER_AES_128_SIV_GCM;
+#endif
     default:
       return 0;
   }
@@ -112,6 +118,19 @@ SIV_CreateInstance(SIV_Algorithm algorithm)
   instance->algorithm = calgo;
   instance->cipher = NULL;
 
+  switch (algorithm) {
+    case AEAD_AES_SIV_CMAC_256:
+      instance->min_nonce_length = 1;
+      instance->max_nonce_length = INT_MAX;
+      break;
+    case AEAD_AES_128_GCM_SIV:
+      instance->min_nonce_length = 12;
+      instance->max_nonce_length = 12;
+      break;
+    default:
+      assert(0);
+  }
+
   instance_counter++;
 
   return instance;
@@ -143,6 +162,8 @@ SIV_GetKeyLength(SIV_Algorithm algorithm)
     return 0;
 
   len = gnutls_cipher_get_key_size(calgo);
+  if (len == 0)
+    return 0;
 
   if (len < 1 || len > SIV_MAX_KEY_LENGTH)
     LOG_FATAL("Invalid key length");
@@ -198,7 +219,7 @@ SIV_SetKey(SIV_Instance instance, const unsigned char *key, int length)
 int
 SIV_GetMinNonceLength(SIV_Instance instance)
 {
-  return 1;
+  return instance->min_nonce_length;
 }
 
 /* ================================================== */
@@ -206,7 +227,7 @@ SIV_GetMinNonceLength(SIV_Instance instance)
 int
 SIV_GetMaxNonceLength(SIV_Instance instance)
 {
-  return INT_MAX;
+  return instance->max_nonce_length;
 }
 
 /* ================================================== */
@@ -238,7 +259,8 @@ SIV_Encrypt(SIV_Instance instance,
   if (!instance->cipher)
     return 0;
 
-  if (nonce_length < 1 || assoc_length < 0 ||
+  if (nonce_length < instance->min_nonce_length ||
+      nonce_length > instance->max_nonce_length || assoc_length < 0 ||
       plaintext_length < 0 || ciphertext_length < 0)
     return 0;
 
@@ -269,7 +291,8 @@ SIV_Decrypt(SIV_Instance instance,
   if (!instance->cipher)
     return 0;
 
-  if (nonce_length < 1 || assoc_length < 0 ||
+  if (nonce_length < instance->min_nonce_length ||
+      nonce_length > instance->max_nonce_length || assoc_length < 0 ||
       plaintext_length < 0 || ciphertext_length < 0)
     return 0;