From a74b63277a9ce110d8acf529a13ec0d497e29034 Mon Sep 17 00:00:00 2001 From: Miroslav Lichvar Date: Tue, 12 Sep 2023 10:18:01 +0200 Subject: [PATCH] siv: add support for AES-GCM-SIV in gnutls 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 | 7 +++++++ siv_gnutls.c | 31 +++++++++++++++++++++++++++---- 2 files changed, 34 insertions(+), 4 deletions(-) diff --git a/configure b/configure index 81bb4b8..e18560f 100755 --- 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);' diff --git a/siv_gnutls.c b/siv_gnutls.c index 95387f0..04628eb 100644 --- a/siv_gnutls.c +++ b/siv_gnutls.c @@ -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;