Mercurial > dropbear
changeset 1756:d5680e12ac33
Move fuzzing code to fuzz/ subdirectory, improve Makefile.in
author | Matt Johnston <matt@ucc.asn.au> |
---|---|
date | Fri, 23 Oct 2020 23:10:20 +0800 |
parents | 7c0fcd19e492 |
children | 517fb7b62438 |
files | Makefile.in configure.ac fuzz-common.c fuzz-harness.c fuzz-hostkeys.c fuzz-wrapfd.c fuzz/fuzz-common.c fuzz/fuzz-harness.c fuzz/fuzz-hostkeys.c fuzz/fuzz-wrapfd.c fuzz/fuzzer-client.c fuzz/fuzzer-client_nomaths.c fuzz/fuzzer-kexcurve25519.c fuzz/fuzzer-kexdh.c fuzz/fuzzer-kexecdh.c fuzz/fuzzer-preauth.c fuzz/fuzzer-preauth_nomaths.c fuzz/fuzzer-pubkey.c fuzz/fuzzer-verify.c fuzzer-client.c fuzzer-client_nomaths.c fuzzer-kexcurve25519.c fuzzer-kexdh.c fuzzer-kexecdh.c fuzzer-preauth.c fuzzer-preauth_nomaths.c fuzzer-pubkey.c fuzzer-verify.c |
diffstat | 28 files changed, 1144 insertions(+), 1162 deletions(-) [+] |
line wrap: on
line diff
--- a/Makefile.in Fri Oct 23 20:53:58 2020 +0800 +++ b/Makefile.in Fri Oct 23 23:10:20 2020 +0800 @@ -62,7 +62,7 @@ SCPOBJS=scp.o progressmeter.o atomicio.o scpmisc.o compat.o ifeq (@DROPBEAR_FUZZ@, 1) - allobjs = $(COMMONOBJS) fuzz-common.o fuzz-wrapfd.o $(CLISVROBJS) $(CLIOBJS) $(SVROBJS) @CRYPTLIB@ + allobjs = $(COMMONOBJS) fuzz/fuzz-common.o fuzz/fuzz-wrapfd.o $(CLISVROBJS) $(CLIOBJS) $(SVROBJS) @CRYPTLIB@ allobjs:=$(subst svr-main.o, ,$(allobjs)) allobjs:=$(subst cli-main.o, ,$(allobjs)) @@ -72,6 +72,7 @@ dropbearconvertobjs=$(allobjs) $(CONVERTOBJS) # CXX only set when fuzzing CXX=@CXX@ + FUZZ_CLEAN=fuzz-clean else dropbearobjs=$(COMMONOBJS) $(CLISVROBJS) $(SVROBJS) dbclientobjs=$(COMMONOBJS) $(CLISVROBJS) $(CLIOBJS) @@ -246,7 +247,7 @@ sizes: dropbear objdump -t dropbear|grep ".text"|cut -d "." -f 2|sort -rn -clean: $(LIBTOM_CLEAN) thisclean +clean: $(LIBTOM_CLEAN) $(FUZZ_CLEAN) thisclean thisclean: -rm -f dropbear$(EXEEXT) dbclient$(EXEEXT) dropbearkey$(EXEEXT) \ @@ -271,47 +272,24 @@ fuzzer-kexdh fuzzer-kexecdh fuzzer-kexcurve25519 fuzzer-client fuzzer-client_nomaths FUZZER_OPTIONS = $(addsuffix .options, $(FUZZ_TARGETS)) +FUZZ_OBJS = $(addprefix fuzz/,$(addsuffix .o,$(FUZZ_TARGETS))) list-fuzz-targets: @echo $(FUZZ_TARGETS) # fuzzers that don't use libfuzzer, just a standalone harness that feeds inputs -fuzzstandalone: FUZZLIB=fuzz-harness.o -fuzzstandalone: fuzz-harness.o fuzz-targets +fuzzstandalone: FUZZLIB=fuzz/fuzz-harness.o +fuzzstandalone: fuzz/fuzz-harness.o fuzz-targets -fuzz-harness.o: $(HEADERS) $(LIBTOM_DEPS) Makefile $(allobjs) fuzz-common.o - -# build all the fuzzers. This will require fail to link unless built with -# make fuzz-targets FUZZLIB=-lFuzzer.a -# or similar - the library provides main(). +# Build all the fuzzers. Usually like +# make fuzz-targets FUZZLIB=-lFuzzer.a +# the library provides main(). Otherwise +# make fuzzstandalone +# provides a main in fuzz-harness.c fuzz-targets: $(FUZZ_TARGETS) $(FUZZER_OPTIONS) -fuzzer-preauth: fuzzer-preauth.o fuzz-harness.o - $(CXX) $(CXXFLAGS) [email protected] $(LDFLAGS) $(allobjs) -o $@$(EXEEXT) $(LIBTOM_LIBS) $(LIBS) $(FUZZLIB) @CRYPTLIB@ - -fuzzer-preauth_nomaths: fuzzer-preauth_nomaths.o fuzz-harness.o - $(CXX) $(CXXFLAGS) [email protected] $(LDFLAGS) $(allobjs) -o $@$(EXEEXT) $(LIBTOM_LIBS) $(LIBS) $(FUZZLIB) @CRYPTLIB@ - -fuzzer-pubkey: fuzzer-pubkey.o fuzz-harness.o - $(CXX) $(CXXFLAGS) [email protected] $(LDFLAGS) $(allobjs) -o $@$(EXEEXT) $(LIBTOM_LIBS) $(LIBS) $(FUZZLIB) @CRYPTLIB@ - -fuzzer-verify: fuzzer-verify.o fuzz-harness.o - $(CXX) $(CXXFLAGS) [email protected] $(LDFLAGS) $(allobjs) -o $@$(EXEEXT) $(LIBTOM_LIBS) $(LIBS) $(FUZZLIB) @CRYPTLIB@ - -fuzzer-kexdh: fuzzer-kexdh.o fuzz-harness.o - $(CXX) $(CXXFLAGS) [email protected] $(LDFLAGS) $(allobjs) -o $@$(EXEEXT) $(LIBTOM_LIBS) $(LIBS) $(FUZZLIB) @CRYPTLIB@ - -fuzzer-kexecdh: fuzzer-kexecdh.o fuzz-harness.o - $(CXX) $(CXXFLAGS) [email protected] $(LDFLAGS) $(allobjs) -o $@$(EXEEXT) $(LIBTOM_LIBS) $(LIBS) $(FUZZLIB) @CRYPTLIB@ - -fuzzer-kexcurve25519: fuzzer-kexcurve25519.o fuzz-harness.o - $(CXX) $(CXXFLAGS) [email protected] $(LDFLAGS) $(allobjs) -o $@$(EXEEXT) $(LIBTOM_LIBS) $(LIBS) $(FUZZLIB) @CRYPTLIB@ - -fuzzer-client: fuzzer-client.o fuzz-harness.o - $(CXX) $(CXXFLAGS) [email protected] $(LDFLAGS) $(allobjs) -o $@$(EXEEXT) $(LIBTOM_LIBS) $(LIBS) $(FUZZLIB) @CRYPTLIB@ - -fuzzer-client_nomaths: fuzzer-client_nomaths.o fuzz-harness.o - $(CXX) $(CXXFLAGS) [email protected] $(LDFLAGS) $(allobjs) -o $@$(EXEEXT) $(LIBTOM_LIBS) $(LIBS) $(FUZZLIB) @CRYPTLIB@ +$(FUZZ_TARGETS): $(FUZZ_OBJS) $(allobjs) $(LIBTOM_DEPS) + $(CXX) $(CXXFLAGS) fuzz/[email protected] $(LDFLAGS) $(allobjs) -o $@$(EXEEXT) $(LIBTOM_LIBS) $(LIBS) $(FUZZLIB) -lcrypt fuzzer-%.options: Makefile echo "[libfuzzer]" > $@ @@ -329,3 +307,6 @@ /usr/bin/xxd -i -a keye >> hostkeys.c /usr/bin/xxd -i -a keyd >> hostkeys.c /usr/bin/xxd -i -a keyed25519 >> hostkeys.c + +fuzz-clean: + -rm -f fuzz/*.o $(FUZZ_TARGETS) $(FUZZER_OPTIONS)
--- a/configure.ac Fri Oct 23 20:53:58 2020 +0800 +++ b/configure.ac Fri Oct 23 23:10:20 2020 +0800 @@ -347,6 +347,7 @@ DROPBEAR_FUZZ=1 # libfuzzer needs linking with c++ libraries AC_PROG_CXX + mkdir -pv fuzz else AC_DEFINE(DROPBEAR_FUZZ, 0, Fuzzing) AC_MSG_NOTICE(Disabling fuzzing)
--- a/fuzz-common.c Fri Oct 23 20:53:58 2020 +0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,311 +0,0 @@ -#include "includes.h" - -#include "includes.h" -#include "fuzz.h" -#include "dbutil.h" -#include "runopts.h" -#include "crypto_desc.h" -#include "session.h" -#include "dbrandom.h" -#include "bignum.h" -#include "atomicio.h" -#include "fuzz-wrapfd.h" - -struct dropbear_fuzz_options fuzz; - -static void fuzz_dropbear_log(int UNUSED(priority), const char* format, va_list param); -static void load_fixed_hostkeys(void); -static void load_fixed_client_key(void); - -void fuzz_common_setup(void) { - disallow_core(); - fuzz.fuzzing = 1; - fuzz.wrapfds = 1; - fuzz.do_jmp = 1; - fuzz.input = m_malloc(sizeof(buffer)); - _dropbear_log = fuzz_dropbear_log; - crypto_init(); - fuzz_seed(); - /* let any messages get flushed */ - setlinebuf(stdout); -} - -int fuzz_set_input(const uint8_t *Data, size_t Size) { - - fuzz.input->data = (unsigned char*)Data; - fuzz.input->size = Size; - fuzz.input->len = Size; - fuzz.input->pos = 0; - - memset(&ses, 0x0, sizeof(ses)); - memset(&svr_ses, 0x0, sizeof(svr_ses)); - memset(&cli_ses, 0x0, sizeof(cli_ses)); - wrapfd_setup(fuzz.input); - - fuzz_seed(); - - return DROPBEAR_SUCCESS; -} - -#if DEBUG_TRACE -static void fuzz_dropbear_log(int UNUSED(priority), const char* format, va_list param) { - if (debug_trace) { - char printbuf[1024]; - vsnprintf(printbuf, sizeof(printbuf), format, param); - fprintf(stderr, "%s\n", printbuf); - } -} -#else -static void fuzz_dropbear_log(int UNUSED(priority), const char* UNUSED(format), va_list UNUSED(param)) { - /* No print */ -} -#endif /* DEBUG_TRACE */ - -void fuzz_svr_setup(void) { - fuzz_common_setup(); - - _dropbear_exit = svr_dropbear_exit; - - char *argv[] = { - "dropbear", - "-E", - }; - - int argc = sizeof(argv) / sizeof(*argv); - svr_getopts(argc, argv); - - load_fixed_hostkeys(); -} - -void fuzz_cli_setup(void) { - fuzz_common_setup(); - - _dropbear_exit = cli_dropbear_exit; - _dropbear_log = cli_dropbear_log; - - char *argv[] = { - "dbclient", - "-y", - "localhost", - "uptime" - }; - - int argc = sizeof(argv) / sizeof(*argv); - cli_getopts(argc, argv); - - load_fixed_client_key(); - /* Avoid password prompt */ - setenv(DROPBEAR_PASSWORD_ENV, "password", 1); -} - -#include "fuzz-hostkeys.c" - -static void load_fixed_client_key(void) { - - buffer *b = buf_new(3000); - sign_key *key; - enum signkey_type keytype; - - key = new_sign_key(); - keytype = DROPBEAR_SIGNKEY_ANY; - buf_putbytes(b, keyed25519, keyed25519_len); - buf_setpos(b, 0); - if (buf_get_priv_key(b, key, &keytype) == DROPBEAR_FAILURE) { - dropbear_exit("failed fixed ed25519 hostkey"); - } - list_append(cli_opts.privkeys, key); - - buf_free(b); -} - -static void load_fixed_hostkeys(void) { - - buffer *b = buf_new(3000); - enum signkey_type type; - - TRACE(("load fixed hostkeys")) - - svr_opts.hostkey = new_sign_key(); - - buf_setlen(b, 0); - buf_putbytes(b, keyr, keyr_len); - buf_setpos(b, 0); - type = DROPBEAR_SIGNKEY_RSA; - if (buf_get_priv_key(b, svr_opts.hostkey, &type) == DROPBEAR_FAILURE) { - dropbear_exit("failed fixed rsa hostkey"); - } - - buf_setlen(b, 0); - buf_putbytes(b, keyd, keyd_len); - buf_setpos(b, 0); - type = DROPBEAR_SIGNKEY_DSS; - if (buf_get_priv_key(b, svr_opts.hostkey, &type) == DROPBEAR_FAILURE) { - dropbear_exit("failed fixed dss hostkey"); - } - - buf_setlen(b, 0); - buf_putbytes(b, keye, keye_len); - buf_setpos(b, 0); - type = DROPBEAR_SIGNKEY_ECDSA_NISTP256; - if (buf_get_priv_key(b, svr_opts.hostkey, &type) == DROPBEAR_FAILURE) { - dropbear_exit("failed fixed ecdsa hostkey"); - } - - buf_setlen(b, 0); - buf_putbytes(b, keyed25519, keyed25519_len); - buf_setpos(b, 0); - type = DROPBEAR_SIGNKEY_ED25519; - if (buf_get_priv_key(b, svr_opts.hostkey, &type) == DROPBEAR_FAILURE) { - dropbear_exit("failed fixed ed25519 hostkey"); - } - - buf_free(b); -} - -void fuzz_kex_fakealgos(void) { - ses.newkeys->recv.crypt_mode = &dropbear_mode_none; -} - -void fuzz_get_socket_address(int UNUSED(fd), char **local_host, char **local_port, - char **remote_host, char **remote_port, int UNUSED(host_lookup)) { - if (local_host) { - *local_host = m_strdup("fuzzlocalhost"); - } - if (local_port) { - *local_port = m_strdup("1234"); - } - if (remote_host) { - *remote_host = m_strdup("fuzzremotehost"); - } - if (remote_port) { - *remote_port = m_strdup("9876"); - } -} - -/* cut down version of svr_send_msg_kexdh_reply() that skips slow maths. Still populates structures */ -void fuzz_fake_send_kexdh_reply(void) { - assert(!ses.dh_K); - m_mp_alloc_init_multi(&ses.dh_K, NULL); - mp_set_ul(ses.dh_K, 12345678uL); - finish_kexhashbuf(); -} - -/* fake version of spawn_command() */ -int fuzz_spawn_command(int *ret_writefd, int *ret_readfd, int *ret_errfd, pid_t *ret_pid) { - *ret_writefd = wrapfd_new(); - *ret_readfd = wrapfd_new(); - if (ret_errfd) { - *ret_errfd = wrapfd_new(); - } - *ret_pid = 999; - return DROPBEAR_SUCCESS; -} - -int fuzz_run_preauth(const uint8_t *Data, size_t Size, int skip_kexmaths) { - static int once = 0; - if (!once) { - fuzz_svr_setup(); - fuzz.skip_kexmaths = skip_kexmaths; - once = 1; - } - - if (fuzz_set_input(Data, Size) == DROPBEAR_FAILURE) { - return 0; - } - - /* - get prefix, allowing for future extensibility. input format is - string prefix - uint32 wrapfd seed - ... to be extended later - [bytes] ssh input stream - */ - - /* be careful to avoid triggering buffer.c assertions */ - if (fuzz.input->len < 8) { - return 0; - } - size_t prefix_size = buf_getint(fuzz.input); - if (prefix_size != 4) { - return 0; - } - uint32_t wrapseed = buf_getint(fuzz.input); - wrapfd_setseed(wrapseed); - - int fakesock = wrapfd_new(); - - m_malloc_set_epoch(1); - if (setjmp(fuzz.jmp) == 0) { - svr_session(fakesock, fakesock); - m_malloc_free_epoch(1, 0); - } else { - m_malloc_free_epoch(1, 1); - TRACE(("dropbear_exit longjmped")) - /* dropbear_exit jumped here */ - } - - return 0; -} - -int fuzz_run_client(const uint8_t *Data, size_t Size, int skip_kexmaths) { - static int once = 0; - if (!once) { - fuzz_cli_setup(); - fuzz.skip_kexmaths = skip_kexmaths; - once = 1; - } - - if (fuzz_set_input(Data, Size) == DROPBEAR_FAILURE) { - return 0; - } - - /* - get prefix, allowing for future extensibility. input format is - string prefix - uint32 wrapfd seed - ... to be extended later - [bytes] ssh input stream - */ - - /* be careful to avoid triggering buffer.c assertions */ - if (fuzz.input->len < 8) { - return 0; - } - size_t prefix_size = buf_getint(fuzz.input); - if (prefix_size != 4) { - return 0; - } - uint32_t wrapseed = buf_getint(fuzz.input); - wrapfd_setseed(wrapseed); - - int fakesock = wrapfd_new(); - - m_malloc_set_epoch(1); - if (setjmp(fuzz.jmp) == 0) { - cli_session(fakesock, fakesock, NULL, 0); - m_malloc_free_epoch(1, 0); - } else { - m_malloc_free_epoch(1, 1); - TRACE(("dropbear_exit longjmped")) - /* dropbear_exit jumped here */ - } - - return 0; -} - -const void* fuzz_get_algo(const algo_type *algos, const char* name) { - const algo_type *t; - for (t = algos; t->name; t++) { - if (strcmp(t->name, name) == 0) { - return t->data; - } - } - assert(0); -} - -void fuzz_dump(const unsigned char* data, size_t len) { - TRACE(("dump %zu", len)) - if (fuzz.dumping) { - assert(atomicio(vwrite, fuzz.recv_dumpfd, (void*)data, len) == len); - } -}
--- a/fuzz-harness.c Fri Oct 23 20:53:58 2020 +0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,48 +0,0 @@ -#include "includes.h" -#include "buffer.h" -#include "dbutil.h" - -extern int LLVMFuzzerTestOneInput(const unsigned char *data, size_t size); - -int main(int argc, char ** argv) { - int i; - buffer *input = buf_new(100000); - - for (i = 1; i < argc; i++) { -#if DEBUG_TRACE - if (strcmp(argv[i], "-v") == 0) { - debug_trace = 1; - TRACE(("debug printing on")) - } -#endif - } - - int old_fuzz_wrapfds = 0; - for (i = 1; i < argc; i++) { - if (argv[i][0] == '-') { - /* ignore arguments */ - continue; - } - - char* fn = argv[i]; - buf_setlen(input, 0); - buf_readfile(input, fn); - buf_setpos(input, 0); - - /* Run twice to catch problems with statefulness */ - fuzz.wrapfds = old_fuzz_wrapfds; - printf("Running %s once \n", fn); - LLVMFuzzerTestOneInput(input->data, input->len); - printf("Running %s twice \n", fn); - LLVMFuzzerTestOneInput(input->data, input->len); - printf("Done %s\n", fn); - - /* Disable wrapfd so it won't interfere with buf_readfile() above */ - old_fuzz_wrapfds = fuzz.wrapfds; - fuzz.wrapfds = 0; - } - - printf("Finished\n"); - - return 0; -}
--- a/fuzz-hostkeys.c Fri Oct 23 20:53:58 2020 +0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,140 +0,0 @@ -/* To be included in fuzz-common.c */ - -static unsigned char keyr[] = { - 0x00, 0x00, 0x00, 0x07, 0x73, 0x73, 0x68, 0x2d, 0x72, 0x73, 0x61, 0x00, - 0x00, 0x00, 0x03, 0x01, 0x00, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0xb1, - 0x06, 0x95, 0xc9, 0xa8, 0x38, 0xb9, 0x99, 0x91, 0xb5, 0x17, 0x39, 0xb9, - 0xfa, 0xa4, 0x49, 0xf8, 0x2a, 0x4c, 0x14, 0xbd, 0xb6, 0x85, 0xdb, 0x38, - 0x99, 0x44, 0xfa, 0xd6, 0xaa, 0x67, 0xef, 0x00, 0x75, 0x2b, 0x6a, 0x5c, - 0x1b, 0x50, 0xa8, 0x52, 0xf9, 0xa7, 0xee, 0xe2, 0xb3, 0x80, 0x38, 0x92, - 0x20, 0x86, 0x7c, 0xe5, 0x89, 0xb3, 0x06, 0xe4, 0x3b, 0xd1, 0xe2, 0x45, - 0xea, 0xc1, 0xd5, 0x8e, 0x05, 0xfb, 0x90, 0x29, 0xd9, 0x41, 0xb3, 0x05, - 0x31, 0x1e, 0xcc, 0xeb, 0x89, 0xdc, 0xd2, 0x6a, 0x99, 0x23, 0xbd, 0x7a, - 0xbe, 0x8c, 0xe3, 0x3f, 0xa1, 0xe8, 0xf5, 0xb4, 0x51, 0x40, 0xb4, 0xb1, - 0xc1, 0x16, 0x9f, 0x07, 0xbb, 0x99, 0xaa, 0x4b, 0x8f, 0x11, 0x19, 0x3c, - 0x18, 0xbd, 0x6e, 0xce, 0x14, 0x54, 0x2c, 0x16, 0x4a, 0x5f, 0x89, 0xe4, - 0x6b, 0x9f, 0x55, 0x68, 0xcc, 0x09, 0x8e, 0x4b, 0x92, 0xc8, 0x87, 0xfe, - 0x09, 0xed, 0x53, 0x6e, 0xff, 0x5f, 0x15, 0x0d, 0x19, 0x9d, 0xa6, 0x54, - 0xd2, 0xea, 0x59, 0x4f, 0xa1, 0x7c, 0xf6, 0xf5, 0x7f, 0x32, 0x23, 0xed, - 0x72, 0xa8, 0x96, 0x17, 0x87, 0x06, 0xf2, 0xc7, 0xcd, 0xda, 0x4a, 0x10, - 0xd1, 0xfd, 0xb8, 0xf1, 0xaf, 0x25, 0x55, 0x32, 0x45, 0x39, 0x95, 0xec, - 0x0c, 0xa9, 0xf0, 0x47, 0x8b, 0x66, 0xe0, 0xb7, 0xa2, 0xf6, 0x35, 0x50, - 0x27, 0xe7, 0x2f, 0x90, 0x35, 0x5b, 0xd5, 0x62, 0x19, 0xb4, 0x41, 0xd4, - 0x52, 0xe7, 0x7f, 0x97, 0xfc, 0x5b, 0x4a, 0x5b, 0x19, 0x06, 0x65, 0x2d, - 0x23, 0x29, 0x15, 0x8b, 0x05, 0xaf, 0xbe, 0xd3, 0x4a, 0x27, 0x5b, 0xc9, - 0xc0, 0xd0, 0xd2, 0xba, 0x8b, 0x00, 0x7a, 0x2f, 0x39, 0xa0, 0x13, 0xb9, - 0xe6, 0xf5, 0x4b, 0x21, 0x54, 0x57, 0xb3, 0xf9, 0x6c, 0x6f, 0xd0, 0x17, - 0xf4, 0x50, 0x9d, 0x00, 0x00, 0x01, 0x00, 0x01, 0xf2, 0xda, 0x5f, 0xfb, - 0xe2, 0xda, 0xfc, 0xe0, 0xdf, 0x3a, 0x0e, 0x14, 0x18, 0xc1, 0xd9, 0x1f, - 0x43, 0xe3, 0x65, 0x3e, 0x07, 0xe7, 0x8d, 0xdc, 0x1d, 0x11, 0xc1, 0xd6, - 0xc0, 0xd8, 0xda, 0x53, 0xf5, 0x04, 0x73, 0x51, 0x1b, 0x26, 0xef, 0x4e, - 0xf5, 0xce, 0x3d, 0x77, 0x21, 0x94, 0xd0, 0xc7, 0xc1, 0xda, 0x19, 0x7d, - 0xf8, 0xc5, 0x4c, 0xc8, 0xee, 0x7d, 0xd1, 0xbb, 0x02, 0x90, 0x2b, 0xff, - 0x4e, 0x4d, 0xd7, 0x9d, 0x72, 0x0c, 0x60, 0x0f, 0x4b, 0x83, 0xf5, 0xc2, - 0x26, 0xd6, 0x22, 0xb8, 0x60, 0x3a, 0xf9, 0x2f, 0x92, 0x2a, 0x2e, 0x14, - 0xa7, 0x56, 0x1c, 0x56, 0x05, 0x41, 0x92, 0xac, 0xb1, 0x4e, 0x44, 0x1e, - 0x70, 0x42, 0xda, 0xc7, 0xc8, 0x9c, 0xae, 0x29, 0x2d, 0x0c, 0x3a, 0xff, - 0x9b, 0xb6, 0xad, 0xb4, 0xfb, 0x49, 0x28, 0x96, 0x74, 0xf5, 0x94, 0x74, - 0xb7, 0x40, 0x93, 0x2b, 0x34, 0x29, 0xd2, 0x8a, 0xf3, 0x99, 0xf9, 0xe9, - 0xd8, 0xcc, 0x48, 0x1d, 0x3e, 0xc1, 0x82, 0x35, 0x4f, 0xef, 0xb1, 0x81, - 0x3c, 0xe1, 0xa1, 0x03, 0x65, 0xac, 0x21, 0x21, 0x40, 0x61, 0xfb, 0xd3, - 0x54, 0xac, 0xa1, 0xf2, 0xf0, 0x61, 0xd9, 0x01, 0x4e, 0xc2, 0x28, 0xb1, - 0x7c, 0x27, 0x6e, 0x56, 0x68, 0x69, 0x8f, 0xc5, 0xfd, 0xca, 0x39, 0x6e, - 0x22, 0x09, 0xf1, 0xb4, 0xd5, 0xac, 0xb8, 0xe0, 0x1b, 0x21, 0x86, 0xf4, - 0xc8, 0x15, 0xc6, 0x1f, 0x21, 0xae, 0xcb, 0xab, 0x5a, 0x09, 0x30, 0x9e, - 0xdd, 0x6c, 0x38, 0x59, 0xec, 0x59, 0x3a, 0x08, 0xee, 0x46, 0x7b, 0x78, - 0x23, 0xbc, 0xfc, 0xe2, 0xda, 0xe8, 0x1a, 0x65, 0xe6, 0xe0, 0x78, 0xd3, - 0xb0, 0x03, 0x2e, 0xf1, 0xb8, 0xca, 0x8e, 0x90, 0x75, 0xaf, 0xf7, 0xa8, - 0x48, 0xed, 0x82, 0xc9, 0xcf, 0x44, 0x56, 0xfc, 0x05, 0xfd, 0x6b, 0x00, - 0x00, 0x00, 0x81, 0x00, 0xfc, 0x94, 0xdf, 0x42, 0xc7, 0x9a, 0xa2, 0xff,