File: nts.h

package info (click to toggle)
ntpsec 1.2.0%2Bdfsg1-4
  • links: PTS, VCS
  • area: main
  • in suites: bullseye
  • size: 10,044 kB
  • sloc: ansic: 60,737; python: 31,610; sh: 1,494; yacc: 1,291; makefile: 176; javascript: 138
file content (240 lines) | stat: -rw-r--r-- 6,993 bytes parent folder | download
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
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
/*
 * nts.h - NTS (Network Time Security) declarations
 * Copyright the NTPsec project contributors
 * SPDX-License-Identifier: BSD-2-Clause
 */

#ifndef GUARD_NTS_H
#define GUARD_NTS_H

#include <stdbool.h>
#include <stdint.h>

/* default file names */
#define NTS_CERT_FILE "/etc/ntpsec/cert-chain.pem"
#define NTS_KEY_FILE "/etc/ntpsec/key.pem"
#define NTS_COOKIE_KEY_FILE "/var/lib/ntpsec/nts-keys"

#define NTS_KE_PORT		4460
#define NTS_KE_PORTA		"4460"

#define NTS_KE_TIMEOUT		3

bool nts_server_init(void);
bool nts_client_init(void);
bool nts_cookie_init(void);
bool nts_server_init2(void);    /* after sandbox */
bool nts_cookie_init2(void);

void nts_cert_timer(void);
void nts_cookie_timer(void);

bool nts_read_cookie_keys(void);
void nts_make_cookie_key(void);
bool nts_write_cookie_keys(void);

int nts_make_cookie(uint8_t *cookie,
  uint16_t aead,
  uint8_t *c2s, uint8_t *s2c, int keylen);
bool nts_unpack_cookie(uint8_t *cookie, int cookielen,
  uint16_t *aead,
  uint8_t *c2s, uint8_t *s2c, int *keylen);

/* working finger into a buffer - updated by append/unpack routines */
struct BufCtl_t {
    uint8_t *next;  /* pointer to next data/space */
    int left;       /* data left or space available */
};
typedef struct BufCtl_t BufCtl;

bool nts_ke_process_receive(struct BufCtl_t *buf, int *aead);
bool nts_ke_setup_send(struct BufCtl_t *buf, int aead,
       uint8_t *c2s, uint8_t *s2c, int keylen);

/***********************************************************/

/* buffer packing/unpacking routines.
 * NB: The length field in NTP extensions includes the header
 * while the length field in NTS-KE data streams does not.
 *
 * These routines do not handle padding.  NTS-KE has no padding.
 * NTP extensions are padded to word (4 byte) boundaries.
 *
 * Note that data on the wire is big endian.
 * buffer is wire format, not host format.
 */


/* xxx_append_record_foo makes whole record with one foo */
/* append_foo appends foo to existing partial record */
void ke_append_record_null(BufCtl* buf, uint16_t type);
void ke_append_record_uint16(BufCtl* buf, uint16_t type, uint16_t data);
void ke_append_record_bytes(BufCtl* buf, uint16_t type, uint8_t *data, int length);

void ex_append_record_null(BufCtl* buf, uint16_t type);
void ex_append_record_uint16(BufCtl* buf, uint16_t type, uint16_t data);
void ex_append_record_bytes(BufCtl* buf, uint16_t type, uint8_t *data, int length);

void ex_append_header(BufCtl* buf, uint16_t type, uint16_t length);
void append_header(BufCtl* buf, uint16_t type, uint16_t length);
void append_uint16(BufCtl* buf, uint16_t data);
void append_bytes(BufCtl* buf, uint8_t *data, int length);

uint16_t ke_next_record(BufCtl* buf, int *length);
uint16_t ex_next_record(BufCtl* buf, int *length);  /* body length */
uint16_t next_uint16(BufCtl* buf);
uint16_t next_bytes(BufCtl* buf, uint8_t *data, int length);

/***********************************************************/

#define NTS_MAX_KEYLEN		64	/* used in cookies */
#define NTS_MAX_COOKIELEN	192	/* see nts_cookie.c */
#define NTS_MAX_COOKIES		8	/* RFC 4.1.6 */
#define NTS_UID_LENGTH		32	/* RFC 5.3 */
#define NTS_UID_MAX_LENGTH	64


/* Client side configuration data for an NTS association
 * All are optional.
 * part of peer struct */
struct ntscfg_t {
	char *ca;		/* root/trusted certificates */
	char *aead;		/* AEAD algorithms on wire */
};

/* Client-side state per connection to server */
struct ntsclient_t {
	/* wire connection */
	uint16_t aead;	/* AEAD algorithm used on wire */
	int keylen;
	uint8_t c2s[NTS_MAX_KEYLEN], s2c[NTS_MAX_KEYLEN];
	/* UID of last request sent - RFC 5.3 */
	uint8_t UID[NTS_UID_LENGTH];
	/* cookies */
	int readIdx, writeIdx;
	int count;			/* -1 if not in NTS mode */
	int cookielen;
	uint8_t cookies[NTS_MAX_COOKIES][NTS_MAX_COOKIELEN];
};

/* Server-side state per packet */
struct ntspacket_t {
	bool valid;
	int uidlen;
	uint8_t UID[NTS_UID_MAX_LENGTH];
	int needed;
	uint16_t aead;
	int keylen;
	uint8_t c2s[NTS_MAX_KEYLEN], s2c[NTS_MAX_KEYLEN];
};


/* Configuration data for an NTS server or client instance */
struct ntsconfig_t {
	bool ntsenable; 	/* enable NTS KE server on this ntpd */
	const char * mintls;	/* minimum TLS version allowed */
	const char * maxtls;	/* maximum TLS version allowed */
	const char *tlsciphersuites;/* allowed TLS 1.3 ciphersuites */
	const char *cert;	/* file holding server certificate key */
	const char *key;	/* file holding server private key */
	const char *KI;		/* file holding K/I for making cookies */
	const char *ca;		/* root cert dir/file */
	const char *aead;	/* AEAD algorithms on wire */
};


/* CMAC length is wired into AEAD_AES_SIV_CMAC_nnn. */
#define CMAC_LENGTH 16
/* The NONCE length comes from RFC 5116 and/or 5297. */
#define NONCE_LENGTH 16

/* NTS protocol constants */

#define NTS_CRITICAL 0x8000
enum nts_record_type {
	nts_end_of_message = 0,		/* CRITICAL */
	nts_next_protocol_negotiation = 1,	/* CRITICAL */
	nts_error = 2,			/* CRITICAL */
	nts_warning = 3,
	nts_algorithm_negotiation = 4,
	nts_new_cookie = 5,
	nts_server_negotiation = 6,
	nts_port_negotiation = 7
};

enum nts_protocol_type {
	nts_protocol_NTP = 0,
};


enum nts_errors_type {
	nts_unrecognized_critical_section = 0,
	nts_bad_request = 1
};

enum aead_ciphers {
#define NO_AEAD 0xffff
	AEAD_AES_128_GCM = 1,
	AEAD_AES_256_GCM = 2,
	AEAD_AES_128_CCM = 3,
	AEAD_AES_256_CCM = 4,

	AEAD_AES_128_GCM_8 = 5,
	AEAD_AES_256_GCM_8 = 6,
	AEAD_AES_128_GCM_12 = 7,
	AEAD_AES_256_GCM_12 = 8,

	AEAD_AES_128_CCM_SHORT = 9,
	AEAD_AES_256_CCM_SHORT = 10,
	AEAD_AES_128_CCM_SHORT_8 = 11,
	AEAD_AES_256_CCM_SHORT_8 = 12,
	AEAD_AES_128_CCM_SHORT_12 = 13,
	AEAD_AES_256_CCM_SHORT_12 = 14,

	AEAD_AES_SIV_CMAC_256 = 15,     /* RFC 5297 */
	AEAD_AES_SIV_CMAC_384 = 16,     /* These 3 are the ones we use */
	AEAD_AES_SIV_CMAC_512 = 17,
#define AEAD_AES_SIV_CMAC_256_KEYLEN 32
#define AEAD_AES_SIV_CMAC_384_KEYLEN 48
#define AEAD_AES_SIV_CMAC_512_KEYLEN 64

	AEAD_AES_128_CCM_8 = 18,
	AEAD_AES_256_CCM_8 = 19,

	AEAD_AES_128_OCB_TAGLEN128 = 20,
	AEAD_AES_128_OCB_TAGLEN96 = 21,
	AEAD_AES_128_OCB_TAGLEN64 = 22,
	AEAD_AES_192_OCB_TAGLEN128 = 23,
	AEAD_AES_192_OCB_TAGLEN96 = 24,
	AEAD_AES_192_OCB_TAGLEN64 = 25,
	AEAD_AES_256_OCB_TAGLEN128 = 26,
	AEAD_AES_256_OCB_TAGLEN96 = 27,
	AEAD_AES_256_OCB_TAGLEN64 = 28,

	AEAD_CHACHA20_POLY1305 = 29
};



extern struct ntsconfig_t ntsconfig;



/* NTS-related statistics visible via ntpq -c nts */
extern uint64_t nts_client_send;
extern uint64_t nts_client_recv_good;
extern uint64_t nts_client_recv_bad;
extern uint64_t nts_server_send;
extern uint64_t nts_server_recv_good;
extern uint64_t nts_server_recv_bad;
extern uint64_t nts_cookie_make;
extern uint64_t nts_cookie_decode;
extern uint64_t nts_cookie_decode_old;
extern uint64_t nts_cookie_decode_too_old;
extern uint64_t nts_cookie_decode_error;
extern uint64_t nts_ke_serves_good;
extern uint64_t nts_ke_serves_bad;
extern uint64_t nts_ke_probes_good;
extern uint64_t nts_ke_probes_bad;

#endif /* GUARD_NTS_H */