[Git][NTPsec/ntpsec][master] 3 commits: Updates to attic/cmac-timing and hmac-timing

Hal Murray (@hal.murray) gitlab at mg.gitlab.com
Mon Aug 31 19:04:36 UTC 2026



Hal Murray pushed to branch master at NTPsec / ntpsec


Commits:
b592318e by Hal Murray at 2026-08-23T21:36:08-07:00
Updates to attic/cmac-timing and hmac-timing

- - - - -
a9e243fe by Hal Murray at 2026-08-23T21:36:08-07:00
Update NetBSD part of buildprep to python 3.14

- - - - -
ccee7465 by Hal Murray at 2026-08-31T12:03:47-07:00
Fix for #896

- - - - -


5 changed files:

- attic/cmac-timing.c
- + attic/hmac-timing.c
- attic/wscript
- buildprep
- ntpd/ntp_config.c


Changes:

=====================================
attic/cmac-timing.c
=====================================
@@ -63,9 +63,9 @@ static void ssl_init(void)
 #if OPENSSL_VERSION_NUMBER > 0x20000000L && !defined(LIBRESSL_VERSION_NUMBER)
 	EVP_MAC *mac;
 #endif
-	ERR_load_crypto_strings();
-	OpenSSL_add_all_digests();
-	OpenSSL_add_all_ciphers();
+//	ERR_load_crypto_strings();
+//	OpenSSL_add_all_digests();
+//	OpenSSL_add_all_ciphers();
 	cmac = CMAC_CTX_new();
 #if OPENSSL_VERSION_NUMBER > 0x20000000L && !defined(LIBRESSL_VERSION_NUMBER)
 	mac = EVP_MAC_fetch(NULL, "cmac", NULL);
@@ -74,6 +74,7 @@ static void ssl_init(void)
 	evp = EVP_MAC_CTX_new(mac);
 	if (NULL == evp)
 		printf("## Oops, EVP_MAC_CTX_new() failed.\n");
+	EVP_MAC_free(mac);
 #endif
 }
 


=====================================
attic/hmac-timing.c
=====================================
@@ -0,0 +1,452 @@
+/*
+ * Copyright the NTPsec project contributors
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+/* Hack to time various implementations of HMAC.
+ *
+ * Build with: cc hmac-timing.c -o hmac-timing -lcrypto
+ *
+ * This is just the HMAC timing.
+ * It doesn't include the copy or compare or finding the right key.
+ *
+ * Beware of overflows in the timing computations.
+ *
+ * Disable AES-NI (Intel hardware: NI == New Instruction) with:
+ *    OPENSSL_ia32cap="~0x200000200000000"
+ * Check /proc/cpuinfo flags for "aes" to see if you have it.
+ */
+
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <time.h>
+#include <unistd.h>
+
+/* Silence warnings from CMAC routines in OpenSSL 3.0.0 */
+#define OPENSSL_SUPPRESS_DEPRECATED 1
+
+#include <openssl/opensslv.h>
+#include <openssl/err.h>
+#include <openssl/hmac.h>
+#include <openssl/ssl.h>
+#include <openssl/evp.h>
+#include <openssl/rand.h>
+#include <openssl/objects.h>
+#if OPENSSL_VERSION_NUMBER > 0x20000000L && !defined(LIBRESSL_VERSION_NUMBER)
+#include <openssl/params.h> 
+#endif
+
+#define UNUSED_ARG(arg)         ((void)(arg))
+
+#if OPENSSL_VERSION_NUMBER > 0x20000000L && !defined(LIBRESSL_VERSION_NUMBER)
+
+int SAMPLESIZE = 1000000;
+
+#define PACKET_LENGTH 48
+#define MAX_PACKET_LENGTH 4096
+#define MAX_KEY_LENGTH 64
+
+EVP_MAC_CTX *evp;
+
+unsigned char answer[EVP_MAX_MD_SIZE];
+
+static void ssl_init(void)
+{
+  EVP_MAC *mac;
+  mac = EVP_MAC_fetch(NULL, "hmac", NULL);
+  if (NULL == mac) {
+    printf("## Oops, EVP_MAC_fetch() failed.\n");
+    exit(1);
+  }
+  evp = EVP_MAC_CTX_new(mac);
+  if (NULL == evp) {
+    printf("## Oops, EVP_MAC_CTX_new() failed.\n");
+    exit(1);
+  }
+  EVP_MAC_free(mac);
+}
+
+
+static const EVP_MD *CheckDigest(const char *name) {
+  const EVP_MD *digest;
+  digest = EVP_get_digestbyname(name);
+  if (NULL == digest) {
+    /* no error available */
+    unsigned long err = ERR_get_error();
+    char *str = ERR_error_string(err, NULL);
+    printf("## Oops: EVP_get_digestbyname() failed: %s\n    %s\n", name, str);
+    return NULL;
+  }
+  return digest;
+}
+
+static void PrintHex(const unsigned char* bytes, int length) {
+  printf("  ");
+  for (int i=0; i<length; i++) {
+    if (16 == i) {
+      printf("...");  break;
+    }
+    printf("%02x", bytes[i]);
+  }
+}
+
+
+
+static size_t One_HMAC(
+  const EVP_MD *digest,     /* digest  */
+  uint8_t *key,             /* key pointer */
+  int     keylength,        /* key length */
+  uint8_t *pkt,             /* packet pointer */
+  int     pktlength         /* packet length */
+) {
+  unsigned int len = EVP_MAX_MD_SIZE;
+
+  if (0 == HMAC(digest,
+      key, keylength, pkt, pktlength, answer, &len)) {
+      unsigned long err = ERR_get_error();
+      char * str = ERR_error_string(err, NULL);
+      printf("## Oops, HMAC() failed: %s.\n", str);
+      return 0;
+    }
+    return len;
+}
+
+
+static void Do_HMAC(
+  const char *name,       /* name of digest */
+  uint8_t *key,           /* key pointer */
+  int     keylength,      /* key length */
+  uint8_t *pkt,           /* packet pointer */
+  int     pktlength       /* packet length */
+)
+{
+	const EVP_MD *digest = CheckDigest(name);
+	struct timespec start, stop;
+	double fast;
+	unsigned long digestlength = 0;
+	int samplesize = SAMPLESIZE;
+
+	if (NULL == digest) {
+		return;
+	}
+	if (pktlength > 1000) samplesize /= 10;
+
+	clock_gettime(CLOCK_MONOTONIC, &start);
+	for (int i = 0; i < samplesize; i++) {
+		digestlength = One_HMAC(digest, key, keylength, pkt, pktlength);
+		if (0 == digestlength) break;
+	}
+	clock_gettime(CLOCK_MONOTONIC, &stop);
+	fast = (stop.tv_sec-start.tv_sec)*1E9 + (stop.tv_nsec-start.tv_nsec);
+	printf("%12s  %2d %4d %2lu %6.0f %7.3f",
+	       name, keylength, pktlength, digestlength, fast/samplesize,  fast/1E9);
+	PrintHex(answer, digestlength);
+	printf("\n");
+}
+
+
+static size_t One_EVP_MAC(
+  EVP_MAC_CTX *ctx,         /* context  */
+  char *name,               /* name of cipher */
+  uint8_t *key,             /* key pointer */
+  int     keylength,        /* key length */
+  uint8_t *pkt,             /* packet pointer */
+  int     pktlength         /* packet length */
+) {
+	OSSL_PARAM params[2];
+	size_t len = EVP_MAX_MD_SIZE;
+
+	params[0] =
+          OSSL_PARAM_construct_utf8_string("digest", name, 0);
+	params[1] = OSSL_PARAM_construct_end();
+	if (0 == EVP_MAC_CTX_set_params(evp, params)) {
+		unsigned long err = ERR_get_error();
+		char * str = ERR_error_string(err, NULL);
+		printf("## Oops, EVP_MAC_CTX_set_params() failed: %s.\n", str);
+		return 0;
+	}
+	if (0 == EVP_MAC_init(ctx, key, keylength, NULL)) {
+		unsigned long err = ERR_get_error();
+		char * str = ERR_error_string(err, NULL);
+		printf("## Oops, EVP_MAC_init() failed: %s.\n", str);
+		return 0;
+	}
+	if (0 == EVP_MAC_update(ctx, pkt, pktlength)) {
+		unsigned long err = ERR_get_error();
+		char * str = ERR_error_string(err, NULL);
+		printf("## Oops, EVP_MAC_update() failed: %s.\n", str);
+		return 0;
+	}
+	if (0 == EVP_MAC_final(ctx, answer, &len, sizeof(answer))) {
+		unsigned long err = ERR_get_error();
+		char * str = ERR_error_string(err, NULL);
+		printf("## Oops, EVP_MAC_final() failed: %s.\n", str);
+		return 0;
+	}
+	return len;
+}
+
+
+static void Do_EVP_MAC(
+  const char *name,       /* name of digest */
+  uint8_t *key,           /* key pointer */
+  int     keylength,      /* key length */
+  uint8_t *pkt,           /* packet pointer */
+  int     pktlength       /* packet length */
+)
+{
+	const EVP_MD *digest = CheckDigest(name);
+	struct timespec start, stop;
+	double fast;
+	unsigned long digestlength = 0;
+	int samplesize = SAMPLESIZE;
+	char stupid[100];			/* OpenSSL rejects const */
+
+	if (NULL == digest) {
+		return;
+	}
+	if (pktlength > 1000) samplesize /= 10;
+	strncpy(stupid, name, sizeof(stupid));
+
+	clock_gettime(CLOCK_MONOTONIC, &start);
+	for (int i = 0; i < samplesize; i++) {
+		digestlength = One_EVP_MAC(evp, stupid, key, keylength, pkt, pktlength);
+		if (0 == digestlength) break;
+	}
+	clock_gettime(CLOCK_MONOTONIC, &stop);
+	fast = (stop.tv_sec-start.tv_sec)*1E9 + (stop.tv_nsec-start.tv_nsec);
+	printf("%12s  %2d %4d %2lu %6.0f %7.3f",
+	       name, keylength, pktlength, digestlength, fast/samplesize,  fast/1E9);
+	PrintHex(answer, digestlength);
+	printf("\n");
+}
+
+
+static size_t One_EVP_MAC2(
+  EVP_MAC_CTX *ctx,         /* context */
+  uint8_t *key,             /* key pointer */
+  int     keylength,        /* key length */
+  uint8_t *pkt,             /* packet pointer */
+  int     pktlength         /* packet length */
+) {
+	size_t len = EVP_MAX_MD_SIZE;
+
+	if (0 == EVP_MAC_init(ctx, key, keylength, NULL)) {
+		unsigned long err = ERR_get_error();
+		char * str = ERR_error_string(err, NULL);
+		printf("## Oops, EVP_MAC_init() failed: %s.\n", str);
+		return 0;
+	}
+	if (0 == EVP_MAC_update(ctx, pkt, pktlength)) {
+		unsigned long err = ERR_get_error();
+		char * str = ERR_error_string(err, NULL);
+		printf("## Oops, EVP_MAC_update() failed: %s.\n", str);
+		return 0;
+	}
+	if (0 == EVP_MAC_final(ctx, answer, &len, sizeof(answer))) {
+		unsigned long err = ERR_get_error();
+		char * str = ERR_error_string(err, NULL);
+		printf("## Oops, EVP_MAC_final() failed: %s.\n", str);
+		return 0;
+	}
+	return len;
+}
+
+
+static void Do_EVP_MAC2(
+  const char *name,       /* name of digest */
+  uint8_t *key,           /* key pointer */
+  int     keylength,      /* key length */
+  uint8_t *pkt,           /* packet pointer */
+  int     pktlength       /* packet length */
+)
+{
+	struct timespec start, stop;
+	double fast;
+	unsigned long digestlength = 0;
+	int samplesize = SAMPLESIZE;
+	const EVP_MD *digest = CheckDigest(name);
+	OSSL_PARAM params[2];
+	char stupid[100];			/* OpenSSL rejects const */
+
+	if (NULL == digest) {
+		return;
+	}
+	if (pktlength > 1000) samplesize /= 10;
+	strncpy(stupid, name, sizeof(stupid));
+
+	params[0] =
+          OSSL_PARAM_construct_utf8_string("digest", stupid, 0);
+	params[1] = OSSL_PARAM_construct_end();
+	if (0 == EVP_MAC_CTX_set_params(evp, params)) {
+		unsigned long err = ERR_get_error();
+		char * str = ERR_error_string(err, NULL);
+		printf("## Oops, EVP_MAC_CTX_set_params() failed: %s.\n", str);
+		return;
+	}
+
+	clock_gettime(CLOCK_MONOTONIC, &start);
+	for (int i = 0; i < samplesize; i++) {
+		digestlength = One_EVP_MAC2(evp, key, keylength, pkt, pktlength);
+if (0 == digestlength) break;
+	}
+	clock_gettime(CLOCK_MONOTONIC, &stop);
+	fast = (stop.tv_sec-start.tv_sec)*1E9 + (stop.tv_nsec-start.tv_nsec);
+	printf("%12s  %2d %4d %2lu %6.0f %7.3f",
+	       name, keylength, pktlength, digestlength, fast/samplesize,  fast/1E9);
+	PrintHex(answer, digestlength);
+	printf("\n");
+}
+
+
+static size_t One_EVP_MAC3(
+  EVP_MAC_CTX *ctx,         /* context  */
+  uint8_t *pkt,             /* packet pointer */
+  int     pktlength         /* packet length */
+) {
+	size_t len = EVP_MAX_MD_SIZE;
+
+	if (0 == EVP_MAC_init(ctx, NULL, 0, NULL)) {
+		unsigned long err = ERR_get_error();
+		char * str = ERR_error_string(err, NULL);
+		printf("## Oops, EVP_MAC_init() failed: %s.\n", str);
+		return 0;
+	}
+	if (0 == EVP_MAC_update(ctx, pkt, pktlength)) {
+		unsigned long err = ERR_get_error();
+		char * str = ERR_error_string(err, NULL);
+		printf("## Oops, EVP_MAC_update() failed: %s.\n", str);
+		return 0;
+	}
+	if (0 == EVP_MAC_final(ctx, answer, &len, sizeof(answer))) {
+		unsigned long err = ERR_get_error();
+		char * str = ERR_error_string(err, NULL);
+		printf("## Oops, EVP_MAC_final() failed: %s.\n", str);
+		return 0;
+	}
+	return len;
+}
+
+
+static void Do_EVP_MAC3(
+  const char *name,       /* name of cipher */
+  uint8_t *key,           /* key pointer */
+  int     keylength,      /* key length */
+  uint8_t *pkt,           /* packet pointer */
+  int     pktlength       /* packet length */
+)
+{
+	struct timespec start, stop;
+	double fast;
+	unsigned long digestlength = 0;
+	int samplesize = SAMPLESIZE;
+	const EVP_MD *digest = CheckDigest(name);
+	OSSL_PARAM params[3];
+	char stupid[100];			/* OpenSSL rejects const */
+
+	if (NULL == digest) {
+		return;
+	}
+	if (pktlength > 1000) samplesize /= 10;
+	strncpy(stupid, name, sizeof(stupid));
+
+	params[0] =
+          OSSL_PARAM_construct_utf8_string("digest", stupid, 0);
+	params[1] =
+          OSSL_PARAM_construct_octet_string("key", key, keylength);
+	params[2] = OSSL_PARAM_construct_end();
+	if (0 == EVP_MAC_CTX_set_params(evp, params)) {
+		unsigned long err = ERR_get_error();
+		char * str = ERR_error_string(err, NULL);
+		printf("## Oops, EVP_MAC_CTX_set_params() failed: %s.\n", str);
+		return;
+	}
+
+	clock_gettime(CLOCK_MONOTONIC, &start);
+	for (int i = 0; i < samplesize; i++) {
+		digestlength = One_EVP_MAC3(evp, pkt, pktlength);
+if (0 == digestlength) break;
+	}
+	clock_gettime(CLOCK_MONOTONIC, &stop);
+	fast = (stop.tv_sec-start.tv_sec)*1E9 + (stop.tv_nsec-start.tv_nsec);
+	printf("%12s  %2d %4d %2lu %6.0f %7.3f",
+	       name, keylength, pktlength, digestlength, fast/samplesize,  fast/1E9);
+	PrintHex(answer, digestlength);
+	printf("\n");
+}
+
+int main(int argc, char *argv[])
+{
+	uint8_t key[MAX_KEY_LENGTH];
+	uint8_t packet[MAX_PACKET_LENGTH];
+	char buff[256];
+	char *ctimetxt;
+	time_t now;
+
+	UNUSED_ARG(argc);
+	UNUSED_ARG(argv);
+
+	setlinebuf(stdout);
+
+	ssl_init();
+	RAND_bytes((unsigned char *)&key, MAX_KEY_LENGTH);
+	RAND_bytes((unsigned char *)&packet, MAX_PACKET_LENGTH);
+	/* make things deterministic */
+	for (int i=0; i< MAX_KEY_LENGTH; i++) key[i]=i*i+0x23;
+	for (int i=0; i< MAX_PACKET_LENGTH; i++) packet[i]=i*i+0x31;
+
+	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("# KL=key length, PL=packet length, HL=HMAC length\n");
+	printf("# HMAC        KL   PL HL  ns/op sec/run\n");
+
+	Do_HMAC("SHA256",       key, 16, packet, PACKET_LENGTH);
+	Do_HMAC("SHA256",       key, 20, packet, PACKET_LENGTH);
+	Do_HMAC("SHA384",       key, 20, packet, PACKET_LENGTH);
+	Do_HMAC("SHA512",       key, 20, packet, PACKET_LENGTH);
+
+	printf("\n");
+	printf("# KL=key length, PL=packet length, HL=HMAC length\n");
+	printf("# EVP_MAC     KL   PL HL  ns/op sec/run\n");
+
+	Do_EVP_MAC("SHA256",    key, 16, packet, PACKET_LENGTH);
+	Do_EVP_MAC("SHA256",    key, 20, packet, PACKET_LENGTH);
+	Do_EVP_MAC("SHA384",    key, 20, packet, PACKET_LENGTH);
+	Do_EVP_MAC("SHA512",    key, 20, packet, PACKET_LENGTH);
+
+	printf("\n");
+	printf("EVP_MAC Preload cipher.\n");
+	Do_EVP_MAC2("SHA256",   key, 16, packet, PACKET_LENGTH);
+	Do_EVP_MAC2("SHA256",   key, 20, packet, PACKET_LENGTH);
+	Do_EVP_MAC2("SHA384",   key, 20, packet, PACKET_LENGTH);
+	Do_EVP_MAC2("SHA512",   key, 20, packet, PACKET_LENGTH);
+
+	printf("\n");
+	printf("EVP_MAC Preload cipher and key.\n");
+	Do_EVP_MAC3("SHA256",   key, 16, packet, PACKET_LENGTH);
+	Do_EVP_MAC3("SHA256",   key, 20, packet, PACKET_LENGTH);
+	Do_EVP_MAC3("SHA384",   key, 20, packet, PACKET_LENGTH);
+	Do_EVP_MAC3("SHA512",   key, 20, packet, PACKET_LENGTH);
+
+	return 0;
+}
+#else
+int main(int argc, char *argv[])
+{
+        UNUSED_ARG(argc);
+        UNUSED_ARG(argv);
+        printf("This program doesn't work on really old versions of OpenSSL\n");
+        return 1; 
+}
+#endif  // OPENSSL_VERSION_NUMBER
+


=====================================
attic/wscript
=====================================
@@ -6,8 +6,9 @@ def build(ctx):
     util = [    'sht',
                 'digest-find', 'cipher-find',
                 'clocks', "random",
-                'digest-timing', 'cmac-timing', 'exp-timing', 'sign-timing',
-		'timestamp-info',
+                'digest-timing', 'cmac-timing', 'hmac-timing',
+                'exp-timing', 'sign-timing',
+                'timestamp-info',
                 'backwards']
 
     if not ctx.env.DISABLE_NTS:


=====================================
buildprep
=====================================
@@ -201,23 +201,23 @@ daemon () {
 	    ;;
 	pkgin)
 	    # NetBSD
-	    #  There is nothing magic about 3.7.
-	    #  In Dec 2018, 3.6 and 2.7 are also good candidates.
-	    $install bison python37 py37-curses-3.7
+	    #  There is nothing magic about 3.14
+	    #  In Aug 2026, 3.14 was the latest available
+	    $install bison python314
 	    # certificates for NTS
 	    $install mozilla-rootcerts mozilla-rootcerts-openssl
 	    # Also needs "nts ca /etc/openssl/certs/"
 	    # setup "python" from command line
-	    $do ln -s /usr/pkg/bin/python3.7 /usr/pkg/bin/python
-	    $do ln -s /usr/pkg/bin/python3.7 /usr/pkg/bin/python3
+	    $do ln -s /usr/pkg/bin/python3.14 /usr/pkg/bin/python
+	    $do ln -s /usr/pkg/bin/python3.14 /usr/pkg/bin/python3
 	    # Add to Python search path
 	    if [ "$DRYRUN" = "yes" ]
             then
-		echo echo /usr/local/lib/python3.7/site-packages \> \\
-		echo "  " /usr/pkg/lib/python3.7/site-packages/ntpsec.pth
+		echo echo /usr/local/lib/python3.14/site-packages \> \\
+		echo "  " /usr/pkg/lib/python3.14/site-packages/ntpsec.pth
 	    else
-		echo /usr/local/lib/python3.7/site-packages > \
-			/usr/pkg/lib/python3.7/site-packages/ntpsec.pth
+		echo /usr/local/lib/python3.14/site-packages > \
+			/usr/pkg/lib/python3.14/site-packages/ntpsec.pth
 	    fi
 	    echo "Last tested a long time ago"
 	    ;;


=====================================
ntpd/ntp_config.c
=====================================
@@ -687,7 +687,7 @@ create_peer_node(
 			break;
 
 		case T_Key:
-			if (option->value.u >= NTP_MAXKEY) {
+			if (option->value.u > NTP_MAXKEY) {
 				msyslog(LOG_ERR, "CONFIG: key: invalid argument");
 				errflag = true;
 			} else {



View it on GitLab: https://gitlab.com/NTPsec/ntpsec/-/compare/9e79f1923b0e53e694767b7ea3e7dfbf36d2e028...ccee7465b6e0717ca2e1ed14d6342a2c5c9c7c76

-- 
View it on GitLab: https://gitlab.com/NTPsec/ntpsec/-/compare/9e79f1923b0e53e694767b7ea3e7dfbf36d2e028...ccee7465b6e0717ca2e1ed14d6342a2c5c9c7c76
You're receiving this email because of your account on gitlab.com. Manage all notifications: https://gitlab.com/-/profile/notifications | Help: https://gitlab.com/help


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


More information about the vc mailing list