nts: refactor NTS context

Add a context structure for the algorithm and keys established by
NTS-KE. Modify the client to save the context and reset the SIV key to
the C2S/S2C key before each request/response instead of keeping two SIV
instances.

This will make it easier for the server to support different algorithms
and allow the client to save the context with cookies to disk.
This commit is contained in:
Miroslav Lichvar
2020-03-30 18:06:57 +02:00
parent 5296858411
commit adcf073484
10 changed files with 121 additions and 91 deletions

View File

@@ -132,8 +132,8 @@ void
test_unit(void)
{
NKSN_Instance session;
NKE_Context context, context2;
NKE_Cookie cookie;
NKE_Key c2s, s2c, c2s2, s2c2;
int i, valid, l;
uint32_t sum, sum2;
@@ -167,14 +167,16 @@ test_unit(void)
for (i = 0; i < 10000; i++) {
get_keys(session, AEAD_AES_SIV_CMAC_256, &c2s, &s2c);
context.algorithm = AEAD_AES_SIV_CMAC_256;
get_keys(session, context.algorithm, &context.c2s, &context.s2c);
memset(&cookie, 0, sizeof (cookie));
TEST_CHECK(NKS_GenerateCookie(&c2s, &s2c, &cookie));
TEST_CHECK(NKS_DecodeCookie(&cookie, &c2s2, &s2c2));
TEST_CHECK(c2s.length == c2s2.length);
TEST_CHECK(s2c.length == s2c2.length);
TEST_CHECK(memcmp(c2s.key, c2s2.key, c2s.length) == 0);
TEST_CHECK(memcmp(s2c.key, s2c2.key, s2c.length) == 0);
TEST_CHECK(NKS_GenerateCookie(&context, &cookie));
TEST_CHECK(NKS_DecodeCookie(&cookie, &context2));
TEST_CHECK(context.algorithm == context2.algorithm);
TEST_CHECK(context.c2s.length == context2.c2s.length);
TEST_CHECK(context.s2c.length == context2.s2c.length);
TEST_CHECK(memcmp(context.c2s.key, context2.c2s.key, context.c2s.length) == 0);
TEST_CHECK(memcmp(context.s2c.key, context2.s2c.key, context.s2c.length) == 0);
if (random() % 4) {
cookie.cookie[random() % (cookie.length)]++;
@@ -185,7 +187,7 @@ test_unit(void)
while (l == cookie.length)
cookie.length = random() % (sizeof (cookie.cookie) + 1);
}
TEST_CHECK(!NKS_DecodeCookie(&cookie, &c2s2, &s2c2));
TEST_CHECK(!NKS_DecodeCookie(&cookie, &context2));
}
unlink("ntskeys");

View File

@@ -32,27 +32,29 @@
#define NKC_Start(inst) (random() % 2)
#define NKC_IsActive(inst) (random() % 2)
static int get_nts_data(NKC_Instance inst, SIV_Algorithm *siv_algorithm, NKE_Key *c2s, NKE_Key *s2c,
NKE_Cookie *cookies, int *num_cookies, int max_cookies, IPSockAddr *ntp_address);
static int get_nts_data(NKC_Instance inst, NKE_Context *context,
NKE_Cookie *cookies, int *num_cookies, int max_cookies,
IPSockAddr *ntp_address);
#define NKC_GetNtsData get_nts_data
#include <nts_ntp_client.c>
static int
get_nts_data(NKC_Instance inst, SIV_Algorithm *siv_algorithm, NKE_Key *c2s, NKE_Key *s2c,
NKE_Cookie *cookies, int *num_cookies, int max_cookies, IPSockAddr *ntp_address)
get_nts_data(NKC_Instance inst, NKE_Context *context,
NKE_Cookie *cookies, int *num_cookies, int max_cookies,
IPSockAddr *ntp_address)
{
int i;
if (random() % 2)
return 0;
*siv_algorithm = AEAD_AES_SIV_CMAC_256;
context->algorithm = AEAD_AES_SIV_CMAC_256;
c2s->length = SIV_GetKeyLength(*siv_algorithm);
UTI_GetRandomBytes(c2s->key, c2s->length);
s2c->length = SIV_GetKeyLength(*siv_algorithm);
UTI_GetRandomBytes(s2c->key, s2c->length);
context->c2s.length = SIV_GetKeyLength(context->algorithm);
UTI_GetRandomBytes(context->c2s.key, context->c2s.length);
context->s2c.length = SIV_GetKeyLength(context->algorithm);
UTI_GetRandomBytes(context->s2c.key, context->s2c.length);
*num_cookies = random() % max_cookies + 1;
for (i = 0; i < *num_cookies; i++) {
@@ -89,8 +91,7 @@ get_request(NNC_Instance inst)
}
TEST_CHECK(inst->num_cookies > 0);
TEST_CHECK(inst->siv_c2s);
TEST_CHECK(inst->siv_s2c);
TEST_CHECK(inst->siv);
memcpy(nonce, inst->nonce, sizeof (nonce));
memcpy(uniq_id, inst->uniq_id, sizeof (uniq_id));
@@ -103,7 +104,7 @@ get_request(NNC_Instance inst)
(inst->cookies[inst->cookie_index].length + 4));
expected_length = info.length + 4 + sizeof (inst->uniq_id) +
req_cookies * (4 + inst->cookies[inst->cookie_index].length) +
4 + 4 + sizeof (inst->nonce) + SIV_GetTagLength(inst->siv_c2s);
4 + 4 + sizeof (inst->nonce) + SIV_GetTagLength(inst->siv);
DEBUG_LOG("length=%d cookie_length=%d expected_length=%d",
info.length, inst->cookies[inst->cookie_index].length, expected_length);
@@ -126,6 +127,7 @@ prepare_response(NNC_Instance inst, NTP_Packet *packet, NTP_PacketInfo *info, in
unsigned char cookie[508], plaintext[512], nonce[512];
int nonce_length, cookie_length, plaintext_length, min_auth_length;
int index, auth_start;
SIV_Instance siv;
memset(packet, 0, sizeof (*packet));
packet->lvm = NTP_LVM(0, 4, MODE_SERVER);
@@ -175,10 +177,15 @@ prepare_response(NNC_Instance inst, NTP_Packet *packet, NTP_PacketInfo *info, in
TEST_CHECK(NEF_SetField(plaintext, sizeof (plaintext), 0, NTP_EF_NTS_COOKIE,
cookie, cookie_length, &plaintext_length));
auth_start = info->length;
if (index != 4)
TEST_CHECK(NNA_GenerateAuthEF(packet, info, inst->siv_s2c,
if (index != 4) {
siv = SIV_CreateInstance(inst->context.algorithm);
TEST_CHECK(siv);
TEST_CHECK(SIV_SetKey(siv, inst->context.s2c.key, inst->context.s2c.length));
TEST_CHECK(NNA_GenerateAuthEF(packet, info, siv,
nonce, nonce_length, plaintext, plaintext_length,
min_auth_length));
SIV_DestroyInstance(siv);
}
if (index == 5)
((unsigned char *)packet)[auth_start + 8]++;
}

View File

@@ -32,17 +32,18 @@ static void
prepare_request(NTP_Packet *packet, NTP_PacketInfo *info, int valid, int nak)
{
unsigned char uniq_id[NTS_MIN_UNIQ_ID_LENGTH], nonce[NTS_MIN_UNPADDED_NONCE_LENGTH];
NKE_Key c2s, s2c;
SIV_Instance siv;
NKE_Context context;
NKE_Cookie cookie;
int i, index, cookie_start, auth_start;
c2s.length = SIV_GetKeyLength(AEAD_AES_SIV_CMAC_256);
UTI_GetRandomBytes(&c2s.key, c2s.length);
s2c.length = SIV_GetKeyLength(AEAD_AES_SIV_CMAC_256);
UTI_GetRandomBytes(&s2c.key, s2c.length);
context.algorithm = SERVER_SIV;
context.c2s.length = SIV_GetKeyLength(context.algorithm);
UTI_GetRandomBytes(&context.c2s.key, context.c2s.length);
context.s2c.length = SIV_GetKeyLength(context.algorithm);
UTI_GetRandomBytes(&context.s2c.key, context.s2c.length);
TEST_CHECK(NKS_GenerateCookie(&c2s, &s2c, &cookie));
TEST_CHECK(NKS_GenerateCookie(&context, &cookie));
UTI_GetRandomBytes(uniq_id, sizeof (uniq_id));
UTI_GetRandomBytes(nonce, sizeof (nonce));
@@ -78,8 +79,8 @@ prepare_request(NTP_Packet *packet, NTP_PacketInfo *info, int valid, int nak)
auth_start = info->length;
if (index != 2) {
siv = SIV_CreateInstance(AEAD_AES_SIV_CMAC_256);
TEST_CHECK(SIV_SetKey(siv, c2s.key, c2s.length));
siv = SIV_CreateInstance(context.algorithm);
TEST_CHECK(SIV_SetKey(siv, context.c2s.key, context.c2s.length));
TEST_CHECK(NNA_GenerateAuthEF(packet, info, siv, nonce, sizeof (nonce),
(const unsigned char *)"", 0, 0));
SIV_DestroyInstance(siv);