15const char NTS_EXPORTER_LABEL[] =
"EXPORTER-network-time-security";
17static void put_u16(uint8_t *p, uint16_t v)
19 p[0] = (uint8_t)(v >> 8);
22static uint16_t get_u16(
const uint8_t *p)
24 return (uint16_t)((p[0] << 8) | p[1]);
27size_t detws_nts_ke_record(
bool critical, uint16_t type,
const uint8_t *body,
size_t body_len, uint8_t *out,
size_t cap)
29 if (!out || (body_len && !body) || body_len > 0xFFFF)
31 size_t n = 4 + body_len;
34 put_u16(out, (uint16_t)((type & 0x7FFF) | (critical ? Nts::NTS_KE_CRITICAL : 0)));
35 put_u16(out + 2, (uint16_t)body_len);
37 memcpy(out + 4, body, body_len);
41size_t detws_nts_ke_request(uint8_t *out,
size_t cap)
44 put_u16(proto, Nts::NTS_NEXT_PROTO_NTPV4);
46 put_u16(aead, Nts::NTS_AEAD_AES_SIV_CMAC_256);
50 r = detws_nts_ke_record(
true, Nts::NTS_KE_NEXT_PROTOCOL, proto, 2, out + n, cap - n);
54 r = detws_nts_ke_record(
true, Nts::NTS_KE_AEAD_ALGORITHM, aead, 2, out + n, cap - n);
58 r = detws_nts_ke_record(
true, Nts::NTS_KE_END_OF_MESSAGE,
nullptr, 0, out + n, cap - n);
65bool detws_nts_ke_parse(
const uint8_t *buf,
size_t len, DetwsNtsKeCb cb,
void *arg)
69 while (off + 4 <= len)
71 uint16_t tf = get_u16(buf + off);
72 uint16_t blen = get_u16(buf + off + 2);
73 bool critical = (tf & Nts::NTS_KE_CRITICAL) != 0;
74 uint16_t type = (uint16_t)(tf & 0x7FFF);
75 if (off + 4 + blen > len)
78 cb(critical, type, blen ? (buf + off + 4) : nullptr, blen, arg);
80 if (type == Nts::NTS_KE_END_OF_MESSAGE)
89size_t detws_nts_ef(uint16_t field_type,
const uint8_t *value,
size_t value_len, uint8_t *out,
size_t cap)
91 if (!out || (value_len && !value))
94 size_t total = 4 + value_len;
95 size_t padded = (total + 3) & ~(
size_t)3;
96 if (padded > 0xFFFF || padded > cap)
98 put_u16(out, field_type);
99 put_u16(out + 2, (uint16_t)padded);
101 memcpy(out + 4, value, value_len);
102 for (
size_t i = total; i < padded; i++)
107size_t detws_nts_ef_unique_id(
const uint8_t *nonce,
size_t nonce_len, uint8_t *out,
size_t cap)
109 return detws_nts_ef(NtsEf::NTS_EF_UNIQUE_IDENTIFIER, nonce, nonce_len, out, cap);
112size_t detws_nts_ef_cookie(
const uint8_t *cookie,
size_t cookie_len, uint8_t *out,
size_t cap)
114 return detws_nts_ef(NtsEf::NTS_EF_COOKIE, cookie, cookie_len, out, cap);
Network Time Security (NTS, RFC 8915) wire codec (DETWS_ENABLE_NTS).