1*403c0413SConrad Meyer /*- 2*403c0413SConrad Meyer * SPDX-License-Identifier: BSD-2-Clause-FreeBSD 3*403c0413SConrad Meyer * 4*403c0413SConrad Meyer * Copyright (c) 2019 Conrad Meyer <cem@FreeBSD.org> 5*403c0413SConrad Meyer * All rights reserved. 6*403c0413SConrad Meyer * 7*403c0413SConrad Meyer * Redistribution and use in source and binary forms, with or without 8*403c0413SConrad Meyer * modification, are permitted provided that the following conditions 9*403c0413SConrad Meyer * are met: 10*403c0413SConrad Meyer * 1. Redistributions of source code must retain the above copyright 11*403c0413SConrad Meyer * notice, this list of conditions and the following disclaimer. 12*403c0413SConrad Meyer * 2. Redistributions in binary form must reproduce the above copyright 13*403c0413SConrad Meyer * notice, this list of conditions and the following disclaimer in the 14*403c0413SConrad Meyer * documentation and/or other materials provided with the distribution. 15*403c0413SConrad Meyer * 16*403c0413SConrad Meyer * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 17*403c0413SConrad Meyer * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18*403c0413SConrad Meyer * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19*403c0413SConrad Meyer * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 20*403c0413SConrad Meyer * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21*403c0413SConrad Meyer * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22*403c0413SConrad Meyer * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23*403c0413SConrad Meyer * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24*403c0413SConrad Meyer * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25*403c0413SConrad Meyer * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26*403c0413SConrad Meyer * SUCH DAMAGE. 27*403c0413SConrad Meyer */ 28*403c0413SConrad Meyer 29*403c0413SConrad Meyer #include <sys/cdefs.h> 30*403c0413SConrad Meyer __FBSDID("$FreeBSD$"); 31*403c0413SConrad Meyer 32*403c0413SConrad Meyer #include <sys/param.h> 33*403c0413SConrad Meyer #include <sys/random.h> 34*403c0413SConrad Meyer 35*403c0413SConrad Meyer #include <errno.h> 36*403c0413SConrad Meyer #include <stdint.h> 37*403c0413SConrad Meyer #include <stdio.h> 38*403c0413SConrad Meyer #include <stdbool.h> 39*403c0413SConrad Meyer 40*403c0413SConrad Meyer #include <crypto/chacha20/chacha.h> 41*403c0413SConrad Meyer #include <crypto/rijndael/rijndael-api-fst.h> 42*403c0413SConrad Meyer #include <crypto/sha2/sha256.h> 43*403c0413SConrad Meyer 44*403c0413SConrad Meyer #include <dev/random/hash.h> 45*403c0413SConrad Meyer #include <dev/random/uint128.h> 46*403c0413SConrad Meyer 47*403c0413SConrad Meyer #include <atf-c.h> 48*403c0413SConrad Meyer 49*403c0413SConrad Meyer static void 50*403c0413SConrad Meyer vec_u32_tole128(uint8_t dst[static 16], const uint32_t src[static 4]) 51*403c0413SConrad Meyer { 52*403c0413SConrad Meyer le32enc(dst, src[0]); 53*403c0413SConrad Meyer le32enc(&dst[4], src[1]); 54*403c0413SConrad Meyer le32enc(&dst[8], src[2]); 55*403c0413SConrad Meyer le32enc(&dst[12], src[3]); 56*403c0413SConrad Meyer } 57*403c0413SConrad Meyer 58*403c0413SConrad Meyer static void 59*403c0413SConrad Meyer le128_to_vec_u32(uint32_t dst[static 4], const uint8_t src[static 16]) 60*403c0413SConrad Meyer { 61*403c0413SConrad Meyer dst[0] = le32dec(src); 62*403c0413SConrad Meyer dst[1] = le32dec(&src[4]); 63*403c0413SConrad Meyer dst[2] = le32dec(&src[8]); 64*403c0413SConrad Meyer dst[3] = le32dec(&src[12]); 65*403c0413SConrad Meyer } 66*403c0413SConrad Meyer 67*403c0413SConrad Meyer static void 68*403c0413SConrad Meyer formatu128(char buf[static 52], uint128_t x) 69*403c0413SConrad Meyer { 70*403c0413SConrad Meyer uint8_t le128x[16]; 71*403c0413SConrad Meyer uint32_t vx[4]; 72*403c0413SConrad Meyer size_t sz, i; 73*403c0413SConrad Meyer int rc; 74*403c0413SConrad Meyer 75*403c0413SConrad Meyer le128enc(le128x, x); 76*403c0413SConrad Meyer le128_to_vec_u32(vx, le128x); 77*403c0413SConrad Meyer 78*403c0413SConrad Meyer sz = 52; 79*403c0413SConrad Meyer for (i = 0; i < 4; i++) { 80*403c0413SConrad Meyer rc = snprintf(buf, sz, "0x%x ", vx[i]); 81*403c0413SConrad Meyer ATF_REQUIRE(rc > 0 && (size_t)rc < sz); 82*403c0413SConrad Meyer 83*403c0413SConrad Meyer buf += rc; 84*403c0413SConrad Meyer sz -= rc; 85*403c0413SConrad Meyer } 86*403c0413SConrad Meyer /* Delete last trailing space */ 87*403c0413SConrad Meyer buf[-1] = '\0'; 88*403c0413SConrad Meyer } 89*403c0413SConrad Meyer 90*403c0413SConrad Meyer static void 91*403c0413SConrad Meyer u128_check_equality(uint128_t a, uint128_t b, const char *descr) 92*403c0413SConrad Meyer { 93*403c0413SConrad Meyer char fmtbufa[52], fmtbufb[52]; 94*403c0413SConrad Meyer 95*403c0413SConrad Meyer formatu128(fmtbufa, a); 96*403c0413SConrad Meyer formatu128(fmtbufb, b); 97*403c0413SConrad Meyer 98*403c0413SConrad Meyer ATF_CHECK_MSG(uint128_equals(a, b), 99*403c0413SConrad Meyer "Expected: [%s] != Actual: [%s]: %s", fmtbufa, fmtbufb, descr); 100*403c0413SConrad Meyer } 101*403c0413SConrad Meyer 102*403c0413SConrad Meyer ATF_TC_WITHOUT_HEAD(uint128_inc); 103*403c0413SConrad Meyer ATF_TC_BODY(uint128_inc, tc) 104*403c0413SConrad Meyer { 105*403c0413SConrad Meyer static const struct u128_inc_tc { 106*403c0413SConrad Meyer uint32_t input[4]; 107*403c0413SConrad Meyer uint32_t expected[4]; 108*403c0413SConrad Meyer const char *descr; 109*403c0413SConrad Meyer } tests[] = { 110*403c0413SConrad Meyer { 111*403c0413SConrad Meyer .input = { 0, 0, 0, 0 }, 112*403c0413SConrad Meyer .expected = { 1, 0, 0, 0 }, 113*403c0413SConrad Meyer .descr = "0 -> 1", 114*403c0413SConrad Meyer }, 115*403c0413SConrad Meyer { 116*403c0413SConrad Meyer .input = { 1, 0, 0, 0 }, 117*403c0413SConrad Meyer .expected = { 2, 0, 0, 0 }, 118*403c0413SConrad Meyer .descr = "0 -> 2", 119*403c0413SConrad Meyer }, 120*403c0413SConrad Meyer { 121*403c0413SConrad Meyer .input = { 0xff, 0, 0, 0 }, 122*403c0413SConrad Meyer .expected = { 0x100, 0, 0, 0 }, 123*403c0413SConrad Meyer .descr = "0xff -> 0x100 (byte carry)", 124*403c0413SConrad Meyer }, 125*403c0413SConrad Meyer { 126*403c0413SConrad Meyer .input = { UINT32_MAX, 0, 0, 0 }, 127*403c0413SConrad Meyer .expected = { 0, 1, 0, 0 }, 128*403c0413SConrad Meyer .descr = "2^32 - 1 -> 2^32 (word carry)", 129*403c0413SConrad Meyer }, 130*403c0413SConrad Meyer { 131*403c0413SConrad Meyer .input = { UINT32_MAX, UINT32_MAX, 0, 0 }, 132*403c0413SConrad Meyer .expected = { 0, 0, 1, 0 }, 133*403c0413SConrad Meyer .descr = "2^64 - 1 -> 2^64 (u128t_word0 carry)", 134*403c0413SConrad Meyer }, 135*403c0413SConrad Meyer { 136*403c0413SConrad Meyer .input = { UINT32_MAX, UINT32_MAX, UINT32_MAX, 0 }, 137*403c0413SConrad Meyer .expected = { 0, 0, 0, 1 }, 138*403c0413SConrad Meyer .descr = "2^96 - 1 -> 2^96 (word carry)", 139*403c0413SConrad Meyer }, 140*403c0413SConrad Meyer }; 141*403c0413SConrad Meyer uint8_t inputle[16], expectedle[16]; 142*403c0413SConrad Meyer uint128_t a; 143*403c0413SConrad Meyer size_t i; 144*403c0413SConrad Meyer 145*403c0413SConrad Meyer for (i = 0; i < nitems(tests); i++) { 146*403c0413SConrad Meyer vec_u32_tole128(inputle, tests[i].input); 147*403c0413SConrad Meyer vec_u32_tole128(expectedle, tests[i].expected); 148*403c0413SConrad Meyer 149*403c0413SConrad Meyer a = le128dec(inputle); 150*403c0413SConrad Meyer uint128_increment(&a); 151*403c0413SConrad Meyer u128_check_equality(le128dec(expectedle), a, tests[i].descr); 152*403c0413SConrad Meyer } 153*403c0413SConrad Meyer } 154*403c0413SConrad Meyer 155*403c0413SConrad Meyer /* 156*403c0413SConrad Meyer * Test assumptions about Chacha incrementing counter in the same way as 157*403c0413SConrad Meyer * uint128.h 158*403c0413SConrad Meyer */ 159*403c0413SConrad Meyer ATF_TC_WITHOUT_HEAD(uint128_chacha_ctr); 160*403c0413SConrad Meyer ATF_TC_BODY(uint128_chacha_ctr, tc) 161*403c0413SConrad Meyer { 162*403c0413SConrad Meyer static const struct u128_chacha_tc { 163*403c0413SConrad Meyer uint32_t input[4]; 164*403c0413SConrad Meyer uint32_t expected[4]; 165*403c0413SConrad Meyer const char *descr; 166*403c0413SConrad Meyer } tests[] = { 167*403c0413SConrad Meyer { 168*403c0413SConrad Meyer .input = { 0, 0, 0, 0 }, 169*403c0413SConrad Meyer .expected = { 1, 0, 0, 0 }, 170*403c0413SConrad Meyer .descr = "Single block", 171*403c0413SConrad Meyer }, 172*403c0413SConrad Meyer { 173*403c0413SConrad Meyer .input = { 1, 0, 0, 0 }, 174*403c0413SConrad Meyer .expected = { 2, 0, 0, 0 }, 175*403c0413SConrad Meyer .descr = "0 -> 2", 176*403c0413SConrad Meyer }, 177*403c0413SConrad Meyer { 178*403c0413SConrad Meyer .input = { 0xff, 0, 0, 0 }, 179*403c0413SConrad Meyer .expected = { 0x100, 0, 0, 0 }, 180*403c0413SConrad Meyer .descr = "0xff -> 0x100 (byte carry)", 181*403c0413SConrad Meyer }, 182*403c0413SConrad Meyer { 183*403c0413SConrad Meyer .input = { UINT32_MAX, 0, 0, 0 }, 184*403c0413SConrad Meyer .expected = { 0, 1, 0, 0 }, 185*403c0413SConrad Meyer .descr = "2^32 - 1 -> 2^32 (word carry)", 186*403c0413SConrad Meyer }, 187*403c0413SConrad Meyer { 188*403c0413SConrad Meyer .input = { UINT32_MAX, UINT32_MAX, 0, 0 }, 189*403c0413SConrad Meyer .expected = { 0, 0, 1, 0 }, 190*403c0413SConrad Meyer .descr = "2^64 - 1 -> 2^64 (u128t_word0 carry)", 191*403c0413SConrad Meyer }, 192*403c0413SConrad Meyer { 193*403c0413SConrad Meyer .input = { UINT32_MAX, UINT32_MAX, UINT32_MAX, 0 }, 194*403c0413SConrad Meyer .expected = { 0, 0, 0, 1 }, 195*403c0413SConrad Meyer .descr = "2^96 - 1 -> 2^96 (word carry)", 196*403c0413SConrad Meyer }, 197*403c0413SConrad Meyer }; 198*403c0413SConrad Meyer union randomdev_key context; 199*403c0413SConrad Meyer uint8_t inputle[16], expectedle[16], trash[CHACHA_BLOCKLEN]; 200*403c0413SConrad Meyer uint8_t notrandomkey[RANDOM_KEYSIZE] = { 0 }; 201*403c0413SConrad Meyer uint128_t a; 202*403c0413SConrad Meyer size_t i; 203*403c0413SConrad Meyer 204*403c0413SConrad Meyer random_chachamode = true; 205*403c0413SConrad Meyer randomdev_encrypt_init(&context, notrandomkey); 206*403c0413SConrad Meyer 207*403c0413SConrad Meyer for (i = 0; i < nitems(tests); i++) { 208*403c0413SConrad Meyer vec_u32_tole128(inputle, tests[i].input); 209*403c0413SConrad Meyer vec_u32_tole128(expectedle, tests[i].expected); 210*403c0413SConrad Meyer 211*403c0413SConrad Meyer a = le128dec(inputle); 212*403c0413SConrad Meyer randomdev_keystream(&context, &a, trash, sizeof(trash) / 213*403c0413SConrad Meyer RANDOM_BLOCKSIZE); 214*403c0413SConrad Meyer u128_check_equality(le128dec(expectedle), a, tests[i].descr); 215*403c0413SConrad Meyer } 216*403c0413SConrad Meyer 217*403c0413SConrad Meyer } 218*403c0413SConrad Meyer 219*403c0413SConrad Meyer ATF_TP_ADD_TCS(tp) 220*403c0413SConrad Meyer { 221*403c0413SConrad Meyer 222*403c0413SConrad Meyer ATF_TP_ADD_TC(tp, uint128_inc); 223*403c0413SConrad Meyer ATF_TP_ADD_TC(tp, uint128_chacha_ctr); 224*403c0413SConrad Meyer return (atf_no_error()); 225*403c0413SConrad Meyer } 226