Path: blob/main/tests/sys/devrandom/uint128_test.c
39535 views
/*-1* SPDX-License-Identifier: BSD-2-Clause2*3* Copyright (c) 2019 Conrad Meyer <[email protected]>4* All rights reserved.5*6* Redistribution and use in source and binary forms, with or without7* modification, are permitted provided that the following conditions8* are met:9* 1. Redistributions of source code must retain the above copyright10* notice, this list of conditions and the following disclaimer.11* 2. Redistributions in binary form must reproduce the above copyright12* notice, this list of conditions and the following disclaimer in the13* documentation and/or other materials provided with the distribution.14*15* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND16* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE17* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE18* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE19* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL20* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS21* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)22* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT23* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY24* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF25* SUCH DAMAGE.26*/2728#include <sys/param.h>29#include <sys/random.h>3031#include <errno.h>32#include <stdint.h>33#include <stdio.h>34#include <stdbool.h>3536#include <crypto/chacha20/chacha.h>37#include <crypto/rijndael/rijndael-api-fst.h>38#include <crypto/sha2/sha256.h>3940#include <dev/random/hash.h>41#include <dev/random/uint128.h>4243#include <atf-c.h>4445static void46vec_u32_tole128(uint8_t dst[static 16], const uint32_t src[static 4])47{48le32enc(dst, src[0]);49le32enc(&dst[4], src[1]);50le32enc(&dst[8], src[2]);51le32enc(&dst[12], src[3]);52}5354static void55le128_to_vec_u32(uint32_t dst[static 4], const uint8_t src[static 16])56{57dst[0] = le32dec(src);58dst[1] = le32dec(&src[4]);59dst[2] = le32dec(&src[8]);60dst[3] = le32dec(&src[12]);61}6263static void64formatu128(char buf[static 52], uint128_t x)65{66uint8_t le128x[16];67uint32_t vx[4];68size_t sz, i;69int rc;7071le128enc(le128x, x);72le128_to_vec_u32(vx, le128x);7374sz = 52;75for (i = 0; i < 4; i++) {76rc = snprintf(buf, sz, "0x%x ", vx[i]);77ATF_REQUIRE(rc > 0 && (size_t)rc < sz);7879buf += rc;80sz -= rc;81}82/* Delete last trailing space */83buf[-1] = '\0';84}8586static void87u128_check_equality(uint128_t a, uint128_t b, const char *descr)88{89char fmtbufa[52], fmtbufb[52];9091formatu128(fmtbufa, a);92formatu128(fmtbufb, b);9394ATF_CHECK_MSG(uint128_equals(a, b),95"Expected: [%s] != Actual: [%s]: %s", fmtbufa, fmtbufb, descr);96}9798ATF_TC_WITHOUT_HEAD(uint128_inc);99ATF_TC_BODY(uint128_inc, tc)100{101static const struct u128_inc_tc {102uint32_t input[4];103uint32_t expected[4];104const char *descr;105} tests[] = {106{107.input = { 0, 0, 0, 0 },108.expected = { 1, 0, 0, 0 },109.descr = "0 -> 1",110},111{112.input = { 1, 0, 0, 0 },113.expected = { 2, 0, 0, 0 },114.descr = "0 -> 2",115},116{117.input = { 0xff, 0, 0, 0 },118.expected = { 0x100, 0, 0, 0 },119.descr = "0xff -> 0x100 (byte carry)",120},121{122.input = { UINT32_MAX, 0, 0, 0 },123.expected = { 0, 1, 0, 0 },124.descr = "2^32 - 1 -> 2^32 (word carry)",125},126{127.input = { UINT32_MAX, UINT32_MAX, 0, 0 },128.expected = { 0, 0, 1, 0 },129.descr = "2^64 - 1 -> 2^64 (u128t_word0 carry)",130},131{132.input = { UINT32_MAX, UINT32_MAX, UINT32_MAX, 0 },133.expected = { 0, 0, 0, 1 },134.descr = "2^96 - 1 -> 2^96 (word carry)",135},136};137uint8_t inputle[16], expectedle[16];138uint128_t a;139size_t i;140141for (i = 0; i < nitems(tests); i++) {142vec_u32_tole128(inputle, tests[i].input);143vec_u32_tole128(expectedle, tests[i].expected);144145a = le128dec(inputle);146uint128_increment(&a);147u128_check_equality(le128dec(expectedle), a, tests[i].descr);148}149}150151ATF_TC_WITHOUT_HEAD(uint128_add64);152ATF_TC_BODY(uint128_add64, tc)153{154static const struct u128_add64_tc {155uint32_t input[4];156uint64_t addend;157uint32_t expected[4];158const char *descr;159} tests[] = {160{161.input = { 0, 0, 0, 0 },162.addend = 1,163.expected = { 1, 0, 0, 0 },164.descr = "0 + 1 -> 1",165},166{167.input = { 1, 0, 0, 0 },168.addend = UINT32_MAX,169.expected = { 0, 1, 0, 0 },170.descr = "1 + (2^32 - 1) -> 2^32 (word carry)",171},172{173.input = { 1, 0, 0, 0 },174.addend = UINT64_MAX,175.expected = { 0, 0, 1, 0 },176.descr = "1 + (2^64 - 1) -> 2^64 (u128t_word0 carry)",177},178{179.input = { 0x11111111, 0x11111111, 0, 0 },180.addend = 0xf0123456789abcdeULL,181.expected = { 0x89abcdef, 0x01234567, 1, 0 },182.descr = "0x1111_1111_1111_1111 +"183"0xf012_3456_789a_bcde ->"184"0x1_0123_4567_89ab_cdef",185},186{187.input = { 1, 0, UINT32_MAX, 0 },188.addend = UINT64_MAX,189.expected = { 0, 0, 0, 1 },190.descr = "Carry ~2^96",191},192};193uint8_t inputle[16], expectedle[16];194uint128_t a;195size_t i;196197for (i = 0; i < nitems(tests); i++) {198vec_u32_tole128(inputle, tests[i].input);199vec_u32_tole128(expectedle, tests[i].expected);200201a = le128dec(inputle);202uint128_add64(&a, tests[i].addend);203u128_check_equality(le128dec(expectedle), a, tests[i].descr);204}205}206207/*208* Test assumptions about Chacha incrementing counter in the same way as209* uint128.h210*/211ATF_TC_WITHOUT_HEAD(uint128_chacha_ctr);212ATF_TC_BODY(uint128_chacha_ctr, tc)213{214static const struct u128_chacha_tc {215uint32_t input[4];216uint32_t expected[4];217const char *descr;218} tests[] = {219{220.input = { 0, 0, 0, 0 },221.expected = { 1, 0, 0, 0 },222.descr = "Single block",223},224{225.input = { 1, 0, 0, 0 },226.expected = { 2, 0, 0, 0 },227.descr = "0 -> 2",228},229{230.input = { 0xff, 0, 0, 0 },231.expected = { 0x100, 0, 0, 0 },232.descr = "0xff -> 0x100 (byte carry)",233},234{235.input = { UINT32_MAX, 0, 0, 0 },236.expected = { 0, 1, 0, 0 },237.descr = "2^32 - 1 -> 2^32 (word carry)",238},239{240.input = { UINT32_MAX, UINT32_MAX, 0, 0 },241.expected = { 0, 0, 1, 0 },242.descr = "2^64 - 1 -> 2^64 (u128t_word0 carry)",243},244{245.input = { UINT32_MAX, UINT32_MAX, UINT32_MAX, 0 },246.expected = { 0, 0, 0, 1 },247.descr = "2^96 - 1 -> 2^96 (word carry)",248},249};250union randomdev_key context;251uint8_t inputle[16], expectedle[16], trash[CHACHA_BLOCKLEN];252uint8_t notrandomkey[RANDOM_KEYSIZE] = { 0 };253uint128_t a;254size_t i;255256random_chachamode = true;257randomdev_encrypt_init(&context, notrandomkey);258259for (i = 0; i < nitems(tests); i++) {260vec_u32_tole128(inputle, tests[i].input);261vec_u32_tole128(expectedle, tests[i].expected);262263a = le128dec(inputle);264randomdev_keystream(&context, &a, trash, sizeof(trash));265u128_check_equality(le128dec(expectedle), a, tests[i].descr);266}267268}269270ATF_TP_ADD_TCS(tp)271{272273ATF_TP_ADD_TC(tp, uint128_inc);274ATF_TP_ADD_TC(tp, uint128_add64);275ATF_TP_ADD_TC(tp, uint128_chacha_ctr);276return (atf_no_error());277}278279280