From 06c634bd848ded832210ed57d262b2d07c5ed87d Mon Sep 17 00:00:00 2001 From: Ian Bruene <ianbruene@gmail.com> Date: Tue, 25 Jun 2019 05:08:21 +0000 Subject: [PATCH] Fixed nts tests. nts.c test errors fixed. Initial nts_client.c test works. nts.c tests flipped to have expected / got values in the proper places. --- ntpd/nts_client.c | 48 ++-- ntpd/nts_extens.c | 260 ++++++++++---------- ntpd/nts_server.c | 4 +- tests/common/tests_main.c | 5 + tests/ntpd/nts.c | 484 +++++++++++++++++++------------------- tests/ntpd/nts_client.c | 269 +++++++++++++++++++++ tests/ntpd/nts_cookie.c | 82 +++++++ tests/ntpd/nts_extens.c | 231 ++++++++++++++++++ tests/ntpd/nts_server.c | 107 +++++++++ tests/wscript | 8 +- 10 files changed, 1117 insertions(+), 381 deletions(-) create mode 100644 tests/ntpd/nts_client.c create mode 100644 tests/ntpd/nts_cookie.c create mode 100644 tests/ntpd/nts_extens.c create mode 100644 tests/ntpd/nts_server.c diff --git a/ntpd/nts_client.c b/ntpd/nts_client.c index 96ed174197..5788e9b601 100644 --- a/ntpd/nts_client.c +++ b/ntpd/nts_client.c @@ -36,6 +36,8 @@ void set_hostname(SSL *ssl, const char *hostname); bool check_certificate(SSL *ssl, struct peer *peer); bool nts_client_send_request(SSL *ssl, struct peer *peer); bool nts_client_process_response(SSL *ssl, struct peer *peer); +bool nts_client_process_response_core(uint8_t *buff, int transferred, struct peer* peer); +bool nts_client_send_request_core(uint8_t *buff, int buf_size, int *used, struct peer* peer); bool nts_server_lookup(char *server, sockaddr_u *addr); static SSL_CTX *client_ctx = NULL; @@ -407,13 +409,28 @@ bool nts_make_keys(SSL *ssl, uint16_t aead, uint8_t *c2s, uint8_t *s2c, int keyl bool nts_client_send_request(SSL *ssl, struct peer* peer) { uint8_t buff[1000]; - char errbuf[100]; int used, transferred; + bool success; + + success = nts_client_send_request_core(buff, sizeof(buff), &used, peer); + if (!success) { + return false; + } + + transferred = nts_ssl_write(ssl, buff, used); + if (used != transferred) + return false; + + return true; +} + +bool nts_client_send_request_core(uint8_t *buff, int buf_size, int *used, struct peer* peer) { + char errbuf[100]; struct BufCtl_t buf; uint16_t aead = NO_AEAD; buf.next = buff; - buf.left = sizeof(buff); + buf.left = buf_size; /* 4.1.2 Next Protocol, 0 for NTP */ ke_append_record_uint16(&buf, @@ -433,31 +450,32 @@ bool nts_client_send_request(SSL *ssl, struct peer* peer) { /* 4.1.1: End, Critical */ ke_append_record_null(&buf, NTS_CRITICAL+nts_end_of_message); - used = sizeof(buff)-buf.left; - if (used >= (int)(sizeof(buff)-10)) { + *used = buf_size-buf.left; + if (*used >= (int)(buf_size - 10)) { IGNORE(strerror_r(errno, errbuf, sizeof(errbuf))); msyslog(LOG_ERR, "NTSc: write failed: %d, %ld, %s", - used, (long)sizeof(buff), errbuf); + *used, (long)buf_size, errbuf); return false; } - - transferred = nts_ssl_write(ssl, buff, used); - if (used != transferred) - return false; - return true; } bool nts_client_process_response(SSL *ssl, struct peer* peer) { uint8_t buff[2048]; /* RFC 4. says SHOULD be 65K */ - int transferred, idx; - struct BufCtl_t buf; + int transferred; transferred = nts_ssl_read(ssl, buff, sizeof(buff)); if (0 > transferred) return false; msyslog(LOG_ERR, "NTSc: read %d bytes", transferred); + return nts_client_process_response_core(buff, transferred, peer); +} + +bool nts_client_process_response_core(uint8_t *buff, int transferred, struct peer* peer) { + int idx; + struct BufCtl_t buf; + peer->nts_state.aead = NO_AEAD; peer->nts_state.keylen = 0; peer->nts_state.writeIdx = 0; @@ -505,7 +523,7 @@ bool nts_client_process_response(SSL *ssl, struct peer* peer) { keylength = nts_get_key_length(data); if (0 == keylength) { msyslog(LOG_ERR, "NTSc: AN-Unsupported AEAN type: %d", data); - return false; + return false; } peer->nts_state.aead = data; break; @@ -569,7 +587,9 @@ bool nts_client_process_response(SSL *ssl, struct peer* peer) { default: msyslog(LOG_ERR, "NTSc: received strange type: T=%d, C=%d, L=%d", type, critical, length); - if (critical) return false; + if (critical) { + return false; + } buf.next += length; buf.left -= length; break; diff --git a/ntpd/nts_extens.c b/ntpd/nts_extens.c index 1c6836c5dd..377977ceaf 100644 --- a/ntpd/nts_extens.c +++ b/ntpd/nts_extens.c @@ -148,88 +148,100 @@ bool extens_server_recv(struct ntspacket_t *ntspacket, uint8_t *pkt, int lng) { bool ok; type = ex_next_record(&buf, &length); /* length excludes header */ - if (length&3 || length > buf.left || length < 0) + if (length&3 || length > buf.left || length < 0) { return false; + } if (NTS_CRITICAL & type) { critical = true; type &= ~NTS_CRITICAL; } switch (type) { - case Unique_Identifier: - if (length > NTS_UID_MAX_LENGTH) - return false; - ntspacket->uidlen = length; - next_bytes(&buf, ntspacket->UID, length); - break; - case NTS_Cookie: - if (sawcookie) - return false; /* second cookie */ - ok = nts_unpack_cookie(buf.next, length, - &aead, - ntspacket->c2s, ntspacket->s2c, &ntspacket->keylen); - if (!ok) - return false; - buf.next += length; - buf.left -= length; - sawcookie = true; - ntspacket->needed++; - ntspacket->aead = aead; - break; - case NTS_Cookie_Placeholder: - /* doesn't check length */ - ntspacket->needed++; - buf.next += length; - buf.left -= length; - break; - case NTS_AEEF: - if (!sawcookie) - return false; /* no cookie yet, no c2s */ - if (length != NTP_EX_HDR_LNG+NONCE_LENGTH+CMAC_LENGTH) - return false; - /* Additional data is up to this exten. */ - /* backup over header */ - adlength = buf.next-NTP_EX_HDR_LNG-pkt; - noncelen = next_uint16(&buf); - cmaclen = next_uint16(&buf); - if (noncelen & 3) - return false; /* would require padding */ - if (CMAC_LENGTH != cmaclen) - return false; - nonce = buf.next; - cmac = nonce+NONCE_LENGTH; - outlen = 6; - ok = AES_SIV_Decrypt(wire_ctx, - NULL, &outlen, - ntspacket->c2s, ntspacket->keylen, - nonce, noncelen, - cmac, CMAC_LENGTH, - pkt, adlength); - if (!ok) - return false; - if (0 != outlen) - return false; - /* we already used 2 length slots way above*/ - length -= (NTP_EX_U16_LNG+NTP_EX_U16_LNG); - buf.next += length; - buf.left -= length; - if (0 != buf.left) - return false; /* Reject extens after AEEF block */ - sawAEEF = true; - break; - default: - /* Non NTS extensions on requests at server. - * Call out when we get some that we want. - * Until then, it's probably a bug. */ - if (critical) - return false; - buf.next += length; - buf.left -= length; + case Unique_Identifier: + if (length > NTS_UID_MAX_LENGTH) { + return false; + } + ntspacket->uidlen = length; + next_bytes(&buf, ntspacket->UID, length); + break; + case NTS_Cookie: + if (sawcookie) { + return false; /* second cookie */ + } + ok = nts_unpack_cookie(buf.next, length, &aead, ntspacket->c2s, + ntspacket->s2c, &ntspacket->keylen); + if (!ok) { + return false; + } + buf.next += length; + buf.left -= length; + sawcookie = true; + ntspacket->needed++; + ntspacket->aead = aead; + break; + case NTS_Cookie_Placeholder: + /* doesn't check length */ + ntspacket->needed++; + buf.next += length; + buf.left -= length; + break; + case NTS_AEEF: + if (!sawcookie) { + return false; /* no cookie yet, no c2s */ + } + if (length != NTP_EX_HDR_LNG+NONCE_LENGTH+CMAC_LENGTH) { + return false; + } + /* Additional data is up to this exten. */ + /* backup over header */ + adlength = buf.next-NTP_EX_HDR_LNG-pkt; + noncelen = next_uint16(&buf); + cmaclen = next_uint16(&buf); + if (noncelen & 3) { + return false; /* would require padding */ + } + if (CMAC_LENGTH != cmaclen) { + return false; + } + nonce = buf.next; + cmac = nonce+NONCE_LENGTH; + outlen = 6; + ok = AES_SIV_Decrypt(wire_ctx, + NULL, &outlen, + ntspacket->c2s, ntspacket->keylen, + nonce, noncelen, + cmac, CMAC_LENGTH, + pkt, adlength); + if (!ok) { + return false; + } + if (0 != outlen) { + return false; + } + /* we already used 2 length slots way above*/ + length -= (NTP_EX_U16_LNG+NTP_EX_U16_LNG); + buf.next += length; + buf.left -= length; + if (0 != buf.left) { + return false; /* Reject extens after AEEF block */ + } + sawAEEF = true; + break; + default: + /* Non NTS extensions on requests at server. + * Call out when we get some that we want. + * Until then, it's probably a bug. */ + if (critical) { return false; + } + buf.next += length; + buf.left -= length; + return false; } } - if (!sawAEEF) + if (!sawAEEF) { return false; + } // printf("ESRx: %d, %d, %d\n", // lng-LEN_PKT_NOMAC, ntspacket->needed, ntspacket->keylen); ntspacket->valid = true; @@ -349,62 +361,62 @@ bool extens_client_recv(struct peer *peer, uint8_t *pkt, int lng) { } // printf("ECR: %d, %d, %d\n", type, length, buf.left); switch (type) { - case Unique_Identifier: - if (NTS_UID_LENGTH != length) - return false; - if (0 != memcmp(buf.next, peer->nts_state.UID, NTS_UID_LENGTH)) - return false; - buf.next += length; - buf.left -= length; - break; - case NTS_Cookie: - if (!sawAEEF) - return false; /* reject unencrypted cookies */ - if (NTS_MAX_COOKIES <= peer->nts_state.count) - return false; /* reject extra cookies */ - if (length != peer->nts_state.cookielen) - return false; /* reject length change */ - idx = peer->nts_state.writeIdx++; - memcpy((uint8_t*)&peer->nts_state.cookies[idx], buf.next, length); - peer->nts_state.writeIdx = peer->nts_state.writeIdx % NTS_MAX_COOKIES; - peer->nts_state.count++; - buf.next += length; - buf.left -= length; - break; - case NTS_AEEF: - adlength = buf.next-NTP_EX_HDR_LNG-pkt; /* backup over header */ - noncelen = next_uint16(&buf); - outlen = next_uint16(&buf); - if (noncelen&3 || outlen&3) - return false; /* else round up */ - nonce = buf.next; - ciphertext = nonce+noncelen; - plaintext = ciphertext+CMAC_LENGTH; - outlen = buf.left-NONCE_LENGTH-CMAC_LENGTH; + case Unique_Identifier: + if (NTS_UID_LENGTH != length) + return false; + if (0 != memcmp(buf.next, peer->nts_state.UID, NTS_UID_LENGTH)) + return false; + buf.next += length; + buf.left -= length; + break; + case NTS_Cookie: + if (!sawAEEF) + return false; /* reject unencrypted cookies */ + if (NTS_MAX_COOKIES <= peer->nts_state.count) + return false; /* reject extra cookies */ + if (length != peer->nts_state.cookielen) + return false; /* reject length change */ + idx = peer->nts_state.writeIdx++; + memcpy((uint8_t*)&peer->nts_state.cookies[idx], buf.next, length); + peer->nts_state.writeIdx = peer->nts_state.writeIdx % NTS_MAX_COOKIES; + peer->nts_state.count++; + buf.next += length; + buf.left -= length; + break; + case NTS_AEEF: + adlength = buf.next-NTP_EX_HDR_LNG-pkt; /* backup over header */ + noncelen = next_uint16(&buf); + outlen = next_uint16(&buf); + if (noncelen&3 || outlen&3) + return false; /* else round up */ + nonce = buf.next; + ciphertext = nonce+noncelen; + plaintext = ciphertext+CMAC_LENGTH; + outlen = buf.left-NONCE_LENGTH-CMAC_LENGTH; // printf("ECRa: %lu, %d\n", (long unsigned)outlen, noncelen); - ok = AES_SIV_Decrypt(wire_ctx, - plaintext, &outlen, - peer->nts_state.s2c, peer->nts_state.keylen, - nonce, noncelen, - ciphertext, outlen+CMAC_LENGTH, - pkt, adlength); + ok = AES_SIV_Decrypt(wire_ctx, + plaintext, &outlen, + peer->nts_state.s2c, peer->nts_state.keylen, + nonce, noncelen, + ciphertext, outlen+CMAC_LENGTH, + pkt, adlength); // printf("ECRb: %d, %lu\n", ok, (long unsigned)outlen); - if (!ok) - return false; - /* setup to process encrypted headers */ - buf.next += NONCE_LENGTH+CMAC_LENGTH; - buf.left -= NONCE_LENGTH+CMAC_LENGTH; - sawAEEF = true; - break; - default: - /* Non NTS extensions on reply from server. - * Call out when we get some that we want. - * For now, it's probably a bug. */ - if (critical) - return false; - buf.next += length; - buf.left -= length; + if (!ok) + return false; + /* setup to process encrypted headers */ + buf.next += NONCE_LENGTH+CMAC_LENGTH; + buf.left -= NONCE_LENGTH+CMAC_LENGTH; + sawAEEF = true; + break; + default: + /* Non NTS extensions on reply from server. + * Call out when we get some that we want. + * For now, it's probably a bug. */ + if (critical) return false; + buf.next += length; + buf.left -= length; + return false; } } diff --git a/ntpd/nts_server.c b/ntpd/nts_server.c index 6098b1e219..0e40e5ef82 100644 --- a/ntpd/nts_server.c +++ b/ntpd/nts_server.c @@ -402,7 +402,9 @@ bool nts_ke_process_receive(struct BufCtl_t *buf, int *aead) { default: msyslog(LOG_ERR, "NTSs: received strange type: T=%d, C=%d, L=%d", type, critical, length); - if (critical) return false; + if (critical) { + return false; + } buf->next += length; buf->left -= length; break; diff --git a/tests/common/tests_main.c b/tests/common/tests_main.c index 050e8d712b..759dcb30d3 100644 --- a/tests/common/tests_main.c +++ b/tests/common/tests_main.c @@ -72,6 +72,11 @@ static void RunAllTests(void) RUN_TEST_GROUP(leapsec); RUN_TEST_GROUP(hackrestrict); RUN_TEST_GROUP(recvbuff); + RUN_TEST_GROUP(nts); + RUN_TEST_GROUP(nts_client); + RUN_TEST_GROUP(nts_server); + RUN_TEST_GROUP(nts_cookie); + RUN_TEST_GROUP(nts_extens); #endif } diff --git a/tests/ntpd/nts.c b/tests/ntpd/nts.c index 6e6bf137eb..1c05602415 100644 --- a/tests/ntpd/nts.c +++ b/tests/ntpd/nts.c @@ -15,390 +15,394 @@ TEST_SETUP(nts) {} TEST_TEAR_DOWN(nts) {} TEST(nts, nts_translate_version) { - TEST_ASSERT_EQUAL_INT32(nts_translate_version(NULL), 0); - TEST_ASSERT_EQUAL_INT32(nts_translate_version("TLS1.2"), TLS1_2_VERSION); + TEST_ASSERT_EQUAL_INT32(0, nts_translate_version(NULL)); + TEST_ASSERT_EQUAL_INT32(TLS1_2_VERSION, nts_translate_version("TLS1.2")); #ifdef TLS1_3_VERSION - TEST_ASSERT_EQUAL_INT32(nts_translate_version("TLS1.3"), TLS1_3_VERSION); + TEST_ASSERT_EQUAL_INT32(TLS1_3_VERSION, nts_translate_version("TLS1.3")); #else - TEST_ASSERT_EQUAL_INT32(nts_translate_version("TLS1.3"), -1); + TEST_ASSERT_EQUAL_INT32(-1, nts_translate_version("TLS1.3")); #endif - TEST_ASSERT_EQUAL_INT32(nts_translate_version("blah"), -1); + TEST_ASSERT_EQUAL_INT32(-1, nts_translate_version("blah")); } TEST(nts, nts_string_to_aead) { - TEST_ASSERT_EQUAL_INT16(nts_string_to_aead("AEAD_AES_SIV_CMAC_256"), - AEAD_AES_SIV_CMAC_256); - TEST_ASSERT_EQUAL_INT16(nts_string_to_aead("AEAD_AES_SIV_CMAC_384"), - AEAD_AES_SIV_CMAC_384); - TEST_ASSERT_EQUAL_INT16(nts_string_to_aead("AEAD_AES_SIV_CMAC_512"), - AEAD_AES_SIV_CMAC_512); - TEST_ASSERT_EQUAL_INT16(nts_string_to_aead("blah"), NO_AEAD); + TEST_ASSERT_EQUAL_INT16(AEAD_AES_SIV_CMAC_256, + nts_string_to_aead("AES_SIV_CMAC_256")); + TEST_ASSERT_EQUAL_INT16(AEAD_AES_SIV_CMAC_384, + nts_string_to_aead("AES_SIV_CMAC_384")); + TEST_ASSERT_EQUAL_INT16(AEAD_AES_SIV_CMAC_512, + nts_string_to_aead("AES_SIV_CMAC_512")); + TEST_ASSERT_EQUAL_INT16(NO_AEAD, nts_string_to_aead("blah")); } TEST(nts, nts_get_key_length) { - TEST_ASSERT_EQUAL_INT32(nts_get_key_length(AEAD_AES_SIV_CMAC_256), - AEAD_AES_SIV_CMAC_256_KEYLEN); - TEST_ASSERT_EQUAL_INT32(nts_get_key_length(AEAD_AES_SIV_CMAC_384), - AEAD_AES_SIV_CMAC_384_KEYLEN); - TEST_ASSERT_EQUAL_INT32(nts_get_key_length(AEAD_AES_SIV_CMAC_512), - AEAD_AES_SIV_CMAC_512_KEYLEN); - TEST_ASSERT_EQUAL_INT32(nts_get_key_length(-23), 0); + TEST_ASSERT_EQUAL_INT32(AEAD_AES_SIV_CMAC_256_KEYLEN, + nts_get_key_length(AEAD_AES_SIV_CMAC_256)); + TEST_ASSERT_EQUAL_INT32(AEAD_AES_SIV_CMAC_384_KEYLEN, + nts_get_key_length(AEAD_AES_SIV_CMAC_384)); + TEST_ASSERT_EQUAL_INT32(AEAD_AES_SIV_CMAC_512_KEYLEN, + nts_get_key_length(AEAD_AES_SIV_CMAC_512)); + TEST_ASSERT_EQUAL_INT32(0, nts_get_key_length(-23)); } TEST(nts, ke_append_record_null) { - // Setup + /* Setup */ uint8_t buf[128]; BufCtl cursor; cursor.next = buf; cursor.left = 128; - // Run test + /* Run test */ ke_append_record_null(&cursor, 0xFA7E); - // Check - TEST_ASSERT_EQUAL_UINT8(buf[0], 0xFA); - TEST_ASSERT_EQUAL_UINT8(buf[1], 0x7E); - TEST_ASSERT_EQUAL_UINT8(buf[2], 0); - TEST_ASSERT_EQUAL_UINT8(buf[3], 0); - TEST_ASSERT_POINTERS_EQUAL(cursor.next, &buf[4]); - TEST_ASSERT_EQUAL_INT(cursor.left, 124); + /* Check */ + TEST_ASSERT_EQUAL_UINT8(0xFA, buf[0]); + TEST_ASSERT_EQUAL_UINT8(0x7E, buf[1]); + TEST_ASSERT_EQUAL_UINT8(0, buf[2]); + TEST_ASSERT_EQUAL_UINT8(0, buf[3]); + TEST_ASSERT_POINTERS_EQUAL(&buf[4], cursor.next); + TEST_ASSERT_EQUAL_INT(124, cursor.left); } TEST(nts, ke_append_record_uint16) { - // Test change - // Setup + /* Test change */ + /* Setup */ uint8_t buf[16] = {0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0}; + 0, 0, 0, 0, 0, 0, 0, 0}; BufCtl cursor; cursor.next = buf; cursor.left = 16; - // Run test + /* Run test */ ke_append_record_uint16(&cursor, 0xCAFE, 0x1234); - // Check - TEST_ASSERT_EQUAL_UINT8(buf[0], 0xCA); - TEST_ASSERT_EQUAL_UINT8(buf[1], 0xFE); - TEST_ASSERT_EQUAL_UINT8(buf[2], 0x12); - TEST_ASSERT_EQUAL_UINT8(buf[3], 0x34); - TEST_ASSERT_POINTERS_EQUAL(cursor.next, &buf[4]); - TEST_ASSERT_EQUAL_INT(cursor.left, 12); - // Test no change - // Setup + /* Check */ + TEST_ASSERT_EQUAL_UINT8(0xCA, buf[0]); + TEST_ASSERT_EQUAL_UINT8(0xFE, buf[1]); + TEST_ASSERT_EQUAL_UINT8(0x00, buf[2]); + TEST_ASSERT_EQUAL_UINT8(0x02, buf[3]); + TEST_ASSERT_EQUAL_UINT8(0x12, buf[4]); + TEST_ASSERT_EQUAL_UINT8(0x34, buf[5]); + TEST_ASSERT_POINTERS_EQUAL(&buf[6], cursor.next); + TEST_ASSERT_EQUAL_INT(10, cursor.left); + /* Test no change */ + /* Setup */ cursor.left = 0; - // Run test + /* Run test */ ke_append_record_uint16(&cursor, 0xCAFE, 0x1234); - // Check - TEST_ASSERT_EQUAL_UINT8(buf[4], 0); - TEST_ASSERT_POINTERS_EQUAL(cursor.next, &buf[4]); - TEST_ASSERT_EQUAL_INT(cursor.left, 0); + /* Check */ + TEST_ASSERT_EQUAL_UINT8(0, buf[6]); + TEST_ASSERT_POINTERS_EQUAL(&buf[6], cursor.next); + TEST_ASSERT_EQUAL_INT(0, cursor.left); } TEST(nts, ke_append_record_bytes) { - // Test change - // Setup + /* Test change */ + /* Setup */ uint8_t buf[16] = {0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0}; + 0, 0, 0, 0, 0, 0, 0, 0}; BufCtl cursor; cursor.next = buf; cursor.left = 16; uint8_t data[6] = {0, 1, 2, 3, 4, 5}; - // Run test + /* Run test */ ke_append_record_bytes(&cursor, 0xCAFE, data, 6); - // Check - TEST_ASSERT_EQUAL_UINT8(buf[0], 0xCA); - TEST_ASSERT_EQUAL_UINT8(buf[1], 0xFE); - TEST_ASSERT_EQUAL_UINT8(buf[2], 0); - TEST_ASSERT_EQUAL_UINT8(buf[3], 1); - TEST_ASSERT_EQUAL_UINT8(buf[4], 2); - TEST_ASSERT_EQUAL_UINT8(buf[5], 3); - TEST_ASSERT_EQUAL_UINT8(buf[6], 4); - TEST_ASSERT_EQUAL_UINT8(buf[7], 5); - TEST_ASSERT_POINTERS_EQUAL(cursor.next, &buf[8]); - TEST_ASSERT_EQUAL_INT(cursor.left, 8); - // Test no change - // Setup + /* Check */ + TEST_ASSERT_EQUAL_UINT8(0xCA, buf[0]); + TEST_ASSERT_EQUAL_UINT8(0xFE, buf[1]); + TEST_ASSERT_EQUAL_UINT8(0x00, buf[2]); + TEST_ASSERT_EQUAL_UINT8(0x06, buf[3]); + TEST_ASSERT_EQUAL_UINT8(0, buf[4]); + TEST_ASSERT_EQUAL_UINT8(1, buf[5]); + TEST_ASSERT_EQUAL_UINT8(2, buf[6]); + TEST_ASSERT_EQUAL_UINT8(3, buf[7]); + TEST_ASSERT_EQUAL_UINT8(4, buf[8]); + TEST_ASSERT_EQUAL_UINT8(5, buf[9]); + TEST_ASSERT_POINTERS_EQUAL(&buf[10], cursor.next); + TEST_ASSERT_EQUAL_INT(6, cursor.left); + /* Test no change */ + /* Setup */ cursor.left = 0; - // Run test + /* Run test */ ke_append_record_bytes(&cursor, 0xCAFE, data, 6); - // Check - TEST_ASSERT_EQUAL_UINT8(buf[8], 0); - TEST_ASSERT_POINTERS_EQUAL(cursor.next, &buf[8]); - TEST_ASSERT_EQUAL_INT(cursor.left, 0); + /* Check */ + TEST_ASSERT_EQUAL_UINT8(0, buf[10]); + TEST_ASSERT_POINTERS_EQUAL(&buf[10], cursor.next); + TEST_ASSERT_EQUAL_INT(0, cursor.left); } TEST(nts, ex_append_record_null) { - // Setup - uint8_t buf[16]; + /* Setup */ + uint8_t buf[16] = {0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0}; BufCtl cursor; cursor.next = buf; cursor.left = 16; - // Run test + /* Run test */ ex_append_record_null(&cursor, 0xFADE); - // Check - TEST_ASSERT_EQUAL_UINT8(buf[0], 0xFA); - TEST_ASSERT_EQUAL_UINT8(buf[1], 0xDE); - TEST_ASSERT_EQUAL_UINT8(buf[2], 0); - TEST_ASSERT_POINTERS_EQUAL(cursor.next, &buf[2]); - TEST_ASSERT_EQUAL_INT(cursor.left, 14); + /* Check */ + TEST_ASSERT_EQUAL_UINT8(0xFA, buf[0]); + TEST_ASSERT_EQUAL_UINT8(0xDE, buf[1]); + TEST_ASSERT_EQUAL_UINT8(0, buf[2]); + TEST_ASSERT_EQUAL_UINT8(4, buf[3]); + TEST_ASSERT_EQUAL_UINT8(0, buf[4]); + TEST_ASSERT_POINTERS_EQUAL(&buf[4], cursor.next); + TEST_ASSERT_EQUAL_INT(12, cursor.left); } TEST(nts, ex_append_record_uint16) { - // Setup - uint8_t buf[16]; + /* Setup */ + uint8_t buf[16] = {0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0}; BufCtl cursor; cursor.next = buf; cursor.left = 16; - // Run test + /* Run test */ ex_append_record_uint16(&cursor, 0xFADE, 0x1234); - // Check - TEST_ASSERT_EQUAL_UINT8(buf[0], 0xFA); - TEST_ASSERT_EQUAL_UINT8(buf[1], 0xDE); - TEST_ASSERT_EQUAL_UINT8(buf[2], 0x12); - TEST_ASSERT_EQUAL_UINT8(buf[3], 0x34); - TEST_ASSERT_EQUAL_UINT8(buf[4], 0); - TEST_ASSERT_POINTERS_EQUAL(cursor.next, &buf[4]); - TEST_ASSERT_EQUAL_INT(cursor.left, 12); - // Test no change - // Setup + /* Check */ + TEST_ASSERT_EQUAL_UINT8(0xFA, buf[0]); + TEST_ASSERT_EQUAL_UINT8(0xDE, buf[1]); + TEST_ASSERT_EQUAL_UINT8(0x00, buf[2]); + TEST_ASSERT_EQUAL_UINT8(0x06, buf[3]); + TEST_ASSERT_EQUAL_UINT8(0x12, buf[4]); + TEST_ASSERT_EQUAL_UINT8(0x34, buf[5]); + TEST_ASSERT_EQUAL_UINT8(0, buf[6]); + TEST_ASSERT_POINTERS_EQUAL(&buf[6], cursor.next); + TEST_ASSERT_EQUAL_INT(10, cursor.left); + /* Test no change */ + /* Setup */ cursor.left = 0; - // Run test + /* Run test */ ke_append_record_uint16(&cursor, 0xCAFE, 0x1234); - // Check - TEST_ASSERT_EQUAL_UINT8(buf[4], 0); - TEST_ASSERT_POINTERS_EQUAL(cursor.next, &buf[4]); - TEST_ASSERT_EQUAL_INT(cursor.left, 0); + /* Check */ + TEST_ASSERT_EQUAL_UINT8(0, buf[6]); + TEST_ASSERT_POINTERS_EQUAL(&buf[6], cursor.next); + TEST_ASSERT_EQUAL_INT(0, cursor.left); } TEST(nts, ex_append_record_bytes) { - // Test change - // Setup + /* Test change */ + /* Setup */ uint8_t buf[16] = {0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0}; + 0, 0, 0, 0, 0, 0, 0, 0}; BufCtl cursor; cursor.next = buf; cursor.left = 16; uint8_t data[6] = {0, 1, 2, 3, 4, 5}; - // Run test + /* Run test */ ex_append_record_bytes(&cursor, 0xCAFE, data, 6); - // Check - TEST_ASSERT_EQUAL_UINT8(buf[0], 0xCA); - TEST_ASSERT_EQUAL_UINT8(buf[1], 0xFE); - TEST_ASSERT_EQUAL_UINT8(buf[2], 0); - TEST_ASSERT_EQUAL_UINT8(buf[3], 1); - TEST_ASSERT_EQUAL_UINT8(buf[4], 2); - TEST_ASSERT_EQUAL_UINT8(buf[5], 3); - TEST_ASSERT_EQUAL_UINT8(buf[6], 4); - TEST_ASSERT_EQUAL_UINT8(buf[7], 5); - TEST_ASSERT_POINTERS_EQUAL(cursor.next, &buf[8]); - TEST_ASSERT_EQUAL_INT(cursor.left, 8); - // Test no change - // Setup + /* Check */ + TEST_ASSERT_EQUAL_UINT8(0xCA, buf[0]); + TEST_ASSERT_EQUAL_UINT8(0xFE, buf[1]); + TEST_ASSERT_EQUAL_UINT8(0x00, buf[2]); + TEST_ASSERT_EQUAL_UINT8(0x0A, buf[3]); + TEST_ASSERT_EQUAL_UINT8(0, buf[4]); + TEST_ASSERT_EQUAL_UINT8(1, buf[5]); + TEST_ASSERT_EQUAL_UINT8(2, buf[6]); + TEST_ASSERT_EQUAL_UINT8(3, buf[7]); + TEST_ASSERT_EQUAL_UINT8(4, buf[8]); + TEST_ASSERT_EQUAL_UINT8(5, buf[9]); + TEST_ASSERT_POINTERS_EQUAL(&buf[10], cursor.next); + TEST_ASSERT_EQUAL_INT(6, cursor.left); + /* Test no change */ + /* Setup */ cursor.left = 0; - // Run test + /* Run test */ ex_append_record_bytes(&cursor, 0xCAFE, data, 6); - // Check - TEST_ASSERT_EQUAL_UINT8(buf[8], 0); - TEST_ASSERT_POINTERS_EQUAL(cursor.next, &buf[8]); - TEST_ASSERT_EQUAL_INT(cursor.left, 0); + /* Check */ + TEST_ASSERT_EQUAL_UINT8(0, buf[10]); + TEST_ASSERT_POINTERS_EQUAL(&buf[10], cursor.next); + TEST_ASSERT_EQUAL_INT(0, cursor.left); } TEST(nts, ex_append_header) { - // Test change - // Setup - uint8_t buf[16]; + /* Test change */ + /* Setup */ + uint8_t buf[16] = {0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0}; BufCtl cursor; cursor.next = buf; cursor.left = 16; - // Run test + /* Run test */ ex_append_header(&cursor, 0xFADE, 0x1234); - // Check - TEST_ASSERT_EQUAL_UINT8(buf[0], 0xFA); - TEST_ASSERT_EQUAL_UINT8(buf[1], 0xDE); - TEST_ASSERT_EQUAL_UINT8(buf[2], 0x12); - TEST_ASSERT_EQUAL_UINT8(buf[3], 0x34); - TEST_ASSERT_EQUAL_UINT8(buf[4], 0); - TEST_ASSERT_POINTERS_EQUAL(cursor.next, &buf[4]); - TEST_ASSERT_EQUAL_INT(cursor.left, 12); - // Test no change - // Setup + /* Check */ + TEST_ASSERT_EQUAL_UINT8(0xFA, buf[0]); + TEST_ASSERT_EQUAL_UINT8(0xDE, buf[1]); + TEST_ASSERT_EQUAL_UINT8(0x12, buf[2]); + TEST_ASSERT_EQUAL_UINT8(0x38, buf[3]); + TEST_ASSERT_EQUAL_UINT8(0, buf[4]); + TEST_ASSERT_POINTERS_EQUAL(&buf[4], cursor.next); + TEST_ASSERT_EQUAL_INT(12, cursor.left); + /* Test no change */ + /* Setup */ cursor.left = 0; - // Run test + /* Run test */ ex_append_header(&cursor, 0xFEED, 0xABCD); - // Check - TEST_ASSERT_EQUAL_UINT8(buf[4], 0); - TEST_ASSERT_POINTERS_EQUAL(cursor.next, &buf[4]); - TEST_ASSERT_EQUAL_INT(cursor.left, 0); + /* Check */ + TEST_ASSERT_EQUAL_UINT8(0, buf[4]); + TEST_ASSERT_POINTERS_EQUAL(&buf[4], cursor.next); + TEST_ASSERT_EQUAL_INT(0, cursor.left); } TEST(nts, append_header) { - // Test change - // Setup - uint8_t buf[16]; + /* Test change */ + /* Setup */ + uint8_t buf[16] = {0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0}; BufCtl cursor; cursor.next = buf; cursor.left = 16; - // Run test + /* Run test */ append_header(&cursor, 0xFADE, 0x1234); - // Check - TEST_ASSERT_EQUAL_UINT8(buf[0], 0xFA); - TEST_ASSERT_EQUAL_UINT8(buf[1], 0xDE); - TEST_ASSERT_EQUAL_UINT8(buf[2], 0x12); - TEST_ASSERT_EQUAL_UINT8(buf[3], 0x34); - TEST_ASSERT_EQUAL_UINT8(buf[4], 0); - TEST_ASSERT_POINTERS_EQUAL(cursor.next, &buf[4]); - TEST_ASSERT_EQUAL_INT(cursor.left, 12); - // Test no change - // Setup + /* Check */ + TEST_ASSERT_EQUAL_UINT8(0xFA, buf[0]); + TEST_ASSERT_EQUAL_UINT8(0xDE, buf[1]); + TEST_ASSERT_EQUAL_UINT8(0x12, buf[2]); + TEST_ASSERT_EQUAL_UINT8(0x34, buf[3]); + TEST_ASSERT_EQUAL_UINT8(0, buf[4]); + TEST_ASSERT_POINTERS_EQUAL(&buf[4], cursor.next); + TEST_ASSERT_EQUAL_INT(12, cursor.left); + /* Test no change */ + /* Setup */ cursor.left = 0; - // Run test + /* Run test */ append_header(&cursor, 0xFEED, 0xABCD); - // Check - TEST_ASSERT_EQUAL_UINT8(buf[4], 0); - TEST_ASSERT_POINTERS_EQUAL(cursor.next, &buf[4]); - TEST_ASSERT_EQUAL_INT(cursor.left, 0); + /* Check */ + TEST_ASSERT_EQUAL_UINT8(0, buf[4]); + TEST_ASSERT_POINTERS_EQUAL(&buf[4], cursor.next); + TEST_ASSERT_EQUAL_INT(0, cursor.left); } TEST(nts, append_uint16) { - // Test change - // Setup + /* Test change */ + /* Setup */ uint8_t buf[16] = {0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0}; + 0, 0, 0, 0, 0, 0, 0, 0}; BufCtl cursor; cursor.next = buf; cursor.left = 16; - // Run test + /* Run test */ append_uint16(&cursor, 0x1234); - // Check - TEST_ASSERT_EQUAL_UINT8(buf[0], 0x12); - TEST_ASSERT_EQUAL_UINT8(buf[1], 0x34); - TEST_ASSERT_POINTERS_EQUAL(cursor.next, &buf[2]); - TEST_ASSERT_EQUAL_INT(cursor.left, 14); - // Test no change - // Setup + /* Check */ + TEST_ASSERT_EQUAL_UINT8(0x12, buf[0]); + TEST_ASSERT_EQUAL_UINT8(0x34, buf[1]); + TEST_ASSERT_POINTERS_EQUAL(&buf[2], cursor.next); + TEST_ASSERT_EQUAL_INT(14, cursor.left); + /* Test no change */ + /* Setup */ cursor.left = 0; - // Run test + /* Run test */ append_uint16(&cursor, 0x5678); - // Check - TEST_ASSERT_EQUAL_UINT8(buf[2], 0); - TEST_ASSERT_POINTERS_EQUAL(cursor.next, &buf[2]); - TEST_ASSERT_EQUAL_INT(cursor.left, 0); + /* Check */ + TEST_ASSERT_EQUAL_UINT8(0, buf[2]); + TEST_ASSERT_POINTERS_EQUAL(&buf[2], cursor.next); + TEST_ASSERT_EQUAL_INT(0, cursor.left); } TEST(nts, append_bytes) { - // Test change - // Setup + /* Test change */ + /* Setup */ uint8_t buf[16] = {0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0}; + 0, 0, 0, 0, 0, 0, 0, 0}; BufCtl cursor; cursor.next = buf; cursor.left = 16; uint8_t data[6] = {0, 1, 2, 3, 4, 5}; - // Run test + /* Run test */ append_bytes(&cursor, data, 6); - // Check - TEST_ASSERT_EQUAL_UINT8(buf[0], 0); - TEST_ASSERT_EQUAL_UINT8(buf[1], 1); - TEST_ASSERT_EQUAL_UINT8(buf[2], 2); - TEST_ASSERT_EQUAL_UINT8(buf[3], 3); - TEST_ASSERT_EQUAL_UINT8(buf[4], 4); - TEST_ASSERT_EQUAL_UINT8(buf[5], 5); - TEST_ASSERT_POINTERS_EQUAL(cursor.next, &buf[6]); - TEST_ASSERT_EQUAL_INT(cursor.left, 10); - // Test no change - // Setup + /* Check */ + TEST_ASSERT_EQUAL_UINT8(0, buf[0]); + TEST_ASSERT_EQUAL_UINT8(1, buf[1]); + TEST_ASSERT_EQUAL_UINT8(2, buf[2]); + TEST_ASSERT_EQUAL_UINT8(3, buf[3]); + TEST_ASSERT_EQUAL_UINT8(4, buf[4]); + TEST_ASSERT_EQUAL_UINT8(5, buf[5]); + TEST_ASSERT_POINTERS_EQUAL(&buf[6], cursor.next); + TEST_ASSERT_EQUAL_INT(10, cursor.left); + /* Test no change */ + /* Setup */ cursor.left = 0; - // Run test + /* Run test */ append_bytes(&cursor, data, 6); - // Check - TEST_ASSERT_EQUAL_UINT8(buf[6], 0); - TEST_ASSERT_POINTERS_EQUAL(cursor.next, &buf[6]); - TEST_ASSERT_EQUAL_INT(cursor.left, 0); + /* Check */ + TEST_ASSERT_EQUAL_UINT8(0, buf[6]); + TEST_ASSERT_POINTERS_EQUAL(&buf[6], cursor.next); + TEST_ASSERT_EQUAL_INT(0, cursor.left); } TEST(nts, ke_next_record) { - // Setup + /* Setup */ uint8_t buf[16] = {0xFA, 0xCE, 0, 4, 0xFF, 0xEE, 0xDD, 0xCC, - 0, 0, 0, 0, 0, 0, 0, 0}; + 0, 0, 0, 0, 0, 0, 0, 0}; BufCtl cursor; cursor.next = buf; cursor.left = 16; int length; uint16_t type; - // Run test + /* Run test */ type = ke_next_record(&cursor, &length); - // Check - TEST_ASSERT_EQUAL_INT(length, 4); - TEST_ASSERT_EQUAL_INT(type, 0xFACE); - TEST_ASSERT_POINTERS_EQUAL(cursor.next, &buf[4]); - TEST_ASSERT_EQUAL_INT(cursor.left, 12); + /* Check */ + TEST_ASSERT_EQUAL_INT(4, length); + TEST_ASSERT_EQUAL_INT(0xFACE, type); + TEST_ASSERT_POINTERS_EQUAL(&buf[4], cursor.next); + TEST_ASSERT_EQUAL_INT(12, cursor.left); } TEST(nts, ex_next_record) { - // Setup - uint8_t buf[16] = {0xFA, 0xCE, 0, 4, 0xFF, 0xEE, 0xDD, 0xCC, - 0, 0, 0, 0, 0, 0, 0, 0}; + /* Setup */ + uint8_t buf[16] = {0xFA, 0xCE, 0, 8, 0xFF, 0xEE, 0xDD, 0xCC, + 0, 0, 0, 0, 0, 0, 0, 0}; BufCtl cursor; cursor.next = buf; cursor.left = 16; int length; uint16_t type; - // Run test + /* Run test */ type = ex_next_record(&cursor, &length); - // Check - TEST_ASSERT_EQUAL_INT(length, 4); - TEST_ASSERT_EQUAL_INT(type, 0xFACE); - TEST_ASSERT_POINTERS_EQUAL(cursor.next, &buf[4]); - TEST_ASSERT_EQUAL_INT(cursor.left, 12); + /* Check */ + TEST_ASSERT_EQUAL_INT(4, length); + TEST_ASSERT_EQUAL_INT(0xFACE, type); + TEST_ASSERT_POINTERS_EQUAL(&buf[4], cursor.next); + TEST_ASSERT_EQUAL_INT(12, cursor.left); } TEST(nts, next_uint16) { - // Setup + /* Setup */ uint8_t buf[16] = {0xFA, 0xCE, 0, 4, 0xFF, 0xEE, 0xDD, 0xCC, - 0, 0, 0, 0, 0, 0, 0, 0}; + 0, 0, 0, 0, 0, 0, 0, 0}; BufCtl cursor; cursor.next = buf; cursor.left = 16; uint16_t data; - // Run test + /* Run test */ data = next_uint16(&cursor); - // Check - TEST_ASSERT_EQUAL_UINT8(data, 0xFACE); - TEST_ASSERT_POINTERS_EQUAL(cursor.next, &buf[2]); - TEST_ASSERT_EQUAL_INT(cursor.left, 14); + /* Check */ + TEST_ASSERT_EQUAL_UINT8(0xFACE, data); + TEST_ASSERT_POINTERS_EQUAL(&buf[2], cursor.next); + TEST_ASSERT_EQUAL_INT(14, cursor.left); } TEST(nts, next_bytes) { - // Setup + /* Setup */ uint8_t buf[16] = {0xFA, 0xCE, 0, 4, 0xFF, 0xEE, 0xDD, 0xCC, - 0, 0, 0, 0, 0, 0, 0, 0}; + 0, 0, 0, 0, 0, 0, 0, 0}; BufCtl cursor; cursor.next = buf; cursor.left = 16; uint8_t data[8]; uint16_t length; - // Run test + /* Run test */ length = next_bytes(&cursor, data, 8); - // Check - TEST_ASSERT_EQUAL_INT(length, 8); - TEST_ASSERT_EQUAL_UINT8(data[0], 0xFA); - TEST_ASSERT_EQUAL_UINT8(data[1], 0xCE); - TEST_ASSERT_EQUAL_UINT8(data[2], 0); - TEST_ASSERT_EQUAL_UINT8(data[3], 4); - TEST_ASSERT_EQUAL_UINT8(data[4], 0xFF); - TEST_ASSERT_EQUAL_UINT8(data[5], 0xEE); - TEST_ASSERT_EQUAL_UINT8(data[6], 0xDD); - TEST_ASSERT_EQUAL_UINT8(data[7], 0xCC); - TEST_ASSERT_POINTERS_EQUAL(cursor.next, &buf[8]); - TEST_ASSERT_EQUAL_INT(cursor.left, 8); + /* Check */ + TEST_ASSERT_EQUAL_INT(8, length); + TEST_ASSERT_EQUAL_UINT8(0xFA, data[0]); + TEST_ASSERT_EQUAL_UINT8(0xCE, data[1]); + TEST_ASSERT_EQUAL_UINT8(0, data[2]); + TEST_ASSERT_EQUAL_UINT8(4, data[3]); + TEST_ASSERT_EQUAL_UINT8(0xFF, data[4]); + TEST_ASSERT_EQUAL_UINT8(0xEE, data[5]); + TEST_ASSERT_EQUAL_UINT8(0xDD, data[6]); + TEST_ASSERT_EQUAL_UINT8(0xCC, data[7]); + TEST_ASSERT_POINTERS_EQUAL(&buf[8], cursor.next); + TEST_ASSERT_EQUAL_INT(8, cursor.left); } -/* Hacks to keep linker happy after moving nts_init to nts.c */ -bool nts_server_init (void) { return true; } -bool nts_client_init (void) { return true; } -bool nts_cookie_init (void) { return true; } -bool nts_server_init2 (void) { return true; } -bool nts_cookie_init2 (void) { return true; } -bool extens_init (void) { return true; } - - - TEST_GROUP_RUNNER(nts) { RUN_TEST_CASE(nts, nts_translate_version); RUN_TEST_CASE(nts, nts_string_to_aead); diff --git a/tests/ntpd/nts_client.c b/tests/ntpd/nts_client.c new file mode 100644 index 0000000000..ceae7d875b --- /dev/null +++ b/tests/ntpd/nts_client.c @@ -0,0 +1,269 @@ +#include "config.h" +#include "ntpd.h" +#include "nts.h" +#include "nts2.h" +#include "ntp_dns.h" +#include "unity.h" +#include "unity_fixture.h" +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +void dns_take_server(struct peer *a, sockaddr_u *b); +void dns_take_status(struct peer *a, DNS_Status b); + +bool nts_client_send_request_core(uint8_t *buff, int buf_size, int *used, struct peer* peer); +bool nts_client_process_response_core(uint8_t *buff, int transferred, struct peer* peer); + + +TEST_GROUP(nts_client); + +TEST_SETUP(nts_client) {} + +TEST_TEAR_DOWN(nts_client) {} + + +TEST(nts_client, nts_client_send_request_core) { + bool success; + int used; + struct peer peer; + uint8_t buffer[1000]; + char pAEAD[50] = "AES_SIV_CMAC_512"; + /* ===== Test: correct, peer aead ===== */ + peer.cfg.nts_cfg.aead = pAEAD; + /* run */ + success = nts_client_send_request_core(buffer, sizeof(buffer), &used, &peer); + TEST_ASSERT_EQUAL(true, success); + TEST_ASSERT_EQUAL(16, used); + TEST_ASSERT_EQUAL(0x80, buffer[0]); + TEST_ASSERT_EQUAL(nts_next_protocol_negotiation, buffer[1]); + TEST_ASSERT_EQUAL(0, buffer[2]); + TEST_ASSERT_EQUAL(2, buffer[3]); + TEST_ASSERT_EQUAL(0, buffer[4]); + TEST_ASSERT_EQUAL(nts_protocol_NTP, buffer[5]); + TEST_ASSERT_EQUAL(0, buffer[6]); + TEST_ASSERT_EQUAL(nts_algorithm_negotiation, buffer[7]); + TEST_ASSERT_EQUAL(0, buffer[8]); + TEST_ASSERT_EQUAL(2, buffer[9]); + TEST_ASSERT_EQUAL(0, buffer[10]); + TEST_ASSERT_EQUAL(AEAD_AES_SIV_CMAC_512, buffer[11]); + TEST_ASSERT_EQUAL(0x80, buffer[12]); + TEST_ASSERT_EQUAL(nts_end_of_message, buffer[13]); + TEST_ASSERT_EQUAL(0, buffer[14]); + TEST_ASSERT_EQUAL(0, buffer[15]); + /* ===== Test: correct, global config aead ===== */ + peer.cfg.nts_cfg.aead = NULL; + char gAEAD[50] = "AES_SIV_CMAC_384"; + ntsconfig.aead = gAEAD; + /* run */ + success = nts_client_send_request_core(buffer, sizeof(buffer), &used, &peer); + TEST_ASSERT_EQUAL(true, success); + TEST_ASSERT_EQUAL(16, used); + TEST_ASSERT_EQUAL(0x80, buffer[0]); + TEST_ASSERT_EQUAL(nts_next_protocol_negotiation, buffer[1]); + TEST_ASSERT_EQUAL(0, buffer[2]); + TEST_ASSERT_EQUAL(2, buffer[3]); + TEST_ASSERT_EQUAL(0, buffer[4]); + TEST_ASSERT_EQUAL(nts_protocol_NTP, buffer[5]); + TEST_ASSERT_EQUAL(0, buffer[6]); + TEST_ASSERT_EQUAL(nts_algorithm_negotiation, buffer[7]); + TEST_ASSERT_EQUAL(0, buffer[8]); + TEST_ASSERT_EQUAL(2, buffer[9]); + TEST_ASSERT_EQUAL(0, buffer[10]); + TEST_ASSERT_EQUAL(AEAD_AES_SIV_CMAC_384, buffer[11]); + TEST_ASSERT_EQUAL(0x80, buffer[12]); + TEST_ASSERT_EQUAL(nts_end_of_message, buffer[13]); + TEST_ASSERT_EQUAL(0, buffer[14]); + TEST_ASSERT_EQUAL(0, buffer[15]); + /* ===== Test: correct, default aead ===== */ + peer.cfg.nts_cfg.aead = NULL; + ntsconfig.aead = NULL; + /* run */ + success = nts_client_send_request_core(buffer, sizeof(buffer), &used, &peer); + TEST_ASSERT_EQUAL(true, success); + TEST_ASSERT_EQUAL(16, used); + TEST_ASSERT_EQUAL(0x80, buffer[0]); + TEST_ASSERT_EQUAL(nts_next_protocol_negotiation, buffer[1]); + TEST_ASSERT_EQUAL(0, buffer[2]); + TEST_ASSERT_EQUAL(2, buffer[3]); + TEST_ASSERT_EQUAL(0, buffer[4]); + TEST_ASSERT_EQUAL(nts_protocol_NTP, buffer[5]); + TEST_ASSERT_EQUAL(0, buffer[6]); + TEST_ASSERT_EQUAL(nts_algorithm_negotiation, buffer[7]); + TEST_ASSERT_EQUAL(0, buffer[8]); + TEST_ASSERT_EQUAL(2, buffer[9]); + TEST_ASSERT_EQUAL(0, buffer[10]); + TEST_ASSERT_EQUAL(AEAD_AES_SIV_CMAC_256, buffer[11]); + TEST_ASSERT_EQUAL(0x80, buffer[12]); + TEST_ASSERT_EQUAL(nts_end_of_message, buffer[13]); + TEST_ASSERT_EQUAL(0, buffer[14]); + TEST_ASSERT_EQUAL(0, buffer[15]); +} + +TEST(nts_client, nts_client_process_response_core) { + /* General init */ + bool success; + struct peer peer; + peer.nts_state.aead = 42; /* Dummy init values */ + peer.nts_state.cookielen = 0; + peer.nts_state.writeIdx = 0; + peer.nts_state.count = 0; + /* ===== Test: all correct ===== */ + /* data */ + uint8_t buf0[] = { + 0x80, nts_next_protocol_negotiation, 0, 2, 0, nts_protocol_NTP, + 0x80, nts_algorithm_negotiation, 0, 2, 0, AEAD_AES_SIV_CMAC_256, + 0x80, nts_new_cookie, 0, 8, 1, 2, 3, 4, 5, 6, 7, 8, + /* server_negotiation skipped due to getaddrinfo() containment breach */ + 0x80, nts_port_negotiation, 0, 2, 0, 3, + 0x80, nts_end_of_message, 0, 0 + }; + /* run */ + success = nts_client_process_response_core(buf0, sizeof(buf0), &peer); + /* check */ + TEST_ASSERT_EQUAL(true, success); + TEST_ASSERT_EQUAL_INT16(AEAD_AES_SIV_CMAC_256, peer.nts_state.aead); + TEST_ASSERT_EQUAL_INT32(8, peer.nts_state.cookielen); + TEST_ASSERT_EQUAL_INT8(1, peer.nts_state.cookies[0][0]); + TEST_ASSERT_EQUAL_INT8(2, peer.nts_state.cookies[0][1]); + TEST_ASSERT_EQUAL_INT8(3, peer.nts_state.cookies[0][2]); + TEST_ASSERT_EQUAL_INT8(4, peer.nts_state.cookies[0][3]); + TEST_ASSERT_EQUAL_INT8(5, peer.nts_state.cookies[0][4]); + TEST_ASSERT_EQUAL_INT8(6, peer.nts_state.cookies[0][5]); + TEST_ASSERT_EQUAL_INT8(7, peer.nts_state.cookies[0][6]); + TEST_ASSERT_EQUAL_INT8(8, peer.nts_state.cookies[0][7]); + TEST_ASSERT_EQUAL_INT32(1, peer.nts_state.writeIdx); + TEST_ASSERT_EQUAL_INT32(1, peer.nts_state.count); + /* ===== Test: nts_error ===== */ + /* data */ + uint8_t buf1[] = { + 0x80, nts_error, 0, 2, 0x11, 0x22, + 0x80, nts_end_of_message, 0, 0 + }; + /* run */ + success = nts_client_process_response_core(buf1, sizeof(buf1), &peer); + TEST_ASSERT_EQUAL(false, success); + /* ===== Test: nts_next_protocol, wrong data length ===== */ + /* data */ + uint8_t buf2[] = { + 0x80, nts_error, 0, 4, 0x11, 0x22, 0x33, 0x44, + 0x80, nts_end_of_message, 0, 0 + }; + /* run */ + success = nts_client_process_response_core(buf2, sizeof(buf2), &peer); + TEST_ASSERT_EQUAL(false, success); + /* ===== Test: nts_next_protocol, wrong data ===== */ + /* data */ + uint8_t buf3[] = { + 0x80, nts_error, 0, 2, 0x11, 0x22, + 0x80, nts_end_of_message, 0, 0 + }; + /* run */ + success = nts_client_process_response_core(buf3, sizeof(buf3), &peer); + TEST_ASSERT_EQUAL(false, success); + /* ===== Test: nts_algorithm_negotiation, wrong length ===== */ + /* data */ + uint8_t buf4[] = { + 0x80, nts_algorithm_negotiation, 0, 4, 0x11, 0x22, 0x33, 0x44, + 0x80, nts_end_of_message, 0, 0 + }; + /* run */ + success = nts_client_process_response_core(buf4, sizeof(buf4), &peer); + TEST_ASSERT_EQUAL(false, success); + /* ===== Test:nts_algorithm_negotiation, bad AEAN type ===== */ + /* data */ + uint8_t buf5[] = { + 0x80, nts_algorithm_negotiation, 0, 4, 0x11, 0x22, + 0x80, nts_end_of_message, 0, 0 + }; + /* run */ + success = nts_client_process_response_core(buf5, sizeof(buf5), &peer); + TEST_ASSERT_EQUAL(false, success); + /* ===== Test: nts_new_cookie, over max cookie length ===== */ + /* data */ + uint8_t buf6[] = { + 0x80, nts_new_cookie, 0, 4, 0x11, 0x22, /* NTS_MAX_COOKIELEN == 192 */ + 0x80, nts_end_of_message, 0, 0 + }; + /* run */ + success = nts_client_process_response_core(buf6, sizeof(buf6), &peer); + TEST_ASSERT_EQUAL(false, success); + /* ===== Test: nts_new_cookie, cookie doesn't equal peer cookie size ===== */ + /* data */ + peer.nts_state.cookielen = 8; + uint8_t buf7[] = { + 0x80, nts_new_cookie, 0, 4, 0, 9, + 0x80, nts_end_of_message, 0, 0 + }; + /* run */ + success = nts_client_process_response_core(buf7, sizeof(buf7), &peer); + TEST_ASSERT_EQUAL(false, success); + /* ===== Test: nts_new_cookie, have max cookies ===== */ + /* data */ + uint8_t buf8[] = { + 0x80, nts_new_cookie, 0, 4, 0, 8, 10, 20, 30, 40, 50, 60, 70, 80, + 0x80, nts_end_of_message, 0, 0 + }; + peer.nts_state.writeIdx = 0; + peer.nts_state.count = NTS_MAX_COOKIES; + /* run */ + success = nts_client_process_response_core(buf8, sizeof(buf8), &peer); + /* check */ + TEST_ASSERT_EQUAL(false, success); + TEST_ASSERT_EQUAL(0, peer.nts_state.writeIdx); + TEST_ASSERT_NOT_EQUAL(10, peer.nts_state.cookies[0][0]); + /* ===== Test: nts_end_of_message, wrong length ===== */ + /* data */ + uint8_t buf9[] = { + 0x80, nts_end_of_message, 0, 4 + }; + /* run */ + success = nts_client_process_response_core(buf9, sizeof(buf9), &peer); + TEST_ASSERT_EQUAL(false, success); + /* ===== Test: nts_end_of_message, data remaining ===== */ + /* data */ + uint8_t buf10[] = { + 0x80, nts_end_of_message, 0, 0, + 42 + }; + /* run */ + success = nts_client_process_response_core(buf10, sizeof(buf10), &peer); + TEST_ASSERT_EQUAL(false, success); + /* ===== Test: weird type, critical ===== */ + /* data */ + uint8_t buf11[] = { + 0x80, 0xFF, 0, 0, + 0x80, nts_end_of_message, 0, 0, + }; + /* run */ + success = nts_client_process_response_core(buf11, sizeof(buf11), &peer); + TEST_ASSERT_EQUAL(false, success); + /* ===== Test: no cookies ===== */ + /* data */ + peer.nts_state.count = 0; + uint8_t buf12[] = { + 0x80, nts_end_of_message, 0, 0 + }; + /* run */ + success = nts_client_process_response_core(buf12, sizeof(buf12), &peer); + TEST_ASSERT_EQUAL(false, success); + /* ===== Test: no aead ===== */ + /* data */ + peer.nts_state.count = 8; /* So this doesn't trigger an error */ + peer.nts_state.aead = NO_AEAD; + uint8_t buf13[] = { + 0x80, nts_end_of_message, 0, 0 + }; + /* run */ + success = nts_client_process_response_core(buf13, sizeof(buf13), &peer); + TEST_ASSERT_EQUAL(false, success); +} + +/* Hacks to keep linker happy */ +void dns_take_server(struct peer *a, sockaddr_u *b) { return; } +void dns_take_status(struct peer *a, DNS_Status b) { return; } + +TEST_GROUP_RUNNER(nts_client) { + RUN_TEST_CASE(nts_client, nts_client_send_request_core); + RUN_TEST_CASE(nts_client, nts_client_process_response_core); +} diff --git a/tests/ntpd/nts_cookie.c b/tests/ntpd/nts_cookie.c new file mode 100644 index 0000000000..23b6083042 --- /dev/null +++ b/tests/ntpd/nts_cookie.c @@ -0,0 +1,82 @@ +#include "config.h" +#include "ntpd.h" +#include "nts.h" +#include "nts2.h" +#include "ntp_dns.h" +#include "unity.h" +#include "unity_fixture.h" +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include "aes_siv.h" + +extern AES_SIV_CTX* cookie_ctx; +extern uint8_t K[NTS_MAX_KEYLEN], K2[NTS_MAX_KEYLEN]; +extern uint32_t I; + +TEST_GROUP(nts_cookie); + +TEST_SETUP(nts_cookie) {} + +TEST_TEAR_DOWN(nts_cookie) {} + + +TEST(nts_cookie, nts_make_cookie_key) { + /* init */ + bool ok; + uint8_t kStart1[NTS_MAX_KEYLEN] = {1, 2, 3, 4, 5}; + uint8_t kStart2[NTS_MAX_KEYLEN] = {10, 20, 30, 40, 50}; + uint32_t iStart = I; + /* copy to key variables */ + memcpy(K, kStart1, sizeof(K)); + memcpy(K2, kStart2, sizeof(K2)); + /* run test */ + ok = nts_make_cookie_key(); + TEST_ASSERT_EQUAL(true, ok); + /* check that K2 now equals former-K */ + TEST_ASSERT_EQUAL_UINT8_ARRAY(kStart1, K2, sizeof(K2)); + /* check that K does not equal former-K */ + /* There is no "TEST UNEQUAL", do it manually */ + bool equal = true; + for (unsigned int i = 0; i < sizeof(K); i++) { + if (K[i] != kStart1[i]) { + equal = false; + break; + } + } + TEST_ASSERT_EQUAL(false, equal); + /* Check that I does not equal former-I */ + TEST_ASSERT_NOT_EQUAL(iStart, I); +} + +TEST(nts_cookie, nts_make_unpack_cookie) { + /* init */ + uint8_t cookie[NTS_MAX_COOKIELEN]; + /* Using 16 bytes in test for ease of handling */ + uint8_t c2s[16] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}; + uint8_t s2c[16] = {16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1}; + uint8_t c2s_2[16] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + uint8_t s2c_2[16] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + int len; + int keylen; + bool ok; + uint16_t aead; /* retrieved on unpack */ + /* Init for cookie_ctx */ + nts_cookie_init(); + /* Test */ + len = nts_make_cookie(cookie, AEAD_AES_SIV_CMAC_256, c2s, s2c, sizeof(c2s)); + TEST_ASSERT_EQUAL(72, len); + /* Very limited in what data can be directly checked here */ + /* Reverse the test */ + ok = nts_unpack_cookie(cookie, len, &aead, c2s_2, s2c_2, &keylen); + TEST_ASSERT_EQUAL(true, ok); + TEST_ASSERT_EQUAL(AEAD_AES_SIV_CMAC_256, aead); + TEST_ASSERT_EQUAL(16, keylen); + TEST_ASSERT_EQUAL_UINT8_ARRAY(c2s, c2s_2, 16); + TEST_ASSERT_EQUAL_UINT8_ARRAY(s2c, s2c_2, 16); +} + +TEST_GROUP_RUNNER(nts_cookie) { + RUN_TEST_CASE(nts_cookie, nts_make_unpack_cookie); + RUN_TEST_CASE(nts_cookie, nts_make_cookie_key); +} diff --git a/tests/ntpd/nts_extens.c b/tests/ntpd/nts_extens.c new file mode 100644 index 0000000000..83181f4386 --- /dev/null +++ b/tests/ntpd/nts_extens.c @@ -0,0 +1,231 @@ +#include "config.h" +#include "ntpd.h" +#include "nts.h" +#include "nts2.h" +#include "ntp_dns.h" +#include "unity.h" +#include "unity_fixture.h" +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include "aes_siv.h" + +/* base_pkt is the size of a bare NTP packet, used for constructing + * dummy packets to feed into the tests */ +uint8_t base_pkt[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, + 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, + 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, + 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47}; + +/* Snipped from nts_extens.c */ +#define NONCE_LENGTH 16 +#define CMAC_LENGTH 16 +#define NTP_EX_HDR_LNG 4 +#define NTP_EX_U16_LNG 2 + +enum NtpExtFieldType { + Unique_Identifier = 0x104, + NTS_Cookie = 0x204, + NTS_Cookie_Placeholder = 0x304, + NTS_AEEF = 0x404 /* Authenticated and Encrypted Extension Fields */ +}; + +TEST_GROUP(nts_extens); + +TEST_SETUP(nts_extens) { + extens_init(); +} + +TEST_TEAR_DOWN(nts_extens) {} + + +TEST(nts_extens, extens_client_send) { + /* init */ + struct peer peer; + peer.nts_state.readIdx = 0; + peer.nts_state.count = 4; /* 1/2 of max, -1, should cause 5 requests */ + uint8_t c2s[NTS_MAX_KEYLEN] = {1, 2, 3, 4, 5, 6, 7, 8}; + memcpy(peer.nts_state.c2s, c2s, sizeof(c2s)); + peer.nts_state.keylen = sizeof(c2s); + peer.nts_state.cookielen = NTS_MAX_COOKIELEN; + struct pkt xpkt; + int used = 0; + /* Test */ + used = extens_client_send(&peer, &xpkt); + TEST_ASSERT_EQUAL(1056, used); + TEST_ASSERT_EQUAL(1, peer.nts_state.readIdx); + TEST_ASSERT_EQUAL(1, nts_client_send); + TEST_ASSERT_EQUAL(3, peer.nts_state.count); +} + +TEST(nts_extens, extens_server_recv) { + /* init */ + struct ntspacket_t ntspkt; + memset(&ntspkt, 0, sizeof(ntspkt)); + uint8_t pkt[2048]; /* Void extracted value */ + BufCtl buf; + bool ok = true; + memset(pkt, 0, sizeof(pkt)); + memcpy(pkt, base_pkt, sizeof(base_pkt)); + buf.next = pkt+LEN_PKT_NOMAC; + buf.left = sizeof(pkt) - LEN_PKT_NOMAC; + /* Make dummy cookie */ + uint8_t cookie[NTS_MAX_COOKIELEN]; + uint8_t c2s[16] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}; + uint8_t s2c[16] = {16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1}; + int cookielen; + cookielen = nts_make_cookie(cookie, AEAD_AES_SIV_CMAC_256, c2s, s2c, + sizeof(c2s)); + /* === Pre Switch === */ + /* Bad record length; non-aligned */ + append_header(&buf, 0x1234, 0x0003); + ok = extens_server_recv(&ntspkt, pkt, sizeof(pkt)); + TEST_ASSERT_EQUAL(false, ok); + /* Bad record length; runs off end of data */ + memset(pkt+LEN_PKT_NOMAC, 0, sizeof(pkt)-LEN_PKT_NOMAC); + buf.next = pkt+LEN_PKT_NOMAC; + buf.left = sizeof(pkt) - LEN_PKT_NOMAC; + append_header(&buf, 0x1234, 0x0010); + ok = extens_server_recv(&ntspkt, pkt, sizeof(base_pkt) + 6); /* hdr + 2 */ + TEST_ASSERT_EQUAL(false, ok); + /* === Unique_Identifier === */ + /* Bad UID length */ + memset(pkt+LEN_PKT_NOMAC, 0, sizeof(pkt)-LEN_PKT_NOMAC); + buf.next = pkt+LEN_PKT_NOMAC; + buf.left = sizeof(pkt) - LEN_PKT_NOMAC; + append_header(&buf, Unique_Identifier, NTS_UID_MAX_LENGTH + 8); + ok = extens_server_recv(&ntspkt, pkt, sizeof(pkt)); + TEST_ASSERT_EQUAL(false, ok); + /* === NTS_Cookie === */ + /* Too many cookies */ + memset(pkt+LEN_PKT_NOMAC, 0, sizeof(pkt)-LEN_PKT_NOMAC); + buf.next = pkt+LEN_PKT_NOMAC; + buf.left = sizeof(pkt) - LEN_PKT_NOMAC; + ex_append_record_bytes(&buf, NTS_Cookie, cookie, cookielen); + ex_append_record_bytes(&buf, NTS_Cookie, cookie, cookielen); + ok = extens_server_recv(&ntspkt, pkt, sizeof(pkt)); + TEST_ASSERT_EQUAL(false, ok); + /* Bad cookie unpack */ + memset(pkt+LEN_PKT_NOMAC, 0, sizeof(pkt)-LEN_PKT_NOMAC); + buf.next = pkt+LEN_PKT_NOMAC; + buf.left = sizeof(pkt) - LEN_PKT_NOMAC; + ex_append_record_bytes(&buf, NTS_Cookie, cookie, sizeof(cookie)); + ok = extens_server_recv(&ntspkt, pkt, sizeof(pkt)); + TEST_ASSERT_EQUAL(false, ok); + /* === NTS_AEEF === */ + /* AEEF without cookie */ + memset(pkt+LEN_PKT_NOMAC, 0, sizeof(pkt)-LEN_PKT_NOMAC); + buf.next = pkt+LEN_PKT_NOMAC; + buf.left = sizeof(pkt) - LEN_PKT_NOMAC; + append_header(&buf, NTS_AEEF, NTP_EX_HDR_LNG+NONCE_LENGTH+CMAC_LENGTH); + ok = extens_server_recv(&ntspkt, pkt, sizeof(pkt)); + TEST_ASSERT_EQUAL(false, ok); + /* Bad AEEF length */ + memset(pkt+LEN_PKT_NOMAC, 0, sizeof(pkt)-LEN_PKT_NOMAC); + buf.next = pkt+LEN_PKT_NOMAC; + buf.left = sizeof(pkt) - LEN_PKT_NOMAC; + ex_append_record_bytes(&buf, NTS_Cookie, cookie, cookielen); + append_header(&buf, NTS_AEEF, NTP_EX_HDR_LNG+NONCE_LENGTH+CMAC_LENGTH+8); + ok = extens_server_recv(&ntspkt, pkt, sizeof(pkt)); + TEST_ASSERT_EQUAL(false, ok); + /* Bad noncelen */ + uint8_t aeef_data1[NTP_EX_HDR_LNG+NONCE_LENGTH+CMAC_LENGTH] = { + 0, 3, /* nonce length, bad, not mod 4 */ + 0, 16, /* cmac length */ + 1, 2, 3, /* nonce */ + 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}; /* cmac */ + memset(pkt+LEN_PKT_NOMAC, 0, sizeof(pkt)-LEN_PKT_NOMAC); + buf.next = pkt+LEN_PKT_NOMAC; + buf.left = sizeof(pkt) - LEN_PKT_NOMAC; + ex_append_record_bytes(&buf, NTS_Cookie, cookie, cookielen); + ex_append_record_bytes(&buf, NTS_AEEF, aeef_data1, sizeof(aeef_data1)); + ok = extens_server_recv(&ntspkt, pkt, sizeof(pkt)); + TEST_ASSERT_EQUAL(false, ok); + /* Bad CMAC length */ + uint8_t aeef_data2[NTP_EX_HDR_LNG+NONCE_LENGTH+CMAC_LENGTH] = { + 0, 16, /* nonce length */ + 0, 8, /* cmac length, bad != 16 */ + 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, /* nonce */ + 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}; /* cmac */ + memset(pkt+LEN_PKT_NOMAC, 0, sizeof(pkt)-LEN_PKT_NOMAC); + buf.next = pkt+LEN_PKT_NOMAC; + buf.left = sizeof(pkt) - LEN_PKT_NOMAC; + ex_append_record_bytes(&buf, NTS_Cookie, cookie, cookielen); + ex_append_record_bytes(&buf, NTS_AEEF, aeef_data2, sizeof(aeef_data2)); + ok = extens_server_recv(&ntspkt, pkt, sizeof(pkt)); + TEST_ASSERT_EQUAL(false, ok); + /* Bad decryption */ + /* I do not know *why* this is a bad decryption, just that it is */ + uint8_t aeef_data3[NTP_EX_HDR_LNG+NONCE_LENGTH+CMAC_LENGTH] = { + 0, 16, /* nonce length */ + 0, 16, /* cmac length */ + 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, /* nonce */ + 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}; /* cmac */ + memset(pkt+LEN_PKT_NOMAC, 0, sizeof(pkt)-LEN_PKT_NOMAC); + buf.next = pkt+LEN_PKT_NOMAC; + buf.left = sizeof(pkt) - LEN_PKT_NOMAC; + ex_append_record_bytes(&buf, NTS_Cookie, cookie, cookielen); + ex_append_record_bytes(&buf, NTS_AEEF, aeef_data3, sizeof(aeef_data3)); + ok = extens_server_recv(&ntspkt, pkt, sizeof(pkt)); + TEST_ASSERT_EQUAL(false, ok); + /* No out data -- Don't know how to trigger this yet */ + /* Remaining data, should be none */ + /* + * TODO: this is hitting decrypt error instead of remaining data. FIXME + */ + uint8_t aeef_data4[NTP_EX_HDR_LNG+NONCE_LENGTH+CMAC_LENGTH] = { + 0, 16, /* nonce length */ + 0, 16, /* cmac length */ + 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, /* nonce */ + 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}; /* cmac */ + memset(pkt+LEN_PKT_NOMAC, 0, sizeof(pkt)-LEN_PKT_NOMAC); + buf.next = pkt+LEN_PKT_NOMAC; + buf.left = sizeof(pkt) - LEN_PKT_NOMAC; + ex_append_record_bytes(&buf, NTS_Cookie, cookie, cookielen); + ex_append_record_bytes(&buf, NTS_AEEF, aeef_data4, sizeof(aeef_data4)); + ok = extens_server_recv(&ntspkt, pkt, sizeof(pkt)); + TEST_ASSERT_EQUAL(false, ok); + /* === default === */ + /* Unknown critical */ + memset(pkt+LEN_PKT_NOMAC, 0, sizeof(pkt)-LEN_PKT_NOMAC); + buf.next = pkt+LEN_PKT_NOMAC; + buf.left = sizeof(pkt) - LEN_PKT_NOMAC; + ex_append_header(&buf, 0xFFFF, 0); + ok = extens_server_recv(&ntspkt, pkt, sizeof(pkt)); + TEST_ASSERT_EQUAL(false, ok); + /* Unknown extension, period */ + memset(pkt+LEN_PKT_NOMAC, 0, sizeof(pkt)-LEN_PKT_NOMAC); + buf.next = pkt+LEN_PKT_NOMAC; + buf.left = sizeof(pkt) - LEN_PKT_NOMAC; + ex_append_header(&buf, 0x00FF, 0); + ok = extens_server_recv(&ntspkt, pkt, sizeof(pkt)); + TEST_ASSERT_EQUAL(false, ok); + /* === Post Loop === */ + /* No AEEF */ + memset(pkt+LEN_PKT_NOMAC, 0, sizeof(pkt)-LEN_PKT_NOMAC); + buf.next = pkt+LEN_PKT_NOMAC; + buf.left = sizeof(pkt) - LEN_PKT_NOMAC; + ex_append_record_bytes(&buf, NTS_Cookie, cookie, cookielen); + ok = extens_server_recv(&ntspkt, pkt, buf.next-pkt); + TEST_ASSERT_EQUAL(false, ok); + /* Working */ + /* TODO / FIXME: This test is currently disabled. I cannot get a good + * cookie decode */ + uint8_t aeef_data5[NTP_EX_HDR_LNG+NONCE_LENGTH+CMAC_LENGTH] = { + 0, 16, /* nonce length */ + 0, 16, /* cmac length */ + 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, /* nonce */ + 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}; /* cmac */ + memset(pkt+LEN_PKT_NOMAC, 0, sizeof(pkt)-LEN_PKT_NOMAC); + buf.next = pkt+LEN_PKT_NOMAC; + buf.left = sizeof(pkt) - LEN_PKT_NOMAC; + ex_append_record_bytes(&buf, NTS_Cookie, cookie, cookielen); + ex_append_record_bytes(&buf, NTS_AEEF, aeef_data5, sizeof(aeef_data5)); + ok = extens_server_recv(&ntspkt, pkt, (buf.next - pkt)); + /* TEST_ASSERT_EQUAL(true, ok); //disable */ +} + +TEST_GROUP_RUNNER(nts_extens) { + RUN_TEST_CASE(nts_extens, extens_client_send); + RUN_TEST_CASE(nts_extens, extens_server_recv); +} diff --git a/tests/ntpd/nts_server.c b/tests/ntpd/nts_server.c new file mode 100644 index 0000000000..3151e30446 --- /dev/null +++ b/tests/ntpd/nts_server.c @@ -0,0 +1,107 @@ +#include "config.h" +#include "ntpd.h" +#include "nts.h" +#include "nts2.h" +#include "ntp_dns.h" +#include "unity.h" +#include "unity_fixture.h" +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +TEST_GROUP(nts_server); + +TEST_SETUP(nts_server) {} + +TEST_TEAR_DOWN(nts_server) {} + +TEST(nts_server, nts_ke_process_receive) { + /* General init */ + struct BufCtl_t buf; + int aead; + bool success; + /* ===== Test: all correct ===== */ + uint8_t buf0[] = { + 0x80, nts_next_protocol_negotiation, 0, 2, 0x00, nts_protocol_NTP, + 0x80, nts_algorithm_negotiation, 0, 2, 0x00, AEAD_AES_SIV_CMAC_256, + 0x80, nts_end_of_message, 0, 0, + }; + buf.next = buf0; + buf.left = sizeof(buf0); + aead = NO_AEAD; + /* test */ + success = nts_ke_process_receive(&buf, &aead); + TEST_ASSERT_EQUAL(true, success); + TEST_ASSERT_EQUAL_INT(AEAD_AES_SIV_CMAC_256, aead); + /* ===== Test: nts_error ===== */ + uint8_t buf1[] = { + 0x80, nts_error, 0, 0, + 0x80, nts_end_of_message, 0, 0, + }; + buf.next = buf1; + buf.left = sizeof(buf1); + /* test */ + success = nts_ke_process_receive(&buf, &aead); + TEST_ASSERT_EQUAL(false, success); + /* ===== Test: nts_next_protocol_negotiation, bad length ===== */ + uint8_t buf2[] = { + 0x80, nts_next_protocol_negotiation, 0, 4, 0x11, 0x22, 0x33, 0x44, + 0x80, nts_end_of_message, 0, 0, + }; + buf.next = buf2; + buf.left = sizeof(buf2); + /* test */ + success = nts_ke_process_receive(&buf, &aead); + TEST_ASSERT_EQUAL(false, success); + /* ===== Test: nts_next_protocol_negotiation, bad protocol ===== */ + uint8_t buf3[] = { + 0x80, nts_next_protocol_negotiation, 0, 2, 0x11, 0x22, + 0x80, nts_end_of_message, 0, 0, + }; + buf.next = buf3; + buf.left = sizeof(buf3); + /* test */ + success = nts_ke_process_receive(&buf, &aead); + TEST_ASSERT_EQUAL(false, success); + /* ===== Test: nts_end_of_message, bad length ===== */ + uint8_t buf4[] = { + 0x80, nts_end_of_message, 0, 23, + }; + buf.next = buf4; + buf.left = sizeof(buf4); + /* test */ + success = nts_ke_process_receive(&buf, &aead); + TEST_ASSERT_EQUAL(false, success); + /* ===== Test: nts_end_of_message, bad critical ===== */ + uint8_t buf5[] = { + 0x00, nts_end_of_message, 0, 0, + }; + buf.next = buf5; + buf.left = sizeof(buf5); + /* test */ + success = nts_ke_process_receive(&buf, &aead); + TEST_ASSERT_EQUAL(false, success); + /* ===== Test: nts_end_of_message, remaining ===== */ + uint8_t buf6[] = { + 0x00, nts_end_of_message, 0, 0, + 1, 2, 3, 4 + }; + buf.next = buf6; + buf.left = sizeof(buf6); + /* test */ + success = nts_ke_process_receive(&buf, &aead); + TEST_ASSERT_EQUAL(false, success); + /* ===== Test: default, bad critical ===== */ + uint8_t buf7[] = { + 0x80, 0xFF, 0, 0, + }; + buf.next = buf7; + buf.left = sizeof(buf7); + /* test */ + success = nts_ke_process_receive(&buf, &aead); + TEST_ASSERT_EQUAL(false, success); +} + +TEST_GROUP_RUNNER(nts_server) { + RUN_TEST_CASE(nts_server, nts_ke_process_receive); +} diff --git a/tests/wscript b/tests/wscript index 2e6f7d2892..f593ab3b5e 100644 --- a/tests/wscript +++ b/tests/wscript @@ -93,16 +93,20 @@ def build(ctx): "ntpd/restrict.c", "ntpd/recvbuff.c", "ntpd/nts.c", + "ntpd/nts_client.c", + "ntpd/nts_server.c", + "ntpd/nts_cookie.c", + "ntpd/nts_extens.c", ] + common_source ctx.ntp_test( defines=unity_config + ["TEST_NTPD=1"], features="c cprogram test", - includes=[ctx.bldnode.parent.abspath(), "../include", "unity", "../ntpd", "common"], + includes=[ctx.bldnode.parent.abspath(), "../include", "unity", "../ntpd", "common", "../libaes_siv"], install_path=None, source=ntpd_source, target="test_ntpd", - use="ntpd_lib libntpd_obj unity ntp " + use="ntpd_lib libntpd_obj unity ntp aes_siv " "M PTHREAD CRYPTO RT SOCKET NSL", ) -- GitLab