int
NNA_GenerateAuthEF(NTP_Packet *packet, NTP_PacketInfo *info, SIV_Instance siv,
- const unsigned char *nonce, int nonce_length,
+ const unsigned char *nonce, int max_nonce_length,
const unsigned char *plaintext, int plaintext_length,
int min_ef_length)
{
- int auth_length, ciphertext_length, assoc_length;
+ int auth_length, ciphertext_length, assoc_length, nonce_length, max_siv_nonce_length;
int nonce_padding, ciphertext_padding, additional_padding;
unsigned char *ciphertext, *body;
struct AuthHeader *header;
assert(sizeof (*header) == 4);
- if (nonce_length <= 0 || plaintext_length < 0) {
+ if (max_nonce_length <= 0 || plaintext_length < 0) {
DEBUG_LOG("Invalid nonce/plaintext length");
return 0;
}
assoc_length = info->length;
+ max_siv_nonce_length = SIV_GetMaxNonceLength(siv);
+ nonce_length = MIN(max_nonce_length, max_siv_nonce_length);
ciphertext_length = SIV_GetTagLength(siv) + plaintext_length;
nonce_padding = get_padding_length(nonce_length);
ciphertext_padding = get_padding_length(ciphertext_length);
auth_length = sizeof (*header) + nonce_length + nonce_padding +
ciphertext_length + ciphertext_padding;
additional_padding = MAX(min_ef_length - auth_length - 4, 0);
- additional_padding = MAX(NTS_MIN_UNPADDED_NONCE_LENGTH - nonce_length - nonce_padding,
- additional_padding);
+ additional_padding = MAX(MIN(NTS_MIN_UNPADDED_NONCE_LENGTH, max_siv_nonce_length) -
+ nonce_length - nonce_padding, additional_padding);
auth_length += additional_padding;
if (!NEF_AddBlankField(packet, info, NTP_EF_NTS_AUTH_AND_EEF, auth_length,
NNA_DecryptAuthEF(NTP_Packet *packet, NTP_PacketInfo *info, SIV_Instance siv, int ef_start,
unsigned char *plaintext, int buffer_length, int *plaintext_length)
{
- int siv_tag_length, nonce_length, ciphertext_length;
+ int siv_tag_length, max_siv_nonce_length, nonce_length, ciphertext_length;
unsigned char *nonce, *ciphertext;
int ef_type, ef_body_length;
void *ef_body;
nonce = (unsigned char *)(header + 1);
ciphertext = nonce + get_padded_length(nonce_length);
+ max_siv_nonce_length = SIV_GetMaxNonceLength(siv);
siv_tag_length = SIV_GetTagLength(siv);
if (nonce_length < 1 ||
return 0;
}
- if (ef_body_length < sizeof (*header) +
- NTS_MIN_UNPADDED_NONCE_LENGTH + get_padded_length(ciphertext_length)) {
+ if (sizeof (*header) + MIN(NTS_MIN_UNPADDED_NONCE_LENGTH, max_siv_nonce_length) +
+ get_padded_length(ciphertext_length) > ef_body_length) {
DEBUG_LOG("Missing padding");
return 0;
}
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 (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));
-
- nonce_length = random() % sizeof (nonce) + 1;
- for (j = 0; j < nonce_length; j++)
- nonce[j] = random() % 256;
-
- plaintext_length = random() % (sizeof (plaintext) + 1);
- for (j = 0; j < plaintext_length; j++)
- plaintext[j] = random() % 256;
-
- packet_length = NTP_HEADER_LENGTH + random() % 100 * 4;
- min_ef_length = random() % (sizeof (packet) - packet_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;
-
- 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,
- -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);
-
- 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,
- -1, &plaintext2_length);
- TEST_CHECK(!r);
-
- 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]--;
+ for (algo = 1; algo < 100; algo++) {
+ siv = SIV_CreateInstance(algo);
+ if (!siv) {
+ TEST_CHECK(algo != AEAD_AES_SIV_CMAC_256);
+ continue;
+ }
+
+ DEBUG_LOG("algo=%d", (int)algo);
+
+ 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));
+
+ 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;
+
+ plaintext_length = random() % (sizeof (plaintext) + 1);
+ for (j = 0; j < plaintext_length; j++)
+ plaintext[j] = random() % 256;
+
+ packet_length = NTP_HEADER_LENGTH + random() % 100 * 4;
+ min_ef_length = random() % (sizeof (packet) - packet_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;
+
+ 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,
+ -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_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,
+ -1, &plaintext2_length);
+ TEST_CHECK(!r);
+
+ 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