From d7e5f516f9df3383ca1263a4258e915ff9df02b8 Mon Sep 17 00:00:00 2001 From: Jaromil Date: Wed, 17 Jul 2024 07:51:16 +0200 Subject: [PATCH] refine fuzzer functions in separate source file add random byte xor TODO: change function names in fuzz_(random|begin|end)_(byte|bit) and optional suffix _xor --- build/meson.build | 1 + src/Makefile | 2 +- src/zen_fuzzer.c | 94 ++++++++++++++++++++++++++++++++++++++++++++ src/zen_fuzzer.h | 22 +++++++++++ src/zen_octet.c | 42 ++++---------------- test/lua/fuzzing.lua | 25 ++++++++++++ 6 files changed, 150 insertions(+), 36 deletions(-) create mode 100644 src/zen_fuzzer.c create mode 100644 src/zen_fuzzer.h create mode 100644 test/lua/fuzzing.lua diff --git a/build/meson.build b/build/meson.build index 6715363fd..0fe45a9f9 100644 --- a/build/meson.build +++ b/build/meson.build @@ -99,6 +99,7 @@ zenroom_src = [ '../src/zen_octet.c', '../src/zen_parse.c', '../src/zen_random.c', + '../src/zen_fuzzer.c', '../src/zenroom.c', '../src/zen_rsa.c', '../src/zen_ecdh_factory.c', diff --git a/src/Makefile b/src/Makefile index 0ff2bd379..0b598cf7a 100644 --- a/src/Makefile +++ b/src/Makefile @@ -50,7 +50,7 @@ SOURCES := \ zen_fp12.o zen_random.o zen_hash.o \ zen_ecdh_factory.o zen_ecdh.o \ zen_aes.o zen_qp.o zen_ed.o zen_float.o zen_time.o \ - api_hash.o randombytes.o \ + api_hash.o randombytes.o zen_fuzzer.o \ cortex_m.o p256-m.o zen_p256.o zen_rsa.o cortex_m_boot.o: $(CORTEX_M_SRC_ASM) diff --git a/src/zen_fuzzer.c b/src/zen_fuzzer.c new file mode 100644 index 000000000..75e5ebcdb --- /dev/null +++ b/src/zen_fuzzer.c @@ -0,0 +1,94 @@ +/* This file is part of Zenroom (https://zenroom.org) + * + * Copyright (C) 2024 Dyne.org foundation + * designed, written and maintained by Denis Roio + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * + */ + +#include +#include +#include + +#include + +#include + +#include +#include +#include + +int fuzz_byte_random(lua_State *L) { + BEGIN(); + octet *o = o_arg(L,1); SAFE(o); + if(o->len >= INT_MAX) { + o_free(L,o); + THROW("fuzz_byte: octet too big"); + END(0); + } + octet *res = o_dup(L,o); + Z(L); + if(res->len < 256) { + uint8_t point8 = RAND_byte(Z->random_generator); + res->val[point8%res->len] = RAND_byte(Z->random_generator); + } else if(res->len < 65535) { + uint16_t point16 = + RAND_byte(Z->random_generator) + | (uint32_t) RAND_byte(Z->random_generator) << 8; + res->val[point16%res->len] = RAND_byte(Z->random_generator); + } else if(res->len < (int)0xffffffff) { + uint32_t point32 = + RAND_byte(Z->random_generator) + | (uint32_t) RAND_byte(Z->random_generator) << 8 + | (uint32_t) RAND_byte(Z->random_generator) << 16 + | (uint32_t) RAND_byte(Z->random_generator) << 24; + res->val[point32%res->len] = RAND_byte(Z->random_generator); + } + o_free(L,o); + END(1); +} + + +int fuzz_byte_xor(lua_State *L) { + BEGIN(); + octet *o = o_arg(L,1); SAFE(o); + if(o->len >= INT_MAX) { + o_free(L,o); + THROW("fuzz_byte: octet too big"); + END(0); + } + octet *res = o_dup(L,o); + Z(L); + if(res->len < 256) { + uint8_t point8 = RAND_byte(Z->random_generator) % res->len; + res->val[point8] ^= 0xff; + } else if(res->len < 65535) { + uint16_t point16 = + RAND_byte(Z->random_generator) + | (uint32_t) RAND_byte(Z->random_generator) << 8; + point16 %= res->len; + res->val[point16] ^= 0xff; + } else if(res->len < INT_MAX) { + uint32_t point32 = + RAND_byte(Z->random_generator) + | (uint32_t) RAND_byte(Z->random_generator) << 8 + | (uint32_t) RAND_byte(Z->random_generator) << 16 + | (uint32_t) RAND_byte(Z->random_generator) << 24; + point32 %= res->len; + res->val[point32] ^= 0xff; + } + o_free(L,o); + END(1); +} diff --git a/src/zen_fuzzer.h b/src/zen_fuzzer.h new file mode 100644 index 000000000..186b0a621 --- /dev/null +++ b/src/zen_fuzzer.h @@ -0,0 +1,22 @@ +/* This file is part of Zenroom (https://zenroom.org) + * + * Copyright (C) 2024 Dyne.org foundation + * designed, written and maintained by Denis Roio + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * + */ + +int fuzz_byte_random(lua_State *L); +int fuzz_byte_xor(lua_State *L); diff --git a/src/zen_octet.c b/src/zen_octet.c index f77062013..3a5595f52 100644 --- a/src/zen_octet.c +++ b/src/zen_octet.c @@ -1,6 +1,6 @@ -/* This file is part of Zenroom (https://zenroom.dyne.org) +/* This file is part of Zenroom (https://zenroom.org) * - * Copyright (C) 2017-2021 Dyne.org foundation + * Copyright (C) 2017-2024 Dyne.org foundation * designed, written and maintained by Denis Roio * * This program is free software: you can redistribute it and/or modify @@ -73,7 +73,7 @@ #include #include #include - +#include #include #include // for log2 in entropy calculation @@ -2000,36 +2000,6 @@ static int lesser_than(lua_State *L) { END(1); } -static int fuzz_byte(lua_State *L) { - BEGIN(); - octet *o = o_arg(L,1); SAFE(o); - if(o->len >= 4294967295) { - o_free(L,o); - THROW("fuzz_byte: octet too big"); - END(0); - } - octet *res = o_dup(L,o); - Z(L); - if(res->len < 256) { - uint8_t point8 = RAND_byte(Z->random_generator); - res->val[point8%res->len] = RAND_byte(Z->random_generator); - } else if(res->len < 65535) { - uint16_t point16 = - RAND_byte(Z->random_generator) - | (uint32_t) RAND_byte(Z->random_generator) << 8; - res->val[point16%res->len] = RAND_byte(Z->random_generator); - } else if(res->len < 4294967295) { - uint32_t point32 = - RAND_byte(Z->random_generator) - | (uint32_t) RAND_byte(Z->random_generator) << 8 - | (uint32_t) RAND_byte(Z->random_generator) << 16 - | (uint32_t) RAND_byte(Z->random_generator) << 24; - res->val[point32%res->len] = RAND_byte(Z->random_generator); - } - o_free(L,o); - END(1); -} - int luaopen_octet(lua_State *L) { (void)L; const struct luaL_Reg octet_class[] = { @@ -2088,7 +2058,8 @@ int luaopen_octet(lua_State *L) { {"popcount_hamming", popcount_hamming_distance}, {"to_segwit", to_segwit_address}, {"from_segwit", from_segwit_address}, - {"fuzz_byte", fuzz_byte}, + {"fuzz_byte", fuzz_byte_random}, + {"fuzz_byte_xor", fuzz_byte_xor}, {NULL,NULL} }; const struct luaL_Reg octet_methods[] = { @@ -2125,7 +2096,8 @@ int luaopen_octet(lua_State *L) { {"compact_ascii", compact_ascii}, {"elide_at_start", elide_at_start}, {"fillrepeat", fillrepeat}, - {"fuzz_byte", fuzz_byte}, + {"fuzz_byte", fuzz_byte_random}, + {"fuzz_byte_xor", fuzz_byte_xor}, // {"zcash_topoint", zcash_topoint}, // idiomatic operators {"__len",size}, diff --git a/test/lua/fuzzing.lua b/test/lua/fuzzing.lua new file mode 100644 index 000000000..5996bd228 --- /dev/null +++ b/test/lua/fuzzing.lua @@ -0,0 +1,25 @@ +print 'test octet fuzzing functions' + +r = OCTET.random(200) +l = r:fuzz_byte() +assert(l ~= r) + +r = OCTET.random(2000) +l = r:fuzz_byte() +assert(l ~= r) + +r = OCTET.random(700000) +l = r:fuzz_byte() +assert(l ~= r) + +r = OCTET.random(200) +l = r:fuzz_byte_xor() +assert(r:hamming(l)==8) + +r = OCTET.random(2000) +l = r:fuzz_byte_xor() +assert(r:hamming(l)==8) + +r = OCTET.random(700000) +l = r:fuzz_byte_xor() +assert(r:hamming(l)==8)