[Git][NTPsec/ntpsec][master] 2 commits: clears STA_UNSYNC on start (fix #848)

Hal Murray (@hal.murray) gitlab at mg.gitlab.com
Wed Apr 30 23:06:01 UTC 2025



Hal Murray pushed to branch master at NTPsec / ntpsec


Commits:
fe098d00 by Hal Murray at 2025-04-30T00:08:34-07:00
clears STA_UNSYNC on start (fix #848)

- - - - -
3c42d068 by Hal Murray at 2025-04-30T00:26:13-07:00
Add attic/aead-timing.c

- - - - -


3 changed files:

- + attic/aead-timing.c
- attic/wscript
- ntpd/ntp_loopfilter.c


Changes:

=====================================
attic/aead-timing.c
=====================================
@@ -0,0 +1,496 @@
+/*
+ * Copyright the NTPsec project contributors
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+/*
+ * Hack to time aead routines
+ *
+ * We use it in 6 places, 3 pairs of encrypt/decrypt
+ *   cookies
+ *   client to server
+ *   server to client
+ *
+ *   This code is the minimal code to get timing of the crypto functions
+ *   so we can compare libaes_siv with OpenSSL
+ *   Then round up so we can test things.
+ *
+ *   For cookies, there are 2 key lengths involved:
+ *     the length of the keys inside the cookie: c2s and s2c
+ *     the length of the key used to make the cookie
+ *
+ * RFC5297, October 2008
+ * Synthetic Initialization Vector (SIV) Authenticated Encryption
+ *           Using the Advanced Encryption Standard (AES)
+ *
+ */
+
+#include <assert.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <time.h>
+#include <unistd.h>
+
+#include <openssl/ssl.h>
+#include <openssl/err.h>
+#include <openssl/rand.h>
+#include "aes_siv.h"
+
+#define UNUSED_ARG(arg)         ((void)(arg))
+#define INSIST(x)       assert(x)
+
+#if OPENSSL_VERSION_NUMBER > 0x20000000L
+
+int samplesize = 1000000;
+
+/* Some copied from nts.h */
+#define AEAD_AES_SIV_CMAC_256 15
+#define AEAD_AES_SIV_CMAC_384 16
+#define 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
+#define NTS_MAX_KEYLEN 64
+#define NTS_MAX_COOKIELEN 192
+#define NONCE_LENGTH 16
+#define AD_LENGTH 20
+#define AEAD_LENGTH 4
+#define TAG_LENGTH 16
+
+AES_SIV_CTX* lib_ctx;
+EVP_CIPHER_CTX *ssl_ctx;
+
+uint32_t key_I = 12345;  /* keep 4 byte alignment */
+uint32_t aead = 54321;
+uint8_t nonce[NONCE_LENGTH];
+uint8_t key[NTS_MAX_KEYLEN];
+uint8_t c2s[NTS_MAX_KEYLEN];
+uint8_t s2c[NTS_MAX_KEYLEN];
+
+uint8_t cookie[NTS_MAX_COOKIELEN];
+uint8_t cookie2[NTS_MAX_COOKIELEN];
+int cookielen;
+uint32_t key_I_out;
+uint8_t nonce_out[NONCE_LENGTH];
+uint32_t aead_out;
+uint8_t c2s_out[NTS_MAX_KEYLEN];
+uint8_t s2c_out[NTS_MAX_KEYLEN];
+
+static void nts_log_ssl_error(void);
+
+static void CookieEncryptLib(int cookie_keylen, int wire_keylen, const char* name) {
+        uint8_t plaintext[NTS_MAX_COOKIELEN];
+        int used, plainlength;
+        uint8_t * finger;
+        size_t left;
+        struct timespec start, stop;
+        double fast;
+
+	memset(cookie, 0, sizeof(cookie));
+
+        finger = plaintext;
+        memcpy(finger, &aead, sizeof(aead));
+        finger += sizeof(aead);
+        memcpy(finger, c2s, wire_keylen);
+        finger += wire_keylen;
+        memcpy(finger, s2c, wire_keylen);
+        finger += wire_keylen;
+        plainlength = finger-plaintext;
+
+        /* collect associated data */
+        finger = cookie;
+
+        memcpy(finger, &key_I, sizeof(key_I));
+        finger += sizeof(key_I);
+
+        memcpy(finger, nonce, NONCE_LENGTH);
+        finger += NONCE_LENGTH;
+
+        used = finger-cookie;
+        left = sizeof(cookie)-used;
+
+        clock_gettime(CLOCK_MONOTONIC, &start);
+        for (int i = 0; i < samplesize; i++) {
+            bool ok;
+            left = sizeof(cookie)-used;
+	    ok = AES_SIV_Encrypt(lib_ctx,
+		/* left: in: max out length, out: length used */
+		finger, &left,
+		key, cookie_keylen,
+		nonce, NONCE_LENGTH,
+		plaintext, plainlength,
+		cookie, AD_LENGTH);
+            if (!ok) {
+                printf("CookieEncryptLib: Error from AES_SIV_Encrypt\n");
+                exit(1);
+            }
+        }
+        clock_gettime(CLOCK_MONOTONIC, &stop);
+        used += left;
+	cookielen = used;
+        INSIST(used <= NTS_MAX_COOKIELEN);
+        fast = (stop.tv_sec-start.tv_sec)*1E9 + (stop.tv_nsec-start.tv_nsec);
+        printf("LIB Encrypt  %3d %3d %3d %6.0f %7.3f  %s\n",
+               cookie_keylen, wire_keylen, used, fast/samplesize,  fast/1E9, name);
+}
+
+
+static void CookieDecryptLib(int cookie_keylen, int wire_keylen) {
+        uint8_t plaintext[NTS_MAX_COOKIELEN];
+        int used;
+        size_t  plainlength, cipherlength;
+        uint8_t * finger;
+        uint8_t * mynonce;
+        struct timespec start, stop;
+        double fast;
+
+        /* associated data */
+        finger = cookie;
+        memcpy(&key_I_out, finger, sizeof(key_I_out));
+        finger += sizeof(key_I_out);
+	mynonce = finger;
+        memcpy(nonce_out, mynonce, NONCE_LENGTH);
+        finger += NONCE_LENGTH;
+
+        used = finger-cookie;
+
+        cipherlength = cookielen - AD_LENGTH;
+        plainlength = NTS_MAX_COOKIELEN;
+
+        clock_gettime(CLOCK_MONOTONIC, &start);
+        for (int i = 0; i < samplesize; i++) {
+            bool ok;
+            plainlength = NTS_MAX_COOKIELEN;  /* Gets updated in loop */
+	    ok = AES_SIV_Decrypt(lib_ctx,
+		/* plainlength: in: max out length, out: length used */
+		plaintext, &plainlength,
+		key, cookie_keylen,
+		mynonce, NONCE_LENGTH,
+		finger, cipherlength,
+		cookie, AD_LENGTH);
+            if (!ok) {
+                printf("CookieDecryptLib: Error from AES_SIV_Decrypt\n");
+                exit(1);
+            }
+        }
+        clock_gettime(CLOCK_MONOTONIC, &stop);
+	used += plainlength;
+	used += TAG_LENGTH;
+        INSIST(used <= NTS_MAX_COOKIELEN);
+        fast = (stop.tv_sec-start.tv_sec)*1E9 + (stop.tv_nsec-start.tv_nsec);
+        printf("LIB Decrypt  %3d %3d %3d %6.0f %7.3f\n",
+               cookie_keylen, wire_keylen, used, fast/samplesize,  fast/1E9);
+
+        finger = plaintext;
+        memcpy(&aead_out, finger, sizeof(aead_out));
+        finger += sizeof(aead);
+        memcpy(c2s_out, finger, wire_keylen);
+        finger += wire_keylen;
+        memcpy(s2c_out, finger, wire_keylen);
+        finger += wire_keylen;
+}
+
+
+static void CookieCheck(int length, int wire_keylen) {
+
+  if (length != cookielen)
+    printf("Length mismatch: %d, %d\n", length, cookielen);
+  if (key_I != key_I_out)
+    printf("key_I mismatch: %u, %u\n", key_I, key_I_out);
+  if (memcmp(nonce, nonce_out, NONCE_LENGTH))
+    printf("nonce mismatch\n");
+
+/* Encryypted stuff */
+  if (aead != aead_out)
+    printf("aead mismatch: %u, %u\n", aead, aead_out);
+  if (memcmp(c2s, c2s_out, wire_keylen))
+    printf("c2s, mismatch\n");
+  if (memcmp(s2c, s2c_out, wire_keylen))
+    printf("s2c, mismatch\n");
+
+}
+
+
+static void CookieCompare(int length) {
+  uint32_t *c1 = (uint32_t*)cookie;
+  uint32_t *c2 = (uint32_t*)cookie2;
+
+  if (0 == memcmp(cookie, cookie2, length)) return;
+
+  for (int i = 0; i*4 < length+8; i++) {
+    printf("%3d: %08x %08x\n", i*4, c1[i], c2[i]);
+  }
+
+}
+
+static void CookieEncryptSSL(int cookie_keylen, int wire_keylen, const char* name) {
+	const EVP_CIPHER *cipher;
+        uint8_t plaintext[NTS_MAX_COOKIELEN];
+        int used, plainlength;
+        uint8_t * finger;
+        uint8_t * tag;
+        int left, adlen;
+        struct timespec start, stop;
+        double fast;
+
+	memset(cookie, 0, sizeof(cookie));
+
+	cipher = EVP_CIPHER_fetch(NULL, name, NULL);
+	if (NULL==cipher) {
+		/* This happens on a FIPS box. */
+		printf("CookieEncryptSSL: Can't find cipher %s.\n", name);
+		exit(1);
+	}
+        finger = plaintext;
+        memcpy(finger, &aead, sizeof(aead));
+        finger += sizeof(aead);
+        memcpy(finger, c2s, wire_keylen);
+        finger += wire_keylen;
+        memcpy(finger, s2c, wire_keylen);
+        finger += wire_keylen;
+        plainlength = finger-plaintext;
+
+        /* collect associated data */
+        finger = cookie;
+        memcpy(finger, &key_I, sizeof(key_I));
+        finger += sizeof(key_I);
+        memcpy(finger, nonce, NONCE_LENGTH);
+        finger += NONCE_LENGTH;
+	adlen = finger-cookie;
+
+	tag = finger;                  /* prepend tag */
+	finger += TAG_LENGTH;
+
+        used = finger-cookie;
+        left = sizeof(cookie)-used;
+
+        clock_gettime(CLOCK_MONOTONIC, &start);
+        for (int i = 0; i < samplesize; i++) {
+            used = finger-cookie;
+            left = sizeof(cookie)-used;
+	    /* FIXME: move cipher init out of loop */
+            if(1 != EVP_EncryptInit_ex2(ssl_ctx, cipher, key, NULL, NULL)) {
+                printf("CookieEncryptSSL: Error from EVP_EncryptInit_ex2\n");
+                exit(1);
+            }
+            if(1 != EVP_EncryptUpdate(ssl_ctx, NULL, &left, cookie, adlen)) {
+                printf("CookieEncryptSSL: EVP_EncryptUpdate--AD\n");
+                exit(1);
+            }
+	    /* bug in real cookie code: nonce used twice */
+            left = sizeof(cookie)-used;
+            if(1 != EVP_EncryptUpdate(ssl_ctx, NULL, &left, nonce, NONCE_LENGTH)) {
+                printf("CookieEncryptSSL: EVP_EncryptUpdate--nonce\n");
+                exit(1);
+            }
+            left = sizeof(cookie)-used;
+            if(1 != EVP_EncryptUpdate(ssl_ctx, finger, &left, plaintext, plainlength)) {
+                printf("CookieEncryptSSL: EVP_EncryptUpdate--AEAD\n");
+                exit(1);
+            }
+	    used += left;
+            if(1 != EVP_EncryptFinal_ex(ssl_ctx, finger+used, &left)) {
+                printf("CookieEncryptSSL: EVP_EncryptFinal_ex\n");
+                exit(1);
+            }
+            if(1 != EVP_CIPHER_CTX_ctrl(ssl_ctx, EVP_CTRL_AEAD_GET_TAG, 16, tag)) {
+                printf("CookieEncryptSSL: EVP_CIPHER_CTX_ctrl\n");
+                exit(1);
+            }
+        }
+        clock_gettime(CLOCK_MONOTONIC, &stop);
+        used += left;
+	cookielen = used;
+        INSIST(used <= NTS_MAX_COOKIELEN);
+        fast = (stop.tv_sec-start.tv_sec)*1E9 + (stop.tv_nsec-start.tv_nsec);
+        printf("SSL Encrypt  %3d %3d %3d %6.0f %7.3f  %s\n",
+               cookie_keylen, wire_keylen, used, fast/samplesize,  fast/1E9, name);
+}
+
+static void CookieDecryptSSL(int cookie_keylen, int wire_keylen, const char* name) {
+        const EVP_CIPHER *cipher;
+        uint8_t plaintext[NTS_MAX_COOKIELEN];
+        int used, left;
+        size_t  cipherlength;
+        uint8_t * finger;
+        uint8_t * tag;
+        uint8_t * mynonce;
+        struct timespec start, stop;
+        double fast;
+
+        cipher = EVP_CIPHER_fetch(NULL, name, NULL);
+        if (NULL==cipher) {
+                /* This happens on a FIPS box. */
+                printf("CookieDecryptSSL: Can't find cipheri %s.\n", name);
+                exit(1);
+        }
+
+        /* associated data */
+        finger = cookie;
+        memcpy(&key_I_out, finger, sizeof(key_I_out));
+        finger += sizeof(key_I_out);
+	mynonce = finger;
+        memcpy(nonce_out, mynonce, NONCE_LENGTH);
+        finger += NONCE_LENGTH;
+	tag = finger;
+	finger += TAG_LENGTH;
+
+        used = finger-cookie;
+        left = sizeof(cookie)-used;
+
+	cipherlength = cookielen -AD_LENGTH -TAG_LENGTH;
+
+        clock_gettime(CLOCK_MONOTONIC, &start);
+        for (int i = 0; i < samplesize; i++) {
+            used = finger-cookie;
+            left = sizeof(cookie)-used;
+            /* FIXME: move cipher init out of loop */
+            if(1 != EVP_DecryptInit_ex2(ssl_ctx, cipher, key, NULL, NULL)) {
+                printf("CookieDecryptSSL: Error from EVP_DecryptInit_ex2\n");
+                exit(1);
+            }
+            if(1 != EVP_CIPHER_CTX_ctrl(ssl_ctx, EVP_CTRL_AEAD_SET_TAG, 16, tag)) {
+                printf("CookieDencryptSSL: EVP_CIPHER_CTX_ctrl\n");
+                exit(1);
+            }
+            left = sizeof(cookie)-used;
+            if(1 != EVP_DecryptUpdate(ssl_ctx, NULL, &left, cookie, AD_LENGTH)) {
+                printf("CookieDecryptSSL: EVP_DecryptUpdate--AD\n");
+                exit(1);
+            }
+            /* bug in real cookie code: nonce used twice */
+            if(1 != EVP_DecryptUpdate(ssl_ctx, NULL, &left, mynonce, NONCE_LENGTH)) {
+                printf("CookieDecryptSSL: EVP_DecryptUpdate--nonce\n");
+                exit(1);
+            }
+            left = sizeof(plaintext);
+            if(1 != EVP_DecryptUpdate(ssl_ctx, plaintext, &left, finger, cipherlength)) {
+                printf("CookieDecryptSSL: EVP_DecryptUpdate--AEAD\n");
+		nts_log_ssl_error();
+                exit(1);
+            }
+            used += left;
+            left = sizeof(cookie)-used;
+            if(1 != EVP_DecryptFinal_ex(ssl_ctx, finger+used, &left)) {
+                printf("CookieDecryptSSL: EVP_DecryptFinal_ex\n");
+                exit(1);
+            }
+            left = sizeof(cookie)-used;
+        }
+        clock_gettime(CLOCK_MONOTONIC, &stop);
+        INSIST(used <= NTS_MAX_COOKIELEN);
+        fast = (stop.tv_sec-start.tv_sec)*1E9 + (stop.tv_nsec-start.tv_nsec);
+        printf("SSL Decrypt  %3d %3d %3d %6.0f %7.3f\n",
+               cookie_keylen, wire_keylen, used, fast/samplesize,  fast/1E9);
+
+        finger = plaintext;
+        memcpy(&aead_out, finger, sizeof(aead_out));
+        finger += sizeof(aead);
+        memcpy(c2s_out, finger, wire_keylen);
+        finger += wire_keylen;
+        memcpy(s2c_out, finger, wire_keylen);
+        finger += wire_keylen;
+}
+
+static void nts_log_ssl_error(void) {
+        char buff[256];
+        int err = ERR_get_error();
+        SSL_load_error_strings();        /* Needed on NetBSD */
+        while (0 != err) {
+                ERR_error_string_n(err, buff, sizeof(buff));
+                printf("NTS err: %s\n", buff);
+                err = ERR_get_error();
+        }
+}
+
+
+int main(int argc, char *argv[])
+{
+	char *ctimetxt;
+	time_t now;
+	char buff[256];
+
+	UNUSED_ARG(argc);
+	UNUSED_ARG(argv);
+
+	setlinebuf(stdout);
+
+        lib_ctx = AES_SIV_CTX_new();
+        ssl_ctx = EVP_CIPHER_CTX_new();
+	nts_log_ssl_error();
+
+        RAND_bytes(nonce, NONCE_LENGTH);
+        RAND_bytes(key, NTS_MAX_KEYLEN);
+        RAND_bytes(c2s, NTS_MAX_KEYLEN);
+        RAND_bytes(s2c, NTS_MAX_KEYLEN);
+
+	now = time(NULL);
+	ctimetxt = ctime(&now);
+	ctimetxt[24] = 0;	/* Hack: smash return */
+	gethostname(buff, sizeof(buff));
+	printf("# %s on %s\n", ctimetxt, buff);
+	printf("# %s\n", OPENSSL_VERSION_TEXT);
+	printf("\n");
+
+	printf("#     cKL=cookieKeyLen, wKL=wireKeyLen, CL=cookieLen\n");
+	printf("#            cKL wKL  CL  ns/op sec/run  Cookie Alg\n");
+
+	/* 1st arg is length of cookie key */
+	/* 2nd arg is length of c2s and s2c */
+
+	/* AES-128-SIV, RFC 5297 */
+	/* default minimal lengths */
+	CookieEncryptLib(32, 32, "AES_SIV_CMAC_256");
+	CookieDecryptLib(32, 32);
+	CookieCheck(104, 32);
+	memcpy(cookie2, cookie, NTS_MAX_COOKIELEN);
+	CookieEncryptSSL(32, 32, "AES-128-SIV");
+	CookieCompare(104);
+	CookieDecryptSSL(32, 32, "AES-128-SIV");
+	CookieCheck(104, 32);
+	printf("\n");
+
+	/* longer cookie key, same size cookie */
+	CookieEncryptLib(64, 32, "AES_SIV_CMAC_512");
+	CookieDecryptLib(64, 32);
+	CookieCheck(104, 32);
+	memcpy(cookie2, cookie, NTS_MAX_COOKIELEN);
+	CookieEncryptSSL(64, 32, "AES-256-SIV");
+	CookieCompare(104);
+	CookieDecryptSSL(64, 32, "AES-256-SIV");
+	CookieCheck(104, 32);
+	printf("\n");
+
+	/* Longer wire key, bigger cookie */
+	CookieEncryptLib(32, 64, "AES_SIV_CMAC_256");
+	CookieDecryptLib(32, 64);
+	CookieCheck(168, 32);
+	memcpy(cookie2, cookie, NTS_MAX_COOKIELEN);
+	CookieEncryptSSL(32, 64, "AES-128-SIV");
+	CookieCompare(168);
+	CookieDecryptSSL(32, 64, "AES-128-SIV");
+	CookieCheck(168, 64);
+	printf("\n");
+
+	/* AES-128-GCM-SIV, RFC 8452 */
+	/* FIXME: need to set ??? length */
+	CookieEncryptSSL(16, 32, "AES-128-GCM-SIV");
+	CookieDecryptSSL(16, 32, "AES-128-GCM-SIV");
+	CookieCheck(104, 32);
+	CookieEncryptSSL(32, 32, "AES-256-GCM-SIV");
+	CookieDecryptSSL(32, 32, "AES-256-GCM-SIV");
+	CookieCheck(104, 32);
+
+	return 0;
+}
+#else
+int main(int argc, char *argv[])
+{
+	UNUSED_ARG(argc);
+	UNUSED_ARG(argv);
+	return 1;
+}
+#endif  // OPENSSL_VERSION_NUMBER


=====================================
attic/wscript
=====================================
@@ -12,6 +12,7 @@ def build(ctx):
 
     if not ctx.env.DISABLE_NTS:
         util.append('aes-siv-timing')
+        util.append('aead-timing')
 
     for name in util:
         ctx(


=====================================
ntpd/ntp_loopfilter.c
=====================================
@@ -1049,9 +1049,9 @@ start_kern_loop(void)
 	clock_ctl.pll_control = true;
 	ZERO(ntv);
 	ntv.modes = MOD_BITS;
-	ntv.status = STA_PLL;
-	ntv.maxerror = sys_maxdisp;
-	ntv.esterror = sys_maxdisp;
+	ntv.status = STA_PLL | STA_UNSYNC;
+	ntv.maxerror = sys_maxdisp * 1e6;
+	ntv.esterror = sys_maxdisp * 1e6;
 	ntv.constant = clkstate.sys_poll;
 	if ((ntp_adj_ret = ntp_adjtime_ns(&ntv)) != 0) {
 	    ntp_adjtime_error_handler(__func__, &ntv, ntp_adj_ret, errno, false, false, __LINE__ - 1);



View it on GitLab: https://gitlab.com/NTPsec/ntpsec/-/compare/977382e7632e4f893de654d3663f32b1b2d55ded...3c42d068b51a4c859e0299fadd6f3970572c4da6

-- 
View it on GitLab: https://gitlab.com/NTPsec/ntpsec/-/compare/977382e7632e4f893de654d3663f32b1b2d55ded...3c42d068b51a4c859e0299fadd6f3970572c4da6
You're receiving this email because of your account on gitlab.com.


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.ntpsec.org/pipermail/vc/attachments/20250430/4b97bb87/attachment-0001.htm>


More information about the vc mailing list