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.
This commit is contained in:
Miroslav Lichvar 2023-09-12 10:18:01 +02:00
parent aa8196328c
commit a74b63277a
2 changed files with 34 additions and 4 deletions

7
configure vendored
View file

@ -1012,6 +1012,13 @@ if [ $feat_ntp = "1" ] && [ $feat_nts = "1" ] && [ $try_gnutls = "1" ]; then
then then
EXTRA_OBJECTS="$EXTRA_OBJECTS siv_gnutls.o" EXTRA_OBJECTS="$EXTRA_OBJECTS siv_gnutls.o"
add_def HAVE_SIV 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' \ if test_code 'gnutls_aead_cipher_set_key()' 'gnutls/crypto.h' \
"$test_cflags" "$test_link $LIBS" ' "$test_cflags" "$test_link $LIBS" '
return gnutls_aead_cipher_set_key((void *)1, (void *)2);' return gnutls_aead_cipher_set_key((void *)1, (void *)2);'

View file

@ -37,6 +37,8 @@
struct SIV_Instance_Record { struct SIV_Instance_Record {
gnutls_cipher_algorithm_t algorithm; gnutls_cipher_algorithm_t algorithm;
gnutls_aead_cipher_hd_t cipher; 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) { switch (algorithm) {
case AEAD_AES_SIV_CMAC_256: case AEAD_AES_SIV_CMAC_256:
return GNUTLS_CIPHER_AES_128_SIV; 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: default:
return 0; return 0;
} }
@ -112,6 +118,19 @@ SIV_CreateInstance(SIV_Algorithm algorithm)
instance->algorithm = calgo; instance->algorithm = calgo;
instance->cipher = NULL; 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++; instance_counter++;
return instance; return instance;
@ -143,6 +162,8 @@ SIV_GetKeyLength(SIV_Algorithm algorithm)
return 0; return 0;
len = gnutls_cipher_get_key_size(calgo); len = gnutls_cipher_get_key_size(calgo);
if (len == 0)
return 0;
if (len < 1 || len > SIV_MAX_KEY_LENGTH) if (len < 1 || len > SIV_MAX_KEY_LENGTH)
LOG_FATAL("Invalid key length"); LOG_FATAL("Invalid key length");
@ -198,7 +219,7 @@ SIV_SetKey(SIV_Instance instance, const unsigned char *key, int length)
int int
SIV_GetMinNonceLength(SIV_Instance instance) SIV_GetMinNonceLength(SIV_Instance instance)
{ {
return 1; return instance->min_nonce_length;
} }
/* ================================================== */ /* ================================================== */
@ -206,7 +227,7 @@ SIV_GetMinNonceLength(SIV_Instance instance)
int int
SIV_GetMaxNonceLength(SIV_Instance instance) 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) if (!instance->cipher)
return 0; 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) plaintext_length < 0 || ciphertext_length < 0)
return 0; return 0;
@ -269,7 +291,8 @@ SIV_Decrypt(SIV_Instance instance,
if (!instance->cipher) if (!instance->cipher)
return 0; 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) plaintext_length < 0 || ciphertext_length < 0)
return 0; return 0;