diff --git a/etc/mtree/BSD.tests.dist b/etc/mtree/BSD.tests.dist index b25dfe78f0a2..d1a841561b97 100644 --- a/etc/mtree/BSD.tests.dist +++ b/etc/mtree/BSD.tests.dist @@ -1,1116 +1,1118 @@ # $FreeBSD$ # # Please see the file src/etc/mtree/README before making changes to this file. # /set type=dir uname=root gname=wheel mode=0755 . bin cat .. chflags .. chmod .. cp .. date .. dd .. echo .. expr .. ln .. ls .. mkdir .. mv .. pax .. pkill .. pwait .. rm .. rmdir .. sh builtins .. errors .. execution .. expansion .. invocation .. parameters .. parser .. set-e .. .. sleep .. test .. .. cddl lib .. sbin .. usr.bin ctfconvert .. ztest .. .. usr.sbin dtrace common aggs .. arithmetic .. arrays .. assocs .. begin .. bitfields .. buffering .. builtinvar .. cg .. clauses .. cpc .. decls .. drops .. dtraceUtil .. end .. env .. enum .. error .. exit .. fbtprovider .. funcs .. grammar .. include .. inline .. io .. ip .. java_api .. json .. lexer .. llquantize .. mdb .. mib .. misc .. multiaggs .. offsetof .. operators .. pid .. plockstat .. pointers .. pragma .. predicates .. preprocessor .. print .. printa .. printf .. privs .. probes .. proc .. profile-n .. providers .. raise .. rates .. safety .. scalars .. sched .. scripting .. sdt .. sizeof .. speculation .. stability .. stack .. stackdepth .. stop .. strlen .. strtoll .. struct .. sugar .. syscall .. sysevent .. tick-n .. trace .. tracemem .. translators .. typedef .. types .. uctf .. union .. usdt .. ustack .. vars .. version .. .. i386 arrays .. funcs .. pid .. ustack .. .. .. zfsd .. .. .. etc rc.d .. .. games .. gnu lib .. usr.bin diff .. .. .. lib atf libatf-c detail .. .. libatf-c++ detail .. .. test-programs .. .. csu dynamic .. dynamiclib .. static .. .. googletest gmock .. gmock_main .. gtest .. gtest_main .. .. libarchive .. libbe .. libc c063 .. db .. gen execve .. posix_spawn .. .. hash data .. .. iconv .. inet .. locale .. net getaddrinfo data .. .. .. nss .. regex data .. .. resolv .. rpc .. ssp .. setjmp .. stdio .. stdlib .. string .. sys .. time .. tls dso .. .. termios .. ttyio .. .. libcam .. libcasper services cap_dns .. cap_grp .. cap_pwd .. cap_sysctl .. .. .. libcrypt .. libdevdctl .. libkvm .. libmp .. libnv .. libproc .. libregex data .. .. librt .. libsbuf .. libthr dlopen .. .. libutil .. libxo .. msun .. .. libexec atf atf-check .. atf-sh .. .. rtld-elf .. tftpd .. .. sbin bectl .. dhclient .. devd .. growfs .. ifconfig .. md5 .. mdconfig .. nvmecontrol .. pfctl files .. .. ping .. .. secure lib .. libexec .. usr.bin .. usr.sbin .. .. share examples tests atf .. googletest .. plain .. tap .. .. .. zoneinfo .. .. sys acl .. aio .. audit .. auditpipe .. capsicum .. cddl zfs bin .. include .. tests acl cifs .. nontrivial .. trivial .. .. atime .. bootfs .. cache .. cachefile .. clean_mirror .. cli_root zfs_upgrade .. zfs_promote .. zfs_clone .. zfs_property .. zfs_destroy .. zpool_create .. zpool_history .. zpool_expand .. zpool_remove .. zfs_mount .. zfs_unshare .. zdb .. zpool_online .. zpool_get .. zpool_export .. zfs_copies .. zfs_get .. zfs .. zpool_clear .. zpool_import blockfiles .. .. zpool .. zpool_offline .. zpool_replace .. zfs_rollback .. zpool_set .. zfs_send .. zfs_set .. zpool_detach .. zfs_diff .. zpool_scrub .. zfs_inherit .. zfs_snapshot .. zfs_share .. zpool_destroy .. zpool_status .. zfs_unmount .. zfs_receive .. zfs_create .. zpool_upgrade blockfiles .. .. zpool_add .. zfs_rename .. zpool_attach .. zfs_reservation .. .. cli_user misc .. zfs_list .. zpool_iostat .. zpool_list .. .. compression .. ctime .. delegate .. devices .. exec .. grow_pool .. grow_replicas .. history .. hotplug .. hotspare .. inheritance .. interop .. inuse .. iscsi .. large_files .. largest_pool .. link_count .. migration .. mmap .. mount .. mv_files .. nestedfs .. no_space .. online_offline .. pool_names .. poolversion .. quota .. redundancy .. refquota .. refreserv .. rename_dirs .. replacement .. reservation .. rootpool .. rsend .. scrub_mirror .. slog .. snapshot .. snapused .. sparse .. threadsappend .. truncate .. txg_integrity .. userquota .. utils_test .. write_dirs .. xattr .. zfsd .. zil .. zinject .. zones .. zvol zvol_ENOSPC .. zvol_cli .. zvol_misc .. zvol_swap .. .. zvol_thrash .. .. .. .. + devrandom + .. dtrace .. fifo .. file .. fs fusefs .. tmpfs .. .. geom class concat .. eli .. gate .. gpt .. mirror .. multipath .. nop .. part .. raid3 .. shsec .. stripe .. uzip etalon .. .. .. .. kern acct .. execve .. pipe .. .. kqueue libkqueue .. .. mac bsdextended .. portacl .. .. mqueue .. net .. netgraph .. netinet .. netinet6 frag6 .. .. netipsec tunnel .. .. netmap .. netpfil common .. pf ioctl .. .. .. opencrypto .. pjdfstest chflags .. chmod .. chown .. ftruncate .. granular .. link .. mkdir .. mkfifo .. mknod .. open .. rename .. rmdir .. symlink .. truncate .. unlink .. utimensat .. .. posixshm .. sys .. vfs .. vm .. .. usr.bin apply .. awk .. basename .. bmake archives fmt_44bsd .. fmt_44bsd_mod .. fmt_oldbsd .. .. basic t0 .. t1 .. t2 .. t3 .. .. execution ellipsis .. empty .. joberr .. plus .. .. shell builtin .. meta .. path .. path_select .. replace .. select .. .. suffixes basic .. src_wild1 .. src_wild2 .. .. syntax directive-t0 .. enl .. funny-targets .. semi .. .. sysmk t0 2 1 .. .. mk .. .. t1 2 1 .. .. mk .. .. t2 2 1 .. .. mk .. .. .. variables modifier_M .. modifier_t .. opt_V .. t0 .. .. .. bsdcat .. calendar .. cmp .. compress .. cpio .. col .. comm .. csplit .. cut .. dc .. diff .. dirname .. du .. file2c .. find .. fold .. getconf .. gh-bc .. grep .. gzip .. head .. hexdump .. ident .. indent .. join .. jot .. lastcomm .. limits .. locale .. m4 .. mkimg .. ncal .. opensm .. patch .. pr .. printf .. procstat .. rs .. sdiff .. sed regress.multitest.out .. .. seq .. soelim .. stat .. tail .. tar .. timeout .. tr .. truncate .. units .. uudecode .. uuencode .. uniq .. vmstat .. xargs .. xinstall .. xo .. yacc yacc .. .. .. usr.sbin chown .. daemon .. etcupdate .. extattr .. fstyp .. jail .. makefs .. mixer .. newsyslog .. nmtree .. praudit .. pw .. rpcbind .. sa .. .. .. # vim: set expandtab ts=4 sw=4: diff --git a/sys/dev/random/hash.c b/sys/dev/random/hash.c index 2f3cb4738bc6..113f76e8a041 100644 --- a/sys/dev/random/hash.c +++ b/sys/dev/random/hash.c @@ -1,222 +1,226 @@ /*- * Copyright (c) 2000-2015 Mark R V Murray * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer * in this position and unchanged. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ #include __FBSDID("$FreeBSD$"); #ifdef _KERNEL #include #include #include #include #include #else /* !_KERNEL */ #include #include +#include #include +#include +#include #include #include #include #include -#include "unit_test.h" +#define KASSERT(x, y) assert(x) +#define CTASSERT(x) _Static_assert(x, "CTASSERT " #x) #endif /* _KERNEL */ #define CHACHA_EMBED #define KEYSTREAM_ONLY #define CHACHA_NONCE0_CTR128 #include #include #include #include #ifdef _KERNEL #include #endif /* This code presumes that RANDOM_KEYSIZE is twice as large as RANDOM_BLOCKSIZE */ CTASSERT(RANDOM_KEYSIZE == 2*RANDOM_BLOCKSIZE); /* Validate that full Chacha IV is as large as the 128-bit counter */ _Static_assert(CHACHA_STATELEN == RANDOM_BLOCKSIZE, ""); /* * Experimental Chacha20-based PRF for Fortuna keystream primitive. For now, * disabled by default. But we may enable it in the future. * * Benefits include somewhat faster keystream generation compared with * unaccelerated AES-ICM. */ bool random_chachamode = false; #ifdef _KERNEL SYSCTL_BOOL(_kern_random, OID_AUTO, use_chacha20_cipher, CTLFLAG_RDTUN, &random_chachamode, 0, "If non-zero, use the ChaCha20 cipher for randomdev PRF. " "If zero, use AES-ICM cipher for randomdev PRF (default)."); #endif /* Initialise the hash */ void randomdev_hash_init(struct randomdev_hash *context) { SHA256_Init(&context->sha); } /* Iterate the hash */ void randomdev_hash_iterate(struct randomdev_hash *context, const void *data, size_t size) { SHA256_Update(&context->sha, data, size); } /* Conclude by returning the hash in the supplied <*buf> which must be * RANDOM_KEYSIZE bytes long. */ void randomdev_hash_finish(struct randomdev_hash *context, void *buf) { SHA256_Final(buf, &context->sha); } /* Initialise the encryption routine by setting up the key schedule * from the supplied <*data> which must be RANDOM_KEYSIZE bytes of binary * data. */ void randomdev_encrypt_init(union randomdev_key *context, const void *data) { if (random_chachamode) { chacha_keysetup(&context->chacha, data, RANDOM_KEYSIZE * 8); } else { rijndael_cipherInit(&context->cipher, MODE_ECB, NULL); rijndael_makeKey(&context->key, DIR_ENCRYPT, RANDOM_KEYSIZE*8, data); } } /* * Create a psuedorandom output stream of 'blockcount' blocks using a CTR-mode * cipher or similar. The 128-bit counter is supplied in the in-out parmeter * 'ctr.' The output stream goes to 'd_out.' 'blockcount' RANDOM_BLOCKSIZE * bytes are generated. */ void randomdev_keystream(union randomdev_key *context, uint128_t *ctr, void *d_out, u_int blockcount) { u_int i; if (random_chachamode) { uint128_t lectr; /* * Chacha always encodes and increments the counter little * endian. So on BE machines, we must provide a swapped * counter to chacha, and swap the output too. */ le128enc(&lectr, *ctr); chacha_ivsetup(&context->chacha, NULL, (const void *)&lectr); chacha_encrypt_bytes(&context->chacha, NULL, d_out, RANDOM_BLOCKSIZE * blockcount); /* * Decode Chacha-updated LE counter to native endian and store * it back in the caller's in-out parameter. */ chacha_ctrsave(&context->chacha, (void *)&lectr); *ctr = le128dec(&lectr); } else { for (i = 0; i < blockcount; i++) { /*- * FS&K - r = r|E(K,C) * - C = C + 1 */ rijndael_blockEncrypt(&context->cipher, &context->key, (void *)ctr, RANDOM_BLOCKSIZE * 8, d_out); d_out = (char *)d_out + RANDOM_BLOCKSIZE; uint128_increment(ctr); } } } /* * Fetch a pointer to the relevant key material and its size. * * This API is expected to only be used only for reseeding, where the * endianness does not matter; the goal is to simply incorporate the key * material into the hash iterator that will produce key'. * * Do not expect the buffer pointed to by this API to match the exact * endianness, etc, as the key material that was supplied to * randomdev_encrypt_init(). */ void randomdev_getkey(union randomdev_key *context, const void **keyp, size_t *szp) { if (!random_chachamode) { *keyp = &context->key.keyMaterial; *szp = context->key.keyLen / 8; return; } /* Chacha20 mode */ *keyp = (const void *)&context->chacha.input[4]; /* Sanity check keysize */ if (context->chacha.input[0] == U8TO32_LITTLE(sigma) && context->chacha.input[1] == U8TO32_LITTLE(&sigma[4]) && context->chacha.input[2] == U8TO32_LITTLE(&sigma[8]) && context->chacha.input[3] == U8TO32_LITTLE(&sigma[12])) { *szp = 32; return; } #if 0 /* * Included for the sake of completeness; as-implemented, Fortuna * doesn't need or use 128-bit Chacha20. */ if (context->chacha->input[0] == U8TO32_LITTLE(tau) && context->chacha->input[1] == U8TO32_LITTLE(&tau[4]) && context->chacha->input[2] == U8TO32_LITTLE(&tau[8]) && context->chacha->input[3] == U8TO32_LITTLE(&tau[12])) { *szp = 16; return; } #endif #ifdef _KERNEL panic("%s: Invalid chacha20 keysize: %16D\n", __func__, (void *)context->chacha.input, " "); #else raise(SIGKILL); #endif } diff --git a/sys/dev/random/hash.h b/sys/dev/random/hash.h index bcc7035a0e4f..e76eaaaf4ccb 100644 --- a/sys/dev/random/hash.h +++ b/sys/dev/random/hash.h @@ -1,67 +1,67 @@ /*- * Copyright (c) 2000-2015 Mark R V Murray * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer * in this position and unchanged. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * $FreeBSD$ */ #ifndef SYS_DEV_RANDOM_HASH_H_INCLUDED #define SYS_DEV_RANDOM_HASH_H_INCLUDED #include #include /* Keys are formed from cipher blocks */ #define RANDOM_KEYSIZE 32 /* (in bytes) == 256 bits */ #define RANDOM_KEYSIZE_WORDS (RANDOM_KEYSIZE/sizeof(uint32_t)) #define RANDOM_BLOCKSIZE 16 /* (in bytes) == 128 bits */ #define RANDOM_BLOCKSIZE_WORDS (RANDOM_BLOCKSIZE/sizeof(uint32_t)) #define RANDOM_KEYS_PER_BLOCK (RANDOM_KEYSIZE/RANDOM_BLOCKSIZE) /* The size of the zero block portion used to form H_d(m) */ #define RANDOM_ZERO_BLOCKSIZE 64 /* (in bytes) == 512 zero bits */ struct randomdev_hash { SHA256_CTX sha; }; union randomdev_key { struct { keyInstance key; /* Key schedule */ cipherInstance cipher; /* Rijndael internal */ }; struct chacha_ctx chacha; }; -extern bool fortuna_chachamode; +extern bool random_chachamode; void randomdev_hash_init(struct randomdev_hash *); void randomdev_hash_iterate(struct randomdev_hash *, const void *, size_t); void randomdev_hash_finish(struct randomdev_hash *, void *); void randomdev_encrypt_init(union randomdev_key *, const void *); void randomdev_keystream(union randomdev_key *context, uint128_t *, void *, u_int); void randomdev_getkey(union randomdev_key *, const void **, size_t *); #endif /* SYS_DEV_RANDOM_HASH_H_INCLUDED */ diff --git a/tests/sys/Makefile b/tests/sys/Makefile index efc4f801890f..e95d193f7bf9 100644 --- a/tests/sys/Makefile +++ b/tests/sys/Makefile @@ -1,51 +1,52 @@ # $FreeBSD$ .include TESTSDIR= ${TESTSBASE}/sys TESTS_SUBDIRS+= acl TESTS_SUBDIRS+= aio TESTS_SUBDIRS+= ${_audit} TESTS_SUBDIRS+= auditpipe TESTS_SUBDIRS+= capsicum TESTS_SUBDIRS+= ${_cddl} +TESTS_SUBDIRS+= devrandom TESTS_SUBDIRS+= fifo TESTS_SUBDIRS+= file TESTS_SUBDIRS+= fs TESTS_SUBDIRS+= geom TESTS_SUBDIRS+= kern TESTS_SUBDIRS+= kqueue TESTS_SUBDIRS+= mac TESTS_SUBDIRS+= mqueue TESTS_SUBDIRS+= ${_netgraph} TESTS_SUBDIRS+= net TESTS_SUBDIRS+= netinet TESTS_SUBDIRS+= netinet6 TESTS_SUBDIRS+= netipsec TESTS_SUBDIRS+= netmap TESTS_SUBDIRS+= netpfil TESTS_SUBDIRS+= opencrypto TESTS_SUBDIRS+= posixshm TESTS_SUBDIRS+= sys TESTS_SUBDIRS+= vfs TESTS_SUBDIRS+= vm .if ${MK_AUDIT} != "no" _audit= audit .endif .if ${MK_CDDL} != "no" _cddl= cddl .endif .if ${MK_NETGRAPH} != "no" _netgraph= netgraph .endif # Items not integrated into kyua runs by default SUBDIR+= pjdfstest SUBDIR+= common .include diff --git a/tests/sys/devrandom/Makefile b/tests/sys/devrandom/Makefile new file mode 100644 index 000000000000..db9f9d42a470 --- /dev/null +++ b/tests/sys/devrandom/Makefile @@ -0,0 +1,26 @@ +# $FreeBSD$ + +.include + +SDEVRANDOM= ${SRCTOP}/sys/dev/random +.PATH: ${SDEVRANDOM} + +TESTSDIR= ${TESTSBASE}/sys/devrandom +WARNS?= 6 + +CFLAGS+= -I${SRCTOP}/sys + +ATF_TESTS_C+= uint128_test + +# Test Chacha CTR behavior <-> uint128 +LDADD.uint128_test+= ${SDEVRANDOM}/hash.c +LDFLAGS.uint128_test+= -Wno-unused-parameter + +# hash.c deps: +LIBADD.uint128_test+= md # SHA256 +LDADD.uint128_test+= ${SRCTOP}/sys/crypto/rijndael/rijndael-alg-fst.c +LDADD.uint128_test+= ${SRCTOP}/sys/crypto/rijndael/rijndael-api-fst.c +LDFLAGS.uint128_test+= -Wno-cast-align + + +.include diff --git a/tests/sys/devrandom/uint128_test.c b/tests/sys/devrandom/uint128_test.c new file mode 100644 index 000000000000..0e02b227f668 --- /dev/null +++ b/tests/sys/devrandom/uint128_test.c @@ -0,0 +1,225 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * + * Copyright (c) 2019 Conrad Meyer + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include + +#include +#include +#include +#include + +#include +#include +#include + +#include +#include + +#include + +static void +vec_u32_tole128(uint8_t dst[static 16], const uint32_t src[static 4]) +{ + le32enc(dst, src[0]); + le32enc(&dst[4], src[1]); + le32enc(&dst[8], src[2]); + le32enc(&dst[12], src[3]); +} + +static void +le128_to_vec_u32(uint32_t dst[static 4], const uint8_t src[static 16]) +{ + dst[0] = le32dec(src); + dst[1] = le32dec(&src[4]); + dst[2] = le32dec(&src[8]); + dst[3] = le32dec(&src[12]); +} + +static void +formatu128(char buf[static 52], uint128_t x) +{ + uint8_t le128x[16]; + uint32_t vx[4]; + size_t sz, i; + int rc; + + le128enc(le128x, x); + le128_to_vec_u32(vx, le128x); + + sz = 52; + for (i = 0; i < 4; i++) { + rc = snprintf(buf, sz, "0x%x ", vx[i]); + ATF_REQUIRE(rc > 0 && (size_t)rc < sz); + + buf += rc; + sz -= rc; + } + /* Delete last trailing space */ + buf[-1] = '\0'; +} + +static void +u128_check_equality(uint128_t a, uint128_t b, const char *descr) +{ + char fmtbufa[52], fmtbufb[52]; + + formatu128(fmtbufa, a); + formatu128(fmtbufb, b); + + ATF_CHECK_MSG(uint128_equals(a, b), + "Expected: [%s] != Actual: [%s]: %s", fmtbufa, fmtbufb, descr); +} + +ATF_TC_WITHOUT_HEAD(uint128_inc); +ATF_TC_BODY(uint128_inc, tc) +{ + static const struct u128_inc_tc { + uint32_t input[4]; + uint32_t expected[4]; + const char *descr; + } tests[] = { + { + .input = { 0, 0, 0, 0 }, + .expected = { 1, 0, 0, 0 }, + .descr = "0 -> 1", + }, + { + .input = { 1, 0, 0, 0 }, + .expected = { 2, 0, 0, 0 }, + .descr = "0 -> 2", + }, + { + .input = { 0xff, 0, 0, 0 }, + .expected = { 0x100, 0, 0, 0 }, + .descr = "0xff -> 0x100 (byte carry)", + }, + { + .input = { UINT32_MAX, 0, 0, 0 }, + .expected = { 0, 1, 0, 0 }, + .descr = "2^32 - 1 -> 2^32 (word carry)", + }, + { + .input = { UINT32_MAX, UINT32_MAX, 0, 0 }, + .expected = { 0, 0, 1, 0 }, + .descr = "2^64 - 1 -> 2^64 (u128t_word0 carry)", + }, + { + .input = { UINT32_MAX, UINT32_MAX, UINT32_MAX, 0 }, + .expected = { 0, 0, 0, 1 }, + .descr = "2^96 - 1 -> 2^96 (word carry)", + }, + }; + uint8_t inputle[16], expectedle[16]; + uint128_t a; + size_t i; + + for (i = 0; i < nitems(tests); i++) { + vec_u32_tole128(inputle, tests[i].input); + vec_u32_tole128(expectedle, tests[i].expected); + + a = le128dec(inputle); + uint128_increment(&a); + u128_check_equality(le128dec(expectedle), a, tests[i].descr); + } +} + +/* + * Test assumptions about Chacha incrementing counter in the same way as + * uint128.h + */ +ATF_TC_WITHOUT_HEAD(uint128_chacha_ctr); +ATF_TC_BODY(uint128_chacha_ctr, tc) +{ + static const struct u128_chacha_tc { + uint32_t input[4]; + uint32_t expected[4]; + const char *descr; + } tests[] = { + { + .input = { 0, 0, 0, 0 }, + .expected = { 1, 0, 0, 0 }, + .descr = "Single block", + }, + { + .input = { 1, 0, 0, 0 }, + .expected = { 2, 0, 0, 0 }, + .descr = "0 -> 2", + }, + { + .input = { 0xff, 0, 0, 0 }, + .expected = { 0x100, 0, 0, 0 }, + .descr = "0xff -> 0x100 (byte carry)", + }, + { + .input = { UINT32_MAX, 0, 0, 0 }, + .expected = { 0, 1, 0, 0 }, + .descr = "2^32 - 1 -> 2^32 (word carry)", + }, + { + .input = { UINT32_MAX, UINT32_MAX, 0, 0 }, + .expected = { 0, 0, 1, 0 }, + .descr = "2^64 - 1 -> 2^64 (u128t_word0 carry)", + }, + { + .input = { UINT32_MAX, UINT32_MAX, UINT32_MAX, 0 }, + .expected = { 0, 0, 0, 1 }, + .descr = "2^96 - 1 -> 2^96 (word carry)", + }, + }; + union randomdev_key context; + uint8_t inputle[16], expectedle[16], trash[CHACHA_BLOCKLEN]; + uint8_t notrandomkey[RANDOM_KEYSIZE] = { 0 }; + uint128_t a; + size_t i; + + random_chachamode = true; + randomdev_encrypt_init(&context, notrandomkey); + + for (i = 0; i < nitems(tests); i++) { + vec_u32_tole128(inputle, tests[i].input); + vec_u32_tole128(expectedle, tests[i].expected); + + a = le128dec(inputle); + randomdev_keystream(&context, &a, trash, sizeof(trash) / + RANDOM_BLOCKSIZE); + u128_check_equality(le128dec(expectedle), a, tests[i].descr); + } + +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, uint128_inc); + ATF_TP_ADD_TC(tp, uint128_chacha_ctr); + return (atf_no_error()); +}