[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