nts: add support for NTP authenticator field using AES-GCM-SIV

Add support for SIV algorithms which have maximum nonce length shorter
than 16 bytes.
This commit is contained in:
Miroslav Lichvar
2022-10-10 15:09:01 +02:00
parent ec89739d50
commit 73042494bd
3 changed files with 85 additions and 61 deletions

View File

@@ -34,74 +34,95 @@ test_unit(void)
unsigned char key[SIV_MAX_KEY_LENGTH], nonce[256], plaintext[256], plaintext2[256];
NTP_PacketInfo info;
NTP_Packet packet;
SIV_Algorithm algo;
SIV_Instance siv;
int i, j, r, packet_length, nonce_length, key_length;
int plaintext_length, plaintext2_length, min_ef_length;
siv = SIV_CreateInstance(AEAD_AES_SIV_CMAC_256);
TEST_CHECK(siv);
for (algo = 1; algo < 100; algo++) {
siv = SIV_CreateInstance(algo);
if (!siv) {
TEST_CHECK(algo != AEAD_AES_SIV_CMAC_256);
continue;
}
for (i = 0; i < 10000; i++) {
key_length = SIV_GetKeyLength(AEAD_AES_SIV_CMAC_256);
for (j = 0; j < key_length; j++)
key[j] = random() % 256;
TEST_CHECK(SIV_SetKey(siv, key, key_length));
DEBUG_LOG("algo=%d", (int)algo);
nonce_length = random() % sizeof (nonce) + 1;
for (j = 0; j < nonce_length; j++)
nonce[j] = random() % 256;
for (i = 0; i < 10000; i++) {
key_length = SIV_GetKeyLength(algo);
for (j = 0; j < key_length; j++)
key[j] = random() % 256;
TEST_CHECK(SIV_SetKey(siv, key, key_length));
plaintext_length = random() % (sizeof (plaintext) + 1);
for (j = 0; j < plaintext_length; j++)
plaintext[j] = random() % 256;
assert(sizeof (nonce) >= SIV_GetMinNonceLength(siv));
nonce_length = SIV_GetMinNonceLength(siv) +
random() % (MIN(sizeof (nonce), SIV_GetMaxNonceLength(siv)) -
SIV_GetMinNonceLength(siv) + 1);
for (j = 0; j < nonce_length; j++)
nonce[j] = random() % 256;
packet_length = NTP_HEADER_LENGTH + random() % 100 * 4;
min_ef_length = random() % (sizeof (packet) - packet_length);
plaintext_length = random() % (sizeof (plaintext) + 1);
for (j = 0; j < plaintext_length; j++)
plaintext[j] = random() % 256;
memset(&packet, 0, sizeof (packet));
packet.lvm = NTP_LVM(0, 4, 0);
memset(&info, 0, sizeof (info));
info.version = 4;
info.length = packet_length;
packet_length = NTP_HEADER_LENGTH + random() % 100 * 4;
min_ef_length = random() % (sizeof (packet) - packet_length);
DEBUG_LOG("packet_length=%d nonce_length=%d plaintext_length=%d min_ef_length=%d",
packet_length, nonce_length, plaintext_length, min_ef_length);
memset(&packet, 0, sizeof (packet));
packet.lvm = NTP_LVM(0, 4, 0);
memset(&info, 0, sizeof (info));
info.version = 4;
info.length = packet_length;
r = NNA_GenerateAuthEF(&packet, &info, siv, nonce, nonce_length, plaintext,
-1, 0);
TEST_CHECK(!r);
r = NNA_GenerateAuthEF(&packet, &info, siv, nonce, 0, plaintext,
plaintext_length, 0);
TEST_CHECK(!r);
r = NNA_GenerateAuthEF(&packet, &info, siv, nonce, nonce_length, plaintext,
plaintext_length, sizeof (packet) - info.length + 1);
TEST_CHECK(!r);
DEBUG_LOG("packet_length=%d nonce_length=%d plaintext_length=%d min_ef_length=%d",
packet_length, nonce_length, plaintext_length, min_ef_length);
r = NNA_GenerateAuthEF(&packet, &info, siv, nonce, nonce_length, plaintext,
plaintext_length, min_ef_length);
TEST_CHECK(r);
TEST_CHECK(info.length - packet_length >= min_ef_length);
r = NNA_GenerateAuthEF(&packet, &info, siv, nonce, nonce_length, plaintext,
-1, 0);
TEST_CHECK(!r);
r = NNA_GenerateAuthEF(&packet, &info, siv, nonce, 0, plaintext,
plaintext_length, 0);
TEST_CHECK(!r);
if (SIV_GetMinNonceLength(siv) > 1) {
r = NNA_GenerateAuthEF(&packet, &info, siv, nonce, SIV_GetMinNonceLength(siv) - 1,
plaintext, plaintext_length, 0);
TEST_CHECK(!r);
}
if (SIV_GetMaxNonceLength(siv) <= sizeof (nonce)) {
r = NNA_GenerateAuthEF(&packet, &info, siv, nonce, SIV_GetMaxNonceLength(siv) - 1,
plaintext, plaintext_length, 0);
TEST_CHECK(!r);
}
r = NNA_GenerateAuthEF(&packet, &info, siv, nonce, nonce_length, plaintext,
plaintext_length, sizeof (packet) - info.length + 1);
TEST_CHECK(!r);
r = NNA_DecryptAuthEF(&packet, &info, siv, packet_length, plaintext2,
-1, &plaintext2_length);
TEST_CHECK(!r);
r = NNA_GenerateAuthEF(&packet, &info, siv, nonce, nonce_length, plaintext,
plaintext_length, min_ef_length);
TEST_CHECK(r);
TEST_CHECK(info.length - packet_length >= min_ef_length);
r = NNA_DecryptAuthEF(&packet, &info, siv, packet_length, plaintext2,
sizeof (plaintext2), &plaintext2_length);
TEST_CHECK(r);
TEST_CHECK(plaintext_length == plaintext2_length);
TEST_CHECK(memcmp(plaintext, plaintext2, plaintext_length) == 0);
r = NNA_DecryptAuthEF(&packet, &info, siv, packet_length, plaintext2,
-1, &plaintext2_length);
TEST_CHECK(!r);
j = random() % (packet_length + plaintext_length +
nonce_length + SIV_GetTagLength(siv) + 8) / 4 * 4;
((unsigned char *)&packet)[j]++;
r = NNA_DecryptAuthEF(&packet, &info, siv, packet_length, plaintext2,
sizeof (plaintext2), &plaintext2_length);
TEST_CHECK(!r);
((unsigned char *)&packet)[j]--;
r = NNA_DecryptAuthEF(&packet, &info, siv, packet_length, plaintext2,
sizeof (plaintext2), &plaintext2_length);
TEST_CHECK(r);
TEST_CHECK(plaintext_length == plaintext2_length);
TEST_CHECK(memcmp(plaintext, plaintext2, plaintext_length) == 0);
j = random() % (packet_length + plaintext_length +
nonce_length + SIV_GetTagLength(siv) + 8) / 4 * 4;
((unsigned char *)&packet)[j]++;
r = NNA_DecryptAuthEF(&packet, &info, siv, packet_length, plaintext2,
sizeof (plaintext2), &plaintext2_length);
TEST_CHECK(!r);
((unsigned char *)&packet)[j]--;
}
SIV_DestroyInstance(siv);
}
SIV_DestroyInstance(siv);
}
#else
void