From: Dave Hart Date: Mon, 5 Jun 2023 00:21:10 +0000 (+0000) Subject: Add tests for loading and using all supported symmetric auth digests. X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=0c396ac816b92489bc4ea8efe226d1e1640792d1;p=thirdparty%2Fntp.git Add tests for loading and using all supported symmetric auth digests. bk: 647d2a76ypF1ZRxI9WVG7YusJXspdQ --- diff --git a/ChangeLog b/ChangeLog index 36137ffc2..39703092a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -2,6 +2,8 @@ * [Bug 3821] 4.2.8p16 misreads hex authentication keys, won't interop with 4.2.8p15. Reported by Matt Nordhoff, thanks to Miroslav Lichvar and Matt for rapid testing narrowing the problem. +* Add tests/libntp/digests.c to catch regressions reading keys file or with + symmetric authentication digest output. --- (4.2.8p16) 2023/05/31 Released by Harlan Stenn diff --git a/include/ntp.h b/include/ntp.h index c037f5986..258ddd613 100644 --- a/include/ntp.h +++ b/include/ntp.h @@ -134,7 +134,7 @@ typedef char s_char; * Miscellaneous stuff */ #define NTP_MAXKEY 65535 /* max authentication key number */ -#define KEY_TYPE_MD5 NID_md5 /* MD5 digest NID */ + /* * Limits of things */ diff --git a/include/ntp_md5.h b/include/ntp_md5.h index 06c90b2d2..8b5a7d0cb 100644 --- a/include/ntp_md5.h +++ b/include/ntp_md5.h @@ -6,6 +6,8 @@ #ifndef NTP_MD5_H #define NTP_MD5_H +# define KEY_TYPE_MD5 NID_md5 + #ifdef OPENSSL # include # include "libssl_compat.h" @@ -30,6 +32,8 @@ typedef MD5_CTX EVP_MD_CTX; +# define NID_md5 4 /* from openssl/objects.h */ +# define EVP_MAX_MD_SIZE 64 /* from openssl/evp.h */ # define EVP_MD_CTX_free(c) free(c) # define EVP_MD_CTX_new() calloc(1, sizeof(MD5_CTX)) # define EVP_get_digestbynid(t) NULL diff --git a/include/ntp_stdlib.h b/include/ntp_stdlib.h index 2d7c64056..446837e3a 100644 --- a/include/ntp_stdlib.h +++ b/include/ntp_stdlib.h @@ -11,6 +11,7 @@ #include "declcond.h" /* ntpd uses ntpd/declcond.h, others include/ */ #include "l_stdlib.h" +#include "ntp_md5.h" #include "ntp_net.h" #include "ntp_debug.h" #include "ntp_malloc.h" @@ -18,6 +19,10 @@ #include "ntp_syslog.h" #include "ntp_keyacc.h" +#ifndef PATH_MAX +# define PATH_MAX MAX_PATH +#endif + #ifdef __GNUC__ #define NTP_PRINTF(fmt, args) __attribute__((__format__(__printf__, fmt, args))) #else @@ -36,24 +41,16 @@ extern void mvsyslog(int, const char *, va_list) NTP_PRINTF(2, 0); extern void init_logging (const char *, u_int32, int); extern int change_logfile (const char *, int); extern void setup_logfile (const char *); -#ifndef errno_to_str +#ifndef errno_to_str /* Windows port defines this */ extern void errno_to_str(int, char *, size_t); #endif -extern char * ntp_realpath(const char * fsname); +extern char * ntp_realpath(const char *fsname); -extern int xvsbprintf(char**, char* const, char const*, va_list) NTP_PRINTF(3, 0); -extern int xsbprintf(char**, char* const, char const*, ...) NTP_PRINTF(3, 4); - -/* - * When building without OpenSSL, use a few macros of theirs to - * minimize source differences in NTP. - */ -#ifndef OPENSSL -#define NID_md5 4 /* from openssl/objects.h */ -/* from openssl/evp.h */ -#define EVP_MAX_MD_SIZE 64 /* longest known is SHA512 */ -#endif +extern int xvsbprintf(char **, char * const, char const *, va_list) + NTP_PRINTF(3, 0); +extern int xsbprintf(char **, char * const, char const *, ...) + NTP_PRINTF(3, 4); #define SAVE_ERRNO(stmt) \ { \ @@ -111,10 +108,16 @@ extern void auth_prealloc_symkeys(int); extern int ymd2yd (int, int, int); /* a_md5encrypt.c */ -extern int MD5authdecrypt (int, const u_char *, size_t, u_int32 *, size_t, size_t, keyid_t); -extern size_t MD5authencrypt (int, const u_char *, size_t, u_int32 *, size_t); -extern void MD5auth_setkey (keyid_t, int, const u_char *, size_t, KeyAccT *c); -extern u_int32 addr2refid (sockaddr_u *); +extern size_t MD5authencrypt (int type, const u_char *key, size_t klen, + u_int32 *pkt, size_t length); +extern int MD5authdecrypt (int type, const u_char *key, size_t klen, + u_int32 *pkt, size_t length, size_t size, + keyid_t keyno); +extern u_int32 addr2refid(sockaddr_u *); + +/* authkeys.c */ +extern void MD5auth_setkey (keyid_t, int, const u_char *, size_t, + KeyAccT *c); /* emalloc.c */ #ifndef EREALLOC_CALLSITE /* ntp_malloc.h defines */ diff --git a/libntp/a_md5encrypt.c b/libntp/a_md5encrypt.c index 6011af52a..7a3729691 100644 --- a/libntp/a_md5encrypt.c +++ b/libntp/a_md5encrypt.c @@ -9,7 +9,6 @@ #include "ntp_string.h" #include "ntp_stdlib.h" #include "ntp.h" -#include "ntp_md5.h" /* provides OpenSSL digest API */ #include "isc/string.h" typedef struct { @@ -22,10 +21,12 @@ typedef struct { size_t len; } rwbuffT; + #if defined(OPENSSL) && defined(ENABLE_CMAC) static size_t cmac_ctx_size( - CMAC_CTX * ctx) + CMAC_CTX * ctx + ) { size_t mlen = 0; @@ -36,14 +37,16 @@ cmac_ctx_size( } return mlen; } -#endif /*OPENSSL && ENABLE_CMAC*/ +#endif /* OPENSSL && ENABLE_CMAC */ + static size_t make_mac( const rwbuffT * digest, int ktype, const robuffT * key, - const robuffT * msg) + const robuffT * msg + ) { /* * Compute digest of key concatenated with packet. Note: the @@ -66,8 +69,8 @@ make_mac( /* adjust key size (zero padded buffer) if necessary */ if (AES_128_KEY_SIZE > key->len) { memcpy(keybuf, keyptr, key->len); - memset((keybuf + key->len), 0, - (AES_128_KEY_SIZE - key->len)); + zero_mem((keybuf + key->len), + (AES_128_KEY_SIZE - key->len)); keyptr = keybuf; } @@ -107,10 +110,10 @@ make_mac( goto mac_fail; } - #ifdef EVP_MD_CTX_FLAG_NON_FIPS_ALLOW + #ifdef EVP_MD_CTX_FLAG_NON_FIPS_ALLOW /* make sure MD5 is allowd */ EVP_MD_CTX_set_flags(ctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW); - #endif + #endif /* [Bug 3457] DON'T use plain EVP_DigestInit! It would * kill the flags! */ if (!EVP_DigestInit_ex(ctx, EVP_get_digestbynid(ktype), NULL)) { @@ -239,8 +242,8 @@ MD5authdecrypt( dlen = MAX_MDG_LEN; if (size != (size_t)dlen + KEY_MAC_LEN) { msyslog(LOG_ERR, - "MAC decrypt: MAC length error: len=%zu key=%d", - size, keyno); + "MAC decrypt: MAC length error: len=%u key=%d", + (u_int)size, keyno); return (0); } return !isc_tsmemcmp(digest, diff --git a/libntp/authkeys.c b/libntp/authkeys.c index 9f9678567..d28b4b932 100644 --- a/libntp/authkeys.c +++ b/libntp/authkeys.c @@ -284,8 +284,7 @@ init_auth(void) */ newalloc = authhashbuckets * sizeof(key_hash[0]); - key_hash = erealloc(key_hash, newalloc); - memset(key_hash, '\0', newalloc); + key_hash = emalloc_zero(newalloc); INIT_DLIST(key_listhead, llink); @@ -458,7 +457,7 @@ auth_resize_hashtable(void) newalloc = authhashbuckets * sizeof(key_hash[0]); key_hash = erealloc(key_hash, newalloc); - memset(key_hash, '\0', newalloc); + zero_mem(key_hash, newalloc); ITER_DLIST_BEGIN(key_listhead, sk, llink, symkey) hash = KEYHASH(sk->keyid); @@ -528,14 +527,14 @@ freesymkey( bucket = &key_hash[KEYHASH(sk->keyid)]; if (sk->secret != NULL) { - memset(sk->secret, '\0', sk->secretsize); + zero_mem(sk->secret, sk->secretsize); free(sk->secret); } UNLINK_SLIST(unlinked, *bucket, sk, hlink, symkey); DEBUG_ENSURE(sk == unlinked); UNLINK_DLIST(sk, llink); - memset((char *)sk + offsetof(symkey, symkey_payload), '\0', - sizeof(*sk) - offsetof(symkey, symkey_payload)); + zero_mem((char *)sk + offsetof(symkey, symkey_payload), + sizeof(*sk) - offsetof(symkey, symkey_payload)); LINK_SLIST(authfreekeys, sk, llink.f); authnumkeys--; authnumfreekeys++; @@ -719,13 +718,13 @@ authistrusted( if (keyno == cache_keyid) { return (KEY_TRUSTED & cache_flags) && - keyacc_contains(cache_keyacclist, sau, TRUE); + keyacc_contains(cache_keyacclist, sau, TRUE); } if (NULL != (sk = auth_findkey(keyno))) { authkeyuncached++; return (KEY_TRUSTED & sk->flags) && - keyacc_contains(sk->keyacclist, sau, TRUE); + keyacc_contains(sk->keyacclist, sau, TRUE); } authkeynotfound++; @@ -816,7 +815,7 @@ MD5auth_setkey( /* * auth_delkeys - delete non-autokey untrusted keys, and clear all info - * except the trusted bit of non-autokey trusted keys, in + * except the trusted bit of non-autokey trusted keys, in * preparation for rereading the keys file. */ void @@ -835,7 +834,7 @@ auth_delkeys(void) */ if (KEY_TRUSTED & sk->flags) { if (sk->secret != NULL) { - memset(sk->secret, 0, sk->secretsize); + zero_mem(sk->secret, sk->secretsize); free(sk->secret); sk->secret = NULL; /* TALOS-CAN-0054 */ } @@ -886,9 +885,9 @@ authencrypt( * consists of a single word with value zero. */ authencryptions++; - pkt[length / 4] = htonl(keyno); + pkt[length / KEY_MAC_LEN] = htonl(keyno); if (0 == keyno) { - return 4; + return KEY_MAC_LEN; } if (!authhavekey(keyno)) { return 0; diff --git a/libntp/authreadkeys.c b/libntp/authreadkeys.c index da91bd0d3..fa2f5b540 100644 --- a/libntp/authreadkeys.c +++ b/libntp/authreadkeys.c @@ -234,7 +234,7 @@ authreadkeys( * The key type is unused, but is required to be 'M' or * 'm' for compatibility. */ - if (!(*token == 'M' || *token == 'm')) { + if (! (toupper(*token) == 'M')) { log_maybe(NULL, "authreadkeys: invalid type for key %d", keyno); @@ -357,13 +357,21 @@ authreadkeys( continue; } - INSIST(NULL != next); + DEBUG_INSIST(NULL != next); +#if defined(OPENSSL) && defined(ENABLE_CMAC) + if (NID_cmac == keytype && len < 16) { + msyslog(LOG_WARNING, CMAC " keys are 128 bits, " + "zero-extending key %u by %u bits", + (u_int)keyno, 8 * (16 - (u_int)len)); + } +#endif /* OPENSSL && ENABLE_CMAC */ next->next = list; list = next; } fclose(fp); if (nerr > 0) { const char * why = ""; + if (nerr > nerr_maxlimit) why = " (emergency break)"; msyslog(LOG_ERR, diff --git a/libntp/msyslog.c b/libntp/msyslog.c index ae950171f..a1ba72792 100644 --- a/libntp/msyslog.c +++ b/libntp/msyslog.c @@ -583,8 +583,9 @@ setup_logfile( syslog_fname); } -/* Helper for unit tests, where stdout + stderr are piped to the same - * stream. This works moderately reliable only if both streams are +/* + * Helper for unit tests, where stdout + stderr are piped to the same + * stream. This works moderately reliably only if both streams are * unbuffered or line buffered. Unfortunately stdout can be fully * buffered on pipes or files... */ diff --git a/libparse/clk_hopf6021.c b/libparse/clk_hopf6021.c index c5980ef13..b0b0c1ff2 100644 --- a/libparse/clk_hopf6021.c +++ b/libparse/clk_hopf6021.c @@ -25,7 +25,6 @@ #include "ntp_fp.h" #include "ntp_unixtime.h" #include "ntp_calendar.h" -#include "ascii.h" #include "parse.h" @@ -37,6 +36,8 @@ extern int printf (const char *, ...); #endif +#include "ascii.h" + /* * hopf Funkuhr 6021 * used with 9600,8N1, @@ -263,7 +264,7 @@ hexval( } #else /* not (REFCLOCK && CLOCK_PARSE && CLOCK_HOPF6021) */ -int clk_hopf6021_bs; +NONEMPTY_TRANSLATION_UNIT #endif /* not (REFCLOCK && CLOCK_PARSE && CLOCK_HOPF6021) */ /* diff --git a/libparse/clk_wharton.c b/libparse/clk_wharton.c index 371137dc6..fbe9cc95f 100644 --- a/libparse/clk_wharton.c +++ b/libparse/clk_wharton.c @@ -15,7 +15,6 @@ */ #include "ntp_fp.h" -#include "ascii.h" #include "parse.h" #ifndef PARSESTREAM @@ -26,6 +25,8 @@ extern void printf (const char *, ...); #endif +#include "ascii.h" + /* * In private e-mail alastair@wharton.co.uk said : * "If you are going to use the 400A and 404.2 system [for ntp] I recommend @@ -166,7 +167,7 @@ clockformat_t clock_wharton_400a = }; #else /* not (REFCLOCK && CLOCK_PARSE && CLOCK_WHARTON_400A) */ -int clk_wharton_400a_bs; +NONEMPTY_TRANSLATION_UNIT #endif /* not (REFCLOCK && CLOCK_PARSE && CLOCK_WHARTON_400A) */ /* diff --git a/ntpd/ntp_control.c b/ntpd/ntp_control.c index d1108c9d1..0cc7fcb47 100644 --- a/ntpd/ntp_control.c +++ b/ntpd/ntp_control.c @@ -26,7 +26,6 @@ #include "ntp_crypto.h" #include "ntp_assert.h" #include "ntp_leapsec.h" -#include "ntp_md5.h" /* provides OpenSSL digest API */ #include "lib_strbuf.h" #include "timexsup.h" diff --git a/ntpd/ntp_loopfilter.c b/ntpd/ntp_loopfilter.c index 0499c3633..e76e4dce0 100644 --- a/ntpd/ntp_loopfilter.c +++ b/ntpd/ntp_loopfilter.c @@ -129,9 +129,6 @@ static int loop_started; /* TRUE after LOOP_DRIFTINIT */ static void rstclock (int, double); /* transition function */ static double direct_freq(double); /* direct set frequency */ static void set_freq(double); /* set frequency */ -#ifndef PATH_MAX -# define PATH_MAX MAX_PATH -#endif static char relative_path[PATH_MAX + 1]; /* relative path per recursive make */ static char *this_file = NULL; diff --git a/sntp/crypto.c b/sntp/crypto.c index 5456c092a..7807ccc00 100644 --- a/sntp/crypto.c +++ b/sntp/crypto.c @@ -10,11 +10,6 @@ #include "crypto.h" #include #include "isc/string.h" -#include "ntp_md5.h" - -#ifndef EVP_MAX_MD_SIZE -# define EVP_MAX_MD_SIZE 32 -#endif struct key *key_ptr; size_t key_cnt = 0; diff --git a/sntp/crypto.h b/sntp/crypto.h index 961dca042..4e75df20a 100644 --- a/sntp/crypto.h +++ b/sntp/crypto.h @@ -8,7 +8,6 @@ #include #include #include -#include /* provides OpenSSL digest API */ #include "utilities.h" #include "sntp-opts.h" diff --git a/tests/libntp/Makefile.am b/tests/libntp/Makefile.am index a1d37ecab..43b72018e 100644 --- a/tests/libntp/Makefile.am +++ b/tests/libntp/Makefile.am @@ -8,10 +8,19 @@ std_unity_list = \ $(abs_srcdir)/testconf.yml \ $(NULL) +# +# Note: the rules to generate run-c_filename.c from c_filename.c below +# use the gmake $< construct for the first prerequisite, which +# does not work on FreeBSD make. Use gmake when adding a new +# test source file, and check in the resulting run-*.c. +# + run_unity = ruby $(std_unity_list) EXTRA_DIST = \ testconf.yml \ + data/ntp.keys \ + data/mills,david-03.jpg \ $(NULL) check_PROGRAMS = \ @@ -26,6 +35,7 @@ check_PROGRAMS = \ test-calyearstart \ test-clocktime \ test-decodenetnum \ + test-digests \ test-hextoint \ test-hextolfp \ test-humandate \ @@ -58,13 +68,13 @@ check_PROGRAMS = \ test-ymd2yd \ $(NULL) -LDADD = \ +LDADD = \ $(top_builddir)/sntp/unity/libunity.a \ - $(top_builddir)/libntp/libntp.a \ - $(LDADD_LIBNTP) \ - $(PTHREAD_LIBS) \ - $(LDADD_NTP) \ - $(LIBM) \ + $(top_builddir)/libntp/libntp.a \ + $(LDADD_LIBNTP) \ + $(PTHREAD_LIBS) \ + $(LDADD_NTP) \ + $(LIBM) \ $(NULL) AM_CFLAGS = $(CFLAGS_NTP) @@ -92,6 +102,7 @@ BUILT_SOURCES += \ $(srcdir)/run-calyearstart.c \ $(srcdir)/run-clocktime.c \ $(srcdir)/run-decodenetnum.c \ + $(srcdir)/run-digests.c \ $(srcdir)/run-hextoint.c \ $(srcdir)/run-hextolfp.c \ $(srcdir)/run-humandate.c \ @@ -263,6 +274,22 @@ $(srcdir)/run-decodenetnum.c: $(srcdir)/decodenetnum.c $(std_unity_list) ### +test_digests_SOURCES = \ + digests.c \ + run-digests.c \ + srcdir.c \ + $(NULL) + +$(srcdir)/run-digests.c: $(srcdir)/digests.c $(std_unity_list) + $(run_unity) $< $@ + +BUILT_SOURCES += srcdir.c + +srcdir.c: Makefile + $(AM_V_GEN)echo 'const char srcdir[] = "$(srcdir)";' >$@ + +### + test_hextoint_SOURCES = \ hextoint.c \ run-hextoint.c \ diff --git a/tests/libntp/data/ntp.keys b/tests/libntp/data/ntp.keys index 30cd07ea1..6c8c743fd 100644 --- a/tests/libntp/data/ntp.keys +++ b/tests/libntp/data/ntp.keys @@ -28,7 +28,7 @@ 54 MDC2 3cb1d4633a460179a7c96aed6c6a9273c3c98af8 55 RIPEMD160 6028ec169bfbe55ab61ffa7baa34b482020f0619 56 SHA1 17d96a86eb9b9075f33e1c0a08bb2bb61e916e33 -57 SHAKE12 70da1a91030eb91836c1cf76cf67ddfd6b96fa91 +57 SHAKE128 70da1a91030eb91836c1cf76cf67ddfd6b96fa91 58 SHA1 7ce5deea7569d7423d5e1b497c8eb3bfeff852d5 # unused so far 59 SHA1 9fd568e8f371deae54a65bc50b52bbe1f6529589 # unused 60 SHA1 ce85046978a4df8366e102c4f1267399bbc25737 # unused diff --git a/tests/libntp/digests.c b/tests/libntp/digests.c new file mode 100644 index 000000000..03e9ef1b8 --- /dev/null +++ b/tests/libntp/digests.c @@ -0,0 +1,415 @@ +#include "config.h" + +#include +#include +#include +#include + +#include "unity.h" +#include "ntp.h" +#include "ntp_stdlib.h" + +/* + * tests/libntp/data/ntp.keys has two keys for each algorithm, 50 keyids apart. + * The first is 20 random ASCII chars, the 2nd 40 random hex values. + */ +#define HEX_KEYID_OFFSET 50 + +/* in generated srcdir.c */ +extern const char srcdir[]; + +/* needed by authtrust() */ +u_long current_time; + +static bool setup; +static u_int32 * pkt; +static size_t pkt_sz; +static u_char * mac; + +/* helper routine */ +void dump_mac(keyid_t keyid, u_char *pmac, size_t octets); + + +/* unity calls setUp before each test routine */ +void setUp(void); +void +setUp(void) +{ + static bool done_once; + const char msg_rel_fname[] = "data/mills,david-03.jpg"; + const char keys_rel_fname[] = "data/ntp.keys"; + char msg_fname[PATH_MAX]; + char keys_fname[PATH_MAX]; + int msgf; + int result; + struct stat msg_stat; + u_char * msg; + size_t msg_sz; + size_t pad_sz; + ssize_t octets; + + if (done_once) { + return; + } + done_once = TRUE; + + init_auth(); + + snprintf(keys_fname, sizeof(keys_fname), "%s/%s", srcdir, + keys_rel_fname); + if (! authreadkeys(keys_fname)) { + fprintf(stderr, "could not load keys %s\n", keys_fname); + return; + } + + snprintf(msg_fname, sizeof(msg_fname), "%s/%s", srcdir, msg_rel_fname); + msgf = open(msg_fname, O_RDONLY); + if (msgf < 0) { + fprintf(stderr, "could not open msg file %s\n", msg_fname); + return; + } + + result = fstat(msgf, &msg_stat); + if (result < 0) { + fprintf(stderr, "could not get msg file %s size\n", msg_fname); + return; + } + + msg_sz = msg_stat.st_size; + /* round up to next multiple of 4 as needed by MD5authencrypt() */ + pad_sz = sizeof(u_int32) - (msg_sz % sizeof(u_int32)); + if (sizeof(u_int32) == pad_sz) { + pad_sz = 0; + } + /* allocate room for the message, key ID, and MAC */ + msg = emalloc_zero(msg_sz + pad_sz + MAX_MAC_LEN); + octets = read(msgf, msg, msg_sz); + if (octets != msg_sz) { + fprintf(stderr, "could not read msg from file %s, %u != %u\n", + msg_fname, (u_int)octets, (u_int)msg_sz); + return; + } + zero_mem(msg + msg_sz, pad_sz); + pkt_sz = msg_sz + pad_sz; + mac = (void *)((u_char *)msg + pkt_sz); + pkt = (void *)msg; + + setup = TRUE; +} + +/* reduce code duplication with an ugly macro */ +#define TEST_ONE_DIGEST(key, exp_sz, exp_mac) \ +do { \ + size_t res_sz; \ + \ + zero_mem(mac, MAX_MAC_LEN); \ + if (!auth_findkey(key)) { \ + TEST_IGNORE_MESSAGE("MAC unsupported on this system"); \ + return; \ + } \ + authtrust((key), 1); \ + \ + res_sz = authencrypt((key), pkt, pkt_sz); \ + if (KEY_MAC_LEN == res_sz) { \ + TEST_IGNORE_MESSAGE("Likely OpenSSL 3 failed digest " \ + "init."); \ + return; \ + } \ + TEST_ASSERT_EQUAL_UINT((u_int)((exp_sz) + KEY_MAC_LEN), res_sz);\ + dump_mac((key), mac, res_sz); \ + TEST_ASSERT_EQUAL_HEX8_ARRAY((exp_mac), mac, MAX_MAC_LEN); \ +} while (FALSE) + + +#define AES128CMAC_KEYID 1 +#undef KEYID_A +#define KEYID_A AES128CMAC_KEYID +#undef DG_SZ +#define DG_SZ 16 +#undef KEYID_B +#define KEYID_B (KEYID_A + HEX_KEYID_OFFSET) +void test_Digest_AES128CMAC(void); +void test_Digest_AES128CMAC(void) +{ +#if defined(OPENSSL) && defined(ENABLE_CMAC) + u_char expectedA[MAX_MAC_LEN] = + { + 0, 0, 0, KEYID_A, + 0x34, 0x5b, 0xcf, 0xa8, + 0x85, 0x6e, 0x9d, 0x01, + 0xeb, 0x81, 0x25, 0xc2, + 0xa4, 0xb8, 0x1b, 0xe0 + }; + u_char expectedB[MAX_MAC_LEN] = + { + 0, 0, 0, KEYID_B, + 0xd1, 0x04, 0x4e, 0xbf, + 0x79, 0x2d, 0x3a, 0x40, + 0xcd, 0xdc, 0x5a, 0x44, + 0xde, 0xe0, 0x0c, 0x84 + }; + + TEST_ASSERT(setup); + TEST_ONE_DIGEST(KEYID_A, DG_SZ, expectedA); + TEST_ONE_DIGEST(KEYID_B, DG_SZ, expectedB); +#else /* ! (OPENSSL && ENABLE_CMAC) follows */ + TEST_IGNORE_MESSAGE("Skipping, no OPENSSL or not ENABLE_CMAC"); +#endif +} + + +#define MD4_KEYID 2 +#undef KEYID_A +#define KEYID_A MD4_KEYID +#undef DG_SZ +#define DG_SZ 16 +#undef KEYID_B +#define KEYID_B (KEYID_A + HEX_KEYID_OFFSET) +void test_Digest_MD4(void); +void test_Digest_MD4(void) +{ +#ifdef OPENSSL + u_char expectedA[MAX_MAC_LEN] = + { + 0, 0, 0, KEYID_A, + 0xf3, 0x39, 0x34, 0xca, + 0xe0, 0x48, 0x26, 0x0f, + 0x13, 0xca, 0x56, 0x9e, + 0xbc, 0x53, 0x9c, 0x66 + }; + u_char expectedB[MAX_MAC_LEN] = + { + 0, 0, 0, KEYID_B, + 0x5e, 0xe6, 0x81, 0xf2, + 0x57, 0x57, 0x8a, 0x2b, + 0xa8, 0x76, 0x8e, 0x7a, + 0xc4, 0xf4, 0x34, 0x7e + }; + + TEST_ASSERT(setup); + TEST_ONE_DIGEST(KEYID_A, DG_SZ, expectedA); + TEST_ONE_DIGEST(KEYID_B, DG_SZ, expectedB); +#else /* ! OPENSSL follows */ + TEST_IGNORE_MESSAGE("Skipping, no OPENSSL"); +#endif +} + + +#define MD5_KEYID 3 +#undef KEYID_A +#define KEYID_A MD5_KEYID +#undef DG_SZ +#define DG_SZ 16 +#undef KEYID_B +#define KEYID_B (KEYID_A + HEX_KEYID_OFFSET) +void test_Digest_MD5(void); +void test_Digest_MD5(void) +{ + u_char expectedA[MAX_MAC_LEN] = + { + 0, 0, 0, KEYID_A, + 0xa6, 0x8d, 0x3a, 0xfe, + 0x52, 0xe5, 0xf7, 0xe9, + 0x4c, 0x97, 0x72, 0x16, + 0x7c, 0x28, 0x18, 0xaf + }; + u_char expectedB[MAX_MAC_LEN] = + { + 0, 0, 0, KEYID_B, + 0xd4, 0x11, 0x2c, 0xc6, + 0x66, 0x74, 0x46, 0x8b, + 0x12, 0xb1, 0x8c, 0x49, + 0xb0, 0x06, 0xda, 0x34 + }; + + TEST_ASSERT(setup); + TEST_ONE_DIGEST(KEYID_A, DG_SZ, expectedA); + TEST_ONE_DIGEST(KEYID_B, DG_SZ, expectedB); +} + + +#define MDC2_KEYID 4 +#undef KEYID_A +#define KEYID_A MDC2_KEYID +#undef DG_SZ +#define DG_SZ 16 +#undef KEYID_B +#define KEYID_B (KEYID_A + HEX_KEYID_OFFSET) +void test_Digest_MDC2(void); +void test_Digest_MDC2(void) +{ +#ifdef OPENSSL + u_char expectedA[MAX_MAC_LEN] = + { + 0, 0, 0, KEYID_A, + 0xa0, 0xfc, 0x18, 0xb6, + 0xea, 0xba, 0xa5, 0x27, + 0xc9, 0x64, 0x0e, 0x41, + 0x95, 0x90, 0x5d, 0xf5 + }; + u_char expectedB[MAX_MAC_LEN] = + { + 0, 0, 0, KEYID_B, + 0xe3, 0x2c, 0x1e, 0x64, + 0x7f, 0x85, 0x81, 0xe7, + 0x3b, 0xc3, 0x93, 0x5e, + 0xcd, 0x0e, 0x89, 0xeb + }; + + TEST_ASSERT(setup); + TEST_ONE_DIGEST(KEYID_A, DG_SZ, expectedA); + TEST_ONE_DIGEST(KEYID_B, DG_SZ, expectedB); +#else /* ! OPENSSL follows */ + TEST_IGNORE_MESSAGE("Skipping, no OPENSSL"); +#endif +} + + +#define RIPEMD160_KEYID 5 +#undef KEYID_A +#define KEYID_A RIPEMD160_KEYID +#undef DG_SZ +#define DG_SZ 20 +#undef KEYID_B +#define KEYID_B (KEYID_A + HEX_KEYID_OFFSET) +void test_Digest_RIPEMD160(void); +void test_Digest_RIPEMD160(void) +{ +#ifdef OPENSSL + u_char expectedA[MAX_MAC_LEN] = + { + 0, 0, 0, KEYID_A, + 0x8c, 0x3e, 0x55, 0xbb, + 0xec, 0x7c, 0xf6, 0x30, + 0xef, 0xd1, 0x45, 0x8c, + 0xdd, 0x29, 0x32, 0x7e, + 0x04, 0x87, 0x6c, 0xd7 + }; + u_char expectedB[MAX_MAC_LEN] = + { + 0, 0, 0, KEYID_B, + 0x2d, 0x4a, 0x48, 0xdd, + 0x28, 0x02, 0xb4, 0x9d, + 0xe3, 0x6d, 0x1b, 0x90, + 0x2b, 0xc4, 0x3f, 0xe5, + 0x19, 0x60, 0x12, 0xbc + }; + + TEST_ASSERT(setup); + TEST_ONE_DIGEST(KEYID_A, DG_SZ, expectedA); + TEST_ONE_DIGEST(KEYID_B, DG_SZ, expectedB); +#else /* ! OPENSSL follows */ + TEST_IGNORE_MESSAGE("Skipping, no OPENSSL"); +#endif +} + + +#define SHA1_KEYID 6 +#undef KEYID_A +#define KEYID_A SHA1_KEYID +#undef DG_SZ +#define DG_SZ 20 +#undef KEYID_B +#define KEYID_B (KEYID_A + HEX_KEYID_OFFSET) +void test_Digest_SHA1(void); +void test_Digest_SHA1(void) +{ +#ifdef OPENSSL + u_char expectedA[MAX_MAC_LEN] = + { + 0, 0, 0, KEYID_A, + 0xe2, 0xc6, 0x17, 0x71, + 0x03, 0xc1, 0x85, 0x56, + 0x35, 0xc7, 0x4e, 0x75, + 0x79, 0x82, 0x9d, 0xcb, + 0x2d, 0x06, 0x0e, 0xfa + }; + u_char expectedB[MAX_MAC_LEN] = + { + 0, 0, 0, KEYID_B, + 0x01, 0x16, 0x37, 0xb4, + 0xf5, 0x2d, 0xe0, 0x97, + 0xaf, 0xd8, 0x58, 0xf7, + 0xad, 0xb3, 0x7e, 0x38, + 0x86, 0x85, 0x78, 0x44 + }; + + TEST_ASSERT(setup); + TEST_ONE_DIGEST(KEYID_A, DG_SZ, expectedA); + TEST_ONE_DIGEST(KEYID_B, DG_SZ, expectedB); +#else /* ! OPENSSL follows */ + TEST_IGNORE_MESSAGE("Skipping, no OPENSSL"); +#endif +} + + +#define SHAKE128_KEYID 7 +#undef KEYID_A +#define KEYID_A SHAKE128_KEYID +#undef DG_SZ +#define DG_SZ 16 +#undef KEYID_B +#define KEYID_B (KEYID_A + HEX_KEYID_OFFSET) +void test_Digest_SHAKE128(void); +void test_Digest_SHAKE128(void) +{ +#ifdef OPENSSL + u_char expectedA[MAX_MAC_LEN] = + { + 0, 0, 0, KEYID_A, + 0x5c, 0x0c, 0x1a, 0x85, + 0xad, 0x03, 0xb2, 0x9a, + 0xe4, 0x75, 0x37, 0x93, + 0xaa, 0xa6, 0xcd, 0x76 + }; + u_char expectedB[MAX_MAC_LEN] = + { + 0, 0, 0, KEYID_B, + 0x07, 0x04, 0x63, 0xcc, + 0x46, 0xaf, 0xca, 0x00, + 0x7d, 0xd1, 0x5a, 0x39, + 0xfd, 0x34, 0xca, 0x10 + }; + + TEST_ASSERT(setup); + TEST_ONE_DIGEST(KEYID_A, DG_SZ, expectedA); + TEST_ONE_DIGEST(KEYID_B, DG_SZ, expectedB); +#else /* ! OPENSSL follows */ + TEST_IGNORE_MESSAGE("Skipping, no OPENSSL"); +#endif +} + + +/* + * Dump a MAC in a form easy to cut and paste into the expected declaration. + */ +void dump_mac( + keyid_t keyid, + u_char * pmac, + size_t octets + ) +{ + char dump[128]; + size_t dc = 0; + size_t idx; + + dc += snprintf(dump + dc, sizeof(dump) - dc, "digest with key %u { ", keyid); + + for (idx = 0; idx < octets; idx++) { + if (10 == idx) { + msyslog(LOG_DEBUG, "%s", dump); + dc = 0; + } + if (dc < sizeof(dump)) { + dc += snprintf(dump + dc, sizeof(dump) - dc, + "0x%02x, ", pmac[idx]); + } + } + + if (dc < sizeof(dump)) { + dc += snprintf(dump + dc, sizeof(dump) - dc, "}"); + } + + msyslog(LOG_DEBUG, "%s", dump); +} + diff --git a/tests/libntp/run-digests.c b/tests/libntp/run-digests.c new file mode 100644 index 000000000..bcfe93953 --- /dev/null +++ b/tests/libntp/run-digests.c @@ -0,0 +1,80 @@ +/* AUTOGENERATED FILE. DO NOT EDIT. */ + +//=======Test Runner Used To Run Each Test Below===== +#define RUN_TEST(TestFunc, TestLineNum) \ +{ \ + Unity.CurrentTestName = #TestFunc; \ + Unity.CurrentTestLineNumber = TestLineNum; \ + Unity.NumberOfTests++; \ + if (TEST_PROTECT()) \ + { \ + setUp(); \ + TestFunc(); \ + } \ + if (TEST_PROTECT() && !TEST_IS_IGNORED) \ + { \ + tearDown(); \ + } \ + UnityConcludeTest(); \ +} + +//=======Automagically Detected Files To Include===== +#include "unity.h" +#include +#include +#include "config.h" +#include "ntp.h" +#include "ntp_stdlib.h" +#include +#include +#include +#include + +//=======External Functions This Runner Calls===== +extern void setUp(void); +extern void tearDown(void); +extern void test_Digest_AES128CMAC(void); +extern void test_Digest_MD4(void); +extern void test_Digest_MD5(void); +extern void test_Digest_MDC2(void); +extern void test_Digest_RIPEMD160(void); +extern void test_Digest_SHA1(void); +extern void test_Digest_SHAKE128(void); + + +//=======Suite Setup===== +static void suite_setup(void) +{ +extern int change_iobufs(int); +extern int change_logfile(const char*, int); +change_iobufs(1); +change_logfile("stderr", 0); +} + +//=======Test Reset Option===== +void resetTest(void); +void resetTest(void) +{ + tearDown(); + setUp(); +} + +char const *progname; + + +//=======MAIN===== +int main(int argc, char *argv[]) +{ + progname = argv[0]; + suite_setup(); + UnityBegin("digests.c"); + RUN_TEST(test_Digest_AES128CMAC, 121); + RUN_TEST(test_Digest_MD4, 180); + RUN_TEST(test_Digest_MD5, 239); + RUN_TEST(test_Digest_MDC2, 289); + RUN_TEST(test_Digest_RIPEMD160, 348); + RUN_TEST(test_Digest_SHA1, 407); + RUN_TEST(test_Digest_SHAKE128, 466); + + return (UnityEnd()); +}