From 27a87d8146fc74464c2466a391ff8d22fa80aac9 Mon Sep 17 00:00:00 2001 From: yutaka Date: Mon, 25 Feb 2008 06:22:27 +0000 Subject: [PATCH] =?UTF-8?q?TwlIPL=5Fprivate=E5=AF=BE=E5=BF=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: file:///Users/lillianskinner/Downloads/platinum/twl/TwlIPL/trunk@735 b08762b0-b915-fc4b-9d8c-17b2551a87ff --- build/buildtools/commondefs | 6 + build/buildtools/commondefs.firm | 7 +- build/gcdfirm/gcdfirm-disp/Makefile | 10 +- build/gcdfirm/gcdfirm-print/Makefile | 6 +- build/gcdfirm/sdmc-launcher/Makefile | 6 +- build/libraries/aes/ARM7/aes_init.c | 5 + build/nandfirm/menu-launcher/Makefile | 10 +- build/nandfirm/menu-launcher2/Makefile | 6 +- build/nandfirm/nandfirm-print/Makefile | 6 +- build/nandfirm/sdmc-launcher/Makefile | 10 +- build/norfirm/firm-dev/Makefile | 10 +- build/norfirm/norfirm-empty/Makefile | 6 +- build/norfirm/norfirm-print/Makefile | 10 +- .../systemMenu_RED/HWInfoWriter/ARM9/Makefile | 9 +- .../NandInitializer/ARM9.TWL/Makefile | 12 +- build/tools/Makefile | 9 +- build/tools/acsign/Makefile | 61 - build/tools/acsign/acsign.c | 334 ----- build/tools/acsign/acsign_gcd.c | 74 -- build/tools/acsign/acsign_nand.c | 75 -- build/tools/acsign/acsign_nor.c | 75 -- build/tools/acsign/aes.h | 139 -- build/tools/acsign/aes2.c | 133 -- build/tools/acsign/aes2.h | 21 - build/tools/acsign/aes_e.c | 115 -- build/tools/acsign/aes_e.h | 284 ----- build/tools/acsign/aes_e_ecb.c | 48 - build/tools/acsign/aes_sbox.h | 59 - build/tools/acsign/aes_skey.c | 143 --- build/tools/acsign/bn_add.c | 304 ----- build/tools/acsign/bn_asm.c | 509 -------- build/tools/acsign/bn_comba.c | 434 ------- build/tools/acsign/bn_div.c | 365 ------ build/tools/acsign/bn_ex_str.c | 437 ------- build/tools/acsign/bn_exp.c | 156 --- build/tools/acsign/bn_fm_w.c | 63 - build/tools/acsign/bn_gcd.c | 229 ---- build/tools/acsign/bn_lib.c | 1079 ---------------- build/tools/acsign/bn_lsh.c | 112 -- build/tools/acsign/bn_m_exp.c | 283 ----- build/tools/acsign/bn_me.c | 251 ---- build/tools/acsign/bn_mont.c | 231 ---- build/tools/acsign/bn_ms_w.c | 121 -- build/tools/acsign/bn_mul.c | 779 ------------ build/tools/acsign/bn_r_exp.c | 134 -- build/tools/acsign/bn_rec.c | 232 ---- build/tools/acsign/bn_recp.c | 202 --- build/tools/acsign/bn_rsh.c | 123 -- build/tools/acsign/bn_sqr.c | 273 ---- build/tools/acsign/bn_wdiv.c | 100 -- build/tools/acsign/bn_word.c | 222 ---- build/tools/acsign/include/acsign.h | 49 - build/tools/acsign/include/acsign_gcd.h | 30 - build/tools/acsign/include/acsign_nand.h | 30 - build/tools/acsign/include/acsign_nor.h | 30 - build/tools/acsign/include/bn.h | 1120 ----------------- build/tools/acsign/include/bn_lcl.h | 324 ----- build/tools/acsign/include/bn_thx.h | 301 ----- build/tools/acsign/include/r_error.h | 210 ---- build/tools/acsign/include/r_stdiag.h | 82 -- build/tools/acsign/include/r_types.h | 241 ---- build/tools/acsign/include/sha.h | 89 -- build/tools/acsign/include/sha1.h | 73 -- build/tools/acsign/include/sha_locl.h | 274 ---- build/tools/acsign/sha1.c | 453 ------- build/tools/acsign/sha1dgst.c | 770 ------------ build/tools/makegcdfirm/Makefile | 151 --- build/tools/makegcdfirm/compress.c | 293 ----- build/tools/makegcdfirm/compress.h | 38 - build/tools/makegcdfirm/defval.c | 315 ----- build/tools/makegcdfirm/defval.h | 38 - build/tools/makegcdfirm/elf.h | 431 ------- build/tools/makegcdfirm/format_nlist.h | 54 - build/tools/makegcdfirm/format_rom.h | 59 - build/tools/makegcdfirm/format_sign.h | 32 - .../gcdfirm_header_twlj.template.sbin | Bin 16384 -> 0 bytes build/tools/makegcdfirm/makegcdfirm.c | 111 -- build/tools/makegcdfirm/makegcdfirm.h | 24 - build/tools/makegcdfirm/misc.c | 628 --------- build/tools/makegcdfirm/misc.h | 124 -- build/tools/makegcdfirm/out_gcdfirm.c | 1009 --------------- build/tools/makegcdfirm/path.c | 931 -------------- build/tools/makegcdfirm/path.h | 93 -- build/tools/makegcdfirm/test/Makefile | 56 - .../makegcdfirm/test/nandfirm_print.nand | Bin 50688 -> 0 bytes .../tools/makegcdfirm/test/norfirm_print.nor | Bin 30896 -> 0 bytes build/tools/makegcdfirm/test/rsa_private.der | Bin 607 -> 0 bytes build/tools/makegcdfirm/test/test.gcdsf | 22 - .../makegcdfirm/test/twl_gcdfirm7_print.axf | Bin 175676 -> 0 bytes .../makegcdfirm/test/twl_gcdfirm7_print.sbin | Bin 12772 -> 0 bytes .../makegcdfirm/test/twl_gcdfirm9_print.axf | Bin 288636 -> 0 bytes .../makegcdfirm/test/twl_gcdfirm9_print.sbin | Bin 33184 -> 0 bytes .../tools/makegcdfirm/test/wram_rbin/Makefile | 48 - .../makegcdfirm/test/wram_rbin/wram_regs.c | 89 -- build/tools/makegcdfirm/wram_regs.c | 96 -- build/tools/makenandfirm/Makefile | 151 --- build/tools/makenandfirm/compress.c | 293 ----- build/tools/makenandfirm/compress.h | 38 - build/tools/makenandfirm/defval.c | 315 ----- build/tools/makenandfirm/defval.h | 38 - build/tools/makenandfirm/elf.h | 431 ------- build/tools/makenandfirm/format_nlist.h | 54 - build/tools/makenandfirm/format_rom.h | 51 - build/tools/makenandfirm/format_sign.h | 32 - build/tools/makenandfirm/makenandfirm.c | 106 -- build/tools/makenandfirm/makenandfirm.h | 24 - build/tools/makenandfirm/misc.c | 628 --------- build/tools/makenandfirm/misc.h | 124 -- build/tools/makenandfirm/out_nandfirm.c | 981 --------------- build/tools/makenandfirm/path.c | 931 -------------- build/tools/makenandfirm/path.h | 93 -- build/tools/makenandfirm/test/Makefile | 56 - build/tools/makenandfirm/test/rsa_private.der | Bin 607 -> 0 bytes build/tools/makenandfirm/test/test.nandsf | 28 - .../makenandfirm/test/twl_nandfirm7_print.axf | Bin 175676 -> 0 bytes .../test/twl_nandfirm7_print.sbin | Bin 12772 -> 0 bytes .../makenandfirm/test/twl_nandfirm9_print.axf | Bin 288636 -> 0 bytes .../test/twl_nandfirm9_print.sbin | Bin 33184 -> 0 bytes .../makenandfirm/test/wram_rbin/Makefile | 48 - .../makenandfirm/test/wram_rbin/wram_regs.c | 89 -- build/tools/makenandfirm/wram_regs.c | 96 -- build/tools/makenorfirm/Makefile | 151 --- build/tools/makenorfirm/compress.c | 293 ----- build/tools/makenorfirm/compress.h | 38 - build/tools/makenorfirm/defval.c | 315 ----- build/tools/makenorfirm/defval.h | 38 - build/tools/makenorfirm/elf.h | 431 ------- build/tools/makenorfirm/format_nlist.h | 54 - build/tools/makenorfirm/format_rom.h | 51 - build/tools/makenorfirm/format_sign.h | 32 - build/tools/makenorfirm/makenorfirm.c | 106 -- build/tools/makenorfirm/makenorfirm.h | 24 - build/tools/makenorfirm/misc.c | 628 --------- build/tools/makenorfirm/misc.h | 128 -- build/tools/makenorfirm/out_norfirm.c | 984 --------------- build/tools/makenorfirm/path.c | 931 -------------- build/tools/makenorfirm/path.h | 93 -- build/tools/makenorfirm/test/Makefile | 58 - build/tools/makenorfirm/test/rsa_private.der | Bin 608 -> 0 bytes build/tools/makenorfirm/test/test.norsf | 30 - .../makenorfirm/test/twl_norfirm7_print.axf | Bin 175676 -> 0 bytes .../makenorfirm/test/twl_norfirm7_print.sbin | Bin 12772 -> 0 bytes .../makenorfirm/test/twl_norfirm9_print.axf | Bin 288636 -> 0 bytes .../makenorfirm/test/twl_norfirm9_print.sbin | Bin 33184 -> 0 bytes .../tools/makenorfirm/test/wram_rbin/Makefile | 48 - .../makenorfirm/test/wram_rbin/wram_regs.c | 89 -- build/tools/makenorfirm/wram_regs.c | 96 -- include/firm/aes.h | 1 - include/firm/aes/ARM7/aes_ids.h | 35 - readme.txt | 12 +- tools/bin/makegcdfirm.exe | Bin 0 -> 124985 bytes tools/bin/makenandfirm.exe | Bin 0 -> 124482 bytes tools/bin/makenorfirm.exe | Bin 0 -> 124469 bytes 153 files changed, 53 insertions(+), 26266 deletions(-) delete mode 100644 build/tools/acsign/Makefile delete mode 100644 build/tools/acsign/acsign.c delete mode 100644 build/tools/acsign/acsign_gcd.c delete mode 100644 build/tools/acsign/acsign_nand.c delete mode 100644 build/tools/acsign/acsign_nor.c delete mode 100644 build/tools/acsign/aes.h delete mode 100644 build/tools/acsign/aes2.c delete mode 100644 build/tools/acsign/aes2.h delete mode 100644 build/tools/acsign/aes_e.c delete mode 100644 build/tools/acsign/aes_e.h delete mode 100644 build/tools/acsign/aes_e_ecb.c delete mode 100644 build/tools/acsign/aes_sbox.h delete mode 100644 build/tools/acsign/aes_skey.c delete mode 100644 build/tools/acsign/bn_add.c delete mode 100644 build/tools/acsign/bn_asm.c delete mode 100644 build/tools/acsign/bn_comba.c delete mode 100644 build/tools/acsign/bn_div.c delete mode 100644 build/tools/acsign/bn_ex_str.c delete mode 100644 build/tools/acsign/bn_exp.c delete mode 100644 build/tools/acsign/bn_fm_w.c delete mode 100644 build/tools/acsign/bn_gcd.c delete mode 100644 build/tools/acsign/bn_lib.c delete mode 100644 build/tools/acsign/bn_lsh.c delete mode 100644 build/tools/acsign/bn_m_exp.c delete mode 100644 build/tools/acsign/bn_me.c delete mode 100644 build/tools/acsign/bn_mont.c delete mode 100644 build/tools/acsign/bn_ms_w.c delete mode 100644 build/tools/acsign/bn_mul.c delete mode 100644 build/tools/acsign/bn_r_exp.c delete mode 100644 build/tools/acsign/bn_rec.c delete mode 100644 build/tools/acsign/bn_recp.c delete mode 100644 build/tools/acsign/bn_rsh.c delete mode 100644 build/tools/acsign/bn_sqr.c delete mode 100644 build/tools/acsign/bn_wdiv.c delete mode 100644 build/tools/acsign/bn_word.c delete mode 100644 build/tools/acsign/include/acsign.h delete mode 100644 build/tools/acsign/include/acsign_gcd.h delete mode 100644 build/tools/acsign/include/acsign_nand.h delete mode 100644 build/tools/acsign/include/acsign_nor.h delete mode 100644 build/tools/acsign/include/bn.h delete mode 100644 build/tools/acsign/include/bn_lcl.h delete mode 100644 build/tools/acsign/include/bn_thx.h delete mode 100644 build/tools/acsign/include/r_error.h delete mode 100644 build/tools/acsign/include/r_stdiag.h delete mode 100644 build/tools/acsign/include/r_types.h delete mode 100644 build/tools/acsign/include/sha.h delete mode 100644 build/tools/acsign/include/sha1.h delete mode 100644 build/tools/acsign/include/sha_locl.h delete mode 100644 build/tools/acsign/sha1.c delete mode 100644 build/tools/acsign/sha1dgst.c delete mode 100644 build/tools/makegcdfirm/Makefile delete mode 100644 build/tools/makegcdfirm/compress.c delete mode 100644 build/tools/makegcdfirm/compress.h delete mode 100644 build/tools/makegcdfirm/defval.c delete mode 100644 build/tools/makegcdfirm/defval.h delete mode 100644 build/tools/makegcdfirm/elf.h delete mode 100644 build/tools/makegcdfirm/format_nlist.h delete mode 100644 build/tools/makegcdfirm/format_rom.h delete mode 100644 build/tools/makegcdfirm/format_sign.h delete mode 100644 build/tools/makegcdfirm/gcdfirm_header_twlj.template.sbin delete mode 100644 build/tools/makegcdfirm/makegcdfirm.c delete mode 100644 build/tools/makegcdfirm/makegcdfirm.h delete mode 100644 build/tools/makegcdfirm/misc.c delete mode 100644 build/tools/makegcdfirm/misc.h delete mode 100644 build/tools/makegcdfirm/out_gcdfirm.c delete mode 100644 build/tools/makegcdfirm/path.c delete mode 100644 build/tools/makegcdfirm/path.h delete mode 100644 build/tools/makegcdfirm/test/Makefile delete mode 100644 build/tools/makegcdfirm/test/nandfirm_print.nand delete mode 100644 build/tools/makegcdfirm/test/norfirm_print.nor delete mode 100644 build/tools/makegcdfirm/test/rsa_private.der delete mode 100644 build/tools/makegcdfirm/test/test.gcdsf delete mode 100644 build/tools/makegcdfirm/test/twl_gcdfirm7_print.axf delete mode 100644 build/tools/makegcdfirm/test/twl_gcdfirm7_print.sbin delete mode 100644 build/tools/makegcdfirm/test/twl_gcdfirm9_print.axf delete mode 100644 build/tools/makegcdfirm/test/twl_gcdfirm9_print.sbin delete mode 100644 build/tools/makegcdfirm/test/wram_rbin/Makefile delete mode 100644 build/tools/makegcdfirm/test/wram_rbin/wram_regs.c delete mode 100644 build/tools/makegcdfirm/wram_regs.c delete mode 100644 build/tools/makenandfirm/Makefile delete mode 100644 build/tools/makenandfirm/compress.c delete mode 100644 build/tools/makenandfirm/compress.h delete mode 100644 build/tools/makenandfirm/defval.c delete mode 100644 build/tools/makenandfirm/defval.h delete mode 100644 build/tools/makenandfirm/elf.h delete mode 100644 build/tools/makenandfirm/format_nlist.h delete mode 100644 build/tools/makenandfirm/format_rom.h delete mode 100644 build/tools/makenandfirm/format_sign.h delete mode 100644 build/tools/makenandfirm/makenandfirm.c delete mode 100644 build/tools/makenandfirm/makenandfirm.h delete mode 100644 build/tools/makenandfirm/misc.c delete mode 100644 build/tools/makenandfirm/misc.h delete mode 100644 build/tools/makenandfirm/out_nandfirm.c delete mode 100644 build/tools/makenandfirm/path.c delete mode 100644 build/tools/makenandfirm/path.h delete mode 100644 build/tools/makenandfirm/test/Makefile delete mode 100644 build/tools/makenandfirm/test/rsa_private.der delete mode 100644 build/tools/makenandfirm/test/test.nandsf delete mode 100644 build/tools/makenandfirm/test/twl_nandfirm7_print.axf delete mode 100644 build/tools/makenandfirm/test/twl_nandfirm7_print.sbin delete mode 100644 build/tools/makenandfirm/test/twl_nandfirm9_print.axf delete mode 100644 build/tools/makenandfirm/test/twl_nandfirm9_print.sbin delete mode 100644 build/tools/makenandfirm/test/wram_rbin/Makefile delete mode 100644 build/tools/makenandfirm/test/wram_rbin/wram_regs.c delete mode 100644 build/tools/makenandfirm/wram_regs.c delete mode 100644 build/tools/makenorfirm/Makefile delete mode 100644 build/tools/makenorfirm/compress.c delete mode 100644 build/tools/makenorfirm/compress.h delete mode 100644 build/tools/makenorfirm/defval.c delete mode 100644 build/tools/makenorfirm/defval.h delete mode 100644 build/tools/makenorfirm/elf.h delete mode 100644 build/tools/makenorfirm/format_nlist.h delete mode 100644 build/tools/makenorfirm/format_rom.h delete mode 100644 build/tools/makenorfirm/format_sign.h delete mode 100644 build/tools/makenorfirm/makenorfirm.c delete mode 100644 build/tools/makenorfirm/makenorfirm.h delete mode 100644 build/tools/makenorfirm/misc.c delete mode 100644 build/tools/makenorfirm/misc.h delete mode 100644 build/tools/makenorfirm/out_norfirm.c delete mode 100644 build/tools/makenorfirm/path.c delete mode 100644 build/tools/makenorfirm/path.h delete mode 100644 build/tools/makenorfirm/test/Makefile delete mode 100644 build/tools/makenorfirm/test/rsa_private.der delete mode 100644 build/tools/makenorfirm/test/test.norsf delete mode 100644 build/tools/makenorfirm/test/twl_norfirm7_print.axf delete mode 100644 build/tools/makenorfirm/test/twl_norfirm7_print.sbin delete mode 100644 build/tools/makenorfirm/test/twl_norfirm9_print.axf delete mode 100644 build/tools/makenorfirm/test/twl_norfirm9_print.sbin delete mode 100644 build/tools/makenorfirm/test/wram_rbin/Makefile delete mode 100644 build/tools/makenorfirm/test/wram_rbin/wram_regs.c delete mode 100644 build/tools/makenorfirm/wram_regs.c delete mode 100644 include/firm/aes/ARM7/aes_ids.h create mode 100644 tools/bin/makegcdfirm.exe create mode 100644 tools/bin/makenandfirm.exe create mode 100644 tools/bin/makenorfirm.exe diff --git a/build/buildtools/commondefs b/build/buildtools/commondefs index 98c45b61..e2dc5c85 100644 --- a/build/buildtools/commondefs +++ b/build/buildtools/commondefs @@ -30,6 +30,12 @@ ifdef FIRM_USE_TWLSDK_KEYS MACRO_FLAGS += -DFIRM_USE_TWLSDK_KEYS=$(FIRM_USE_TWLSDK_KEYS) endif +ifeq ($(TWL_IPL_RED_PRIVATE_ROOT),) +TWL_KEYSDIR := $(TWL_IPL_RED_ROOT)/keys/dummy +else +TWL_KEYSDIR := $(TWL_IPL_RED_PRIVATE_ROOT)/keys +endif + #---------------------------------------------------------------------------- endif # TWL_IPL_COMMONDEFS_ #----- End of commondefs ----- diff --git a/build/buildtools/commondefs.firm b/build/buildtools/commondefs.firm index 7ca5d5d5..c1a1e6ae 100644 --- a/build/buildtools/commondefs.firm +++ b/build/buildtools/commondefs.firm @@ -21,12 +21,7 @@ TWLFIRM_COMMONDEFS_ = TRUE EMPTY ?= SPACE ?= $(EMPTY) $(EMPTY) -ifndef TWL_KEYSDIR -DUMMY_KEYS_SUFFIX = .dummykey -endif -TWL_KEYSDIR ?= $(FIRM_ROOT)/keys/dummy - -TARGET_BIN ?= $(subst .,$(DUMMY_KEYS_SUFFIX).,$(TARGET_FIRM_BIN)) +TARGET_BIN ?= $(TARGET_FIRM_BIN) # # change default variables for product diff --git a/build/gcdfirm/gcdfirm-disp/Makefile b/build/gcdfirm/gcdfirm-disp/Makefile index e541274c..4b121de5 100644 --- a/build/gcdfirm/gcdfirm-disp/Makefile +++ b/build/gcdfirm/gcdfirm-disp/Makefile @@ -1,6 +1,6 @@ #! make -f #---------------------------------------------------------------------------- -# Project: TwlFirm - nandfirm - gcdfirm-disp +# Project: TwlIPL - gcdfirm - gcdfirm-disp # File: Makefile # # Copyright 2007 Nintendo. All rights reserved. @@ -12,15 +12,11 @@ # in whole or in part, without the prior written consent of Nintendo. # # $Date:: $ -# $Rev:$ -# $Author:$ +# $Rev$ +# $Author$ #---------------------------------------------------------------------------- -# if you have valid keys, set environment value like below -#export TWL_KEYSDIR='$(FIRM_ROOT)/../twl_firmware/bootrom/build/keys' - - #---------------------------------------------------------------------------- SUBDIRS = \ diff --git a/build/gcdfirm/gcdfirm-print/Makefile b/build/gcdfirm/gcdfirm-print/Makefile index 592a90bb..58f93251 100644 --- a/build/gcdfirm/gcdfirm-print/Makefile +++ b/build/gcdfirm/gcdfirm-print/Makefile @@ -1,6 +1,6 @@ #! make -f #---------------------------------------------------------------------------- -# Project: TwlFirm - build +# Project: TwlIPL - gcdfirm - gcdfirm-print # File: Makefile # # Copyright 2007 Nintendo. All rights reserved. @@ -12,8 +12,8 @@ # in whole or in part, without the prior written consent of Nintendo. # # $Date:: $ -# $Rev:$ -# $Author:$ +# $Rev$ +# $Author$ #---------------------------------------------------------------------------- diff --git a/build/gcdfirm/sdmc-launcher/Makefile b/build/gcdfirm/sdmc-launcher/Makefile index 3fc5086b..f192adfa 100644 --- a/build/gcdfirm/sdmc-launcher/Makefile +++ b/build/gcdfirm/sdmc-launcher/Makefile @@ -1,6 +1,6 @@ #! make -f #---------------------------------------------------------------------------- -# Project: TwlFirm - nandfirm - gcdfirm-disp +# Project: TwlIPL - gcdfirm - sdmc-launcher # File: Makefile # # Copyright 2007 Nintendo. All rights reserved. @@ -17,10 +17,6 @@ #---------------------------------------------------------------------------- -# if you have valid keys, set environment value like below -#export TWL_KEYSDIR='$(TWL_IPL_RED_ROOT)/../twl_firmware/bootrom/build/keys' - - #---------------------------------------------------------------------------- SUBDIRS = \ diff --git a/build/libraries/aes/ARM7/aes_init.c b/build/libraries/aes/ARM7/aes_init.c index 2c97e03f..c9146fca 100644 --- a/build/libraries/aes/ARM7/aes_init.c +++ b/build/libraries/aes/ARM7/aes_init.c @@ -18,6 +18,11 @@ #include #include +// 変更可 +#define AES_IDS_ID0_C(c) (((unsigned long)c[0] << 0) | ((unsigned long)c[1] << 8) | ((unsigned long)c[2] << 16) | ((unsigned long)c[3] << 24)) +#define AES_IDS_ID0_D(c) (((unsigned long)c[3] << 0) | ((unsigned long)c[2] << 8) | ((unsigned long)c[1] << 16) | ((unsigned long)c[0] << 24)) + + /*---------------------------------------------------------------------------* Name: AESi_InitKeysForApp diff --git a/build/nandfirm/menu-launcher/Makefile b/build/nandfirm/menu-launcher/Makefile index 232ee475..fe8d3353 100644 --- a/build/nandfirm/menu-launcher/Makefile +++ b/build/nandfirm/menu-launcher/Makefile @@ -1,6 +1,6 @@ #! make -f #---------------------------------------------------------------------------- -# Project: TwlFirm - nandfirm - menu-launcher +# Project: TwlIPL - nandfirm - menu-launcher # File: Makefile # # Copyright 2007 Nintendo. All rights reserved. @@ -12,15 +12,11 @@ # in whole or in part, without the prior written consent of Nintendo. # # $Date:: $ -# $Rev:$ -# $Author:$ +# $Rev$ +# $Author$ #---------------------------------------------------------------------------- -# if you have valid keys, set environment value like below -#export TWL_KEYSDIR='$(TWL_IPL_RED_ROOT)/../twl_firmware/bootrom/build/keys' - - #---------------------------------------------------------------------------- SUBDIRS = \ diff --git a/build/nandfirm/menu-launcher2/Makefile b/build/nandfirm/menu-launcher2/Makefile index beab20d3..3ecb4e21 100644 --- a/build/nandfirm/menu-launcher2/Makefile +++ b/build/nandfirm/menu-launcher2/Makefile @@ -1,6 +1,6 @@ #! make -f #---------------------------------------------------------------------------- -# Project: TwlFirm - nandfirm - menu-launcher2 +# Project: TwlIPL - nandfirm - menu-launcher2 # File: Makefile # # Copyright 2007 Nintendo. All rights reserved. @@ -17,10 +17,6 @@ #---------------------------------------------------------------------------- -# if you have valid keys, set environment value like below -#export TWL_KEYSDIR='$(TWL_IPL_RED_ROOT)/../twl_firmware/bootrom/build/keys' - - #---------------------------------------------------------------------------- SUBDIRS = \ diff --git a/build/nandfirm/nandfirm-print/Makefile b/build/nandfirm/nandfirm-print/Makefile index ecd52984..87f7aea9 100644 --- a/build/nandfirm/nandfirm-print/Makefile +++ b/build/nandfirm/nandfirm-print/Makefile @@ -1,6 +1,6 @@ #! make -f #---------------------------------------------------------------------------- -# Project: TwlFirm - build +# Project: TwlIPL - nandfirm - nandfirm-print # File: Makefile # # Copyright 2007 Nintendo. All rights reserved. @@ -12,8 +12,8 @@ # in whole or in part, without the prior written consent of Nintendo. # # $Date:: $ -# $Rev:$ -# $Author:$ +# $Rev$ +# $Author$ #---------------------------------------------------------------------------- diff --git a/build/nandfirm/sdmc-launcher/Makefile b/build/nandfirm/sdmc-launcher/Makefile index 3e3117e5..4eb1d0f2 100644 --- a/build/nandfirm/sdmc-launcher/Makefile +++ b/build/nandfirm/sdmc-launcher/Makefile @@ -1,6 +1,6 @@ #! make -f #---------------------------------------------------------------------------- -# Project: TwlFirm - nandfirm - sdmc-launcher +# Project: TwlIPL - nandfirm - sdmc-launcher # File: Makefile # # Copyright 2007 Nintendo. All rights reserved. @@ -12,15 +12,11 @@ # in whole or in part, without the prior written consent of Nintendo. # # $Date:: $ -# $Rev:$ -# $Author:$ +# $Rev$ +# $Author$ #---------------------------------------------------------------------------- -# if you have valid keys, set environment value like below -#export TWL_KEYSDIR='$(TWL_IPL_RED_ROOT)/../twl_firmware/bootrom/build/keys' - - #---------------------------------------------------------------------------- SUBDIRS = \ diff --git a/build/norfirm/firm-dev/Makefile b/build/norfirm/firm-dev/Makefile index 0777144a..b94d093a 100644 --- a/build/norfirm/firm-dev/Makefile +++ b/build/norfirm/firm-dev/Makefile @@ -1,6 +1,6 @@ #! make -f #---------------------------------------------------------------------------- -# Project: TwlFirm - build +# Project: TwlIPL - norfirm - firm-dev # File: Makefile # # Copyright 2007 Nintendo. All rights reserved. @@ -12,15 +12,11 @@ # in whole or in part, without the prior written consent of Nintendo. # # $Date:: $ -# $Rev:$ -# $Author:$ +# $Rev$ +# $Author$ #---------------------------------------------------------------------------- -# if you have no valid key, comment out next line -#TWL_KEYSDIR = $(FIRM_ROOT)/../twl_firmware/bootrom/build/keys - - #---------------------------------------------------------------------------- SUBDIRS = \ diff --git a/build/norfirm/norfirm-empty/Makefile b/build/norfirm/norfirm-empty/Makefile index c518dda7..52ada49f 100644 --- a/build/norfirm/norfirm-empty/Makefile +++ b/build/norfirm/norfirm-empty/Makefile @@ -1,6 +1,6 @@ #! make -f #---------------------------------------------------------------------------- -# Project: TwlFirm - build +# Project: TwlIPL - norfirm - norfirm-empty # File: Makefile # # Copyright 2007 Nintendo. All rights reserved. @@ -12,8 +12,8 @@ # in whole or in part, without the prior written consent of Nintendo. # # $Date:: $ -# $Rev:$ -# $Author:$ +# $Rev$ +# $Author$ #---------------------------------------------------------------------------- override TARGET_PLATFORM := TWL diff --git a/build/norfirm/norfirm-print/Makefile b/build/norfirm/norfirm-print/Makefile index 3e9e4ff6..18048884 100644 --- a/build/norfirm/norfirm-print/Makefile +++ b/build/norfirm/norfirm-print/Makefile @@ -1,6 +1,6 @@ #! make -f #---------------------------------------------------------------------------- -# Project: TwlFirm - build +# Project: TwlIPL - norfirm - norfirm-print # File: Makefile # # Copyright 2007 Nintendo. All rights reserved. @@ -12,15 +12,11 @@ # in whole or in part, without the prior written consent of Nintendo. # # $Date:: $ -# $Rev:$ -# $Author:$ +# $Rev$ +# $Author$ #---------------------------------------------------------------------------- -# if you have no valid key, comment out next line -#TWL_KEYSDIR = $(FIRM_ROOT)/../twl_firmware/bootrom/build/keys - - #---------------------------------------------------------------------------- SUBDIRS = \ diff --git a/build/systemMenu_RED/HWInfoWriter/ARM9/Makefile b/build/systemMenu_RED/HWInfoWriter/ARM9/Makefile index 747aaf93..d171fb30 100644 --- a/build/systemMenu_RED/HWInfoWriter/ARM9/Makefile +++ b/build/systemMenu_RED/HWInfoWriter/ARM9/Makefile @@ -20,9 +20,6 @@ SUBDIRS = \ #---------------------------------------------------------------------------- -USE_PRODUCT_KEY = TRUE - -KEYS_DIR = $(shell $(CYGPATH) -m $(TWL_KEYSDIR)) TARGET_FIRM = SYSTEMMENU TARGET_PLATFORM = TWL TWL_ARCHGEN = LIMITED @@ -47,11 +44,9 @@ MAKEROM_FLAGS += -DTITLEID_LO='$(TITLEID_LO)' \ -DHWINFO_PRIVKEY='private_HWInfo.der' MAKETAD_FLAGS += -s -ifdef USE_PRODUCT_KEY -MAKEROM_FLAGS += -DPRIVKEY_PATH='$(KEYS_DIR)/rsa' +TWL_KEYSDIR += -DPRIVKEY_PATH='$(TWL_KEYSDIR)/rsa' +ifneq ($(TWL_IPL_RED_PRIVATE_ROOT),) MACRO_FLAGS += -DUSE_PRODUCT_KEY -else -MAKEROM_FLAGS += -DPRIVKEY_PATH='../../../../keys/dummy/rsa' endif include $(TWL_IPL_RED_ROOT)/build/buildtools/commondefs diff --git a/build/systemMenu_RED/NandInitializer/ARM9.TWL/Makefile b/build/systemMenu_RED/NandInitializer/ARM9.TWL/Makefile index c89a6dab..c7317262 100644 --- a/build/systemMenu_RED/NandInitializer/ARM9.TWL/Makefile +++ b/build/systemMenu_RED/NandInitializer/ARM9.TWL/Makefile @@ -1,6 +1,6 @@ #! make -f #---------------------------------------------------------------------------- -# Project: TwlSDK - tests - camera-test +# Project: TwlIPL - systemMenu_RED - NandInitializer # File: Makefile # # Copyright 2007 Nintendo. All rights reserved. @@ -21,10 +21,6 @@ SUBDIRS = #---------------------------------------------------------------------------- -USE_PRODUCT_KEY = TRUE - -KEYS_DIR = $(shell $(CYGPATH) -m $(TWL_KEYSDIR)) - TARGET_FIRM = SYSTEMMENU TARGET_PLATFORM = TWL TWL_ARCHGEN = LIMITED @@ -73,11 +69,9 @@ MAKEROM_FLAGS += -DTITLEID_LO='$(TITLEID_LO)' \ -DHWINFO_PRIVKEY='private_HWInfo.der' MAKETAD_FLAGS += -s -ifdef USE_PRODUCT_KEY -MAKEROM_FLAGS += -DPRIVKEY_PATH='$(KEYS_DIR)/rsa' +TWL_KEYSDIR += -DPRIVKEY_PATH='$(TWL_KEYSDIR)/rsa' +ifneq ($(TWL_IPL_RED_PRIVATE_ROOT),) MACRO_FLAGS += -DUSE_PRODUCT_KEY -else -MAKEROM_FLAGS += -DPRIVKEY_PATH='../../../../keys/dummy/rsa' endif LLIBRARIES += libes$(TWL_LIBSUFFIX).a \ diff --git a/build/tools/Makefile b/build/tools/Makefile index 1a5e9be1..f78ee4f2 100644 --- a/build/tools/Makefile +++ b/build/tools/Makefile @@ -1,6 +1,6 @@ #! make -f #---------------------------------------------------------------------------- -# Project: TwlFirm - firmware +# Project: TwlIPL - firmware # File: Makefile # # Copyright 2007 Nintendo. All rights reserved. @@ -16,21 +16,18 @@ # $Author$ #---------------------------------------------------------------------------- -include $(TWLSDK_ROOT)/build/buildtools/commondefs +include $(TWL_IPL_RED_ROOT)/build/buildtools/commondefs #---------------------------------------------------------------------------- SUBDIRS = \ - makenorfirm \ - makegcdfirm \ - makenandfirm \ attach_dummyromheader \ #---------------------------------------------------------------------------- -include $(TWLSDK_ROOT)/build/buildtools/modulerules +include $(TWL_IPL_RED_ROOT)/build/buildtools/modulerules #===== End of Makefile ===== diff --git a/build/tools/acsign/Makefile b/build/tools/acsign/Makefile deleted file mode 100644 index d66418af..00000000 --- a/build/tools/acsign/Makefile +++ /dev/null @@ -1,61 +0,0 @@ -#! make -f -#---------------------------------------------------------------------------- -# Project: NitroSDK - libraries - acsign -# File: Makefile -# -# Copyright 2003,2004 Nintendo. All rights reserved. -# -# These coded instructions, statements, and computer programs contain -# proprietary information of Nintendo of America Inc. and/or Nintendo -# Company Ltd., and are protected by Federal copyright law. They may -# not be disclosed to third parties or copied or duplicated in any form, -# in whole or in part, without the prior written consent of Nintendo. -# -# $NoKeywords: $ -#---------------------------------------------------------------------------- - -#---------------------------------------------------------------------------- -# Codegen for sub processer -NITRO_PROC = ARM9 - -# build ARM & THUMB libraries -NITRO_CODEGEN_ALL = True - -#---------------------------------------------------------------------------- - -SUBDIRS = - - -#---------------------------------------------------------------------------- - -SRCDIR = ./src -INCDIR = ./include $(ROOT)/build/libraries/mb/include - - -SRCS = acsign.c acmemory.c acsign_util.c - -TARGET_LIB = libacsign_x86.a - - -include $(TWL_IPL_RED_ROOT)/build/buildtools/commondefs - -# CCFLAGS += -DOPT_32_BIT -DSTANDALONE -DNO_SPLIT -DNO_FP_API -DNO_R_DIAG -DNO_STDIO_H -DNO_STDLIB_H -CCFLAGS += -DSMALL_CODE_SIZE \ - -DSTANDALONE \ - -DOPT_32_BIT \ - -DNO_SPLIT \ - -DNO_FP_API \ - -DNO_R_DIAG \ - -DNO_STDIO_H \ - -DNO_STDLIB_H - -INSTALL_TARGETS = $(TARGETS) -INSTALL_DIR = . - - -do-build: $(TARGETS) - -include $(TWL_IPL_RED_ROOT)/build/buildtools/modulerules - - -#===== End of Makefile ===== diff --git a/build/tools/acsign/acsign.c b/build/tools/acsign/acsign.c deleted file mode 100644 index 7b63142f..00000000 --- a/build/tools/acsign/acsign.c +++ /dev/null @@ -1,334 +0,0 @@ -#include -#include "format_sign.h" -#include "acsign.h" - -// SHA1 -#include "sha1dgst.c" - -// RSA - -// BN -#include "bn.h" - -#include "bn_lib.c" -#include "bn_asm.c" -#include "bn_comba.c" -#include "bn_lsh.c" -#include "bn_rsh.c" -#include "bn_word.c" -#include "bn_add.c" -#include "bn_mul.c" -#include "bn_div.c" -#include "bn_exp.c" -#include "bn_sqr.c" -#include "bn_fm_w.c" -#include "bn_gcd.c" -#include "bn_ex_str.c" -#include "bn_ms_w.c" -//#include "bn_me.c" -#include "bn_rec.c" -#include "bn_mont.c" -#include "bn_recp.c" -#include "bn_wdiv.c" -#include "bn_r_exp.c" -#include "bn_m_exp.c" - - - -#define BER_NULL 5 -#define BER_OBJECT 6 -#define BER_SEQUENCE 16 -#define BER_OCTET_STRING 4 -#define BER_CONSTRUCTED 0x20 - - -/** - * Perform the EMSA-PKCS1_v1_5 padding - * - * @param random random context for seed data generation - * @param out destination buffer - * @param out_len length written to out - * @param in data to be padded - * @param in_len length of in - * @param flags mask of operation directives - * - * @pre out_len must contain length of data allocated to out - * @pre out must be the allocated the total length to be padded - * - * @note Method from PKCS#1 v2.1 standard 9.2.1 EMSA-PKCS1-v1_5 - * @li In: Hash is hash funtion, hLen denotes length of octets of hash output - * @li In: M is message to be encoded - * @li In: emLen is intended length of octets - * @li Out: EM encoded message of length emLen - * - * @li Apply the hash function to message M to produce a hash value H - * If hash output is message to long the output message too long and - * stop - * @li Encode the algorithm ID for the hash in function into an ASN1 value - * @li if emLen < 10 + BER encoded message T output message length too short - * and stop - * @li generate octet string PS consisting of emLen - Length(T) - 2 octets - * with value FF - * @li Concatenate PS, DER encoding T and other padding such that EM is: - * 01 || PS || 00 || T - * - * @note it is the out layers responsibility to DER encode the - * data prior to padding as described in the first 2 steps in method - */ -// -// rsa_padding_add_pkcs1_type_1関数相当 -// -static int add_padding(unsigned char *out, - int out_len, const unsigned char *in, int in_len) -{ - unsigned char *p; - int j,i; - - if ((in_len+11) > out_len) - return(1); - - /* First we copy data bytes to the output buffer, this - * way the input and output buffers can be the same - * and things will still work */ - p=out+out_len-in_len; - for (i=in_len-1; i>=0; i--) - p[i]=in[i]; - p=out; - *(p++)=0; - *(p++)=1; /* Private Key BT (Block Type) */ - - /* pad with 0xff data */ - j=out_len-3-in_len; - Memset(p,0xff,j); - p[j]='\0'; - return(0); -} - -static void debug_dump(const void* buf, int len, const char* str, int line_elms) -{ - const u8* bufp = (u8*)buf; - int i,ii; - - if (str) - { - debug_printf("%s :\n", str); - } - for (i=0; i<=len/line_elms; i++) - { - if (i*line_elms >= len) - { - break; - } - for (ii=0; ii= len) - { - break; - } - debug_printf("%02x ", bufp[i*line_elms+ii]); - } - debug_printf("\n"); - } -} - -// -// RSA -// -BOOL ACSign_Encrypto(void *sign, const void *key, const void *data, int length) -{ - BN_CTX *ctx; - BIGNUM src, dst, exp, mod; - u8* key_exp = &((u8*)key)[ACS_RSA_PRVEXP_OFFSET]; - u8* key_mod = &((u8*)key)[ACS_RSA_PRVMOD_OFFSET]; - u8 buf[ACS_ENCRYPTED_HASH_LEN]; - u32 len = length; - BOOL result = TRUE; - - if (NULL == sign || NULL == key || NULL == data || 0 > length) { - return FALSE; - } - - if ( add_padding( buf, ACS_ENCRYPTED_HASH_LEN, data, length ) ) { - debug_printf2("encode_padding was failed.\n"); - result = FALSE; - goto end; - } - - { - debug_dump(buf, ACS_ENCRYPTED_HASH_LEN, "padded hash", 16); - debug_dump(key_mod, ACS_RSA_PRVMOD_LEN, "key mod", 16); - debug_dump(key_exp, ACS_RSA_PRVEXP_LEN, "key exp", 16); - } - - ctx = BN_CTX_new(); - - BN_init(&src); - BN_init(&dst); - BN_init(&exp); - BN_init(&mod); - - BN_bin2bn((u8*)buf, ACS_ENCRYPTED_HASH_LEN, &src); - BN_bin2bn(key_exp, ACS_RSA_PRVEXP_LEN, &exp); - BN_bin2bn(key_mod, ACS_RSA_PRVMOD_LEN, &mod); - - BN_mod_exp( &dst, &src, &exp, &mod, ctx ); - - len = BN_bn2bin( &dst, sign ); - - BN_free(&src); - BN_free(&dst); - BN_free(&exp); - BN_free(&mod); - - if (ctx) { - BN_CTX_free(ctx); - } - - if ( len != ACS_DECRYPTED_HASH_LEN ) { - result = FALSE; - goto end; - } -end: - return result; -} - -BOOL ACSign_Decrypto(void *buf, const void *key, const void *sign, int length) -{ - BN_CTX *ctx; - BIGNUM src, dst, exp, mod; - u32 key_exp = ACS_RSA_EXP; - u8* key_mod = &((u8*)key)[ACS_RSA_PRVMOD_OFFSET]; - u8* bufp = (u8*)buf; - u32 len = length; - BOOL result = TRUE; - - if (NULL == buf || NULL == key || NULL == sign || 0 > length) { - return FALSE; - } - - ctx = BN_CTX_new(); - - BN_init(&src); - BN_init(&dst); - BN_init(&exp); - BN_init(&mod); - - BN_bin2bn((u8*)sign, ACS_ENCRYPTED_HASH_LEN, &src); - BN_bin2bn((u8*)&key_exp, ACS_RSA_PUBEXP_LEN, &exp); - BN_bin2bn(key_mod, ACS_RSA_PRVMOD_LEN, &mod); - - BN_mod_exp( &dst, &src, &exp, &mod, ctx ); - - len = BN_bn2bin( &dst, bufp ); - - BN_free(&src); - BN_free(&dst); - BN_free(&exp); - BN_free(&mod); - - if (ctx) { - BN_CTX_free(ctx); - } - - if ( len != ACS_DECRYPTED_HASH_LEN ) { - result = FALSE; - goto end; - } -end: - return result; -} - -// -int ACSign_DigestUnit( - void* buffer, // 出力領域 - const void* buf, // データへのポインタ - unsigned int len // データの長さ - ) -{ - HASHContext context; - unsigned char *bufferp = buffer; - - HASHReset( &context ); - HASHUpdate( &context, buf, len ); - HASHGetDigest( &context, bufferp ); - - return TRUE; -} - -// -int ACSign_CompareUnit( - const void* decedHash, // ACSign_Decryptoの出力 - const void* digest // ACSign_DigestUnitの出力 - ) -{ - const unsigned char* dgt = digest; - const unsigned char* dgtCmp = decedHash; - int i; - int test = TRUE; - - if ( !decedHash ) return FALSE; - if ( !digest ) return FALSE; - - for ( i = 0; i < ACS_HASH_LEN; i++ ) - { - if ( *dgt++ != *dgtCmp++ ) - { - test = FALSE; - break; - } - } - return test; -} - -/* - 任意バイト数の入力データから - 任意バイト数の出力データを得ます。 - 偏っているかもしれない入力値を一様な値にマップするだけです。 - 入出力メモリがかぶっていても問題ない -*/ -int ACSign_GetKey( - void* dest_ptr, // 出力データへのポインタ - unsigned int dest_len, // 出力データの長さ - const void* src_ptr, // 入力データへのポインタ - unsigned int src_len // 入力データの長さ - ) -{ - HASHContext ctx; - unsigned char *ptr; - unsigned char state[ACS_HASH_LEN]; - unsigned char output[ACS_HASH_LEN]; - int i; - - if (dest_ptr == NULL) - return 1; - if (src_ptr == NULL && src_len > 0) - return 0; - - HASHReset(&ctx); - - HASHUpdate(&ctx, src_ptr, src_len); - HASHGetDigest(&ctx, state); - - ptr = dest_ptr; - while (dest_len > 0) - { - unsigned int len = dest_len < ACS_HASH_LEN ? dest_len : ACS_HASH_LEN; - - // plus one - for (i = 0; i < ACS_HASH_LEN; i++) - { - if (state[ACS_HASH_LEN-1-i]++) - break; - } - - HASHUpdate(&ctx, state, ACS_HASH_LEN); - HASHGetDigest(&ctx, output); - memcpy(ptr, output, len); - ptr += len; - dest_len -= len; - } - memset(state, 0, ACS_HASH_LEN); - memset(output, 0, ACS_HASH_LEN); - return 1; -} - diff --git a/build/tools/acsign/acsign_gcd.c b/build/tools/acsign/acsign_gcd.c deleted file mode 100644 index e8b45670..00000000 --- a/build/tools/acsign/acsign_gcd.c +++ /dev/null @@ -1,74 +0,0 @@ -#include -#include "acsign_gcd.h" - -static void debug_dump(void* buf, int len, char* str, int line_elms) -{ - u8* bufp = (u8*)buf; - int i,ii; - - if (str) - { - debug_printf("%s :\n", str); - } - for (i=0; i<=len/line_elms; i++) - { - if (i*line_elms >= len) - { - break; - } - for (ii=0; ii= len) - { - break; - } - debug_printf("%02x ", bufp[i*line_elms+ii]); - } - debug_printf("\n"); - } -} - -// -int ACSign_DigestHeader( - void* buffer, // 出力領域 - GCDHeader* header // ヘッダへのポインタ - ) -{ - HASHContext context; - GCDHeader* nh = header; - unsigned char *bufferp = buffer; - - HASHReset( &context ); - HASHUpdate( &context, (void*)&nh->l, sizeof(GCDHeaderLow) ); - HASHUpdate( &context, (void*)&nh->h, sizeof(GCDHeaderHigh) ); - HASHGetDigest( &context, bufferp ); - - return TRUE; -} - -// -int ACSign_Final( - GCDHeader* header, // ヘッダへのポインタ - void* buffer, // 入力領域 - const void* key - ) -{ - GCDHeader* nh = header; - FIRMSignedContext* sc = buffer; - - if (key) - { - unsigned char decSign[ACS_ENCRYPTED_HASH_LEN]; - - debug_dump(sc->hash, sizeof(sc->hash), "5 hashs of header, norfirms and total", 20); - - ACSign_Encrypto(&nh->sign, key, buffer, sizeof(FIRMSignedContext)); - ACSign_Decrypto(decSign, key, (void*)&nh->sign, ACS_ENCRYPTED_HASH_LEN); - - debug_dump(&nh->sign, ACS_ENCRYPTED_HASH_LEN, "encrypted sign", 16); - debug_dump(decSign, ACS_ENCRYPTED_HASH_LEN, "decrypted sign", 16); - } - - return TRUE; -} - diff --git a/build/tools/acsign/acsign_nand.c b/build/tools/acsign/acsign_nand.c deleted file mode 100644 index 8b0b719c..00000000 --- a/build/tools/acsign/acsign_nand.c +++ /dev/null @@ -1,75 +0,0 @@ -#include -#include "acsign_nand.h" - -static void debug_dump(void* buf, int len, char* str, int line_elms) -{ - u8* bufp = (u8*)buf; - int i,ii; - - if (str) - { - debug_printf("%s :\n", str); - } - for (i=0; i<=len/line_elms; i++) - { - if (i*line_elms >= len) - { - break; - } - for (ii=0; ii= len) - { - break; - } - debug_printf("%02x ", bufp[i*line_elms+ii]); - } - debug_printf("\n"); - } -} - -// -int ACSign_DigestHeader( - void* buffer, // 出力領域 - NANDHeader* header // ヘッダへのポインタ - ) -{ - HASHContext context; - NANDHeader* nh = header; - unsigned char *bufferp = buffer; - - HASHReset( &context ); - HASHUpdate( &context, (void*)&nh->d, sizeof(NORHeaderDS) ); - HASHUpdate( &context, (void*)&nh->l, sizeof(NANDHeaderLow) ); - HASHUpdate( &context, (void*)&nh->h, sizeof(NANDHeaderHigh) ); - HASHGetDigest( &context, bufferp ); - - return TRUE; -} - -// -int ACSign_Final( - NANDHeader* header, // ヘッダへのポインタ - void* buffer, // 入力領域 - const void* key - ) -{ - NANDHeader* nh = header; - FIRMSignedContext* sc = buffer; - - if (key) - { - unsigned char decSign[ACS_ENCRYPTED_HASH_LEN]; - - debug_dump(sc->hash, sizeof(sc->hash), "5 hashs of header, nandfirms and total", 20); - - ACSign_Encrypto(&nh->sign, key, buffer, sizeof(FIRMSignedContext)); - ACSign_Decrypto(decSign, key, (void*)&nh->sign, ACS_ENCRYPTED_HASH_LEN); - - debug_dump(&nh->sign, ACS_ENCRYPTED_HASH_LEN, "encrypted sign", 16); - debug_dump(decSign, ACS_ENCRYPTED_HASH_LEN, "decrypted sign", 16); - } - - return TRUE; -} - diff --git a/build/tools/acsign/acsign_nor.c b/build/tools/acsign/acsign_nor.c deleted file mode 100644 index 0bb690c9..00000000 --- a/build/tools/acsign/acsign_nor.c +++ /dev/null @@ -1,75 +0,0 @@ -#include -#include "acsign_nor.h" - -static void debug_dump(void* buf, int len, char* str, int line_elms) -{ - u8* bufp = (u8*)buf; - int i,ii; - - if (str) - { - debug_printf("%s :\n", str); - } - for (i=0; i<=len/line_elms; i++) - { - if (i*line_elms >= len) - { - break; - } - for (ii=0; ii= len) - { - break; - } - debug_printf("%02x ", bufp[i*line_elms+ii]); - } - debug_printf("\n"); - } -} - -// -int ACSign_DigestHeader( - void* buffer, // 出力領域 - NORHeader* header // ヘッダへのポインタ - ) -{ - HASHContext context; - NORHeader* nh = header; - unsigned char *bufferp = buffer; - - HASHReset( &context ); - HASHUpdate( &context, (void*)&nh->d, sizeof(NORHeaderDS) ); - HASHUpdate( &context, (void*)&nh->l, sizeof(NORHeaderLow) ); - HASHUpdate( &context, (void*)&nh->h, sizeof(NORHeaderHigh) ); - HASHGetDigest( &context, bufferp ); - - return TRUE; -} - -// -int ACSign_Final( - NORHeader* header, // ヘッダへのポインタ - void* buffer, // 入力領域 - const void* key - ) -{ - NORHeader* nh = header; - FIRMSignedContext* sc = buffer; - - if (key) - { - unsigned char decSign[ACS_ENCRYPTED_HASH_LEN]; - - debug_dump(sc->hash, sizeof(sc->hash), "5 hashs of header, norfirms and total", 20); - - ACSign_Encrypto(&nh->sign, key, buffer, sizeof(FIRMSignedContext)); - ACSign_Decrypto(decSign, key, (void*)&nh->sign, ACS_ENCRYPTED_HASH_LEN); - - debug_dump(&nh->sign, ACS_ENCRYPTED_HASH_LEN, "encrypted sign", 16); - debug_dump(decSign, ACS_ENCRYPTED_HASH_LEN, "decrypted sign", 16); - } - - return TRUE; -} - diff --git a/build/tools/acsign/aes.h b/build/tools/acsign/aes.h deleted file mode 100644 index a7a75d8d..00000000 --- a/build/tools/acsign/aes.h +++ /dev/null @@ -1,139 +0,0 @@ -/* $Id$ */ -/* - * Copyright (C) 1998-2003 RSA Security Inc. All rights reserved. - * - * This work contains proprietary information of RSA Security. - * Distribution is limited to authorized licensees of RSA - * Security. Any unauthorized reproduction, distribution or - * modification of this work is strictly prohibited. - */ - -#ifndef HEADER_COMMON_AES_H -#define HEADER_COMMON_AES_H - -#ifdef __cplusplus -extern "C" { -#endif - -#define AES_ecb_encrypt(key, out, in) \ - AES_ecb_encrypt_com((key), (out), (in), AES_encrypt) -#define AES_ecb_encrypt_m(key, out, in) \ - AES_ecb_encrypt_com((key), (out), (in), AES_encrypt_m) -#define AES_ecb_encrypt_s(key, out, in) \ - AES_ecb_encrypt_com((key), (out), (in), AES_encrypt_s) - -#define AES_ecb_decrypt(key, out, in) \ - AES_ecb_decrypt_com((key), (out), (in), AES_decrypt) -#define AES_ecb_decrypt_m(key, out, in) \ - AES_ecb_decrypt_com((key), (out), (in), AES_decrypt_m) -#define AES_ecb_decrypt_s(key, out, in) \ - AES_ecb_decrypt_com((key), (out), (in), AES_decrypt_s) - -#define AES_cbc_encrypt(ctx, out, in, len, iv) \ - AES_cbc_encrypt_com((ctx), (out), (in), (len), (iv), AES_encrypt) -#define AES_cbc_encrypt_m(ctx, out, in, len, iv) \ - AES_cbc_encrypt_com((ctx), (out), (in), (len), (iv), AES_encrypt_m) -#define AES_cbc_encrypt_s(ctx, out, in, len, iv) \ - AES_cbc_encrypt_com((ctx), (out), (in), (len), (iv), AES_encrypt_s) - -#define AES_cbc_decrypt(ctx, out, in, len, iv) \ - AES_cbc_decrypt_com((ctx), (out), (in), (len), (iv), AES_decrypt) -#define AES_cbc_decrypt_m(ctx, out, in, len, iv) \ - AES_cbc_decrypt_com((ctx), (out), (in), (len), (iv), AES_decrypt_m) -#define AES_cbc_decrypt_s(ctx, out, in, len, iv) \ - AES_cbc_decrypt_com((ctx), (out), (in), (len), (iv), AES_decrypt_s) - -#define AES_cfb128_encrypt(ks, out, in, len, iv, num) \ - AES_cfb128_encrypt_com((ks), (out), (in), (len), (iv), (num), \ - AES_encrypt) -#define AES_cfb128_encrypt_m(ks, out, in, len, iv, num) \ - AES_cfb128_encrypt_com((ks), (out), (in), (len), (iv), (num), \ - AES_encrypt_m) -#define AES_cfb128_encrypt_s(ks, out, in, len, iv, num) \ - AES_cfb128_encrypt_com((ks), (out), (in), (len), (iv), (num), \ - AES_encrypt_s) - -#define AES_cfb128_decrypt(ks, out, in, len, iv, num) \ - AES_cfb128_decrypt_com((ks), (out), (in), (len), (iv), (num), \ - AES_decrypt) -#define AES_cfb128_decrypt_m(ks, out, in, len, iv, num) \ - AES_cfb128_decrypt_com((ks), (out), (in), (len), (iv), (num), \ - AES_decrypt_m) -#define AES_cfb128_decrypt_s(ks, out, in, len, iv, num) \ - AES_cfb128_decrypt_com((ks), (out), (in), (len), (iv), (num), \ - AES_decrypt_s) - -/** Note. OFB encryption is also used for decryption */ -#define AES_ofb128_encrypt(ks, out, in, len, iv, num) \ - AES_ofb128_encrypt_com((ks), (out), (in), (len), (iv), (num), \ - AES_encrypt) -#define AES_ofb128_encrypt_m(ks, out, in, len, iv, num) \ - AES_ofb128_encrypt_com((ks), (out), (in), (len), (iv), (num), \ - AES_encrypt_m) -#define AES_ofb128_encrypt_s(ks, out, in, len, iv, num) \ - AES_ofb128_encrypt_com((ks), (out), (in), (len), (iv), (num), \ - AES_encrypt_s) - -#define AES_ofb128_decrypt(ks, out, in, len, iv, num) \ - AES_ofb128_encrypt_com((ks), (out), (in), (len), (iv), (num), \ - AES_encrypt) -#define AES_ofb128_decrypt_m(ks, out, in, len, iv, num) \ - AES_ofb128_encrypt_com((ks), (out), (in), (len), (iv), (num), \ - AES_encrypt_m) -#define AES_ofb128_decrypt_s(ks, out, in, len, iv, num) \ - AES_ofb128_encrypt_com((ks), (out), (in), (len), (iv), (num), \ - AES_encrypt_s) - - -#define AES_MAXROUNDS 14 - -#define AES_ENCRYPT 1 -#define AES_DECRYPT 0 - -typedef unsigned int AES_INT4; - -typedef struct aes_key_st { - unsigned int rounds; - unsigned int key_size; - AES_INT4 ks[(AES_MAXROUNDS+1)*8]; - } AES_KEY; - -typedef void (* AES_ENC_DEC_FN)(AES_KEY *, AES_INT4 *); - -void AES_encrypt(AES_KEY *ctx,AES_INT4 *data); -void AES_encrypt_m(AES_KEY *ctx,AES_INT4 *data); -void AES_encrypt_s(AES_KEY *ctx,AES_INT4 *data); -void AES_decrypt(AES_KEY *ctx,AES_INT4 *data); -void AES_decrypt_m(AES_KEY *ctx,AES_INT4 *data); -void AES_decrypt_s(AES_KEY *ctx,AES_INT4 *data); - -void AES_ecb_encrypt_com(AES_KEY *key, unsigned char *out, - const unsigned char *in, AES_ENC_DEC_FN enc_fn); -void AES_ecb_decrypt_com(AES_KEY *key, unsigned char *out, - const unsigned char *in, AES_ENC_DEC_FN dec_fn); -void AES_cbc_encrypt_com(AES_KEY *ctx, unsigned char *out, - const unsigned char *in, long length, unsigned char *iv, - AES_ENC_DEC_FN enc_fn); -void AES_cbc_decrypt_com(AES_KEY *ctx, unsigned char *out, - const unsigned char *in, long length, unsigned char *iv, - AES_ENC_DEC_FN dec_fn); -void AES_ofb128_encrypt_com(AES_KEY *ks,const unsigned char *in, - unsigned char *out, long length, unsigned char *ivec, int *num, - AES_ENC_DEC_FN enc_fn); -void AES_cfb128_encrypt_com(AES_KEY *ks, const unsigned char *in, - unsigned char *out, long length, unsigned char *ivec, int *num, - AES_ENC_DEC_FN enc_fn); -void AES_cfb128_decrypt_com(AES_KEY *ks, const unsigned char *in, - unsigned char *out, long length, unsigned char *ivec, int *num, - AES_ENC_DEC_FN dec_fn); - -int AES_set_key(AES_KEY *ctx, const unsigned char *key, int len); -void AES_convert_key(AES_KEY *ctx); -AES_INT4 AES_rotate(AES_INT4 u); -unsigned char AES_xtime(AES_INT4 x); - -#ifdef __cplusplus -} -#endif - -#endif /* HEADER_COMMON_AES_H */ diff --git a/build/tools/acsign/aes2.c b/build/tools/acsign/aes2.c deleted file mode 100644 index 778dc53a..00000000 --- a/build/tools/acsign/aes2.c +++ /dev/null @@ -1,133 +0,0 @@ -#include -#include - -#include "aes2.h" - -#include "aes_e.c" -#include "aes_e_ecb.c" -#include "aes_skey.c" - -// -// swap with memory allocation -// -static unsigned char* AES_Swap(const unsigned char *src, int len, int unit) -{ - int i; - int j; - unsigned char *dest = malloc(len); - for (i = 0; i < len; i+=unit) - for (j = 0; j < unit; j++) - dest[i + j] = src[i + unit - j - 1]; - return dest; -} - -// -// set keys -// -void AES_SetKey(AES_KEY *key, const unsigned char seed[AES_BLOCK_SIZE], const unsigned char id[AES_BLOCK_SIZE]) -{ - static const unsigned char f[AES_BLOCK_SIZE] = {0xff, 0xfe, 0xfb, 0x4e, 0x29, 0x59, 0x02, 0x58, 0x2a, 0x68, 0x0f, 0x5f, 0x1a, 0x4f, 0x3e, 0x79}; - static const unsigned char s = 0x2a; - - unsigned char key1[AES_BLOCK_SIZE]; - unsigned char key2[AES_BLOCK_SIZE]; - int i; - int o = 0; - - for (i = 0; i < AES_BLOCK_SIZE; i++) { - key1[i] = seed[AES_BLOCK_SIZE-i-1] ^ id[AES_BLOCK_SIZE-i-1]; - } - for (i = AES_BLOCK_SIZE - 1; i >= 0; i--) { - int t = key1[i] + f[i] + o; - o = (t > 0xFF ? 1 : 0); - key1[i] = t & 0xFF; - } - for (i = 0; i < AES_BLOCK_SIZE; i++) { - int j1 = (i + s / 8) % AES_BLOCK_SIZE; - int j2 = (j1 + 1) % AES_BLOCK_SIZE; - int k = s % 8; - key2[i] = ((key1[j1] << k) & 0xFF) | ((key1[j2] >> (8 - k)) & 0xFF); - } - AES_set_key(key, key2, 16); - memset(key2, 0, 16); - memset(key1, 0, 16); -} - -// -// ctr mode -// -#define GETU32(pt) (((unsigned long)(pt)[0] << 24) ^ ((unsigned long)(pt)[1] << 16) ^ ((unsigned long)(pt)[2] << 8) ^ ((unsigned long)(pt)[3])) -#define PUTU32(ct, st) { (ct)[0] = (unsigned char)((st) >> 24); (ct)[1] = (unsigned char)((st) >> 16); (ct)[2] = (unsigned char)((st) >> 8); (ct)[3] = (unsigned char)(st); } - -/* increment counter as u128 */ -static void AES_ctr128_increment(unsigned char *counter) { - unsigned long c; - - c = GETU32(counter + 12); - c++; c &= 0xFFFFFFFF; - PUTU32(counter + 12, c); - if (c) return; // return unless overflow - - c = GETU32(counter + 8); - c++; c &= 0xFFFFFFFF; - PUTU32(counter + 8, c); - if (c) return; // return unless overflow - - c = GETU32(counter + 4); - c++; c &= 0xFFFFFFFF; - PUTU32(counter + 4, c); - if (c) return; // return unless overflow - - c = GETU32(counter + 0); - c++; c &= 0xFFFFFFFF; - PUTU32(counter + 0, c); -} -static void AES_ctr128(const unsigned char *in, unsigned char *out, const unsigned long length, AES_KEY *key, - unsigned char ivec[AES_BLOCK_SIZE], unsigned char ebuf[AES_BLOCK_SIZE], unsigned int *num) { - - unsigned int n; - unsigned long l=length; - - n = *num; - - while (l--) { // loop each byte - if (n == 0) { - AES_ecb_encrypt(key, ebuf, ivec); // encrypt counter - AES_ctr128_increment(ivec); // increment counter - } - *(out++) = *(in++) ^ ebuf[n]; - n = (n+1) % AES_BLOCK_SIZE; - } - - *num=n; -} - -void AES_Ctr(AES_KEY *key, unsigned char *outdata, const unsigned char *indata, int len, unsigned char iv[AES_BLOCK_SIZE]) -{ - unsigned char ebuf[AES_BLOCK_SIZE]; - unsigned char *tmp; - unsigned int nums; - - if (len <= 0 || len > 0xFFFF00 || (len % AES_BLOCK_SIZE) != 0 || indata == NULL || outdata == NULL) - { - return; - } - - // CTR - memset(ebuf, 0, AES_BLOCK_SIZE); - nums = 0; - - tmp = AES_Swap(iv, AES_BLOCK_SIZE, AES_BLOCK_SIZE); - memcpy(iv, tmp, AES_BLOCK_SIZE); - free(tmp); - - tmp = AES_Swap(indata, len, AES_BLOCK_SIZE); - AES_ctr128(tmp, outdata, len, key, iv, ebuf, &nums); - free(tmp); - - tmp = AES_Swap(outdata, len, AES_BLOCK_SIZE); - memcpy(outdata, tmp, len); - free(tmp); - return; -} - diff --git a/build/tools/acsign/aes2.h b/build/tools/acsign/aes2.h deleted file mode 100644 index 3e80799d..00000000 --- a/build/tools/acsign/aes2.h +++ /dev/null @@ -1,21 +0,0 @@ -#ifndef __AES_2_H__ -#define __AES_2_H__ - -#include "aes.h" - -#define AES_BLOCK_SIZE 16 -#define AES_NONCE_SIZE 12 -#define AES_QUANTITY (AES_BLOCK_SIZE - AES_NONCE_SIZE - 1) - -#ifdef __cplusplus -extern "C" { -#endif - -void AES_SetKey(AES_KEY *key, const unsigned char seed[AES_BLOCK_SIZE], const unsigned char id[AES_BLOCK_SIZE]); -void AES_Ctr(AES_KEY *key, unsigned char *outdata, const unsigned char *indata, int len, unsigned char iv[AES_BLOCK_SIZE]); - -#ifdef __cplusplus -} -#endif - -#endif // __AES_2_H__ diff --git a/build/tools/acsign/aes_e.c b/build/tools/acsign/aes_e.c deleted file mode 100644 index fab235c1..00000000 --- a/build/tools/acsign/aes_e.c +++ /dev/null @@ -1,115 +0,0 @@ -/* $Id$ */ -/* - * Copyright (C) 1998-2003 RSA Security Inc. All rights reserved. - * - * This work contains proprietary information of RSA Security. - * Distribution is limited to authorized licensees of RSA - * Security. Any unauthorized reproduction, distribution or - * modification of this work is strictly prohibited. - */ - -/** - * @file aes_e.c - * \brief Large code size (thus fast) AES Encryption - */ - -#ifndef NO_AES - -#include "aes.h" - -/* Include the Large aes_submix tables */ -#include "aes_e.h" - -/* AES ECB Encryption of 1 x 128 bit Block */ -void AES_encrypt(AES_KEY *ctx, AES_INT4 *data) -{ - int r; - int rounds; - AES_INT4 *k; - AES_INT4 o0,o1,o2,o3; - AES_INT4 tmp0,tmp1,tmp2,tmp3; - - rounds=ctx->rounds; - k= (AES_INT4 *)ctx->ks; - - /* Encrypt one block. - */ - tmp0=data[0]; - tmp1=data[1]; - tmp2=data[2]; - tmp3=data[3]; -/*printf("K %08X %08X %08X %08X\n",tmp0,tmp1,tmp2,tmp3); -printf("KS %08X %08X %08X %08X\n",k[0],k[1],k[2],k[3]); */ - tmp0^=k[0]; - tmp1^=k[1]; - tmp2^=k[2]; - tmp3^=k[3]; - k+=4; - - for(r = 1; r < rounds; r++) - { -/*printf("%2d %08X %08X %08X %08X\n",r,tmp0,tmp1,tmp2,tmp3); */ - o0 = aes_submix[3][(tmp3 )&0xff]^ - aes_submix[2][(tmp2>> 8)&0xff]^ - aes_submix[1][(tmp1>>16)&0xff]^ - aes_submix[0][(tmp0>>24)&0xff]; - - o1 = aes_submix[3][(tmp0 )&0xff]^ - aes_submix[2][(tmp3>> 8)&0xff]^ - aes_submix[1][(tmp2>>16)&0xff]^ - aes_submix[0][(tmp1>>24)&0xff]; - - o2 = - aes_submix[3][(tmp1 )&0xff]^ - aes_submix[2][(tmp0>> 8)&0xff]^ - aes_submix[1][(tmp3>>16)&0xff]^ - aes_submix[0][(tmp2>>24)&0xff]; - - o3 = - aes_submix[3][(tmp2 )&0xff]^ - aes_submix[2][(tmp1>> 8)&0xff]^ - aes_submix[1][(tmp0>>16)&0xff]^ - aes_submix[0][(tmp3>>24)&0xff]; - -/* -printf(" %08X %08X %08X %08X\n",o0,o1,o2,o3); -printf("KS %08X %08X %08X %08X\n",k[0],k[1],k[2],k[3]); */ - tmp0=o0^k[0]; - tmp1=o1^k[1]; - tmp2=o2^k[2]; - tmp3=o3^k[3]; - k+=4; - } -/*printf("O %08X %08X %08X %08X\n",o0,o1,o2,o3); */ - o0 = (aes_submix[0][(tmp3 )&0xff]>> 8)&0xFF; - o1 = (aes_submix[0][(tmp0 )&0xff]>> 8)&0xFF; - o2 = (aes_submix[0][(tmp1 )&0xff]>> 8)&0xFF; - o3 = (aes_submix[0][(tmp2 )&0xff]>> 8)&0xFF; - - o0|= (aes_submix[0][(tmp2>> 8)&0xff] )&0xFF00; - o1|= (aes_submix[0][(tmp3>> 8)&0xff] )&0xFF00; - o2|= (aes_submix[0][(tmp0>> 8)&0xff] )&0xFF00; - o3|= (aes_submix[0][(tmp1>> 8)&0xff] )&0xFF00; - - o0|= (aes_submix[0][(tmp1>>16)&0xff]<< 8)&0xFF0000; - o1|= (aes_submix[0][(tmp2>>16)&0xff]<< 8)&0xFF0000; - o2|= (aes_submix[0][(tmp3>>16)&0xff]<< 8)&0xFF0000; - o3|= (aes_submix[0][(tmp0>>16)&0xff]<< 8)&0xFF0000; - - o0|= (aes_submix[0][(tmp0>>24) ]<<16)&0xFF000000; - o1|= (aes_submix[0][(tmp1>>24) ]<<16)&0xFF000000; - o2|= (aes_submix[0][(tmp2>>24) ]<<16)&0xFF000000; - o3|= (aes_submix[0][(tmp3>>24) ]<<16)&0xFF000000; -/*printf("P %08X %08X %08X %08X\n",o0,o1,o2,o3); */ - o0^=k[0]; - o1^=k[1]; - o2^=k[2]; - o3^=k[3]; -/*printf("Q %08X %08X %08X %08X\n",o0,o1,o2,o3); */ - data[0]= o0; - data[1]= o1; - data[2]= o2; - data[3]= o3; - } - -#endif /* NO_AES */ diff --git a/build/tools/acsign/aes_e.h b/build/tools/acsign/aes_e.h deleted file mode 100644 index 74f6db70..00000000 --- a/build/tools/acsign/aes_e.h +++ /dev/null @@ -1,284 +0,0 @@ -/* $Id$ */ -/* - * Copyright (C) 1998-2003 RSA Security Inc. All rights reserved. - * - * This work contains proprietary information of RSA Security. - * Distribution is limited to authorized licensees of RSA - * Security. Any unauthorized reproduction, distribution or - * modification of this work is strictly prohibited. - */ - -#ifndef HEADER_COMMON_AES_E_H -#define HEADER_COMMON_AES_E_H - -#ifdef __cplusplus -extern "C" { -#endif - -const AES_INT4 aes_submix[4][256]={{ - 0xC66363A5,0xF87C7C84,0xEE777799,0xF67B7B8D, - 0xFFF2F20D,0xD66B6BBD,0xDE6F6FB1,0x91C5C554, - 0x60303050,0x02010103,0xCE6767A9,0x562B2B7D, - 0xE7FEFE19,0xB5D7D762,0x4DABABE6,0xEC76769A, - 0x8FCACA45,0x1F82829D,0x89C9C940,0xFA7D7D87, - 0xEFFAFA15,0xB25959EB,0x8E4747C9,0xFBF0F00B, - 0x41ADADEC,0xB3D4D467,0x5FA2A2FD,0x45AFAFEA, - 0x239C9CBF,0x53A4A4F7,0xE4727296,0x9BC0C05B, - 0x75B7B7C2,0xE1FDFD1C,0x3D9393AE,0x4C26266A, - 0x6C36365A,0x7E3F3F41,0xF5F7F702,0x83CCCC4F, - 0x6834345C,0x51A5A5F4,0xD1E5E534,0xF9F1F108, - 0xE2717193,0xABD8D873,0x62313153,0x2A15153F, - 0x0804040C,0x95C7C752,0x46232365,0x9DC3C35E, - 0x30181828,0x379696A1,0x0A05050F,0x2F9A9AB5, - 0x0E070709,0x24121236,0x1B80809B,0xDFE2E23D, - 0xCDEBEB26,0x4E272769,0x7FB2B2CD,0xEA75759F, - 0x1209091B,0x1D83839E,0x582C2C74,0x341A1A2E, - 0x361B1B2D,0xDC6E6EB2,0xB45A5AEE,0x5BA0A0FB, - 0xA45252F6,0x763B3B4D,0xB7D6D661,0x7DB3B3CE, - 0x5229297B,0xDDE3E33E,0x5E2F2F71,0x13848497, - 0xA65353F5,0xB9D1D168,0x00000000,0xC1EDED2C, - 0x40202060,0xE3FCFC1F,0x79B1B1C8,0xB65B5BED, - 0xD46A6ABE,0x8DCBCB46,0x67BEBED9,0x7239394B, - 0x944A4ADE,0x984C4CD4,0xB05858E8,0x85CFCF4A, - 0xBBD0D06B,0xC5EFEF2A,0x4FAAAAE5,0xEDFBFB16, - 0x864343C5,0x9A4D4DD7,0x66333355,0x11858594, - 0x8A4545CF,0xE9F9F910,0x04020206,0xFE7F7F81, - 0xA05050F0,0x783C3C44,0x259F9FBA,0x4BA8A8E3, - 0xA25151F3,0x5DA3A3FE,0x804040C0,0x058F8F8A, - 0x3F9292AD,0x219D9DBC,0x70383848,0xF1F5F504, - 0x63BCBCDF,0x77B6B6C1,0xAFDADA75,0x42212163, - 0x20101030,0xE5FFFF1A,0xFDF3F30E,0xBFD2D26D, - 0x81CDCD4C,0x180C0C14,0x26131335,0xC3ECEC2F, - 0xBE5F5FE1,0x359797A2,0x884444CC,0x2E171739, - 0x93C4C457,0x55A7A7F2,0xFC7E7E82,0x7A3D3D47, - 0xC86464AC,0xBA5D5DE7,0x3219192B,0xE6737395, - 0xC06060A0,0x19818198,0x9E4F4FD1,0xA3DCDC7F, - 0x44222266,0x542A2A7E,0x3B9090AB,0x0B888883, - 0x8C4646CA,0xC7EEEE29,0x6BB8B8D3,0x2814143C, - 0xA7DEDE79,0xBC5E5EE2,0x160B0B1D,0xADDBDB76, - 0xDBE0E03B,0x64323256,0x743A3A4E,0x140A0A1E, - 0x924949DB,0x0C06060A,0x4824246C,0xB85C5CE4, - 0x9FC2C25D,0xBDD3D36E,0x43ACACEF,0xC46262A6, - 0x399191A8,0x319595A4,0xD3E4E437,0xF279798B, - 0xD5E7E732,0x8BC8C843,0x6E373759,0xDA6D6DB7, - 0x018D8D8C,0xB1D5D564,0x9C4E4ED2,0x49A9A9E0, - 0xD86C6CB4,0xAC5656FA,0xF3F4F407,0xCFEAEA25, - 0xCA6565AF,0xF47A7A8E,0x47AEAEE9,0x10080818, - 0x6FBABAD5,0xF0787888,0x4A25256F,0x5C2E2E72, - 0x381C1C24,0x57A6A6F1,0x73B4B4C7,0x97C6C651, - 0xCBE8E823,0xA1DDDD7C,0xE874749C,0x3E1F1F21, - 0x964B4BDD,0x61BDBDDC,0x0D8B8B86,0x0F8A8A85, - 0xE0707090,0x7C3E3E42,0x71B5B5C4,0xCC6666AA, - 0x904848D8,0x06030305,0xF7F6F601,0x1C0E0E12, - 0xC26161A3,0x6A35355F,0xAE5757F9,0x69B9B9D0, - 0x17868691,0x99C1C158,0x3A1D1D27,0x279E9EB9, - 0xD9E1E138,0xEBF8F813,0x2B9898B3,0x22111133, - 0xD26969BB,0xA9D9D970,0x078E8E89,0x339494A7, - 0x2D9B9BB6,0x3C1E1E22,0x15878792,0xC9E9E920, - 0x87CECE49,0xAA5555FF,0x50282878,0xA5DFDF7A, - 0x038C8C8F,0x59A1A1F8,0x09898980,0x1A0D0D17, - 0x65BFBFDA,0xD7E6E631,0x844242C6,0xD06868B8, - 0x824141C3,0x299999B0,0x5A2D2D77,0x1E0F0F11, - 0x7BB0B0CB,0xA85454FC,0x6DBBBBD6,0x2C16163A, - },{ - 0xA5C66363,0x84F87C7C,0x99EE7777,0x8DF67B7B, - 0x0DFFF2F2,0xBDD66B6B,0xB1DE6F6F,0x5491C5C5, - 0x50603030,0x03020101,0xA9CE6767,0x7D562B2B, - 0x19E7FEFE,0x62B5D7D7,0xE64DABAB,0x9AEC7676, - 0x458FCACA,0x9D1F8282,0x4089C9C9,0x87FA7D7D, - 0x15EFFAFA,0xEBB25959,0xC98E4747,0x0BFBF0F0, - 0xEC41ADAD,0x67B3D4D4,0xFD5FA2A2,0xEA45AFAF, - 0xBF239C9C,0xF753A4A4,0x96E47272,0x5B9BC0C0, - 0xC275B7B7,0x1CE1FDFD,0xAE3D9393,0x6A4C2626, - 0x5A6C3636,0x417E3F3F,0x02F5F7F7,0x4F83CCCC, - 0x5C683434,0xF451A5A5,0x34D1E5E5,0x08F9F1F1, - 0x93E27171,0x73ABD8D8,0x53623131,0x3F2A1515, - 0x0C080404,0x5295C7C7,0x65462323,0x5E9DC3C3, - 0x28301818,0xA1379696,0x0F0A0505,0xB52F9A9A, - 0x090E0707,0x36241212,0x9B1B8080,0x3DDFE2E2, - 0x26CDEBEB,0x694E2727,0xCD7FB2B2,0x9FEA7575, - 0x1B120909,0x9E1D8383,0x74582C2C,0x2E341A1A, - 0x2D361B1B,0xB2DC6E6E,0xEEB45A5A,0xFB5BA0A0, - 0xF6A45252,0x4D763B3B,0x61B7D6D6,0xCE7DB3B3, - 0x7B522929,0x3EDDE3E3,0x715E2F2F,0x97138484, - 0xF5A65353,0x68B9D1D1,0x00000000,0x2CC1EDED, - 0x60402020,0x1FE3FCFC,0xC879B1B1,0xEDB65B5B, - 0xBED46A6A,0x468DCBCB,0xD967BEBE,0x4B723939, - 0xDE944A4A,0xD4984C4C,0xE8B05858,0x4A85CFCF, - 0x6BBBD0D0,0x2AC5EFEF,0xE54FAAAA,0x16EDFBFB, - 0xC5864343,0xD79A4D4D,0x55663333,0x94118585, - 0xCF8A4545,0x10E9F9F9,0x06040202,0x81FE7F7F, - 0xF0A05050,0x44783C3C,0xBA259F9F,0xE34BA8A8, - 0xF3A25151,0xFE5DA3A3,0xC0804040,0x8A058F8F, - 0xAD3F9292,0xBC219D9D,0x48703838,0x04F1F5F5, - 0xDF63BCBC,0xC177B6B6,0x75AFDADA,0x63422121, - 0x30201010,0x1AE5FFFF,0x0EFDF3F3,0x6DBFD2D2, - 0x4C81CDCD,0x14180C0C,0x35261313,0x2FC3ECEC, - 0xE1BE5F5F,0xA2359797,0xCC884444,0x392E1717, - 0x5793C4C4,0xF255A7A7,0x82FC7E7E,0x477A3D3D, - 0xACC86464,0xE7BA5D5D,0x2B321919,0x95E67373, - 0xA0C06060,0x98198181,0xD19E4F4F,0x7FA3DCDC, - 0x66442222,0x7E542A2A,0xAB3B9090,0x830B8888, - 0xCA8C4646,0x29C7EEEE,0xD36BB8B8,0x3C281414, - 0x79A7DEDE,0xE2BC5E5E,0x1D160B0B,0x76ADDBDB, - 0x3BDBE0E0,0x56643232,0x4E743A3A,0x1E140A0A, - 0xDB924949,0x0A0C0606,0x6C482424,0xE4B85C5C, - 0x5D9FC2C2,0x6EBDD3D3,0xEF43ACAC,0xA6C46262, - 0xA8399191,0xA4319595,0x37D3E4E4,0x8BF27979, - 0x32D5E7E7,0x438BC8C8,0x596E3737,0xB7DA6D6D, - 0x8C018D8D,0x64B1D5D5,0xD29C4E4E,0xE049A9A9, - 0xB4D86C6C,0xFAAC5656,0x07F3F4F4,0x25CFEAEA, - 0xAFCA6565,0x8EF47A7A,0xE947AEAE,0x18100808, - 0xD56FBABA,0x88F07878,0x6F4A2525,0x725C2E2E, - 0x24381C1C,0xF157A6A6,0xC773B4B4,0x5197C6C6, - 0x23CBE8E8,0x7CA1DDDD,0x9CE87474,0x213E1F1F, - 0xDD964B4B,0xDC61BDBD,0x860D8B8B,0x850F8A8A, - 0x90E07070,0x427C3E3E,0xC471B5B5,0xAACC6666, - 0xD8904848,0x05060303,0x01F7F6F6,0x121C0E0E, - 0xA3C26161,0x5F6A3535,0xF9AE5757,0xD069B9B9, - 0x91178686,0x5899C1C1,0x273A1D1D,0xB9279E9E, - 0x38D9E1E1,0x13EBF8F8,0xB32B9898,0x33221111, - 0xBBD26969,0x70A9D9D9,0x89078E8E,0xA7339494, - 0xB62D9B9B,0x223C1E1E,0x92158787,0x20C9E9E9, - 0x4987CECE,0xFFAA5555,0x78502828,0x7AA5DFDF, - 0x8F038C8C,0xF859A1A1,0x80098989,0x171A0D0D, - 0xDA65BFBF,0x31D7E6E6,0xC6844242,0xB8D06868, - 0xC3824141,0xB0299999,0x775A2D2D,0x111E0F0F, - 0xCB7BB0B0,0xFCA85454,0xD66DBBBB,0x3A2C1616, - },{ - 0x63A5C663,0x7C84F87C,0x7799EE77,0x7B8DF67B, - 0xF20DFFF2,0x6BBDD66B,0x6FB1DE6F,0xC55491C5, - 0x30506030,0x01030201,0x67A9CE67,0x2B7D562B, - 0xFE19E7FE,0xD762B5D7,0xABE64DAB,0x769AEC76, - 0xCA458FCA,0x829D1F82,0xC94089C9,0x7D87FA7D, - 0xFA15EFFA,0x59EBB259,0x47C98E47,0xF00BFBF0, - 0xADEC41AD,0xD467B3D4,0xA2FD5FA2,0xAFEA45AF, - 0x9CBF239C,0xA4F753A4,0x7296E472,0xC05B9BC0, - 0xB7C275B7,0xFD1CE1FD,0x93AE3D93,0x266A4C26, - 0x365A6C36,0x3F417E3F,0xF702F5F7,0xCC4F83CC, - 0x345C6834,0xA5F451A5,0xE534D1E5,0xF108F9F1, - 0x7193E271,0xD873ABD8,0x31536231,0x153F2A15, - 0x040C0804,0xC75295C7,0x23654623,0xC35E9DC3, - 0x18283018,0x96A13796,0x050F0A05,0x9AB52F9A, - 0x07090E07,0x12362412,0x809B1B80,0xE23DDFE2, - 0xEB26CDEB,0x27694E27,0xB2CD7FB2,0x759FEA75, - 0x091B1209,0x839E1D83,0x2C74582C,0x1A2E341A, - 0x1B2D361B,0x6EB2DC6E,0x5AEEB45A,0xA0FB5BA0, - 0x52F6A452,0x3B4D763B,0xD661B7D6,0xB3CE7DB3, - 0x297B5229,0xE33EDDE3,0x2F715E2F,0x84971384, - 0x53F5A653,0xD168B9D1,0x00000000,0xED2CC1ED, - 0x20604020,0xFC1FE3FC,0xB1C879B1,0x5BEDB65B, - 0x6ABED46A,0xCB468DCB,0xBED967BE,0x394B7239, - 0x4ADE944A,0x4CD4984C,0x58E8B058,0xCF4A85CF, - 0xD06BBBD0,0xEF2AC5EF,0xAAE54FAA,0xFB16EDFB, - 0x43C58643,0x4DD79A4D,0x33556633,0x85941185, - 0x45CF8A45,0xF910E9F9,0x02060402,0x7F81FE7F, - 0x50F0A050,0x3C44783C,0x9FBA259F,0xA8E34BA8, - 0x51F3A251,0xA3FE5DA3,0x40C08040,0x8F8A058F, - 0x92AD3F92,0x9DBC219D,0x38487038,0xF504F1F5, - 0xBCDF63BC,0xB6C177B6,0xDA75AFDA,0x21634221, - 0x10302010,0xFF1AE5FF,0xF30EFDF3,0xD26DBFD2, - 0xCD4C81CD,0x0C14180C,0x13352613,0xEC2FC3EC, - 0x5FE1BE5F,0x97A23597,0x44CC8844,0x17392E17, - 0xC45793C4,0xA7F255A7,0x7E82FC7E,0x3D477A3D, - 0x64ACC864,0x5DE7BA5D,0x192B3219,0x7395E673, - 0x60A0C060,0x81981981,0x4FD19E4F,0xDC7FA3DC, - 0x22664422,0x2A7E542A,0x90AB3B90,0x88830B88, - 0x46CA8C46,0xEE29C7EE,0xB8D36BB8,0x143C2814, - 0xDE79A7DE,0x5EE2BC5E,0x0B1D160B,0xDB76ADDB, - 0xE03BDBE0,0x32566432,0x3A4E743A,0x0A1E140A, - 0x49DB9249,0x060A0C06,0x246C4824,0x5CE4B85C, - 0xC25D9FC2,0xD36EBDD3,0xACEF43AC,0x62A6C462, - 0x91A83991,0x95A43195,0xE437D3E4,0x798BF279, - 0xE732D5E7,0xC8438BC8,0x37596E37,0x6DB7DA6D, - 0x8D8C018D,0xD564B1D5,0x4ED29C4E,0xA9E049A9, - 0x6CB4D86C,0x56FAAC56,0xF407F3F4,0xEA25CFEA, - 0x65AFCA65,0x7A8EF47A,0xAEE947AE,0x08181008, - 0xBAD56FBA,0x7888F078,0x256F4A25,0x2E725C2E, - 0x1C24381C,0xA6F157A6,0xB4C773B4,0xC65197C6, - 0xE823CBE8,0xDD7CA1DD,0x749CE874,0x1F213E1F, - 0x4BDD964B,0xBDDC61BD,0x8B860D8B,0x8A850F8A, - 0x7090E070,0x3E427C3E,0xB5C471B5,0x66AACC66, - 0x48D89048,0x03050603,0xF601F7F6,0x0E121C0E, - 0x61A3C261,0x355F6A35,0x57F9AE57,0xB9D069B9, - 0x86911786,0xC15899C1,0x1D273A1D,0x9EB9279E, - 0xE138D9E1,0xF813EBF8,0x98B32B98,0x11332211, - 0x69BBD269,0xD970A9D9,0x8E89078E,0x94A73394, - 0x9BB62D9B,0x1E223C1E,0x87921587,0xE920C9E9, - 0xCE4987CE,0x55FFAA55,0x28785028,0xDF7AA5DF, - 0x8C8F038C,0xA1F859A1,0x89800989,0x0D171A0D, - 0xBFDA65BF,0xE631D7E6,0x42C68442,0x68B8D068, - 0x41C38241,0x99B02999,0x2D775A2D,0x0F111E0F, - 0xB0CB7BB0,0x54FCA854,0xBBD66DBB,0x163A2C16, - },{ - 0x6363A5C6,0x7C7C84F8,0x777799EE,0x7B7B8DF6, - 0xF2F20DFF,0x6B6BBDD6,0x6F6FB1DE,0xC5C55491, - 0x30305060,0x01010302,0x6767A9CE,0x2B2B7D56, - 0xFEFE19E7,0xD7D762B5,0xABABE64D,0x76769AEC, - 0xCACA458F,0x82829D1F,0xC9C94089,0x7D7D87FA, - 0xFAFA15EF,0x5959EBB2,0x4747C98E,0xF0F00BFB, - 0xADADEC41,0xD4D467B3,0xA2A2FD5F,0xAFAFEA45, - 0x9C9CBF23,0xA4A4F753,0x727296E4,0xC0C05B9B, - 0xB7B7C275,0xFDFD1CE1,0x9393AE3D,0x26266A4C, - 0x36365A6C,0x3F3F417E,0xF7F702F5,0xCCCC4F83, - 0x34345C68,0xA5A5F451,0xE5E534D1,0xF1F108F9, - 0x717193E2,0xD8D873AB,0x31315362,0x15153F2A, - 0x04040C08,0xC7C75295,0x23236546,0xC3C35E9D, - 0x18182830,0x9696A137,0x05050F0A,0x9A9AB52F, - 0x0707090E,0x12123624,0x80809B1B,0xE2E23DDF, - 0xEBEB26CD,0x2727694E,0xB2B2CD7F,0x75759FEA, - 0x09091B12,0x83839E1D,0x2C2C7458,0x1A1A2E34, - 0x1B1B2D36,0x6E6EB2DC,0x5A5AEEB4,0xA0A0FB5B, - 0x5252F6A4,0x3B3B4D76,0xD6D661B7,0xB3B3CE7D, - 0x29297B52,0xE3E33EDD,0x2F2F715E,0x84849713, - 0x5353F5A6,0xD1D168B9,0x00000000,0xEDED2CC1, - 0x20206040,0xFCFC1FE3,0xB1B1C879,0x5B5BEDB6, - 0x6A6ABED4,0xCBCB468D,0xBEBED967,0x39394B72, - 0x4A4ADE94,0x4C4CD498,0x5858E8B0,0xCFCF4A85, - 0xD0D06BBB,0xEFEF2AC5,0xAAAAE54F,0xFBFB16ED, - 0x4343C586,0x4D4DD79A,0x33335566,0x85859411, - 0x4545CF8A,0xF9F910E9,0x02020604,0x7F7F81FE, - 0x5050F0A0,0x3C3C4478,0x9F9FBA25,0xA8A8E34B, - 0x5151F3A2,0xA3A3FE5D,0x4040C080,0x8F8F8A05, - 0x9292AD3F,0x9D9DBC21,0x38384870,0xF5F504F1, - 0xBCBCDF63,0xB6B6C177,0xDADA75AF,0x21216342, - 0x10103020,0xFFFF1AE5,0xF3F30EFD,0xD2D26DBF, - 0xCDCD4C81,0x0C0C1418,0x13133526,0xECEC2FC3, - 0x5F5FE1BE,0x9797A235,0x4444CC88,0x1717392E, - 0xC4C45793,0xA7A7F255,0x7E7E82FC,0x3D3D477A, - 0x6464ACC8,0x5D5DE7BA,0x19192B32,0x737395E6, - 0x6060A0C0,0x81819819,0x4F4FD19E,0xDCDC7FA3, - 0x22226644,0x2A2A7E54,0x9090AB3B,0x8888830B, - 0x4646CA8C,0xEEEE29C7,0xB8B8D36B,0x14143C28, - 0xDEDE79A7,0x5E5EE2BC,0x0B0B1D16,0xDBDB76AD, - 0xE0E03BDB,0x32325664,0x3A3A4E74,0x0A0A1E14, - 0x4949DB92,0x06060A0C,0x24246C48,0x5C5CE4B8, - 0xC2C25D9F,0xD3D36EBD,0xACACEF43,0x6262A6C4, - 0x9191A839,0x9595A431,0xE4E437D3,0x79798BF2, - 0xE7E732D5,0xC8C8438B,0x3737596E,0x6D6DB7DA, - 0x8D8D8C01,0xD5D564B1,0x4E4ED29C,0xA9A9E049, - 0x6C6CB4D8,0x5656FAAC,0xF4F407F3,0xEAEA25CF, - 0x6565AFCA,0x7A7A8EF4,0xAEAEE947,0x08081810, - 0xBABAD56F,0x787888F0,0x25256F4A,0x2E2E725C, - 0x1C1C2438,0xA6A6F157,0xB4B4C773,0xC6C65197, - 0xE8E823CB,0xDDDD7CA1,0x74749CE8,0x1F1F213E, - 0x4B4BDD96,0xBDBDDC61,0x8B8B860D,0x8A8A850F, - 0x707090E0,0x3E3E427C,0xB5B5C471,0x6666AACC, - 0x4848D890,0x03030506,0xF6F601F7,0x0E0E121C, - 0x6161A3C2,0x35355F6A,0x5757F9AE,0xB9B9D069, - 0x86869117,0xC1C15899,0x1D1D273A,0x9E9EB927, - 0xE1E138D9,0xF8F813EB,0x9898B32B,0x11113322, - 0x6969BBD2,0xD9D970A9,0x8E8E8907,0x9494A733, - 0x9B9BB62D,0x1E1E223C,0x87879215,0xE9E920C9, - 0xCECE4987,0x5555FFAA,0x28287850,0xDFDF7AA5, - 0x8C8C8F03,0xA1A1F859,0x89898009,0x0D0D171A, - 0xBFBFDA65,0xE6E631D7,0x4242C684,0x6868B8D0, - 0x4141C382,0x9999B029,0x2D2D775A,0x0F0F111E, - 0xB0B0CB7B,0x5454FCA8,0xBBBBD66D,0x16163A2C, - }}; - -#ifdef __cplusplus -} -#endif - -#endif /* HEADER_COMMON_AES_E_H */ diff --git a/build/tools/acsign/aes_e_ecb.c b/build/tools/acsign/aes_e_ecb.c deleted file mode 100644 index 55867bd9..00000000 --- a/build/tools/acsign/aes_e_ecb.c +++ /dev/null @@ -1,48 +0,0 @@ -/* $Id$ */ -/* - * Copyright (C) 1998-2003 RSA Security Inc. All rights reserved. - * - * This work contains proprietary information of RSA Security. - * Distribution is limited to authorized licensees of RSA - * Security. Any unauthorized reproduction, distribution or - * modification of this work is strictly prohibited. - */ - -#ifndef NO_AES - -#include "aes.h" - - -void AES_ecb_encrypt_com(AES_KEY *key, unsigned char *out, - const unsigned char *in, AES_ENC_DEC_FN enc_fn) - { - AES_INT4 data[4],w; - - data[0]=((in[ 0]<<24)|(in[ 1]<<16)|(in[ 2]<<8)|(in[ 3])); - data[1]=((in[ 4]<<24)|(in[ 5]<<16)|(in[ 6]<<8)|(in[ 7])); - data[2]=((in[ 8]<<24)|(in[ 9]<<16)|(in[10]<<8)|(in[11])); - data[3]=((in[12]<<24)|(in[13]<<16)|(in[14]<<8)|(in[15])); - enc_fn(key,&(data[0])); - w=data[0]; - out[ 0]=(w>>24)&0xff; - out[ 1]=(w>>16)&0xff; - out[ 2]=(w>> 8)&0xff; - out[ 3]=(w )&0xff; - w=data[1]; - out[ 4]=(w>>24)&0xff; - out[ 5]=(w>>16)&0xff; - out[ 6]=(w>> 8)&0xff; - out[ 7]=(w )&0xff; - w=data[2]; - out[ 8]=(w>>24)&0xff; - out[ 9]=(w>>16)&0xff; - out[10]=(w>> 8)&0xff; - out[11]=(w )&0xff; - w=data[3]; - out[12]=(w>>24)&0xff; - out[13]=(w>>16)&0xff; - out[14]=(w>> 8)&0xff; - out[15]=(w )&0xff; - } - -#endif /* NO_AES */ diff --git a/build/tools/acsign/aes_sbox.h b/build/tools/acsign/aes_sbox.h deleted file mode 100644 index 6a584f4b..00000000 --- a/build/tools/acsign/aes_sbox.h +++ /dev/null @@ -1,59 +0,0 @@ -/* $Id$ */ -/* - * Copyright (C) 1998-2003 RSA Security Inc. All rights reserved. - * - * This work contains proprietary information of RSA Security. - * Distribution is limited to authorized licensees of RSA - * Security. Any unauthorized reproduction, distribution or - * modification of this work is strictly prohibited. - */ - -#ifndef HEADER_COMMON_AES_SBOX_H -#define HEADER_COMMON_AES_SBOX_H - -#ifdef __cplusplus -extern "C" { -#endif - -extern const unsigned char aes_sbox[256]; - -const unsigned char aes_sbox[256]={ - 0x63,0x7C,0x77,0x7B,0xF2,0x6B,0x6F,0xC5, - 0x30,0x01,0x67,0x2B,0xFE,0xD7,0xAB,0x76, - 0xCA,0x82,0xC9,0x7D,0xFA,0x59,0x47,0xF0, - 0xAD,0xD4,0xA2,0xAF,0x9C,0xA4,0x72,0xC0, - 0xB7,0xFD,0x93,0x26,0x36,0x3F,0xF7,0xCC, - 0x34,0xA5,0xE5,0xF1,0x71,0xD8,0x31,0x15, - 0x04,0xC7,0x23,0xC3,0x18,0x96,0x05,0x9A, - 0x07,0x12,0x80,0xE2,0xEB,0x27,0xB2,0x75, - 0x09,0x83,0x2C,0x1A,0x1B,0x6E,0x5A,0xA0, - 0x52,0x3B,0xD6,0xB3,0x29,0xE3,0x2F,0x84, - 0x53,0xD1,0x00,0xED,0x20,0xFC,0xB1,0x5B, - 0x6A,0xCB,0xBE,0x39,0x4A,0x4C,0x58,0xCF, - 0xD0,0xEF,0xAA,0xFB,0x43,0x4D,0x33,0x85, - 0x45,0xF9,0x02,0x7F,0x50,0x3C,0x9F,0xA8, - 0x51,0xA3,0x40,0x8F,0x92,0x9D,0x38,0xF5, - 0xBC,0xB6,0xDA,0x21,0x10,0xFF,0xF3,0xD2, - 0xCD,0x0C,0x13,0xEC,0x5F,0x97,0x44,0x17, - 0xC4,0xA7,0x7E,0x3D,0x64,0x5D,0x19,0x73, - 0x60,0x81,0x4F,0xDC,0x22,0x2A,0x90,0x88, - 0x46,0xEE,0xB8,0x14,0xDE,0x5E,0x0B,0xDB, - 0xE0,0x32,0x3A,0x0A,0x49,0x06,0x24,0x5C, - 0xC2,0xD3,0xAC,0x62,0x91,0x95,0xE4,0x79, - 0xE7,0xC8,0x37,0x6D,0x8D,0xD5,0x4E,0xA9, - 0x6C,0x56,0xF4,0xEA,0x65,0x7A,0xAE,0x08, - 0xBA,0x78,0x25,0x2E,0x1C,0xA6,0xB4,0xC6, - 0xE8,0xDD,0x74,0x1F,0x4B,0xBD,0x8B,0x8A, - 0x70,0x3E,0xB5,0x66,0x48,0x03,0xF6,0x0E, - 0x61,0x35,0x57,0xB9,0x86,0xC1,0x1D,0x9E, - 0xE1,0xF8,0x98,0x11,0x69,0xD9,0x8E,0x94, - 0x9B,0x1E,0x87,0xE9,0xCE,0x55,0x28,0xDF, - 0x8C,0xA1,0x89,0x0D,0xBF,0xE6,0x42,0x68, - 0x41,0x99,0x2D,0x0F,0xB0,0x54,0xBB,0x16, - }; - -#ifdef __cplusplus -} -#endif - -#endif /* HEADER_COMMON_AES_SBOX_H */ diff --git a/build/tools/acsign/aes_skey.c b/build/tools/acsign/aes_skey.c deleted file mode 100644 index 682766ea..00000000 --- a/build/tools/acsign/aes_skey.c +++ /dev/null @@ -1,143 +0,0 @@ -/* $Id$ */ -/* - * Copyright (C) 1998-2003 RSA Security Inc. All rights reserved. - * - * This work contains proprietary information of RSA Security. - * Distribution is limited to authorized licensees of RSA - * Security. Any unauthorized reproduction, distribution or - * modification of this work is strictly prohibited. - */ - -#ifndef NO_AES - -#include "aes.h" -#include "aes_sbox.h" - -static const unsigned char Rcon[30]={ - 0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80, - 0x1b,0x36,0x6c,0xd8,0xab,0x4d,0x9a,0x2f, - 0x5e,0xbc,0x63,0xc6,0x97,0x35,0x6a,0xd4, - 0xb3,0x7d,0xfa,0xef,0xc5,0x91, - }; - -int AES_set_key(AES_KEY *ctx, const unsigned char *key, int len) - { - int i,ii; - AES_INT4 *W,tmp,tmp2; - const unsigned char *ip; - int words; - - if (len == 16) - { - i=10; - words=4; - } - else if (len == 24) - { - i=12; - words=6; - } - else if (len == 32) - { - i=14; - words=8; - } - else - return(1); - - ctx->rounds=i; - ctx->key_size=words; - W=(unsigned int *)ctx->ks; - for (i=0; irounds+1); - for (i=words; i> 8)&0xff]<<16; - tmp2|=(AES_INT4)aes_sbox[(tmp>>16)&0xff]<<24; - tmp2|=(AES_INT4)aes_sbox[(tmp>>24) ]; - tmp=tmp2^(((unsigned int)*ip)<<24); - ip++; - } - if ((words == 8) && ((i % words) == 4)) - { - tmp2 =(AES_INT4)aes_sbox[(tmp )&0xff] ; - tmp2|=(AES_INT4)aes_sbox[(tmp>> 8)&0xff]<< 8; - tmp2|=(AES_INT4)aes_sbox[(tmp>>16)&0xff]<<16; - tmp2|=(AES_INT4)aes_sbox[(tmp>>24) ]<<24; - tmp=tmp2; - } - W[i]=W[i-words]^tmp; - } - return(0); - } - -#define rot1(x) (((x) << 24) | ((x) >> 8)) -#define rot2(x) (((x) << 16) | ((x) >> 16)) -#define rot3(x) (((x) << 8) | ((x) >> 24)) - -/* This cute trick does 4 'mul by two' at once. Stolen from - * Dr B. R. Gladman but I'm sure the u-(u>>7) is - * a standard graphics trick - * The key to this is that we need to xor with 0x1b if the top bit is set. - * a 1xxx xxxx 0xxx 0xxx First we mask the 7bit, - * b 1000 0000 0000 0000 then we shift right by 7 puting the 7bit in 0bit, - * c 0000 0001 0000 0000 we then subtract (c) from (b) - * d 0111 1111 0000 0000 and now we and with our mask - * e 0001 1011 0000 0000 - */ -#define mt 0x80808080 -#define ml 0x7f7f7f7f -#define mh 0xfefefefe -#define mm 0x1b1b1b1b -#define mul2(x,t) ((t)=((x)&mt), \ - ((((x)+(x))&mh)^(((t)-((t)>>7))&mm))) - -#define mix_col(x,f2,f3) (\ - (f2)=mul2(x,f3), \ - (f3)=(x)^(f2), \ - (rot3(f3) ^ rot2(x) ^ rot1(x)^(f2))) - -#define inv_mix_col(x,f2,f4,f8,f9) (\ - (f2)=mul2(x,f2), \ - (f4)=mul2(f2,f4), \ - (f8)=mul2(f4,f8), \ - (f9)=(x)^(f8), \ - (f8)=((f2)^(f4)^(f8)), \ - (f2)^=(f9), \ - (f4)^=(f9), \ - (f8)^=rot3(f2), \ - (f8)^=rot2(f4), \ - (f8)^rot1(f9)) - -void AES_convert_key(AES_KEY *ctx) - { - int i; - AES_INT4 *k,w,t1,t2,t3,t4; - - k= ctx->ks; - k+=4; - for (i=ctx->rounds*4; i>4; i--) - { - w= *k; - w = inv_mix_col(w,t1,t2,t3,t4); - *k++ =w; - } - } -#endif /* NO_AES */ diff --git a/build/tools/acsign/bn_add.c b/build/tools/acsign/bn_add.c deleted file mode 100644 index 75820c61..00000000 --- a/build/tools/acsign/bn_add.c +++ /dev/null @@ -1,304 +0,0 @@ -/* $Id$ */ -/* - * Copyright (C) 1998-2002 RSA Security Inc. All rights reserved. - * - * This work contains proprietary information of RSA Security. - * Distribution is limited to authorized licensees of RSA - * Security. Any unauthorized reproduction, distribution or - * modification of this work is strictly prohibited. - * - */ - -/** - * @file bn_add.c - * @brief BIGNUM addition and subtraction functions - */ - -#include "bn_lcl.h" - -#if !(defined(NO_SPLIT) && defined(SPLIT_FILE)) - -#ifdef NO_SPLIT -#define SPLIT_BN_ADD -#define SPLIT_BN_UADD -#define SPLIT_BN_USUB -#define SPLIT_BN_SUB -#endif /* NO_SPLIT */ - -#ifdef SPLIT_BN_ADD -/* r can == a or b */ -int BN_add(r, a, b) -BIGNUM *r; -BIGNUM *a; -BIGNUM *b; - { - BIGNUM *tmp; - - bn_check_top(a); - bn_check_top(b); - - /* a + b a+b - * a + -b a-b - * -a + b b-a - * -a + -b -(a+b) - */ - if (a->neg ^ b->neg) - { - /* only one is negative */ - if (a->neg) - { tmp=a; a=b; b=tmp; } - - /* we are now a - b */ - - if (BN_ucmp(a,b) < 0) - { - if (!BN_usub(r,b,a)) return(0); - r->neg=1; - } - else - { - if (!BN_usub(r,a,b)) return(0); - r->neg=0; - } - return(1); - } - - if (a->neg) /* both are neg */ - r->neg=1; - else - r->neg=0; - - if (!BN_uadd(r,a,b)) return(0); - return(1); - } -#endif - -#ifdef SPLIT_BN_UADD -/* unsigned add of b to a, r must be large enough */ -int BN_uadd(r,a,b) -BIGNUM *r; -BIGNUM *a; -BIGNUM *b; - { - register int i; - int max,min; - BN_ULONG *ap,*bp,*rp,carry,t1; - BIGNUM *tmp; - - bn_check_top(a); - bn_check_top(b); - - if (a->top < b->top) - { tmp=a; a=b; b=tmp; } - max=a->top; - min=b->top; - - if (bn_wexpand(r,max+1) == NULL) - return(0); - - r->top=max; - - - ap=a->d; - bp=b->d; - rp=r->d; - carry=0; - - carry=bn_add_words(rp,ap,bp,min); - rp+=min; - ap+=min; - bp+=min; - i=min; - - if (carry) - { - while (i < max) - { - i++; - t1= *(ap++); - if ((*(rp++)=(t1+1)&BN_MASK2) >= t1) - { - carry=0; - break; - } - } - if ((i >= max) && carry) - { - *(rp++)=1; - r->top++; - } - } - if (rp != ap) - { - for (; ib from a - * @param r result of subtraction - * @param a pointer to a BIGNUM - * @param b pointer to a BIGNUM - * @pre a must be larger than b - * @return 1 on success, 0 on failure - * @todo On next IRIX port check the validity of IRIX_CC_BUG. - */ -#ifdef SPLIT_BN_USUB -int BN_usub(r, a, b) -BIGNUM *r; -BIGNUM *a; -BIGNUM *b; - { - int max,min; - register BN_ULONG t1,t2,*ap,*bp,*rp; - int i,carry; -#if defined(IRIX_CC_BUG) && !defined(LINT) - int dummy; -#endif - - bn_check_top(a); - bn_check_top(b); - - /* - * check for pre-condition violation - */ - if (a->top < b->top) - { -#ifndef NO_ERR - BNerr(BN_F_BN_USUB,BN_R_ARG2_LT_ARG3); -#endif - return(0); - } - - max=a->top; - min=b->top; - if (bn_wexpand(r,max) == NULL) return(0); - - ap=a->d; - bp=b->d; - rp=r->d; - - /* - * perform the subtraction and see if we - * have a (final) carry - */ - carry=0; - for (i=0; i t2) break; - } - } - - if (rp != ap) - { -#ifdef BN_LIBRARY_SMALL - Memcpy(rp,ap,sizeof(*rp)*(max-i)); -#else /* BN_LIBRARY_SMALL */ - for (;;) - { - if (i++ >= max) break; - rp[0]=ap[0]; - if (i++ >= max) break; - rp[1]=ap[1]; - if (i++ >= max) break; - rp[2]=ap[2]; - if (i++ >= max) break; - rp[3]=ap[3]; - rp+=4; - ap+=4; - } -#endif /* BN_LIBRARY_SMALL */ - } - - r->top=max; - bn_fix_top(r); - return(1); - } -#endif - -#ifdef SPLIT_BN_SUB -int BN_sub(r, a, b) -BIGNUM *r; -BIGNUM *a; -BIGNUM *b; - { - int max; - int add=0,neg=0; - BIGNUM *tmp; - - bn_check_top(a); - bn_check_top(b); - - /* a - b a-b - * a - -b a+b - * -a - b -(a+b) - * -a - -b b-a - */ - if (a->neg) - { - if (b->neg) - { tmp=a; a=b; b=tmp; } - else - { add=1; neg=1; } - } - else - { - if (b->neg) { add=1; neg=0; } - } - - if (add) - { - if (!BN_uadd(r,a,b)) return(0); - r->neg=neg; - return(1); - } - - /* We are actually doing a - b */ - - max=(a->top > b->top)?a->top:b->top; - if (bn_wexpand(r,max) == NULL) return(0); - if (BN_ucmp(a,b) < 0) - { - if (!BN_usub(r,b,a)) return(0); - r->neg=1; - } - else - { - if (!BN_usub(r,a,b)) return(0); - r->neg=0; - } - return(1); - } -#endif - -#endif diff --git a/build/tools/acsign/bn_asm.c b/build/tools/acsign/bn_asm.c deleted file mode 100644 index 59326c1f..00000000 --- a/build/tools/acsign/bn_asm.c +++ /dev/null @@ -1,509 +0,0 @@ -/* $Id$ */ -/* - * Copyright (C) 1998-2002 RSA Security Inc. All rights reserved. - * - * This work contains proprietary information of RSA Security. - * Distribution is limited to authorized licensees of RSA - * Security. Any unauthorized reproduction, distribution or - * modification of this work is strictly prohibited. - * - */ - -#ifndef OPT_BN_ASM - -#define BN_MUL_ADD_WORDS - -#ifndef BN_MUL_WORDS -#define BN_MUL_WORDS -#endif - -#ifndef BN_SQR_WORDS -#define BN_SQR_WORDS -#endif - -#ifndef BN_ADD_WORDS -#define BN_ADD_WORDS -#endif - -#ifndef BN_SUB_WORDS -#define BN_SUB_WORDS -#endif - -#endif - - -#include "bn_lcl.h" - -#ifdef BN_LLONG - -/* - * bn_mul_add_words - * - * for(i=0;i=0; i--) - fprintf(stderr,BN_HEX_FMT,ap[i]); - fprintf(stderr,"*"); - fprintf(stderr,BN_HEX_FMT,w); - fprintf(stderr,"+"); - for (i=num-1; i>=0; i--) - fprintf(stderr,BN_HEX_FMT,rp[i]); -#endif - - for (;;) - { - mul_add(rp[0],ap[0],w,c1); - if (--num == 0) break; - mul_add(rp[1],ap[1],w,c1); - if (--num == 0) break; - mul_add(rp[2],ap[2],w,c1); - if (--num == 0) break; - mul_add(rp[3],ap[3],w,c1); - if (--num == 0) break; - ap+=4; - rp+=4; - } - -#if defined(BN_ASM_DEBUG) && !defined(NO_FP_API) - fprintf(stderr,"-"); - fprintf(stderr,BN_HEX_FMT,c1); - for (i=nn-1; i>=0; i--) - fprintf(stderr,BN_HEX_FMT,rp[i]); - fprintf(stderr,"\n"); - } -#endif - return(c1); - } -#endif - -#ifdef BN_MUL_WORDS -BN_ULONG bn_mul_words(rp,ap,num,w) -BN_ULONG *rp,*ap; -int num; -BN_ULONG w; - { - BN_ULONG c1=0; - - bn_check_num(num); - if (num <= 0) return(c1); - -#if defined(BN_ASM_DEBUG) && !defined(NO_FP_API) - { - int i,nn=num; - - for (i=num-1; i>=0; i--) - fprintf(stderr,BN_HEX_FMT,ap[i]); - fprintf(stderr,"*"); - fprintf(stderr,BN_HEX_FMT,w); -#endif - - for (;;) - { - mul(rp[0],ap[0],w,c1); - if (--num == 0) break; - mul(rp[1],ap[1],w,c1); - if (--num == 0) break; - mul(rp[2],ap[2],w,c1); - if (--num == 0) break; - mul(rp[3],ap[3],w,c1); - if (--num == 0) break; - ap+=4; - rp+=4; - } - -#if defined(BN_ASM_DEBUG) && !defined(NO_FP_API) - fprintf(stderr,"-"); - fprintf(stderr,BN_HEX_FMT,c1); - for (i=nn-1; i>=0; i--) - fprintf(stderr,BN_HEX_FMT,rp[i]); - fprintf(stderr,"\n"); - } -#endif - return(c1); - } -#endif - -#ifdef BN_SQR_WORDS -void bn_sqr_words(r,a,n) -BN_ULONG *r,*a; -int n; - { - bn_check_num(n); - if (n <= 0) return; - -#if defined(BN_ASM_DEBUG) && !defined(NO_FP_API) - { - int i,nn=n; - - for (i=n-1; i>=0; i--) - { - fprintf(stderr,BN_HEX_FMT,a[i]); - if (i != 0) - fprintf(stderr,"^2*2^%X+",i*2*BN_BITS2); - else - fprintf(stderr,"^2"); - } -#endif - - for (;;) - { - BN_ULLONG t; - - t=(BN_ULLONG)(a[0])*(a[0]); - r[0]=Lw(t); r[1]=Hw(t); - if (--n == 0) break; - - t=(BN_ULLONG)(a[1])*(a[1]); - r[2]=Lw(t); r[3]=Hw(t); - if (--n == 0) break; - - t=(BN_ULLONG)(a[2])*(a[2]); - r[4]=Lw(t); r[5]=Hw(t); - if (--n == 0) break; - - t=(BN_ULLONG)(a[3])*(a[3]); - r[6]=Lw(t); r[7]=Hw(t); - if (--n == 0) break; - - a+=4; - r+=8; - } -#if defined(BN_ASM_DEBUG) && !defined(NO_FP_API) - - fprintf(stderr,"-"); - for (i=nn+nn-1; i>=0; i--) - fprintf(stderr,BN_HEX_FMT,r[i]); - fprintf(stderr,"\n"); - } -#endif - } -#endif - -#else - -#ifdef BN_MUL_ADD_WORDS - -BN_ULONG bn_mul_add_words(rp,ap,num,w) -BN_ULONG *rp,*ap; -int num; -BN_ULONG w; - { - BN_ULONG c=0; - BN_ULONG bl,bh,b_hl; - - bn_check_num(num); - if (num <= 0) return((BN_ULONG)0); - - bl=LBITS(w); - bh=HBITS(w); - b_hl=bh-bl; -/* -{ int i,nnum=num; -BN_ULONG *rrp=rp; -for (i=num-1; i>=0; i--) printf("%02X",rp[i]); -printf("+"); -for (i=num-1; i>=0; i--) printf("%02X",ap[i]); -printf("*%02X - ",w); -*/ - for (;;) - { - mul_add(rp[0],ap[0],bl,bh,b_hl,c); - if (--num == 0) break; - mul_add(rp[1],ap[1],bl,bh,b_hl,c); - if (--num == 0) break; - mul_add(rp[2],ap[2],bl,bh,b_hl,c); - if (--num == 0) break; - mul_add(rp[3],ap[3],bl,bh,b_hl,c); - if (--num == 0) break; - ap+=4; - rp+=4; - } - -/* -printf("%02X",c); -for (i=nnum-1; i>=0; i--) printf("%02X",rrp[i]); -printf("\n"); -} -*/ - return(c); - } - -#endif - -#ifdef BN_MUL_WORDS -BN_ULONG bn_mul_words(rp,ap,num,w) -BN_ULONG *rp,*ap; -int num; -BN_ULONG w; - { - BN_ULONG carry=0; - BN_ULONG bl,bh; - - bn_check_num(num); - if (num <= 0) return((BN_ULONG)0); - - bl=LBITS(w); - bh=HBITS(w); - - for (;;) - { - mul(rp[0],ap[0],bl,bh,carry); - if (--num == 0) break; - mul(rp[1],ap[1],bl,bh,carry); - if (--num == 0) break; - mul(rp[2],ap[2],bl,bh,carry); - if (--num == 0) break; - mul(rp[3],ap[3],bl,bh,carry); - if (--num == 0) break; - ap+=4; - rp+=4; - } - return(carry); - } -#endif - -#ifdef BN_SQR_WORDS -void bn_sqr_words(r,a,n) -BN_ULONG *r,*a; -int n; - { - bn_check_num(n); - if (n <= 0) return; - for (;;) - { - sqr64(r[0],r[1],a[0]); - if (--n == 0) break; - - sqr64(r[2],r[3],a[1]); - if (--n == 0) break; - - sqr64(r[4],r[5],a[2]); - if (--n == 0) break; - - sqr64(r[6],r[7],a[3]); - if (--n == 0) break; - - a+=4; - r+=8; - } - } -#endif - -#endif - -#ifdef BN_ADD_WORDS -#ifdef BN_LLONG -BN_ULONG bn_add_words(r,a,b,n) -BN_ULONG *r,*a,*b; -int n; - { - BN_ULLONG ll=0; - - bn_check_num(n); - if (n <= 0) return((BN_ULONG)0); - -#if defined(BN_ASM_DEBUG) && !defined(NO_FP_API) - { - int i,nn=n; - - for (i=n-1; i>=0; i--) - fprintf(stderr,BN_HEX_FMT,a[i]); - fprintf(stderr,"+"); - for (i=n-1; i>=0; i--) - fprintf(stderr,BN_HEX_FMT,b[i]); -#endif - - for (;;) - { - ll+=(BN_ULLONG)a[0]+b[0]; - r[0]=(BN_ULONG)ll&BN_MASK2; - ll>>=BN_BITS2; - if (--n <= 0) break; - - ll+=(BN_ULLONG)a[1]+b[1]; - r[1]=(BN_ULONG)ll&BN_MASK2; - ll>>=BN_BITS2; - if (--n <= 0) break; - - ll+=(BN_ULLONG)a[2]+b[2]; - r[2]=(BN_ULONG)ll&BN_MASK2; - ll>>=BN_BITS2; - if (--n <= 0) break; - - ll+=(BN_ULLONG)a[3]+b[3]; - r[3]=(BN_ULONG)ll&BN_MASK2; - ll>>=BN_BITS2; - if (--n <= 0) break; - - a+=4; - b+=4; - r+=4; - } -#if defined(BN_ASM_DEBUG) && !defined(NO_FP_API) - fprintf(stderr,"-"); - fprintf(stderr,BN_HEX_FMT,(BN_ULONG)ll); - for (i=nn-1; i>=0; i--) - fprintf(stderr,BN_HEX_FMT,r[i]); - fprintf(stderr,"\n"); - } -#endif - return((BN_ULONG)ll); - } -#else -BN_ULONG bn_add_words(r,a,b,n) -BN_ULONG *r,*a,*b; -int n; - { - BN_ULONG c,l,t; - - bn_check_num(n); - if (n <= 0) return((BN_ULONG)0); - - c=0; - for (;;) - { - t=a[0]; - t=(t+c)&BN_MASK2; - c=(t < c); - l=(t+b[0])&BN_MASK2; - c+=(l < t); - r[0]=l; - if (--n <= 0) break; - - t=a[1]; - t=(t+c)&BN_MASK2; - c=(t < c); - l=(t+b[1])&BN_MASK2; - c+=(l < t); - r[1]=l; - if (--n <= 0) break; - - t=a[2]; - t=(t+c)&BN_MASK2; - c=(t < c); - l=(t+b[2])&BN_MASK2; - c+=(l < t); - r[2]=l; - if (--n <= 0) break; - - t=a[3]; - t=(t+c)&BN_MASK2; - c=(t < c); - l=(t+b[3])&BN_MASK2; - c+=(l < t); - r[3]=l; - if (--n <= 0) break; - - a+=4; - b+=4; - r+=4; - } - - return((BN_ULONG)c); - } -#endif -#endif - -#ifdef BN_SUB_WORDS -BN_ULONG bn_sub_words(r,a,b,n) -BN_ULONG *r,*a,*b; -int n; - { - BN_ULONG c,t1,t2; - - bn_check_num(n); - if (n <= 0) return((BN_ULONG)0); - -#if defined(BN_ASM_DEBUG) && !defined(NO_FP_API) - { - int i,nn=n; - - for (i=n-1; i>=0; i--) - fprintf(stderr,BN_HEX_FMT,a[i]); - fprintf(stderr,"-"); - for (i=n-1; i>=0; i--) - fprintf(stderr,BN_HEX_FMT,b[i]); -#endif - - c=0; - for (;;) - { - t1=a[0]; t2=b[0]; - r[0]=(t1-t2-c)&BN_MASK2; - if (t1 != t2) c=(t1 < t2); - if (--n <= 0) break; - - t1=a[1]; t2=b[1]; - r[1]=(t1-t2-c)&BN_MASK2; - if (t1 != t2) c=(t1 < t2); - if (--n <= 0) break; - - t1=a[2]; t2=b[2]; - r[2]=(t1-t2-c)&BN_MASK2; - if (t1 != t2) c=(t1 < t2); - if (--n <= 0) break; - - t1=a[3]; t2=b[3]; - r[3]=(t1-t2-c)&BN_MASK2; - if (t1 != t2) c=(t1 < t2); - if (--n <= 0) break; - - a+=4; - b+=4; - r+=4; - } - -#if defined(BN_ASM_DEBUG) && !defined(NO_FP_API) - fprintf(stderr,"- "); - if (c) fprintf(stderr,"-"); - for (i=nn-1; i>=0; i--) - fprintf(stderr,BN_HEX_FMT,r[i]); - fprintf(stderr,"\n"); - } -#endif - return(c); - } -#endif - diff --git a/build/tools/acsign/bn_comba.c b/build/tools/acsign/bn_comba.c deleted file mode 100644 index 61dbc937..00000000 --- a/build/tools/acsign/bn_comba.c +++ /dev/null @@ -1,434 +0,0 @@ -/* $Id$ */ -/* - * Copyright (C) 1998-2002 RSA Security Inc. All rights reserved. - * - * This work contains proprietary information of RSA Security. - * Distribution is limited to authorized licensees of RSA - * Security. Any unauthorized reproduction, distribution or - * modification of this work is strictly prohibited. - * - */ - -#include "bn_lcl.h" - -#if !(defined(NO_SPLIT) && defined(SPLIT_FILE)) - -#ifdef NO_SPLIT -#define SPLIT_BN_MUL_COMBA8 -#define SPLIT_BN_MUL_COMBA4 -#define SPLIT_BN_SQR_COMBA8 -#define SPLIT_BN_SQR_COMBA4 -#endif /* NO_SPLIT */ - -#ifndef OPT_BN_ASM -/* #if 1 */ - -#ifdef BN_LLONG -#define mul_add_c(a,b,c0,c1,c2) \ - t=(BN_ULLONG)a*b; \ - t1=(BN_ULONG)Lw(t); \ - t2=(BN_ULONG)Hw(t); \ - c0=(c0+t1)&BN_MASK2; if ((c0) < t1) t2++; \ - c1=(c1+t2)&BN_MASK2; if ((c1) < t2) c2++; - -#define mul_add_c2(a,b,c0,c1,c2) \ - t=(BN_ULLONG)a*b; \ - tt=(t+t)&BN_MASK; \ - if (tt < t) c2++; \ - t1=(BN_ULONG)Lw(tt); \ - t2=(BN_ULONG)Hw(tt); \ - c0=(c0+t1)&BN_MASK2; \ - if ((c0 < t1) && (((++t2)&BN_MASK2) == 0)) c2++; \ - c1=(c1+t2)&BN_MASK2; if ((c1) < t2) c2++; - -#define sqr_add_c(a,i,c0,c1,c2) \ - t=(BN_ULLONG)a[i]*a[i]; \ - t1=(BN_ULONG)Lw(t); \ - t2=(BN_ULONG)Hw(t); \ - c0=(c0+t1)&BN_MASK2; if ((c0) < t1) t2++; \ - c1=(c1+t2)&BN_MASK2; if ((c1) < t2) c2++; - -#define sqr_add_c2(a,i,j,c0,c1,c2) \ - mul_add_c2((a)[i],(a)[j],c0,c1,c2) -#else -#define mul_add_c(a,b,c0,c1,c2) \ - t1=LBITS(a); t2=HBITS(a); \ - bl=LBITS(b); bh=HBITS(b); \ - mul64(t1,t2,bl,bh); \ - c0=(c0+t1)&BN_MASK2; if ((c0) < t1) t2++; \ - c1=(c1+t2)&BN_MASK2; if ((c1) < t2) c2++; - -#define mul_add_c2(a,b,c0,c1,c2) \ - t1=LBITS(a); t2=HBITS(a); \ - bl=LBITS(b); bh=HBITS(b); \ - mul64(t1,t2,bl,bh); \ - if (t2 & BN_TBIT) c2++; \ - t2=(t2+t2)&BN_MASK2; \ - if (t1 & BN_TBIT) t2++; \ - t1=(t1+t1)&BN_MASK2; \ - c0=(c0+t1)&BN_MASK2; \ - if ((c0 < t1) && (((++t2)&BN_MASK2) == 0)) c2++; \ - c1=(c1+t2)&BN_MASK2; if ((c1) < t2) c2++; - -#define sqr_add_c(a,i,c0,c1,c2) \ - sqr64(t1,t2,(a)[i]); \ - c0=(c0+t1)&BN_MASK2; if ((c0) < t1) t2++; \ - c1=(c1+t2)&BN_MASK2; if ((c1) < t2) c2++; - -#define sqr_add_c2(a,i,j,c0,c1,c2) \ - mul_add_c2((a)[i],(a)[j],c0,c1,c2) -#endif - -#if defined(BN_MUL_COMBA) - -#ifdef SPLIT_BN_MUL_COMBA8 -#undef bn_mul_comba8 -void bn_mul_comba8(r,a,b) -BN_ULONG *r,*a,*b; - { -#ifdef BN_LLONG - BN_ULLONG t; -#else - BN_ULONG bl,bh; -#endif - BN_ULONG t1,t2; - BN_ULONG c1,c2,c3; - - c1=0; - c2=0; - c3=0; - mul_add_c(a[0],b[0],c1,c2,c3); - r[0]=c1; - c1=0; - mul_add_c(a[0],b[1],c2,c3,c1); - mul_add_c(a[1],b[0],c2,c3,c1); - r[1]=c2; - c2=0; - mul_add_c(a[2],b[0],c3,c1,c2); - mul_add_c(a[1],b[1],c3,c1,c2); - mul_add_c(a[0],b[2],c3,c1,c2); - r[2]=c3; - c3=0; - mul_add_c(a[0],b[3],c1,c2,c3); - mul_add_c(a[1],b[2],c1,c2,c3); - mul_add_c(a[2],b[1],c1,c2,c3); - mul_add_c(a[3],b[0],c1,c2,c3); - r[3]=c1; - c1=0; - mul_add_c(a[4],b[0],c2,c3,c1); - mul_add_c(a[3],b[1],c2,c3,c1); - mul_add_c(a[2],b[2],c2,c3,c1); - mul_add_c(a[1],b[3],c2,c3,c1); - mul_add_c(a[0],b[4],c2,c3,c1); - r[4]=c2; - c2=0; - mul_add_c(a[0],b[5],c3,c1,c2); - mul_add_c(a[1],b[4],c3,c1,c2); - mul_add_c(a[2],b[3],c3,c1,c2); - mul_add_c(a[3],b[2],c3,c1,c2); - mul_add_c(a[4],b[1],c3,c1,c2); - mul_add_c(a[5],b[0],c3,c1,c2); - r[5]=c3; - c3=0; - mul_add_c(a[6],b[0],c1,c2,c3); - mul_add_c(a[5],b[1],c1,c2,c3); - mul_add_c(a[4],b[2],c1,c2,c3); - mul_add_c(a[3],b[3],c1,c2,c3); - mul_add_c(a[2],b[4],c1,c2,c3); - mul_add_c(a[1],b[5],c1,c2,c3); - mul_add_c(a[0],b[6],c1,c2,c3); - r[6]=c1; - c1=0; - mul_add_c(a[0],b[7],c2,c3,c1); - mul_add_c(a[1],b[6],c2,c3,c1); - mul_add_c(a[2],b[5],c2,c3,c1); - mul_add_c(a[3],b[4],c2,c3,c1); - mul_add_c(a[4],b[3],c2,c3,c1); - mul_add_c(a[5],b[2],c2,c3,c1); - mul_add_c(a[6],b[1],c2,c3,c1); - mul_add_c(a[7],b[0],c2,c3,c1); - r[7]=c2; - c2=0; - mul_add_c(a[7],b[1],c3,c1,c2); - mul_add_c(a[6],b[2],c3,c1,c2); - mul_add_c(a[5],b[3],c3,c1,c2); - mul_add_c(a[4],b[4],c3,c1,c2); - mul_add_c(a[3],b[5],c3,c1,c2); - mul_add_c(a[2],b[6],c3,c1,c2); - mul_add_c(a[1],b[7],c3,c1,c2); - r[8]=c3; - c3=0; - mul_add_c(a[2],b[7],c1,c2,c3); - mul_add_c(a[3],b[6],c1,c2,c3); - mul_add_c(a[4],b[5],c1,c2,c3); - mul_add_c(a[5],b[4],c1,c2,c3); - mul_add_c(a[6],b[3],c1,c2,c3); - mul_add_c(a[7],b[2],c1,c2,c3); - r[9]=c1; - c1=0; - mul_add_c(a[7],b[3],c2,c3,c1); - mul_add_c(a[6],b[4],c2,c3,c1); - mul_add_c(a[5],b[5],c2,c3,c1); - mul_add_c(a[4],b[6],c2,c3,c1); - mul_add_c(a[3],b[7],c2,c3,c1); - r[10]=c2; - c2=0; - mul_add_c(a[4],b[7],c3,c1,c2); - mul_add_c(a[5],b[6],c3,c1,c2); - mul_add_c(a[6],b[5],c3,c1,c2); - mul_add_c(a[7],b[4],c3,c1,c2); - r[11]=c3; - c3=0; - mul_add_c(a[7],b[5],c1,c2,c3); - mul_add_c(a[6],b[6],c1,c2,c3); - mul_add_c(a[5],b[7],c1,c2,c3); - r[12]=c1; - c1=0; - mul_add_c(a[6],b[7],c2,c3,c1); - mul_add_c(a[7],b[6],c2,c3,c1); - r[13]=c2; - c2=0; - mul_add_c(a[7],b[7],c3,c1,c2); - r[14]=c3; - r[15]=c1; - } -#endif - -#ifdef SPLIT_BN_MUL_COMBA4 -#undef bn_mul_comba4 -void bn_mul_comba4(r,a,b) -BN_ULONG *r,*a,*b; - { -#ifdef BN_LLONG - BN_ULLONG t; -#else - BN_ULONG bl,bh; -#endif - BN_ULONG t1,t2; - BN_ULONG c1,c2,c3; - - c1=0; - c2=0; - c3=0; - mul_add_c(a[0],b[0],c1,c2,c3); - r[0]=c1; - c1=0; - mul_add_c(a[0],b[1],c2,c3,c1); - mul_add_c(a[1],b[0],c2,c3,c1); - r[1]=c2; - c2=0; - mul_add_c(a[2],b[0],c3,c1,c2); - mul_add_c(a[1],b[1],c3,c1,c2); - mul_add_c(a[0],b[2],c3,c1,c2); - r[2]=c3; - c3=0; - mul_add_c(a[0],b[3],c1,c2,c3); - mul_add_c(a[1],b[2],c1,c2,c3); - mul_add_c(a[2],b[1],c1,c2,c3); - mul_add_c(a[3],b[0],c1,c2,c3); - r[3]=c1; - c1=0; - mul_add_c(a[3],b[1],c2,c3,c1); - mul_add_c(a[2],b[2],c2,c3,c1); - mul_add_c(a[1],b[3],c2,c3,c1); - r[4]=c2; - c2=0; - mul_add_c(a[2],b[3],c3,c1,c2); - mul_add_c(a[3],b[2],c3,c1,c2); - r[5]=c3; - c3=0; - mul_add_c(a[3],b[3],c1,c2,c3); - r[6]=c1; - r[7]=c2; - } -#endif - -#else - -#ifdef SPLIT_BN_MUL_COMBA4 -#undef bn_mul_comba4 -void bn_mul_comba4(r,a,b) -BN_ULONG *r,*a,*b; - { - r[4]=bn_mul_words( &(r[0]),a,4,b[0]); - r[5]=bn_mul_add_words(&(r[1]),a,4,b[1]); - r[6]=bn_mul_add_words(&(r[2]),a,4,b[2]); - r[7]=bn_mul_add_words(&(r[3]),a,4,b[3]); - } -#endif - -#ifdef SPLIT_BN_MUL_COMBA8 -#undef bn_mul_comba8 -void bn_mul_comba8(r,a,b) -BN_ULONG *r,*a,*b; - { - r[ 8]=bn_mul_words( &(r[0]),a,8,b[0]); - r[ 9]=bn_mul_add_words(&(r[1]),a,8,b[1]); - r[10]=bn_mul_add_words(&(r[2]),a,8,b[2]); - r[11]=bn_mul_add_words(&(r[3]),a,8,b[3]); - r[12]=bn_mul_add_words(&(r[4]),a,8,b[4]); - r[13]=bn_mul_add_words(&(r[5]),a,8,b[5]); - r[14]=bn_mul_add_words(&(r[6]),a,8,b[6]); - r[15]=bn_mul_add_words(&(r[7]),a,8,b[7]); - } -#endif - -#endif /* BN_MUL_COMBA */ - -#ifdef BN_SQR_COMBA - -#ifdef SPLIT_BN_SQR_COMBA8 -#undef bn_sqr_comba8 -void bn_sqr_comba8(r,a) -BN_ULONG *r,*a; - { -#ifdef BN_LLONG - BN_ULLONG t,tt; -#else - BN_ULONG bl,bh; -#endif - BN_ULONG t1,t2; - BN_ULONG c1,c2,c3; - - c1=0; - c2=0; - c3=0; - sqr_add_c(a,0,c1,c2,c3); - r[0]=c1; - c1=0; - sqr_add_c2(a,1,0,c2,c3,c1); - r[1]=c2; - c2=0; - sqr_add_c(a,1,c3,c1,c2); - sqr_add_c2(a,2,0,c3,c1,c2); - r[2]=c3; - c3=0; - sqr_add_c2(a,3,0,c1,c2,c3); - sqr_add_c2(a,2,1,c1,c2,c3); - r[3]=c1; - c1=0; - sqr_add_c(a,2,c2,c3,c1); - sqr_add_c2(a,3,1,c2,c3,c1); - sqr_add_c2(a,4,0,c2,c3,c1); - r[4]=c2; - c2=0; - sqr_add_c2(a,5,0,c3,c1,c2); - sqr_add_c2(a,4,1,c3,c1,c2); - sqr_add_c2(a,3,2,c3,c1,c2); - r[5]=c3; - c3=0; - sqr_add_c(a,3,c1,c2,c3); - sqr_add_c2(a,4,2,c1,c2,c3); - sqr_add_c2(a,5,1,c1,c2,c3); - sqr_add_c2(a,6,0,c1,c2,c3); - r[6]=c1; - c1=0; - sqr_add_c2(a,7,0,c2,c3,c1); - sqr_add_c2(a,6,1,c2,c3,c1); - sqr_add_c2(a,5,2,c2,c3,c1); - sqr_add_c2(a,4,3,c2,c3,c1); - r[7]=c2; - c2=0; - sqr_add_c(a,4,c3,c1,c2); - sqr_add_c2(a,5,3,c3,c1,c2); - sqr_add_c2(a,6,2,c3,c1,c2); - sqr_add_c2(a,7,1,c3,c1,c2); - r[8]=c3; - c3=0; - sqr_add_c2(a,7,2,c1,c2,c3); - sqr_add_c2(a,6,3,c1,c2,c3); - sqr_add_c2(a,5,4,c1,c2,c3); - r[9]=c1; - c1=0; - sqr_add_c(a,5,c2,c3,c1); - sqr_add_c2(a,6,4,c2,c3,c1); - sqr_add_c2(a,7,3,c2,c3,c1); - r[10]=c2; - c2=0; - sqr_add_c2(a,7,4,c3,c1,c2); - sqr_add_c2(a,6,5,c3,c1,c2); - r[11]=c3; - c3=0; - sqr_add_c(a,6,c1,c2,c3); - sqr_add_c2(a,7,5,c1,c2,c3); - r[12]=c1; - c1=0; - sqr_add_c2(a,7,6,c2,c3,c1); - r[13]=c2; - c2=0; - sqr_add_c(a,7,c3,c1,c2); - r[14]=c3; - r[15]=c1; - } -#endif - -#ifdef SPLIT_BN_SQR_COMBA4 -#undef bn_sqr_comba4 -void bn_sqr_comba4(r,a) -BN_ULONG *r,*a; - { -#ifdef BN_LLONG - BN_ULLONG t,tt; -#else - BN_ULONG bl,bh; -#endif - BN_ULONG t1,t2; - BN_ULONG c1,c2,c3; - - c1=0; - c2=0; - c3=0; - sqr_add_c(a,0,c1,c2,c3); - r[0]=c1; - c1=0; - sqr_add_c2(a,1,0,c2,c3,c1); - r[1]=c2; - c2=0; - sqr_add_c(a,1,c3,c1,c2); - sqr_add_c2(a,2,0,c3,c1,c2); - r[2]=c3; - c3=0; - sqr_add_c2(a,3,0,c1,c2,c3); - sqr_add_c2(a,2,1,c1,c2,c3); - r[3]=c1; - c1=0; - sqr_add_c(a,2,c2,c3,c1); - sqr_add_c2(a,3,1,c2,c3,c1); - r[4]=c2; - c2=0; - sqr_add_c2(a,3,2,c3,c1,c2); - r[5]=c3; - c3=0; - sqr_add_c(a,3,c1,c2,c3); - r[6]=c1; - r[7]=c2; - } -#endif -#else - -#ifdef SPLIT_BN_SQR_COMBA4 -/* hmm... is it faster just to do a multiply? */ -#undef bn_sqr_comba4 -void bn_sqr_comba4(r,a) -BN_ULONG *r,*a; - { - BN_ULONG t[8]; - bn_sqr_normal(r,a,4,t); - } -#endif - -#ifdef SPLIT_BN_SQR_COMBA8 -#undef bn_sqr_comba8 -void bn_sqr_comba8(r,a) -BN_ULONG *r,*a; - { - BN_ULONG t[16]; - bn_sqr_normal(r,a,8,t); - } -#endif - -#endif - -#endif /* OPT_BN_ASM */ - -#endif diff --git a/build/tools/acsign/bn_div.c b/build/tools/acsign/bn_div.c deleted file mode 100644 index d2c12575..00000000 --- a/build/tools/acsign/bn_div.c +++ /dev/null @@ -1,365 +0,0 @@ -/* $Id$ */ -/* - * Copyright (C) 1998-2002 RSA Security Inc. All rights reserved. - * - * This work contains proprietary information of RSA Security. - * Distribution is limited to authorized licensees of RSA - * Security. Any unauthorized reproduction, distribution or - * modification of this work is strictly prohibited. - * - */ -/** - * @file bn_div.c - * @brief Division and modulus functions - */ -#include "bn_lcl.h" - -#if !(defined(NO_SPLIT) && defined(SPLIT_FILE)) - -#ifdef NO_SPLIT -#define SPLIT_BN_DIV -#define SPLIT_BN_MOD -#endif /* NO_SPLIT */ - -#ifdef SPLIT_BN_DIV -/* The old slow way */ -#ifdef OLD_BN_DIVISION -int BN_div(dv, rem, m, d,ctx) -BIGNUM *dv; -BIGNUM *rem; -BIGNUM *m; -BIGNUM *d; -BN_CTX *ctx; - { - int i,nm,nd; - BIGNUM *D; - - bn_check_top(m); - bn_check_top(d); - if (BN_is_zero(d)) - { -#ifndef NO_ERR - BNerr(BN_F_BN_DIV,BN_R_DIV_BY_ZERO); -#endif - return(0); - } - - if (BN_ucmp(m,d) < 0) - { - if (rem != NULL) - { if (BN_copy(rem,m) == NULL) return(0); } - if (dv != NULL) BN_zero(dv); - return(1); - } - - D= &(ctx->bn[ctx->tos]); - if (dv == NULL) dv= &(ctx->bn[ctx->tos+1]); - if (rem == NULL) rem= &(ctx->bn[ctx->tos+2]); - - nd=BN_num_bits(d); - nm=BN_num_bits(m); - if (BN_copy(D,d) == NULL) return(0); - if (BN_copy(rem,m) == NULL) return(0); - - /* The next 2 are needed so we can do a dv->d[0]|=1 later - * since BN_lshift1 will only work once there is a value - */ - BN_zero(dv); - bn_wexpand(dv,1); - dv->top=1; - - if (!BN_lshift(D,D,nm-nd)) return(0); - for (i=nm-nd; i>=0; i--) - { - if (!BN_lshift1(dv,dv)) return(0); - if (BN_ucmp(rem,D) >= 0) - { - dv->d[0]|=1; - if (!BN_usub(rem,rem,D)) return(0); - } -/* CAN IMPROVE (and have now :=) */ - if (!BN_rshift1(D,D)) return(0); - } - rem->neg=BN_is_zero(rem)?0:m->neg; - dv->neg=m->neg^d->neg; - return(1); - } - -#else -/** - * Performs Big number division - * - * @param dv [In] division - * @param rm [Out] remainder - * @param num [In] number - * @param divisor [In] divisor - * @param ctx [In] Temporary data storage - * - * @todo add more comments to this function - */ -int BN_div(BIGNUM *dv, BIGNUM *rm, BIGNUM *num, BIGNUM *divisor, BN_CTX *ctx) - { - int norm_shift,i,j,loop; - BIGNUM *tmp,wnum,*snum,*sdiv,*res; - BN_ULONG *resp,*wnump; - BN_ULONG d0,d1; - int num_n,div_n; - - bn_check_top(num); - bn_check_top(divisor); - - if (BN_is_zero(divisor)) - { -#ifndef NO_ERR - BNerr(BN_F_BN_DIV,BN_R_DIV_BY_ZERO); -#endif - return(0); - } - - if (BN_ucmp(num,divisor) < 0) - { - if (rm != NULL) - { if (BN_copy(rm,num) == NULL) return(0); } - if (dv != NULL) (void)BN_zero(dv); - return(1); - } - - tmp= &(ctx->bn[ctx->tos]); - tmp->neg=0; - snum= &(ctx->bn[ctx->tos+1]); - sdiv= &(ctx->bn[ctx->tos+2]); - if (dv == NULL) - res= &(ctx->bn[ctx->tos+3]); - else res=dv; - - /* First we normalise the numbers */ - norm_shift=BN_BITS2-((BN_num_bits(divisor))%BN_BITS2); - if (!BN_lshift(sdiv,divisor,norm_shift)) return(0); - sdiv->neg=0; - norm_shift+=BN_BITS2; - if (!BN_lshift(snum,num,norm_shift)) return(0); - snum->neg=0; - div_n=sdiv->top; - num_n=snum->top; - loop=num_n-div_n; - - /* Lets setup a 'window' into snum - * This is the part that corresponds to the current - * 'area' being divided */ - BN_init(&wnum); - wnum.d= &(snum->d[loop]); - wnum.top= div_n; - wnum.max= snum->max+1; /* a bit of a lie */ - - /* Get the top 2 words of sdiv */ - /* i=sdiv->top; */ - d0=sdiv->d[div_n-1]; - d1=(div_n == 1)?0:sdiv->d[div_n-2]; - - /* pointer to the 'top' of snum */ - wnump= &(snum->d[num_n-1]); - - /* Setup to 'res' */ - if (!bn_wexpand(res,(loop+1))) goto err; - res->neg= (num->neg^divisor->neg); - res->top=loop; - resp= &(res->d[loop-1]); - - /* space for temp */ - if (!bn_wexpand(tmp,(div_n+1))) goto err; - - if (BN_ucmp(&wnum,sdiv) >= 0) - { - if (!BN_usub(&wnum,&wnum,sdiv)) goto err; - *resp=1; - res->d[res->top-1]=1; - } - else - res->top--; - resp--; - - for (i=0; i>BN_BITS2) || - (t2 <= ((BN_ULLONG)(rem< t1l) t3h++; - t3h=(t1h-t3h)&BN_MASK2; - - /*if ((t3>>BN_BITS2) || - (t2 <= ((t3<d,sdiv->d,div_n,q); - tmp->d[div_n]=l0; - for (j=div_n+1; j>0; j--) - if (tmp->d[j-1]) break; - tmp->top=j; - - j=wnum.top; -#ifdef BN_DEBUG - /* Sometimes this is 0 now (wnum.top is not). - * We need to look at this some time, I am quite - * sure it has no affect. - */ - bn_fix_top(&wnum); -#endif - (void)BN_sub(&wnum,&wnum,tmp); - - snum->top=snum->top+wnum.top-j; - - if (wnum.neg) - { - q--; - j=wnum.top; - (void)BN_add(&wnum,&wnum,sdiv); - snum->top+=wnum.top-j; - } - *(resp--)=q; - wnump--; - } - bn_fix_top(snum); - if (rm != NULL) - { - i=num->neg; /* just in case num == rm */ - if (BN_rshift(rm,snum,norm_shift) == 0) - return(0); - rm->neg=i; - } - return(1); -err: - return(0); - } -#endif -#endif - -#ifdef SPLIT_BN_MOD -/** - * Calculate the remainder where rem = m mod d - * - * @param rem [Out] Modulus result - * @param m [In] Base value - * @param d [In] Divisor - * @param ctx [In] BN_CTX for data space - * - * @pre variables are initialised and valid - * @post rem contained modulus - * - * @retval 1 success - * @retval 0 failure - * - * @note when BN_LIBRARY_SMALL define uses following algorithm - * otherwise calls through to BN_div - * - * @note m < d rem = m - * (length m = length of d) and (m > d) , rem = m - d - * alg otherwise - * let rem = m - * loop while rem > d - * let dv = shift left d, n bits to = length rem - * if dv > rem - * let dv = shift left d, n - 1 bits ( = length rem - 1) - * end if - * let rem = rem - dv; - * end loop - * - * @relates BN_div - */ -int BN_mod(BIGNUM *rem, BIGNUM *m, BIGNUM *d, BN_CTX *ctx) -{ -#ifdef BN_LIBRARY_SMALL - int nm,nd; - BIGNUM *dv, *dv2; - - /* if m < d , mod = m */ - if (BN_ucmp(m,d) < 0) - return((BN_copy(rem,m) == NULL)?0:1); - - dv= &(ctx->bn[ctx->tos]); - dv2 = &(ctx->bn[ctx->tos+1]); - - nm=BN_num_bits(m); - nd=BN_num_bits(d); - - /* if bits m = bits d and m >= d (from above) - * rem = m - d - */ - if(nm == nd) - { - BN_usub(rem, m, d); - goto end; - } - - if (BN_copy(rem, m) == NULL) - { - return 0; - } - - /* while the rem > d */ - while(BN_ucmp(rem,d) > 0) - { - nm=BN_num_bits(rem); - if(!BN_lshift(dv2,d,nm-nd)) - { - return(0); - } - - if(BN_ucmp(dv2, rem) >0) - { - if(!BN_lshift(dv2,d,nm-nd-1)) - { - return(0); - } - } - - BN_usub(rem,rem,dv2); - } -end: - return(1); -#else - return(BN_div(NULL,rem,m,d,ctx)); -#endif -} -#endif - -#endif diff --git a/build/tools/acsign/bn_ex_str.c b/build/tools/acsign/bn_ex_str.c deleted file mode 100644 index dc40f5c0..00000000 --- a/build/tools/acsign/bn_ex_str.c +++ /dev/null @@ -1,437 +0,0 @@ -/* $Id$ */ -/* - * Copyright (C) 1998-2002 RSA Security Inc. All rights reserved. - * - * This work contains proprietary information of RSA Security. - * Distribution is limited to authorized licensees of RSA - * Security. Any unauthorized reproduction, distribution or - * modification of this work is strictly prohibited. - * - */ -#include "bn_lcl.h" - -const static unsigned char p2 []={0,8,1,1,1,1,1,0,0,0}; -const static unsigned char p4 []={0,8,1,1,1,4,1,0,0,0}; -const static unsigned char p16[]={0,8,1,1,1,16,1,0,0,0}; - -/* The following defines allow for redefinition of the window size - * of the exponent string at compile time, this affects the size - * of temporary data required in montgomery operations. - * Larger window sizes have more memory and are slightly faster - */ -#ifndef MAX_WIN_SIZE -#define MAX_WIN_SIZE 5 -#endif - -#if (MAX_WIN_SIZE == 6) -#define MAX_NUM_SIZE 16 -#endif - -#if (MAX_WIN_SIZE == 5) -#define MAX_NUM_SIZE 16 -#endif - -#if (MAX_WIN_SIZE == 4) -#define MAX_NUM_SIZE 8 -#endif - -#if (MAX_WIN_SIZE == 3) -#define MAX_NUM_SIZE 4 -#endif - -#ifndef MAX_NUM_SIZE -#define MAX_NUM_SIZE 16 -#endif - -/* This table is used to calculate how far to shift a window to find - * the next 1 bit within the window, for a given window size - * Comment next to each value represents window size, value of the window - * and the number of shifts to find the next 1 bit. - * where the value of the window is 0, the shift is the size of the window - * and thus may not necessary yield a 1 bit, but refreshes the window - */ -const static unsigned char shift[64]= - {6, /* window 6, bits 000000, shift 6 */ - 0, /* 6, bits 000001, shift 0 */ - 1, /* 6, bits 000010, shift 1 */ - 0, /* 6, bits 000011, shift 0 */ - 2, /* 6, bits 000100, shift 2 */ - 0, /* 6, bits 000101, shift 0 */ - 1, /* 6, bits 000110, shift 1 */ - 0, /* 6, bits 000111, shift 0 */ - 3, /* 6, bits 001000, shift 3 */ - 0, /* 6, bits 001001, shift 0 */ - 1, /* 6, bits 001010, shift 1 */ - 0, /* 6, bits 001011, shift 0 */ - 2, /* 6, bits 001100, shift 2 */ - 0, /* 6, bits 001101, shift 0 */ - 1, /* 6, bits 001110, shift 1 */ - 0, /* 6, bits 001111, shift 0 */ - 4, /* 6, bits 010000, shift 4 */ - 0, /* 6, bits 010001, shift 0 */ - 1, /* 6, bits 010010, shift 1 */ - 0, /* 6, bits 010011, shift 0 */ - 2, /* 6, bits 010100, shift 2 */ - 0, /* 6, bits 010101, shift 0 */ - 1, /* 6, bits 010110, shift 1 */ - 0, /* 6, bits 010111, shift 0 */ - 3, /* 6, bits 011000, shift 3 */ - 0, /* 6, bits 011001, shift 0 */ - 1, /* 6, bits 011010, shift 1 */ - 0, /* 6, bits 011011, shift 0 */ - 2, /* 6, bits 011100, shift 2 */ - 0, /* 6, bits 011101, shift 0 */ - 1, /* 6, bits 011110, shift 1 */ - 0, /* 6, bits 011111, shift 0 */ - 5, /* 6, bits 100000, shift 5 */ - /* also window 5, bits 00000, shift 5 */ - 0, /* 5 ,bits 00001, shift 0 */ - 1, /* 5 ,bits 00010, shift 1 */ - 0, /* 5 ,bits 00011, shift 0 */ - 2, /* 5 ,bits 00100, shift 2 */ - 0, /* 5 ,bits 00101, shift 0 */ - 1, /* 5 ,bits 00110, shift 1 */ - 0, /* 5 ,bits 00111, shift 0 */ - 3, /* 5 ,bits 01000, shift 3 */ - 0, /* 5 ,bits 01001, shift 0 */ - 1, /* 5 ,bits 01010, shift 1 */ - 0, /* 5 ,bits 01011, shift 0 */ - 2, /* 5 ,bits 01100, shift 2 */ - 0, /* 5 ,bits 01101, shift 0 */ - 1, /* 5 ,bits 01110, shift 1 */ - 0, /* 5 ,bits 01111, shift 0 */ - 4, /* 5 ,bits 10000, shift 1 */ - /* also window 4, bits 0000, shift 4 */ - 0, /* 4 ,bits 0001, shift 0 */ - 1, /* 4 ,bits 0010, shift 1 */ - 0, /* 4 ,bits 0011, shift 0 */ - 2, /* 4 ,bits 0100, shift 2 */ - 0, /* 4 ,bits 0101, shift 0 */ - 1, /* 4 ,bits 0110, shift 1 */ - 0, /* 4 ,bits 0111, shift 0 */ - 3, /* 4 ,bits 1000, shift 3 */ - /* also window 3, bits 000, shift 3 */ - 0, /* 3 ,bits 001, shift 0 */ - 1, /* 3 ,bits 010, shift 1 */ - 0, /* 3 ,bits 011, shift 0 */ - 2, /* 3 ,bits 100, shift 2 */ - 0, /* 3 ,bits 101, shift 0 */ - 1, /* 3 ,bits 110, shift 1 */ - 0 /* 3 ,bits 111, shift 0 */ - }; - -/* This table defines the starting point in the shift table for - * a particular window size - */ -const static unsigned char *shift_val[7]= - { - &(shift[63]), /* window 0 - unused */ - &(shift[62]), /* window 1 */ - &(shift[60]), /* window 2 - unused */ - &(shift[56]), /* window 3 */ - &(shift[48]), /* window 4 */ - &(shift[32]), /* window 5 */ - &(shift[ 0]), /* window 6 - unused */ - }; - -/** - * Calculates a Montgomery exponent string. - * - * For a supplied exponent p, generate an exponent string strp, which - * defines in pairs the number of multiplies and square operations - * required by a particular bit pattern, commonly used exponents - * 3, 11 and F4 have predefined constant string values, the rest - * are calculated into a cast unsigned char * array via the data - * pointer of a BIGNUM taken from the BN_CTX stack of BIGNUMs - * - * @param p [In] Exponent - * @param strp [Out] Exponent string result - * @param flags [In] Unused - * @param ctx [In] Temporary data storage - * - * @pre p, and ctx are initialised and valid - * @post strp points to required exponent string - * - * @notes String length value in strp[2] is invalid for strings - * greater than length 255 - * string terminates with pattern, 0, 0 this should be - * used in accurately determining the length of a returned - * string strp. - * - * @note strings with value sqr = 255, mul = 0, sqr value should be - * treated as value 256, and added to the next sqr value, this - * is used by exponent strings where more then 256 contiguous - * zero bits are in the exponent bit representation. - * - * @note code contains conditional compilation of code dependent on - * the OS int/long sizes - */ -int BN_gen_exp_bits(p,strp,flags,ctx) -BIGNUM *p; -unsigned char **strp; -int flags; -BN_CTX *ctx; - { - int bits,i,j,window,num; - unsigned char *str=NULL; - BIGNUM *tmp; - - flags=flags; - bits=p->top*BN_BITS2; - tmp=&(ctx->bn[ctx->tos]); - if (p->top == 0) - return(0); - -#if (BN_BITS2 > 17) - if (p->top == 1) -#else - if (bits <= 32) -#endif - { -#if (BN_BITS2 > 17) - if ((p->top == 1) && (p->d[0] == 0x10001)) - str=(unsigned char *)p16; -#endif -#if (16 >= BN_BITS2) && (BN_BITS > 8) - if ( (p->top == 2) && - (p->d[0] == 0x0001) && - (p->d[1] == 0x0001)) - str=(unsigned char *)p16; -#endif -#if (8 >= BN_BITS) - if ( (p->top == 3) && - (p->d[0] == 0x01) && - (p->d[1] == 0x00) && - (p->d[2] == 0x01)) - str=(unsigned char *)p16; -#endif - else if ((p->d[0] == 0x11) && (p->top == 1)) - str=(unsigned char *)p4; - else if ((p->d[0] == 0x3) && (p->top == 1)) - str=(unsigned char *)p2; - window=1; - num=1; - i=BN_BITS2; - } - else if (bits >= 256) - { - window=MAX_WIN_SIZE; /* max size of window */ - num=MAX_NUM_SIZE; - i=(BN_BITS2+(MAX_WIN_SIZE -1))/MAX_WIN_SIZE; - } - else if (bits >= 128) - { - window=4; - num=8; - i=(BN_BITS2+3)/4; - } - else /* 128 to 33 */ - { - window=3; - num=4; - i=(BN_BITS2+2)/3; - } - - /* Number of tmp words */ - j=(p->top*i*2+BN_BYTES-1+4)/BN_BYTES; - - if (str == NULL) - { - if (!bn_wexpand(tmp,j)) - return(0); - str=(unsigned char *)tmp->d; - i=BN_gen_exp_string(&(str[4]),p,window); - i+=2; - str[0]=(unsigned char)((i>>8)&0xff); - str[1]=(unsigned char)((i )&0xff); - str[2]=(unsigned char)window; - str[3]=(unsigned char)num; - } - else - { - i=8; - } - *strp=str; - return(i+2); - } - - -/** - * Generates the Montgomery exponent string. - * - * This function is used to generate an 'exponent string' - * which is an array of bytes that encode how to perform the steps in - * the a^p%m operation. - * - * @param str [Out] Containing the generated string - * @param p [In] Exponent to generate the string for - * @param bits [In] Size of the window for shifting the values of the BIGNUM - * - * @pre p is initialised and value BIGNUM, bits is not 0 - * @post str points to generated exponent string - * - * @note str is cast assigned the data of a BIGNUM allocated and - * expanded from the BN_CTX of the calling function BN_gen_exp_bits - * it does not need to be de-allocated - * - * @note string consisted of unsigned char pairs and 4 byte init - * pairs are sqr count and multiply, where strings are greater - * than 256 bit, length in position str[2] is invalid - * - * @note strings with value sqr = 255, mul = 0, sqr value should be - * treated as value 256, and added to the next sqr value, this - * is used by exponent strings where more then 256 contiguous - * zero bits are in the exponent bit representation. - * - */ -int BN_gen_exp_string(str,p,bits) -unsigned char *str; -BIGNUM *p; -int bits; - { - unsigned char *sp; - unsigned int mask; - const unsigned char *shift; - BN_ULONG w,wh,wl,*d; - unsigned int i,mul,sqr,t,s,ss; - int top; - - if (bits > 6) bits=6; - shift= shift_val[bits]; - - /* This is the mask for the bits we wish to operate on */ - mask=(1<top*BN_BITS2+bits-1)/bits)*2+2]); - *sp-- = 0; - *sp-- = 0; - top=p->top; /* Total words we will shift in */ - d=p->d; - w=wl= *d++; - if (top <= 1) - wh=0; - else - wh= *d++; - sqr=0; - i=0; - - for (;;) - { - /* t will contain how far we need to shift to set a 1 - * in the bottom bit. */ - for (;;) - { - t=w&mask; /* retrieve our window */ - s=shift[t]; /* get the shift value for the window */ - if (s == 0) break; /* no shift write out the vals */ - sqr+=s; /* add the shifted zero count to sqr */ - ss+=s; /* ss is total shift for wl */ - if (ss >= BN_BITS2) /* we have shifted > word len */ - { - if (top <= 1) break; /* no more to do */ - top--; /* dec the count */ - - wl=wh; /* copy the next word */ - /* load the word after or 0 if no more */ - wh=(top <= 1)?0:(*d++); - /* adjust our shift by len of word */ - ss-=BN_BITS2; - } - /* reset our window word w */ - if (ss == 0) - w=wl; - else - w=(wl>>ss)|(wh<<(BN_BITS2-ss)); - } - - /* At this point we have the 0th bit set */ - mul=t; - if (t == 0) break; /* we have reached the end of p */ - /* write out sqr/mul pair */ - *sp-- = (unsigned char)(sqr & 0xff); - *sp-- = (unsigned char)(mul & 0xff); - if(sqr >= 256) /* check whether sqr exceeds max uchar */ - { - /* output the expanded list of to allow for this - * and numbers will require to be added together - * at interpret time - */ - while(sqr >= 256) - { - *sp-- = 255; - *sp-- = 0; /* mul is never zero normally */ - sqr-= 256; - } - } - sqr=bits; /* set sqr to be the window size */ - - ss+=bits; /* ss is total shift for wl */ - if (ss >= BN_BITS2) /* adjust window words w,wl, wh again */ - { - if (top <= 1) break; - top--; - - wl=wh; - wh=(top <= 1)?0:(*(d++)); - ss-=BN_BITS2; - } - - if (ss == 0) - w=wl; - else - w=(wl>>ss)|(wh<<(BN_BITS2-ss)); - } - sp++; - i=2; - /* reverse the string from the top of the exponent string - * and copy to the bottom, allocated exponent string is 2 * max length - * expected for exponent string - */ - while (sp[0] != 0 || sp[1] != 0) - { - str[0]=sp[0]; - str[1]=sp[1]; - str+=2; - sp+=2; - i+=2; - } - str[0]=0; - str[1]=0; - - return(i); - } - -#ifdef MAIN -main() - { - BIGNUM p; - unsigned char buf[512],*pp; - int i; - - BN_init(&p); - BN_rand(&p,33,1,0); -#ifndef NO_FP_API - BN_print_fp(stdout,&p); fprintf(stdout,"\n"); -#endif - - BN_rand(&p,512,1,1); -#ifndef NO_FP_API - BN_print_fp(stdout,&p); fprintf(stdout,"\n"); -#endif - for (i=0; i<10000; i++) - BN_gen_exp_string(buf,&p,5); - -#if 0 - BN_gen_exp_string(buf,&p,3); - - pp=buf; - for (;;) - { - printf("mul %d sqr %d\n",pp[0],pp[1]); - if (pp[1] == 0) break; - pp+=2; - } -#endif - } -#endif diff --git a/build/tools/acsign/bn_exp.c b/build/tools/acsign/bn_exp.c deleted file mode 100644 index 08634e7e..00000000 --- a/build/tools/acsign/bn_exp.c +++ /dev/null @@ -1,156 +0,0 @@ -/* $Id$ */ -/* - * Copyright (C) 1998-2002 RSA Security Inc. All rights reserved. - * - * This work contains proprietary information of RSA Security. - * Distribution is limited to authorized licensees of RSA - * Security. Any unauthorized reproduction, distribution or - * modification of this work is strictly prohibited. - * - */ - -#include "bn_lcl.h" - -#if !(defined(NO_SPLIT) && defined(SPLIT_FILE)) - -#ifdef NO_SPLIT -#define SPLIT_BN_MOD_EXP_ORIG -#define SPLIT_BN_MOD_EXP -#endif /* NO_SPLIT */ - -#define TABLE_SIZE 16 - -#ifdef SPLIT_BN_MOD_EXP_ORIG -#if 0 -/* this one works - simple but works */ -int BN_mod_exp_orig(r,a,p,m,ctx) -BIGNUM *r,*a,*p,*m; -BN_CTX *ctx; - { - int i,bits,ret=0; - BIGNUM *v,*tmp; - - v= &(ctx->bn[ctx->tos++]); - tmp= &(ctx->bn[ctx->tos++]); - - if (BN_copy(v,a) == NULL) goto err; - bits=BN_num_bits(p); - - if (BN_is_odd(p)) - { if (BN_copy(r,a) == NULL) goto err; } - else { if (!BN_one(r)) goto err; } - - for (i=1; itos-=2; - return(ret); - } - -#endif - -/* this one works - simple but works */ -int BN_exp(r,a,p,ctx) -BIGNUM *r,*a,*p; -BN_CTX *ctx; - { - int i,bits,ret=0,tos; - BIGNUM *v,*rr; - - bn_check_top(a); - bn_check_top(p); - - tos=ctx->tos; - v= &(ctx->bn[ctx->tos++]); - if ((r == a) || (r == p)) - rr= &(ctx->bn[ctx->tos++]); - else - rr=r; - - if (BN_copy(v,a) == NULL) goto err; - bits=BN_num_bits(p); - - if (BN_is_odd(p)) - { if (BN_copy(rr,a) == NULL) goto err; } - else { if (!BN_one(rr)) goto err; } - - for (i=1; itos=tos; - if (r != rr) (void)BN_copy(r,rr); - return(ret); - } -#endif - -#ifdef SPLIT_BN_MOD_EXP -/** - * Perform mod exp on BIGNUM - * @param r Pointer to return value BIGNUM - * @param a Pointer to data value BIGNUM - * @param p Pointer to Public exponent BIGNUM - * @param m Pointer to modulus BIGNUM - * @param ctx Pointer to BN_CTX - * @return 0 success - * @pre BIGNUMs a, p, m and BN_CTX ctx exist and are valid - * @post BIGNUM r points to evaluated mod_exp - * @note BN_mod_exp_mont is only available if library compiled - * with define BN_MONT_MUL, and will only be used to compute - * mod_exp operation where the modulus m is odd. - * BN_mod_exp_recp is only available if library is compiled - * with define RECP_MUL_MOD. - * BN_mod_exp_simple is the default method, not available if - * library is compiled with define RECP_MUL_MOD. - * if BN_mod_exp_mont is available, which ever of BN_mod_exp_simple - * or BN_mod_exp_recp is available will only be used for even - * modulus m values. - * @relates BN_mod_exp_mont - * @relates BN_mod_exp_recp - * @relates BN_mod_exp_simple - */ -int BN_mod_exp(r,a,p,m,ctx) -BIGNUM *r; -BIGNUM *a; -BIGNUM *p; -BIGNUM *m; -BN_CTX *ctx; - { - int ret; - - bn_check_top(a); - bn_check_top(p); - bn_check_top(m); - -#ifdef MONT_MUL_MOD - - if (BN_is_odd(m)) - { ret=BN_mod_exp_mont(r,a,p,m,ctx,NULL); } - else -#endif -#ifdef RECP_MUL_MOD - { ret=BN_mod_exp_recp(r,a,p,m,ctx); } -#else - { ret=BN_mod_exp_simple(r,a,p,m,ctx); } -#endif - - return(ret); - } -#endif - -#endif diff --git a/build/tools/acsign/bn_fm_w.c b/build/tools/acsign/bn_fm_w.c deleted file mode 100644 index 999ed55f..00000000 --- a/build/tools/acsign/bn_fm_w.c +++ /dev/null @@ -1,63 +0,0 @@ -/* $Id$ */ -/* - * Copyright (C) 1998-2002 RSA Security Inc. All rights reserved. - * - * This work contains proprietary information of RSA Security. - * Distribution is limited to authorized licensees of RSA - * Security. Any unauthorized reproduction, distribution or - * modification of this work is strictly prohibited. - * - */ -#include "bn_lcl.h" - -/* rp has w words, the top w words are 0 */ -void bn_from_montgomery_words(ret,a,np,w,n0) -BN_ULONG *ret; -BN_ULONG *a; -BN_ULONG *np; -int w; -BN_ULONG n0; - { - BN_ULONG v0,v1,*ap,*wap; - int i; - - v1=0; - - ap=a; - wap= &(a[w]); - /* Consider putting this loop in ASM */ - for (i=0; i0; i--) - if (ap[i] != np[i]) break; - } - v1=(ap[i] >= np[i]); - } - if (v1) - (void)bn_sub_words(ret,ap,np,w); - else - { -#if 0 /* Alpha does not like Memcpy */ - Memcpy(ret,ap,sizeof(BN_ULONG)*w); -#else - for (i=0; ibn[ctx->tos]); - b= &(ctx->bn[ctx->tos+1]); - - if (BN_copy(a,in_a) == NULL) goto err; - if (BN_copy(b,in_b) == NULL) goto err; - - if (BN_cmp(a,b) < 0) { t=a; a=b; b=t; } - t=bn_euclid(a,b); - if (t == NULL) goto err; - - if (BN_copy(r,t) == NULL) goto err; - ret=1; -err: - return(ret); - } - -BIGNUM *bn_euclid(a,b) -BIGNUM *a,*b; - { - BIGNUM *t; - int shifts=0; - - bn_check_top(a); - bn_check_top(b); - - for (;;) - { - if (BN_is_zero(b)) - break; - - if (BN_is_odd(a)) - { - if (BN_is_odd(b)) - { - if (!BN_sub(a,a,b)) goto err; - if (!BN_rshift1(a,a)) goto err; - if (BN_cmp(a,b) < 0) - { t=a; a=b; b=t; } - } - else /* a odd - b even */ - { - if (!BN_rshift1(b,b)) goto err; - if (BN_cmp(a,b) < 0) - { t=a; a=b; b=t; } - } - } - else /* a is even */ - { - if (BN_is_odd(b)) - { - if (!BN_rshift1(a,a)) goto err; - if (BN_cmp(a,b) < 0) - { t=a; a=b; b=t; } - } - else /* a even - b even */ - { - if (!BN_rshift1(a,a)) goto err; - if (!BN_rshift1(b,b)) goto err; - shifts++; - } - } - } - if (shifts) - { - if (!BN_lshift(a,a,shifts)) goto err; - } - return(a); -err: - return(NULL); - } -#endif - -#ifdef SPLIT_BN_MOD_INVERSE -/* solves ax == 1 (mod n) */ -BIGNUM *BN_mod_inverse(in, a, n, ctx) -BIGNUM *in; -BIGNUM *a; -BIGNUM *n; -BN_CTX *ctx; - { - BIGNUM *A,*B,*X,*Y,*M,*D,*R; - BIGNUM *T,*ret=NULL; - int sign; - - bn_check_top(a); - bn_check_top(n); - - A= &(ctx->bn[ctx->tos]); - B= &(ctx->bn[ctx->tos+1]); - X= &(ctx->bn[ctx->tos+2]); - D= &(ctx->bn[ctx->tos+3]); - M= &(ctx->bn[ctx->tos+4]); - Y= &(ctx->bn[ctx->tos+5]); - ctx->tos+=6; - if (in == NULL) - R=BN_new(); - else - R=in; - if (R == NULL) goto err; - - (void)BN_zero(X); - (void)BN_one(Y); - if (BN_copy(A,a) == NULL) goto err; - if (BN_copy(B,n) == NULL) goto err; - sign=1; - - while (!BN_is_zero(B)) - { - if (!BN_div(D,M,A,B,ctx)) goto err; - T=A; - A=B; - B=M; - /* T has a struct, M does not */ - - if (!BN_mul(T,D,X,ctx)) goto err; - if (!BN_add(T,T,Y)) goto err; - M=Y; - Y=X; - X=T; - sign= -sign; - } - if (sign < 0) - { - if (!BN_sub(Y,n,Y)) goto err; - } - - if (BN_is_one(A)) - { if (!BN_mod(R,Y,n,ctx)) goto err; } - else - { -#ifndef NO_ERR - BNerr(BN_F_BN_MOD_INVERSE,BN_R_NO_INVERSE); -#endif - goto err; - } - ret=R; -err: - if ((ret == NULL) && (in == NULL)) BN_free(R); - ctx->tos-=6; - return(ret); - } -#endif - -#ifdef SPLIT_BN_MOD_INVERSE_WORD -/* solves 1 == (ret*(1<l - * @param l [In] a word (size of word depends on machine) - * @returns number of bits in parameter l - */ -#ifdef SPLIT_BN_NUM_BITS_WORD -int BN_num_bits_word(l) -BN_ILONG l; - { - int i; - - /* - * This table represents the number of bits required to - * represent a "number", where "number" is indexed from - * 0 into the table. So: - * number 0 = # bits req'd to represent 0 = bits[0] = 0 - * number 1 = # bits req'd to represent 1 = bits[1] = 1 - * number 2 = # bits req'd to represent 2 = bits[2] = 2 - * number 3 = # bits req'd to represent 3 = bits[3] = 2 - * number 4 = # bits req'd to represent 4 = bits[4] = 3 - * etc. - * - * The small code size table exists to save some space, - * but requires (at most) an extra shift, an extra AND, - * and an extra add. - */ -#ifdef SMALL_CODE_SIZE - const static char bits[16]={ - 0,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4 - }; -#else - const static char bits[256]={ - 0,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4, - 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, - 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6, - 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6, - 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, - 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, - 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, - 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, - 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, - 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, - 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, - 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, - 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, - 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, - 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, - 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, - }; -#endif - -#if defined(SIXTY_FOUR_BIT_LONG) - if (l & 0xffffffff00000000L) - { - if (l & 0xffff000000000000L) - { - if (l & 0xff00000000000000L) - i=56; - else i=48; - } - else - { - if (l & 0x0000ff0000000000L) - i=40; - else i=32; - } - } - else -#else -#ifdef SIXTY_FOUR_BIT - if (l & 0xffffffff00000000LL) - { - if (l & 0xffff000000000000LL) - { - if (l & 0xff00000000000000LL) - i=56; - else i=48; - } - else - { - if (l & 0x0000ff0000000000LL) - i=40; - else i=32; - } - } - else -#endif -#endif - { -#if defined(THIRTY_BIT) || defined(THIRTY_ONE_BIT) || defined(THIRTY_TWO_BIT) || defined(SIXTY_FOUR_BIT) || defined(SIXTY_FOUR_BIT_LONG) - if (l & 0xffff0000L) - { - if (l & 0xff000000L) - i=24; - else i=16; - } - else -#endif - { - if (l & 0xff00L) - i=8; - else - i=0; - } - } -#ifndef SMALL_CODE_SIZE - return(i+bits[l>>i]); -#else - l>>=i; - if (l & 0xf0) - return(bits[l>>4]+i+4); - else - return(bits[l]+i); -#endif - } -#endif - -#ifdef SPLIT_BN_NUM_BITS -int BN_num_bits(a) -BIGNUM *a; - { - BN_ULONG l; - int i; - - bn_check_top(a); - - if (a->top == 0) return(0); - l=a->d[a->top-1]; - i=(a->top-1)*BN_BITS2; -#ifdef BN_DEBUG - if (l == 0) - { -#if !defined(NO_FP_API) && !defined(WIN16) - fprintf(stderr,"BAD TOP VALUE\n"); -#endif - abort(); /* BN_DEBUG */ - /* TODO: need to understand what sort of error can - * be reported for this error - */ - return(0); - } -#endif - return(i+BN_num_bits_word(l)); - } -#endif - -/** - * Clears and free a BIGNUM - * - * @param a [In] BIGNUM to clear then free - */ -#ifdef SPLIT_BN_CLEAR_FREE -void BN_clear_free(BIGNUM *a) -{ - if (a == NULL) - { - return; - } - - BN_clear(a); - BN_free(a); -} -#endif - -#ifdef SPLIT_BN_FREE -/** - * Frees a BIGNUM - * - * @param a [In] BIGNUM to free - */ -void BN_free(a) -BIGNUM *a; - { - if (a == NULL) return; - if ((a->d != NULL) && !(BN_get_flags(a,BN_FLG_STATIC_DATA))) - Free(a->d); - a->flags|=BN_FLG_FREE; /* REMOVE? */ - if (a->flags & BN_FLG_MALLOCED) - Free(a); - } -#endif - -#ifdef SPLIT_BN_INIT - -#ifdef SMALL_CODE_SIZE -/** - * Zero expands a bignum - * - * @param a [In] BIGNUM to expand - * @param n [In] number of bits to expand to - * - * @pre a is a valid BIGNUM. - */ -void bn_zexpand(a,n) -BIGNUM *a; -int n; - { - if ((a)->top < n) - { - int i; - bn_wexpand((a),n); - if (a->d!=NULL) - { - for (i=(a)->top; id[i]=0; - } - } - } - -/** - * Fixes the top value in the BIGNUM to be the count of BN_ULONGs with data. - * - * @param a [In] BIGNUM to free - * - * @pre a is a valid BIGNUM. - */ -void bn_fix_top(a) -BIGNUM *a; - { - BN_ULONG *ftl; - if ((a)->top > 0) - { - for (ftl= &((a)->d[(a)->top-1]); (a)->top > 0; (a)->top--) - if (*(ftl--)) break; - } - } -#endif - -/** - * Initializes a BIGNUM - * - * @param a [In] BIGNUM reference - * - * @pre a is a valid BIGNUM. - */ -void BN_init(a) -BIGNUM *a; - { - (void)Memset(a,0,sizeof(BIGNUM)); - } -#endif - -#ifdef SPLIT_BN_NEW -/** - * Allocates a BIGNUM - * - * @return pointer to allocated BIGNUM - */ -BIGNUM *BN_new() - { - BIGNUM *ret; - - if ((ret=(BIGNUM *)Malloc(sizeof(BIGNUM))) == NULL) - { -#ifndef NO_ERR - BNerr(BN_F_BN_NEW,ERR_R_MALLOC_FAILURE); -#endif - return(NULL); - } - ret->flags=BN_FLG_MALLOCED; - ret->top=0; - ret->neg=0; - ret->max=0; - ret->d=NULL; - return(ret); - } -#endif - -#ifdef SPLIT_BN_CTX_NEW -/** - * Allocates a BIGNUM context - * - * @return pointer to allocated BIGNUM context - */ -BN_CTX *BN_CTX_new() - { - BN_CTX *ret; - - ret=(BN_CTX *)Malloc(sizeof(BN_CTX)); - if (ret == NULL) - { -#ifndef NO_ERR - BNerr(BN_F_BN_CTX_NEW,ERR_R_MALLOC_FAILURE); -#endif - return(NULL); - } - - BN_CTX_init(ret); - ret->flags=BN_FLG_MALLOCED; - return(ret); - } -#endif - -#ifdef SPLIT_CTX_INIT -/** - * Initializes a BIGNUM context - * - * @param a [In] BIGNUM context reference - * - * @pre a is a valid BIGNUM context. - */ -void BN_CTX_init(ctx) -BN_CTX *ctx; - { - (void)Memset(ctx,0,sizeof(BN_CTX)); - ctx->tos=0; - ctx->flags=0; - } -#endif - -#ifdef SPLIT_BN_CTX_FREE -/** - * Frees a BIGNUM context - * - * @param a [In] BIGNUM context reference - * - * @pre a is a valid BIGNUM context. - */ -void BN_CTX_free(c) -BN_CTX *c; - { - int i; - - for (i=0; ibn[i])); - if (c->flags & BN_FLG_MALLOCED) - Free(c); - } -#endif - -#ifdef SPLIT_BN_EXPAND2 -BIGNUM *bn_expand2(b, words) -BIGNUM *b; -int words; - { - BN_ULONG *A,*B,*a; - - R_DIAG_CHECK_STACK; - - bn_check_top(b); - - if (words > b->max) - { - bn_check_top(b); - if (BN_get_flags(b,BN_FLG_STATIC_DATA)) - { -#ifndef NO_ERR - BNerr(BN_F_BN_EXPAND2,BN_R_EXPAND_ON_STATIC_BIGNUM_DATA); -#endif - return(NULL); - } - a=A=(BN_ULONG *)Malloc(sizeof(BN_ULONG)*(words+1)); - if (A == NULL) - { -#ifndef NO_ERR - BNerr(BN_F_BN_EXPAND2,ERR_R_MALLOC_FAILURE); -#endif - return(NULL); - } - /* during development this is a nice way of making sure - * that we are not relying on the top byte being 0 or - * other such things - */ -#ifdef BN_DEBUG - (void)Memset(A,0x5c,sizeof(BN_ULONG)*(words+1)); -#endif - - B=b->d; - if (B != NULL) - { -#ifndef SMALL_CODE_SIZE - int i; - - /* for (i=b->top&(~7); i>0; i-=8) */ - /* The above line can induce a SunC compiler bug */ - for (i=(b->top>>3); i>0; i--) - { - BN_ULONG T0,T1,T2,T3; - - T0=B[0]; - T1=B[1]; - T2=B[2]; - T3=B[3]; - A[0]=T0; - A[1]=T1; - A[2]=T2; - A[3]=T3; - T0=B[4]; - T1=B[5]; - T2=B[6]; - T3=B[7]; - A[4]=T0; - A[5]=T1; - A[6]=T2; - A[7]=T3; - A+=8; - B+=8; - } - switch (b->top&7) - { - case 7: - A[6]=B[6]; - case 6: - A[5]=B[5]; - case 5: - A[4]=B[4]; - case 4: - A[3]=B[3]; - case 3: - A[2]=B[2]; - case 2: - A[1]=B[1]; - case 1: - A[0]=B[0]; - case 0: - /* I need the 'case 0' entry for utrix cc. - * If the optimiser is turned on, it does the - * switch table by doing - * a=top&7 - * a--; - * goto jump_table[a]; - * If top is 0, this makes us jump to 0xffffffc - * which is rather bad. - * eric 23-Apr-1998 - */ - ; - } -#if 0 /* Not needed */ - B= &(b->d[b->top]); - j=b->max-8; - for (i=b->top; itop); -#endif - Free(b->d); - } - - b->d=a; - b->max=words; - } - return(b); - } -#endif - -#ifdef SPLIT_BN_DUP -/** - * Duplicates a BIGNUM - * - * @param a [In] BIGNUM reference - * - * @returns pointer to duplicate BIGNUM of a - */ -BIGNUM *BN_dup(a) -BIGNUM *a; - { - BIGNUM *r; - BIGNUM *ret; - - bn_check_top(a); - - r=BN_new(); - if (r == NULL) return(NULL); - ret = (BIGNUM *)BN_copy(r,a); - if (ret == NULL) - { - BN_free(r); - } - return(ret); - } -#endif - -#ifdef SPLIT_BN_COPY -/** - * Copies a BIGNUM to an existing BIGNUM - * - * @param a [In] To BIGNUM reference - * @param b [Out] From BIGNUM reference - * - * @pre Both a and b are valid BIGNUMs - * - * @returns pointer to duplicate BIGNUM of a - */ -BIGNUM *BN_copy(a, b) -BIGNUM *a; -BIGNUM *b; - { -#ifndef SMALL_CODE_SIZE - int i; - BN_ULONG *A,*B; -#endif - - bn_check_top(b); - - if (a == b) return(a); - if (bn_wexpand(a,b->top) == NULL) return(NULL); -#ifndef SMALL_CODE_SIZE - A=a->d; - B=b->d; - -/* for (i=b->top&~0x07; i>0; i-=8) */ -/* The above version of this loop has been removed. It appeared - to generate a compiler bug in SunC 4.x and 5.x. I do not believe - that the code was to blame. Compiling with -fast was the problem - since this would loop unroll the loop below another 3 times. - The compiler would generate generate - andcc %o0,-8,%o1 # load ~0x07 - ld [%i2],%o3 # load *B - ble .L77000125 # exit loop unless 8 or more - ld [%i1],%o2 # load *A - sub %o1,-7,%o0 # - sdivcc %o0,8,%o0 # when do we clear %y? - bvs,a .L900001510 - sethi %hi(0x80000000),%o0 -.L900001510: - cmp %o0,3 - bl .L77000114 # one loop - ld [%o2],%o0 - # three loop code - - The loop would then be unrolled 3 times. The problem I believe - I was seeing was that the sdivcc operates is %y:%o0 / 8. - %y is not being cleared, and so occasionally this would - cause problems. The replacement code sequence stops - the compiler generating the sdiv instruction. - */ - for (i=(b->top>>3); i>0; i--) - { - BN_ULONG T0,T1,T2,T3; - T0=B[0]; - T1=B[1]; - T2=B[2]; - T3=B[3]; - A[0]=T0; - A[1]=T1; - A[2]=T2; - A[3]=T3; - T0=B[4]; - T1=B[5]; - T2=B[6]; - T3=B[7]; - A[4]=T0; - A[5]=T1; - A[6]=T2; - A[7]=T3; - A+=8; - B+=8; - } - switch (b->top&0x07) - { - case 7: - A[6]=B[6]; - case 6: - A[5]=B[5]; - case 5: - A[4]=B[4]; - case 4: - A[3]=B[3]; - case 3: - A[2]=B[2]; - case 2: - A[1]=B[1]; - case 1: - A[0]=B[0]; - case 0: - /* I need the 'case 0' entry for utrix cc. - * If the optimiser is turned on, it does the - * switch table by doing - * a=top&7 - * a--; - * goto jump_table[a]; - * If top is 0, this makes us jump to 0xffffffc which is - * rather bad. - * eric 23-Apr-1998 - */ - ; - } -#else - (void)Memcpy(a->d,b->d,sizeof(b->d[0])*b->top); -#endif - -/* (void)Memset(&(a->d[b->top]),0,sizeof(a->d[0])*(a->max-b->top));*/ - a->top=b->top; - if ((a->top == 0) && (a->d != NULL)) - a->d[0]=0; - a->neg=b->neg; - return(a); - } -#endif - -#ifdef SPLIT_BN_CLEAR -/** - * Clears a BIGNUM - * - * @param a [In] BIGNUM to clear - * - * @pre a is valid - */ -void BN_clear(a) -BIGNUM *a; - { - if (a->d != NULL) - (void)Memset(a->d,0,a->max*sizeof(a->d[0])); - a->top=0; - a->neg=0; - } -#endif - -#ifdef SPLIT_BN_GET_WORD -BN_ULONG BN_get_word(a) -BIGNUM *a; - { - int i,n; - BN_ULONG ret=0; - - n=BN_num_bytes(a); - if (n > ((int) sizeof(BN_ULONG))) - return(BN_MASK2); - for (i=a->top-1; i>=0; i--) - { -#ifndef SIXTY_FOUR_BIT /* the data item > unsigned long */ - ret<<=BN_BITS4; /* stops the compiler complaining */ - ret<<=BN_BITS4; -#else - ret=0; -#endif - ret|=a->d[i]; - } - return(ret); - } -#endif - -#ifdef SPLIT_BN_SET_WORD -/** - * Set the BIGNUM to the supplied BN_ULONG value. - * - * @param a [In/Out] BIGNUM to be updated - * @param w [In] Value to be set in a - * - * @notes Function will expand a to be an - * array of 8 BN_ULONGs in size. - * @todo Review behaviour of expansion without checking - * of size first. - */ -int BN_set_word(a,w) -BIGNUM *a; -BN_ULONG w; - { - int i,n; - - if (bn_expand(a,(int)(sizeof(BN_ULONG)*8)) == NULL) return(0); - -#ifdef BN_BYTES - /* This is used when a BN_ULONG is greater in size - * than the BN_BYTES of the array, eg BN_ULONG 64 bits - * and actual a->d array of 32 bits. - */ - n=sizeof(BN_ULONG)/BN_BYTES; -#else - n=1; -#endif - a->neg=0; - a->top=0; - a->d[0]=(BN_ULONG)w&BN_MASK2; - if (a->d[0] != 0) a->top=1; - for (i=1; i>=BN_BITS2 so compilers don't complain - * on builds where sizeof(long) == BN_TYPES */ -#ifndef SIXTY_FOUR_BIT /* the data item > unsigned long */ - w>>=BN_BITS4; - w>>=BN_BITS4; -#else - w=0; -#endif - a->d[i]=(BN_ULONG)w&BN_MASK2; - if (a->d[i] != 0) a->top=i+1; - } - return(1); - } -#endif - -#ifdef BN_BYTES -#ifdef SPLIT_BN_BIN2BN -/* ignore negative */ -BIGNUM *BN_bin2bn(s, len, ret) -unsigned char *s; -int len; -BIGNUM *ret; - { - unsigned int i,m; - unsigned int n; - BN_ULONG l; - - if (ret == NULL) ret=BN_new(); - if (ret == NULL) return(NULL); - l=0; - n=len; - if (n == 0) - { - ret->top=0; - return(ret); - } - if (bn_expand(ret,(int)(n+2)*8) == NULL) - return(NULL); - i=((n-1)/BN_BYTES)+1; - m=((n-1)%(BN_BYTES)); - ret->top=i; - while (n-- > 0) - { - l=(l<<8L)| *(s++); - if (m-- == 0) - { - ret->d[--i]=l; - l=0; - m=BN_BYTES-1; - } - } - /* need to call this due to clear byte at top if avoiding - * having the top bit set (-ve number) */ - bn_fix_top(ret); - return(ret); - } -#endif - -#ifdef SPLIT_BN_BN2BIN -/* ignore negative */ -int BN_bn2bin(a, to) -BIGNUM *a; -unsigned char *to; - { - int n,i; - BN_ULONG l; - - bn_check_top(a); - - n=i=BN_num_bytes(a); - while (i-- > 0) - { - l=a->d[i/BN_BYTES]; - *(to++)=(unsigned char)((l>>(8*(i%BN_BYTES)))&0xff); - } - return(n); - } -#endif -#else -#ifdef SPLIT_BN_BIN2BN -/* ignore negative */ -BIGNUM *BN_bin2bn(s, len, ret) -unsigned char *s; -int len; -BIGNUM *ret; - { - int i,w,r,b,j,v; - int n; - BN_ULONG l; - - if (ret == NULL) ret=BN_new(); - if (ret == NULL) return(NULL); - while (len > 0) - { - if (*s != 0) break; - s++; - len--; - } - n=len*8; - if (bn_expand(ret,n) == NULL) - return(NULL); - for (i=0; imax; i++) - ret->d[i]=0; - j=0; - for (i=len-1; i>=0; i--) - { - v=((int)s[i])&0xff; - w=j/BN_BITS2; - b=j%BN_BITS2; - r=BN_BITS2-b; - j+=8; - if (r >= 8) - { - ret->d[w]|=(((BN_ULONG)v)<d[w] =(ret->d[w]|(((BN_ULONG)v)<d[w+1]=(ret->d[w+1]|(((BN_ULONG)v)>>r)); - } - } - - ret->top=((n-1)/BN_BITS2)+1; - bn_fix_top(ret); - return(ret); - } -#endif - -#ifdef SPLIT_BN_BN2BIN -int BN_bn2bin(a, to) -BIGNUM *a; -unsigned char *to; - { - int num,i,bi,w,b,r,max; - BN_ULONG l,*lp; - - bn_check_top(a); - - num=bi=BN_num_bytes(a); - lp=a->d; - for (i=0; i= 8) - to[bi]=(lp[w]>>b)&0xff; - else - { - to[bi]=(lp[w]>>b); - if (w+1 < a->top) - to[bi]|=lp[w+1]<top-b->top; - if (i != 0) return(i); - ap=a->d; - bp=b->d; - for (i=a->top-1; i>=0; i--) - { - t1= ap[i]; - t2= bp[i]; - if (t1 != t2) - return(t1 > t2?1:-1); - } - return(0); - } -#endif - -#ifdef SPLIT_BN_CMP -int BN_cmp(a, b) -BIGNUM *a; -BIGNUM *b; - { - int i; - int gt,lt; - BN_ULONG t1,t2; - - if ((a == NULL) || (b == NULL)) - { - if (a != NULL) - return(-1); - else if (b != NULL) - return(1); - else - return(0); - } - - bn_check_top(a); - bn_check_top(b); - - if (a->neg != b->neg) - { - if (a->neg) - return(-1); - else return(1); - } - if (a->neg == 0) - { gt=1; lt= -1; } - else { gt= -1; lt=1; } - - if (a->top > b->top) return(gt); - if (a->top < b->top) return(lt); - for (i=a->top-1; i>=0; i--) - { - t1=a->d[i]; - t2=b->d[i]; - if (t1 > t2) return(gt); - if (t1 < t2) return(lt); - } - return(0); - } -#endif - -#ifdef SPLIT_BN_SET_BIT -int BN_set_bit(a, n) -BIGNUM *a; -int n; - { - int i,j,k; - - bn_check_top(a); - - i=n/BN_BITS2; - j=n%BN_BITS2; - if (a->top <= i) - { - if (bn_wexpand(a,i+1) == NULL) return(0); - for(k=a->top; kd[k]=0; - a->top=i+1; - } - - a->d[i]|=(((BN_ULONG)1)<top <= i) return(0); - - a->d[i]&=(~(((BN_ULONG)1)<top <= i) return(0); - return((a->d[i]&(((BN_ULONG)1)<= a->top) return(0); - if (b == 0) - a->top=w; - else - { - a->top=w+1; - a->d[w]&= ~(((BN_ULONG)BN_MASK2)< bb)?1:-1); - for (i=n-2; i>=0; i--) - { - aa=a[i]; - bb=b[i]; - if (aa != bb) return((aa > bb)?1:-1); - } - return(0); - } -#endif -#endif - diff --git a/build/tools/acsign/bn_lsh.c b/build/tools/acsign/bn_lsh.c deleted file mode 100644 index 133b33ed..00000000 --- a/build/tools/acsign/bn_lsh.c +++ /dev/null @@ -1,112 +0,0 @@ -/* $Id$ */ -/* - * Copyright (C) 1998-2002 RSA Security Inc. All rights reserved. - * - * This work contains proprietary information of RSA Security. - * Distribution is limited to authorized licensees of RSA - * Security. Any unauthorized reproduction, distribution or - * modification of this work is strictly prohibited. - * - */ - -#include "bn_lcl.h" - -#if !(defined(NO_SPLIT) && defined(SPLIT_FILE)) - -#ifdef NO_SPLIT -#define SPLIT_BN_LSHIFT1 -#define SPLIT_BN_LSHIFT -#endif /* NO_SPLIT */ - -#ifdef SPLIT_BN_LSHIFT1 -#ifdef SMALL_CODE_SIZE - -int BN_lshift1(r, a) -BIGNUM *r,*a; - { - return(BN_lshift(r, a, 1)); - } - -#else - -int BN_lshift1(r, a) -BIGNUM *r; -BIGNUM *a; - { - register BN_ULONG *ap,*rp,t,c; - int i; - - bn_check_top(a); - - if (r != a) - { - if (bn_wexpand(r,a->top+1) == NULL) return(0); - r->neg=a->neg; - r->top=a->top; - } - else - { - if (bn_wexpand(r,a->top+1) == NULL) return(0); - } - ap=a->d; - rp=r->d; - c=0; - for (i=0; itop; i++) - { - t= *(ap++); - *(rp++)=((t<<1L)|c)&BN_MASK2; - c=(t & BN_TBIT)?1:0; - } - if (c) - { - *rp=1; - r->top++; - } - return(1); - } -#endif -#endif - -#ifdef SPLIT_BN_LSHIFT -int BN_lshift(r, a, n) -BIGNUM *r; -BIGNUM *a; -int n; - { - int i,nw,lb,rb; - BN_ULONG *t,*f; - BN_ULONG l; - - bn_check_top(a); - -#ifndef SMALL_CODE_SIZE - if (n == 1) return(BN_lshift1(r,a)); -#endif - if (bn_wexpand(r,a->top+(n/BN_BITS2)+1) == NULL) return(0); - r->neg=a->neg; - nw=n/BN_BITS2; - lb=n%BN_BITS2; - rb=BN_BITS2-lb; - f=a->d; - t=r->d; - t[a->top+nw]=0; - if (lb == 0) - for (i=a->top-1; i>=0; i--) - t[nw+i]=f[i]; - else - for (i=a->top-1; i>=0; i--) - { - l=f[i]; - t[nw+i+1]|=(l>>rb)&BN_MASK2; - t[nw+i]=(l<top=a->top+nw+1; - bn_fix_top(r); - return(1); - } -#endif - -#endif diff --git a/build/tools/acsign/bn_m_exp.c b/build/tools/acsign/bn_m_exp.c deleted file mode 100644 index 8d8afe94..00000000 --- a/build/tools/acsign/bn_m_exp.c +++ /dev/null @@ -1,283 +0,0 @@ -/* $Id$ */ -/* - * Copyright (C) 1998-2002 RSA Security Inc. All rights reserved. - * - * This work contains proprietary information of RSA Security. - * Distribution is limited to authorized licensees of RSA - * Security. Any unauthorized reproduction, distribution or - * modification of this work is strictly prohibited. - * - */ - -#if 0 //RSA -#include -#endif -#include "bn_lcl.h" - -/* #ifdef MONT_MUL_MOD */ -/** - * Generic form of Montgomery Exponentiation, can be called directly - * out side of a BN_ME_METH - * - * @param rr_in BIGNUM pointer for result - * @param a_in BIGNUM pointer for base - * @param p BIGNUM pointer to the exponent - * @param m BIGNUM pointer to the modulus - * @param ctx BN_CTX pointer for temp values are argument storage - * @param in_mont BN_MONT_CTX pointer to structure of montgomery values - * - * @pre arguments are all initialised and not NULL or zero - * @post rr_in contains evaluated result - * - * @note - */ -int BN_mod_exp_mont(rr_in,a_in,p,m,ctx,in_mont) -BIGNUM *rr_in; -BIGNUM *a_in; -BIGNUM *p; -BIGNUM *m; -BN_CTX *ctx; -BN_MONT_CTX *in_mont; - { - int i,j,k,ret=0,tos,top; - int mul,sqr,num; - BIGNUM *d,*aa,*r,*a,*t; - BN_ULONG *vall[BN_EXP_TABLE_SIZE],*dp,*rp,n0,*rr,*tmp,*np; - BN_MONT_CTX *mont=NULL; - unsigned char *str=NULL; -#ifdef BN_SURRENDER - R_SURRENDER *surrender=NULL; - int count=0; -#endif - - bn_check_top(a_in); - bn_check_top(p); - bn_check_top(m); - - if (!(m->d[0] & 1)) - { -#ifndef NO_ERR - BNerr(BN_F_BN_MOD_EXP_MONT,BN_R_CALLED_WITH_EVEN_MODULUS); -#endif - return(0); - } - - tos=ctx->tos; - - if (BN_is_zero(a_in)) - { (void)BN_zero(rr_in); return(1); } - if (BN_is_zero(p)) - { (void)BN_one(rr_in); return(1); } - if (BN_is_one(p)) - { (void)BN_copy(rr_in,a_in); return(1); } - - /* If this is not done, things will break in the montgomery - * part */ - -#if 1 - if (in_mont != NULL) - mont=in_mont; - else -#endif - { - if ((mont=BN_MONT_CTX_new()) == NULL) goto err; - if (!BN_MONT_CTX_set(mont,m,ctx)) goto err; - } - -#ifdef BN_SURRENDER - surrender=ctx->surrender; -#endif - - if (!BN_gen_exp_bits(p,&str,0,ctx)) goto err; - /* Remember this function uses another element from the passed ctx */ - ctx->tos++; - num=str[3]; - i=(BN_BITS+str[2]-1)/str[2]; - str+=4; - - - top=mont->N.top; - if ((a_in->top == top) && (a_in->d[top-1] < m->d[top-1])) - { - a=a_in; - } - else if (a_in->top < top) - { - a= &(ctx->bn[ctx->tos++]); - a->top=a_in->top; - bn_zexpand(a,top); - for (j=0; jtop; j++) - a->d[j]=a_in->d[j]; - } - else /* if (a_in->top > i) */ - { - a= &(ctx->bn[ctx->tos++]); - if (!BN_mod(a,a_in,m,ctx)) goto err; - bn_zexpand(a,top); - } - - /* At this point a is the size of the modulus and is 0 padded - * out to its size if needed. - */ - - /* Number of tmp words */ - k=num*top; - j=k+(p->top*i*2+BN_BYTES-1+4)/BN_BYTES; - - aa=&(ctx->bn[ctx->tos++]); - d= &(ctx->bn[ctx->tos++]); - r= &(ctx->bn[ctx->tos++]); - t= &(ctx->bn[ctx->tos++]); - - if (bn_wexpand(rr_in,top) == NULL) goto err; - if (bn_wexpand(d,top*4) == NULL) goto err; /* *2? */ - if (bn_wexpand(r,top*2) == NULL) goto err; - if (bn_wexpand(aa,j) == NULL) goto err; - if (bn_wexpand(t,top*2) == NULL) goto err; - dp=d->d; - rp=r->d; - tmp=t->d; - rr=mont->RR.d; - - n0=mont->n0; - np=mont->N.d; - - vall[0]=aa->d; - - bn_mul_normal(tmp,a->d,top,rr,top); - bn_from_montgomery_words(vall[0],tmp,np,top,n0); - - if (num > 1) - { - bn_sqr_normal(tmp,vall[0],top,dp); - bn_from_montgomery_words(dp,tmp,np,top,n0); - - for (i=1; i>1],sizeof(BN_ULONG)*top); - while (sqr != 0) - { -#ifdef BN_SURRENDER - /* - * Check this at the start of the loop rather than the - * end so we avoid as many of the bn operations as possible - */ - if (surrender != NULL) - { - if (surrender->callback(surrender,0xff, count++) != 0) - { - goto err; - } - } -#endif /* BN_SURRENDER */ - - /* - * check the abort flag at the start of the loop so we avoid - * as many of the bn operations as possible - */ - if (BN_CTX_get_flags(ctx, BN_CTX_FLG_ABORT)) - { - goto err; - } - - for (i=0; i>1],top); - bn_from_montgomery_words(rp,tmp,np,top,n0); - } - else - { - bn_mul_normal(tmp,rp,top,a->d,top); - bn_from_montgomery_words(rr_in->d,tmp,np,top,n0); - goto end; - } - } - - /* if (mul != 1) */ - { - for (i=top; id,rp,np,top,n0); - } -end: /* Use this to avoid an if */ - - /* - * Even if the operation has completed successfully, if the - * abort flag is set we want to abort so that anything - * calling this function will know not to continue. - */ - if (BN_CTX_get_flags(ctx, BN_CTX_FLG_ABORT)) - { - goto err; - } - - rr_in->top=top; - bn_fix_top(rr_in); - ret=1; -err: -#ifdef BN_SURRENDER - /* - * Even if the operation completed successfully we want to abort - * if the abort flag has been is set, so that subsequent operations - * do not continue. Allow the caller change to return value and - * cause the function to fail. - */ - if (surrender != NULL) - { - if (surrender->callback(surrender, 0xff, -1) != 0) - { - ret = 0; - } - } -#endif - if ((in_mont == NULL) && (mont != NULL)) BN_MONT_CTX_free(mont); - ctx->tos=tos; - return(ret); - } -/* #endif */ - diff --git a/build/tools/acsign/bn_me.c b/build/tools/acsign/bn_me.c deleted file mode 100644 index 250967c9..00000000 --- a/build/tools/acsign/bn_me.c +++ /dev/null @@ -1,251 +0,0 @@ -/* $Id$ */ -/* - * Copyright (C) 1998-2002 RSA Security Inc. All rights reserved. - * - * This work contains proprietary information of RSA Security. - * Distribution is limited to authorized licensees of RSA - * Security. Any unauthorized reproduction, distribution or - * modification of this work is strictly prohibited. - * - */ -/** - * @file bn_me.c - * @brief BN method functions and utilities - */ -#include "bn_lcl.h" -#include "bn_thx.h" - -#if !(defined(NO_SPLIT) && defined(SPLIT_FILE)) - -#ifdef NO_SPLIT -#define SPLIT_BN_MOD_EXP_METH_DEFAULT -#define SPLIT_BN_MONT_CTX_USEIT -#define SPLIT_BN_ME_CTX_NAME -#define SPLIT_BN_ME_CTX_NEW -#define SPLIT_BN_ME_CTX_FREE -#define SPLIT_BN_ME_CTX_SET -#define SPLIT_BN_ME_CTX_MOD_EXP -#endif /* NO_SPLIT */ - -#ifndef NOPROTO -BN_ME_METH *bn_mod_exp_meth_default(int fallback); -#else -BN_ME_METH *bn_mod_exp_meth_default(); -#endif - -#ifdef SPLIT_BN_MOD_EXP_METH_DEFAULT - -/** - * Returns the default mod_exp method, choose first available in the - * method table or a hardwired default - * - * @param fallback [In] Flag for choice of method - * - 0 use the first value in the method table - * - 1 use the all encompassing default method - * - * @pre BN_default_init() has been run setting up library - * - * @post - * - * @internal uses global table bnme[] and counter me_num - * - * @internal only read the BN_ME_METH_INFO table no need for locking - * - * @relates BN_library_init - * @relates BN_default_init - * @relates BN_ME_CTX_new - * @relates BN_ME_CTX_free - * - */ -BN_ME_METH *bn_mod_exp_meth_default(int fallback) -{ - const BN_ME_METH *tmp; - -#ifndef BN_LIBRARY_SMALL - BN_ME_METH_INFO *meth_info; - - if(!fallback && ((meth_info = BN_bnme_get_info(0)) != NULL)) - { - tmp = meth_info->meth(); - } - else -#endif - { - /* set in bn.h or override bn_thx.h */ - tmp = BN_ME_METH_DEFAULT(); - } - return((BN_ME_METH *)tmp); -} -#endif - -#ifdef SPLIT_BN_MONT_CTX_USEIT - -#ifndef NOPROTO -int bn_mont_ctx_useit(int argi); -#else -int bn_mont_ctx_useit(); -#endif - -/** - * Montgomery method default useit function - * - * @param argi [In] reserved for future use - * - * @return 0 success - */ -int bn_mont_ctx_useit(int argi) - { - return(0); - } -#endif - -#ifdef SPLIT_BN_ME_CTX_NAME -/** - * Retrieve the BN method name string - * - * @param ctx [In] Method - * - * @pre ctx is valid and not NULL - * - * @return string pointer - */ -char *BN_ME_CTX_name(BN_ME_CTX *ctx) - { - return(ctx->meth->name); - } -#endif - -#ifdef SPLIT_BN_ME_CTX_NEW -/** - * Allocate a new BN_ME_CTX structure and assign method - * - * @param meth [In] Method to assign - * @param in [Out] Result BN_ME_CTX - * - * @note if meth is NULL system method default is used - * - * @retval pointer to BN_ME_CTX success - * @retval NULL failure - */ -BN_ME_CTX *BN_ME_CTX_new(BN_ME_METH *meth, BN_ME_CTX **in) - { - int i; - BN_ME_CTX *ret; - - if (in == NULL) - in= &ret; - - if (meth == NULL) - meth=bn_mod_exp_meth_default(0); - i=meth->init_ctx(meth,in); - if (i) - return(NULL); - else - return(*in); - } -#endif - -#ifdef SPLIT_BN_ME_CTX_FREE -/** - * Free context method - * - * @param mctx [In] Context object to be deallocated - * - * @note it is the callers responsibility to set mctx to NULL after free - * - * @pre mctx is not NULL and is valide BN_ME_CTX - */ -void BN_ME_CTX_free(BN_ME_CTX *mctx) - { - mctx->meth->free_ctx(mctx); - } -#endif - -#ifdef SPLIT_BN_ME_CTX_SET -/** - * Set value to BN_ME_CTX by identifier - * - * @param mctx [In] Method context object - * @param b [In] Big number - * @param cmd [In] Command identifier - * @param flags [In] Mask operation directives - * @param ctx [In] BN data store - * - * @note cmd values: - * @li BN_ME_SET_MOD will cause a method lookup is method not set - * - * @note passes control to set method in mctx - * - * @return result of mctx method set operation - */ -int BN_ME_CTX_set(BN_ME_CTX *mctx, BIGNUM *b, int cmd, int flags, BN_CTX *ctx) - { -#ifndef BN_LIBRARY_SMALL -#ifndef NOPROTO - const BN_ME_METH *(*meth)(void); -#else - const BN_ME_METH *(*meth)(); -#endif -#endif /* BN_LIBRARY_SMALL */ - - /* If we are loading the modulus, and we do not have the - * no_lookup flag (without a null method) - */ - if ((cmd == BN_ME_SET_MOD) && - ((mctx->meth != NULL) && !(flags & BN_ME_SET_FLG_NO_LOOKUP))) - { -#ifndef BN_LIBRARY_SMALL - meth=(const BN_ME_METH*(*)(void)) - BN_bnme_get(BN_num_bits(b),BN_BNME_F_BITS); - if (meth != NULL) - mctx->meth=meth(); - else -#endif - mctx->meth=bn_mod_exp_meth_default(1); - } - return(mctx->meth->set(mctx,b,cmd,flags,ctx)); - } -#endif - -#ifdef SPLIT_BN_ME_CTX_MOD_EXP -/** - * Call method mod_exp operation - * - * @param mctx [In] Method context object - * @param ret [Out] Result - * @param a [In] Base value - * @param p [In] Exponent - * @param m [In] Modulus - * @param ctx [In] Data storage - * - * @pre a must be expandable - * - * @return 0 success - */ -int BN_ME_CTX_mod_exp(BN_ME_CTX *mctx, BIGNUM *ret, BIGNUM *a, BIGNUM *p, - BIGNUM *m, BN_CTX *ctx) - { - int wtop; - - /* Before we call the method, make sure we are not doing 0^p, - * and p is not 0 or 1 */ - if (BN_is_zero(a)) - { BN_zero(ret); return(0); } - if (p != NULL) - { - if (BN_is_zero(p)) - { BN_one(ret); return(0); } - else if (BN_is_one(p)) - { BN_copy(ret,a); return(0); } - } - - /* wtop is the size 'a' needs to be for the method */ - wtop=mctx->meth->num; - bn_zexpand(a,wtop); - - return(mctx->meth->mod_exp(mctx,ret,a,p,ctx)); - } -#endif - -#endif - diff --git a/build/tools/acsign/bn_mont.c b/build/tools/acsign/bn_mont.c deleted file mode 100644 index 6fc5fea4..00000000 --- a/build/tools/acsign/bn_mont.c +++ /dev/null @@ -1,231 +0,0 @@ -/* $Id$ */ -/* - * Copyright (C) 1998-2002 RSA Security Inc. All rights reserved. - * - * This work contains proprietary information of RSA Security. - * Distribution is limited to authorized licensees of RSA - * Security. Any unauthorized reproduction, distribution or - * modification of this work is strictly prohibited. - * - */ - -#undef BN_DEBUG -#include "bn_lcl.h" - -#if !(defined(NO_SPLIT) && defined(SPLIT_FILE)) - -#ifdef NO_SPLIT -#define SPLIT_BN_MOD_MUL_MONTGOMERY -#define SPLIT_BN_FROM_MONTGOMERY -#define SPLIT_BN_MONT_CTX_NEW -#define SPLIT_BN_MONT_CTX_INIT -#define SPLIT_BN_MONT_CTX_FREE -#define SPLIT_BN_MONT_CTX_COPY -#endif /* NO_SPLIT */ - -/* #define DEBUG */ - -#ifdef SPLIT_BN_MOD_MUL_MONTGOMERY -/* We multiply a by b, generating a number 2n words long. - * This is then reduced by the montogmery number, which is - * n words. */ -int BN_mod_mul_montgomery(r,a,b,mont,ctx) -BIGNUM *r,*a,*b; -BN_MONT_CTX *mont; -BN_CTX *ctx; - { - BIGNUM *tmp,*tmp2; - int ret=0,w; - int i; - - bn_check_top(a); - bn_check_top(b); - - w=mont->riw; - - tmp= &(ctx->bn[ctx->tos++]); - tmp2= &(ctx->bn[ctx->tos++]); - bn_check_top(tmp); - bn_check_top(tmp2); - if (bn_wexpand(tmp,w+w) == NULL) goto err; - if (bn_wexpand(r,w+w) == NULL) goto err; - - if (a == b) - { - if (bn_wexpand(tmp2,w+w) == NULL) goto err; -#ifdef BN_SQR_COMBA - if ((a->top == 8) && (a->top == b->top)) - bn_sqr_comba8(tmp->d,a->d); - else -#endif - { - bn_sqr_normal(tmp->d,a->d,a->top,tmp2->d); - } - } - else - { -#ifdef BN_MUL_COMBA - if (a->top == 8) - bn_mul_comba8(tmp->d,a->d,b->d); - else -#endif - { - bn_mul_normal(tmp->d,a->d,a->top,b->d,b->top); - } - } - - i=a->top+b->top; - while (i<(w+w)) - { - tmp->d[i]=0; - i++; - } - tmp->top=w+w; - tmp->neg=0; - - /* reduce from aRR to aR */ - /* tmp->d is 2w words */ -#if 0 - bn_fix_top(tmp); - BN_from_montgomery_words(r,tmp,mont,ctx); -#else - bn_from_montgomery_words(r->d,tmp->d,mont->N.d,w,mont->n0); -#endif - r->top=w; - r->neg=0; - bn_fix_top(r); - - ret=1; -err: - ctx->tos-=2; - return(ret); - } -#endif - -#ifdef SPLIT_BN_FROM_MONTGOMERY -int BN_from_montgomery(ret,a,mont,ctx) -BIGNUM *ret; -BIGNUM *a; -BN_MONT_CTX *mont; -BN_CTX *ctx; - { - BIGNUM *n,*r; - BN_ULONG *np,*rp,n0,v0,v1,*nrp; - int al,nl,max,i; - int retn=0; - - bn_check_top(a); - - r= &(ctx->bn[ctx->tos]); - - if (!BN_copy(r,a)) goto err1; - n= &(mont->N); - - /* mont->riw is the size of mont->N in bits/words */ - al=mont->riw; - - nl=n->top; - if ((al == 0) || (nl == 0)) { r->top=0; return(1); } - - max=(nl+al+1); /* allow for overflow (no?) XXX */ - if (bn_wexpand(r,max) == NULL) goto err1; - if (bn_wexpand(ret,max) == NULL) goto err1; - - r->neg=a->neg^n->neg; - np=n->d; - rp=r->d; - nrp= &(r->d[nl]); - - /* clear the top words of T */ - for (i=r->top; id[i]=0; - - r->top=max; - n0=mont->n0; - - v1=0; - for (i=0; iriw will be a multiple of the word size */ - (void)BN_rshift(ret,r,mont->riw*BN_BITS2); - - if (BN_ucmp(ret, &(mont->N)) >= 0) - { - (void)BN_usub(ret,ret,&(mont->N)); /* XXX */ - } - retn=1; - -err1: - return(retn); - } -#endif - -#ifdef SPLIT_BN_MONT_CTX_NEW -BN_MONT_CTX *BN_MONT_CTX_new() - { - BN_MONT_CTX *ret; - - if ((ret=(BN_MONT_CTX *)Malloc(sizeof(BN_MONT_CTX))) == NULL) - return(NULL); - - BN_MONT_CTX_init(ret); - ret->flags=BN_FLG_MALLOCED; - return(ret); - } -#endif - -#ifdef SPLIT_BN_MONT_CTX_INIT -void BN_MONT_CTX_init(ctx) -BN_MONT_CTX *ctx; - { - ctx->use_word=0; - ctx->riw=0; - BN_init(&(ctx->RR)); - BN_init(&(ctx->N)); - BN_init(&(ctx->Ni)); - ctx->flags=0; - } -#endif - -#ifdef SPLIT_BN_MONT_CTX_FREE -void BN_MONT_CTX_free(mont) -BN_MONT_CTX *mont; - { - BN_free(&(mont->RR)); - BN_free(&(mont->N)); - BN_free(&(mont->Ni)); - if (mont->flags & BN_FLG_MALLOCED) - Free(mont); - } -#endif - -#ifdef SPLIT_BN_MONT_CTX_COPY -BN_MONT_CTX *BN_MONT_CTX_copy(to, from) -BN_MONT_CTX *to, *from; - { - if (to == from) return(to); - - (void)BN_copy(&(to->RR),&(from->RR)); - (void)BN_copy(&(to->N),&(from->N)); - (void)BN_copy(&(to->Ni),&(from->Ni)); - bn_zexpand(&(to->RR),from->riw); - bn_zexpand(&(to->Ni),from->riw); - to->use_word=from->use_word; - to->riw=from->riw; - to->n0=from->n0; - return(to); - } -#endif - -#endif diff --git a/build/tools/acsign/bn_ms_w.c b/build/tools/acsign/bn_ms_w.c deleted file mode 100644 index 1ddd40e3..00000000 --- a/build/tools/acsign/bn_ms_w.c +++ /dev/null @@ -1,121 +0,0 @@ -/* $Id$ */ -/* - * Copyright (C) 1998-2002 RSA Security Inc. All rights reserved. - * - * This work contains proprietary information of RSA Security. - * Distribution is limited to authorized licensees of RSA - * Security. Any unauthorized reproduction, distribution or - * modification of this work is strictly prohibited. - * - */ - -#include "bn_lcl.h" - -int BN_MONT_CTX_set_word(mont,mod,ctx) -BN_MONT_CTX *mont; -BIGNUM *mod; -BN_CTX *ctx; - { - BIGNUM Ri,*R; -#if 1 - BN_ULONG tmod,rr; -#else - BN_ULONG buf[2]; - BIGNUM tmod; -#endif - - - bn_check_top(mod); - if (mod->top == 0) return(0); - - R= &(mont->RR); /* grab RR as a temp */ - if (BN_copy(&(mont->N),mod) == NULL) /* Set N */ - return(0); - - BN_init(&Ri); - - mont->use_word=1; - -/* EAY is this number of words to shift, or the number to shift to end up - * with a '1' in the next word? - * for 8 bit words, is 0x01ab == 1 or 2 - */ - mont->riw=(BN_num_bits(mod)+(BN_BITS2-1))/BN_BITS2; - if (!BN_zero(R)) return(0); - - /* We are now setting a number which is larger than our current - * one after we do the shift - */ - if (!BN_set_bit(R,BN_BITS2)) - goto err; - -#if 0 - tmod.d=buf; - tmod.top=1; - tmod.max=mod->max; - tmod.neg=mod->neg; - buf[0]=mod->d[0]&BN_MASK2; - buf[1]=0; - - if ((BN_mod_inverse(&Ri,R,&tmod,ctx)) == NULL) - goto err; -#else - tmod=mod->d[0]; - rr=BN_mod_inverse_word(tmod); - if (!BN_set_word(&Ri,rr)) - goto err; -#endif - - /* R*Ri */ - if (!BN_lshift(&Ri,&Ri,BN_BITS2)) - goto err; - - if (!BN_is_zero(&Ri)) - (void)BN_sub_word(&Ri,1); - else - { - /* This is not common..., 1 in BN_MASK2, - * It happens when buf[0] was == 1. So for 8 bit, - * this is 1/256, 16bit, 1 in 2^16 etc. - */ - if (!BN_set_word(&Ri,BN_MASK2)) - goto err; - } -#if 0 - BN_div(&Ri,NULL,&Ri,&tmod,ctx); - //BN_div_word(&Ri,tmod); - mont->n0=Ri.d[0]; -#else -#if 0 - { - BN_ULONG h,l; - - h=l=0; - if (Ri.top >= 2) h=Ri.d[1]; - if (Ri.top >= 1) l=Ri.d[0]; - mont->n0=bn_div_words(h,l,tmod); - } -#endif - mont->n0=bn_div_words( - (Ri.top >= 2)?Ri.d[1]:0, - (Ri.top >= 1)?Ri.d[0]:0, - tmod); -#endif - /* mod->top=z; */ - - /* setup RR for conversions */ - (void)BN_zero(&(mont->RR)); - if (!BN_set_bit(&(mont->RR),mont->riw*2*BN_BITS2)) - goto err; - (void)BN_mod(&(mont->RR),&(mont->RR),&(mont->N),ctx); - bn_zexpand(&(mont->RR),mont->riw); -#if 0 - bn_zexpand(&(mont->Ni),mont->riw); /*This is not used? */ -#endif - -err: - BN_free(&Ri); - return(1); - } - - diff --git a/build/tools/acsign/bn_mul.c b/build/tools/acsign/bn_mul.c deleted file mode 100644 index 4dd0e235..00000000 --- a/build/tools/acsign/bn_mul.c +++ /dev/null @@ -1,779 +0,0 @@ -/* $Id$ */ -/* - * Copyright (C) 1998-2002 RSA Security Inc. All rights reserved. - * - * This work contains proprietary information of RSA Security. - * Distribution is limited to authorized licensees of RSA - * Security. Any unauthorized reproduction, distribution or - * modification of this work is strictly prohibited. - * - */ - -#include "bn_lcl.h" - -#if !(defined(NO_SPLIT) && defined(SPLIT_FILE)) - -#ifdef NO_SPLIT -#define SPLIT_BN_MUL_RECURSIVE -#define SPLIT_BN_MUL_PART_RECURSIVE -#define SPLIT_BN_MUL_LOW_RECURSIVE -#define SPLIT_BN_MUL_HIGH -#define SPLIT_BN_MUL -#define SPLIT_BN_MUL_NORMAL -#define SPLIT_BN_MUL_LOW_NORMAL -#endif /* NO_SPLIT */ - -#ifdef SMALL_CODE_SIZE -#undef BN_RECURSION_MUL -#endif - -#ifdef BN_RECURSION_MUL -#if 0 /* Replaced by bn_mul_rec_words() */ -/* r is 2*n2 words in size, - * a and b are both n2 words in size. - * n2 must be a power of 2. - * We multiply and return the result. - * t must be 2*n2 words in size - * We calulate - * a[0]*b[0] - * a[0]*b[0]+a[1]*b[1]+(a[0]-a[1])*(b[1]-b[0]) - * a[1]*b[1] - */ -#ifdef SPLIT_BN_MUL_RECURSIVE -void bn_mul_recursive(r,a,b,n2,t) -BN_ULONG *r,*a,*b; -int n2; -BN_ULONG *t; - { - int n=n2/2,c1,c2; - unsigned int neg,zero; - BN_ULONG ln,lo,*p; - -#ifdef BN_COUNT -printf(" bn_mul_recursive %d * %d\n",n2,n2); -#endif -#ifdef BN_MUL_COMBA -/* if (n2 == 4) - { - bn_mul_comba4(r,a,b); - return; - } - else */ if (n2 == 8) - { - bn_mul_comba8(r,a,b); - return; - } -#endif - if (n2 < BN_MUL_RECURSIVE_SIZE_NORMAL) - { - /* This should not happen */ - bn_mul_normal(r,a,n2,b,n2); - return; - } - /* r=(a[0]-a[1])*(b[1]-b[0]) */ - c1=bn_cmp_words(a,&(a[n]),n); - c2=bn_cmp_words(&(b[n]),b,n); - zero=neg=0; - switch (c1*3+c2) - { - case -4: - bn_sub_words(t, &(a[n]),a, n); /* - */ - bn_sub_words(&(t[n]),b, &(b[n]),n); /* - */ - break; - case -3: - zero=1; - break; - case -2: - bn_sub_words(t, &(a[n]),a, n); /* - */ - bn_sub_words(&(t[n]),&(b[n]),b, n); /* + */ - neg=1; - break; - case -1: - case 0: - case 1: - zero=1; - break; - case 2: - bn_sub_words(t, a, &(a[n]),n); /* + */ - bn_sub_words(&(t[n]),b, &(b[n]),n); /* - */ - neg=1; - break; - case 3: - zero=1; - break; - case 4: - bn_sub_words(t, a, &(a[n]),n); - bn_sub_words(&(t[n]),&(b[n]),b, n); - break; - } - -#ifdef BN_MUL_COMBA - if (n == 4) - { - if (!zero) - bn_mul_comba4(&(t[n2]),t,&(t[n])); - else - Memset(&(t[n2]),0,8*sizeof(BN_ULONG)); - - bn_mul_comba4(r,a,b); - bn_mul_comba4(&(r[n2]),&(a[n]),&(b[n])); - } - else if (n == 8) - { - if (!zero) - bn_mul_comba8(&(t[n2]),t,&(t[n])); - else - Memset(&(t[n2]),0,16*sizeof(BN_ULONG)); - - bn_mul_comba8(r,a,b); - bn_mul_comba8(&(r[n2]),&(a[n]),&(b[n])); - } - else -#endif - { - p= &(t[n2*2]); - if (!zero) - bn_mul_recursive(&(t[n2]),t,&(t[n]),n,p); - else - Memset(&(t[n2]),0,n2*sizeof(BN_ULONG)); - bn_mul_recursive(r,a,b,n,p); - bn_mul_recursive(&(r[n2]),&(a[n]),&(b[n]),n,p); - } - - /* t[32] holds (a[0]-a[1])*(b[1]-b[0]), c1 is the sign - * r[10] holds (a[0]*b[0]) - * r[32] holds (b[1]*b[1]) - */ - - c1=(int)bn_add_words(t,r,&(r[n2]),n2); - - if (neg) /* if t[32] is negative */ - { - c1-=(int)bn_sub_words(&(t[n2]),t,&(t[n2]),n2); - } - else - { - /* Might have a carry */ - c1+=(int)bn_add_words(&(t[n2]),&(t[n2]),t,n2); - } - - /* t[32] holds (a[0]-a[1])*(b[1]-b[0])+(a[0]*b[0])+(a[1]*b[1]) - * r[10] holds (a[0]*b[0]) - * r[32] holds (b[1]*b[1]) - * c1 holds the carry bits - */ - c1+=(int)bn_add_words(&(r[n]),&(r[n]),&(t[n2]),n2); - if (c1) - { - p= &(r[n+n2]); - lo= *p; - ln=(lo+c1)&BN_MASK2; - *p=ln; - - /* The overflow will stop before we over write - * words we should not overwrite */ - if (ln < (BN_ULONG)c1) - { - do { - p++; - lo= *p; - ln=(lo+1)&BN_MASK2; - *p=ln; - } while (ln == 0); - } - } - } -#endif -#endif - -#if 0 -#ifdef SPLIT_BN_MUL_PART_RECURSIVE -/* n+tn is the word length - * t must be n*4 is size, as does r */ -void bn_mul_part_recursive(r,a,b,tn,n,t) -BN_ULONG *r,*a,*b; -int tn,n; -BN_ULONG *t; - { - int i,j,n2=n*2; - int c1; - BN_ULONG ln,lo,*p; - -#ifdef BN_COUNT -printf(" bn_mul_part_recursive %d * %d\n",tn+n,tn+n); -#endif - if (n < 8) - { - i=tn+n; - bn_mul_normal(r,a,i,b,i); - return; - } - - /* r=(a[0]-a[1])*(b[1]-b[0]) */ - bn_sub_words(t, a, &(a[n]),n); /* + */ - bn_sub_words(&(t[n]),b, &(b[n]),n); /* - */ - -#ifdef BN_MUL_COMBA -/* if (n == 4) - { - bn_mul_comba4(&(t[n2]),t,&(t[n])); - bn_mul_comba4(r,a,b); - bn_mul_normal(&(r[n2]),&(a[n]),tn,&(b[n]),tn); - Memset(&(r[n2+tn*2]),0,sizeof(BN_ULONG)*(n2-tn*2)); - } - else */ if (n == 8) - { - bn_mul_comba8(&(t[n2]),t,&(t[n])); - bn_mul_comba8(r,a,b); - bn_mul_normal(&(r[n2]),&(a[n]),tn,&(b[n]),tn); - Memset(&(r[n2+tn*2]),0,sizeof(BN_ULONG)*(n2-tn*2)); - } - else -#endif - { - p= &(t[n2*2]); - bn_mul_recursive(&(t[n2]),t,&(t[n]),n,p); - bn_mul_recursive(r,a,b,n,p); - i=n/2; - /* If there is only a bottom half to the number, - * just do it */ - j=tn-i; - if (j == 0) - { - bn_mul_recursive(&(r[n2]),&(a[n]),&(b[n]),i,p); - Memset(&(r[n2+i*2]),0,sizeof(BN_ULONG)*(n2-i*2)); - } - else if (j > 0) /* eg, n == 16, i == 8 and tn == 11 */ - { - bn_mul_part_recursive(&(r[n2]),&(a[n]),&(b[n]), - j,i,p); - Memset(&(r[n2+tn*2]),0, - sizeof(BN_ULONG)*(n2-tn*2)); - } - else /* (j < 0) eg, n == 16, i == 8 and tn == 5 */ - { - Memset(&(r[n2]),0,sizeof(BN_ULONG)*n2); - if (tn < BN_MUL_RECURSIVE_SIZE_NORMAL) - { - bn_mul_normal(&(r[n2]),&(a[n]),tn,&(b[n]),tn); - } - else - { - for (;;) - { - i/=2; - if (i < tn) - { - bn_mul_part_recursive(&(r[n2]), - &(a[n]),&(b[n]), - tn-i,i,p); - break; - } - else if (i == tn) - { - bn_mul_recursive(&(r[n2]), - &(a[n]),&(b[n]), - i,p); - break; - } - } - } - } - } - - /* t[32] holds (a[0]-a[1])*(b[1]-b[0]), c1 is the sign - * r[10] holds (a[0]*b[0]) - * r[32] holds (b[1]*b[1]) - */ - - c1=(int)bn_add_words(t,r,&(r[n2]),n2); - c1-=(int)bn_sub_words(&(t[n2]),t,&(t[n2]),n2); - - /* t[32] holds (a[0]-a[1])*(b[1]-b[0])+(a[0]*b[0])+(a[1]*b[1]) - * r[10] holds (a[0]*b[0]) - * r[32] holds (b[1]*b[1]) - * c1 holds the carry bits - */ - c1+=(int)bn_add_words(&(r[n]),&(r[n]),&(t[n2]),n2); - if (c1) - { - p= &(r[n+n2]); - lo= *p; - ln=(lo+c1)&BN_MASK2; - *p=ln; - - /* The overflow will stop before we over write - * words we should not overwrite */ - if (ln < (BN_ULONG)c1) - { - do { - p++; - lo= *p; - ln=(lo+1)&BN_MASK2; - *p=ln; - } while (ln == 0); - } - } - } -#endif -#endif - -#if 0 -#ifdef SPLIT_BN_MUL_LOW_RECURSIVE -/* a and b must be the same size, which is n2. - * r must be n2 words and t must be n2*2 - */ -void bn_mul_low_recursive(r,a,b,n2,t) -BN_ULONG *r,*a,*b; -int n2; -BN_ULONG *t; - { - int n=n2/2; - -#ifdef BN_COUNT -printf(" bn_mul_low_recursive %d * %d\n",n2,n2); -#endif - - bn_mul_recursive(r,a,b,n,&(t[0])); - if (n >= BN_MUL_LOW_RECURSIVE_SIZE_NORMAL) - { - bn_mul_low_recursive(&(t[0]),&(a[0]),&(b[n]),n,&(t[n2])); - bn_add_words(&(r[n]),&(r[n]),&(t[0]),n); - bn_mul_low_recursive(&(t[0]),&(a[n]),&(b[0]),n,&(t[n2])); - bn_add_words(&(r[n]),&(r[n]),&(t[0]),n); - } - else - { - bn_mul_low_normal(&(t[0]),&(a[0]),&(b[n]),n); - bn_mul_low_normal(&(t[n]),&(a[n]),&(b[0]),n); - bn_add_words(&(r[n]),&(r[n]),&(t[0]),n); - bn_add_words(&(r[n]),&(r[n]),&(t[n]),n); - } - } -#endif -#endif - -#ifdef SPLIT_BN_MUL_HIGH -#if 0 -/* a and b must be the same size, which is n2. - * r must be n2 words and t must be n2*2 - * l is the low words of the output. - * t must be n2*3 - */ -void bn_mul_high(r,a,b,l,n2,t) -BN_ULONG *r,*a,*b,*l; -int n2; -BN_ULONG *t; - { - int i,n; - int c1,c2; - int neg,oneg,zero; - BN_ULONG ll,lc,*lp,*mp; - -#ifdef BN_COUNT -printf(" bn_mul_high %d * %d\n",n2,n2); -#endif - n=n2/2; - - /* Calculate (al-ah)*(bh-bl) */ - neg=zero=0; - c1=bn_cmp_words(&(a[0]),&(a[n]),n); - c2=bn_cmp_words(&(b[n]),&(b[0]),n); - switch (c1*3+c2) - { - case -4: - bn_sub_words(&(r[0]),&(a[n]),&(a[0]),n); - bn_sub_words(&(r[n]),&(b[0]),&(b[n]),n); - break; - case -3: - zero=1; - break; - case -2: - bn_sub_words(&(r[0]),&(a[n]),&(a[0]),n); - bn_sub_words(&(r[n]),&(b[n]),&(b[0]),n); - neg=1; - break; - case -1: - case 0: - case 1: - zero=1; - break; - case 2: - bn_sub_words(&(r[0]),&(a[0]),&(a[n]),n); - bn_sub_words(&(r[n]),&(b[0]),&(b[n]),n); - neg=1; - break; - case 3: - zero=1; - break; - case 4: - bn_sub_words(&(r[0]),&(a[0]),&(a[n]),n); - bn_sub_words(&(r[n]),&(b[n]),&(b[0]),n); - break; - } - - oneg=neg; - /* t[10] = (a[0]-a[1])*(b[1]-b[0]) */ - /* r[10] = (a[1]*b[1]) */ -#ifdef BN_MUL_COMBA - if (n == 8) - { - bn_mul_comba8(&(t[0]),&(r[0]),&(r[n])); - bn_mul_comba8(r,&(a[n]),&(b[n])); - } - else -#endif - { -#ifdef BN_MUL_RECURSION - bn_mul_recursive(&(t[0]),&(r[0]),&(r[n]),n,&(t[n2])); - bn_mul_recursive(r,&(a[n]),&(b[n]),n,&(t[n2])); -#else - bn_mul_normal(&(t[0]),&(r[0]),n,&(r[n]),n); - bn_mul_normal(r,&(a[n]),n,&(b[n]),n); -#endif - } - - /* s0 == low(al*bl) - * s1 == low(ah*bh)+low((al-ah)*(bh-bl))+low(al*bl)+high(al*bl) - * We know s0 and s1 so the only unknown is high(al*bl) - * high(al*bl) == s1 - low(ah*bh+s0+(al-ah)*(bh-bl)) - * high(al*bl) == s1 - (r[0]+l[0]+t[0]) - */ - if (l != NULL) - { - lp= &(t[n2+n]); - c1=(int)bn_add_words(lp,&(r[0]),&(l[0]),n); - } - else - { - c1=0; - lp= &(r[0]); - } - - if (neg) - neg=(int)bn_sub_words(&(t[n2]),lp,&(t[0]),n); - else - { - bn_add_words(&(t[n2]),lp,&(t[0]),n); - neg=0; - } - - if (l != NULL) - { - bn_sub_words(&(t[n2+n]),&(l[n]),&(t[n2]),n); - } - else - { - lp= &(t[n2+n]); - mp= &(t[n2]); - for (i=0; i 0) - { - lc=c1; - do { - ll=(r[i]+lc)&BN_MASK2; - r[i++]=ll; - lc=(lc > ll); - } while (lc); - } - else - { - lc= -c1; - do { - ll=r[i]; - r[i++]=(ll-lc)&BN_MASK2; - lc=(lc > ll); - } while (lc); - } - } - if (c2 != 0) /* Add starting at r[1] */ - { - i=n; - if (c2 > 0) - { - lc=c2; - do { - ll=(r[i]+lc)&BN_MASK2; - r[i++]=ll; - lc=(lc > ll); - } while (lc); - } - else - { - lc= -c2; - do { - ll=r[i]; - r[i++]=(ll-lc)&BN_MASK2; - lc=(lc > ll); - } while (lc); - } - } - } -#endif -#endif -#endif - -#ifdef SPLIT_BN_MUL -int BN_mul(r,a,b,ctx) -BIGNUM *r,*a,*b; -BN_CTX *ctx; - { - int top,al,bl,neg; - BIGNUM *rr; -#ifdef BN_RECURSION_MUL - BIGNUM *t; - int i,j,k,l; -#endif - -#ifdef BN_COUNT -printf("BN_mul %d * %d\n",a->top,b->top); -#endif - - bn_check_top(a); - bn_check_top(b); - bn_check_top(r); - - al=a->top; - bl=b->top; - - if ((al == 0) || (bl == 0)) - { - (void)BN_zero(r); - return(1); - } - top=al+bl; - neg=a->neg^b->neg; - - if ((r == a) || (r == b)) - rr= &(ctx->bn[ctx->tos+1]); - else - rr=r; - - if (bn_wexpand(rr,top) == NULL) return(0); - rr->top=top; - -#if defined(BN_MUL_COMBA) || defined(BN_RECURSION_MUL) - if (al == bl) - { -# ifdef BN_MUL_COMBA -/* if (al == 4) - { - bn_mul_comba4(rr->d,a->d,b->d); - goto end; - } - else */ if (al == 8) - { - bn_mul_comba8(rr->d,a->d,b->d); - goto end; - } - else -# endif -#ifdef BN_RECURSION_MUL - if (al < BN_MULL_SIZE_NORMAL) -#endif - { - bn_mul_normal(rr->d,a->d,al,b->d,bl); - goto end; - } -# ifdef BN_RECURSION_MUL - goto symetric; -# endif - } -#endif -#ifdef BN_RECURSION_MUL - else if ((al < BN_MULL_SIZE_NORMAL) || (bl < BN_MULL_SIZE_NORMAL)) - { - bn_mul_normal(rr->d,a->d,al,b->d,bl); - goto end; - } - else - { - i=(al-bl); - if ((i == 1) && !BN_get_flags(b,BN_FLG_STATIC_DATA)) - { - bn_wexpand(b,al); - b->d[bl]=0; - bl++; - goto symetric; - } - else if ((i == -1) && !BN_get_flags(a,BN_FLG_STATIC_DATA)) - { - bn_wexpand(a,bl); - a->d[al]=0; - al++; - goto symetric; - } - } -#endif - -#ifdef BN_RECURSION_MUL -normal_mul: -#endif - bn_mul_normal(rr->d,a->d,al,b->d,bl); - -#ifdef BN_RECURSION_MUL - if (0) - { -symetric: - /* symetric and > 4 */ - /* 16 or larger */ - l=BN_num_bits_word((BN_ULONG)al); - j=1<<(l-1); - k=j+j; - t= &(ctx->bn[ctx->tos]); - if (al == j) /* exact multiple */ - { - BN_REC rec; - rec.depth=l-5; - rec.n=j; - rec.mul=bn_mul_comba8; - rec.sqr=bn_sqr_comba8; - if (bn_wexpand(t,k+k) == NULL) - return(0); - if (bn_wexpand(rr,k) == NULL) - return(0); - bn_mul_rec_words(rr->d,a->d,b->d,t->d,&rec); - } - else - goto normal_mul; -#if 0 - { - bn_zexpand(a,k); - bn_zexpand(b,k); - bn_wexpand(t,k); - bn_wexpand(rr,k); - bn_mul_part_recursive(rr->d,a->d,b->d,al-j,j,t->d); - } -#endif - } -#endif -#if defined(BN_MUL_COMBA) || defined(BN_RECURSION_MUL) -end: -#endif - - r->neg=neg; - bn_fix_top(rr); - if (r != rr) (void)BN_copy(r,rr); - return(1); - } -#endif - - -#ifdef SPLIT_BN_MUL_NORMAL -void bn_mul_normal(r,a,na,b,nb) -BN_ULONG *r,*a; -int na; -BN_ULONG *b; -int nb; - { - BN_ULONG *rr; - -#ifdef BN_COUNT -printf(" bn_mul_normal %d * %d\n",na,nb); -#endif - /* asymetric and >= 4 */ -#if 0 - if ((na == nb) && (na == 8)) - { - bn_mul_normal(r,a,na,b,nb); - return; - } -#endif - - if (na < nb) - { - int itmp; - BN_ULONG *ltmp; - - itmp=na; na=nb; nb=itmp; - ltmp=a; a=b; b=ltmp; - - } - rr= &(r[na]); - rr[0]=bn_mul_words(r,a,na,b[0]); - - for (;;) - { - if (--nb <= 0) return; - rr[1]=bn_mul_add_words(&(r[1]),a,na,b[1]); - if (--nb <= 0) return; - rr[2]=bn_mul_add_words(&(r[2]),a,na,b[2]); - if (--nb <= 0) return; - rr[3]=bn_mul_add_words(&(r[3]),a,na,b[3]); - if (--nb <= 0) return; - rr[4]=bn_mul_add_words(&(r[4]),a,na,b[4]); - rr+=4; - r+=4; - b+=4; - } - } -#endif - -#ifdef SPLIT_BN_MUL_LOW_NORMAL -void bn_mul_low_normal(r,a,b,n) -BN_ULONG *r,*a,*b; -int n; - { -#ifdef BN_COUNT -printf(" bn_mul_low_normal %d * %d\n",n,n); -#endif - (void)bn_mul_words(r,a,n,b[0]); - - for (;;) - { - if (--n <= 0) return; - (void)bn_mul_add_words(&(r[1]),a,n,b[1]); - if (--n <= 0) return; - (void)bn_mul_add_words(&(r[2]),a,n,b[2]); - if (--n <= 0) return; - (void)bn_mul_add_words(&(r[3]),a,n,b[3]); - if (--n <= 0) return; - (void)bn_mul_add_words(&(r[4]),a,n,b[4]); - r+=4; - b+=4; - } - } -#endif -#endif diff --git a/build/tools/acsign/bn_r_exp.c b/build/tools/acsign/bn_r_exp.c deleted file mode 100644 index 9465e402..00000000 --- a/build/tools/acsign/bn_r_exp.c +++ /dev/null @@ -1,134 +0,0 @@ -/* $Id$ */ -/* - * Copyright (C) 1998-2002 RSA Security Inc. All rights reserved. - * - * This work contains proprietary information of RSA Security. - * Distribution is limited to authorized licensees of RSA - * Security. Any unauthorized reproduction, distribution or - * modification of this work is strictly prohibited. - * - */ - -#include "bn_lcl.h" - -/* #ifdef RECP_MUL_MOD */ -int BN_mod_exp_recp(r,a,p,m,ctx) -BIGNUM *r; -BIGNUM *a; -BIGNUM *p; -BIGNUM *m; -BN_CTX *ctx; - { - int i,j,bits,ret=0,wstart,wend,window,wvalue; - int start=1,ts=0; - BIGNUM *aa; - BIGNUM val[BN_EXP_TABLE_SIZE]; - BN_RECP_CTX recp; - - bits=BN_num_bits(p); - - if (BN_is_zero(a)) - { (void)BN_zero(r); return(1); } - if (BN_is_zero(p)) - { (void)BN_one(r); return(1); } - if (BN_is_one(p)) - { (void)BN_copy(r,a); return(1); } - - BN_RECP_CTX_init(&recp); - if (BN_RECP_CTX_set(&recp,m,ctx) <= 0) goto err; - - BN_init(&(val[0])); - ts=1; - - aa= &(ctx->bn[ctx->tos++]); - - if (!BN_mod(&(val[0]),a,m,ctx)) goto err; /* 1 */ - if (!BN_mod_mul_reciprocal(aa,&(val[0]),&(val[0]),&recp,ctx)) - goto err; /* 2 */ - - if (bits <= 17) /* This is probably 3 or 0x10001, so just do singles */ - window=1; - else if (bits >= 256) - window=5; /* max size of window */ - else if (bits >= 128) - window=4; - else - window=3; - - j=1<<(window-1); - for (i=1; i>1]),&recp,ctx)) - goto err; - - /* move the 'window' down further */ - wstart-=wend+1; - wvalue=0; - start=0; - if (wstart < 0) break; - } - ret=1; -err: - ctx->tos--; - for (i=0; in; - int n2=n/2; - int c1,neg=0; - - - if (rec->depth == 0) - { - /* t needs to have space for 4*n words - * The multiply needs to be a n2*n2 -> n - */ -#ifndef NOPROTO - void (PRE_CCONV CCONV *rmul)(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b); -#else - void (PRE_CCONV CCONV *rmul)(); -#endif - rmul=rec->mul; - -#ifdef _EXTRA_ARG_ - /* THIS IS WRONG - there is no extra int arg on the end */ - rmul(&(r[0]),&(a[0]),&(b[0]),n2); - rmul(&(r[n]),&(a[n2]),&(b[n2]),n2); -#else - rmul(&(r[0]),&(a[0]),&(b[0])); - rmul(&(r[n]),&(a[n2]),&(b[n2])); -#endif - - if (bn_sub_words(&(tt[n+0]), &(a[0]),&(a[n2]),n2)) - { - bn_2s_comp(&(tt[n+ 0]),&(tt[n+ 0]),n2); - neg=1; - } - else - neg=0; - if (bn_sub_words(&(tt[n+n2]),&(b[n2]),&(b[0]),n2)) - { - neg^=1; - bn_2s_comp(&(tt[n+n2]),&(tt[n+n2]),n2); - } - -#ifdef _EXTRA_ARG_ - rmul(&(tt[0]),&(tt[n+0]),&(tt[n+n2]),n2); -#else - rmul(&(tt[0]),&(tt[n+0]),&(tt[n+n2])); -#endif - } - else /* Leaf node */ - { - /* t has 4*n words taken per call. - * Since n is half the size per call, we need - * 6*n words for our current level and all sub levels - * The multiply needs to be a n2*n2 -> n - */ - rec->depth--; - rec->n=n2; - bn_mul_rec_words(&(r[0]), &(a[0]), &(b[0]), &(tt[n+n]),rec); - bn_mul_rec_words(&(r[n]), &(a[n2]),&(b[n2]), &(tt[n+n]),rec); - - neg=0; - if (bn_sub_words(&(tt[n+0]), &(a[0]),&(a[n2]),n2)) - { - bn_2s_comp(&(tt[n+ 0]),&(tt[n+ 0]),n2); - neg=1; - } - else - neg=0; - if (bn_sub_words(&(tt[n+n2]),&(b[n2]),&(b[0]),n2)) - { - neg^=1; - bn_2s_comp(&(tt[n+n2]),&(tt[n+n2]),n2); - } - - bn_mul_rec_words(&(tt[0]),&(tt[n]),&(tt[n+n2]),&(tt[n+n]),rec); - rec->n=n; - rec->depth++; - } - - c1=bn_add_words(&(tt[n]),&(r[0]),&(r[n]),n); - - if (neg) - c1-=bn_sub_words(&(tt[0]),&(tt[n]),&(tt[0]),n); - else - c1+=bn_add_words(&(tt[0]),&(tt[n]),&(tt[0]),n); - tt[n]=c1; - c1=bn_add_words(&(r[n2]),&(r[n2]),&(tt[0]),n+1); - if (c1) - { - tt= &(r[n+n2+1]); - do { - } while (++(*(tt++)) == 0); - } - } -#endif - -#ifdef SPLIT_BN_SQR_REC_WORDS -/* tt needs to be 3*n words */ -void bn_sqr_rec_words(r,a,tt,rec) -BN_ULONG *r,*a,*tt; -BN_REC *rec; - { - int n=rec->n; - int n2=n/2; - int c1; - - if (rec->depth == 0) - { - /* t needs to have space for 4*n words - * The multiply needs to be a n2*n2 -> n - */ -#ifndef NOPROTO - void (PRE_CCONV CCONV *rsqr)(BN_ULONG *r, BN_ULONG *a); -#else - void (PRE_CCONV CCONV *rsqr)(); -#endif - - rsqr=rec->sqr; - -#ifdef _EXTRA_ARG_ - /* THIS IS WRONG - there is no extra int arg on the end */ - rsqr(&(r[0]), &(a[0]), n2); - rsqr(&(r[n]), &(a[n2]),n2); -#else - rsqr(&(r[0]), &(a[0])); - rsqr(&(r[n]), &(a[n2])); -#endif - - if (bn_sub_words(&(tt[n+0]), &(a[0]),&(a[n2]),n2)) - bn_2s_comp(&(tt[n+0]),&tt[n+0], n2); - -#ifdef _EXTRA_ARG_ - rsqr(&(tt[0]),&(tt[n]), n2); -#else - rsqr(&(tt[0]),&(tt[n])); -#endif - - } - else /* Leaf node */ - { - /* t has 4*n words taken per call. - * Since n is half the size per call, we need - * 6*n words for our current level and all sub levels - * The multiply needs to be a n2*n2 -> n - */ - rec->depth--; - rec->n=n2; - bn_sqr_rec_words(&(r[0]), &(a[0]), &(tt[n+n]),rec); - bn_sqr_rec_words(&(r[n]), &(a[n2]),&(tt[n+n]),rec); - - if (bn_sub_words(&(tt[n+0]), &(a[0]),&(a[n2]),n2)) - bn_2s_comp(&(tt[n+0]),&tt[n+0], n2); - bn_sqr_rec_words(&(tt[0]),&(tt[n]),&(tt[n+n]),rec); - - rec->n=n; - rec->depth++; - } - - c1=bn_add_words(&(tt[n]),&(r[0]),&(r[n]),n); - c1-=bn_sub_words(&(tt[0]),&(tt[n]),&(tt[0]),n); - - tt[n]=c1; - c1=bn_add_words(&(r[n2]),&(r[n2]),&(tt[0]),n+1); - if (c1) - { - tt= &(r[n+n2+1]); - do { - } while (++(*(tt++)) == 0); - } - } -#endif - -#endif /* !NO_SPLIT || !SPLIT_FILE */ diff --git a/build/tools/acsign/bn_recp.c b/build/tools/acsign/bn_recp.c deleted file mode 100644 index e762a819..00000000 --- a/build/tools/acsign/bn_recp.c +++ /dev/null @@ -1,202 +0,0 @@ -/* $Id$ */ -/* - * Copyright (C) 1998-2002 RSA Security Inc. All rights reserved. - * - * This work contains proprietary information of RSA Security. - * Distribution is limited to authorized licensees of RSA - * Security. Any unauthorized reproduction, distribution or - * modification of this work is strictly prohibited. - * - */ - -#include "bn_lcl.h" - -void BN_RECP_CTX_init(recp) -BN_RECP_CTX *recp; - { - BN_init(&(recp->N)); - BN_init(&(recp->Nr)); - recp->num_bits=0; - recp->flags=0; - } - -BN_RECP_CTX *BN_RECP_CTX_new() - { - BN_RECP_CTX *ret; - - if ((ret=(BN_RECP_CTX *)Malloc(sizeof(BN_RECP_CTX))) == NULL) - return(NULL); - - BN_RECP_CTX_init(ret); - ret->flags=BN_FLG_MALLOCED; - return(ret); - } - -void BN_RECP_CTX_free(recp) -BN_RECP_CTX *recp; - { - BN_free(&(recp->N)); - BN_free(&(recp->Nr)); - if (recp->flags & BN_FLG_MALLOCED) - Free(recp); - } - -int BN_RECP_CTX_set(recp,d,ctx) -BN_RECP_CTX *recp; -BIGNUM *d; -BN_CTX *ctx; - { - (void)BN_copy(&(recp->N),d); - (void)BN_zero(&(recp->Nr)); - recp->num_bits=BN_num_bits(d); - recp->shift=0; - ctx=ctx; /* Stop warning */ - return(1); - } - -int BN_mod_mul_reciprocal(r, x, y, recp, ctx) -BIGNUM *r; -BIGNUM *x; -BIGNUM *y; -BN_RECP_CTX *recp; -BN_CTX *ctx; - { - int ret=0; - BIGNUM *a; - - bn_check_top(x); - bn_check_top(y); - - a= &(ctx->bn[ctx->tos++]); - if (y != NULL) - { - if (x == y) - { if (!BN_sqr(a,x,ctx)) goto err; } - else - { if (!BN_mul(a,x,y,ctx)) goto err; } - } - else - a=x; /* Just do the mod */ - - (void)BN_div_recp(NULL,r,a,recp,ctx); - ret=1; -err: - ctx->tos--; - return(ret); - } - -int BN_div_recp(dv,rem,m,recp,ctx) -BIGNUM *dv; -BIGNUM *rem; -BIGNUM *m; -BN_RECP_CTX *recp; -BN_CTX *ctx; - { - int i,j,tos,ret=0,ex; - BIGNUM *a,*b,*d,*r; - - bn_check_top(m); - - tos=ctx->tos; - a= &(ctx->bn[ctx->tos++]); - b= &(ctx->bn[ctx->tos++]); - if (dv != NULL) - d=dv; - else - d= &(ctx->bn[ctx->tos++]); - if (rem != NULL) - r=rem; - else - r= &(ctx->bn[ctx->tos++]); - - if (BN_ucmp(m,&(recp->N)) < 0) - { - (void)BN_zero(d); - (void)BN_copy(r,m); - ctx->tos=tos; - return(1); - } - - /* We want the remainder - * Given input of ABCDEF / ab - * we need multiply ABCDEF by 3 digests of the reciprocal of ab - * - */ - i=BN_num_bits(m); - - j=recp->num_bits*2; - if (j > i) - { - i=j; - ex=0; - } - else - { - ex=(i-j)/2; - } - - j=i/2; - - if (i != recp->shift) - recp->shift=BN_reciprocal(&(recp->Nr),&(recp->N), - i,ctx); - - if (!BN_rshift(a,m,j-ex)) goto err; - if (!BN_mul(b,a,&(recp->Nr),ctx)) goto err; - if (!BN_rshift(d,b,j+ex)) goto err; - d->neg=0; - if (!BN_mul(b,&(recp->N),d,ctx)) goto err; - if (!BN_usub(r,m,b)) goto err; - r->neg=0; - - j=0; -#if 1 - while (BN_ucmp(r,&(recp->N)) >= 0) - { - if (j++ > 2) - { -#ifndef NO_ERR - BNerr(BN_F_BN_DIV_RECP,BN_R_BAD_RECIPROCAL); -#endif - goto err; - } - if (!BN_usub(r,r,&(recp->N))) goto err; - if (!BN_add_word(d,1)) goto err; - } -#endif - - r->neg=BN_is_zero(r)?0:m->neg; - d->neg=m->neg^recp->N.neg; - ret=1; -err: - ctx->tos=tos; - return(ret); - } - -/* len is the expected size of the result - * We actually calculate with an extra word of precision, so - * we can do faster division if the remainder is not required. - */ -int BN_reciprocal(r,m,len,ctx) -BIGNUM *r; -BIGNUM *m; -int len; -BN_CTX *ctx; - { - int ret= -1; - BIGNUM t; - - bn_check_top(m); - - BN_init(&t); - - (void)BN_zero(&t); - if (!BN_set_bit(&t,len)) goto err; - - if (!BN_div(r,NULL,&t,m,ctx)) goto err; - ret=len; -err: - BN_free(&t); - return(ret); - } - diff --git a/build/tools/acsign/bn_rsh.c b/build/tools/acsign/bn_rsh.c deleted file mode 100644 index 909cd9a1..00000000 --- a/build/tools/acsign/bn_rsh.c +++ /dev/null @@ -1,123 +0,0 @@ -/* $Id$ */ -/* - * Copyright (C) 1998-2002 RSA Security Inc. All rights reserved. - * - * This work contains proprietary information of RSA Security. - * Distribution is limited to authorized licensees of RSA - * Security. Any unauthorized reproduction, distribution or - * modification of this work is strictly prohibited. - * - */ - -#include "bn_lcl.h" - -#if !(defined(NO_SPLIT) && defined(SPLIT_FILE)) - -#ifdef NO_SPLIT -#define SPLIT_BN_RSHIFT1 -#define SPLIT_BN_RSHIFT -#endif /* NO_SPLIT */ - -#ifdef SPLIT_BN_RSHIFT1 -#ifdef SMALL_CODE_SIZE -int BN_rshift1(r, a) -BIGNUM *r; -BIGNUM *a; - { - return(BN_rshift(r,a,1)); - } - -#else - -int BN_rshift1(r, a) -BIGNUM *r; -BIGNUM *a; - { - BN_ULONG *ap,*rp,t,c; - int i; - - bn_check_top(a); - - if (BN_is_zero(a)) - { - BN_zero(r); - return(1); - } - if (a != r) - { - if (bn_wexpand(r,a->top) == NULL) return(0); - r->top=a->top; - r->neg=a->neg; - } - ap=a->d; - rp=r->d; - c=0; - for (i=a->top-1; i>=0; i--) - { - t=ap[i]; - rp[i]=((t>>1)&BN_MASK2)|c; - c=(t&1)?BN_TBIT:0; - } - bn_fix_top(r); - return(1); - } -#endif -#endif - -#ifdef SPLIT_BN_RSHIFT -int BN_rshift(r, a, n) -BIGNUM *r; -BIGNUM *a; -int n; - { - int i,j,nw,lb,rb; - BN_ULONG *t,*f; - BN_ULONG l,tmp; - - bn_check_top(a); - -#ifndef SMALL_CODE_SIZE - if (n == 1) return(BN_rshift1(r,a)); -#endif - nw=n/BN_BITS2; - rb=n%BN_BITS2; - lb=BN_BITS2-rb; - if (nw > a->top) - { - (void)BN_zero(r); - return(1); - } - if (r != a) - { - if (bn_wexpand(r,a->top-nw+1+1/*???*/) == NULL) return(0); - r->neg=a->neg; - } - - f= &(a->d[nw]); - t=r->d; - j=a->top-nw; - r->top=j; - - if (rb == 0) - { - for (i=j+1; i > 0; i--) - *(t++)= *(f++); - } - else - { - l= *(f++); - for (i=1; i>rb)&BN_MASK2; - l= *(f++); - *(t++) =(tmp|(l<>rb)&BN_MASK2; - *t=0; - } - bn_fix_top(r); - return(1); - } -#endif - -#endif diff --git a/build/tools/acsign/bn_sqr.c b/build/tools/acsign/bn_sqr.c deleted file mode 100644 index 4762cd9d..00000000 --- a/build/tools/acsign/bn_sqr.c +++ /dev/null @@ -1,273 +0,0 @@ -/* $Id$ */ -/* - * Copyright (C) 1998-2002 RSA Security Inc. All rights reserved. - * - * This work contains proprietary information of RSA Security. - * Distribution is limited to authorized licensees of RSA - * Security. Any unauthorized reproduction, distribution or - * modification of this work is strictly prohibited. - * - */ - -#include "bn_lcl.h" - -#ifdef SMALL_CODE_SIZE -#undef BN_RECURSION_SQR -#endif - -#if !(defined(NO_SPLIT) && defined(SPLIT_FILE)) - -#ifdef NO_SPLIT -#define SPLIT_BN_SQR -#define SPLIT_BN_SQR_NORMAL -#define SPLIT_BN_RECURSION_SQR -#endif /* NO_SPLIT */ - -#ifdef SPLIT_BN_SQR -/* r must not be a */ -int BN_sqr(r, a, ctx) -BIGNUM *r; -BIGNUM *a; -BN_CTX *ctx; - { - int max,al; - BIGNUM *tmp,*rr; - -#ifdef BN_COUNT -printf("BN_sqr %d * %d\n",a->top,a->top); -#endif - bn_check_top(a); - tmp= &(ctx->bn[ctx->tos]); - rr=(a != r)?r: (&ctx->bn[ctx->tos+1]); - - al=a->top; - if (al <= 0) - { - r->top=0; - return(1); - } - - max=(al+al); - if (bn_wexpand(rr,max) == NULL) return(0); - - rr->top=max; - rr->neg=0; - - if (al == 4) - { -#ifndef BN_SQR_COMBA - BN_ULONG t[8]; - bn_sqr_normal(rr->d,a->d,4,t); -#else - bn_sqr_comba4(rr->d,a->d); -#endif - } - else if (al == 8) - { -#ifndef BN_SQR_COMBA - BN_ULONG t[16]; - bn_sqr_normal(rr->d,a->d,8,t); -#else - bn_sqr_comba8(rr->d,a->d); -#endif - } - else - { -#if 1 && defined(BN_RECURSION_SQR) - if (al < BN_SQR_RECURSIVE_SIZE_NORMAL) - { - BN_ULONG t[BN_SQR_RECURSIVE_SIZE_NORMAL*2]; - bn_sqr_normal(rr->d,a->d,al,t); - } - else - { - int j,l,k; - - l=BN_num_bits_word((BN_ULONG)al); - j=1<<(l-1); - k=j+j; - if ((al == j) && !BN_get_flags(a,BN_FLG_STATIC_DATA)) - { - BN_REC rec; - if (bn_wexpand(tmp,k*2) == NULL) return(0); - rec.depth=l-5; - rec.n=j; - rec.mul=bn_mul_comba8; - rec.sqr=bn_sqr_comba8; - - bn_sqr_rec_words(rr->d,a->d,tmp->d,&rec); - } - else - { - if (bn_wexpand(tmp,max) == NULL) return(0); - bn_assert(al*2 <= max); - bn_sqr_normal(rr->d,a->d,al,tmp->d); - } - } -#else - if (bn_wexpand(tmp,max) == NULL) return(0); - bn_assert(al*2 <= max); - bn_sqr_normal(rr->d,a->d,al,tmp->d); -#endif -#ifdef BN_DEBUG - tmp->top=0; -#endif - } - - if ((max > 0) && (rr->d[max-1] == 0)) rr->top--; - if (rr != r) (void)BN_copy(r,rr); - return(1); - } -#endif - -#ifdef SPLIT_BN_SQR_NORMAL -/* tmp must have 2*n words */ -void bn_sqr_normal(r, a, n, tmp) -BN_ULONG *r; -BN_ULONG *a; -int n; -BN_ULONG *tmp; - { - int i,j,max; - BN_ULONG *ap,*rp,m; - - max=n*2; - ap=a; - rp=r; - rp[0]=rp[max-1]=0; - rp++; - j=n; - - if (--j > 0) - { - m= (*ap++); - rp[j]=bn_mul_words(rp,ap,j,m); - rp+=2; - } - - for (i=n-2; i>0; i--) - { - j--; - m= *(ap++); - rp[j]=bn_mul_add_words(rp,ap,j,m); - rp+=2; - } - - (void)bn_add_words(r,r,r,max); - - /* There will not be a carry */ - - bn_sqr_words(tmp,a,n); - - (void)bn_add_words(r,r,tmp,max); - } -#endif - -#if 0 /* replaced by bn_sqr_rec_words() AND this has bugs */ -#ifdef SPLIT_BN_RECURSION_SQR -#ifdef BN_RECURSION_SQR -/* r is 2*n words in size, - * a and b are both n words in size. - * n must be a power of 2. - * We multiply and return the result. - * t must be 2*n words in size - * We calulate - * a[0]*b[0] - * a[0]*b[0]+a[1]*b[1]+(a[0]-a[1])*(b[1]-b[0]) - * a[1]*b[1] - */ -void bn_sqr_recursive(r,a,n2,t) -BN_ULONG *r,*a; -int n2; -BN_ULONG *t; - { - int n=n2/2; - int zero,c1; - BN_ULONG ln,lo,*p; - -#ifdef BN_COUNT -printf(" bn_sqr_recursive %d * %d\n",n2,n2); -#endif - if (n2 == 4) - { -#ifndef BN_SQR_COMBA - bn_sqr_normal(r,a,4,t); -#else - bn_sqr_comba4(r,a); -#endif - return; - } - else if (n2 == 8) - { -#ifndef BN_SQR_COMBA - bn_sqr_normal(r,a,8,t); -#else - bn_sqr_comba8(r,a); -#endif - return; - } - if (n2 < BN_SQR_RECURSIVE_SIZE_NORMAL) - { - bn_sqr_normal(r,a,n2,t); - return; - } - /* r=(a[0]-a[1])*(a[1]-a[0]) */ - c1=bn_cmp_words(a,&(a[n]),n); - zero=0; - if (c1 > 0) - bn_sub_words(t,a,&(a[n]),n); - else if (c1 < 0) - bn_sub_words(t,&(a[n]),a,n); - else - zero=1; - - /* The result will always be negative unless it is zero */ - p= &(t[n2*2]); - - if (!zero) - bn_sqr_recursive(&(t[n2]),t,n,p); - else - Memset(&(t[n2]),0,n*sizeof(BN_ULONG)); - bn_sqr_recursive(r,a,n,p); - bn_sqr_recursive(&(r[n2]),&(a[n]),n,p); - - /* t[32] holds (a[0]-a[1])*(a[1]-a[0]), it is negative or zero - * r[10] holds (a[0]*b[0]) - * r[32] holds (b[1]*b[1]) - */ - - c1=(int)(bn_add_words(t,r,&(r[n2]),n2)); - - /* t[32] is negative */ - c1-=(int)(bn_sub_words(&(t[n2]),t,&(t[n2]),n2)); - - /* t[32] holds (a[0]-a[1])*(a[1]-a[0])+(a[0]*a[0])+(a[1]*a[1]) - * r[10] holds (a[0]*a[0]) - * r[32] holds (a[1]*a[1]) - * c1 holds the carry bits - */ - c1+=(int)(bn_add_words(&(r[n]),&(r[n]),&(t[n2]),n2)); - if (c1) - { - p= &(r[n+n2]); - lo= *p; - ln=(lo+c1)&BN_MASK2; - *p=ln; - - /* The overflow will stop before we over write - * words we should not overwrite */ - if (ln < (BN_ULONG)c1) - { - do { - p++; - lo= *p; - ln=(lo+1)&BN_MASK2; - *p=ln; - } while (ln == 0); - } - } - } -#endif -#endif -#endif -#endif diff --git a/build/tools/acsign/bn_wdiv.c b/build/tools/acsign/bn_wdiv.c deleted file mode 100644 index d76752a4..00000000 --- a/build/tools/acsign/bn_wdiv.c +++ /dev/null @@ -1,100 +0,0 @@ -/* $Id$ */ -/* - * Copyright (C) 1998-2002 RSA Security Inc. All rights reserved. - * - * This work contains proprietary information of RSA Security. - * Distribution is limited to authorized licensees of RSA - * Security. Any unauthorized reproduction, distribution or - * modification of this work is strictly prohibited. - * - */ - -#include "bn_lcl.h" - -#ifndef OPT_BN_ASM - -#ifndef BN_DIV_WORDS -#define BN_DIV_WORDS -#endif - -#endif - -#ifdef BN_DIV_WORDS -#if defined(BN_LLONG) -BN_ULONG bn_div_words(h,l,d) -BN_ULONG h,l,d; - { - return((BN_ULONG)(((((BN_ULLONG)h)< ((BN_ULONG)1)<= d) h-=d; - - if (i) - { - d=(d<>(BN_BITS2-i)))&BN_MASK2; - l=(l<>BN_BITS4)&BN_MASK2lh; - dl=(d&BN_MASK2l); - for (;;) - { - if ((h>>BN_BITS4) == dh) - q=BN_MASK2l; - else - q=h/dh; - - for (;;) - { - t=(h-q*dh)&BN_MASK2; - if ((t&BN_MASK2h) || - (((dl*q)&BN_MASK2) <= (( - (t<>BN_BITS4)&BN_MASK2lh))&BN_MASK2))) - break; - q--; - } - th=(q*dh)&BN_MASK2; - tl=(q*dl)&BN_MASK2; - t=(tl>>BN_BITS4); - tl=(tl&BN_MASK2lh)<>BN_BITS4))&BN_MASK2; - l=(l&BN_MASK2l)<top-1; i>=0; i--) - { -#ifndef BN_LLONG - ret=((ret<d[i]>>BN_BITS4)&BN_MASK2l))%w; - ret=((ret<d[i]&BN_MASK2l))%w; -#else - ret=(BN_ULLONG)(((ret<<(BN_ULLONG)BN_BITS2)|a->d[i])% - (BN_ULLONG)w); -#endif - } - return((BN_ULONG)ret); - } -#endif - -#ifdef SPLIT_BN_DIV_WORD -BN_ULONG BN_div_word(a, w) -BIGNUM *a; -BN_ULONG w; - { - BN_ULONG ret; - int i; - - if (a->top == 0) return(0); - ret=0; - w=w&BN_MASK2;//w&=BN_MASK2; - for (i=a->top-1; i>=0; i--) - { - BN_ULONG l,d; - - l=a->d[i]; - d=bn_div_words(ret,l,w); - ret=(l-((d*w)&BN_MASK2))&BN_MASK2; - a->d[i]=d; - } - if ((a->top > 0) && (a->d[a->top-1] == 0)) - a->top--; - return(ret); - } -#endif - -#ifdef SPLIT_BN_ADD_WORD -int BN_add_word(a, w) -BIGNUM *a; -BN_ULONG w; - { - BN_ULONG l; - int i; - - if (w == 0) return(1); - bn_check_top(a); - - w=w&BN_MASK2;//w&=BN_MASK2; - if (a->neg) - { - if(a->top > 1) - { - a->neg=0; - i=BN_sub_word(a,w); - a->neg=1; - return(i); - } - else - { /* a->top == 1, it cannot be 0 */ - l=a->d[0]; - if (l > w) - a->d[0]=l-w; - else if (l < w) - { - a->neg=0; - a->d[0]=w-l; - } - else - { - a->neg=0; - a->top=0; - } - return(1); - } - } - w=w&BN_MASK2;//w&=BN_MASK2; - if (bn_wexpand(a,a->top+1) == NULL) return(0); - a->d[a->top]=0; - i=0; - for (;;) - { - l=(a->d[i]+(BN_ULONG)w)&BN_MASK2; - a->d[i]=l; - if (w > l) - w=1; - else - break; - i++; - } - if (i >= a->top) - a->top++; - return(1); - } -#endif - -#ifdef SPLIT_BN_SUB_WORD -int BN_sub_word(a, w) -BIGNUM *a; -BN_ULONG w; - { - int i; - - bn_check_top(a); - if (w == 0) return(1); - - w=w&BN_MASK2;//w&=BN_MASK2; - if (a->neg) - { - a->neg=0; - i=BN_add_word(a,w); - a->neg=1; - return(i); - } - - w=w&BN_MASK2;//w&=BN_MASK2; - if (a->top <= 1) - { - BN_ULONG l; - - if (a->top == 0) - { - if (bn_wexpand(a,1) == NULL) return(0); - a->d[0]=w; - a->neg = 1; - a->top = 1; - return(1); - } - l=a->d[0]; - if (l == w) - a->top=0; - else if (l > w) - a->d[0]=l-w; - else - { - a->neg=1; - a->d[0]=w-l; - } - return(1); - } - i=0; - for (;;) - { - if (a->d[i] >= w) - { - a->d[i]-=w; - break; - } - else - { - a->d[i]=(a->d[i]-w)&BN_MASK2; - i++; - w=1; - } - } - if ((a->d[i] == 0) && (i == (a->top-1))) - a->top--; - return(1); - } -#endif - -#ifdef SPLIT_BN_MUL_WORD -int BN_mul_word(a,w) -BIGNUM *a; -BN_ULONG w; - { - BN_ULONG ll; - - w=w&BN_MASK2;//w&=BN_MASK2; - if (a->top) - { - ll=bn_mul_words(a->d,a->d,a->top,w); - if (ll) - { - if (bn_wexpand(a,a->top+1) == NULL) return(0); - a->d[a->top++]=ll; - } - } - return(1); - } -#endif - -#endif diff --git a/build/tools/acsign/include/acsign.h b/build/tools/acsign/include/acsign.h deleted file mode 100644 index 6e11663c..00000000 --- a/build/tools/acsign/include/acsign.h +++ /dev/null @@ -1,49 +0,0 @@ -#ifndef _ACSIGN_H_ -#define _ACSIGN_H_ - -#include "sha.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#define HASHContext SHA_CTX - -#define HASHReset( _context ) \ -do{ \ - (_context)->sha_block = NULL; \ - (void)SHA1_Init( _context ); \ -} while(0) -#define HASHUpdate( _context, _ptr, _len ) (void)SHA1_Update( _context, _ptr, _len ) -#define HASHGetDigest( _context, _ptr ) (void)SHA1_Final( _ptr, _context ) - -// -BOOL ACSign_Encrypto(void *sign, const void *key, const void *data, int length); -BOOL ACSign_Decrypto(void *buf, const void *key, const void *sign, int length); - -// -int ACSign_DigestUnit( - void* buffer, // 出力領域 - const void* buf, // データへのポインタ - unsigned int len // データの長さ - ); - -// -int ACSign_CompareUnit( - const void* decedHash, // ACSign_Decryptoの出力 - const void* digest // ACSign_DigestUnitの出力 - ); - -// -int ACSign_GetKey( - void* dest_ptr, // 出力データへのポインタ - unsigned int dest_len, // 出力データの長さ - const void* src_ptr, // 入力データへのポインタ - unsigned int src_len // 入力データの長さ - ); - -#ifdef __cplusplus -} -#endif - -#endif //_ACSIGN_H_ diff --git a/build/tools/acsign/include/acsign_gcd.h b/build/tools/acsign/include/acsign_gcd.h deleted file mode 100644 index 2c9853e6..00000000 --- a/build/tools/acsign/include/acsign_gcd.h +++ /dev/null @@ -1,30 +0,0 @@ -#ifndef _ACSIGN_GCD_H_ -#define _ACSIGN_GCD_H_ - -#include "sha.h" -#include "format_sign.h" -#include "format_rom.h" -#include "acsign.h" - -#ifdef __cplusplus -extern "C" { -#endif - -// -int ACSign_Final( - GCDHeader* header, // ヘッダへのポインタ - void* buffer, // 出力領域 - const void* key - ); - -// -int ACSign_DigestHeader( - void* buffer, // 出力領域 - GCDHeader* header // データへのポインタ - ); - -#ifdef __cplusplus -} -#endif - -#endif //_ACSIGN_GCD_H_ diff --git a/build/tools/acsign/include/acsign_nand.h b/build/tools/acsign/include/acsign_nand.h deleted file mode 100644 index 97afa980..00000000 --- a/build/tools/acsign/include/acsign_nand.h +++ /dev/null @@ -1,30 +0,0 @@ -#ifndef _ACSIGN_NAND_H_ -#define _ACSIGN_NAND_H_ - -#include "sha.h" -#include "format_sign.h" -#include "format_rom.h" -#include "acsign.h" - -#ifdef __cplusplus -extern "C" { -#endif - -// -int ACSign_Final( - NANDHeader* header, // ヘッダへのポインタ - void* buffer, // 出力領域 - const void* key - ); - -// -int ACSign_DigestHeader( - void* buffer, // 出力領域 - NANDHeader* header // データへのポインタ - ); - -#ifdef __cplusplus -} -#endif - -#endif //_ACSIGN_NAND_H_ diff --git a/build/tools/acsign/include/acsign_nor.h b/build/tools/acsign/include/acsign_nor.h deleted file mode 100644 index eb097b50..00000000 --- a/build/tools/acsign/include/acsign_nor.h +++ /dev/null @@ -1,30 +0,0 @@ -#ifndef _ACSIGN_NOR_H_ -#define _ACSIGN_NOR_H_ - -#include "sha.h" -#include "format_sign.h" -#include "format_rom.h" -#include "acsign.h" - -#ifdef __cplusplus -extern "C" { -#endif - -// -int ACSign_Final( - NORHeader* header, // ヘッダへのポインタ - void* buffer, // 出力領域 - const void* key - ); - -// -int ACSign_DigestHeader( - void* buffer, // 出力領域 - NORHeader* header // データへのポインタ - ); - -#ifdef __cplusplus -} -#endif - -#endif //_ACSIGN_NOR_H_ diff --git a/build/tools/acsign/include/bn.h b/build/tools/acsign/include/bn.h deleted file mode 100644 index f68b3d22..00000000 --- a/build/tools/acsign/include/bn.h +++ /dev/null @@ -1,1120 +0,0 @@ -/* $Id$ */ -/* - * Copyright (C) 1998-2002 RSA Security Inc. All rights reserved. - * - * This work contains proprietary information of RSA Security. - * Distribution is limited to authorized licensees of RSA - * Security. Any unauthorized reproduction, distribution or - * modification of this work is strictly prohibited. - * - */ - -#ifndef HEADER_COMMON_BN_H -#define HEADER_COMMON_BN_H - -#ifdef __cplusplus -extern "C" { -#endif - -#ifdef FLAT_INC -#include "r_types.h" -#else -#include "../include/r_types.h" -#endif - -#if !defined(CCONV) -#define CCONV -#endif - -#ifndef PRE_CCONV -#define PRE_CCONV -#endif - -/* convert from the new to the old option names */ -#if defined(OPT_BN_LLONG) -#define BN_LLONG /* comment to make sure Configure leaves this alone */ -#endif - -#if defined(OPT_BN_MUL_LATENCY) -#define BN_MUL_LATENCY -#endif - -/* by default we have the following switched on - unless we have an option - * that switched them off for a specific platform - */ -#ifdef OPT_NO_COMBA -#define OPT_NO_BN_MUL_COMBA -#define OPT_NO_BN_SQR_COMBA -#endif - -#ifdef OPT_NO_REC -#define OPT_NO_BN_RECURSION_MUL -#define OPT_NO_BN_RECURSION_SQR -#endif - -#ifndef OPT_NO_BN_MUL_COMBA -#define BN_MUL_COMBA -#endif -#ifndef OPT_NO_BN_SQR_COMBA -#define BN_SQR_COMBA -#endif -#ifndef OPT_NO_BN_RECURSION_MUL -#define BN_RECURSION_MUL -#endif -#ifndef OPT_NO_BN_RECURSION_SQR -#define BN_RECURSION_SQR -#endif -#ifndef OPT_NO_BN_RECURSION_MONT -#undef BN_RECURSION_MONT /* DO NOT TURN THIS ON, IT IS BROKEN */ -#endif - -#if (!defined(OPT_NO_BN_MUL_COMBA) && !defined(OPT_NO_BN_SQR_COMBA)) -#if OPT_MONT_REDUCE_COMBA /* TEMP UNTIL C IS IMPLEMENTED-DEF'd ON PLATFORMS W/ ASM */ -#define BN_REDUCE_COMBA -#endif -#endif - -#define RECP_MUL_MOD -#define MONT_MUL_MOD - -#ifndef OPT_NO_BN_SURRENDER -#define BN_SURRENDER -#else -#undef BN_SURRENDER -#endif - -#ifdef SMALL_CODE_SIZE -#undef BN_MUL_COMBA /* stop modification */ -#undef BN_SQR_COMBA /* stop modification */ -#undef BN_REDUCE_COMBA /* stop modification */ -#undef BN_RECURSION_MUL /* stop modification */ -#undef BN_RECURSION_SQR /* stop modification */ -#undef BN_RECURSION_MONT /* stop modification */ -#endif - - - -/* This next option uses the C libraries (2 word)/(1 word) function. - * If it is not defined, I use my C version (which is slower). - * The reason for this flag is that when the particular C compiler - * library routine is used, and the library is linked with a different - * compiler, the library is missing. This mostly happens when the - * library is built with gcc and then linked using nornal cc. This would - * be a common occurance because gcc normally produces code that is - * 2 times faster than system compilers for the big number stuff. - * For machines with only one compiler (or shared libraries), this should - * be on. Again this in only really a problem on machines - * using "long long's", are 32bit, and are not using my assember code. */ -#if defined(MSDOS) || defined(WINDOWS) || defined(linux) -#define BN_DIV2W -#endif - -/* Only one for the following should be defined */ -/* The prime number generation stuff may not work when - * EIGHT_BIT but I don't care since I've only used this mode - * for debuging the bignum libraries */ -#undef SIXTY_FOUR_BIT_LONG -#undef SIXTY_FOUR_BIT -#undef SIXTY_BIT -#undef THIRTY_TWO_BIT -#undef THIRTY_BIT -#undef SIXTEEN_BIT -#undef EIGHT_BIT -#undef TEST_EIGHT_BIT - -#if defined(OPT_64_BIT_LONG) -#define SIXTY_FOUR_BIT_LONG -#endif -#if defined(OPT_64_BIT) -#define SIXTY_FOUR_BIT -#endif -#if defined(OPT_60_BIT) -#define SIXTY_BIT -#endif -#if defined(OPT_32_BIT) -#define THIRTY_TWO_BIT -#endif -#if defined(OPT_32_BIT_INT) -#define THIRTY_TWO_BIT -#endif -#if defined(OPT_30_BIT) -#define THIRTY_BIT -#endif -#if defined(OPT_16_BIT) -#define SIXTEEN_BIT -#endif -#if defined(OPT_8_BIT) -#define EIGHT_BIT -#endif -#if defined(OPT_8_BIT_TEST) -#define TEST_EIGHT_BIT -#endif - -/* This define is used for those few functions that 'break' when - * things are compiled for 8 bit words. Basically the size of an - * integer. - */ -#define BN_ILONG BN_ULONG - -/* assuming long is 64bit - this is the DEC Alpha - * unsigned long long is only 64 bits, don't define - * BN_LLONG for the DEC Alpha */ -#ifdef SIXTY_FOUR_BIT_LONG -#undef BN_LLONG -#define BN_ULLONG unsigned long long -#define BN_ULONG unsigned long -#define BN_LONG long -#define BN_BITS 128 -#define BN_BYTES 8 -#define BN_BITS2 64 -#define BN_BITS4 32 -#define BN_MASK (0xffffffffffffffffffffffffffffffffLL) -#define BN_MASK2 (0xffffffffffffffffL) -#define BN_MASK2l (0xffffffffL) -#define BN_MASK2lh (0xffffffffL) -#define BN_MASK2h (0xffffffff00000000L) -#define BN_MASK2h1 (0xffffffff80000000L) -#define BN_TBIT (0x8000000000000000L) -#define BN_DEC_CONV (10000000000000000000UL) -#define BN_DEC_FMT1 "%lu" -#define BN_DEC_FMT2 "%019lu" -#define BN_DEC_NUM 19 -#define BN_HEX_FMT "%016lX" -#endif - -/* This is where the long long data type is 64 bits, but long is 32. - * For machines where there are 64bit registers, this is the mode to use. - * IRIX, on R4000 and above should use this mode, along with the relevent - * assember code. Do NOT define BN_LLONG. - */ -#ifdef SIXTY_FOUR_BIT -#undef BN_LLONG /* Protect against config */ -/* #define BN_ULLONG unsigned long long */ -#ifdef WIN64 -#define BN_ULONG unsigned _int64 -#define BN_LONG _int64 -#else -#define BN_ULONG unsigned long long -#define BN_LONG long long -#endif -#define BN_BITS 128 -#define BN_BYTES 8 -#define BN_BITS2 64 -#define BN_BITS4 32 -#define BN_MASK2 (0xffffffffffffffffLL) -#define BN_MASK2l (0xffffffffL) -#define BN_MASK2lh (0xffffffffL) -#define BN_MASK2h (0xffffffff00000000LL) -#define BN_MASK2h1 (0xffffffff80000000LL) -#define BN_TBIT (0x8000000000000000LL) -#define BN_DEC_CONV (10000000000000000000ULL) -#ifdef WIN64 -#define BN_DEC_FMT1 "%I64u" -#define BN_DEC_FMT2 "%019I64u" -#define BN_DEC_NUM 19 -#define BN_HEX_FMT "%016I64X" -#else -#define BN_DEC_FMT1 "%llu" -#define BN_DEC_FMT2 "%019llu" -#define BN_DEC_NUM 19 -#define BN_HEX_FMT "%016llX" -#endif -#endif - -#ifdef SIXTY_BIT -#undef SIXTY_FOUR_BIT -#undef BN_LLONG /* Protect against config */ -/* #define BN_ULLONG unsigned long long */ -#define BN_ULONG unsigned long long -#define BN_LONG long long -#define BN_BITS 120 -#define BN_BITS2 60 -#define BN_BITS4 30 -#define BN_MASK2 (0x0fffffffffffffffLL) -#define BN_MASK2l ( 0x3fffffffL) -#define BN_MASK2lh ( 0x3fffffffL) -#define BN_MASK2h (0x0fffffffc0000000LL) -#define BN_MASK2h1 (0x0fffffffe0000000LL) -#define BN_TBIT (0x0800000000000000LL) -#define BN_DEC_CONV (100000000000000000LL) -#define BN_DEC_FMT1 "%9u" -#define BN_DEC_FMT2 "%017llu" -#define BN_DEC_NUM 17 -#define BN_HEX_FMT "%016llX" -#endif - -#ifdef THIRTY_TWO_BIT -#ifdef WIN32 -#if defined(__BORLANDC__) -#define BN_ULLONG unsigned __int64 -#else /* !__BORLANDC__ */ -#if defined(__MINGW32__) || defined(__DJGPP__) -#define BN_ULLONG unsigned long long -#else -#define BN_ULLONG unsigned _int64 -#endif /* __MINGW32__ || __DJGPP__ */ -#endif /* __BORLANDC__ */ -#else /* !WIN32 */ -#define BN_ULLONG unsigned long long -#endif /* WIN32 */ -#ifdef OPT_32_BIT_INT -#define BN_ULONG unsigned int -#define BN_LONG int -#else -#define BN_ULONG unsigned long -#define BN_LONG long -#endif -#define BN_BITS 64 -#define BN_BYTES 4 -#define BN_BITS2 32 -#define BN_BITS4 16 -/* This is needed because the Watcom compiler pre-processor - * under QNX tries to parses the 'LL' part even though it is - * never used. - */ -#ifdef BN_LLONG -#ifndef WIN32 -#define BN_MASK (0xffffffffffffffffLL) -#else -#define BN_MASK (0xffffffffffffffffL) -#endif -#endif -#define BN_MASK2 (0xffffffffL) -#define BN_MASK2l (0xffff) -#define BN_MASK2lh (0xffff) -#define BN_MASK2h1 (0xffff8000L) -#define BN_MASK2h (0xffff0000L) -#define BN_TBIT (0x80000000L) -#define BN_DEC_CONV (1000000000L) -#define BN_DEC_FMT1 "%lu" -#define BN_DEC_FMT2 "%09lu" -#define BN_DEC_NUM 9 -#define BN_HEX_FMT "%08lX" -#endif - -#ifdef THIRTY_BIT -#ifdef WIN32 -#if defined(__MINGW32__) || defined(__DJGPP__) -#define BN_ULLONG unsigned long long -#else /* ! (__MINGW32__ || __DJGPP__) */ -#define BN_ULLONG unsigned _int64 -#endif /* __MINGW32__ || __DJGPP__ */ -#else /* !WIN32 */ -#define BN_ULLONG unsigned long long -#endif /* WIN32 */ -#define BN_ULONG unsigned long -#define BN_LONG long -#define BN_BITS 60 -#define BN_BITS2 30 -#define BN_BITS4 15 -/* This is needed because the Watcom compiler pre-processor - * under QNX tries to parses the 'LL' part even though it is - * never used. - */ -#ifdef BN_LLONG -#ifndef WIN32 -#define BN_MASK (0x0fffffffffffffffLL) -#else -#define BN_MASK (0x0fffffffffffffffL) -#endif -#endif -#define BN_MASK2 (0x3fffffffL) -#define BN_MASK2l (0x7fff) -#define BN_MASK2lh (0x7fff) -#define BN_MASK2h1 (0x3fffc000L) -#define BN_MASK2h (0x3fff8000L) -#define BN_TBIT (0x20000000L) -#define BN_DEC_CONV (1000000000L) -#define BN_DEC_FMT1 "%lu" -#define BN_DEC_FMT2 "%09lu" -#define BN_DEC_NUM 9 -#define BN_HEX_FMT "%08lX" -#endif - -#ifdef SIXTEEN_BIT -#ifndef BN_DIV2W -#define BN_DIV2W -#endif -#define BN_ULLONG unsigned long -#define BN_ULONG unsigned short -#define BN_LONG short -#define BN_BITS 32 -#define BN_BYTES 2 -#define BN_BITS2 16 -#define BN_BITS4 8 -#define BN_MASK (0xffffffff) -#define BN_MASK2 (0xffff) -#define BN_MASK2l (0xff) -#define BN_MASK2lh (0xff) -#define BN_MASK2h1 (0xff80) -#define BN_MASK2h (0xff00) -#define BN_TBIT (0x8000) -#define BN_DEC_CONV (10000) -#define BN_DEC_FMT1 "%u" -#define BN_DEC_FMT2 "%04u" -#define BN_DEC_NUM 4 -#define BN_HEX_FMT "%04X" -#endif - -#ifdef TEST_EIGHT_BIT -#define EIGHT_BIT /* comment to stop editing */ -#endif - -#ifdef EIGHT_BIT -#undef BN_ILONG -#define BN_ILONG unsigned int -#ifndef BN_DIV2W -#define BN_DIV2W -#endif -#ifdef TEST_EIGHT_BIT -#define BN_ULLONG unsigned int -#define BN_ULONG unsigned int -#define BN_LONG int -#else -#define BN_ULLONG unsigned short -#define BN_ULONG unsigned char -#define BN_LONG char -#endif -#define BN_BITS 16 -#define BN_BYTES 1 -#define BN_BITS2 8 -#define BN_BITS4 4 -#define BN_MASK (0xffff) -#define BN_MASK2 (0xff) -#define BN_MASK2lh (0xf) -#define BN_MASK2l (0xf) -#define BN_MASK2h1 (0xf8) -#define BN_MASK2h (0xf0) -#define BN_TBIT (0x80) -#define BN_DEC_CONV (100) -#define BN_DEC_FMT1 "%u" -#define BN_DEC_FMT2 "%02u" -#define BN_DEC_NUM 2 -#define BN_HEX_FMT "%02X" -#endif - -#ifdef BIGNUM -#undef BIGNUM -#endif - -#define BN_FLG_MALLOCED 0x01 -#define BN_FLG_STATIC_DATA 0x02 -#define BN_FLG_FREE 0x8000 /* used for debuging */ -#define BN_CTX_FLG_ABORT 0x4000 /* used for aborting RSA operations*/ -#define BN_set_flags(b,n) ((b)->flags|=(n)) -#define BN_get_flags(b,n) ((b)->flags&(n)) -#define BN_CTX_set_flags(b,n) ((b)->flags|=(n)) -#define BN_CTX_get_flags(b,n) ((b)->flags&(n)) - -#ifndef HEADER_COMMON_BN_H_TYPEDEF_DEF -#define HEADER_COMMON_BN_H_TYPEDEF_DEF -typedef struct bignum_st BIGNUM; -typedef struct bignum_ctx BN_CTX; -typedef struct bn_mont_ctx_st BN_MONT_CTX; -typedef struct bn_recp_ctx_st BN_RECP_CTX; -typedef struct bn_prime_ctx_st BN_PRIME_CTX; -typedef struct bn_blind_ctx_st BN_BLIND_CTX; -typedef struct bn_blind_meth_st BN_BLIND_METH; -#endif - -typedef struct bn_mod_exp_meth_st BN_ME_METH; -typedef struct bn_mod_exp_ctx_st BN_ME_CTX; - - -/* The data array d must always have an extra 'valid' word in location - * bn->d[bn->max]. It must be ok for reading. This is needed if - * BN_MUL_LATENCY is defined. - */ -struct bignum_st - { - BN_ULONG *d; /* Pointer to an array of 'BN_BITS2' bit chunks. */ - int top; /* Index of last used d +1. */ - /* The next are internal book keeping for bn_expand. */ - int max; /* Size of the d array. */ - int neg; /* one if the number is negative */ - int flags; - }; - -/* Used for temp variables */ -#define BN_CTX_NUM 12 -struct bignum_ctx - { - int tos; - BIGNUM bn[BN_CTX_NUM+1]; - int flags; - R_SURRENDER *surrender; - }; - -#if defined(WIN64) || defined(__ia64__) || defined(CPU_IA64) -#define BN_USHORT unsigned int -#else -#define BN_USHORT unsigned short -#endif - -/* Used for prime number generation */ -struct bn_prime_ctx_st - { - BN_USHORT *primes; - BN_USHORT *mods; - int num_primes; - int prime_checks; - R_SURRENDER *surrender; - R_RANDOM *random; - int flags; - }; - -struct bn_blind_ctx_st - { - int init; - BN_BLIND_METH *meth; - BIGNUM B; - BIGNUM Bi; - BIGNUM mod; - }; - -struct bn_blind_meth_st - { - void (*init) (BN_BLIND_CTX *); - void (*ctx_free)(BN_BLIND_CTX *); - int (*set) (BN_BLIND_CTX *,R_RANDOM *,BIGNUM *,BIGNUM *, BN_ME_CTX *,BN_CTX *); - int (*convert) (BN_BLIND_CTX *,BIGNUM *,BN_CTX *); - int (*invert) (BN_BLIND_CTX *,BIGNUM *,BN_CTX *); - int (*update) (BN_BLIND_CTX *,BN_CTX *); - int (*copy) (BN_BLIND_CTX *,BN_BLIND_CTX *); - }; - -/* Used for montgomery multiplication */ -struct bn_mont_ctx_st - { - int use_word; /* 0 for word form, 1 for long form */ - int ri; /* number of bits in R */ - int riw; /* number of words in R */ - BIGNUM RR; /* used to convert to montgomery form */ - BIGNUM N; /* The modulus */ - BIGNUM Ni; /* The inverse of N */ - BN_ULONG n0; /* word form of inverse, normally only one of - * Ni or n0 is defined */ - int flags; - }; - -/* Used by the recursive exponentiation implementations */ -typedef struct bn_mod_exp_rec_meth_st - { -#ifndef NOPROTO - void (PRE_CCONV CCONV *mul)(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b); - void (PRE_CCONV CCONV *sqr)(BN_ULONG *r, BN_ULONG *a); - void (PRE_CCONV CCONV *low_mul)(); -#else - void (PRE_CCONV CCONV *mul)(); - void (PRE_CCONV CCONV *sqr)(); - void (PRE_CCONV CCONV *low_mul)(); -#endif - } BN_MOD_EXP_REC_METH; - -/* If this flag is set, if there is a custom method for a modulus - * two times larger, use it. This is mostly mean for use on the - * itanium where a 512*512 routine is 10 times faster than the C - * code version, so we need to detect that we can turn of CRT - * for RSA if there is an native IA64 512*512 present. - */ -#define BN_ME_FLG_FAST_ASM 0x0001 - -struct bn_mod_exp_meth_st - { - int num; /* Word size we target */ - char *name; /* Identify the method */ -#ifndef NOPROTO - int (*useit)(const BN_ME_METH *meth); - /* If 'power' is null, reuse the old one */ - int (*mod_exp)(BN_ME_CTX *mctx,BIGNUM *r,BIGNUM *a,BIGNUM *p, - BN_CTX *ctx); - /* Create the BN_ME_CTX */ - int (*init_ctx)(const BN_ME_METH *meth,BN_ME_CTX **mctx); - /* Get rid of it */ - int (*free_ctx)(BN_ME_CTX *mctx); - /* Assign the modulus */ - int (*set)(BN_ME_CTX *mctx,BIGNUM *n,int cmd,int flags,BN_CTX *ctx); -#else - int (*useit)(); - int (*mod_exp)(); - int (*init_ctx)(); - int (*free_ctx)(); - int (*set)(); -#endif - int argi; - char *argp; /* 'Extra stuff' */ - }; - -#define BN_ME_METH_TABLE_MAX 32 -/* Used in BN_library_init */ -#define BN_INIT_LAST 0x00 -#define BN_INIT_BN_ME_METH 0x01 - -#define BN_BNME_F_DEFAULT 0x01 -/* Used only when loading, kept as bits internally, normally loaded as - * words */ -#define BN_BNME_F_BITS 0x02 -typedef struct bn_me_meth_info_st - { -#ifndef NOPROTO - const BN_ME_METH *(*meth)(void); -#else - const BN_ME_METH *(*meth)(); -#endif - int min; - int max; - int flags; - } BN_ME_METH_INFO; - -#define BN_ME_SET_MOD 0x01 -#define BN_ME_SET_BASE 0x02 -#define BN_ME_SET_EXP 0x03 -#define BN_ME_SET_FLG_NO_LOOKUP 0x01 /* Passed to BN_ME_CTX_set() */ - -#define BN_FLG_CACHE 0x10 /* Cache values */ -#define BN_ME_FLG_BASE 0x40 /* base has been cached */ -#define BN_ME_FLG_EXP 0x80 /* power has been cached */ -/* When one of these structures is setup, it is intended that the - * base or power, if not null, will be used for the current calculation. - * If the base and/or power are cached, they will only be used if the input - * value is null. - * For RSA, the power would normally be set. - * For DH, the base and power would be set. The initial value generated - * would be the public key, which is exchanged. The phase2 part would - * change the base but not the power. - * For DSA signing, a fixed base is used, but a random power. - * For DSA verification, there are two bases and two powers, - * a^p%m * b^q%m - * One way to implement this is to use a special function to - * generate a composite power value, and or a special base form. - * The other option is to have a special function to generate - * the 'base' array. The problem is that we are exponentiating with - * a 3 value power value, instead of the normal two. It should be possible - * to use the standard a^b%m function. - */ -struct bn_mod_exp_ctx_st - { - const BN_ME_METH *meth; - char *callback; - char *cb_arg; - int flags; - /* Evil hack for storage of data values, it should really be here - * other than the first value */ - char *modulus; /* eg BN_MONT_CTX */ - char *power; /* eg power representation */ - char *base; /* eg base representation */ - char *arg; - }; - -/* Used for reciprocal division/mod functions - * It cannot be shared between threads - */ -struct bn_recp_ctx_st - { - BIGNUM N; /* the divisor */ - BIGNUM Nr; /* the reciprocal */ - int num_bits; - int shift; - int flags; - }; - -typedef struct bn_rec_st - { - int depth; - int n; -#ifndef NOPROTO - void (PRE_CCONV CCONV *mul)(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b); - void (PRE_CCONV CCONV *sqr)(BN_ULONG *r, BN_ULONG *a); - void (PRE_CCONV CCONV *low_mul)(); -#else - void (PRE_CCONV CCONV *mul)(); - void (PRE_CCONV CCONV *sqr)(); - void (PRE_CCONV CCONV *low_mul)(); -#endif - } BN_REC; - -#define BN_to_montgomery(r,a,mont,ctx) BN_mod_mul_montgomery(\ - r,a,&((mont)->RR),(mont),ctx) - -#define BN_prime_checks (5) - -#define BN_num_bytes(a) ((BN_num_bits(a)+7)/8) -#define BN_length(a) ((a)->top * BN_BYTES) -#define BN_is_word(a,w) (((a)->top == 1) && ((a)->d[0] == (BN_ULONG)(w))) -#define BN_is_zero(a) (((a)->top == 0) || BN_is_word(a,0)) -#define BN_is_one(a) (BN_is_word((a),1)) -#define BN_is_odd(a) (((a)->top > 0) && ((a)->d[0] & 1)) -#define BN_one(a) (BN_set_word((a),(BN_ULONG)1)) -#define BN_zero(a) (BN_set_word((a),(BN_ULONG)0)) - -/*#define BN_ascii2bn(a) BN_hex2bn(a) */ -/*#define BN_bn2ascii(a) BN_bn2hex(a) */ - -#define bn_expand(n,b) ((((((b+BN_BITS2-1))/BN_BITS2)) <= (n)->max)?\ - (n):bn_expand2((n),(b)/BN_BITS2+1)) -#define bn_wexpand(n,b) (((b) <= (n)->max)?(n):bn_expand2((n),(b))) - -#ifdef SMALL_CODE_SIZE -void bn_zexpand(BIGNUM *a,int n); -void bn_fix_top(BIGNUM *a); -#else -#define bn_zexpand(a,n) \ - if ((a)->top < n) \ - { \ - int i; \ - bn_wexpand((a),n); \ - if ((a)->d!=NULL) \ - { \ - for (i=(a)->top; id[i]=0; \ - } \ - } - -#define bn_fix_top(a) \ - { \ - BN_ULONG *ftl; \ - if ((a)->top > 0) \ - { \ - for (ftl= &((a)->d[(a)->top-1]); (a)->top > 0; (a)->top--) \ - if (*(ftl--)) break; \ - } \ - } -#endif - -#define BN_MONT_CTX_set(a,b,c) BN_MONT_CTX_set_word((a),(b),(c)) - -#ifndef NOPROTO - - -const BN_ME_METH *BN_ME_METH_word(void); -const BN_ME_METH *BN_ME_METH_full(void); - -#if (defined(BN_MUL_COMBA) || defined(BN_SQR_COMBA)) - -/* word4 - used for 64bit multiprime*/ -const BN_ME_METH *BN_ME_METH_word4(void); -const BN_ME_METH *BN_ME_METH_rec4_word8(void); -const BN_ME_METH *BN_ME_METH_rec4_word16(void); -const BN_ME_METH *BN_ME_METH_rec4_word32(void); -const BN_ME_METH *BN_ME_METH_rec4_word64(void); -const BN_ME_METH *BN_ME_METH_rec4_word128(void); - -/* word6 - used for 64bit multiprime*/ -const BN_ME_METH *BN_ME_METH_word6(void); -const BN_ME_METH *BN_ME_METH_rec6_word12(void); -const BN_ME_METH *BN_ME_METH_rec6_word24(void); -const BN_ME_METH *BN_ME_METH_rec6_word48(void); -const BN_ME_METH *BN_ME_METH_rec6_word96(void); - -const BN_ME_METH *BN_ME_METH_word8(void); -const BN_ME_METH *BN_ME_METH_rec8_word16(void); -const BN_ME_METH *BN_ME_METH_rec8_word32(void); -const BN_ME_METH *BN_ME_METH_rec8_word64(void); -const BN_ME_METH *BN_ME_METH_rec8_word128(void); -const BN_ME_METH *BN_ME_METH_rec8_word256(void); - -const BN_ME_METH *BN_ME_METH_word11(void); -const BN_ME_METH *BN_ME_METH_rec11_word22(void); -const BN_ME_METH *BN_ME_METH_rec11_word44(void); -const BN_ME_METH *BN_ME_METH_rec11_word88(void); - -const BN_ME_METH *BN_ME_METH_word16(void); -const BN_ME_METH *BN_ME_METH_rec16_word32(void); -const BN_ME_METH *BN_ME_METH_rec16_word64(void); -const BN_ME_METH *BN_ME_METH_rec16_word128(void); -const BN_ME_METH *BN_ME_METH_rec16_word256(void); - -#endif - -#ifdef CPU_IA64 -const BN_ME_METH *BN_ME_METH_ia64_384(void); -const BN_ME_METH *BN_ME_METH_ia64_512(void); -const BN_ME_METH *BN_ME_METH_ia64_1024(void); -#endif - -#if (defined(CPU_SPARC_V8PLUS) || defined (CPU_SPARC_V9)) -const BN_ME_METH *BN_ME_METH_usparc(void); -const BN_ME_METH *BN_ME_METH_usparc_352(void); -const BN_ME_METH *BN_ME_METH_usparc_512(void); -#endif - -#if 1 || defined(CPU_X86) -const BN_ME_METH *BN_ME_METH_pentium4_29(void); -const BN_ME_METH *BN_ME_METH_pentium4_28(void); -#endif - -/* NCipher Nfast hardware accelerator method prototype */ -const BN_ME_METH *BN_ME_METH_nfast(void); - - -BIGNUM *BN_value_one(void); -const char * BN_options(void); -BN_CTX *BN_CTX_new(void); -void BN_CTX_init(BN_CTX *c); -void BN_CTX_free(BN_CTX *c); -#ifndef NO_BN_RAND -int BN_rand(BIGNUM *rnd, R_RANDOM *rand, int bits, int top,int bottom); -#endif -int BN_num_bits(BIGNUM *a); -int BN_num_bits_word(BN_ILONG); -BIGNUM *BN_new(void); -void BN_init(BIGNUM *); -void BN_clear_free(BIGNUM *a); -BIGNUM *BN_copy(BIGNUM *a, BIGNUM *b); -BIGNUM *BN_bin2bn(unsigned char *s,int len,BIGNUM *ret); -int BN_bn2bin(BIGNUM *a, unsigned char *to); -BIGNUM *BN_mpi2bn(unsigned char *s,int len,BIGNUM *ret); -int BN_bn2mpi(BIGNUM *a, unsigned char *to); -int BN_sub(BIGNUM *r, BIGNUM *a, BIGNUM *b); -int BN_usub(BIGNUM *r, BIGNUM *a, BIGNUM *b); -int BN_uadd(BIGNUM *r, BIGNUM *a, BIGNUM *b); -int BN_add(BIGNUM *r, BIGNUM *a, BIGNUM *b); -int BN_mod(BIGNUM *rem, BIGNUM *m, BIGNUM *d, BN_CTX *ctx); -int BN_div(BIGNUM *dv, BIGNUM *rem, BIGNUM *m, BIGNUM *d, BN_CTX *ctx); -int BN_mul(BIGNUM *r, BIGNUM *a, BIGNUM *b,BN_CTX *ctx); -int BN_sqr(BIGNUM *r, BIGNUM *a,BN_CTX *ctx); -BN_ULONG BN_mod_word(BIGNUM *a, BN_ULONG w); -BN_ULONG BN_div_word(BIGNUM *a, BN_ULONG w); -int BN_mul_word(BIGNUM *a, BN_ULONG w); -int BN_add_word(BIGNUM *a, BN_ULONG w); -int BN_sub_word(BIGNUM *a, BN_ULONG w); -int BN_set_word(BIGNUM *a, BN_ULONG w); -BN_ULONG BN_get_word(BIGNUM *a); -int BN_cmp(BIGNUM *a, BIGNUM *b); -void BN_free(BIGNUM *a); -int BN_is_bit_set(BIGNUM *a, int n); -int BN_lshift(BIGNUM *r, BIGNUM *a, int n); -int BN_lshift1(BIGNUM *r, BIGNUM *a); -int BN_exp(BIGNUM *r, BIGNUM *a, BIGNUM *p,BN_CTX *ctx); -int BN_mod_exp(BIGNUM *r, BIGNUM *a, BIGNUM *p, BIGNUM *m,BN_CTX *ctx); -int BN_mod_exp_mont(BIGNUM *r, BIGNUM *a, BIGNUM *p, BIGNUM *m,BN_CTX *ctx, - BN_MONT_CTX *m_ctx); -int BN_mod_exp2_mont(BIGNUM *r, BIGNUM *a1, BIGNUM *p1,BIGNUM *a2, - BIGNUM *p2,BIGNUM *m,BN_CTX *ctx,BN_MONT_CTX *m_ctx); -int BN_mod_exp_simple(BIGNUM *r, BIGNUM *a, BIGNUM *p, - BIGNUM *m,BN_CTX *ctx); -int BN_mask_bits(BIGNUM *a,int n); -int BN_mod_mul(BIGNUM *ret, BIGNUM *a, BIGNUM *b, BIGNUM *m, - BN_CTX *ctx); -#if !defined(WIN16) && !defined(NO_FP_API) -int BN_print_fp(FILE *fp, BIGNUM *a); -#endif -#ifdef HEADER_COMMON_BIO_H -int BN_print(BIO *fp, BIGNUM *a); -#else -/* int BN_print(char *fp, BIGNUM *a); */ -#endif -int BN_reciprocal(BIGNUM *r, BIGNUM *m, int len, BN_CTX *ctx); -int BN_rshift(BIGNUM *r, BIGNUM *a, int n); -int BN_rshift1(BIGNUM *r, BIGNUM *a); -void BN_clear(BIGNUM *a); -BIGNUM *bn_expand2(BIGNUM *b, int bits); -BIGNUM *BN_dup(BIGNUM *a); -int BN_ucmp(BIGNUM *a, BIGNUM *b); -int BN_set_bit(BIGNUM *a, int n); -int BN_clear_bit(BIGNUM *a, int n); -char * BN_bn2hex(BIGNUM *a); -char * BN_bn2dec(BIGNUM *a); -int BN_hex2bn(BIGNUM **a,char *str); -int BN_dec2bn(BIGNUM **a,char *str); -int BN_gcd(BIGNUM *r,BIGNUM *in_a,BIGNUM *in_b,BN_CTX *ctx); -BIGNUM *BN_mod_inverse(BIGNUM *ret,BIGNUM *a, BIGNUM *n,BN_CTX *ctx); -/* Return R, where it is R*(1< -#include -//#include "r_error.h" -//#include "err.h" -#include - -#ifndef STANDALONE -#include "r_com.h" -#else -#define NO_STDLIB_MAPPING -#define Malloc(a) malloc(a) -#define Free(a) free(a) -#define Memset(a,b,c) memset(a,b,c) -#define Memcpy(a,b,c) memcpy(a,b,c) -#endif - -/* TEMP FIX */ -#undef BNerr -#define BNerr(a,b) -#include "bn.h" - -#define BN_EXP_TABLE_SIZE 16 - -/* see the bn_limit_ fields which are the start of a runtime - * tunable set of values to match these fixed compile-time constants - */ -/* Pentium pro 16,16,16,32,64 */ -/* Alpha 16,16,16,16.64 */ -/* StrongARM */ -#define BN_MULL_SIZE_NORMAL (16) /* 32 */ -#define BN_MUL_RECURSIVE_SIZE_NORMAL (16) /* 32 */ /* less than */ -#define BN_SQR_RECURSIVE_SIZE_NORMAL (16) /* 32 */ -#define BN_MUL_LOW_RECURSIVE_SIZE_NORMAL (32) /* 32 */ -#define BN_MONT_CTX_SET_SIZE_WORD (64) /* 32 */ - -/************************************************************* - * Using the long long type - */ -#define Lw(t) (((BN_ULONG)(t))&BN_MASK2) -#define Hw(t) (((BN_ULONG)((t)>>BN_BITS2))&BN_MASK2) - -/* These are used for internal error checking and are not normally used */ -#ifdef BN_DEBUG -#define bn_check_top(a) \ - { if ( ((a)->top < 0) || \ - ((a)->top > (a)->max) || \ - (((a)->top == 0) && (a)->neg) || \ - (((a)->top == 1) && (a->d[0] == 0))) \ - { char *nullp=NULL; *nullp='z'; } } -#define bn_check_num(a) if ((a) < 0) { char *nullp=NULL; *nullp='z'; } -#define bn_assert(a) if (!(a)) { char *nullp=NULL; *nullp='z'; } -#define bn_set_used_check(l,size,num) bn_su_check(l,size,num) -#ifdef BN_DEBUG2 -#define bn_do_used_check(fp,str,l,size,num) bn_du_check(fp,str,l,size,num) -#else -#define bn_do_used_check(fp,str,l,size,num) -#endif -#else -#define bn_assert(a) -#define bn_check_top(a) -#define bn_check_num(a) -#define bn_set_used_check(l,size,num) -#define bn_do_used_check(fp,str,l,size,num) -#endif - - -/*********************************************** -* IA64 32 bit build SWIZZLE code -* This essentially casts our points which are -* 32bits under abi32 to 64bit unsigned long -* longs and then grabs the top two bits of the -* pointer and places it in the 2nd and 3rd bits -* of the unsigned long long. -**********************************************/ -#ifdef HPUX_IA64_32 -#define SWIZLLE(VALUE) ((((unsigned long long)(VALUE) & 0xc0000000LL) <<31)\ -|((unsigned long long)(VALUE))) -#else -#define SWIZZLE(VALUE) (VALUE) -#endif - -#define bn_neg_words(a,n) \ - { \ - int iii; \ - \ - for (iii=0; iiimax=(r)->top,BN_set_flags((r),BN_FLG_STATIC_DATA)) -#else -#define bn_set_max(r) -#endif - -/* These macros are used to 'take' a section of a bignum for read only use */ -#define bn_set_low(r,a,n) \ - { \ - (r)->top=((a)->top > (n))?(n):(a)->top; \ - (r)->d=(a)->d; \ - (r)->neg=(a)->neg; \ - (r)->flags|=BN_FLG_STATIC_DATA; \ - bn_set_max(r); \ - } - -#define bn_set_high(r,a,n) \ - { \ - if ((a)->top > (n)) \ - { \ - (r)->top=(a)->top-n; \ - (r)->d= &((a)->d[n]); \ - } \ - else \ - (r)->top=0; \ - (r)->neg=(a)->neg; \ - (r)->flags|=BN_FLG_STATIC_DATA; \ - bn_set_max(r); \ - } - -/* #define bn_expand(n,b) ((((b)/BN_BITS2) <= (n)->max)?(n):bn_expand2((n),(b))) */ - -#ifdef BN_LLONG -#define mul_add(r,a,w,c) { \ - BN_ULLONG t; \ - t=(BN_ULLONG)w * (a) + (r) + (c); \ - (r)= Lw(t); \ - (c)= Hw(t); \ - } - -#define mul(r,a,w,c) { \ - BN_ULLONG t; \ - t=(BN_ULLONG)w * (a) + (c); \ - (r)= Lw(t); \ - (c)= Hw(t); \ - } - -#else -/************************************************************* - * No long long type - */ - -#define LBITS(a) ((a)&BN_MASK2l) -#define HBITS(a) (((a)>>BN_BITS4)&BN_MASK2lh) -#define L2HBITS(a) ((BN_ULONG)((a)&BN_MASK2lh)<>(BN_BITS4-1); \ - m =((m&BN_MASK2l)<<(BN_BITS4+1))&BN_MASK2; \ - l=(l+m)&BN_MASK2; if (l < m) h++; \ - (lo)=l; \ - (ho)=h; \ - } - -#if 0 -#define mul_add(r,a,bl,bh,b_hl,c) { \ - BN_ULONG l,h; \ - BN_ULONG lt,mt; \ - \ - h= (a); \ - l=LBITS(h); \ - h=HBITS(h); \ - mt=bl*l; \ - lt=mt+c+(r); \ - c=bh*h; \ - mt+=c+(l-h)*b_hl; \ - mt+=(lt>>BN_BITS4); \ - (r)=(lt&BN_MASK2l)|((mt&BN_MASK2l)<>BN_BITS4); \ - } -#else /* Normal version */ -#define mul_add(r,a,bl,bh,b_hl,c) { \ - BN_ULONG l,h; \ - \ - h= (a); \ - l=LBITS(h); \ - h=HBITS(h); \ - mul64(l,h,(bl),(bh)); \ - \ - /* non-multiply part */ \ - l=(l+(c))&BN_MASK2; if (l < (c)) h++; \ - (c)=(r); \ - l=(l+(c))&BN_MASK2; if (l < (c)) h++; \ - (c)=h&BN_MASK2; \ - (r)=l; \ - } -#endif - -#define mul(r,a,bl,bh,c) { \ - BN_ULONG l,h; \ - \ - h= (a); \ - l=LBITS(h); \ - h=HBITS(h); \ - mul64(l,h,(bl),(bh)); \ - \ - /* non-multiply part */ \ - l+=(c); if ((l&BN_MASK2) < (c)) h++; \ - (c)=h&BN_MASK2; \ - (r)=l&BN_MASK2; \ - } - -#endif - -#ifndef BN_MUL_COMBA -#define bn_mul_comba4(r,a,b) bn_mul_normal(r,a,4,b,4) -#define bn_mul_comba5(r,a,b) bn_mul_normal(r,a,5,b,5) -#define bn_mul_comba6(r,a,b) bn_mul_normal(r,a,6,b,6) -#define bn_mul_comba8(r,a,b) bn_mul_normal(r,a,8,b,8) -#define bn_mul_comba11(r,a,b) bn_mul_normal(r,a,11,b,11) -#define bn_mul_comba12(r,a,b) bn_mul_normal(r,a,12,b,12) -#define bn_mul_comba16(r,a,b) bn_mul_normal(r,a,16,b,16) -#endif -#if 1 -#ifndef BN_SQR_COMBA -#define bn_sqr_comba4(r,a) bn_mul_normal(r,a,4,a,4) -#define bn_sqr_comba5(r,a) bn_mul_normal(r,a,5,a,5) -#define bn_sqr_comba6(r,a) bn_mul_normal(r,a,6,a,6) -#define bn_sqr_comba8(r,a) bn_mul_normal(r,a,8,a,8) -#define bn_sqr_comba11(r,a) bn_mul_normal(r,a,11,a,11) -#define bn_sqr_comba12(r,a) bn_mul_normal(r,a,12,a,12) -#define bn_sqr_comba16(r,a) bn_mul_normal(r,a,16,a,16) -#endif -#else -#ifndef BN_SQR_COMBA -#define bn_sqr_comba4(r,a) bn_mul_comba4(r,a,a) -#define bn_sqr_comba5(r,a) bn_mul_comba5(r,a,a) -#define bn_sqr_comba6(r,a) bn_mul_comba6(r,a,a) -#define bn_sqr_comba8(r,a) bn_mul_comba8(r,a,a) -#define bn_sqr_comba11(r,a) bn_mul_comba11(r,a,a) -#define bn_sqr_comba12(r,a) bn_mul_comba12(r,a,a) -#define bn_sqr_comba16(r,a) bn_mul_comba16(r,a,a) -#endif -#endif -#ifndef BN_REDUCE_COMBA -#define r0_bn_mont_comba4(r,a,n,num,n0) bn_from_montgomery_words(r,a,n,num,n0) -#define r0_bn_mont_comba5(r,a,n,num,n0) bn_from_montgomery_words(r,a,n,num,n0) -#define r0_bn_mont_comba6(r,a,n,num,n0) bn_from_montgomery_words(r,a,n,num,n0) -#define r0_bn_mont_comba8(r,a,n,num,n0) bn_from_montgomery_words(r,a,n,num,n0) -#define r0_bn_mont_comba11(r,a,n,num,n0) bn_from_montgomery_words(r,a,n,num,n0) -#define r0_bn_mont_comba12(r,a,n,num,n0) bn_from_montgomery_words(r,a,n,num,n0) -#define r0_bn_mont_comba16(r,a,n,num,n0) bn_from_montgomery_words(r,a,n,num,n0) -#endif - -#ifndef NOPROTO - -BIGNUM *bn_expand2(BIGNUM *b, int bits); - -#ifdef X86_ASM -void bn_add_words(BN_ULONG *r,BN_ULONG *a,int num); -#endif - -#else - -BIGNUM *bn_expand2(); -#ifdef X86_ASM -BN_ULONG bn_add_words(); -#endif - -#endif - -#ifdef __cplusplus -} -#endif - -#endif /* HEADER_COMMON_BN_LCL_H */ - -void bn_mul_low_recursive(BN_ULONG *r,BN_ULONG *a,BN_ULONG *b,int n2,BN_ULONG *t); -void bn_mul_high(BN_ULONG *r,BN_ULONG *a,BN_ULONG *b,BN_ULONG *l,int n2, BN_ULONG *t); -int BN_gen_exp_string(unsigned char *str, BIGNUM *p, int bits); -void bn_from_montgomery_rec_full(BN_ULONG *rp, BN_ULONG *ap, - BN_ULONG *np, BN_ULONG *nip, BN_ULONG *tmp,BN_REC *rec); - -int bn_mont_ctx_new_word(const BN_ME_METH *meth, BN_ME_CTX **retp); - diff --git a/build/tools/acsign/include/bn_thx.h b/build/tools/acsign/include/bn_thx.h deleted file mode 100644 index 13e157b7..00000000 --- a/build/tools/acsign/include/bn_thx.h +++ /dev/null @@ -1,301 +0,0 @@ -/* $Id$ */ -/* - * Copyright (C) 1998-2002 RSA Security Inc. All rights reserved. - * - * This work contains proprietary information of RSA Security. - * Distribution is limited to authorized licensees of RSA - * Security. Any unauthorized reproduction, distribution or - * modification of this work is strictly prohibited. - * - */ -/***************************************************************************** - * Copyright (c). 2001 RSA Security Inc. All rights reserved. - * This work contains proprietary information of RSA Security. - * Distribution is limited to authorized licensees of RSA - * Security. Any unauthorized reproduction, distribution or - * modification of this work is strictly prohibited. - ****************************************************************************/ -/** - * @file bn_thx.h - * @brief header file created for used as interface defines for systems - * containing hetergeneous environments where some bn operations - * will be performed in isolation from the rest of the library - */ -#ifndef HEADER_COMMON_BN_THX_H -#define HEADER_COMMON_BN_THX_H - -#ifdef __cplusplus -extern "C" { -#endif - -/* These defines are required on systems so that the mod_exp code - * to be used in isolation from the bn operation with library will work, - * if these are not available, the header files with equivalent functionality - * should be added inside a CPU or Operating system define - */ -#ifndef NO_STDIO_H -#include -#endif - -#ifndef NO_STDLIB_H -#include -#endif - -#ifndef NO_STRING_H -#include -#endif - -/* Interface for ARM/DSP systems, this interface requires only - * the standard defines and includes at the moment - */ -#ifdef CPU_TMS320 -#define THX_RECIPIENT -#define CPU_DSP -#endif - -#ifdef THX_RECIPIENT - -#ifndef restrict -#define restrict -#endif - -#ifndef Malloc -#define Malloc malloc -#endif - -#ifndef Memcpy -#define Memcpy memcpy -#endif - -#ifndef Memmove -#define Memmove memmove -#endif - -#ifndef Memset -#define Memset memset -#endif - -#ifndef Free -#define Free free -#endif - -#endif /* THX_RECIPIENT */ - -#ifndef THX_RECIPIENT /* not the recipient, we must be the caller */ - -#include "bn_lcl.h" - -#endif /* ! THX_RECIPIENT */ - -/* The follow define protected inclusions are excerpts from the - * header file bn.h, this has been done, so that code written for the - * THX systems can be used in isolation from the library - * This code may need to be updated in line with changes to the bn.h - * header file. - */ -#ifndef HEADER_COMMON_BN_H -#define HEADER_COMMON_BN_H - -#if !defined(CCONV) -#define CCONV -#endif - -#ifndef PRE_CCONV -#define PRE_CCONV -#endif - -/* convert from the new to the old option names */ -#if defined(OPT_BN_LLONG) -#define BN_LLONG /* comment to make sure Configure leaves this alone */ -#endif - -#if defined(OPT_32_BIT_INT) || defined(OPT_32_BIT) -#define THIRTY_TWO_BIT -#endif - -#define BN_ILONG BN_ULONG - -#ifdef THIRTY_TWO_BIT -#define BN_ULLONG unsigned long long -#ifdef OPT_32_BIT_INT -#define BN_ULONG unsigned int -#define BN_LONG int -#else -#define BN_ULONG unsigned long -#define BN_LONG long -#endif -#define BN_BITS 64 -#define BN_BYTES 4 -#define BN_BITS2 32 -#define BN_BITS4 16 -/* This is needed because the Watcom compiler pre-processor - * under QNX is perverted and tries to parses the 'LL' - * part even though it is never used. - */ -#ifdef BN_LLONG -#define BN_MASK (0xffffffffffffffffL) -#endif -#define BN_MASK2 (0xffffffffL) -#define BN_MASK2l (0xffff) -#define BN_MASK2lh (0xffff) -#define BN_MASK2h1 (0xffff8000L) -#define BN_MASK2h (0xffff0000L) -#define BN_TBIT (0x80000000L) -#define BN_DEC_CONV (1000000000L) -#define BN_DEC_FMT1 "%lu" -#define BN_DEC_FMT2 "%09lu" -#define BN_DEC_NUM 9 -#define BN_HEX_FMT "%08lX" -#endif - -#define BN_EXP_TABLE_SIZE 16 - -typedef struct bignum_st BIGNUM; - -struct bignum_st - { - BN_ULONG *d; /* Pointer to an array of 'BN_BITS2' bit chunks. */ - int top; /* Index of last used d +1. */ - /* The next are internal book keeping for bn_expand. */ - int max; /* Size of the d array. */ - int neg; /* one if the number is negative */ - int flags; - }; - -PRE_CCONV BN_ULONG CCONV bn_mul_add_words(BN_ULONG *rp,BN_ULONG *ap, - int num, BN_ULONG w); -PRE_CCONV BN_ULONG CCONV bn_mul_words(BN_ULONG *rp, BN_ULONG *ap, - int num, BN_ULONG w); -PRE_CCONV void CCONV bn_sqr_words(BN_ULONG *rp, BN_ULONG *ap, int num); -BN_ULONG CCONV bn_div_words(BN_ULONG h, BN_ULONG l, BN_ULONG d); -PRE_CCONV BN_ULONG CCONV bn_add_words(BN_ULONG *rp, BN_ULONG *ap, - BN_ULONG *bp,int num); -PRE_CCONV BN_ULONG CCONV bn_sub_words(BN_ULONG *rp, BN_ULONG *ap, - BN_ULONG *bp,int num); - -#ifndef BN_ME_METH -#define BN_ME_METH void -#endif - -#endif /* ! HEADER_COMMON_BN_H */ - -/* The follow define protected inclusions are excerpts from the - * header file r_error.h, this has been done, so that code written for the - * THX systems can be used in isolation from the library - * This code may need to be updated in line with changes to the r_error.h - * header file. - */ -#ifndef HEADER_COMMON_R_ERROR_H -#define HEADER_COMMON_R_ERROR_H - -/* The FATAL_INTERNAL_ERROR is a flag that is set with the following - * error codes: - * R_ERROR_INVALID_STATE - * R_ERROR_INIT_NOT_CALLED - * R_ERROR_SHOULD_NOT_HAVE_BEEN_CALLED - */ -#define R_ERROR_FATAL_INTERNAL_ERROR 64 - -/* The BAD_PARAMETER is a flag that is set with the following error - * codes: - * R_ERROR_NULL_ARG - * R_ERROR_BUFFER_TOO_SMALL - * R_ERROR_BAD_VALUE - * R_ERROR_BAD_RANGE - * R_ERROR_BAD_FORMAT - * R_ERROR_BAD_TYPE - * R_ERROR_BAD_DATA - * R_ERROR_BAD_LENGTH - */ -#define R_ERROR_BAD_PARAMETER 32 - -/* Base value for all general errors used through all products */ -#define R_ERROR_BASE 10000 - -#define R_ERROR_NONE 0 - -#define R_ERROR_FAILED (R_ERROR_BASE+1) -#define R_ERROR_IO (R_ERROR_BASE+2) -#define R_ERROR_PROTOCOL (R_ERROR_BASE+3) -#define R_ERROR_EOF (R_ERROR_BASE+4) -#define R_ERROR_ALLOC_FAILURE (R_ERROR_BASE+5) -#define R_ERROR_EVAL_RESTRICTION (R_ERROR_BASE+6) -#define R_ERROR_EVAL_EXPIRED (R_ERROR_BASE+7) -#define R_ERROR_NOT_FOUND (R_ERROR_BASE+8) -#define R_ERROR_NOT_AVAILABLE (R_ERROR_BASE+9) -#define R_ERROR_NOT_IMPLEMENTED (R_ERROR_BASE+10) -#define R_ERROR_NOT_SUPPORTED (R_ERROR_BASE+11) -#define R_ERROR_INVALID_STATE \ - ((R_ERROR_BASE+12) | R_ERROR_FATAL_INTERNAL_ERROR) -#define R_ERROR_INIT_NOT_CALLED \ - ((R_ERROR_BASE+13) | R_ERROR_FATAL_INTERNAL_ERROR) -#define R_ERROR_SHOULD_NOT_HAVE_BEEN_CALLED \ - ((R_ERROR_BASE+14) | R_ERROR_FATAL_INTERNAL_ERROR) -#define R_ERROR_METHOD_UNDEFINED \ - ((R_ERROR_BASE+15) | R_ERROR_FATAL_INTERNAL_ERROR) -#define R_ERROR_BUFFER_TOO_SMALL \ - ((R_ERROR_BASE+16) | R_ERROR_BAD_PARAMETER) -#define R_ERROR_NULL_ARG ((R_ERROR_BASE+17) | R_ERROR_BAD_PARAMETER) -#define R_ERROR_BAD_VALUE ((R_ERROR_BASE+18) | R_ERROR_BAD_PARAMETER) -#define R_ERROR_BAD_RANGE ((R_ERROR_BASE+19) | R_ERROR_BAD_PARAMETER) -#define R_ERROR_BAD_FORMAT ((R_ERROR_BASE+20) | R_ERROR_BAD_PARAMETER) -#define R_ERROR_BAD_TYPE ((R_ERROR_BASE+21) | R_ERROR_BAD_PARAMETER) -#define R_ERROR_BAD_DATA ((R_ERROR_BASE+22) | R_ERROR_BAD_PARAMETER) -#define R_ERROR_BAD_LENGTH ((R_ERROR_BASE+23) | R_ERROR_BAD_PARAMETER) -#define R_ERROR_RCOM_LIBRARY_NOT_SUPPORTED (R_ERROR_BASE+24) - -/* Resource Manager base for errors */ -#define R_COM_ERR_LIB_CTX_BASE 10100 - -#endif /* HEADER_COMMON_R_ERROR_H */ - - -const BN_ME_METH *BN_ME_METH_thxc(void); -/** - * @note THX code only needs to store rr, n0, str - * - */ -typedef struct thxc_mont_ctx_st - { - BIGNUM *rr; - unsigned char *str; - unsigned int str_len; - BN_ULONG n0; - } THXC_MONT_CTX; - - -int Rx_thxr_mod_exp_mont( BN_ULONG *result, BN_ULONG *ap, BN_ULONG *np, - BN_ULONG *rrp, BN_ULONG n0, int top, int tmp_len, unsigned char *str); - -int Ri_thxr_mod_exp_mont( BN_ULONG *result, BN_ULONG *ap, BN_ULONG *np, - BN_ULONG *rrp, BN_ULONG *dp, BN_ULONG *aap, BN_ULONG *rp, BN_ULONG *tmp, - BN_ULONG n0, int top, unsigned char *str); - -void Ri_thxr_mul_normal(BN_ULONG *r,BN_ULONG *a,int na,BN_ULONG *b,int nb); -void Ri_thxr_sqr_normal(BN_ULONG *r, BN_ULONG *a, int n, BN_ULONG *tmp); - -void Ri_thxr_from_montgomery_words(BN_ULONG *ret,BN_ULONG *ap,BN_ULONG *np, - int w, BN_ULONG n0); - -BN_ULONG Ri_thxr_from_mont_words(BN_ULONG *ap,BN_ULONG *wap, - BN_ULONG *np, int w, BN_ULONG n0); - -#ifdef CPU_TMS320 - -/* Method and functions required for the ARM/DSP interface */ - -const BN_ME_METH *BN_ME_METH_dspc(void); - -int Rx_dsp_mod_exp_mont( BN_ULONG *result, BN_ULONG *ap, BN_ULONG *np, - BN_ULONG *rrp, BN_ULONG n0, int top, int tmp_len, unsigned char *str); - -int Ri_dsp_mod_exp_mont( BN_ULONG *result, BN_ULONG *ap, BN_ULONG *np, - BN_ULONG *rrp, BN_ULONG *dp, BN_ULONG *aap, BN_ULONG *rp, BN_ULONG *tmp, - BN_ULONG n0, int top, unsigned char *str); - -#endif - -#ifdef __cplusplus -} -#endif -#endif /* HEADER_COMMON_BN_THX_H */ diff --git a/build/tools/acsign/include/r_error.h b/build/tools/acsign/include/r_error.h deleted file mode 100644 index 8e269f36..00000000 --- a/build/tools/acsign/include/r_error.h +++ /dev/null @@ -1,210 +0,0 @@ -/* $Id$ */ -/* - * Copyright (C) 1998-2002 RSA Security Inc. All rights reserved. - * - * This work contains proprietary information of RSA Security. - * Distribution is limited to authorized licensees of RSA - * Security. Any unauthorized reproduction, distribution or - * modification of this work is strictly prohibited. - * - */ -/** - * @file r_error.h - * This file contains the error definitions for the toolkit. - */ -#ifndef HEADER_COMMON_R_ERROR_H -#define HEADER_COMMON_R_ERROR_H - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * @defgroup R_ERROR_IDS Error Identifiers - * This section outlines the error codes returned, enabling identification of - * specific errors. For more information, see the - * Developer's Guide. - * - * @{ - */ -/** - * Indicates that a fatal error has occurred in the operation performed. - * This flag is set with the following error codes:
- *
    - *
  • #R_ERROR_INVALID_STATE.
  • - *
  • #R_ERROR_INIT_NOT_CALLED.
  • - *
  • #R_ERROR_SHOULD_NOT_HAVE_BEEN_CALLED.
  • - *
- */ -#define R_ERROR_FATAL_INTERNAL_ERROR 64 - -/** - * Indicates that the specified parameter is incorrect or contains invalid - * information. This flag is set with the following error codes:
- *
    - *
  • #R_ERROR_NULL_ARG.
  • - *
  • #R_ERROR_BUFFER_TOO_SMALL.
  • - *
  • #R_ERROR_BAD_VALUE.
  • - *
  • #R_ERROR_BAD_RANGE.
  • - *
  • #R_ERROR_BAD_FORMAT.
  • - *
  • #R_ERROR_BAD_TYPE.
  • - *
  • #R_ERROR_BAD_DATA.
  • - *
  • #R_ERROR_BAD_LENGTH.
  • - *
- */ -#define R_ERROR_BAD_PARAMETER 32 - -/* Indicates the base value for all general errors used through all products */ -#define R_ERROR_BASE 10000 - -/** - * Indicates that no errors were detected in the requested operation. - */ -#define R_ERROR_NONE 0 - -/** - * Indicates that the requested operation failed. - */ -#define R_ERROR_FAILED (R_ERROR_BASE+1) -/** - * Indicates that the requested operation detected an Input/Output error. - */ -#define R_ERROR_IO (R_ERROR_BASE+2) -/** - * Indicates that the requested operation detected a protocol error. - */ -#define R_ERROR_PROTOCOL (R_ERROR_BASE+3) -/** - * Indicates that the requested operation detected an End-of-File (EOF) error. - */ -#define R_ERROR_EOF (R_ERROR_BASE+4) -/** - * Indicates that the requested operation failed in a memory allocation - * operation. - */ -#define R_ERROR_ALLOC_FAILURE (R_ERROR_BASE+5) -/** - * Indicates that the requested operation is restricted in an evaluation - * version of the library. - */ -#define R_ERROR_EVAL_RESTRICTION (R_ERROR_BASE+6) -/** - * Indicates that the evaluation period of the library has expired. - */ -#define R_ERROR_EVAL_EXPIRED (R_ERROR_BASE+7) -/** - * Indicates that the requested operation detected that a pre-requirement was - * not found. - */ -#define R_ERROR_NOT_FOUND (R_ERROR_BASE+8) -/** - * Indicates that the requested operation detected that a pre-requirement was - * unavailable. - */ -#define R_ERROR_NOT_AVAILABLE (R_ERROR_BASE+9) -/** - * Indicates that the requested operation is not implemented in the current - * instantiation of the library. - */ -#define R_ERROR_NOT_IMPLEMENTED (R_ERROR_BASE+10) -/** - * Indicates that the requested operation is not supported in the current - * instantiation of the library. - */ -#define R_ERROR_NOT_SUPPORTED (R_ERROR_BASE+11) -/** - * Indicates that the requested operation entered an invalid state. - */ -#define R_ERROR_INVALID_STATE \ - ((R_ERROR_BASE+12) | R_ERROR_FATAL_INTERNAL_ERROR) -/** - * Indicates that the requested operation detected that an initialization - * operation has not been performed. - */ -#define R_ERROR_INIT_NOT_CALLED \ - ((R_ERROR_BASE+13) | R_ERROR_FATAL_INTERNAL_ERROR) -/** - * Indicates that the requested operation should not have been called. - */ -#define R_ERROR_SHOULD_NOT_HAVE_BEEN_CALLED \ - ((R_ERROR_BASE+14) | R_ERROR_FATAL_INTERNAL_ERROR) -/** - * Indicates that the requested method is not defined. - */ -#define R_ERROR_METHOD_UNDEFINED \ - ((R_ERROR_BASE+15) | R_ERROR_FATAL_INTERNAL_ERROR) -/** - * Indicates that the requested operation detected an inadequately sized - * buffer. - */ -#define R_ERROR_BUFFER_TOO_SMALL \ - ((R_ERROR_BASE+16) | R_ERROR_BAD_PARAMETER) -/** - * Indicates that the requested operation detected that a required argument - * was passed as NULL. - */ -#define R_ERROR_NULL_ARG ((R_ERROR_BASE+17) | R_ERROR_BAD_PARAMETER) -/** - * Indicates that the requested operation detected that a required argument - * passed contained a bad or incorrect value. - */ -#define R_ERROR_BAD_VALUE ((R_ERROR_BASE+18) | R_ERROR_BAD_PARAMETER) -/** - * Indicates that the requested operation detected that a required argument - * passed was out of the allowed range. - */ -#define R_ERROR_BAD_RANGE ((R_ERROR_BASE+19) | R_ERROR_BAD_PARAMETER) -/** - * Indicates that the requested operation detected that a required argument - * passed used a format that is not supported or incorrect. - */ -#define R_ERROR_BAD_FORMAT ((R_ERROR_BASE+20) | R_ERROR_BAD_PARAMETER) -/** - * Indicates that the requested operation detected that a required argument - * passed used a type that is not supported or incorrect. - */ -#define R_ERROR_BAD_TYPE ((R_ERROR_BASE+21) | R_ERROR_BAD_PARAMETER) -/** - * Indicates that the requested operation detected that a required argument - * passed contained incorrect or invalid data. - */ -#define R_ERROR_BAD_DATA ((R_ERROR_BASE+22) | R_ERROR_BAD_PARAMETER) -/** - * Indicates that the requested operation detected that a required argument - * passed contained an incorrect length value. - */ -#define R_ERROR_BAD_LENGTH ((R_ERROR_BASE+23) | R_ERROR_BAD_PARAMETER) -/** - * Indicates that the library instantiation requested is not supported. - */ -#define R_ERROR_RCOM_LIBRARY_NOT_SUPPORTED (R_ERROR_BASE+24) -/** - * Indicates that the request operation was denied. - */ -#define R_ERROR_DENIED (R_ERROR_BASE+25) -/** - * Indicates that authentication is required before the operation - * can succeed. - */ -#define R_ERROR_AUTHENTICATION_REQUIRED (R_ERROR_BASE+26) - -/** - * Indicates that a required module was unable to be loaded. - */ -#define R_ERROR_MODULE_LOAD_FAILED \ - ((R_ERROR_BASE+27)|R_ERROR_FATAL_INTERNAL_ERROR) - -/* Resource Manager base for errors */ -#define R_COM_ERR_LIB_CTX_BASE 10100 - -/** - * @} - */ - -#ifdef __cplusplus -} -#endif -#endif /* HEADER_COMMON_R_ERROR_H */ - - - diff --git a/build/tools/acsign/include/r_stdiag.h b/build/tools/acsign/include/r_stdiag.h deleted file mode 100644 index 566de6fa..00000000 --- a/build/tools/acsign/include/r_stdiag.h +++ /dev/null @@ -1,82 +0,0 @@ -/* $Id$ */ -/* - * Copyright (C) 1998-2002 RSA Security Inc. All rights reserved. - * - * This work contains proprietary information of RSA Security. - * Distribution is limited to authorized licensees of RSA - * Security. Any unauthorized reproduction, distribution or - * modification of this work is strictly prohibited. - * - */ - -/* - * *************************************************************************** - * - * Purpose: - * - * This file defines an API for performing stack diagnostics. - * - * It provides: - * Peek Stack Usage statistics - * To use it: - * 1. Build the library without "NO_R_DIAG" defined - * 2. Make a call to R_DIAG_set_stack_datum() prior to - * calling the first library function. - * 3. Add calls to the macro R_DIAG_CHECK_STACK where potential - * high stack usage points are. - * 4. Call R_DIAG_get_stack_low_water_mark() at then end of the - * library calls to return the maximum stack usage OR - * 5. Call R_DIAG_print_stack_depth() to display the peek stack - * usage - * - * - * - * History: - * 3-Aug-00 mjs development - * - * ************************************************************************** - */ - - -#ifndef HEADER_COMMON_R_STDIAG_H -#define HEADER_COMMON_R_STDIAG_H - -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef NO_R_DIAG - -#ifdef NOPROTO -int R_DIAG_set_stack_datum(char *ptr); -int R_DIAG_check_stack(char *ptr, char *file, int line, int hit); -int R_DIAG_get_stack_low_water_mark(int *depth, char **file, int *line, - int *hit); -int R_DIAG_print_stack_depth(BIO *bio); - -#else - -int R_DIAG_set_stack_datum(); -int R_DIAG_check_stack(); -int R_DIAG_get_stack_low_water_mark(); -int R_DIAG_print_stack_depth(); - -#endif - -#define R_DIAG_CHECK_STACK {\ - char r_diag_stack_check_var = 0;\ - static int r_diag_stack_check_cnt = 0;\ -\ - R_DIAG_check_stack(&r_diag_stack_check_var, __FILE__,\ - __LINE__,++r_diag_stack_check_cnt);\ - } -#else -#define R_DIAG_CHECK_STACK -#endif - - -#ifdef __cplusplus -} -#endif -#endif /* HEADER_COMMON_R_STDIAG_H */ - diff --git a/build/tools/acsign/include/r_types.h b/build/tools/acsign/include/r_types.h deleted file mode 100644 index d35556ad..00000000 --- a/build/tools/acsign/include/r_types.h +++ /dev/null @@ -1,241 +0,0 @@ -/* $Id$ */ -/* - * Copyright (C) 1998-2002 RSA Security Inc. All rights reserved. - * - * This work contains proprietary information of RSA Security. - * Distribution is limited to authorized licensees of RSA - * Security. Any unauthorized reproduction, distribution or - * modification of this work is strictly prohibited. - * - */ -/** - * @file r_types.h - * This file contains the library structure and type definitions. - */ -#ifndef HEADER_COMMON_R_TYPES_H -#define HEADER_COMMON_R_TYPES_H - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * @defgroup DATA_MNG_FLAGS Data Management Flags - * This section lists the data management flags. - * @{ - */ - -/** - * @} - */ - -/* This gets set if the flags field if the we need to 'free' the - * R_RANDOM when we call R_rand_free(). If it is not set, the - * rand_ctrl will only be called to clean things up. - */ -#define R_RANDOM_FLG_MALLOCED 0x01 - -/* portable form of a random callback function */ -/** - * @typedef R_RANDOM - * The random object type. - */ -typedef struct r_random_st R_RANDOM; -/** - * This structure is used by the random object type. - */ -struct r_random_st -{ - /** - * A method function for generation of random data. - * - * @see R_rand_bytes(). - */ - int (*rand_bytes)(R_RANDOM *ctx,unsigned char *bytes,int len); - /** - * A method function for seeding of the random generator. - * @see R_rand_seed(). - */ - int (*rand_seed)(R_RANDOM *ctx,unsigned char *bytes,int len); - /** - * A method function for control of the random generator used by - * other functions as a single interface. - * - * @see R_rand_entropy_count(), R_rand_set_entropy_func(), - * R_rand_get_entropy_func(), R_rand_load_file(), R_rand_write_file() - * and R_rand_file_name(). - */ - int (*rand_ctrl)(R_RANDOM *ctx,int op,char *arg); - /** - * The data used by the random implementation. - */ - char *arg; - /** - * A method flag for used for keeping the state of the #R_RANDOM. - */ - int flags; /* normally set to zero */ -}; -/** - * @typedef R_SURRENDER - * The surrender function and argument. - */ -typedef struct r_surrender_st R_SURRENDER; -/** - * This structure provides a status update of a time intensive operation. It - * also allows you to abort the operation if required. - */ -struct r_surrender_st -{ - /* Return 0 to continue, non-zero to 'cancel' function */ - /** - * The surrender function pointer used as a generic method of - * passing user-defined callback or information collection functions. - */ - int (*callback)(R_SURRENDER *ctx,int function,int num); - /** - * The argument data used by the callback operation. - */ - char *arg; -}; - -typedef struct r_fixed_point_number_st R_FIXED_POINT_NUMBER; -struct r_fixed_point_number_st -{ - unsigned long hi; - unsigned long lo; -}; - -/** - * @typedef R_INDEXED_INFO - * This structure details the index containing information for get and set - * functions. - */ -typedef struct r_indexed_info_st R_INDEXED_INFO; -/** This structure details the index containing information for get and set - * functions. - */ -struct r_indexed_info_st -{ - /** The index into the list of the item to work with. */ - int index; - /** The data of the item in the list. */ - void *data; - /** The length of the data. */ - unsigned int len; - /** The data value as an integer. */ - int value; -}; - -/** - * @typedef R_ID_INFO - * The information to work with requires a second identity value to find it. - */ -typedef struct r_id_info_st R_ID_INFO; -/** The information to get or set requires a second information identifier. - * This type is used when calling set_info and get_info to get a number of - * information items in one call. - */ -struct r_id_info_st -{ - /** The information identifier. */ - int info_id; - /** The information data associated with the identifier. */ - void *value; -}; - -/** @defgroup R_FLAG_COPY_IDS Copy Flag Identifiers - * - * This section provides information on the copy mode. When data is passed - * to/from the library you can specify whether or not the copy should be done - * by value, by reference or by direct assignment. - * @ingroup DATA_MNG_FLAGS - * @{ - */ - -/** - * The copy flag. When data is passed to/from the library you can specify - * whether or not the copy should be done by value, by reference or - * by direct assignment. - */ -typedef int R_FLAG_COPY; - -/* - * action flag app lib - * obj_get BY_VAL F X - * BY_REF X F [app will not free "obj" until it is - * BY_ASSIGN F X finished with the returned reference] - * obj_set BY_VAL F X - * BY_REF F X [app will not free passed reference - * BY_ASSIGN X F until after it has freed "obj"] - * - * BY_REF makes the lifetime of the two objects linked and it is up to - * the application to manage the objects in a manner that preserves this - * relationship. - */ - -/** - * Indicates to copy by value. A complete clone of the object is made. - * The lifecycles of the two objects are independent. - */ -#define R_FLAG_COPY_BY_VALUE 0x0000 - -/** - * Indicates to copy by reference. A reference to the object is made. - * The lifecycles of objects sharing references are linked. - */ -#define R_FLAG_COPY_BY_REFERENCE 0x0001 - -/** - * Indicates to copy by assignment. The object is assigned to the required - * party. The caller does not keep a reference to the passed object. - */ -#define R_FLAG_COPY_BY_ASSIGN 0x0002 - -/** - * Indicates to copy using the default flag settings. - */ -#define R_FLAG_COPY_DEFAULT R_FLAG_COPY_BY_VALUE - -/** - * @} - */ - -/** @defgroup R_FLAG_SHARE_IDS Shared Flag Identifiers - * - * This section provides information on the shared flags available. - * @ingroup DATA_MNG_FLAGS - * @{ - */ - -/** - * The constructor flag. Indicates whether or not it is permissible to share - * the internal state between objects. - */ -typedef int R_FLAG_SHARE; - -/** - * Indicates to share nothing. The states of the two objects are completely - * separate. - */ -#define R_FLAG_SHARE_NONE 0x0000 - -/** - * Indicates to share data. Constructed objects may reference the state of - * the object from which it was constructed. The lifecycles of the two objects - * are linked. - */ -#define R_FLAG_SHARE_DATA 0x0001 - -/** Indicates the share default in which nothing is shared. */ -#define R_FLAG_SHARE_DEFAULT R_FLAG_SHARE_NONE - -/** - * @} - */ - -#ifdef __cplusplus -} -#endif - -#endif - diff --git a/build/tools/acsign/include/sha.h b/build/tools/acsign/include/sha.h deleted file mode 100644 index d6eeed2b..00000000 --- a/build/tools/acsign/include/sha.h +++ /dev/null @@ -1,89 +0,0 @@ -/* $Id$ */ -/* - * Copyright (C) 1998-2002 RSA Security Inc. All rights reserved. - * - * This work contains proprietary information of RSA Security. - * Distribution is limited to authorized licensees of RSA - * Security. Any unauthorized reproduction, distribution or - * modification of this work is strictly prohibited. - * - */ - -#ifndef HEADER_COMMON_SHA_H -#define HEADER_COMMON_SHA_H - -#ifdef __cplusplus -extern "C" { -#endif - -#if !defined(CCONV) -#define CCONV -#endif - -#ifndef PRE_CCONV -#define PRE_CCONV -#endif - -#define SHA_CBLOCK 64 -#define SHA_LBLOCK 16 -#define SHA_BLOCK 16 -#define SHA_LAST_BLOCK 56 -#define SHA_LENGTH_BLOCK 8 -#define SHA_DIGEST_LENGTH 20 - -/* the default is to use unsigned long */ -#if !defined(OPT_SHA_INT) && !defined(OPT_SHA_LONG) -#define OPT_SHA_LONG -#endif - -#ifdef OPT_SHA_LONG -#define SHA_LONG unsigned long -#endif - -#ifdef OPT_SHA_INT -#define SHA_LONG unsigned int -#endif - -typedef struct sha_ctx_st SHA_CTX; - -struct sha_ctx_st - { - SHA_LONG h0,h1,h2,h3,h4; - SHA_LONG Nl,Nh; - SHA_LONG data[SHA_LBLOCK]; - int num; - void (PRE_CCONV CCONV *sha_block)(SHA_CTX *c, const unsigned char *W, - int num); - }; - -#ifndef NOPROTO -int SHA1_Setup(SHA_CTX *c, void (PRE_CCONV CCONV *sha_block)(SHA_CTX *c, - const unsigned char *W, int num)); -void SHA_Init(SHA_CTX *c); -void SHA_Update(SHA_CTX *c, const unsigned char *data, unsigned long len); -void SHA_Final(unsigned char *md, SHA_CTX *c); -unsigned char *SHA(const unsigned char *d, unsigned long n,unsigned char *md); -void SHA_Transform(SHA_CTX *c, const unsigned char *data); -void SHA1_Init(SHA_CTX *c); -void SHA1_Update(SHA_CTX *c, const unsigned char *data, unsigned long len); -void SHA1_Final(unsigned char *md, SHA_CTX *c); -unsigned char *SHA1(const unsigned char *d, unsigned long n,unsigned char *md); -void SHA1_Transform(SHA_CTX *c, const unsigned char *data); -#else -void SHA_Init(); -void SHA_Update(); -void SHA_Final(); -unsigned char *SHA(); -void SHA_Transform(); -void SHA1_Init(); -void SHA1_Update(); -void SHA1_Final(); -unsigned char *SHA1(); -void SHA1_Transform(); -#endif - -#ifdef __cplusplus -} -#endif - -#endif /* HEADER_COMMON_SHA_H */ diff --git a/build/tools/acsign/include/sha1.h b/build/tools/acsign/include/sha1.h deleted file mode 100644 index ed4a672e..00000000 --- a/build/tools/acsign/include/sha1.h +++ /dev/null @@ -1,73 +0,0 @@ -/* - * sha1.h - * - * Description: - * This is the header file for code which implements the Secure - * Hashing Algorithm 1 as defined in FIPS PUB 180-1 published - * April 17, 1995. - * - * Many of the variable names in this code, especially the - * single character names, were used because those were the names - * used in the publication. - * - * Please read the file sha1.c for more information. - * - */ - -#ifndef _SHA1_H_ -#define _SHA1_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef _SHA_enum_ -#define _SHA_enum_ -enum -{ - shaSuccess = 0, - shaNull, /* Null pointer parameter */ - shaInputTooLong, /* input data too long */ - shaStateError /* called Input after Result */ -}; -#endif - -/* - * This structure will hold context information for the SHA-1 - * hashing operation - */ -typedef struct SHA1Context -{ - unsigned long Intermediate_Hash[20/4]; /* Message Digest */ - - unsigned long Length_Low; /* Message length in bits */ - unsigned long Length_High; /* Message length in bits */ - - int Message_Block_Index; /* Index into message block array */ - unsigned char Message_Block[64]; /* 512-bit message blocks */ - - int Computed; /* Is the digest computed? */ - int Corrupted; /* Is the message digest corrupted? */ -} SHA1Context; - -/* - * Function Prototypes - */ - -int SHA1Reset( SHA1Context *); -int SHA1Input( SHA1Context *, - const unsigned char *, - unsigned int); -int SHA1Result( SHA1Context *, - unsigned char Message_Digest[20]); - -#if defined( SHA1_TEST ) -int SHA1Test( ); -#endif // SHA1_TEST - - -#ifdef __cplusplus -} -#endif - -#endif // _SHA1_H_ diff --git a/build/tools/acsign/include/sha_locl.h b/build/tools/acsign/include/sha_locl.h deleted file mode 100644 index 2361282b..00000000 --- a/build/tools/acsign/include/sha_locl.h +++ /dev/null @@ -1,274 +0,0 @@ -/* $Id$ */ -/* - * Copyright (C) 1998-2002 RSA Security Inc. All rights reserved. - * - * This work contains proprietary information of RSA Security. - * Distribution is limited to authorized licensees of RSA - * Security. Any unauthorized reproduction, distribution or - * modification of this work is strictly prohibited. - * - */ - -#ifndef HEADER_COMMON_SHA_LOCL_H -#define HEADER_COMMON_SHA_LOCL_H - -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef STANDALONE -//#include "r_com.h" -#else -#if 1 //RSA -#include -#include -#include -//#define Memcpy memcpy -//#define Memset memset -#define Strcpy strcpy -#else //NITRO -#include "acmemory.h" -#define Malloc(a) ACMemory_Alloc(a) -#define Free(a) ACMemory_Free(a) -#define Memset(a,b,c) ACMemory_Memset(a,b,c) -#define Memcpy(a,b,c) ACMemory_Memcpy(a,b,c) -#endif -#endif - -#ifdef undef -/* one or the other must be defined */ -#ifndef SHA_1 /* FIPE 180-1 */ -#define SHA_0 /* FIPS 180 */ -#endif -#endif - -#define ULONG unsigned long -#define UCHAR unsigned char -#define UINT unsigned int - -#ifdef NOCONST -#define const -#endif - -#undef c2nl -#define c2nl(c,l) (l =(((unsigned long)(*((c)++)))<<24), \ - l|=(((unsigned long)(*((c)++)))<<16), \ - l|=(((unsigned long)(*((c)++)))<< 8), \ - l|=(((unsigned long)(*((c)++))) )) - -#undef p_c2nl -#define p_c2nl(c,l,n) { \ - switch (n) { \ - case 0: l =((unsigned long)(*((c)++)))<<24; \ - case 1: l|=((unsigned long)(*((c)++)))<<16; \ - case 2: l|=((unsigned long)(*((c)++)))<< 8; \ - case 3: l|=((unsigned long)(*((c)++))); \ - } \ - } - -#undef c2nl_p -/* NOTE the pointer is not incremented at the end of this */ -#define c2nl_p(c,l,n) { \ - l=0; \ - (c)+=n; \ - switch (n) { \ - case 3: l =((unsigned long)(*(--(c))))<< 8; \ - case 2: l|=((unsigned long)(*(--(c))))<<16; \ - case 1: l|=((unsigned long)(*(--(c))))<<24; \ - } \ - } - -#undef p_c2nl_p -#define p_c2nl_p(c,l,sc,len) { \ - switch (sc) \ - { \ - case 0: l =((unsigned long)(*((c)++)))<<24; \ - if (--len == 0) break; \ - case 1: l|=((unsigned long)(*((c)++)))<<16; \ - if (--len == 0) break; \ - case 2: l|=((unsigned long)(*((c)++)))<< 8; \ - } \ - } - -#undef nl2c -#define nl2c(l,c) (*((c)++)=(unsigned char)(((l)>>24)&0xff), \ - *((c)++)=(unsigned char)(((l)>>16)&0xff), \ - *((c)++)=(unsigned char)(((l)>> 8)&0xff), \ - *((c)++)=(unsigned char)(((l) )&0xff)) - -#undef c2l -#define c2l(c,l) (l =(((unsigned long)(*((c)++))) ), \ - l|=(((unsigned long)(*((c)++)))<< 8), \ - l|=(((unsigned long)(*((c)++)))<<16), \ - l|=(((unsigned long)(*((c)++)))<<24)) - -#undef p_c2l -#define p_c2l(c,l,n) { \ - switch (n) { \ - case 0: l =((unsigned long)(*((c)++))); \ - case 1: l|=((unsigned long)(*((c)++)))<< 8; \ - case 2: l|=((unsigned long)(*((c)++)))<<16; \ - case 3: l|=((unsigned long)(*((c)++)))<<24; \ - } \ - } - -#undef c2l_p -/* NOTE the pointer is not incremented at the end of this */ -#define c2l_p(c,l,n) { \ - l=0; \ - (c)+=n; \ - switch (n) { \ - case 3: l =((unsigned long)(*(--(c))))<<16; \ - case 2: l|=((unsigned long)(*(--(c))))<< 8; \ - case 1: l|=((unsigned long)(*(--(c)))); \ - } \ - } - -#undef p_c2l_p -#define p_c2l_p(c,l,sc,len) { \ - switch (sc) \ - { \ - case 0: l =((unsigned long)(*((c)++))); \ - if (--len == 0) break; \ - case 1: l|=((unsigned long)(*((c)++)))<< 8; \ - if (--len == 0) break; \ - case 2: l|=((unsigned long)(*((c)++)))<<16; \ - } \ - } - -#undef l2c -#define l2c(l,c) (*((c)++)=(unsigned char)(((l) )&0xff), \ - *((c)++)=(unsigned char)(((l)>> 8)&0xff), \ - *((c)++)=(unsigned char)(((l)>>16)&0xff), \ - *((c)++)=(unsigned char)(((l)>>24)&0xff)) - -#ifdef OPT_SHA_B_ENDIAN -#define B_ENDIAN -#endif -#ifdef OPT_SHA_L_ENDIAN -#define L_ENDIAN -#endif - -#undef ROTATE -#if defined(WIN32) -#define ROTATE(a,n) _lrotl(a,n) -#else -#define ROTATE(a,n) (((a)<<(n))|(((a)&0xffffffff)>>(32-(n)))) -#endif - -/* byte order reversal */ -#if defined(WIN32) -/* 5 instructions with rotate instruction, else 9 */ -#define Endian_Reverse32(a) \ - { \ - unsigned long l=(a); \ - (a)=((ROTATE(l,8)&0x00FF00FF)|(ROTATE(l,24)&0xFF00FF00)); \ - } -#else -/* 6 instructions with rotate instruction, else 8 */ -#define Endian_Reverse32(a) \ - { \ - unsigned long l=(a); \ - l=(((l&0xFF00FF00)>>8L)|((l&0x00FF00FF)<<8L)); \ - (a)=ROTATE(l,16L); \ - } -#endif - -/* F() below can be - * simplified to the code in F_00_19. - * #define F(x,y,z) (((x) & (y)) | ((~(x)) & (z))) - * another tweak to be made - * in F_40_59, (x&a)|(y&a) -> (x|y)&a - */ -#define F_00_19(b,c,d) ((((c) ^ (d)) & (b)) ^ (d)) -#define F_20_39(b,c,d) ((b) ^ (c) ^ (d)) -#define F_40_59(b,c,d) (((b) & (c)) | (((b)|(c)) & (d))) -#define F_60_79(b,c,d) F_20_39(b,c,d) - -#ifdef SHA_0 -#undef Xupdate -#define Xupdate(a,i,ia,ib,ic,id) X[(i)&0x0f]=(a)=\ - (ia[(i)&0x0f]^ib[((i)+2)&0x0f]^ic[((i)+8)&0x0f]^id[((i)+13)&0x0f]); -#endif -#ifdef SHA_1 -#undef Xupdate -#define Xupdate(a,i,ia,ib,ic,id) (a)=\ - (ia[(i)&0x0f]^ib[((i)+2)&0x0f]^ic[((i)+8)&0x0f]^id[((i)+13)&0x0f]);\ - X[(i)&0x0f]=(a)=ROTATE((a),1); -#endif - -#define BODY_00_15(i,a,b,c,d,e,f,xa) \ - (f)=xa[i]+(e)+K_00_19+ROTATE((a),5)+F_00_19((b),(c),(d)); \ - (b)=ROTATE((b),30); - -#define BODY_60_79(i,a,b,c,d,e,f,xa) \ - Xupdate(f,i,xa,xa,xa,xa); \ - (f)=X[(i)&0x0f]+(e)+K_60_79+ROTATE((a),5)+F_60_79((b),(c),(d)); \ - (b)=ROTATE((b),30); - -/* - * The CodeWarrior compiler has a problem correctly expanding things like - * - * (f)+=(e)+K_00_19+ROTATE((a),5)+F_00_19((b),(c),(d)); - * - * so we separate this to 3 explicit adds, just for PalmOS. - */ -#ifndef UNDER_PALMOS - -#define BODY_16_19(i,a,b,c,d,e,f,xa,xb,xc,xd) \ - Xupdate(f,i,xa,xb,xc,xd); \ - (f)+=(e)+K_00_19+ROTATE((a),5)+F_00_19((b),(c),(d)); \ - (b)=ROTATE((b),30); - -#define BODY_20_31(i,a,b,c,d,e,f,xa,xb,xc,xd) \ - Xupdate(f,i,xa,xb,xc,xd); \ - (f)+=(e)+K_20_39+ROTATE((a),5)+F_20_39((b),(c),(d)); \ - (b)=ROTATE((b),30); - -#define BODY_32_39(i,a,b,c,d,e,f,xa) \ - Xupdate(f,i,xa,xa,xa,xa); \ - (f)+=(e)+K_20_39+ROTATE((a),5)+F_20_39((b),(c),(d)); \ - (b)=ROTATE((b),30); - -#define BODY_40_59(i,a,b,c,d,e,f,xa) \ - Xupdate(f,i,xa,xa,xa,xa); \ - (f)+=(e)+K_40_59+ROTATE((a),5)+F_40_59((b),(c),(d)); \ - (b)=ROTATE((b),30); - -#else /* UNDER_PALMOS */ - -#define BODY_16_19(i,a,b,c,d,e,f,xa,xb,xc,xd) \ - Xupdate(f,i,xa,xb,xc,xd); \ - (f)+=(e); \ - (f)+=K_00_19; \ - (f)+=ROTATE((a),5)+F_00_19((b),(c),(d)); \ - (b)=ROTATE((b),30); - -#define BODY_20_31(i,a,b,c,d,e,f,xa,xb,xc,xd) \ - Xupdate(f,i,xa,xb,xc,xd); \ - (f)+=(e); \ - (f)+=K_20_39; \ - (f)+=ROTATE((a),5)+F_20_39((b),(c),(d)); \ - (b)=ROTATE((b),30); - -#define BODY_32_39(i,a,b,c,d,e,f,xa) \ - Xupdate(f,i,xa,xa,xa,xa); \ - (f)+=(e); \ - (f)+=K_20_39; \ - (f)+=ROTATE((a),5)+F_20_39((b),(c),(d)); \ - (b)=ROTATE((b),30); - -#define BODY_40_59(i,a,b,c,d,e,f,xa) \ - Xupdate(f,i,xa,xa,xa,xa); \ - (f)+=(e); \ - (f)+=K_40_59; \ - (f)+=ROTATE((a),5)+F_40_59((b),(c),(d)); \ - (b)=ROTATE((b),30); - -#endif /* UNDER_PALMOS */ - -#ifdef __cplusplus -} -#endif - -#endif /* HEADER_COMMON_SHA_LOCL_H */ diff --git a/build/tools/acsign/sha1.c b/build/tools/acsign/sha1.c deleted file mode 100644 index 6bebd125..00000000 --- a/build/tools/acsign/sha1.c +++ /dev/null @@ -1,453 +0,0 @@ -/* - * sha1.c - * - * Description: - * This file implements the Secure Hashing Algorithm 1 as - * defined in FIPS PUB 180-1 published April 17, 1995. - * - * The SHA-1, produces a 160-bit message digest for a given - * data stream. It should take about 2**n steps to find a - * message with the same digest as a given message and - * 2**(n/2) to find any two messages with the same digest, - * when n is the digest size in bits. Therefore, this - * algorithm can serve as a means of providing a - * "fingerprint" for a message. - * - * Portability Issues: - * SHA-1 is defined in terms of 32-bit "words". This code - * uses (included via "sha1.h" to define 32 and 8 - * bit unsigned integer types. If your C compiler does not - * support 32 bit unsigned integers, this code is not - * appropriate. - * - * Caveats: - * SHA-1 is designed to work with messages less than 2^64 bits - * long. Although SHA-1 allows a message digest to be generated - * for messages of any number of bits less than 2^64, this - * implementation only works with messages with a length that is - * a multiple of the size of an 8-bit character. - * - */ - -#include "sha1.h" - -/* - * Define the SHA1 circular left shift macro - */ -#define SHA1CircularShift(bits,word) \ - (((word) << (bits)) | ((word) >> (32-(bits)))) - -/* Local Function Prototyptes */ -void SHA1PadMessage(SHA1Context *); -void SHA1ProcessMessageBlock(SHA1Context *); - -/* - * SHA1Reset - * - * Description: - * This function will initialize the SHA1Context in preparation - * for computing a new SHA1 message digest. - * - * Parameters: - * context: [in/out] - * The context to reset. - * - * Returns: - * sha Error Code. - * - */ -int SHA1Reset(SHA1Context *context) -{ - if (!context) - { - return shaNull; - } - - context->Length_Low = 0; - context->Length_High = 0; - context->Message_Block_Index = 0; - - context->Intermediate_Hash[0] = 0x67452301; - context->Intermediate_Hash[1] = 0xEFCDAB89; - context->Intermediate_Hash[2] = 0x98BADCFE; - context->Intermediate_Hash[3] = 0x10325476; - context->Intermediate_Hash[4] = 0xC3D2E1F0; - - context->Computed = 0; - context->Corrupted = 0; - - return shaSuccess; -} - -/* - * SHA1Result - * - * Description: - * This function will return the 160-bit message digest into the - * Message_Digest array provided by the caller. - * NOTE: The first octet of hash is stored in the 0th element, - * the last octet of hash in the 19th element. - * - * Parameters: - * context: [in/out] - * The context to use to calculate the SHA-1 hash. - * Message_Digest: [out] - * Where the digest is returned. - * - * Returns: - * sha Error Code. - * - */ -int SHA1Result( SHA1Context *context, - unsigned char Message_Digest[20]) -{ - int i; - - if (!context || !Message_Digest) - { - return shaNull; - } - - if (context->Corrupted) - { - return context->Corrupted; - } - - if (!context->Computed) - { - SHA1PadMessage(context); - for(i=0; i<64; ++i) - { - /* message may be sensitive, clear it out */ - context->Message_Block[i] = 0; - } - context->Length_Low = 0; /* and clear length */ - context->Length_High = 0; - context->Computed = 1; - - } - - for(i = 0; i < 20; ++i) - { - Message_Digest[i] = (unsigned char) - (context->Intermediate_Hash[i>>2] - >> 8 * ( 3 - ( i & 0x03 ) )); - } - - return shaSuccess; -} - -/* - * SHA1Input - * - * Description: - * This function accepts an array of octets as the next portion - * of the message. - * - * Parameters: - * context: [in/out] - * The SHA context to update - * message_array: [in] - * An array of characters representing the next portion of - * the message. - * length: [in] - * The length of the message in message_array - * - * Returns: - * sha Error Code. - * - */ -int SHA1Input( SHA1Context *context, - const unsigned char *message_array, - unsigned int length) -{ - if (!length) - { - return shaSuccess; - } - - if (!context || !message_array) - { - return shaNull; - } - - if (context->Computed) - { - context->Corrupted = shaStateError; - - return shaStateError; - } - - if (context->Corrupted) - { - return context->Corrupted; - } - while(length-- && !context->Corrupted) - { - context->Message_Block[context->Message_Block_Index++] = - (unsigned char)(*message_array & 0xFF); - - context->Length_Low += 8; - if (context->Length_Low == 0) - { - context->Length_High++; - if (context->Length_High == 0) - { - /* Message is too long */ - context->Corrupted = 1; - } - } - - if (context->Message_Block_Index == 64) - { - SHA1ProcessMessageBlock(context); - } - - message_array++; - } - - return shaSuccess; -} - -/* - * SHA1ProcessMessageBlock - * - * Description: - * This function will process the next 512 bits of the message - * stored in the Message_Block array. - * - * Parameters: - * None. - * - * Returns: - * Nothing. - * - * Comments: - * - * Many of the variable names in this code, especially the - * single character names, were used because those were the - * names used in the publication. - * - * - */ -void SHA1ProcessMessageBlock(SHA1Context *context) -{ - const unsigned long K[] = { /* Constants defined in SHA-1 */ - 0x5A827999, - 0x6ED9EBA1, - 0x8F1BBCDC, - 0xCA62C1D6 - }; - int t; /* Loop counter */ - unsigned long temp; /* Temporary word value */ - unsigned long W[80]; /* Word sequence */ - unsigned long A, B, C, D, E; /* Word buffers */ - - /* - * Initialize the first 16 words in the array W - */ - for(t = 0; t < 16; t++) - { - W[t] = context->Message_Block[t * 4 ] << 24; - W[t] |= context->Message_Block[t * 4 + 1] << 16; - W[t] |= context->Message_Block[t * 4 + 2] << 8; - W[t] |= context->Message_Block[t * 4 + 3]; - } - - for(t = 16; t < 80; t++) - { - W[t] = SHA1CircularShift(1,W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16]); - } - - A = context->Intermediate_Hash[0]; - B = context->Intermediate_Hash[1]; - C = context->Intermediate_Hash[2]; - D = context->Intermediate_Hash[3]; - E = context->Intermediate_Hash[4]; - - for(t = 0; t < 20; t++) - { - temp = SHA1CircularShift(5,A) + - ((B & C) | ((~B) & D)) + E + W[t] + K[0]; - E = D; - D = C; - C = SHA1CircularShift(30,B); - - B = A; - A = temp; - } - - for(t = 20; t < 40; t++) - { - temp = SHA1CircularShift(5,A) + (B ^ C ^ D) + E + W[t] + K[1]; - E = D; - D = C; - C = SHA1CircularShift(30,B); - B = A; - A = temp; - } - - for(t = 40; t < 60; t++) - { - temp = SHA1CircularShift(5,A) + - ((B & C) | (B & D) | (C & D)) + E + W[t] + K[2]; - E = D; - D = C; - C = SHA1CircularShift(30,B); - B = A; - A = temp; - } - - for(t = 60; t < 80; t++) - { - temp = SHA1CircularShift(5,A) + (B ^ C ^ D) + E + W[t] + K[3]; - E = D; - D = C; - C = SHA1CircularShift(30,B); - B = A; - A = temp; - } - - context->Intermediate_Hash[0] += A; - context->Intermediate_Hash[1] += B; - context->Intermediate_Hash[2] += C; - context->Intermediate_Hash[3] += D; - context->Intermediate_Hash[4] += E; - - context->Message_Block_Index = 0; -} - -/* - * SHA1PadMessage - * - - * Description: - * According to the standard, the message must be padded to an even - * 512 bits. The first padding bit must be a '1'. The last 64 - * bits represent the length of the original message. All bits in - * between should be 0. This function will pad the message - * according to those rules by filling the Message_Block array - * accordingly. It will also call the ProcessMessageBlock function - * provided appropriately. When it returns, it can be assumed that - * the message digest has been computed. - * - * Parameters: - * context: [in/out] - * The context to pad - * ProcessMessageBlock: [in] - * The appropriate SHA*ProcessMessageBlock function - * Returns: - * Nothing. - * - */ - -void SHA1PadMessage(SHA1Context *context) -{ - /* - * Check to see if the current message block is too small to hold - * the initial padding bits and length. If so, we will pad the - * block, process it, and then continue padding into a second - * block. - */ - if (context->Message_Block_Index > 55) - { - context->Message_Block[context->Message_Block_Index++] = 0x80; - while(context->Message_Block_Index < 64) - { - context->Message_Block[context->Message_Block_Index++] = 0; - } - - SHA1ProcessMessageBlock(context); - - while(context->Message_Block_Index < 56) - { - context->Message_Block[context->Message_Block_Index++] = 0; - } - } - else - { - context->Message_Block[context->Message_Block_Index++] = 0x80; - while(context->Message_Block_Index < 56) - { - - context->Message_Block[context->Message_Block_Index++] = 0; - } - } - - /* - * Store the message length as the last 8 octets - */ - context->Message_Block[56] = (unsigned char)(context->Length_High >> 24); - context->Message_Block[57] = (unsigned char)(context->Length_High >> 16); - context->Message_Block[58] = (unsigned char)(context->Length_High >> 8); - context->Message_Block[59] = (unsigned char)(context->Length_High ); - context->Message_Block[60] = (unsigned char)(context->Length_Low >> 24); - context->Message_Block[61] = (unsigned char)(context->Length_Low >> 16); - context->Message_Block[62] = (unsigned char)(context->Length_Low >> 8); - context->Message_Block[63] = (unsigned char)(context->Length_Low ); - - SHA1ProcessMessageBlock(context); -} - - - - -////////////////////////////////////////////////////////////////////////////// -#if defined( SHA1_TEST ) - -#include "string.h" - -char* samplearray[4] = -{ - "abc", - "abcdbcdecdefdefgefghfghighijhi" "jkijkljklmklmnlmnomnopnopq", - "a", - "01234567012345670123456701234567" "01234567012345670123456701234567" -}; - -char* resultarray[ 4 ] = -{ - "\xA9\x99\x3E\x36\x47\x06\x81\x6A\xBA\x3E\x25\x71\x78\x50\xC2\x6C\x9C\xD0\xD8\x9D", - "\x84\x98\x3E\x44\x1C\x3B\xD2\x6E\xBA\xAE\x4A\xA1\xF9\x51\x29\xE5\xE5\x46\x70\xF1", - "\x34\xAA\x97\x3C\xD4\xC4\xDA\xA4\xF6\x1E\xEB\x2B\xDB\xAD\x27\x31\x65\x34\x01\x6F", - "\xDE\xA3\x56\xA2\xCD\xDD\x90\xC7\xA7\xEC\xED\xC5\xEB\xB5\x63\x93\x4F\x46\x04\x52" -}; - -long int repeatcount[4] = { 1, 1, 1000000, 10 }; - -int SHA1Test( ) -{ - SHA1Context sha; - unsigned char digest[20]; - int i, j, error; - - error = 0; - for ( j = 0; j < 4; ++j ) - { - if ( !error ) - error = SHA1Reset(&sha); - - for(i = 0; i < repeatcount[j]; ++i) - { - if ( !error ) - error = SHA1Input(&sha, - (const unsigned char *)samplearray[j], - (unsigned int)strlen(samplearray[j])); - } - - if ( !error ) - error = SHA1Result(&sha, digest); - - if ( !error ) - error = memcmp( digest, resultarray[j], 20 ); - - if (error) - break; - } - - return error ? 0 : 1; -} - -#endif // SHA1_TEST -////////////////////////////////////////////////////////////////////////////// - diff --git a/build/tools/acsign/sha1dgst.c b/build/tools/acsign/sha1dgst.c deleted file mode 100644 index f9759158..00000000 --- a/build/tools/acsign/sha1dgst.c +++ /dev/null @@ -1,770 +0,0 @@ -/* $Id$ */ -/* - * Copyright (C) 1998-2002 RSA Security Inc. All rights reserved. - * - * This work contains proprietary information of RSA Security. - * Distribution is limited to authorized licensees of RSA - * Security. Any unauthorized reproduction, distribution or - * modification of this work is strictly prohibited. - * - */ - -////!!!!#include "r_com.h" - -#ifndef NO_SHA1 -#undef SHA_0 -#define SHA_1 -#include "sha.h" -#include "sha_locl.h" -#ifdef CPU_X86 -#include "r_cpuid.h" -#endif /* NO_SHA1 */ - -const char *SHA1_version="SHA1 part of RCOM 2.3.0 11-Jun-2002"; - -/* Implemented from SHA-1 document - The Secure Hash Algorithm - */ - -#define INIT_DATA_h0 (SHA_LONG)0x67452301L -#define INIT_DATA_h1 (SHA_LONG)0xefcdab89L -#define INIT_DATA_h2 (SHA_LONG)0x98badcfeL -#define INIT_DATA_h3 (SHA_LONG)0x10325476L -#define INIT_DATA_h4 (SHA_LONG)0xc3d2e1f0L - -#define K_00_19 (SHA_LONG)0x5a827999L -#define K_20_39 (SHA_LONG)0x6ed9eba1L -#define K_40_59 (SHA_LONG)0x8f1bbcdcL -#define K_60_79 (SHA_LONG)0xca62c1d6L - -#ifndef CCONV -#define CCONV -#endif - -#ifndef PRE_CCONV -#define PRE_CCONV -#endif - -/* Endian flags are only used for the assembler code */ -#ifndef OPT_SHA1_ASM -#undef L_ENDIAN -#undef B_ENDIAN -#endif - - -#ifdef OPT_SHA1_ASM - -#ifdef CPU_X86 -void CCONV sha1_block_586(SHA_CTX *c,const unsigned char *p, int num); -void CCONV sha1_block_686(SHA_CTX *c,const unsigned char *p, int num); -void CCONV sha1_block_786(SHA_CTX *c,const unsigned char *p, int num); -unsigned long r_cpuid(unsigned long *,char **name); - -#elif OPT_SHA1_ARM -PRE_CCONV void CCONV sha1_arm4_fast(SHA_CTX *c, const unsigned char *p, - int num); -PRE_CCONV void CCONV sha1_arm4_small(SHA_CTX *c, const unsigned char *p, - int num); -#else -void CCONV sha1_block_asm(SHA_CTX *c, const unsigned char *p, int num); -#endif /* CPU_X86 */ - -#else /* OPT_SHA1_ASM */ - -void sha1_block(SHA_CTX *c, SHA_LONG *p, int num); - -#endif /* OPT_SHA1_ASM */ - -#undef M_c2nl -#undef M_p_c2nl -#undef M_c2nl_p -#undef M_p_c2nl_p -#undef M_nl2c - -#if defined(L_ENDIAN) && !defined(OPT_SHA1_ASM) -# define M_c2nl c2l -# define M_p_c2nl p_c2l -# define M_c2nl_p c2l_p -# define M_p_c2nl_p p_c2l_p -# define M_nl2c l2c -#else -# define M_c2nl c2nl -# define M_p_c2nl p_c2nl -# define M_c2nl_p c2nl_p -# define M_p_c2nl_p p_c2nl_p -# define M_nl2c nl2c -#endif /* defined(L_ENDIAN) && !defined(OPT_SHA1_ASM) */ - -int SHA1_Setup(c,sha_block) -SHA_CTX *c; -void (PRE_CCONV CCONV *sha_block)(SHA_CTX *c, const unsigned char *W, int num); - { - c->sha_block=sha_block; - return(0); - } - -void SHA1_Init(c) -SHA_CTX *c; - { - c->h0=INIT_DATA_h0; - c->h1=INIT_DATA_h1; - c->h2=INIT_DATA_h2; - c->h3=INIT_DATA_h3; - c->h4=INIT_DATA_h4; - c->Nl=0; - c->Nh=0; - c->num=0; - -#ifdef OPT_SHA1_ASM -#ifdef CPU_X86 - if (c->sha_block == NULL) - { - unsigned long cpu,attrib; - - /* We should make the methods loadable */ - cpu=r_cpuid(&attrib,NULL); - if (attrib & R_CPU_X86_HAS_PENTIUM_IV) - c->sha_block=sha1_block_786; - else if (attrib & R_CPU_X86_HAS_PENTIUM_PRO) - c->sha_block=sha1_block_686; - else - c->sha_block=sha1_block_586; - } -#else /* CPU_X86 */ - -#ifndef OPT_SHA1_ARM - c->sha_block=sha1_block_asm; -#else /* OPT_SHA1_ARM */ - if (c->sha_block == NULL) - { -#ifdef SMALL_CODE_SIZE - c->sha_block = sha1_arm4_small; -#else /* SMALL_CODE_SIZE */ - c->sha_block = sha1_arm4_fast; -#endif /* SMALL_CODE_SIZE */ - } -#endif /* OPT_SHA1_ARM */ -#endif /* CPU_X86 */ - -#else /* OPT_SHA1_ASM */ - c->sha_block=(void (PRE_CCONV CCONV *)(SHA_CTX *, const unsigned char *, int))sha1_block; -#endif /* OPT_SHA1_ASM */ - } - -#ifdef OPT_SHA1_ASM - -void SHA1_Update(c, data, len) -SHA_CTX *c; -const register unsigned char *data; -unsigned long len; - { - int i; - unsigned int alignment; - unsigned long l; - unsigned char *cp=(unsigned char *)c->data; - - if (len == 0) return; - - l=(c->Nl+(len<<3))&0xffffffffL; - if (l < c->Nl) /* overflow */ - c->Nh++; - c->Nh+=(len>>29); - c->Nl=l; - - if (c->num != 0) - { - if (c->num+len >= SHA_CBLOCK) - { - i=SHA_CBLOCK-c->num; - Memcpy(&(cp[c->num]),data,i); - len-=i; - data+=i; - - c->sha_block(c,cp,64); - c->num=0; - /* drop through and do the rest */ - } - else - { - Memcpy(&(cp[c->num]),data,len); - c->num+=(int)len; - return; - } - } - /* we now can process the input data in blocks of SHA_CBLOCK - * chars and save the leftovers to c->data. */ - if (len >= SHA_CBLOCK) - { - i=(int)(len& ~63); - len-=i; - - /* - * Check to see if the input data lies on a word boundary. - * Do this as the ASM relies on input data being word aligned. - */ - alignment = (((unsigned int)data) & (sizeof(unsigned int)-1)) - & 0x03; - if (alignment == 0) - { - c->sha_block(c,data,i); - data+=i; - } - else - { - do { - Memcpy(cp, data, SHA_CBLOCK); - data += SHA_CBLOCK; - c->sha_block(c, cp, SHA_CBLOCK); - i -= SHA_CBLOCK; - } while (i > 0); - } - } - c->num=len; - if (len) - { - Memcpy(cp,data,(int)len); - } - } - -void SHA1_Transform(c,b) -SHA_CTX *c; -const unsigned char *b; - { - c->sha_block(c,b,64); - } - -void SHA1_Final(md, c) -unsigned char *md; -SHA_CTX *c; - { - register int i,j; - register SHA_LONG l; - register SHA_LONG *p; - const static unsigned char end[4]={0x80,0x00,0x00,0x00}; - unsigned char *cp= (unsigned char *)end; - unsigned char *pc; - - /* c->num should definitly have room for at least one more byte. */ - p=c->data; - j=c->num; - i=j>>2; - -#ifdef PURIFY - /* PURIFY */ - /* we reference uninitialised data but don't keep the result - * which purify complains about ... and we don't want to have - * to come back here to find a non-existant problem later - */ - - /* purify often complains about the following line as an - * Uninitialized Memory Read. While this can be true, the - * following p_c2l macro will reset l when that case is true. - * This is because j&0x03 contains the number of 'valid' bytes - * already in p[i]. If and only if j&0x03 == 0, the UMR will - * occur but this is also the only time p_c2l will do - * l= *(cp++) instead of l|= *(cp++) - */ - if ((j&0x03) == 0) p[i]=0; -#endif - - pc=(unsigned char *)c->data; - pc[j]=0x80; - for (j++; j & 0x03; j++) - pc[j]=0; - i++; - /* i is the next 'undefined word' */ - if (c->num >= SHA_LAST_BLOCK) - { - for (; isha_block(c,(unsigned char *)p,64); - i=0; - } - for (; i<(SHA_LBLOCK-2); i++) - p[i]=0; - - l=c->Nl; - pc[63]=(unsigned char)((l )&0xff); - pc[62]=(unsigned char)((l>> 8)&0xff); - pc[61]=(unsigned char)((l>>16)&0xff); - pc[60]=(unsigned char)((l>>24)&0xff); - l=c->Nh; - pc[59]=(unsigned char)((l )&0xff); - pc[58]=(unsigned char)((l>> 8)&0xff); - pc[57]=(unsigned char)((l>>16)&0xff); - pc[56]=(unsigned char)((l>>24)&0xff); - - c->sha_block(c,(unsigned char *)p,64); - cp=md; - l=c->h0; nl2c(l,cp); - l=c->h1; nl2c(l,cp); - l=c->h2; nl2c(l,cp); - l=c->h3; nl2c(l,cp); - l=c->h4; nl2c(l,cp); - - /* clear stuff, sha1_block_asm may be leaving some stuff on the stack - * but I'm not worried :-) */ - c->num=0; -/* Memset((char *)&c,0,sizeof(c));*/ - } - -#else /* !OPT_SHA1_ASM */ - -void SHA1_Update(c, data, len) -SHA_CTX *c; -const register unsigned char *data; -unsigned long len; - { - register SHA_LONG *p; - int ew,ec,sw,sc; - SHA_LONG l; - - if (len == 0) return; - - l=(c->Nl+(len<<3))&0xffffffffL; - if (l < c->Nl) /* overflow */ - c->Nh++; - c->Nh+=(len>>29); - c->Nl=l; - - if (c->num != 0) - { - p=c->data; - sw=c->num>>2; - sc=c->num&0x03; - - if ((c->num+len) >= SHA_CBLOCK) - { - l= p[sw]; - M_p_c2nl(data,l,sc); - p[sw++]=l; - for (; swnum); - - c->sha_block(c,(unsigned char *)p,64); - c->num=0; - /* drop through and do the rest */ - } - else - { - c->num+=(int)len; - if ((sc+len) < 4) /* ugly, add char's to a word */ - { - l= p[sw]; - M_p_c2nl_p(data,l,sc,len); - p[sw]=l; - } - else - { - ew=(c->num>>2); - ec=(c->num&0x03); - l= p[sw]; - M_p_c2nl(data,l,sc); - p[sw++]=l; - for (; sw < ew; sw++) - { M_c2nl(data,l); p[sw]=l; } - if (ec) - { - M_c2nl_p(data,l,ec); - p[sw]=l; - } - } - return; - } - } - /* We can only do the following code for assember, the reason - * being that the sha1_block 'C' version changes the values - * in the 'data' array. The assember code avoids this and - * copies it to a local array. I should be able to do this for - * the C version as well.... - */ -#if defined(B_ENDIAN) || defined(OPT_SHA1_ASM) - if ((((unsigned long)data)%sizeof(SHA_LONG)) == 0) - { - sw=len/SHA_CBLOCK; - if (sw) - { - sw*=SHA_CBLOCK; - c->sha_block(c,(SHA_LONG *)data,sw); - data+=sw; - len-=sw; - } - } -#endif - /* we now can process the input data in blocks of SHA_CBLOCK - * chars and save the leftovers to c->data. */ - p=c->data; - while (len >= SHA_CBLOCK) - { -#if defined(B_ENDIAN) || defined(L_ENDIAN) - if (p != (SHA_LONG *)data) - Memcpy(p,data,SHA_CBLOCK); - data+=SHA_CBLOCK; -# ifdef L_ENDIAN -# ifndef OPT_SHA1_ASM /* Will not happen */ - for (sw=(SHA_LBLOCK/4); sw; sw--) - { - Endian_Reverse32(p[0]); - Endian_Reverse32(p[1]); - Endian_Reverse32(p[2]); - Endian_Reverse32(p[3]); - p+=4; - } - p=c->data; -# endif -# endif -#else - for (sw=(SHA_BLOCK/4); sw; sw--) - { - M_c2nl(data,l); *(p++)=l; - M_c2nl(data,l); *(p++)=l; - M_c2nl(data,l); *(p++)=l; - M_c2nl(data,l); *(p++)=l; - } - p=c->data; -#endif - c->sha_block(c,(unsigned char *)p,64); - len-=SHA_CBLOCK; - } - ec=(int)len; - c->num=ec; - ew=(ec>>2); - ec&=0x03; - - for (sw=0; sw < ew; sw++) - { M_c2nl(data,l); p[sw]=l; } - M_c2nl_p(data,l,ec); - p[sw]=l; - } - -void SHA1_Transform(c,b) -SHA_CTX *c; -const unsigned char *b; - { - SHA_LONG p[16]; -#ifndef B_ENDIAN - SHA_LONG *q; - int i; -#endif - -#if defined(B_ENDIAN) || defined(L_ENDIAN) - Memcpy(p,b,64); -#ifdef L_ENDIAN - q=p; - for (i=(SHA_LBLOCK/4); i; i--) - { - Endian_Reverse32(q[0]); - Endian_Reverse32(q[1]); - Endian_Reverse32(q[2]); - Endian_Reverse32(q[3]); - q+=4; - } -#endif -#else - q=p; - for (i=(SHA_LBLOCK/4); i; i--) - { - SHA_LONG l; - c2nl(b,l); *(q++)=l; - c2nl(b,l); *(q++)=l; - c2nl(b,l); *(q++)=l; - c2nl(b,l); *(q++)=l; - } -#endif - c->sha_block(c,(unsigned char *)p,64); - } - - -void sha1_block(c, W, num) -SHA_CTX *c; -SHA_LONG *W; -int num; - { -#ifndef SMALL_CODE_SIZE - register SHA_LONG A,B,C,D,E,T; - SHA_LONG X[16]; - - A=c->h0; - B=c->h1; - C=c->h2; - D=c->h3; - E=c->h4; - - for (;;) - { - BODY_00_15( 0,A,B,C,D,E,T,W); - BODY_00_15( 1,T,A,B,C,D,E,W); - BODY_00_15( 2,E,T,A,B,C,D,W); - BODY_00_15( 3,D,E,T,A,B,C,W); - BODY_00_15( 4,C,D,E,T,A,B,W); - BODY_00_15( 5,B,C,D,E,T,A,W); - BODY_00_15( 6,A,B,C,D,E,T,W); - BODY_00_15( 7,T,A,B,C,D,E,W); - BODY_00_15( 8,E,T,A,B,C,D,W); - BODY_00_15( 9,D,E,T,A,B,C,W); - BODY_00_15(10,C,D,E,T,A,B,W); - BODY_00_15(11,B,C,D,E,T,A,W); - BODY_00_15(12,A,B,C,D,E,T,W); - BODY_00_15(13,T,A,B,C,D,E,W); - BODY_00_15(14,E,T,A,B,C,D,W); - BODY_00_15(15,D,E,T,A,B,C,W); - BODY_16_19(16,C,D,E,T,A,B,W,W,W,W); - BODY_16_19(17,B,C,D,E,T,A,W,W,W,W); - BODY_16_19(18,A,B,C,D,E,T,W,W,W,W); - BODY_16_19(19,T,A,B,C,D,E,W,W,W,X); - - BODY_20_31(20,E,T,A,B,C,D,W,W,W,X); - BODY_20_31(21,D,E,T,A,B,C,W,W,W,X); - BODY_20_31(22,C,D,E,T,A,B,W,W,W,X); - BODY_20_31(23,B,C,D,E,T,A,W,W,W,X); - BODY_20_31(24,A,B,C,D,E,T,W,W,X,X); - BODY_20_31(25,T,A,B,C,D,E,W,W,X,X); - BODY_20_31(26,E,T,A,B,C,D,W,W,X,X); - BODY_20_31(27,D,E,T,A,B,C,W,W,X,X); - BODY_20_31(28,C,D,E,T,A,B,W,W,X,X); - BODY_20_31(29,B,C,D,E,T,A,W,W,X,X); - BODY_20_31(30,A,B,C,D,E,T,W,X,X,X); - BODY_20_31(31,T,A,B,C,D,E,W,X,X,X); - BODY_32_39(32,E,T,A,B,C,D,X); - BODY_32_39(33,D,E,T,A,B,C,X); - BODY_32_39(34,C,D,E,T,A,B,X); - BODY_32_39(35,B,C,D,E,T,A,X); - BODY_32_39(36,A,B,C,D,E,T,X); - BODY_32_39(37,T,A,B,C,D,E,X); - BODY_32_39(38,E,T,A,B,C,D,X); - BODY_32_39(39,D,E,T,A,B,C,X); - - BODY_40_59(40,C,D,E,T,A,B,X); - BODY_40_59(41,B,C,D,E,T,A,X); - BODY_40_59(42,A,B,C,D,E,T,X); - BODY_40_59(43,T,A,B,C,D,E,X); - BODY_40_59(44,E,T,A,B,C,D,X); - BODY_40_59(45,D,E,T,A,B,C,X); - BODY_40_59(46,C,D,E,T,A,B,X); - BODY_40_59(47,B,C,D,E,T,A,X); - BODY_40_59(48,A,B,C,D,E,T,X); - BODY_40_59(49,T,A,B,C,D,E,X); - BODY_40_59(50,E,T,A,B,C,D,X); - BODY_40_59(51,D,E,T,A,B,C,X); - BODY_40_59(52,C,D,E,T,A,B,X); - BODY_40_59(53,B,C,D,E,T,A,X); - BODY_40_59(54,A,B,C,D,E,T,X); - BODY_40_59(55,T,A,B,C,D,E,X); - BODY_40_59(56,E,T,A,B,C,D,X); - BODY_40_59(57,D,E,T,A,B,C,X); - BODY_40_59(58,C,D,E,T,A,B,X); - BODY_40_59(59,B,C,D,E,T,A,X); - - BODY_60_79(60,A,B,C,D,E,T,X); - BODY_60_79(61,T,A,B,C,D,E,X); - BODY_60_79(62,E,T,A,B,C,D,X); - BODY_60_79(63,D,E,T,A,B,C,X); - BODY_60_79(64,C,D,E,T,A,B,X); - BODY_60_79(65,B,C,D,E,T,A,X); - BODY_60_79(66,A,B,C,D,E,T,X); - BODY_60_79(67,T,A,B,C,D,E,X); - BODY_60_79(68,E,T,A,B,C,D,X); - BODY_60_79(69,D,E,T,A,B,C,X); - BODY_60_79(70,C,D,E,T,A,B,X); - BODY_60_79(71,B,C,D,E,T,A,X); - BODY_60_79(72,A,B,C,D,E,T,X); - BODY_60_79(73,T,A,B,C,D,E,X); - BODY_60_79(74,E,T,A,B,C,D,X); - BODY_60_79(75,D,E,T,A,B,C,X); - BODY_60_79(76,C,D,E,T,A,B,X); - BODY_60_79(77,B,C,D,E,T,A,X); - BODY_60_79(78,A,B,C,D,E,T,X); - BODY_60_79(79,T,A,B,C,D,E,X); - - c->h0=(c->h0+E)&0xffffffffL; - c->h1=(c->h1+T)&0xffffffffL; - c->h2=(c->h2+A)&0xffffffffL; - c->h3=(c->h3+B)&0xffffffffL; - c->h4=(c->h4+C)&0xffffffffL; - - num-=64; - if (num <= 0) break; - - A=c->h0; - B=c->h1; - C=c->h2; - D=c->h3; - E=c->h4; - - W+=16; - } -#else /* SMALL_CODE_SIZE */ - SHA_LONG A,B,C,D,E,T; - SHA_LONG X[16]; - SHA_LONG *a1,*a2,*a3; - - A=c->h0; - B=c->h1; - C=c->h2; - D=c->h3; - E=c->h4; - - for (;;) - { - int i; - - for (i=0; i<16; i++) - { - BODY_00_15(i,A,B,C,D,E,T,W); - E=D; D=C; C=B; B=A; A=T; - } - - a1=W; - for (i=16; i<20; i++) - { - if (i == 19) a1=X; - BODY_16_19(i,A,B,C,D,E,T,W,W,W,a1); - E=D; D=C; C=B; B=A; A=T; - } - - a1=a2=a3=W; - for (i=20; i<40; i++) - { - if (i == 24) a3=X; - if (i == 30) a2=X; - if (i == 32) a1=X; - BODY_20_31(i,A,B,C,D,E,T,a1,a2,a3,X); - E=D; D=C; C=B; B=A; A=T; - } - - for (i=40; i<60; i++) - { - BODY_40_59(i,A,B,C,D,E,T,X); - E=D; D=C; C=B; B=A; A=T; - } - - for (i=60; i<80; i++) - { - BODY_60_79(i,A,B,C,D,E,T,X); - E=D; D=C; C=B; B=A; A=T; - } - - c->h0=(c->h0+A)&0xffffffffL; - c->h1=(c->h1+B)&0xffffffffL; - c->h2=(c->h2+C)&0xffffffffL; - c->h3=(c->h3+D)&0xffffffffL; - c->h4=(c->h4+E)&0xffffffffL; - - num-=64; - if (num <= 0) break; - - A=c->h0; - B=c->h1; - C=c->h2; - D=c->h3; - E=c->h4; - - W+=16; - } -#endif /* SMALL_CODE_SIZE */ - } - -void SHA1_Final(md, c) -unsigned char *md; -SHA_CTX *c; - { - register int i,j; - register SHA_LONG l; - register SHA_LONG *p; - const static unsigned char end[4]={0x80,0x00,0x00,0x00}; - unsigned char *cp= (unsigned char *)end; - - /* c->num should definitly have room for at least one more byte. */ - p=c->data; - j=c->num; - i=j>>2; - -#ifdef PURIFY - /* PURIFY */ - /* we reference uninitialised data but don't keep the result - * which purify complains about ... and we don't want to have - * to come back here to find a non-existant problem later - */ - - /* purify often complains about the following line as an - * Uninitialized Memory Read. While this can be true, the - * following p_c2l macro will reset l when that case is true. - * This is because j&0x03 contains the number of 'valid' bytes - * already in p[i]. If and only if j&0x03 == 0, the UMR will - * occur but this is also the only time p_c2l will do - * l= *(cp++) instead of l|= *(cp++) - */ - if ((j&0x03) == 0) p[i]=0; -#endif - - l=p[i]; - M_p_c2nl(cp,l,j&0x03); - p[i]=l; - i++; - /* i is the next 'undefined word' */ - if (c->num >= SHA_LAST_BLOCK) - { - for (; isha_block(c,(unsigned char *)p,64); - i=0; - } - for (; i<(SHA_LBLOCK-2); i++) - p[i]=0; - p[SHA_LBLOCK-2]=c->Nh; - p[SHA_LBLOCK-1]=c->Nl; -#if defined(L_ENDIAN) - Endian_Reverse32(p[SHA_LBLOCK-2]); - Endian_Reverse32(p[SHA_LBLOCK-1]); -#endif - c->sha_block(c,(unsigned char *)p,64); - cp=md; - l=c->h0; nl2c(l,cp); - l=c->h1; nl2c(l,cp); - l=c->h2; nl2c(l,cp); - l=c->h3; nl2c(l,cp); - l=c->h4; nl2c(l,cp); - - /* clear stuff, sha1_block may be leaving some stuff on the stack - * but I'm not worried :-) */ - c->num=0; -/* Memset((char *)&c,0,sizeof(c));*/ - } -#endif - -#if 0 -int pr(ctx) -SHA_CTX *ctx; - { - int i,j; - unsigned char *p=(unsigned char *)(ctx->data); - - fprintf(stderr,"num = %08X%08X\n",ctx->Nh,ctx->Nl); - fprintf(stderr," %08X %08X %08X %08X %08X\n", - ctx->h0,ctx->h1,ctx->h2,ctx->h3,ctx->h4); - fprintf(stderr,"bufnum = %d\n",ctx->num); - fprintf(stderr," "); - for (j=0; j<64; j+=16) - { - for (i=0; i<16; i++) - { -/* - if ((i+j) >= ctx->num) - fprintf(stderr,"--"); - else -*/ - fprintf(stderr,"%02X",p[i+j]); - } - if ((j+16) >=64) - fprintf(stderr,"\n"); - else - fprintf(stderr,"\n "); - } - } - -#endif - -#endif /* NO_SHA1 */ diff --git a/build/tools/makegcdfirm/Makefile b/build/tools/makegcdfirm/Makefile deleted file mode 100644 index a46292ac..00000000 --- a/build/tools/makegcdfirm/Makefile +++ /dev/null @@ -1,151 +0,0 @@ -#! make -f -#--------------------------------------------------------------------------- -# Project: TwlFirm - tools - makegcdfirm -# File: Makefile -# -# Copyright 2007 Nintendo. All rights reserved. -# -# These coded instructions, statements, and computer programs contain -# proprietary information of Nintendo of America Inc. and/or Nintendo -# Company Ltd., and are protected by Federal copyright law. They may -# not be disclosed to third parties or copied or duplicated in any form, -# in whole or in part, without the prior written consent of Nintendo. -# -# $Date:: $ -# $Rev:$ -# $Author:$ -#--------------------------------------------------------------------------- - -TARGET_PLATFORM = TWL - -SUPPORT_ECC = 0 - -ifeq ($(SUPPORT_ECC),1) -ECC_SRCDIR = ../../libraries/acsign_ecc/common \ - ../../libraries/acsign_ecc/common/algae/common/ecc \ - ../../libraries/acsign_ecc/common/algae/cmp \ - ../../libraries/acsign_ecc/common/algae/ecsource \ - -ECC_INCDIR = ../../libraries/acsign_ecc/include \ - ../../libraries/acsign_ecc/common/algae/include \ - ../../libraries/acsign_ecc/common/algae/common/include \ - -ECC_SRCS = acsign_ecc.c acsign_cryptoc.c \ - \ - cmparith.c cmpbits.c cmpcnv.c cmpdiv.c cmpmem.c \ - cmpmod.c cmpmuldv.c cmpspprt.c cmpsqr.c cmpvectr.c \ - computem.c ecfpatbl.c ecfpsmul.c \ - spcprime.c secfpcom.c \ - \ - p224v1.c p224v1a.c \ - -ECC_DEFS = -DRSA_PROTOTYPES=RSA_ENABLED \ - -DRCOM_BUILD=RSA_ENABLED -DRSA_FAST_INVERSE=RSA_ENABLED \ - -DRSA_STD_MEM_FUNCS=RSA_ENABLED -DRSA_STD_ALLOC_FUNCS=RSA_ENABLED \ -else -ECC_SRCDIR = -ECC_INCDIR = -ECC_SRCS = -ECC_DEFS = -endif - -SRCDIR += ../acsign $(ECC_SRCDIR) -INCDIR += ../acsign/include $(ECC_INCDIR) $(ECC_SRCDIR) - - -include $(TWL_IPL_RED_ROOT)/build/buildtools/commondefs - -TARGETS = makegcdfirm.exe - -SOURCES_C = makegcdfirm.c \ - out_gcdfirm.c \ - misc.c \ - path.c \ - defval.c \ - compress.c \ - wram_regs.c \ - acsign.c \ - acsign_gcd.c \ - aes2.c \ - $(ECC_SRCS) - -SOURCES = $(SORUCES_C) - -OBJECTS = $(SOURCES_C:.c=.o) - -HEADERS = format_nlist.h \ - makegcdfirm.h \ - path.h \ - format_rom.h \ - misc.h \ - defval.h \ - compress.h \ - -MACROS += -DSMALL_CODE_SIZE \ - -DSTANDALONE \ - -DOPT_32_BIT \ - -DNO_SPLIT \ - -DNO_FP_API \ - -DNO_R_DIAG \ - $(ECC_DEFS) - -INSTALL_DIR = $(FIRM_INSTALL_TOOLSDIR)/bin -INSTALL_TARGETS = $(TARGETS) - -LDIRT_CLEAN = $(OBJECTS) $(TARGETS) version.h - - -VPATH = $(SRCDIR) -TWL_INCDIR := $(TWL_INCDIR) $(addprefix -I,$(INCDIR)) $(addprefix -I,$(FIRM_INCDIR)) - -include $(TWLSDK_ROOT)/build/buildtools/twl/modulerules.x86 - -#---------------------------------------------------------------------------- -# build -#---------------------------------------------------------------------------- -do-build: $(TARGETS) - -$(TARGETS): $(OBJECTS) - $(CC_X86) $+ -o $@ - -makegcdfirm.o: makegcdfirm.c makegcdfirm.h format_rom.h path.h version.h -out_gcdfirm.o: out_gcdfirm.c misc.h format_rom.h format_nlist.h format_sign.h elf.h compress.h \ - $(FIRM_INCDIR)/firm/format/sign.h \ - $(FIRM_INCDIR)/firm/format/wram_regs.h \ - $(FIRM_INCDIR)/firm/format/gcdfirm.h \ - -misc.o: misc.c misc.h -path.o: path.c path.h -compress.o: compress.c compress.h -wram_regs.o: wram_regs.c -acsign.o: acsign.c ../acsign/include/acsign.h -acsign_gcd.o: acsign_gcd.c format_sign.h \ - $(FIRM_INCDIR)/firm/format/sign.h \ - $(FIRM_INCDIR)/firm/format/wram_regs.h \ - $(FIRM_INCDIR)/firm/format/gcdfirm.h \ - -aes2.o: aes2.c aes2.h - -$(FIRM_INCDIR)/firm/format/sign.h: -$(FIRM_INCDIR)/firm/format/wram_regs.h: -$(FIRM_INCDIR)/firm/format/gcdfirm.h: -format_nlist.h: -format_rom.h: -makegcdfirm.h: -acsign.h: -acsign_gcd.h: -path.h: - -# avoid to warning message -misc.o:WARNING += -Wno-format-y2k - -# - -version.h: $(SOURCES) $(HEADERS) - @for i in $^ ; \ - do \ - date -r $$i +'#define SDK_DATE_OF_LATEST_FILE %Y%m%dUL'; \ - done | sort | tail -1 > $@ - -test: path.c misc.c - $(CC_X86) -DTEST $+ -o $@ diff --git a/build/tools/makegcdfirm/compress.c b/build/tools/makegcdfirm/compress.c deleted file mode 100644 index 6a8c4038..00000000 --- a/build/tools/makegcdfirm/compress.c +++ /dev/null @@ -1,293 +0,0 @@ -/*---------------------------------------------------------------------------* - Project: TwlFirm - tools - makegcdfirm - File: compress.c - - Copyright 2007 Nintendo. All rights reserved. - - These coded instructions, statements, and computer programs contain - proprietary information of Nintendo of America Inc. and/or Nintendo - Company Ltd., and are protected by Federal copyright law. They may - not be disclosed to third parties or copied or duplicated in any form, - in whole or in part, without the prior written consent of Nintendo. - - $Date:: 2007-09-06$ - $Rev$ - $Author$ - *---------------------------------------------------------------------------*/ -#include -#include // atoi() -#include // strcmp() -#include // isprint() -#include // chdir() -#include -#include // UCHAR_MAX -#include -#include // stat() -#include "elf.h" -#include "misc.h" -#include "defval.h" -#include "format_rom.h" -#include "format_nlist.h" -#include "makegcdfirm.h" - -//#define ADD_HEADER - -#define DIFF_CODE_HEADER (0x80) -#define RL_CODE_HEADER (0x30) -#define LZ_CODE_HEADER (0x10) -#define HUFF_CODE_HEADER (0x20) -#define CODE_HEADER_MASK (0xF0) - -//=========================================================================== -// LZ77圧縮 -//=========================================================================== -static u8 SearchLZ(const u8 *nextp, u32 remainSize, u16 *offset); - -static u16 windowPos; -static u16 windowLen; - -static s16 LZOffsetTable[4096]; -static s16 LZByteTable[256]; -static s16 LZEndTable[256]; - - -static void LZInitTable(void) -{ - u16 i; - - for (i = 0; i < 256; i++) - { - LZByteTable[i] = -1; - LZEndTable[i] = -1; - } - windowPos = 0; - windowLen = 0; -} - -static void SlideByte(const u8 *srcp) -{ - s16 offset; - u8 in_data = *srcp; - u16 insert_offset; - - if (windowLen == 4096) - { - u8 out_data = *(srcp - 4096); - if ((LZByteTable[out_data] = LZOffsetTable[LZByteTable[out_data]]) == -1) - { - LZEndTable[out_data] = -1; - } - insert_offset = windowPos; - } - else - { - insert_offset = windowLen; - } - - offset = LZEndTable[in_data]; - if (offset == -1) - { - LZByteTable[in_data] = insert_offset; - } - else - { - LZOffsetTable[offset] = insert_offset; - } - LZEndTable[in_data] = insert_offset; - LZOffsetTable[insert_offset] = -1; - - if (windowLen == 4096) - { - windowPos = (u16)((windowPos + 1) % 0x1000); - } - else - { - windowLen++; - } -} - -static void LZSlide(const u8 *srcp, u32 n) -{ - u32 i; - - for (i = 0; i < n; i++) - { - SlideByte(srcp++); - } -} - -/*---------------------------------------------------------------------------* - Name: MI_CompressLZ - - Description: LZ77圧縮を行なう関数 - - Arguments: srcp 圧縮元データへのポインタ - size 圧縮元データサイズ - dstp 圧縮先データへのポインタ - 圧縮元データよりも大きいサイズのバッファが必要です。 - - Returns: 圧縮後のデータサイズ。 - 圧縮後のデータが圧縮前よりも大きくなる場合には圧縮を中断し0を返します。 - *---------------------------------------------------------------------------*/ -u32 LZCompWrite(u8 *srcp, u32 size, u8 *dstp, int boundary) -{ - u32 LZDstCount; // 圧縮データのバイト数 - u8 LZCompFlags; // 圧縮の有無を示すフラグ系列 - u8 *LZCompFlagsp; // LZCompFlags を格納するメモリ領域をポイント - u16 lastOffset; // 一致データまでのオフセット (その時点での最長一致データ) - u8 lastLength; // 一致データ長 (その時点での最長一致データ) - u8 i; - u32 dstMax; - -#ifdef ADD_HEADER - *(u32 *)dstp = size << 8 | LZ_CODE_HEADER; // データ・ヘッダ - dstp += 4; -#endif - LZDstCount = 4; - dstMax = size; - LZInitTable(); - - while (size > 0) - { - LZCompFlags = 0; - LZCompFlagsp = dstp++; // フラグ系列の格納先 - LZDstCount++; - - // フラグ系列が8ビットデータとして格納されるため、8回ループ - for (i = 0; i < 8; i++) - { - LZCompFlags <<= 1; // 初回 (i=0) は特に意味はない - if (size <= 0) - { - // 終端に来た場合はフラグを最後までシフトさせてから終了 - continue; - } - - if ((lastLength = SearchLZ(srcp, size, &lastOffset))) - { - // 圧縮可能な場合はフラグを立てる - LZCompFlags |= 0x1; - - // オフセットは上位4ビットと下位8ビットに分けて格納 - *dstp++ = (u8)((lastLength - 3) << 4 | (lastOffset - 1) >> 8); - *dstp++ = (u8)((lastOffset - 1) & 0xff); - LZDstCount += 2; - LZSlide(srcp, lastLength); - srcp += lastLength; - size -= lastLength; - } - else - { - // 圧縮なし - LZSlide(srcp, 1); - *dstp++ = *srcp++; - size--; - LZDstCount++; - } - } // 8回ループ終了 - *LZCompFlagsp = LZCompFlags; // フラグ系列を格納 - } - - // 16バイト境界アラインメント - // アラインメント用データ0 はデータサイズに含める - i = 0; - while (LZDstCount & (boundary - 1)) -// while ((LZDstCount + i) & 0x3) - { - *dstp++ = 0; - LZDstCount++; - i++; - } - - return LZDstCount; -} - -//-------------------------------------------------------- -// LZ77圧縮でスライド窓の中から最長一致列を検索します。 -// Arguments: startp データの開始位置を示すポインタ -// nextp 検索を開始するデータのポインタ -// remainSize 残りデータサイズ -// offset 一致したオフセットを格納する領域へのポインタ -// Return : 一致列が見つかった場合は TRUE -// 見つからなかった場合は FALSE -//-------------------------------------------------------- -static u8 SearchLZ(const u8 *nextp, u32 remainSize, u16 *offset) -{ - const u8 *searchp; - const u8 *headp, *searchHeadp; - u16 maxOffset; - u8 maxLength = 2; - u8 tmpLength; - s32 w_offset; - - if (remainSize < 3) - { - return 0; - } - - w_offset = LZByteTable[*nextp]; - - while (w_offset != -1) - { - if (w_offset < windowPos) - { - searchp = nextp - windowPos + w_offset; - } - else - { - searchp = nextp - windowLen - windowPos + w_offset; - } - - /* 無くても良いが、僅かに高速化する */ - if (*(searchp + 1) != *(nextp + 1) || *(searchp + 2) != *(nextp + 2)) - { - w_offset = LZOffsetTable[w_offset]; - continue; - } - - if (nextp - searchp < 2) - { - // VRAMは2バイトアクセスなので (VRAMからデータを読み出す場合があるため)、 - // 検索対象データは2バイト前からのデータにしなければならない。 - // - // オフセットは12ビットで格納されるため、4096以下 - break; - } - tmpLength = 3; - searchHeadp = searchp + 3; - headp = nextp + 3; - - while (((u32)(headp - nextp) < remainSize) && (*headp == *searchHeadp)) - { - headp++; - searchHeadp++; - tmpLength++; - - // データ長は4ビットで格納されるため、18以下 (3の下駄をはかせる) - if (tmpLength == (0xF + 3)) - { - break; - } - } - if (tmpLength > maxLength) - { - // 最大長オフセットを更新 - maxLength = tmpLength; - maxOffset = (u16)(nextp - searchp); - if (maxLength == (0xF + 3)) - { - // 一致長が最大なので、検索を終了する。 - break; - } - } - w_offset = LZOffsetTable[w_offset]; - } - - if (maxLength < 3) - { - return 0; - } - *offset = maxOffset; - return maxLength; -} - diff --git a/build/tools/makegcdfirm/compress.h b/build/tools/makegcdfirm/compress.h deleted file mode 100644 index e3dc58f0..00000000 --- a/build/tools/makegcdfirm/compress.h +++ /dev/null @@ -1,38 +0,0 @@ -/*---------------------------------------------------------------------------* - Project: TwlFirm - tools - makenorfirm - File: compress.h - - Copyright 2007 Nintendo. All rights reserved. - - These coded instructions, statements, and computer programs contain - proprietary information of Nintendo of America Inc. and/or Nintendo - Company Ltd., and are protected by Federal copyright law. They may - not be disclosed to third parties or copied or duplicated in any form, - in whole or in part, without the prior written consent of Nintendo. - - $Date:: 2007-09-06$ - $Rev$ - $Author$ - *---------------------------------------------------------------------------*/ -#ifndef COMPRESS_H_ -#define COMPRESS_H_ - -#include "misc.h" - - -/*---------------------------------------------------------------------------* - Name: MI_CompressLZ - - Description: LZ77圧縮を行なう関数 - - Arguments: srcp 圧縮元データへのポインタ - size 圧縮元データサイズ - dstp 圧縮先データへのポインタ - 圧縮元データよりも大きいサイズのバッファが必要です。 - - Returns: 圧縮後のデータサイズ。 - *---------------------------------------------------------------------------*/ -u32 LZCompWrite(u8 *srcp, u32 size, u8 *dstp, int boundary); - - -#endif //COMPRESS_H_ diff --git a/build/tools/makegcdfirm/defval.c b/build/tools/makegcdfirm/defval.c deleted file mode 100644 index 679fb0e6..00000000 --- a/build/tools/makegcdfirm/defval.c +++ /dev/null @@ -1,315 +0,0 @@ -/*---------------------------------------------------------------------------* - Project: NitroSDK - tools - makerom - File: defval.c - - Copyright 2003-2006 Nintendo. All rights reserved. - - These coded instructions, statements, and computer programs contain - proprietary information of Nintendo of America Inc. and/or Nintendo - Company Ltd., and are protected by Federal copyright law. They may - not be disclosed to third parties or copied or duplicated in any form, - in whole or in part, without the prior written consent of Nintendo. - - $Log: defval.c,v $ - Revision 1.10 2006/01/18 02:11:19 kitase_hirotake - do-indent - - Revision 1.9 2005/02/28 05:26:03 yosizaki - do-indent. - - Revision 1.8 2004/08/05 13:50:13 yasu - Support -M option - - Revision 1.7 2004/06/29 04:55:40 yasu - Use VBuffer to resolve variables - - Revision 1.6 2004/06/23 07:51:02 yasu - fix a bug as illegal memory freeing at ResolveDefVal() - - Revision 1.5 2004/05/27 00:40:49 yasu - care also about current directory (dot ".") - - Revision 1.4 2004/05/27 00:25:46 yasu - care about double-dots ".." for defvalue option :r, :e - - Revision 1.3 2004/05/27 00:11:19 yasu - fix a error when searching a "dot" of file extension - - Revision 1.2 2004/05/26 12:02:47 yasu - support :h, :t, :r, :e option for variable name - - Revision 1.1 2004/03/26 05:06:45 yasu - support variables like as -DNAME=VALUE - - $NoKeywords: $ - *---------------------------------------------------------------------------*/ -#include -#include // getenv() -#include // strcasecmp() -#include // getopt() -#include "misc.h" -#include "defval.h" - -typedef struct tValdef -{ - struct tValdef *next; - char *name; - char *value; -} -tValdef; - -tValdef *valdef_top = NULL; - - -// -// Add new define value via file -// -// opt : "DEFINE=VALUE" -// -BOOL AddDefValFromFile(char *filename) -{ - char *buffer; - int buffer_size; - int read_size; - FILE *fp; - - if (filename[0] == '-' && filename[1] == '\0') - { - fp = stdin; - } - else if (NULL == (fp = fopen(filename, "rb"))) - { - fprintf(stderr, "Cannot open file \"%s\".\n", filename); - return FALSE; - } - - buffer_size = DEFVAL_DEFAULT_BUFFER_SIZE; - - if (NULL == (buffer = malloc(buffer_size))) - { - fprintf(stderr, "Cannot allocate memory.\n"); - return FALSE; - } - - read_size = 0; - - while (NULL != fgets(buffer + read_size, buffer_size - read_size, fp)) - { - read_size = strlen(buffer); - - if (read_size == buffer_size - 1 && buffer[read_size - 1] != '\n') - { - buffer_size *= 2; - - if (NULL == (buffer = realloc(buffer, buffer_size))) - { - fprintf(stderr, "Cannot allocate memory.\n"); - return FALSE; - } - continue; - } - - AddDefVal(buffer); - read_size = 0; - } - - if (fp != stdin) - { - fclose(fp); - } - free(buffer); - - return TRUE; -} - - -// -// Add new define value -// -// opt : "DEFINE=VALUE" -// -void AddDefVal(char *opt) -{ - int i; - tValdef *t; - - for (i = 0;; i++) - { - if ('=' == opt[i] || '\0' == opt[i]) - { - break; - } - } - - if (i > 0) - { - t = Alloc(sizeof(tValdef)); - t->name = strncpy(Alloc(i + 1), opt, i); - t->name[i] = '\0'; - - if (opt[i] == '=') - { - i++; - } - t->value = strdup(opt + i); - - t->next = valdef_top; - valdef_top = t; - - debug_printf("DEFINE:$(%s)=\"%s\"\n", t->name, t->value); - } - return; -} - -// -// Search define value -// -// Return: value of specified name -// -char *SearchDefVal(char *name) -{ - tValdef *t; - - for (t = valdef_top; t; t = t->next) - { - if (!strcmp(t->name, name)) - { - return t->value; - } - } - - return getenv(name); -} - - -// -// Search define value and Modify it by : option -// -// Return: duplicated value of specified name modified by :x option -// -char *SearchDefValWithOption(char *name) -{ - int len_name = strlen(name); - char *value; - char option = '\0'; - - if (len_name > 2 && name[len_name - 2] == ':') - { - name[len_name - 2] = '\0'; - option = name[len_name - 1]; - } - - value = SearchDefVal(name); - - if (value) - { - int value_len = strlen(value); - int col_dot = value_len; - int col_filename = 0; - int i; - - for (i = 0; i < value_len; i++) - { - switch (value[i]) - { - case '.': - if (col_filename == i && - (value[i + 1] == '\0' || (value[i + 1] == '.' && value[i + 2] == '\0'))) - { - i = value_len; // exit loop if last entry is . or .. - } - else - { - col_dot = i; // Save the last dot column - } - break; - - case '/': - case '\\': - case ':': - col_filename = i + 1; // Save the last filename - col_dot = value_len; // Reset dot position - break; - - default: - ; - } - } - - switch (option) - { - case 'h': // Dirname with the last slash - value = strdup(value); - value[col_filename] = '\0'; - break; - - case 't': // Filename - value = strdup(value + col_filename); - break; - - case 'r': // All without . file extension - value = strdup(value); - value[col_dot] = '\0'; - break; - - case 'e': // File extension - value = strdup(value + col_dot + 1); - break; - - default: - value = strdup(value); - } - } - return value; -} - - -// -// Resolve define value -// -// Return: new string -// -char *ResolveDefVal(char *str) -{ - int i, j; - char *val; - VBuffer buf; - - InitVBuffer(&buf); - - for (i = 0; '\0' != str[i]; i++) - { - // search $(XXX) - if ('$' == str[i] && '(' == str[i + 1]) - { - for (j = i + 2; '\0' != str[j]; j++) - { - if (')' == str[j]) - { - str[j] = '\0'; - - // get value of XXX - val = SearchDefValWithOption(&str[i + 2]); - - // copy value of XXX - if (val) - { - char *s = val; - - while (*s) - { - PutVBuffer(&buf, *s); - s++; - } - free(val); - } - i = j; - goto next; - } - } - } - PutVBuffer(&buf, str[i]); - next:; - } - return GetVBuffer(&buf); // pass allocated buffer, should be freed by caller -} diff --git a/build/tools/makegcdfirm/defval.h b/build/tools/makegcdfirm/defval.h deleted file mode 100644 index 71355101..00000000 --- a/build/tools/makegcdfirm/defval.h +++ /dev/null @@ -1,38 +0,0 @@ -/*---------------------------------------------------------------------------* - Project: NitroSDK - tools - makerom - File: defval.h - - Copyright 2003-2006 Nintendo. All rights reserved. - - These coded instructions, statements, and computer programs contain - proprietary information of Nintendo of America Inc. and/or Nintendo - Company Ltd., and are protected by Federal copyright law. They may - not be disclosed to third parties or copied or duplicated in any form, - in whole or in part, without the prior written consent of Nintendo. - - $Log: defval.h,v $ - Revision 1.4 2006/01/18 02:11:19 kitase_hirotake - do-indent - - Revision 1.3 2005/02/28 05:26:03 yosizaki - do-indent. - - Revision 1.2 2004/08/05 13:50:13 yasu - Support -M option - - Revision 1.1 2004/03/26 05:06:45 yasu - support variables like as -DNAME=VALUE - - $NoKeywords: $ - *---------------------------------------------------------------------------*/ -#ifndef DEFVAL_H_ -#define DEFVAL_H_ - -#define DEFVAL_DEFAULT_BUFFER_SIZE (1024) - -BOOL AddDefValFromFile(char *filename); -void AddDefVal(char *opt); -char *SearchDefVal(char *name); -char *ResolveDefVal(char *str); - -#endif //DEFVAL_H_ diff --git a/build/tools/makegcdfirm/elf.h b/build/tools/makegcdfirm/elf.h deleted file mode 100644 index c360cd33..00000000 --- a/build/tools/makegcdfirm/elf.h +++ /dev/null @@ -1,431 +0,0 @@ -/*---------------------------------------------------------------------------* - Project: TwlFirm - ELF - File: elf.h - - Copyright 2007 Nintendo. All rights reserved. - - These coded instructions, statements, and computer programs contain - proprietary information of Nintendo of America Inc. and/or Nintendo - Company Ltd., and are protected by Federal copyright law. They may - not be disclosed to third parties or copied or duplicated in any form, - in whole or in part, without the prior written consent of Nintendo. - *---------------------------------------------------------------------------*/ - -#ifndef ELF_H_ -#define ELF_H_ - -#include "misc.h" - -/*--------------------------------------------------------- - 型定義 - --------------------------------------------------------*/ -typedef u32 Elf32_Addr; /* size:4, align:4 Unsigned program address */ -typedef u16 Elf32_Half; /* size:2, align:2 Unsigned medium int */ -typedef u32 Elf32_Off; /* size:4, align:4 Unsigned file offset */ -typedef s32 Elf32_Sword; /* size:4, align:4 Signed large int */ -typedef u32 Elf32_Word; /* size:4, align:4 Unsigned large int */ - -/*--------------------------------------------------------- - ELF Header - --------------------------------------------------------*/ -/* e_identのインデックス */ -#define EI_MAG0 0 /* File identification */ -#define EI_MAG1 1 /* File identification */ -#define EI_MAG2 2 /* File identification */ -#define EI_MAG3 3 /* File identification */ -#define EI_CLASS 4 /* File class 0=invalid, 1=32bit, 2=64bit */ -#define EI_DATA 5 /* Data encoding 0=invalid, 1=LSB, 2=MSB */ -#define EI_VERSION 6 /* File version 現在は1 */ -#define EI_PAD 7 /* Start of padding bytes */ -#define EI_NIDENT 16 /* Size of e_ident[] */ - -typedef struct { - unsigned char e_ident[EI_NIDENT]; - Elf32_Half e_type; /* ELFの形式(再配置可能, 実行可能など) */ - Elf32_Half e_machine; /* ファイルで要求されるアーキテクチャ */ - Elf32_Word e_version; /* ELFフォーマットのバージョン(現在は1) */ - Elf32_Addr e_entry; /* プログラムのエントリポイント。指定無しなら0。 */ - Elf32_Off e_phoff; /* プログラムヘッダテーブルのファイル先頭からのオフセット */ - Elf32_Off e_shoff; /* セクションヘッダテーブルのファイル先頭からのオフセット */ - Elf32_Word e_flags; /* プロセッサ固有のフラグ */ - Elf32_Half e_ehsize; /* ELFヘッダのサイズ */ - Elf32_Half e_phentsize; /* 1プログラムヘッダのサイズ */ - Elf32_Half e_phnum; /* プログラムヘッダの数 */ - Elf32_Half e_shentsize; /* 1セクションヘッダのサイズ */ - Elf32_Half e_shnum; /* セクションヘッダの数 */ - Elf32_Half e_shstrndx; /* セクション名文字列テーブルセクションへのインデックス */ -} Elf32_Ehdr; - -/* e_ident[EI_*]の中身定義 */ -#define ELFMAG0 0x7f -#define ELFMAG1 'E' -#define ELFMAG2 'L' -#define ELFMAG3 'F' -#define ELFCLASSNONE 0 /* invalid */ -#define ELFCLASS32 1 /* ARM and Thumb processors use 32-bit ELF. */ -#define ELFCLASS64 2 -#define ELFDATANONE 0 /* invalid */ -#define ELFDATA2LSB 1 /* little-endian */ -#define ELFDATA2MSB 2 /* big-endian */ - - -/* [e_type] */ -#define ET_NONE 0 /* No file type */ -#define ET_REL 1 /* Re-locatable file */ -#define ET_EXEC 2 /* Executable file */ -#define ET_DYN 3 /* Shared object file */ -#define ET_CORE 4 /* Core file */ -#define ET_LOPROC 0xff00 /* Processor-specific */ -#define ET_HIPROC 0xffff /* Processor-specific */ - -/* [e_machine] */ -#define EM_NONE 0 /* No machine */ -#define EM_M32 1 -#define EM_SPARC 2 -#define EM_386 3 -#define EM_68K 4 -#define EM_88K 5 -#define EM_860 7 -#define EM_MIPS 8 -#define EM_MIPS_RS4_BE 10 -#define EM_ARM 40 /* ARM/Thumb Architecture */ - - -/* [e_version] This member identifies the object file version.*/ -#define EV_NONE 0 /* Invalid version */ -#define EV_CURRENT 1 /* Current version */ - - -/* - ARM-specific e_flags - e_flags Field Value Meaning - EF_ARM_HASENTRY (0x02) e_entry contains a program-loader entry point - (see section 4.1.1, Entry points, below). - EF_ARM_SYMSARESORTED (0x04) Each subsection of the symbol table is sorted by symbol value - (see section 4.4.8, Symbol table order, below) - EF_ARM_DYNSYMSUSESEGIDX (0x8) Symbols in dynamic symbol tables that are defined in sections - included in program segment n have st_shndx = n + 1. - (see section 4.4.9, Dynamic symbol table entries, below). - EF_ARM_MAPSYMSFIRST (0x10) Mapping symbols precede other local symbols in the symbol table - (see section 4.4.8, Symbol table order, below). - - EF_ARM_EABIMASK (0xFF000000)(current version is 0x02000000) - This masks an 8-bit version number, the version of the ARM - EABI to which this ELF file conforms. This EABI is version 2. A - value of 0 denotes unknown conformance. -*/ -#define EF_ARM_HASENTRY 0x02 -#define EF_ARM_SYMSARESORTED 0x04 -#define EF_ARM_DYNSYMSUSESEGIDX 0x8 -#define EF_ARM_MAPSYMSFIRST 0x10 -#define EF_ARM_EABIMASK 0xFF000000 - - -/*--------------------------------------------------------- - Program headers - --------------------------------------------------------*/ -typedef struct { - Elf32_Word p_type; - Elf32_Off p_offset; - Elf32_Addr p_vaddr; - Elf32_Addr p_paddr; - Elf32_Word p_filesz; - Elf32_Word p_memsz; - Elf32_Word p_flags; - Elf32_Word p_align; -} Elf32_Phdr; - -/* [p_type] */ -#define PT_NULL 0 /* 使われないエントリで、他のメンバの値の意味は未定義 */ -#define PT_LOAD 1 /* 実行時にロードされるセグメント */ -#define PT_DYNAMIC 2 /* 動的構造体配列を保持するセグメント */ -#define PT_INTERP 3 /* ファイルの解釈に使われるインタプリタのパスを保持するセグメント */ -#define PT_NOTE 4 /* ファイルの解釈には使われない情報を保持するセグメント */ -#define PT_SHLIB 5 /* 予約 */ -#define PT_PHDR 6 /* プログラムヘッダテーブル(プログラムのメモリイメージの一部である場合のみ存在) */ -//#define PT_TLS ? /* スレッド局所記憶領域のテンプレート */ - -#define PT_LOOS 0x60000000 /* OS固有に予約された領域 */ -#define PT_HIOS 0x6fffffff - -#define PT_LOPROC 0x70000000 /* プロセッサ固有に予約された領域 */ -#define PT_HIPROC 0x7fffffff - -/* [p_flags]*/ -#define PF_X 1 /*実行可能*/ -#define PF_W 2 /*書き込み可能*/ -#define PF_R 4 /*読み出し可能*/ -#define PF_ARM_SB 0x10000000 /*The segment contains the location addressed by the static base*/ -#define PF_ARM_PI 0x20000000 /*The segment is position-independent*/ -#define PF_ARM_ENTRY 0x80000000 /*The segment contains the entry point*/ -#define PF_MASKPROC 0xf0000000 - - -/*--------------------------------------------------------- - Section headers - --------------------------------------------------------*/ -typedef struct { - Elf32_Word sh_name; /*セクションヘッダ文字列テーブルセクションのインデックス*/ - Elf32_Word sh_type; /* タイプ(下記定義参照) */ - Elf32_Word sh_flags; - Elf32_Addr sh_addr; /* */ - Elf32_Off sh_offset; /* ファイルの先頭からのオフセット */ - Elf32_Word sh_size; /* バイト単位のサイズ */ - Elf32_Word sh_link; /* sh_typeによって値の意味が変わる */ - Elf32_Word sh_info; /* sh_typeによって値の意味が変わる */ - Elf32_Word sh_addralign; /* アラインメント制限(0or1で制限なし,4で4ByteAlign) */ - Elf32_Word sh_entsize; /* 固定サイズのエントリテーブルがある場合、1要素のサイズ */ -} Elf32_Shdr; - -/* sh_addr mod sh_addralign = 0 でなければならない */ - -/* Section Types, [sh_type] */ -#define SHT_NULL 0 -#define SHT_PROGBITS 1 -#define SHT_SYMTAB 2 -#define SHT_STRTAB 3 -#define SHT_RELA 4 -#define SHT_HASH 5 -#define SHT_DYNAMIC 6 -#define SHT_NOTE 7 -#define SHT_NOBITS 8 -#define SHT_REL 9 -#define SHT_SHLIB 10 -#define SHT_DYNSYM 11 -#define SHT_LOPROC 0x70000000 -#define SHT_HIPROC 0x7fffffff -#define SHT_LOUSER 0x80000000 -#define SHT_HIUSER 0xffffffff - - -/* [sh_flags] */ -#define SHF_WRITE 0x1 -#define SHF_ALLOC 0x2 -#define SHF_EXECINSTR 0x4 -#define SHF_MASKPROC 0xf0000000 -/* ARM-EABI-specific */ -#define SHF_ENTRYSECT 0x10000000 /* The section contains an entry point. */ -#define SHF_COMDEF 0x80000000 /* The section may be multiply defined in the input to a link step. */ -/* others */ -#define SHF_LINK_ORDER 0x80 - -/*セクションインデックス*/ -//Sym->st_shndxなど -#define SHN_UNDEF 0 -#define SHN_LORESERVE 0xff00 -#define SHN_LOPROC 0xff00 -#define SHN_HIPROC 0xff1f -#define SHN_ABS 0xfff1 -#define SHN_COMMON 0xfff2 -#define SHN_HIRESERVE 0xffff - - -//ここからはヘッダでなく実体データ構造 - -/*--------------------------------------------------------- - Symbol Table Entry - --------------------------------------------------------*/ -typedef struct { - Elf32_Word st_name; /* シンボル文字列テーブルのインデックス */ - Elf32_Addr st_value; /* おそらく関連するセクション内でのオフセット値 */ - Elf32_Word st_size; /* サイズがないか、不明な場合は 0 */ - unsigned char st_info; /* バインド と タイプ */ - unsigned char st_other; /* 現在は 0 が入る */ - Elf32_Half st_shndx; /* 関連するセクションヘッダテーブルのインデックス */ -} Elf32_Sym; - - -/* st_info */ -#define ELF32_ST_BIND(i) ((i)>>4) -#define ELF32_ST_TYPE(i) ((i)&0xf) -#define ELF32_ST_INFO(b,t) (((b)<<4)+((t)&0xf)) - -/* st_info の BIND */ -#define STB_LOCAL 0 -#define STB_GLOBAL 1 -#define STB_WEAK 2 -#define STB_LOPROC 13 -#define STB_HIPROC 15 - -/* st_info の TYPE */ -#define STT_NOTYPE 0 /*未定義*/ -#define STT_OBJECT 1 /*データオブジェクト*/ -#define STT_FUNC 2 -#define STT_SECTION 3 -#define STT_FILE 4 -#define STT_LOPROC 13 -#define STT_HIPROC 15 - - -/*--------------------------------------------------------- - Relocation Entry - --------------------------------------------------------*/ -typedef struct { - Elf32_Addr r_offset; - Elf32_Word r_info; -} Elf32_Rel; - -typedef struct { - Elf32_Addr r_offset; - Elf32_Word r_info; - Elf32_Sword r_addend; -} Elf32_Rela; - -#define ELF32_R_SYM(i) ((i)>>8) -#define ELF32_R_TYPE(i) ((unsigned char)(i)) -#define ELF32_R_INFO(s,t) (((s)<<8)+(unsigned char)(t)) - - -/* r_info の TYPE */ -#define R_ARM_NONE 0 /* Any No relocation. Encodes dependencies between sections. */ -#define R_ARM_PC24 1 /* ARM B/BL S . P + A */ -#define R_ARM_ABS32 2 /* 32-bit word S + A */ -#define R_ARM_REL32 3 /* 32-bit word S . P + A */ -#define R_ARM_PC13 4 /* ARM LDR r, [pc,…] S . P + A */ -#define R_ARM_ABS16 5 /* 16-bit half-word S + A */ -#define R_ARM_ABS12 6 /* ARM LDR/STR S + A */ -#define R_ARM_THM_ABS5 7 /* Thumb LDR/STR S + A */ -#define R_ARM_ABS8 8 /* 8-bit byte S + A */ -#define R_ARM_SBREL32 9 /* 32-bit word S . B + A */ -#define R_ARM_THM_PC22 10 /* Thumb BL pair S . P+ A */ -#define R_ARM_THM_PC8 11 /* Thumb LDR r, [pc,…] S . P + A */ -#define R_ARM_AMP_VCALL9 12 /* AMP VCALL Obsolete.SA-1500 only. */ -#define R_ARM_SWI24 13 /* ARM SWI S + A */ -#define R_ARM_THM_SWI8 14 /* Thumb SWI S + A */ -#define R_ARM_XPC25 15 /* ARM BLX S . P+ A */ -#define R_ARM_THM_XPC22 16 /* Thumb BLX pair S . P+ A */ - -/* 17-31, reserved to ARM Linux */ -//17-19 Reserved to ARM LINUX -#define R_ARM_COPY 20 /* 32 bit word Copy symbol at dynamic link time. */ -#define R_ARM_GLOB_DAT 21 /* 32 bit word Create GOT entry. */ -#define R_ARM_JUMP_SLOT 22 /* 32 bit word Create PLT entry. */ -#define R_ARM_RELATIVE 23 /* 32 bit word Adjust by program base. */ -#define R_ARM_GOTOFF 24 /* 32 bit word Offset relative to start of GOT. */ -#define R_ARM_GOTPC 25 /* 32 bit word Insert address of GOT. */ -#define R_ARM_GOT32 26 /* 32 bit word Entry in GOT. */ -#define R_ARM_PLT32 27 /* ARM BL Entry in PLT. */ - -/* 28-31 Reserved to ARM LINUX */ -#define R_ARM_ALU_PCREL_7_0 32 /* ARM ADD/SUB (S . P + A) & 0x000000FF */ -#define R_ARM_ALU_PCREL_15_8 33 /* ARM ADD/SUB (S . P + A) & 0x0000FF00 */ -#define R_ARM_ALU_PCREL_23_15 34 /* ARM ADD/SUB (S . P + A) & 0x00FF0000 */ -#define R_ARM_LDR_SBREL_11_0 35 /* ARM LDR/STR (S . B + A) & 0x00000FFF */ -#define R_ARM_ALU_SBREL_19_12 36 /* ARM ADD/SUB (S . B + A) & 0x000FF000 */ -#define R_ARM_ALU_SBREL_27_20 37 /* ARM ADD/SUB (S . B + A) & 0x0FF00000 */ - -#define R_ARM_TARGET1 38 -#define R_ARM_ROSEGREL32 39 -#define R_ARM_V4BX 40 -#define R_ARM_TARGET2 41 -#define R_ARM_PREL31 42 - -/* 96-111, reserved to ARM g++ */ -#define R_ARM_GNU_VTENTRY 100 /* 32 bit word Record C++ vtable entry. */ -#define R_ARM_GNU_VTINHERIT 101 /* 32 bit word Record C++ member usage. */ -#define R_ARM_THM_PC11 102 /* Thumb B S . P + A */ -#define R_ARM_THM_PC9 103 /* Thumb B S . P + A */ - -/* 112-127, reserved for private experiments */ - -/* 128-248, reserved to ARM */ -#define R_ARM_RXPC25 249 /* ARM BLX (ΔS . ΔP) + A #define For calls between program segments. */ -#define R_ARM_RSBREL32 250 /* Word (ΔS . ΔSB) + A For an offset from SB, the static base. */ -#define R_ARM_THM_RPC22 251 /* Thumb BL/BLX pair (ΔS . ΔP) + A For calls between program segments. */ -#define R_ARM_RREL32 252 /* Word (ΔS . ΔP) + A For on offset between two segments. */ -#define R_ARM_RABS32 253 /* Word ΔS + A For the address of a location in the target segment. */ -#define R_ARM_RPC24 254 /* ARM B/BL (ΔS . ΔP) + A For calls between program segments. */ -#define R_ARM_RBASE 255 /* None None.Identifies the segment being relocated by the following - relocation directives. The ARM EABI poses two problems for relocating - executables and shared objects encoded in */ - - -// shirait -#define R_ARM_LDR_PC_G0 4 //LDR - -#define R_ARM_ABS12 6 //LDR, STR - -#define R_ARM_THM_CALL 10 //R_ARM_THM_PC22と同じ - -#define R_ARM_CALL 28 //BL/BLX -#define R_ARM_JUMP24 29 //B/BL -#define R_ARM_THM_JUMP24 30 - -#define R_ARM_MOVW_ABS_NC 43 //MOVW -#define R_ARM_MOVT_ABS 44 //MOVT -#define R_ARM_MOVW_PREL_NC 45 //MOVW -#define R_ARM_MOVT_PREL 46 //MOVT - -#define R_ARM_ALU_PC_G0_NC 57 //ADD, SUB -#define R_ARM_ALU_PC_G0 58 //ADD, SUB -#define R_ARM_ALU_PC_G1_NC 59 //ADD, SUB -#define R_ARM_ALU_PC_G1 60 //ADD, SUB -#define R_ARM_ALU_PC_G2 61 //ADD, SUB -#define R_ARM_LDR_PC_G1 62 //LDR, STR, LDRB, STRB -#define R_ARM_LDR_PC_G2 63 //LDR, STR, LDRB, STRB -#define R_ARM_LDRS_PC_G0 64 //LDRD, STRD, LDRH, STRH, LDRSH, LDRSB -#define R_ARM_LDRS_PC_G1 65 //LDRD, STRD, LDRH, STRH, LDRSH, LDRSB -#define R_ARM_LDRS_PC_G2 66 //LDRD, STRD, LDRH, STRH, LDRSH, LDRSB -#define R_ARM_LDC_PC_G0 67 //LDC, STC -#define R_ARM_LDC_PC_G1 68 //LDC, STC -#define R_ARM_LDC_PC_G2 69 //LDC, STC -#define R_ARM_ALU_SB_G0_NC 70 //ADD, SUB -#define R_ARM_ALU_SB_G0 71 //ADD, SUB -#define R_ARM_ALU_SB_G1_NC 72 //ADD, SUB -#define R_ARM_ALU_SB_G1 73 //ADD, SUB -#define R_ARM_ALU_SB_G2 74 //ADD, SUB -#define R_ARM_LDR_SB_G0 75 //LDR, STR, LDRB, STRB -#define R_ARM_LDR_SB_G1 76 //LDR, STR, LDRB, STRB -#define R_ARM_LDR_SB_G2 77 //LDR, STR, LDRB, STRB -#define R_ARM_LDRS_SB_G0 78 //LDRD, STRD, LDRH, STRH, LDRSH, LDRSB -#define R_ARM_LDRS_SB_G1 79 //LDRD, STRD, LDRH, STRH, LDRSH, LDRSB -#define R_ARM_LDRS_SB_G2 80 //LDRD, STRD, LDRH, STRH, LDRSH, LDRSB -#define R_ARM_LDC_SB_G0 81 //LDC, STC -#define R_ARM_LDC_SB_G1 82 //LDC, STC -#define R_ARM_LDC_SB_G2 83 //LDC, STC -#define R_ARM_MOVW_BREL_NC 84 //MOVW -#define R_ARM_MOVT_BREL 85 //MOVT -#define R_ARM_MOVW_BREL 86 //MOVW - -#define R_ARM_GOT_BREL12 97 //LDR -#define R_ARM_GOTOFF12 98 //LDR, STR - -#define R_ARM_TLS_LDO12 109 //LDR, STR -#define R_ARM_TLS_LE12 110 //LDR, STR -#define R_ARM_TLS_TE12GP 111 //LDR - - - -/*--------------------------------------------------------- - Dynamic Section elf_v1.2 - --------------------------------------------------------*/ -typedef struct { - Elf32_Sword d_tag; - union { - Elf32_Word d_val; - Elf32_Addr d_ptr; - } d_un; -} Elf32_Dyn; - - -/* Additional symbol types for Thumb. */ -#define STT_ARM_TFUNC STT_LOPROC /* A Thumb function. */ -#define STT_ARM_16BIT STT_HIPROC /* A Thumb label. */ - - - - - - - - - -/*--------------------------------------------------------- - ELFヘッダを読み出す - --------------------------------------------------------*/ -void *ELF_LoadELFHeader(const void *buf, Elf32_Ehdr *ehdr); - - - -#endif /* ELF_H_ */ - diff --git a/build/tools/makegcdfirm/format_nlist.h b/build/tools/makegcdfirm/format_nlist.h deleted file mode 100644 index e3bee645..00000000 --- a/build/tools/makegcdfirm/format_nlist.h +++ /dev/null @@ -1,54 +0,0 @@ -/*---------------------------------------------------------------------------* - Project: TwlFirm - tools - makegcdfirm - File: format_nlist.h - - Copyright 2007 Nintendo. All rights reserved. - - These coded instructions, statements, and computer programs contain - proprietary information of Nintendo of America Inc. and/or Nintendo - Company Ltd., and are protected by Federal copyright law. They may - not be disclosed to third parties or copied or duplicated in any form, - in whole or in part, without the prior written consent of Nintendo. - - $Date:: 2007-09-06$ - $Rev$ - $Author$ - *---------------------------------------------------------------------------*/ -#ifndef FORMAT_NLIST_H_ -#define FORMAT_NLIST_H_ - -#include -#include "misc.h" -#include "path.h" - -#define SPECFILE_MAGIC_ID "#NORSF" - -#define CRC16_INIT_VALUE 0xffff - -//--------------------------------------------------------------------------- -// Banner Spec File -//--------------------------------------------------------------------------- - -// Command List -typedef struct -{ - char *string; - BOOL (*funcp) (char *, int num); - -} -tCommandDesc; - - -// F Command -typedef struct -{ - u32 offsetStart; - u32 offsetEnd; - u32 padding; - char fullPathSrc[FILENAME_MAX]; - -} -tFileDesc; - - -#endif // FORMAT_NLIST_H_ diff --git a/build/tools/makegcdfirm/format_rom.h b/build/tools/makegcdfirm/format_rom.h deleted file mode 100644 index c1c6d89e..00000000 --- a/build/tools/makegcdfirm/format_rom.h +++ /dev/null @@ -1,59 +0,0 @@ -/*---------------------------------------------------------------------------* - Project: TwlFirm - tools - makegcdfirm - File: format_rom.h - - Copyright 2007 Nintendo. All rights reserved. - - These coded instructions, statements, and computer programs contain - proprietary information of Nintendo of America Inc. and/or Nintendo - Company Ltd., and are protected by Federal copyright law. They may - not be disclosed to third parties or copied or duplicated in any form, - in whole or in part, without the prior written consent of Nintendo. - - $Date:: 2007-09-06$ - $Rev$ - $Author$ - *---------------------------------------------------------------------------*/ -#ifndef FORMAT_ROM_H_ -#define FORMAT_ROM_H_ - -#include "misc.h" -#include - - -#define DEFAULT_ALIGN 0x200 -#define FIRM_ALIGN DEFAULT_ALIGN -#define FIRM_ALIGN_MASK (FIRM_ALIGN - 1) - -#define NML_AREA_ALIGN 0x80000 // 512KB -#define TWL_AREA_ALIGN 0x80000 // 512KB -#define SEC2_AREA_OFFSET 0x3000 // 12KB -#define GAME2_AREA_OFFSET 0x7000 // 28KB - -#define DEFAULT_HOSTROOT "." -#define DEFAULT_ROOT "/" - -#define DEFAULT_REJECT_1 "CVS" -#define DEFAULT_REJECT_2 "vssver.scc" - -#define FORMAT_VERSION "1.0" - -#define ENTRYNAME_MAX 127 - -#define ROM_SIZE_MIN 0x20000 - -#define DEFAULT_ROMHEADER_TEMPLATE "gcdfirm_header_twlj.template.sbin" -#define DEFAULT_LISTFILE "default.nlf" - -#define DEFAULT_NORFIRM_SUFFIX ".gcd" -#define DEFAULT_SPECFILE_SUFFIX ".gcdsf" - -/*===========================================================================* - * ROM FORMAT - *===========================================================================*/ - -//--------------------------------------------------------------------------- -// ROM HEADER -//--------------------------------------------------------------------------- - -#endif //FORMAT_ROM_H_ diff --git a/build/tools/makegcdfirm/format_sign.h b/build/tools/makegcdfirm/format_sign.h deleted file mode 100644 index 782a5d2b..00000000 --- a/build/tools/makegcdfirm/format_sign.h +++ /dev/null @@ -1,32 +0,0 @@ -/*---------------------------------------------------------------------------* - Project: TwlFirm - SS - File: format_sign.h - - Copyright 2006 Nintendo. All rights reserved. - - These coded instructions, statements, and computer programs contain - proprietary information of Nintendo of America Inc. and/or Nintendo - Company Ltd., and are protected by Federal copyright law. They may - not be disclosed to third parties or copied or duplicated in any form, - in whole or in part, without the prior written consent of Nintendo. - - $Date:: 2007-09-06$ - $Rev$ - $Author$ - *---------------------------------------------------------------------------*/ -#ifndef FIRM_MAKENORFIRM_ACSIGN_FORMAT_H_ -#define FIRM_MAKENORFIRM_ACSIGN_FORMAT_H_ - -#include "format_rom.h" - - -#ifdef __cplusplus -extern "C" { -#endif - -#ifdef __cplusplus -} /* extern "C" */ -#endif - -/* FIRM_MAKENORFIRM_ACSIGN_FORMAT_H_ */ -#endif diff --git a/build/tools/makegcdfirm/gcdfirm_header_twlj.template.sbin b/build/tools/makegcdfirm/gcdfirm_header_twlj.template.sbin deleted file mode 100644 index 06a882131831fcf3eb05aa51ef31d09ace384e7d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16384 zcmeIup$z~b5Jkb27(DG@FGvzPpbY9po;X1RsLQPSYo3^hbA7bue0SEEHFhfLtF3&e zszQJO0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 Z2oNAZfB*pk1PBlyK!5-N0tEgg@B*;^1M2_) diff --git a/build/tools/makegcdfirm/makegcdfirm.c b/build/tools/makegcdfirm/makegcdfirm.c deleted file mode 100644 index 887cc4c8..00000000 --- a/build/tools/makegcdfirm/makegcdfirm.c +++ /dev/null @@ -1,111 +0,0 @@ -/*---------------------------------------------------------------------------* - Project: TwlFirm - tools - makegcdfirm - File: makegcdfirm.c - - Copyright 2007 Nintendo. All rights reserved. - - These coded instructions, statements, and computer programs contain - proprietary information of Nintendo of America Inc. and/or Nintendo - Company Ltd., and are protected by Federal copyright law. They may - not be disclosed to third parties or copied or duplicated in any form, - in whole or in part, without the prior written consent of Nintendo. - - $Date:: 2007-09-06$ - $Rev$ - $Author$ - *---------------------------------------------------------------------------*/ -#include -#include -#include // strcasecmp() -#include // getopt() -#include "makegcdfirm.h" -#include "format_rom.h" -#include "path.h" -#include "defval.h" -#include "version.h" - -static int makegcdfirm(const char *specFile, const char *norFile, const char *rhFile); - -//--------------------------------------------------------------------------- -// Main -//--------------------------------------------------------------------------- - -int main(int argc, char *argv[]) -{ - int n; - int narg; - char *gcdfirmFile; - char *rhFile = NULL; - - InitAppName(argv[0]); - - while ((n = getopt(argc, argv, "D:hvt:pd")) != -1) - { - switch (n) - { - case 'h': - case 'v': - goto usage; - - case 'D': - AddDefVal(optarg); - break; - - case 't': - rhFile = optarg; - break; - - case 'p': - PrintMode = TRUE; - break; - - case 'd': - DebugMode = TRUE; - break; - - default: - break; - } - } - - narg = argc - optind; - if (narg > 0) - { - // Make SpecFile->GcdfirmFile - gcdfirmFile = - strdup(narg > - 1 ? argv[optind + 1] : ChangeSuffix(argv[optind], DEFAULT_NORFIRM_SUFFIX)); - return makegcdfirm(argv[optind], gcdfirmFile, rhFile); - } - - usage: - { - char *makegcdfirm = GetAppName(); - - fprintf(stderr, - "NITRO-SDK Development Tool - %s - Make gcdfirm file \n" - "Build %lu\n\n" - "Usage: %s [-phv] [-tROMHEADERFILE] [-DNAME=VALUE ...] SPECFILE [NORFIRMFILE]\n\n", - makegcdfirm, SDK_DATE_OF_LATEST_FILE, makegcdfirm); - } - return 1; -} - - -//--------------------------------------------------------------------------- -// makegcdfirm -//--------------------------------------------------------------------------- - -static int makegcdfirm(const char *specFile, const char *norFile, const char *rhFile) -{ - debug_printf("makegcdfirm(): '%s' -> '%s'\n", specFile, norFile); - - // Check identical - if (specFile && norFile && !strcasecmp(specFile, norFile)) - { - error("gcdfirm spec file is identical '%s'", norFile); - return 1; - } - - return OutputGcdfirmFile(specFile, norFile, rhFile) ? 0 : 1; -} diff --git a/build/tools/makegcdfirm/makegcdfirm.h b/build/tools/makegcdfirm/makegcdfirm.h deleted file mode 100644 index 803ce06f..00000000 --- a/build/tools/makegcdfirm/makegcdfirm.h +++ /dev/null @@ -1,24 +0,0 @@ -/*---------------------------------------------------------------------------* - Project: TwlFirm - tools - makegcdfirm - File: makegcdfirm.h - - Copyright 2007 Nintendo. All rights reserved. - - These coded instructions, statements, and computer programs contain - proprietary information of Nintendo of America Inc. and/or Nintendo - Company Ltd., and are protected by Federal copyright law. They may - not be disclosed to third parties or copied or duplicated in any form, - in whole or in part, without the prior written consent of Nintendo. - - $Date:: 2007-09-06$ - $Rev$ - $Author$ - *---------------------------------------------------------------------------*/ -#ifndef MAKEGCDFIRM_H_ -#define MAKEGCDFIRM_H_ - -#include "misc.h" - -BOOL OutputGcdfirmFile(const char *specFile, const char *gcdFile, const char *rhFile); - -#endif //MAKEGCDFIRM_H_ diff --git a/build/tools/makegcdfirm/misc.c b/build/tools/makegcdfirm/misc.c deleted file mode 100644 index 7706d6be..00000000 --- a/build/tools/makegcdfirm/misc.c +++ /dev/null @@ -1,628 +0,0 @@ -/*---------------------------------------------------------------------------* - Project: TwlFirm - tools - makenorfirm - File: misc.c - - Copyright 2007 Nintendo. All rights reserved. - - These coded instructions, statements, and computer programs contain - proprietary information of Nintendo of America Inc. and/or Nintendo - Company Ltd., and are protected by Federal copyright law. They may - not be disclosed to third parties or copied or duplicated in any form, - in whole or in part, without the prior written consent of Nintendo. - - $Date:: 2007-09-06$ - $Rev$ - $Author$ - *---------------------------------------------------------------------------*/ -#include -#include // calloc() -#include // free(), exit() -#include // setmode() -#include // stat() -#include // setmode() -#include // strlen() -#include // va_start(),va_end() -#include // localtime() - -#include -#include "misc.h" - -BOOL DebugMode = FALSE; -BOOL PrintMode = FALSE; -char *PubkeyFileName = NULL; - -/*---------------------------------------------------------------------------* - * File Output Utilities - * - * BOOL OpenFile( const char* filename ) - * void CloseFile( void ) - * BOOL CheckResult( void ) - * void PutBuffer( const void* ptr, int len ) - * void PutByte( u8 c ) - * void PutWord( u16 c ) - * void PutWord( u32 c ) - * void PutString( const char *str ) - *---------------------------------------------------------------------------*/ - -static FILE *OutFile = NULL; -static const char *FileName = NULL; -static BOOL Status = FALSE; - - -// -// File Open -// - -BOOL OpenFile(const char *filename) -{ - if (OutFile) - CloseFile(); - - if (filename) - { - if (NULL == (OutFile = fopen(filename, "wb+"))) - { - error("Can't write '%s'", filename); - Status = FALSE; - return FALSE; - } - } - else - { - setmode(1, O_BINARY); - OutFile = stdout; // out to console if filename == NULL - } - FileName = filename; - Status = TRUE; - - return TRUE; -} - - -// -// File Close -// - -BOOL CloseFile(void) -{ - if (OutFile) - { - if (FileName) - { - if (fclose(OutFile) == -1) - { - error("Can't close '%s'", FileName); - Status = FALSE; - } - } - else - { - setmode(1, O_TEXT); - } - } - OutFile = NULL; - - return Status; -} - - -// -// File Seek -// - -void SeekFile(long pos) -{ - if (OutFile && fseek(OutFile, pos, SEEK_SET)) - { - error("Can't seek '%s'", FileName ? FileName : ""); - CloseFile(); - Status = FALSE; - } -} - - -// -// Error Check -// - -BOOL CheckResult(void) -{ - return Status; -} - - -// -// Delete outfile -// - -void DeleteOutFile(void) -{ - // Delete outfile - if (FileName) - { - debug_printf("Delete '%s'\n", FileName); - (void)unlink(FileName); - FileName = NULL; - } - return; -} - - -// -// Buffer Output -// - -void PutBuffer(const void *ptr, int len) /* If error, close file */ -{ - if (OutFile && len != fwrite(ptr, 1, len, OutFile)) - { - error("Can't write buffer to '%s'", FileName ? FileName : ""); - CloseFile(); - Status = FALSE; - } -} - -// -// Buffer Input -// - -void GetBuffer(void *ptr, int len) /* If error, close file */ -{ - if (OutFile && len != fread(ptr, 1, len, OutFile)) - { - error("Can't read '%s'", FileName ? FileName : ""); - CloseFile(); - Status = FALSE; - } -} - -// -// Byte/Half/Word Output -// - -void PutByte(u8 c) -{ - PutBuffer(&c, 1); -} -void PutHalf(u16 c) -{ - PutBuffer(&c, 2); -} -void PutWord(u32 c) -{ - PutBuffer(&c, 4); -} -void PutString(const char *str) -{ - PutBuffer(str, strlen(str)); -} - - -// -// Printf -// - -void PrintString(const char *fmt, ...) -{ - char *buffer; - va_list va; - int nchars; - int bufsize = FILENAME_MAX; - - while (1) - { - buffer = Alloc(bufsize); - va_start(va, fmt); - nchars = vsnprintf(buffer, bufsize, fmt, va); - va_end(va); - - if (0 <= nchars && nchars < bufsize) - { - break; - } - - Free(&buffer); - bufsize *= 2; - } - - if (nchars > 0) - { - PutBuffer(buffer, nchars); - } - Free(&buffer); -} - - -/*---------------------------------------------------------------------------* - * File Read/Write Utilities - * - * int ReadFile( const char* filename, void** buffer ) - * - * Read a file to buffer allocated internally - * Return read size - * Add '\0' at tail of file for help to handle text file - * - * BOOL WriteFile( const char* filename, void** buffer, int size ) - *---------------------------------------------------------------------------*/ - -int ReadFile(const char *filename, void *filebuffer, int size) -{ - FILE *fp; - struct stat fileStat; - int fileSize, readSize; - void **buffer = (void **)filebuffer; - - /* Check file */ - if (stat(filename, &fileStat) || !S_ISREG(fileStat.st_mode)) - { - goto error; - } - fileSize = fileStat.st_size; - if (fileSize < 0) - { - goto error; - } - - /* Open file */ - fp = fopen(filename, "rb"); - if (!fp) - { - goto error; - } - - if (size && (size < fileSize)) - { - readSize = size; - } - else - { - readSize = fileSize; - } - - /* Read file */ - *buffer = Alloc(readSize + 1); /* error handle is done in Alloc() */ - /* size+1 for '\0' to handle text file */ - if (readSize != fread(*buffer, sizeof(char), readSize, fp)) - { - goto error_free_close; - } - - (*(char **)buffer)[readSize] = '\0'; /* Works as terminater if file is text file */ - - /* Close file */ - fclose(fp); - return readSize; - - error_free_close: - Free(buffer); - fclose(fp); - error: - error("Can't read '%s'", filename); - return -1; -} - - -int ReadFileWithPadding(const char *filename, void *filebuffer, int size, int boundary) -{ - FILE *fp; - struct stat fileStat; - int fileSize, readSize, padSize; - void **buffer = (void **)filebuffer; - - if (!boundary) - { - return ReadFile(filename, buffer, size); - } - - /* Check file */ - if (stat(filename, &fileStat) || !S_ISREG(fileStat.st_mode)) - { - goto error; - } - fileSize = fileStat.st_size; - if (fileSize < 0) - { - goto error; - } - - /* Open file */ - fp = fopen(filename, "rb"); - if (!fp) - { - goto error; - } - - if (size && (size < fileSize)) - { - readSize = size; - } - else - { - readSize = fileSize; - } - - padSize = (boundary - (readSize & (boundary-1))) & (boundary-1); - - /* Read file */ - *buffer = Alloc(readSize + padSize); /* error handle is done in Alloc() */ - /* size+1 for '\0' to handle text file */ - if (readSize != fread(*buffer, sizeof(char), readSize, fp)) - { - goto error_free_close; - } - - memset((char*)*buffer + readSize, 0, padSize); - - /* Close file */ - fclose(fp); - return readSize + padSize; - - error_free_close: - Free(buffer); - fclose(fp); - error: - error("Can't read '%s'", filename); - return -1; -} - - -BOOL WriteFile(const char *filename, void *buffer, int size) -{ - debug_printf("WriteFile %s\n", filename); - - (void)OpenFile(filename); - PutBuffer(buffer, size); - CloseFile(); - Free(&buffer); - return CheckResult(); -} - - -/*---------------------------------------------------------------------------* - * Time Format Utilities - * - * char* GetGMTime( const time_t time ) Show GMT - * char* GetTime( const time_t time ) Show local Time - *---------------------------------------------------------------------------*/ - -char *GetGMTime(const time_t time) -{ - static char timebuffer[32]; - strftime(timebuffer, sizeof(timebuffer), "%y/%m/%d-%H:%M:%S", gmtime(&time)); - return timebuffer; -} - - -char *GetTime(const time_t time) -{ - static char timebuffer[32]; - strftime(timebuffer, sizeof(timebuffer), "%y/%m/%d-%H:%M:%S", localtime(&time)); - return timebuffer; -} - - -/*---------------------------------------------------------------------------* - * Memory Allocation Utilities - * - * void* Alloc( size_t size ) - *---------------------------------------------------------------------------*/ - -void *Alloc(size_t size) -{ - void *t = calloc(1, size); - - if (t == NULL) - { - error("Can't allocate memory."); - exit(10); - } - return t; -} - - -void Free(void *p) -{ - void **ptr = (void **)p; - - if (*ptr) - { - free(*ptr); - (*ptr) = NULL; - } -} - - -/*---------------------------------------------------------------------------* - * VBuffer - * - * void PutVBuffer( VBuffer* vbuf, char c ) - *---------------------------------------------------------------------------*/ - -void PutVBuffer(VBuffer * vbuf, char c) -{ - int size; - char *tmp_buffer; - - if (vbuf->buffer == 0) - { - vbuf->size = VBUFFER_INITIAL_SIZE; - vbuf->buffer = Alloc(vbuf->size); // buffer is CALLOCed - } - size = strlen(vbuf->buffer); - - if (size >= vbuf->size - 1) - { - // Need buffer expansion - vbuf->size *= 2; - tmp_buffer = Alloc(vbuf->size); // buffer is CALLOCed - strcpy(tmp_buffer, vbuf->buffer); - Free(&vbuf->buffer); - vbuf->buffer = tmp_buffer; - } - vbuf->buffer[size] = c; - return; -} - -char *GetVBuffer(VBuffer * vbuf) -{ - return vbuf->buffer; -} - -void InitVBuffer(VBuffer * vbuf) -{ - vbuf->buffer = 0; - vbuf->size = 0; -} - -void FreeVBuffer(VBuffer * vbuf) -{ - Free(&vbuf->buffer); -} - - -/*---------------------------------------------------------------------------* - * File Path Utilities - * - * char* ChangeBackSlash( char* path ) - *---------------------------------------------------------------------------*/ - -char *ChangeBackSlash(char *path) -{ - char *p = path; - - while (*p) - { - if (*p == '\\') - { - *p = '/'; - } - p++; - } - return path; -} - - -/*---------------------------------------------------------------------------* - * Math - * - * u16 CalcCRC16( u16 start, u8 *data, int size ) - *---------------------------------------------------------------------------*/ - -static u16 crc16_table[16] = { - 0x0000, 0xCC01, 0xD801, 0x1400, - 0xF001, 0x3C00, 0x2800, 0xE401, - 0xA001, 0x6C00, 0x7800, 0xB401, - 0x5000, 0x9C01, 0x8801, 0x4400 -}; - -u16 CalcCRC16(u16 start, u8 *data, int size) -{ - u16 r1; - u16 total = start; - - while (size-- > 0) - { - // 下位4bit - r1 = crc16_table[total & 0xf]; - total = (total >> 4) & 0x0fff; - total = total ^ r1 ^ crc16_table[*data & 0xf]; - - // 上位4bit - r1 = crc16_table[total & 0xf]; - total = (total >> 4) & 0x0fff; - total = total ^ r1 ^ crc16_table[(*data >> 4) & 0xf]; - - data++; - } - return total; -} - - -/*---------------------------------------------------------------------------* - * for firm header - * - *---------------------------------------------------------------------------*/ - -static u8 ConvertAlign( u32 ofs ) -{ - u8 i; - - ofs /= 4; - for (i=0; i<7; i++) - { - if ( ofs & 1 ) - { - break; - } - ofs >>= 1; - } - - return i; -} - -tROMAddrConvType ConvertHeaderRamAddr( s32 p ) -{ - tROMAddrConvType retval; - - retval.align = ConvertAlign( p ); - retval.address = (u16)((p - HW_WRAM)/(4< - -typedef enum -{ - FALSE = 0, - TRUE = 1 -} -BOOL; - -typedef unsigned char u8; -typedef unsigned short int u16; -typedef unsigned long int u32; -typedef unsigned long long u64; -typedef signed char s8; -typedef signed short int s16; -typedef signed long int s32; -typedef signed long long s64; -typedef volatile u8 vu8; -typedef volatile u32 vu32; -typedef vu32 REGType32v; - -#define error(...) do { fprintf(stderr, "Error: "); \ - fprintf(stderr, __VA_ARGS__); \ - fprintf(stderr, "\n"); } while(0) - -#define warning(...) do { fprintf(stderr, "Warning: "); \ - fprintf(stderr, __VA_ARGS__); \ - fprintf(stderr, "\n"); } while(0) - -BOOL OpenFile(const char *filename); -BOOL CloseFile(void); -void SeekFile(long pos); -BOOL CheckResult(void); -void DeleteOutFile(void); -void PutBuffer(const void *ptr, int len); -void GetBuffer(void *ptr, int len); -void PutByte(u8 c); -void PutHalf(u16 c); -void PutWord(u32 c); -void PutString(const char *str); -void PrintString(const char *fmt, ...); - -#define READ_ALL 0 -int ReadFile(const char *filename, void *filebuffer, int size); -int ReadFileWithPadding(const char *filename, void *filebuffer, int size, int boundary); -BOOL WriteFile(const char *filename, void *buffer, int size); - -char *GetGMTime(const time_t time); -char *GetTime(const time_t time); - -void *Alloc(size_t size); -void Free(void *p); - -typedef struct -{ - char *buffer; - int size; -} -VBuffer; - -#define VBUFFER_INITIAL_SIZE 1024 -void InitVBuffer(VBuffer * vbuf); -void FreeVBuffer(VBuffer * vbuf); -void PutVBuffer(VBuffer * vbuf, char c); -char *GetVBuffer(VBuffer * vbuf); - -char *ChangeBackSlash(char *path); - -u16 CalcCRC16(u16 start, u8 *data, int size); -const char *WrapNull(const char *str); - -typedef struct -{ - u16 address; - u8 align; -} -tROMAddrConvType; - -tROMAddrConvType ConvertHeaderRamAddr( s32 p ); -tROMAddrConvType ConvertHeaderRomOffset( s32 p ); -u16 ConvertHeaderRomOffsetAlign( s32 p, u32 align ); - -typedef union -{ - struct - { - u32 sign:1; - u32 header_hash:1; - u32 arm9_hash:1; - u32 arm7_hash:1; - u32 hash_table_hash:1; - u32 final_hash:1; - u32 header_footer:1; - } - e; - u32 raw; -} -tErrorFlags; - -extern BOOL DebugMode; -extern BOOL PrintMode; -extern char *PubkeyFileName; -void debug_printf(const char *str, ...); -void debug_printf2(const char *str, ...); - -#endif //MISC_H_ diff --git a/build/tools/makegcdfirm/out_gcdfirm.c b/build/tools/makegcdfirm/out_gcdfirm.c deleted file mode 100644 index 6e33fa88..00000000 --- a/build/tools/makegcdfirm/out_gcdfirm.c +++ /dev/null @@ -1,1009 +0,0 @@ -/*---------------------------------------------------------------------------* - Project: TwlFirm - tools - makegcdfirm - File: out_gcdfirm.c - - Copyright 2007 Nintendo. All rights reserved. - - These coded instructions, statements, and computer programs contain - proprietary information of Nintendo of America Inc. and/or Nintendo - Company Ltd., and are protected by Federal copyright law. They may - not be disclosed to third parties or copied or duplicated in any form, - in whole or in part, without the prior written consent of Nintendo. - - $Date:: 2007-09-06$ - $Rev$ - $Author$ - *---------------------------------------------------------------------------*/ -#include -#include // atoi() -#include // strcmp() -#include // isprint() -#include // chdir() -#include -#include // UCHAR_MAX -#include -#include // stat() -#include "elf.h" -#include "misc.h" -#include "defval.h" -#include "format_rom.h" -#include "format_nlist.h" -#include "makegcdfirm.h" -#include "format_sign.h" -#include "acsign_gcd.h" -#include "compress.h" - -#define SDK_ASM - -#include -#include "../acsign/aes2.h" - -#define ROMHDRCMD "ROM_HDR" -#define SBIN9CMD "ARM9_SBIN" -#define SBIN7CMD "ARM7_SBIN" -#define ELF9CMD "ARM9_ELF" -#define ELF7CMD "ARM7_ELF" -#define GAMECODECMD "GAMECODE" -#define ARM9X2CMD "ARM9_X2" -#define NMLOFSCMD "NML_OFS" -#define TWLOFSCMD "TWL_OFS" -#define VERCMD "VERSION" -#define RSAKEYCMD "RSA_KEY" -#define OUTKEYCMD "OUT_KEY" -#define WREGCMD "WRAM_RBIN" -#define NANDFMCMD "NANDFIRM" -#define NORFMCMD "NORFIRM" -#define ERRCMD "ERROR" - -static BOOL ConstructGcdfirmFile(char * specFile); -static BOOL ReadRomHeaderFile(const char *fileName); -static BOOL ReadSbinFile(const char *fileName, void* minfo, void* hash, BOOL comp); -static size_t ReadFirmFile(const char *fileName); -static BOOL ReadKeyFile(const char *fileName); -static BOOL ReadWramRegFile(const char *fileName); -static s32 GetRamAddr(const char *fileName); - -static BOOL EncryptBuffer(char *buffer, int length); - -static BOOL RomHeader_Command(char * line, int num); -static BOOL Sbin9_Command(char * line, int num); -static BOOL Sbin7_Command(char * line, int num); -static BOOL Elf9_Command(char * line, int num); -static BOOL Elf7_Command(char * line, int num); -static BOOL GAMECODE_Command(char * line, int num); -static BOOL ARM9X2_Command(char * line, int num); -static BOOL NMLOFS_Command(char * line, int num); -static BOOL TWLOFS_Command(char * line, int num); -static BOOL VERSION_Command(char * line, int num); -static BOOL RSAKEY_Command(char * line, int num); -static BOOL OUTKEY_Command(char * line, int num); -static BOOL WramRegs_Command(char * line, int num); -static BOOL NorFirm_Command(char * line, int num); -static BOOL NandFirm_Command(char * line, int num); -static BOOL ERROR_Command(char * line, int num); - -static BOOL InitializeAesKey(void); -static BOOL InitializeGcdfirmFile(const char *rhFile); -static BOOL FinalizeGcdfirmFile(const char *gcdFile); - -static s32 Offset; // Current offset -static int LineNum; // Line number for error message -static const char *specFileName; // specFile name for error message - -GCDHeader gcdHeader; // Gcdfirm Header Shadow -FIRMSignedContext signedContext; -u8 *keyFileBuf; -BOOL compArm9 = FALSE; -BOOL compArm7 = FALSE; -tErrorFlags errFlags; - -//--------------------------------------------------------------------------- -// Output - gcdfirm File -//--------------------------------------------------------------------------- - -BOOL OutputGcdfirmFile(const char *specFile, const char *gcdFile, const char *rhFile) -{ - char *buffer; - BOOL state; - - if (ReadFile(specFile, &buffer, READ_ALL) <= 0) - { - return FALSE; - } - - if (!OpenFile(gcdFile)) - { - return FALSE; - } - - specFileName = specFile; - - state = InitializeGcdfirmFile( rhFile ) && ConstructGcdfirmFile(buffer) && - FinalizeGcdfirmFile(gcdFile) && CloseFile(); - - if (!state) - { - DeleteOutFile(); - } - - return state; -} - - -//--------------------------------------------------------------------------- -// Output - Gcdfirm File -//--------------------------------------------------------------------------- - -static const tCommandDesc command[] = { - {ROMHDRCMD, RomHeader_Command}, - {SBIN9CMD, Sbin9_Command}, {SBIN7CMD, Sbin7_Command}, - {ELF9CMD, Elf9_Command},{ELF7CMD, Elf7_Command}, - {VERCMD, VERSION_Command}, - {GAMECODECMD, GAMECODE_Command}, - {ARM9X2CMD, ARM9X2_Command}, - {NMLOFSCMD, NMLOFS_Command}, - {TWLOFSCMD, TWLOFS_Command}, - {RSAKEYCMD, RSAKEY_Command}, - {OUTKEYCMD, OUTKEY_Command}, - {WREGCMD, WramRegs_Command}, - {NANDFMCMD, NandFirm_Command}, - {NORFMCMD, NorFirm_Command}, - {ERRCMD, ERROR_Command}, -}; - -BOOL ConstructGcdfirmFile(char * specFile) -{ - char *line; - char *line_top; - char *p; - int i; - - LineNum = 0; - Offset = 0x4000; - SeekFile(Offset); - - line = specFile++; - - while (*line != '\0') - { - LineNum++; - - // Get command line - line_top = line; - while (*line != '\0') - { - if (*line++ == '\n') - { - break; - } - } - - // Print for debug - debug_printf("GCDSF Line%4d [", LineNum, line); - for (p = line_top; p != line; p++) - { - if (isprint(*p)) - { - debug_printf("%c", *p); - } - } - debug_printf("]\n"); - - if (*line_top == '#') - { - } - else - { - for (i = 0; i < (sizeof(command) / sizeof(command[0])); i++) - { - if (!strncmp(line_top, command[i].string, strlen(command[i].string))) - { - if (command[i].funcp != NULL) - { - char line_cmd[FILENAME_MAX]; - char line_scan[FILENAME_MAX]; - char* line_conv; - int num; - - num = sscanf( line_top, - "%1024[^ :] : %1024[^ \x0d:#\n]", - line_cmd, line_scan - ); - line_conv = ResolveDefVal(line_scan); - - debug_printf("line_cmd = %s, line_conv = %s\n", line_cmd, line_conv); - - if (!command[i].funcp(line_conv, num - 1)) - return FALSE; - } - } - } - } - - } - return TRUE; -} - - -//--------------------------------------------------------------------------- -// Output - 'RomHeader' Command -//--------------------------------------------------------------------------- - -static BOOL RomHeader_Command(char * line, int num) -{ - if (num != 1) - { - error("Wrong format spec file '%s' line:%d", specFileName, LineNum); - return FALSE; - } - - debug_printf2("hom header file = %s\n", line); - - return ReadRomHeaderFile(line); -} - - -static BOOL ReadRomHeaderFile(const char *fileName) -{ - char *file; - int file_size; - struct stat st; - - if (FILESTATUS_FILE != GetFileStatus(&st, fileName)) - { - error("'%s' is not regular file.", fileName); - return FALSE; - } - - if ((file_size = ReadFile(fileName, &file, READ_ALL)) < 0) - return FALSE; - - gcdHeader = *(GCDHeader*)file; - - // Output file image with fitting region - SeekFile(0L); - PutBuffer(file, file_size); - - Free(&file); - - return CheckResult(); -} - -//--------------------------------------------------------------------------- -// Output - 'WramRegs' Command -//--------------------------------------------------------------------------- - -extern MIHeader_WramRegs wram_regs_init; -MIHeader_WramRegs* wram_regs; - -static BOOL WramRegs_Command(char * line, int num) -{ - if (num != 1) - { - error("Wrong format spec file '%s' line:%d", specFileName, LineNum); - return FALSE; - } - - debug_printf2("wram regs file = %s\n", line); - - return ReadWramRegFile(line); -} - -static BOOL ReadWramRegFile(const char *fileName) -{ - int file_size; - struct stat st; - - if (FILESTATUS_FILE != GetFileStatus(&st, fileName)) - { - error("'%s' is not regular file.", fileName); - return FALSE; - } - - if ((file_size = ReadFile(fileName, &wram_regs, READ_ALL)) < 0) - return FALSE; - - gcdHeader.h.w = *wram_regs; - - return CheckResult(); -} - -//--------------------------------------------------------------------------- -// Output - 'RSAKEY' Command -//--------------------------------------------------------------------------- - -static BOOL RSAKEY_Command(char * line, int num) -{ - if (num != 1) - { - error("Wrong format spec file '%s' line:%d", specFileName, LineNum); - return FALSE; - } - - debug_printf2("rsa key = %s\n", line); - - return ReadKeyFile(line); -} - -static BOOL ReadKeyFile(const char *fileName) -{ - int file_size; - struct stat st; - - if (FILESTATUS_FILE != GetFileStatus(&st, fileName)) - { - error("'%s' is not regular file.", fileName); - return FALSE; - } - - if ((file_size = ReadFile(fileName, &keyFileBuf, READ_ALL)) < 0) - return FALSE; - - return CheckResult(); -} - - -//--------------------------------------------------------------------------- -// Output - 'OUTKEY' Command -//--------------------------------------------------------------------------- - -static BOOL OUTKEY_Command(char * line, int num) -{ - if (num != 1) - { - error("Wrong format spec file '%s' line:%d", specFileName, LineNum); - return FALSE; - } - - debug_printf2("out key = %s\n", line); - - PubkeyFileName = line; - - return CheckResult(); -} - - -//--------------------------------------------------------------------------- -// Output - 'VERSION' Command -//--------------------------------------------------------------------------- - -static u8 ConvToBCD8(int x) -{ - u8 bcd = 0; - - x %= 100; - bcd |= (x / 10)<<4; - bcd |= (x % 10); - - return bcd; -} - -static BOOL VERSION_Command(char * line, int num) -{ - char scan[FILENAME_MAX]; - u64 version = -1; - - // rescan - num = sscanf( line, - "0x%1024[^\x0d\n]", - scan - ); - - if (num == 1) - { - // convert version info - version = strtoull(scan, NULL, 16); - } - else if (num == 0) - { - // generate version info - u8* ver8 = (u8*)&version; - time_t timer; - struct tm *t_st; - - time(&timer); - t_st = localtime(&timer); - - ver8[0] = ConvToBCD8(t_st->tm_min); - ver8[1] = ConvToBCD8(t_st->tm_hour); - ver8[2] = ConvToBCD8(t_st->tm_mday); - ver8[3] = ConvToBCD8(t_st->tm_mon+1); - ver8[4] = ConvToBCD8(t_st->tm_year); - ver8[5] = 0x57; - ver8[6] = 0xff; - ver8[7] = 0xff; - } - - debug_printf2("version = %08llx\n", version); - - return CheckResult(); -} - - -//--------------------------------------------------------------------------- -// Output - 'NMLOFS' Command -//--------------------------------------------------------------------------- - -static BOOL NMLOFS_Command(char * line, int num) -{ - u32 offset = 0; - - if (num != 1) - { - error("Wrong format spec file '%s' line:%d", specFileName, LineNum); - return FALSE; - } - - offset = strtoul(line, NULL, 0); - - gcdHeader.l.normal_area_offset = offset / NML_AREA_ALIGN; - - debug_printf2("normal area offset = %#x\n", offset); - - return CheckResult(); -} - - -//--------------------------------------------------------------------------- -// Output - 'TWLOFS' Command -//--------------------------------------------------------------------------- - -static BOOL TWLOFS_Command(char * line, int num) -{ - u32 offset = 0; - - if (num != 1) - { - error("Wrong format spec file '%s' line:%d", specFileName, LineNum); - return FALSE; - } - - offset = strtoul(line, NULL, 0); - - gcdHeader.l.twl_area_offset = offset / TWL_AREA_ALIGN; - - debug_printf2("twl area offset = %#x\n", offset); - - return CheckResult(); -} - - -//--------------------------------------------------------------------------- -// Output - 'ARM9_X2' Command -//--------------------------------------------------------------------------- - -static BOOL ARM9X2_Command(char * line, int num) -{ - char* dbg_str = "FALSE"; - - if (num != 1) - { - error("Wrong format spec file '%s' line:%d", specFileName, LineNum); - return FALSE; - } - - if (!strcmp(line, "TRUE")) - { - gcdHeader.l.arm9_x2 = TRUE; - dbg_str = "TRUE"; - } - - debug_printf2("arm9 x2 = %s\n", dbg_str); - - return CheckResult(); -} - - -//--------------------------------------------------------------------------- -// Output - 'GAMECODE' Command -//--------------------------------------------------------------------------- - -static BOOL GAMECODE_Command(char * line, int num) -{ - u32 key; - - if (num != 1) - { - error("Wrong format spec file '%s' line:%d", specFileName, LineNum); - return FALSE; - } - - key = strtoul(line, NULL, 0); - - debug_printf2("keyinfo = %#x\n", key); - - return CheckResult(); -} - - -//--------------------------------------------------------------------------- -// Output - 'Elf9' Command -//--------------------------------------------------------------------------- - -static BOOL Elf9_Command(char * line, int num) -{ - if (num != 1) - { - error("Wrong format spec file '%s' line:%d", specFileName, LineNum); - return FALSE; - } - - debug_printf2("arm9 elf = %s\n", line); - - { - s32 ramAddr = GetRamAddr(line); - gcdHeader.l.main_ram_address = (void*)ramAddr; - } - - return CheckResult(); -} - - -//--------------------------------------------------------------------------- -// Output - 'Elf7' Command -//--------------------------------------------------------------------------- - -static BOOL Elf7_Command(char * line, int num) -{ - if (num != 1) - { - error("Wrong format spec file '%s' line:%d", specFileName, LineNum); - return FALSE; - } - - debug_printf2("arm7 elf = %s\n", line); - - { - s32 ramAddr = GetRamAddr(line); - gcdHeader.l.sub_ram_address = (void*)ramAddr; - } - - return CheckResult(); -} - - -static s32 GetRamAddr(const char *fileName) -{ - Elf32_Ehdr *ehdr; - s32 ramAddr; - int file_size; - struct stat st; - - if (FILESTATUS_FILE != GetFileStatus(&st, fileName)) - { - error("'%s' is not regular file.", fileName); - return FALSE; - } - - if ((file_size = ReadFile(fileName, &ehdr, sizeof(Elf32_Ehdr))) < 0) - return FALSE; - - ramAddr = ehdr->e_entry; - - Free(&ehdr); - - debug_printf2("ramaddr = 0x%08x\n", ramAddr); - - return ramAddr; -} - - -//--------------------------------------------------------------------------- -// Output - 'NANDFIRM' Command -//--------------------------------------------------------------------------- - -static BOOL NandFirm_Command(char * line, int num) -{ - if (num != 1) - { - error("Wrong format spec file '%s' line:%d", specFileName, LineNum); - return FALSE; - } - - debug_printf2("nandfirm = %s\n", line); - - if ( ! line ) - { - return TRUE; - } - - // Set NANDFIRM ROM Offset - if (!Offset) - { - Offset = sizeof(GCDHeader); - SeekFile(Offset); - } - debug_printf2("romoffset = %#x\n", Offset); - { - gcdHeader.l.nandfirm_offset = Offset; - gcdHeader.l.nandfirm_size = ReadFirmFile(line); - } - - return CheckResult(); -} - - -//--------------------------------------------------------------------------- -// Output - 'NORFIRM' Command -//--------------------------------------------------------------------------- - -static BOOL NorFirm_Command(char * line, int num) -{ - if (num != 1) - { - error("Wrong format spec file '%s' line:%d", specFileName, LineNum); - return FALSE; - } - - debug_printf2("norfirm = %s\n", line); - - if ( ! line ) - { - return TRUE; - } - - // Set NORFIRM ROM Offset - if (!Offset) - { - Offset = sizeof(GCDHeader); - SeekFile(Offset); - } - debug_printf2("romoffset = %#x\n", Offset); - { - gcdHeader.l.norfirm_offset = Offset; - gcdHeader.l.norfirm_size = ReadFirmFile(line); - } - - return CheckResult(); -} - - -static size_t ReadFirmFile(const char *fileName) -{ - char *file; - int file_size; - struct stat st; - - if (FILESTATUS_FILE != GetFileStatus(&st, fileName)) - { - error("'%s' is not regular file.", fileName); - return FALSE; - } - - if ((file_size = ReadFileWithPadding(fileName, &file, READ_ALL, FIRM_ALIGN)) < 0) - return FALSE; - - Offset += file_size; - - // Output file image with fitting region - PutBuffer(file, file_size); - - Free(&file); - - return file_size; -} - - -//--------------------------------------------------------------------------- -// Output - 'Sbin9' Command -//--------------------------------------------------------------------------- - -static BOOL Sbin9_Command(char * line, int num) -{ - FIRMSignedContext* sc = &signedContext; - - if (num != 1) - { - error("Wrong format spec file '%s' line:%d", specFileName, LineNum); - return FALSE; - } - - debug_printf2("arm9 sbin = %s\n", line); - - // Set ARM9 ROM Offset - if (!Offset) - - { - Offset = sizeof(GCDHeader); - SeekFile(Offset); - } - debug_printf2("romoffset = %#x\n", Offset); - { - gcdHeader.l.main_rom_offset = Offset; - } - - return ReadSbinFile(line, &gcdHeader.l.main_rom_offset, &sc->hash[FIRM_SIGNED_HASH_IDX_ARM9], compArm9); -} - -//--------------------------------------------------------------------------- -// Output - 'Sbin7' Command -//--------------------------------------------------------------------------- - -static BOOL Sbin7_Command(char * line, int num) -{ - FIRMSignedContext* sc = &signedContext; - - if (num != 1) - { - error("Wrong format spec file '%s' line:%d", specFileName, LineNum); - return FALSE; - } - - debug_printf2("arm7 sbin = %s\n", line); - - // Set ARM7 ROM Offset - if (!Offset) - { - Offset = sizeof(GCDHeader); - SeekFile(Offset); - } - debug_printf2("romoffset = %#x\n", Offset); - { - gcdHeader.l.sub_rom_offset = Offset; - } - - return ReadSbinFile(line, &gcdHeader.l.sub_rom_offset, &sc->hash[FIRM_SIGNED_HASH_IDX_ARM7], compArm7); -} - - -static BOOL ReadSbinFile(const char *fileName, void* minfo, void* hash, BOOL comp) -{ - const GCDHeader_ModuleInfo *m = minfo; - u32 *size = (void*)&m->size; - u32 *orig_size = (void*)&m->decomp_size; - char *buffer; - char *file; - int file_size; - struct stat st; - - if (FILESTATUS_FILE != GetFileStatus(&st, fileName)) - { - error("'%s' is not regular file.", fileName); - return FALSE; - } - - if ((file_size = ReadFile(fileName, &file, READ_ALL)) < 0) - return FALSE; - - *orig_size = file_size; - - // Digest file image - if (hash) - { - ACSign_DigestUnit(hash, file, file_size); - } - - // Compress file image with fitting region - buffer = Alloc(file_size * 2); - if ( comp ) - { - file_size = LZCompWrite(file, file_size, buffer, FIRM_ALIGN); - } - else - { - memcpy(&buffer[0], file, file_size); - { - u32 pad_size = (DEFAULT_ALIGN - (file_size % FIRM_ALIGN)) % FIRM_ALIGN; - if (pad_size) - memset(&buffer[file_size], 0, pad_size); - file_size += pad_size; - } - } - Free(&file); - file = buffer; - - if (size) - { - *size = file_size; - } - Offset += file_size; - - // Encrypt file image - EncryptBuffer(file, file_size); - - // Output file image with fitting region - PutBuffer(file, file_size); - - Free(&file); - - return CheckResult(); -} - -typedef struct -{ - unsigned long e[4]; -} u128; - -static BOOL EncryptBuffer(char *buffer, int length) -{ - const u128 id = {{ AES_IDS_ID2_A, AES_IDS_ID2_B, AES_IDS_ID2_C, AES_IDS_ID2_D }}; - u128 iv = {{ length, -length, ~length, 0 }}; - FIRMSignedContext* sc = &signedContext; - char *buffer2 = Alloc(length); - AES_KEY key; - if (!buffer2) - return FALSE; - AES_SetKey(&key, sc->aes_key, (unsigned char*)&id); - AES_Ctr(&key, buffer2, buffer, length, (unsigned char*)&iv); - memcpy(buffer, buffer2, length); - memset(buffer2, 0, length); - Free(buffer2); - return TRUE; -} - - -//--------------------------------------------------------------------------- -// Output - 'ERROR' Command -//--------------------------------------------------------------------------- -static char* error_type[] = -{ - "SIGN", - "HEADER_HASH", - "ARM9_HASH", - "ARM7_HASH", - "HASH_TABLE_HASH", - "FINAL_HASH", - "HEADER_FOOTER", -}; - -static BOOL ERROR_Command(char * line, int num) -{ - char* dbg_str = "UNKNOWN"; - int i; - - if (num != 1) - { - error("Wrong format spec file '%s' line:%d", specFileName, LineNum); - return FALSE; - } - - for (i=0; ihash[FIRM_SIGNED_HASH_IDX_HEADER][0] ^= 1; - } - if ( errFlags.e.arm9_hash ) - { - sc->hash[FIRM_SIGNED_HASH_IDX_ARM9][0] ^= 1; - } - if ( errFlags.e.arm7_hash ) - { - sc->hash[FIRM_SIGNED_HASH_IDX_ARM7][0] ^= 1; - } - if ( errFlags.e.hash_table_hash ) - { - sc->hash[FIRM_SIGNED_HASH_IDX_HASH_TABLE][0] ^= 1; - } -} - -static void SetFinalHashError(FIRMSignedContext* sc) -{ - if ( errFlags.e.final_hash ) - { - sc->hash[FIRM_SIGNED_HASH_IDX_FINAL][0] ^= 1; - } -} - -static void SetSignError(GCDHeader* nh) -{ - if ( errFlags.e.sign ) - { - nh->sign.raw[0] ^= 1; - } - -} - -static void SetFooterError(GCDHeader* nh) -{ - if ( errFlags.e.header_footer ) - { - nh->h.reserved_footer[sizeof(nh->h.reserved_footer)-1] ^= 1; - } - -} - -//--------------------------------------------------------------------------- -// Output - Initialize AES Key -//--------------------------------------------------------------------------- -static BOOL InitializeAesKey(void) -{ - FIRMSignedContext* sc = &signedContext; - struct stat specstat; - time_t spectime; - if (stat(specFileName, &specstat) != 0) - return FALSE; - time(&spectime); - memcpy(&sc->aes_key[0], &specstat.st_atime, 4); - memcpy(&sc->aes_key[4], &specstat.st_mtime, 4); - memcpy(&sc->aes_key[8], &specstat.st_ctime, 4); - memcpy(&sc->aes_key[12], &spectime, 4); - ACSign_GetKey(sc->aes_key, sizeof(sc->aes_key), sc->aes_key, sizeof(sc->aes_key)); - return TRUE; -} - - -//--------------------------------------------------------------------------- -// Output - Initialize Gcdfirm File -//--------------------------------------------------------------------------- - -static BOOL InitializeGcdfirmFile(const char *rhFile) -{ - if ( !rhFile ) - { - rhFile = GetSrcPath(GetAppBaseName(), DEFAULT_ROMHEADER_TEMPLATE); - } - - ReadRomHeaderFile( rhFile ); - - memset(&signedContext.hash[FIRM_SIGNED_HASH_IDX_HASH_TABLE], 0x00, sizeof(signedContext.hash[0])); - gcdHeader.h.w = wram_regs_init; - InitializeAesKey(); - return TRUE; -} - -//--------------------------------------------------------------------------- -// Output - Finalize Gcdfirm File -//--------------------------------------------------------------------------- - -static BOOL FinalizeGcdfirmFile(const char *gcdFile) -{ - GCDHeader* nh = &gcdHeader; - FIRMSignedContext* sc = &signedContext; - u8* key = keyFileBuf; - int size; - - // set rom size - size = ROM_SIZE_MIN; - nh->l.rom_size = 0; - while (size < Offset) - { - size <<= 1; - nh->l.rom_size++; - } - - ACSign_DigestHeader(&sc->hash[FIRM_SIGNED_HASH_IDX_HEADER], nh); - - SetUnitHashErrors(sc); - - ACSign_DigestUnit(&sc->hash[FIRM_SIGNED_HASH_IDX_FINAL], sc, FIRM_HEADER_2ND_HASH_AREA_LEN); - - SetFinalHashError(sc); - - if (key) - { - ACSign_Final(nh, sc, key); - } - - SetFooterError(nh); - - SetSignError(nh); - - // Output file image - SeekFile(0L); - PutBuffer(&gcdHeader, sizeof(gcdHeader)); - - // Output public key (modulus) - if (PubkeyFileName) - { - WriteFile(PubkeyFileName, &keyFileBuf[ACS_RSA_PRVMOD_OFFSET], ACS_RSA_PRVMOD_LEN); - } - - return TRUE; -} diff --git a/build/tools/makegcdfirm/path.c b/build/tools/makegcdfirm/path.c deleted file mode 100644 index eeeb9895..00000000 --- a/build/tools/makegcdfirm/path.c +++ /dev/null @@ -1,931 +0,0 @@ -/*---------------------------------------------------------------------------* - Project: NitroSDK - tools - makebanner - File: path.c - - Copyright 2003-2006 Nintendo. All rights reserved. - - These coded instructions, statements, and computer programs contain - proprietary information of Nintendo of America Inc. and/or Nintendo - Company Ltd., and are protected by Federal copyright law. They may - not be disclosed to third parties or copied or duplicated in any form, - in whole or in part, without the prior written consent of Nintendo. - - $Log: path.c,v $ - Revision 1.3 2006/01/18 02:11:20 kitase_hirotake - do-indent - - Revision 1.2 2005/02/28 05:26:13 yosizaki - do-indent. - - Revision 1.1 2004/08/30 08:41:14 yasu - makebanner moves into CVS tree - - $NoKeywords: $ - *---------------------------------------------------------------------------*/ -#include -#include // free() -#include // strcasecmp() -#include // stat() -#include // opendir()/readdir()/closedir() -#include // getcwd() -#ifdef __CYGWIN__ -#include // cygwin_conv_to_win32_path() -#endif -#include "path.h" - -//--------------------------------------------------------------------------- -// Get File Statue -//--------------------------------------------------------------------------- - -tFileStatus GetFileStatus(struct stat *s, const char *filename) -{ - // Get file status - if (stat(filename, s)) - { - error("Can't get status %s", filename); - return FILESTATUS_ERROR; - } - - if (S_ISREG(s->st_mode)) - { - return FILESTATUS_FILE; - } - else if (S_ISDIR(s->st_mode)) - { - return FILESTATUS_DIR; - } - - error("Unknown file type %s", filename); - return FILESTATUS_ERROR; -} - - -//--------------------------------------------------------------------------- -// File Globbing & Dir Listing -//--------------------------------------------------------------------------- - -typedef struct -{ - tCallBack callBack; - void *param; - tWildCard *accept; - tWildCard *reject; - -} -tForeachEntryParam; - - -static BOOL isAcceptEntryName(char *pathName, tWildCard * accept, tWildCard * reject) -{ - char *p = pathName; - - while (*p) - { - if (*p == '/') - pathName = p + 1; - p++; - } - - if (accept) - { - while (accept) - { - if (WildCardCmp(accept->name, pathName)) - { - goto accepted; - } - accept = accept->next; - } - return FALSE; - } - accepted: - - while (reject) - { - if (WildCardCmp(reject->name, pathName)) - { - return FALSE; - } - reject = reject->next; - } - return TRUE; -} - - -static BOOL ForeachEntry_CallBack(char *pathName, void *param) -{ - tForeachEntryParam *t = (tForeachEntryParam *) param; - struct stat fstat; - - if (!isAcceptEntryName(pathName, t->accept, t->reject)) - { - // Reject!!! ignored - return TRUE; - } - - switch (GetFileStatus(&fstat, pathName)) - { - case FILESTATUS_FILE: - return t->callBack(pathName, t->param); - - case FILESTATUS_DIR: - return ForeachDirList(pathName, ForeachEntry_CallBack, param); - - default: - break; - } - return FALSE; -} - - -BOOL ForeachEntry(const char *pathName, tWildCard * reject, tCallBack callBack, void *param) -{ - tForeachEntryParam t; - - t.callBack = callBack; - t.param = param; - t.accept = NULL; - t.reject = reject; - - return ForeachPathGlobbing(pathName, ForeachEntry_CallBack, &t); -} - - -typedef struct -{ - tCallBack callBack; - void *param; - char *baseName; - -} -tForeachFileParam; - - -static BOOL ForeachFile_CallBack(char *pathName, void *param) -{ - tForeachFileParam *t = (tForeachFileParam *) param; - - int len = strlen(t->baseName); - - debug_printf(" ForeachFile_CallBack path[%s] base[%s]\n", pathName, t->baseName); - - if (strncmp(pathName, t->baseName, len)) - { - error("Wildcard in Root is not supported"); - return FALSE; - } - - return t->callBack(pathName + len, t->param); -} - - -BOOL ForeachFile(const char *baseName, const char *fileName, tWildCard * reject, tCallBack callBack, - void *param) -{ - char *cBaseName; - char *cPathName; - BOOL state; - tForeachFileParam t; - - debug_printf("ForeachFile : baseName[%s] fileName[%s]\n", baseName, fileName); - - cBaseName = GetSrcPath(baseName, ""); - cPathName = GetSrcPath(baseName, fileName); - - debug_printf("ForeachFile : cBaseName[%s] cPathName[%s]\n", cBaseName, cPathName); - - t.callBack = callBack; - t.param = param; - t.baseName = cBaseName; - - state = ForeachEntry(cPathName, reject, ForeachFile_CallBack, &t); - - free(cBaseName); - free(cPathName); - - return state; -} - - -//--------------------------------------------------------------------------- -// FilePath Globbing -//--------------------------------------------------------------------------- - -typedef struct -{ - char *baseName; - char *pathName; - tCallBack callBack; - void *param; - -} -tGlobParam; - - -static int CountFile; -static BOOL ForeachPathGlobbing_Entry(tGlobParam * pg); -static BOOL ForeachPathGlobbing_WildCard(char *pathName, void *param); - -BOOL ForeachPathGlobbing(const char *pathName, tCallBack callBack, void *param) -{ - tGlobParam g; - BOOL ret; - - g.baseName = NULL; - g.pathName = PathNormalize(pathName, TRUE); - g.callBack = callBack; - g.param = param; - CountFile = 0; - - debug_printf("PathGlobbing : Name [%s]->[%s]\n", pathName, g.pathName); - - ret = ForeachPathGlobbing_Entry(&g); - - free(g.pathName); - - if (ret && CountFile == 0) - { - error("No file or directory matched %s", pathName); - return FALSE; - } - return ret; -} - - -static BOOL ForeachPathGlobbing_Entry(tGlobParam * pg) -{ - tGlobParam g; - char *entryName; - struct stat s; - BOOL state; - - if (pg->pathName) - { - entryName = PathDup(pg->pathName); - - g = *pg; - g.pathName = PathGetDirLevelDown(pg->pathName); - - if (pg->baseName) - { - g.baseName = Alloc(strlen(pg->baseName) + strlen(entryName) + 2); - sprintf(g.baseName, "%s/%s", pg->baseName, entryName); - } - else - { - g.baseName = strdup(entryName); - } - - // Check if wildcard ? - if (isPathWildCard(entryName)) - { - state = ForeachDirList(pg->baseName, ForeachPathGlobbing_WildCard, &g); - } - else - { - state = ForeachPathGlobbing_Entry(&g); - } - - Free(&entryName); - Free(&g.baseName); - } - else - { - // Check if file exists - if (!stat(pg->baseName, &s)) - { - debug_printf(" File Found [%s]\n", pg->baseName); - - // Globbing done, exec callback - - state = pg->callBack(pg->baseName, pg->param); - CountFile++; - } - else - { - debug_printf(" File Not Found [%s]\n", pg->baseName); - state = TRUE; // Ignored - } - } - return state; -} - - -static BOOL ForeachPathGlobbing_WildCard(char *pathName, void *param) -{ - tGlobParam g; - tGlobParam *pg = (tGlobParam *) param; - - debug_printf(" WildCardCmp: [%s] [%s]\n", pg->baseName, pathName); - - if (WildCardCmp(pg->baseName, pathName)) - { - g = *pg; - g.baseName = pathName; - return ForeachPathGlobbing_Entry(&g); - } - - return TRUE; // Ignored -} - - -//--------------------------------------------------------------------------- -// Directory Listing -// Listing directory & Exec CallBack -//--------------------------------------------------------------------------- - -BOOL ForeachDirList(const char *dirName, tCallBack callBack, void *param) -{ - DIR *dir; - struct dirent *entry; - char *pathName; - BOOL state = TRUE; - - if (!dirName) - { - dirName = "."; - } - - debug_printf("DirectoryList: Name [%s]\n", dirName); - - // Open directory - if (NULL == (dir = opendir(dirName))) - { - error("Can't read directory %s", dirName); - return FALSE; - } - - // Store new files - while (NULL != (entry = readdir(dir))) - { - pathName = entry->d_name; - - if (!strcmp(pathName, ".") || !strcmp(pathName, "..")) - { - continue; - } - - debug_printf(" :%s\n", pathName); - pathName = GetSrcPath(dirName, pathName); - state = callBack(pathName, param); - free(pathName); - - if (!state) - break; - } - - closedir(dir); - return state; -} - - -//--------------------------------------------------------------------------- -// -// PathName Utilities -// -//--------------------------------------------------------------------------- - -//--------------------------------------------------------------------------- -// StrCmp/StrCpy entry name terminated / or \0 -//--------------------------------------------------------------------------- - -int PathCmp(const char *path, const char *cmp) -{ - char c; - - do - { - c = *path; - if (c == '/') - c = '\0'; // end of string if '/' - if (c != *cmp) - return 1; - path++; - cmp++; - } - while (c); - - return 0; -} - - -char *PathCpy(char *dest, const char *src) -{ - while (*src != '\0' && *src != '/') - { - *dest++ = *src++; - } - return dest; // Don't set '\0' -} - - -int PathLen(const char *path) -{ - int n = 0; - - while (*path != '\0' && *path != '/') - { - n++; - path++; - } - return n; -} - - -char *PathDup(const char *src) -{ - int n = PathLen(src); - char *dest = Alloc(n + 2); - - PathCpy(dest, src); - dest[n] = '\0'; - - return dest; -} - - -BOOL WildCardCmp(const char *wildcard, const char *path) -{ - if (*wildcard == '*') - { - if (*path != '\0' && WildCardCmp(wildcard, path + 1)) - return TRUE; - if (WildCardCmp(wildcard + 1, path)) - return TRUE; - } - - else if (*wildcard == '?') - { - return *path != '\0' && WildCardCmp(wildcard + 1, path + 1); - } - - else if (*wildcard == *path) - { - return *path == '\0' || WildCardCmp(wildcard + 1, path + 1); - } - - return FALSE; -} - - -BOOL isPathWildCard(const char *path) -{ - while (*path != '\0' && *path != '/') - { - if (*path == '*' || *path == '?') - { - return TRUE; - } - path++; - } - return FALSE; -} - - -//--------------------------------------------------------------------------- -// Go up/down directory level -//--------------------------------------------------------------------------- - -char *PathGetDirLevelDown(const char *path) -{ - while (*path) - { - if (*path == '/') - return (char *)path + 1; - path++; - } - return NULL; -} - - -//--------------------------------------------------------------------------- -// Get Basename -//--------------------------------------------------------------------------- - -char *GetBaseName(const char *path) -{ - int i; - char *new_path; - - for (i = strlen(path) - 1; i >= 0; i--) - { - if (path[i] == '/') - { - new_path = strdup(path); - new_path[i] = '\0'; - return new_path; - } - if (path[i] == ':') - { - new_path = Alloc(i + 3); - strncpy(new_path, path, i); - strcpy(new_path + i, ":."); - return new_path; - } - } - - new_path = strdup("."); - return new_path; -} - - -//--------------------------------------------------------------------------- -// Get Filename -//--------------------------------------------------------------------------- - -char *GetFileName(const char *path) -{ - int i; - char *new_file; - - for (i = strlen(path) - 1; i >= 0; i--) - { - if (path[i] == '/' || path[i] == ':') - { - new_file = strdup(path + i + 1); - return new_file; - } - } - new_file = strdup(path); - return new_file; -} - - -//--------------------------------------------------------------------------- -// Reconstruct path name -// -// - Resolve '.' or '..' in path name -// - Work around . and / to translate regular form -// -// Regular form of path: -// Absolute Path [Drive:]/.[/Entry...] -// Relative Path [Drive:].[/Entry]... -// -// ex) -// abc/def -> ./abc/def -// /aaa -> /./aaa -// D:/aaa -> D:/./aaa -// / -> /. -// . -> . -// ../aa -> ./../aa -//--------------------------------------------------------------------------- - -char *PathNormalize(const char *pathName, BOOL isTreatDotDot) -{ - int i, level, level_root, n; - BOOL isAbsolute; - const char *entry[DIRLEVEL_MAX]; - - char *pathNormal = Alloc(strlen(pathName) + 4); - const char *p_org; - char *p_new; - - // - // Check if drive letter C: D: E: - // Check if absolute path - // - p_new = pathNormal; - p_org = SkipDriveName(pathName); - n = (int)p_org - (int)pathName; - - if (n > 0) - { - strncpy(p_new, pathName, n); - p_new += n; - } - isAbsolute = isAbsolutePath(p_org); - - // - // Resolve '.' and '..' - // - // Slice the path at point of / , put them into entry[] - // - - level = level_root = 0; - - for (; p_org; p_org = PathGetDirLevelDown(p_org)) - { - if (!PathCmp(p_org, "") || !PathCmp(p_org, ".")) - { - // skip it - continue; - } - else if (!PathCmp(p_org, "..") && isTreatDotDot) - { - if (level > level_root) - { - // Back to parent dir - level--; - continue; - } - - // if pathname starts with '/', no directory to go up - if (isAbsolute) - { - error("Can't go up directory, '..' Ignored. %s", pathName); - continue; - } - - // keep '..' - level_root = level + 1; - } - - // name entry - entry[level] = p_org; - level++; - } - - // Reconstruct pathname - if (isAbsolute) - { - *p_new++ = '/'; - } - *p_new++ = '.'; - - for (i = 0; i < level; i++) - { - *p_new++ = '/'; - p_new = PathCpy(p_new, entry[i]); - } - *p_new = '\0'; - -#if 0 - if (strcmp(pathNormal, pathName)) - { - debug_printf(" PathNormal: [%s] -> [%s]\n", pathName, pathNormal); - } -#endif - return pathNormal; -} - - -//--------------------------------------------------------------------------- -// Get Src Path -// Normalize BASENAME -// Normalize FILENAME -// Concat both -//--------------------------------------------------------------------------- - -char *GetSrcPath(const char *baseName, const char *fileName) -{ - char *base; - char *file; - char *t; - char *path; - - base = PathNormalize(baseName, TRUE); - file = PathNormalize(fileName, TRUE); - t = Alloc(strlen(base) + strlen(file) + 2); - - // Concat base + '/' + file - sprintf(t, "%s/%s", base, file); - path = PathNormalize(t, FALSE); - - free(base); - free(file); - free(t); - - debug_printf(" GetSrcPath: [%s]\n", path); - return path; -} - - -//--------------------------------------------------------------------------- -// Get Dest Path -// Concat BASENAME + FILENAME -// Normalize it -//--------------------------------------------------------------------------- - -char *GetDestPath(const char *baseName, const char *fileName) -{ - char *t; - char *path; - - t = Alloc(strlen(baseName) + strlen(fileName) + 2); - - // Concat base + '/' + file - sprintf(t, "%s/%s", baseName, fileName); - path = PathNormalize(t, TRUE); - - free(t); - - debug_printf(" GetDestPath: [%s]\n", path); - return path; -} - - -//--------------------------------------------------------------------------- -// Remake the path into familier shape -// Delete ./ -//--------------------------------------------------------------------------- - -char *PathDenormalize(char *path) -{ - char *p; - - p = (char *)SkipDriveName(path); - if (*p == '/') - { - p++; - } - - // Cut './' - if (*p == '.' && *(p + 1) == '/') - { - while ('\0' != (*p = *(p + 2))) - { - p++; - } - - if (p == path) - { - - } - } - - - - return path; -} - - -//--------------------------------------------------------------------------- -// Get PC Path -//--------------------------------------------------------------------------- - -char *GetWin32Path(char *cygpath) -{ - static char buffer[FILENAME_MAX]; - -#ifdef __CYGWIN__ - if (*cygpath == '/') - { - cygwin_conv_to_win32_path(cygpath, buffer); - } - else -#endif - { - strcpy(buffer, cygpath); - } - - return ChangeBackSlash(buffer); -} - -char *ChangeWin32Path(char *cygpath) -{ - char *win32path = strdup(GetWin32Path(cygpath)); - - free(cygpath); - return win32path; -} - -//--------------------------------------------------------------------------- -// Change suffix -//--------------------------------------------------------------------------- -char *ChangeSuffix(const char *file, const char *suffix) -{ - int i, n; - char *path; - - n = strlen(file); - - for (i = n; file[i] != '.'; i--) - { - if (file[i] == '/' || i == 0) - { - i = n; - break; - } - } - - path = Alloc(i + strlen(suffix) + 1); - strncpy(path, file, i); - strcpy(path + i, suffix); - - return path; -} - - -//--------------------------------------------------------------------------- -// Get Current Dir -//--------------------------------------------------------------------------- - -char *GetCurrentDirectory(void) -{ - static char buffer[FILENAME_MAX]; - char *cwd; - - cwd = getcwd(buffer, FILENAME_MAX); - if (!cwd) - { - error("Can't access current directory"); - exit(10); - } - return cwd; -} - - -//--------------------------------------------------------------------------- -// Check if absolute path -// -// Return True in case of ... -// -// /dirA/dirB/fileC -// D:/dirA/dirB/fileC -// -// Return False in case of ... -// -// dirX/dirY/fileZ -// D:dirX/dirY/fileZ -//--------------------------------------------------------------------------- - -BOOL isAbsolutePath(const char *path) -{ - const char *p = path; - - while (*p != '\0') - { - if (*p == '/' || *p == '\\') - { - if (p == path || p[-1] == ':') - { - return TRUE; - } - } - p++; - } - return FALSE; -} - -//--------------------------------------------------------------------------- -// Check if drive name -// -// Return next character of ':' if drive name -// Return head of path if no drive name -//--------------------------------------------------------------------------- - -const char *SkipDriveName(const char *path) -{ - const char *p = path; - - while (*p != '\0' && *p != '/' && *p != '\\') - { - if (*p == ':') - { - return p + 1; - } - p++; - } - return path; -} - - -//--------------------------------------------------------------------------- -// App Name Utilities -//--------------------------------------------------------------------------- -static char *appName; -static char *appBaseName; -static char *appFileName; - -void InitAppName(const char *path) -{ - char *slash_path = ChangeBackSlash(strdup(path)); - - appBaseName = GetBaseName(slash_path); - appFileName = GetFileName(slash_path); - appName = ChangeSuffix(appFileName, ""); - - free(slash_path); -} - -char *GetAppName(void) -{ - return appName; -} - -char *GetAppBaseName(void) -{ - return appBaseName; -} - -char *GetAppFileName(void) -{ - return appFileName; -} - - -#ifdef TEST -int main(int argc, char *argv[]) -{ - int i; - char *s; - - for (i = 1; i < argc; i++) - { - s = PathNormalize(argv[i], TRUE); - printf("[%s] -> [%s]\n", argv[i], s); - free(s); - } - return 0; -} -#endif diff --git a/build/tools/makegcdfirm/path.h b/build/tools/makegcdfirm/path.h deleted file mode 100644 index e9956dc6..00000000 --- a/build/tools/makegcdfirm/path.h +++ /dev/null @@ -1,93 +0,0 @@ -/*---------------------------------------------------------------------------* - Project: NitroSDK - tools - makebanner - File: path.h - - Copyright 2003-2006 Nintendo. All rights reserved. - - These coded instructions, statements, and computer programs contain - proprietary information of Nintendo of America Inc. and/or Nintendo - Company Ltd., and are protected by Federal copyright law. They may - not be disclosed to third parties or copied or duplicated in any form, - in whole or in part, without the prior written consent of Nintendo. - - $Log: path.h,v $ - Revision 1.3 2006/01/18 02:11:20 kitase_hirotake - do-indent - - Revision 1.2 2005/02/28 05:26:13 yosizaki - do-indent. - - Revision 1.1 2004/08/30 08:41:14 yasu - makebanner moves into CVS tree - - $NoKeywords: $ - *---------------------------------------------------------------------------*/ -#ifndef PATH_H_ -#define PATH_H_ - -#include // struct tat -#include "misc.h" - -#define DIRLEVEL_MAX 256 -#ifndef FILENAME_MAX -#define FILENAME_MAX 1024 -#endif - -typedef enum -{ - FILESTATUS_ERROR = -1, - FILESTATUS_FILE = 0, - FILESTATUS_DIR = 1 -} -tFileStatus; - - -// Item Reject Control - -typedef struct tWildCard -{ - struct tWildCard *next; - char *name; - -} -tWildCard; - - -// CallBacks - -typedef BOOL (*tCallBack) (char *, void *); - - -// Prototypes - -tFileStatus GetFileStatus(struct stat *s, const char *filename); -BOOL ForeachEntry(const char *pathName, tWildCard * reject, tCallBack callBack, void *param); -BOOL ForeachFile(const char *baseName, const char *fileName, tWildCard * reject, - tCallBack callBack, void *param); -BOOL ForeachPathGlobbing(const char *pathName, tCallBack callBack, void *param); -BOOL ForeachDirList(const char *dirName, tCallBack callBack, void *param); -int PathCmp(const char *path, const char *cmp); -char *PathCpy(char *dest, const char *src); -int PathLen(const char *path); -char *PathDup(const char *src); -char *PathGetDirLevelDown(const char *path); -char *GetBaseName(const char *path); -char *GetFileName(const char *path); -BOOL WildCardCmp(const char *wildcard, const char *path); -BOOL isPathWildCard(const char *path); -char *PathNormalize(const char *pathName, BOOL isTreatDotDot); -char *PathDenormalize(char *path); -char *GetSrcPath(const char *base, const char *file); -char *GetDestPath(const char *base, const char *file); -char *GetWin32Path(char *cygpath); -char *ChangeWin32Path(char *cygpath); -char *ChangeSuffix(const char *file, const char *suffix); -char *GetCurrentDirectory(void); -BOOL isAbsolutePath(const char *path); -const char *SkipDriveName(const char *path); -void InitAppName(const char *path); -char *GetAppName(void); -char *GetAppBaseName(void); -char *GetAppFileName(void); - -#endif //PATH_H_ diff --git a/build/tools/makegcdfirm/test/Makefile b/build/tools/makegcdfirm/test/Makefile deleted file mode 100644 index 2c2b4741..00000000 --- a/build/tools/makegcdfirm/test/Makefile +++ /dev/null @@ -1,56 +0,0 @@ -#! make -f -#--------------------------------------------------------------------------- -# Project: TwlFirm - tools - makenorfirm -# File: Makefile -# -# Copyright 2007 Nintendo. All rights reserved. -# -# These coded instructions, statements, and computer programs contain -# proprietary information of Nintendo of America Inc. and/or Nintendo -# Company Ltd., and are protected by Federal copyright law. They may -# not be disclosed to third parties or copied or duplicated in any form, -# in whole or in part, without the prior written consent of Nintendo. -# -# $Date:: $ -# $Rev:$ -# $Author:$ -#--------------------------------------------------------------------------- - -SUBDIRS = wram_rbin \ - -include $(TWL_IPL_RED_ROOT)/build/buildtools/commondefs - -MAKEGCDFIRM = ../makegcdfirm.exe - -MAKEFIRM_ARM9 = ./twl_gcdfirm9_print.axf -MAKEFIRM_ARM7 = ./twl_gcdfirm7_print.axf -SDEPENDS_BIN += $(MAKEFIRM_ARM9) $(MAKEFIRM_ARM7) -MAKEFIRM_FLAGS += -d -MAKEFIRM_DEFS += -DFIRM_ROOT='$(FIRM_ROOT)' \ - -DMAKEFIRM_ARM9='$(basename $(MAKEFIRM_ARM9))' \ - -DMAKEFIRM_ARM7='$(basename $(MAKEFIRM_ARM7))' \ - -DMAKEFIRM_RSA_PRVKEY='$(MAKEFIRM_RSA_PRVKEY)' \ - -TARGET = test.srl - -%.srl: %.gcdsf $(MAKEGCDFIRM) - $(MAKEGCDFIRM) $(MAKEFIRM_FLAGS) $(MAKEFIRM_DEFS) $< $@ - -.PHONY: build install do-autotest clean clobber - -define ECHO_CURDIR - echo "==== $(CURDIR)"; -endef - -build: - @$(ECHO_CURDIR) - @$(MAKE) $(TARGET) - -install do-autotest: - @$(ECHO_CURDIR) - -clean clobber super-clobber: - @$(ECHO_CURDIR) - -rm -f $(TARGET) *~ - -test-utf16.bsf: icon.nbfc icon.nbfp diff --git a/build/tools/makegcdfirm/test/nandfirm_print.nand b/build/tools/makegcdfirm/test/nandfirm_print.nand deleted file mode 100644 index 999ce185fdcfb579f464763668963b8df624cbfe..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 50688 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 diff --git a/build/tools/makegcdfirm/test/norfirm_print.nor b/build/tools/makegcdfirm/test/norfirm_print.nor deleted file mode 100644 index 2a6baecd577a7a206c2142f3d4d150b051f973ca..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 30896 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
!FLVkp-gh|pyn{u^Nvd$Xre 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 OP^yOlYL>lFFw77|zB@Sp diff --git a/build/tools/makegcdfirm/test/rsa_private.der b/build/tools/makegcdfirm/test/rsa_private.der deleted file mode 100644 index 06f5f4ccbac2e2f50ebc312c9d601a422754c370..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 607 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
U4<#z|> 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 V0e$D4tJkd|WOOI~ka7)h{{^{CZ=wJI diff --git a/build/tools/makegcdfirm/test/twl_gcdfirm9_print.axf b/build/tools/makegcdfirm/test/twl_gcdfirm9_print.axf deleted file mode 100644 index 3d064b38a5509e8ea9e4ce4cc5302e3f0684d513..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 288636 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 diff --git a/build/tools/makegcdfirm/test/wram_rbin/Makefile b/build/tools/makegcdfirm/test/wram_rbin/Makefile deleted file mode 100644 index 926c9b05..00000000 --- a/build/tools/makegcdfirm/test/wram_rbin/Makefile +++ /dev/null @@ -1,48 +0,0 @@ -#! make -f -#---------------------------------------------------------------------------- -# Project: TwlFirm - tools - gcdfirm-print -# File: Makefile -# -# Copyright 2007 Nintendo. All rights reserved. -# -# These coded instructions, statements, and computer programs contain -# proprietary information of Nintendo of America Inc. and/or Nintendo -# Company Ltd., and are protected by Federal copyright law. They may -# not be disclosed to third parties or copied or duplicated in any form, -# in whole or in part, without the prior written consent of Nintendo. -# -# $Date:: $ -# $Rev:$ -# $Author:$ -#---------------------------------------------------------------------------- - -SUBDIRS = - -LINCLUDES = ../include - -#---------------------------------------------------------------------------- - -TARGET_BIN = wram_regs.rbin - -SRCS = \ - wram_regs.c \ - -#SRCDIR = # using default -#LCFILE = # using default - - -include $(TWL_IPL_RED_ROOT)/build/buildtools/commondefs - -INSTALL_DIR = . -INSTALL_TARGETS = $(BINDIR)/$(TARGET_BIN) - - -#---------------------------------------------------------------------------- - -do-build: $(TARGETS) - - -include $(TWL_IPL_RED_ROOT)/build/buildtools/modulerules - - -#===== End of Makefile ===== diff --git a/build/tools/makegcdfirm/test/wram_rbin/wram_regs.c b/build/tools/makegcdfirm/test/wram_rbin/wram_regs.c deleted file mode 100644 index ee7d112c..00000000 --- a/build/tools/makegcdfirm/test/wram_rbin/wram_regs.c +++ /dev/null @@ -1,89 +0,0 @@ -/*---------------------------------------------------------------------------* - Project: TwlFirm - tools - makegcdfirm - File: wram_regs.c - - Copyright 2007 Nintendo. All rights reserved. - - These coded instructions, statements, and computer programs contain - proprietary information of Nintendo of America Inc. and/or Nintendo - Company Ltd., and are protected by Federal copyright law. They may - not be disclosed to third parties or copied or duplicated in any form, - in whole or in part, without the prior written consent of Nintendo. - - $Date:: 2007-09-06$ - $Rev$ - $Author$ - *---------------------------------------------------------------------------*/ -#include -#include - -MIHeader_WramRegs wram_regs = -{ - // ARM9 - { - REG_WRAM_A_BNK_PACK(0, MI_WRAM_A_ARM7, MI_WRAM_A_OFS_0KB, TRUE), - REG_WRAM_A_BNK_PACK(1, MI_WRAM_A_ARM7, MI_WRAM_A_OFS_64KB, TRUE), - REG_WRAM_A_BNK_PACK(2, MI_WRAM_A_ARM7, MI_WRAM_A_OFS_128KB, TRUE), - REG_WRAM_A_BNK_PACK(3, MI_WRAM_A_ARM7, MI_WRAM_A_OFS_192KB, TRUE), - }, - { - REG_WRAM_B_BNK_PACK(0, MI_WRAM_B_ARM7, MI_WRAM_B_OFS_0KB, TRUE), - REG_WRAM_B_BNK_PACK(1, MI_WRAM_B_ARM7, MI_WRAM_B_OFS_32KB, TRUE), - REG_WRAM_B_BNK_PACK(2, MI_WRAM_B_ARM7, MI_WRAM_B_OFS_64KB, TRUE), - REG_WRAM_B_BNK_PACK(3, MI_WRAM_B_ARM7, MI_WRAM_B_OFS_96KB, TRUE), - REG_WRAM_B_BNK_PACK(4, MI_WRAM_B_ARM7, MI_WRAM_B_OFS_128KB, TRUE), - REG_WRAM_B_BNK_PACK(5, MI_WRAM_B_ARM7, MI_WRAM_B_OFS_160KB, TRUE), - REG_WRAM_B_BNK_PACK(6, MI_WRAM_B_ARM7, MI_WRAM_B_OFS_192KB, TRUE), - REG_WRAM_B_BNK_PACK(7, MI_WRAM_B_ARM7, MI_WRAM_B_OFS_224KB, TRUE), - }, - { - REG_WRAM_C_BNK_PACK(0, MI_WRAM_C_ARM9, MI_WRAM_C_OFS_0KB, TRUE), - REG_WRAM_C_BNK_PACK(1, MI_WRAM_C_ARM9, MI_WRAM_C_OFS_32KB, TRUE), - REG_WRAM_C_BNK_PACK(2, MI_WRAM_C_ARM9, MI_WRAM_C_OFS_64KB, TRUE), - REG_WRAM_C_BNK_PACK(3, MI_WRAM_C_ARM9, MI_WRAM_C_OFS_96KB, TRUE), - REG_WRAM_C_BNK_PACK(4, MI_WRAM_C_ARM9, MI_WRAM_C_OFS_128KB, TRUE), - REG_WRAM_C_BNK_PACK(5, MI_WRAM_C_ARM9, MI_WRAM_C_OFS_160KB, TRUE), - REG_WRAM_C_BNK_PACK(6, MI_WRAM_C_ARM9, MI_WRAM_C_OFS_192KB, TRUE), - REG_WRAM_C_BNK_PACK(7, MI_WRAM_C_ARM9, MI_WRAM_C_OFS_224KB, TRUE), - }, - REG_WRAM_A_MAP_PACK(MI_WRAM_MAP_NULL, - MI_WRAM_MAP_NULL, - MI_WRAM_A_IMG_128KB - ), - REG_WRAM_B_MAP_PACK(MI_WRAM_MAP_NULL, - MI_WRAM_MAP_NULL, - MI_WRAM_B_IMG_128KB - ), - REG_WRAM_C_MAP_PACK(HW_WRAM_AREA_HALF, - HW_WRAM_AREA_HALF + 0x00020000, - MI_WRAM_C_IMG_128KB - ), - - // ARM7 - REG_WRAM_A_MAP_PACK(HW_WRAM_AREA_HALF, - HW_WRAM_AREA_HALF + 0x00020000, - MI_WRAM_A_IMG_128KB - ), - REG_WRAM_B_MAP_PACK(HW_WRAM_AREA_HALF + 0x00020000, - HW_WRAM_AREA_HALF + 0x00040000, - MI_WRAM_B_IMG_128KB - ), - REG_WRAM_C_MAP_PACK(MI_WRAM_MAP_NULL, - MI_WRAM_MAP_NULL, - MI_WRAM_C_IMG_128KB - ), - // WRAM Lock - { - 0, - 0, - 0, - }, - - // WRAM-0/1 - MI_WRAM_ARM7_ALL, - - // VRAM-C - 7, - // VRAM-D - 7, -}; diff --git a/build/tools/makegcdfirm/wram_regs.c b/build/tools/makegcdfirm/wram_regs.c deleted file mode 100644 index fba20ce8..00000000 --- a/build/tools/makegcdfirm/wram_regs.c +++ /dev/null @@ -1,96 +0,0 @@ -/*---------------------------------------------------------------------------* - Project: TwlFirm - tools - makegcdfirm - File: wram_regs.c - - Copyright 2007 Nintendo. All rights reserved. - - These coded instructions, statements, and computer programs contain - proprietary information of Nintendo of America Inc. and/or Nintendo - Company Ltd., and are protected by Federal copyright law. They may - not be disclosed to third parties or copied or duplicated in any form, - in whole or in part, without the prior written consent of Nintendo. - - $Date:: 2007-09-06$ - $Rev$ - $Author$ - *---------------------------------------------------------------------------*/ -#include "format_rom.h" -//#define SDK_ASM -#define NITRO_TYPES_H_ -#include -#include -#include - - -MIHeader_WramRegs wram_regs_init = -{ - // ARM9 - { - REG_MI_MBK_A0_FIELD( 1, MI_WRAM_A_OFFSET_0KB , MI_WRAM_ARM7 ), - REG_MI_MBK_A1_FIELD( 1, MI_WRAM_A_OFFSET_64KB , MI_WRAM_ARM7 ), - REG_MI_MBK_A2_FIELD( 1, MI_WRAM_A_OFFSET_128KB, MI_WRAM_ARM7 ), - REG_MI_MBK_A3_FIELD( 1, MI_WRAM_A_OFFSET_192KB, MI_WRAM_ARM7 ), - }, - { - REG_MI_MBK_B0_FIELD( 1, MI_WRAM_BC_OFFSET_0KB , MI_WRAM_ARM7 ), - REG_MI_MBK_B1_FIELD( 1, MI_WRAM_BC_OFFSET_32KB , MI_WRAM_ARM7 ), - REG_MI_MBK_B2_FIELD( 1, MI_WRAM_BC_OFFSET_64KB , MI_WRAM_ARM7 ), - REG_MI_MBK_B3_FIELD( 1, MI_WRAM_BC_OFFSET_96KB , MI_WRAM_ARM7 ), - REG_MI_MBK_B4_FIELD( 1, MI_WRAM_BC_OFFSET_128KB, MI_WRAM_ARM7 ), - REG_MI_MBK_B5_FIELD( 1, MI_WRAM_BC_OFFSET_160KB, MI_WRAM_ARM7 ), - REG_MI_MBK_B6_FIELD( 1, MI_WRAM_BC_OFFSET_192KB, MI_WRAM_ARM7 ), - REG_MI_MBK_B7_FIELD( 1, MI_WRAM_BC_OFFSET_224KB, MI_WRAM_ARM7 ), - }, - { - REG_MI_MBK_C0_FIELD( 1, MI_WRAM_BC_OFFSET_0KB , MI_WRAM_ARM9 ), - REG_MI_MBK_C1_FIELD( 1, MI_WRAM_BC_OFFSET_32KB , MI_WRAM_ARM9 ), - REG_MI_MBK_C2_FIELD( 1, MI_WRAM_BC_OFFSET_64KB , MI_WRAM_ARM9 ), - REG_MI_MBK_C3_FIELD( 1, MI_WRAM_BC_OFFSET_96KB , MI_WRAM_ARM9 ), - REG_MI_MBK_C4_FIELD( 1, MI_WRAM_BC_OFFSET_128KB, MI_WRAM_ARM9 ), - REG_MI_MBK_C5_FIELD( 1, MI_WRAM_BC_OFFSET_160KB, MI_WRAM_ARM9 ), - REG_MI_MBK_C6_FIELD( 1, MI_WRAM_BC_OFFSET_192KB, MI_WRAM_ARM9 ), - REG_MI_MBK_C7_FIELD( 1, MI_WRAM_BC_OFFSET_224KB, MI_WRAM_ARM9 ), - }, - REG_MI_MBK6_FIELD( REG_WRAM_MAP_CONV_ADDR( 6, A, EADDR, MI_WRAM_MAP_NULL ), - MI_WRAM_IMAGE_128KB, - REG_WRAM_MAP_CONV_ADDR( 6, A, SADDR, MI_WRAM_MAP_NULL ) - ), - REG_MI_MBK7_FIELD( REG_WRAM_MAP_CONV_ADDR( 7, B, EADDR, MI_WRAM_MAP_NULL ), - MI_WRAM_IMAGE_128KB, - REG_WRAM_MAP_CONV_ADDR( 7, B, SADDR, MI_WRAM_MAP_NULL ) - ), - REG_MI_MBK8_FIELD( REG_WRAM_MAP_CONV_ADDR( 8, C, EADDR, HW_WRAM_AREA_HALF + 0x00020000 ), - MI_WRAM_IMAGE_128KB, - REG_WRAM_MAP_CONV_ADDR( 8, C, SADDR, HW_WRAM_AREA_HALF ) - ), - - // ARM7 - REG_MI_MBK6_FIELD( REG_WRAM_MAP_CONV_ADDR( 6, A, EADDR, HW_WRAM_AREA_HALF + 0x00020000 ), - MI_WRAM_IMAGE_128KB, - REG_WRAM_MAP_CONV_ADDR( 6, A, SADDR, HW_WRAM_AREA_HALF ) - ), - REG_MI_MBK7_FIELD( REG_WRAM_MAP_CONV_ADDR( 7, B, EADDR, HW_WRAM_AREA_HALF + 0x00040000 ), - MI_WRAM_IMAGE_128KB, - REG_WRAM_MAP_CONV_ADDR( 7, B, SADDR, HW_WRAM_AREA_HALF + 0x00020000 ) - ), - REG_MI_MBK8_FIELD( REG_WRAM_MAP_CONV_ADDR( 8, C, EADDR, MI_WRAM_MAP_NULL ), - MI_WRAM_IMAGE_128KB, - REG_WRAM_MAP_CONV_ADDR( 8, C, SADDR, MI_WRAM_MAP_NULL ) - ), - - // WRAM Lock - { - 0, - 0, - 0, - }, - - // WRAM-0/1 - 3, - - // VRAM-C - 7, - // VRAM-D - 7, -}; - diff --git a/build/tools/makenandfirm/Makefile b/build/tools/makenandfirm/Makefile deleted file mode 100644 index 09832e39..00000000 --- a/build/tools/makenandfirm/Makefile +++ /dev/null @@ -1,151 +0,0 @@ -#! make -f -#--------------------------------------------------------------------------- -# Project: TwlFirm - tools - makenandfirm -# File: Makefile -# -# Copyright 2007 Nintendo. All rights reserved. -# -# These coded instructions, statements, and computer programs contain -# proprietary information of Nintendo of America Inc. and/or Nintendo -# Company Ltd., and are protected by Federal copyright law. They may -# not be disclosed to third parties or copied or duplicated in any form, -# in whole or in part, without the prior written consent of Nintendo. -# -# $Date:: $ -# $Rev:$ -# $Author:$ -#--------------------------------------------------------------------------- - -TARGET_PLATFORM = TWL - -SUPPORT_ECC = 0 - -ifeq ($(SUPPORT_ECC),1) -ECC_SRCDIR = ../../libraries/acsign_ecc/common \ - ../../libraries/acsign_ecc/common/algae/common/ecc \ - ../../libraries/acsign_ecc/common/algae/cmp \ - ../../libraries/acsign_ecc/common/algae/ecsource \ - -ECC_INCDIR = ../../libraries/acsign_ecc/include \ - ../../libraries/acsign_ecc/common/algae/include \ - ../../libraries/acsign_ecc/common/algae/common/include \ - -ECC_SRCS = acsign_ecc.c acsign_cryptoc.c \ - \ - cmparith.c cmpbits.c cmpcnv.c cmpdiv.c cmpmem.c \ - cmpmod.c cmpmuldv.c cmpspprt.c cmpsqr.c cmpvectr.c \ - computem.c ecfpatbl.c ecfpsmul.c \ - spcprime.c secfpcom.c \ - \ - p224v1.c p224v1a.c \ - -ECC_DEFS = -DRSA_PROTOTYPES=RSA_ENABLED \ - -DRCOM_BUILD=RSA_ENABLED -DRSA_FAST_INVERSE=RSA_ENABLED \ - -DRSA_STD_MEM_FUNCS=RSA_ENABLED -DRSA_STD_ALLOC_FUNCS=RSA_ENABLED \ -else -ECC_SRCDIR = -ECC_INCDIR = -ECC_SRCS = -ECC_DEFS = -endif - -SRCDIR += ../acsign $(ECC_SRCDIR) -INCDIR += ../acsign/include $(ECC_INCDIR) $(ECC_SRCDIR) - - -include $(TWL_IPL_RED_ROOT)/build/buildtools/commondefs - -TARGETS = makenandfirm.exe - -SOURCES_C = makenandfirm.c \ - out_nandfirm.c \ - misc.c \ - path.c \ - defval.c \ - compress.c \ - wram_regs.c \ - acsign.c \ - acsign_nand.c \ - aes2.c \ - $(ECC_SRCS) - -SOURCES = $(SORUCES_C) - -OBJECTS = $(SOURCES_C:.c=.o) - -HEADERS = format_nlist.h \ - makenandfirm.h \ - path.h \ - format_rom.h \ - misc.h \ - defval.h \ - compress.h \ - -MACROS += -DSMALL_CODE_SIZE \ - -DSTANDALONE \ - -DOPT_32_BIT \ - -DNO_SPLIT \ - -DNO_FP_API \ - -DNO_R_DIAG \ - $(ECC_DEFS) - -INSTALL_DIR = $(FIRM_INSTALL_TOOLSDIR)/bin -INSTALL_TARGETS = $(TARGETS) - -LDIRT_CLEAN = $(OBJECTS) $(TARGETS) version.h - - -VPATH = $(SRCDIR) -TWL_INCDIR := $(TWL_INCDIR) $(addprefix -I,$(INCDIR)) $(addprefix -I,$(FIRM_INCDIR)) - -include $(TWLSDK_ROOT)/build/buildtools/twl/modulerules.x86 - -#---------------------------------------------------------------------------- -# build -#---------------------------------------------------------------------------- -do-build: $(TARGETS) - -$(TARGETS): $(OBJECTS) - $(CC_X86) $+ -o $@ - -makenandfirm.o: makenandfirm.c makenandfirm.h format_rom.h path.h version.h -out_nandfirm.o: out_nandfirm.c misc.h format_rom.h format_nlist.h format_sign.h elf.h compress.h \ - $(FIRM_INCDIR)/firm/format/sign.h \ - $(FIRM_INCDIR)/firm/format/wram_regs.h \ - $(FIRM_INCDIR)/firm/format/nandfirm.h \ - -misc.o: misc.c misc.h -path.o: path.c path.h -compress.o: compress.c compress.h -wram_regs.o: wram_regs.c -acsign.o: acsign.c ../acsign/include/acsign.h -acsign_nand.o: acsign_nand.c format_sign.h \ - $(FIRM_INCDIR)/firm/format/sign.h \ - $(FIRM_INCDIR)/firm/format/wram_regs.h \ - $(FIRM_INCDIR)/firm/format/nandfirm.h \ - -aes2.o: aes2.c aes2.h - -$(FIRM_INCDIR)/firm/format/sign.h: -$(FIRM_INCDIR)/firm/format/wram_regs.h: -$(FIRM_INCDIR)/firm/format/nandfirm.h: -format_nlist.h: -format_rom.h: -makenandfirm.h: -acsign.h: -acsign_nand.h: -path.h: - -# avoid to warning message -misc.o:WARNING += -Wno-format-y2k - -# - -version.h: $(SOURCES) $(HEADERS) - @for i in $^ ; \ - do \ - date -r $$i +'#define SDK_DATE_OF_LATEST_FILE %Y%m%dUL'; \ - done | sort | tail -1 > $@ - -test: path.c misc.c - $(CC_X86) -DTEST $+ -o $@ diff --git a/build/tools/makenandfirm/compress.c b/build/tools/makenandfirm/compress.c deleted file mode 100644 index 71e468cc..00000000 --- a/build/tools/makenandfirm/compress.c +++ /dev/null @@ -1,293 +0,0 @@ -/*---------------------------------------------------------------------------* - Project: TwlFirm - tools - makenandfirm - File: compress.c - - Copyright 2007 Nintendo. All rights reserved. - - These coded instructions, statements, and computer programs contain - proprietary information of Nintendo of America Inc. and/or Nintendo - Company Ltd., and are protected by Federal copyright law. They may - not be disclosed to third parties or copied or duplicated in any form, - in whole or in part, without the prior written consent of Nintendo. - - $Date:: 2007-09-06$ - $Rev$ - $Author$ - *---------------------------------------------------------------------------*/ -#include -#include // atoi() -#include // strcmp() -#include // isprint() -#include // chdir() -#include -#include // UCHAR_MAX -#include -#include // stat() -#include "elf.h" -#include "misc.h" -#include "defval.h" -#include "format_rom.h" -#include "format_nlist.h" -#include "makenandfirm.h" - -//#define ADD_HEADER - -#define DIFF_CODE_HEADER (0x80) -#define RL_CODE_HEADER (0x30) -#define LZ_CODE_HEADER (0x10) -#define HUFF_CODE_HEADER (0x20) -#define CODE_HEADER_MASK (0xF0) - -//=========================================================================== -// LZ77圧縮 -//=========================================================================== -static u8 SearchLZ(const u8 *nextp, u32 remainSize, u16 *offset); - -static u16 windowPos; -static u16 windowLen; - -static s16 LZOffsetTable[4096]; -static s16 LZByteTable[256]; -static s16 LZEndTable[256]; - - -static void LZInitTable(void) -{ - u16 i; - - for (i = 0; i < 256; i++) - { - LZByteTable[i] = -1; - LZEndTable[i] = -1; - } - windowPos = 0; - windowLen = 0; -} - -static void SlideByte(const u8 *srcp) -{ - s16 offset; - u8 in_data = *srcp; - u16 insert_offset; - - if (windowLen == 4096) - { - u8 out_data = *(srcp - 4096); - if ((LZByteTable[out_data] = LZOffsetTable[LZByteTable[out_data]]) == -1) - { - LZEndTable[out_data] = -1; - } - insert_offset = windowPos; - } - else - { - insert_offset = windowLen; - } - - offset = LZEndTable[in_data]; - if (offset == -1) - { - LZByteTable[in_data] = insert_offset; - } - else - { - LZOffsetTable[offset] = insert_offset; - } - LZEndTable[in_data] = insert_offset; - LZOffsetTable[insert_offset] = -1; - - if (windowLen == 4096) - { - windowPos = (u16)((windowPos + 1) % 0x1000); - } - else - { - windowLen++; - } -} - -static void LZSlide(const u8 *srcp, u32 n) -{ - u32 i; - - for (i = 0; i < n; i++) - { - SlideByte(srcp++); - } -} - -/*---------------------------------------------------------------------------* - Name: MI_CompressLZ - - Description: LZ77圧縮を行なう関数 - - Arguments: srcp 圧縮元データへのポインタ - size 圧縮元データサイズ - dstp 圧縮先データへのポインタ - 圧縮元データよりも大きいサイズのバッファが必要です。 - - Returns: 圧縮後のデータサイズ。 - 圧縮後のデータが圧縮前よりも大きくなる場合には圧縮を中断し0を返します。 - *---------------------------------------------------------------------------*/ -u32 LZCompWrite(u8 *srcp, u32 size, u8 *dstp, int boundary) -{ - u32 LZDstCount; // 圧縮データのバイト数 - u8 LZCompFlags; // 圧縮の有無を示すフラグ系列 - u8 *LZCompFlagsp; // LZCompFlags を格納するメモリ領域をポイント - u16 lastOffset; // 一致データまでのオフセット (その時点での最長一致データ) - u8 lastLength; // 一致データ長 (その時点での最長一致データ) - u8 i; - u32 dstMax; - -#ifdef ADD_HEADER - *(u32 *)dstp = size << 8 | LZ_CODE_HEADER; // データ・ヘッダ - dstp += 4; -#endif - LZDstCount = 4; - dstMax = size; - LZInitTable(); - - while (size > 0) - { - LZCompFlags = 0; - LZCompFlagsp = dstp++; // フラグ系列の格納先 - LZDstCount++; - - // フラグ系列が8ビットデータとして格納されるため、8回ループ - for (i = 0; i < 8; i++) - { - LZCompFlags <<= 1; // 初回 (i=0) は特に意味はない - if (size <= 0) - { - // 終端に来た場合はフラグを最後までシフトさせてから終了 - continue; - } - - if ((lastLength = SearchLZ(srcp, size, &lastOffset))) - { - // 圧縮可能な場合はフラグを立てる - LZCompFlags |= 0x1; - - // オフセットは上位4ビットと下位8ビットに分けて格納 - *dstp++ = (u8)((lastLength - 3) << 4 | (lastOffset - 1) >> 8); - *dstp++ = (u8)((lastOffset - 1) & 0xff); - LZDstCount += 2; - LZSlide(srcp, lastLength); - srcp += lastLength; - size -= lastLength; - } - else - { - // 圧縮なし - LZSlide(srcp, 1); - *dstp++ = *srcp++; - size--; - LZDstCount++; - } - } // 8回ループ終了 - *LZCompFlagsp = LZCompFlags; // フラグ系列を格納 - } - - // 16バイト境界アラインメント - // アラインメント用データ0 はデータサイズに含める - i = 0; - while (LZDstCount & (boundary - 1)) -// while ((LZDstCount + i) & 0x3) - { - *dstp++ = 0; - LZDstCount++; - i++; - } - - return LZDstCount; -} - -//-------------------------------------------------------- -// LZ77圧縮でスライド窓の中から最長一致列を検索します。 -// Arguments: startp データの開始位置を示すポインタ -// nextp 検索を開始するデータのポインタ -// remainSize 残りデータサイズ -// offset 一致したオフセットを格納する領域へのポインタ -// Return : 一致列が見つかった場合は TRUE -// 見つからなかった場合は FALSE -//-------------------------------------------------------- -static u8 SearchLZ(const u8 *nextp, u32 remainSize, u16 *offset) -{ - const u8 *searchp; - const u8 *headp, *searchHeadp; - u16 maxOffset; - u8 maxLength = 2; - u8 tmpLength; - s32 w_offset; - - if (remainSize < 3) - { - return 0; - } - - w_offset = LZByteTable[*nextp]; - - while (w_offset != -1) - { - if (w_offset < windowPos) - { - searchp = nextp - windowPos + w_offset; - } - else - { - searchp = nextp - windowLen - windowPos + w_offset; - } - - /* 無くても良いが、僅かに高速化する */ - if (*(searchp + 1) != *(nextp + 1) || *(searchp + 2) != *(nextp + 2)) - { - w_offset = LZOffsetTable[w_offset]; - continue; - } - - if (nextp - searchp < 2) - { - // VRAMは2バイトアクセスなので (VRAMからデータを読み出す場合があるため)、 - // 検索対象データは2バイト前からのデータにしなければならない。 - // - // オフセットは12ビットで格納されるため、4096以下 - break; - } - tmpLength = 3; - searchHeadp = searchp + 3; - headp = nextp + 3; - - while (((u32)(headp - nextp) < remainSize) && (*headp == *searchHeadp)) - { - headp++; - searchHeadp++; - tmpLength++; - - // データ長は4ビットで格納されるため、18以下 (3の下駄をはかせる) - if (tmpLength == (0xF + 3)) - { - break; - } - } - if (tmpLength > maxLength) - { - // 最大長オフセットを更新 - maxLength = tmpLength; - maxOffset = (u16)(nextp - searchp); - if (maxLength == (0xF + 3)) - { - // 一致長が最大なので、検索を終了する。 - break; - } - } - w_offset = LZOffsetTable[w_offset]; - } - - if (maxLength < 3) - { - return 0; - } - *offset = maxOffset; - return maxLength; -} - diff --git a/build/tools/makenandfirm/compress.h b/build/tools/makenandfirm/compress.h deleted file mode 100644 index f8fd899e..00000000 --- a/build/tools/makenandfirm/compress.h +++ /dev/null @@ -1,38 +0,0 @@ -/*---------------------------------------------------------------------------* - Project: TwlFirm - tools - makenandfirm - File: compress.h - - Copyright 2007 Nintendo. All rights reserved. - - These coded instructions, statements, and computer programs contain - proprietary information of Nintendo of America Inc. and/or Nintendo - Company Ltd., and are protected by Federal copyright law. They may - not be disclosed to third parties or copied or duplicated in any form, - in whole or in part, without the prior written consent of Nintendo. - - $Date:: 2007-09-06$ - $Rev$ - $Author$ - *---------------------------------------------------------------------------*/ -#ifndef COMPRESS_H_ -#define COMPRESS_H_ - -#include "misc.h" - - -/*---------------------------------------------------------------------------* - Name: MI_CompressLZ - - Description: LZ77圧縮を行なう関数 - - Arguments: srcp 圧縮元データへのポインタ - size 圧縮元データサイズ - dstp 圧縮先データへのポインタ - 圧縮元データよりも大きいサイズのバッファが必要です。 - - Returns: 圧縮後のデータサイズ。 - *---------------------------------------------------------------------------*/ -u32 LZCompWrite(u8 *srcp, u32 size, u8 *dstp, int boundary); - - -#endif //COMPRESS_H_ diff --git a/build/tools/makenandfirm/defval.c b/build/tools/makenandfirm/defval.c deleted file mode 100644 index 679fb0e6..00000000 --- a/build/tools/makenandfirm/defval.c +++ /dev/null @@ -1,315 +0,0 @@ -/*---------------------------------------------------------------------------* - Project: NitroSDK - tools - makerom - File: defval.c - - Copyright 2003-2006 Nintendo. All rights reserved. - - These coded instructions, statements, and computer programs contain - proprietary information of Nintendo of America Inc. and/or Nintendo - Company Ltd., and are protected by Federal copyright law. They may - not be disclosed to third parties or copied or duplicated in any form, - in whole or in part, without the prior written consent of Nintendo. - - $Log: defval.c,v $ - Revision 1.10 2006/01/18 02:11:19 kitase_hirotake - do-indent - - Revision 1.9 2005/02/28 05:26:03 yosizaki - do-indent. - - Revision 1.8 2004/08/05 13:50:13 yasu - Support -M option - - Revision 1.7 2004/06/29 04:55:40 yasu - Use VBuffer to resolve variables - - Revision 1.6 2004/06/23 07:51:02 yasu - fix a bug as illegal memory freeing at ResolveDefVal() - - Revision 1.5 2004/05/27 00:40:49 yasu - care also about current directory (dot ".") - - Revision 1.4 2004/05/27 00:25:46 yasu - care about double-dots ".." for defvalue option :r, :e - - Revision 1.3 2004/05/27 00:11:19 yasu - fix a error when searching a "dot" of file extension - - Revision 1.2 2004/05/26 12:02:47 yasu - support :h, :t, :r, :e option for variable name - - Revision 1.1 2004/03/26 05:06:45 yasu - support variables like as -DNAME=VALUE - - $NoKeywords: $ - *---------------------------------------------------------------------------*/ -#include -#include // getenv() -#include // strcasecmp() -#include // getopt() -#include "misc.h" -#include "defval.h" - -typedef struct tValdef -{ - struct tValdef *next; - char *name; - char *value; -} -tValdef; - -tValdef *valdef_top = NULL; - - -// -// Add new define value via file -// -// opt : "DEFINE=VALUE" -// -BOOL AddDefValFromFile(char *filename) -{ - char *buffer; - int buffer_size; - int read_size; - FILE *fp; - - if (filename[0] == '-' && filename[1] == '\0') - { - fp = stdin; - } - else if (NULL == (fp = fopen(filename, "rb"))) - { - fprintf(stderr, "Cannot open file \"%s\".\n", filename); - return FALSE; - } - - buffer_size = DEFVAL_DEFAULT_BUFFER_SIZE; - - if (NULL == (buffer = malloc(buffer_size))) - { - fprintf(stderr, "Cannot allocate memory.\n"); - return FALSE; - } - - read_size = 0; - - while (NULL != fgets(buffer + read_size, buffer_size - read_size, fp)) - { - read_size = strlen(buffer); - - if (read_size == buffer_size - 1 && buffer[read_size - 1] != '\n') - { - buffer_size *= 2; - - if (NULL == (buffer = realloc(buffer, buffer_size))) - { - fprintf(stderr, "Cannot allocate memory.\n"); - return FALSE; - } - continue; - } - - AddDefVal(buffer); - read_size = 0; - } - - if (fp != stdin) - { - fclose(fp); - } - free(buffer); - - return TRUE; -} - - -// -// Add new define value -// -// opt : "DEFINE=VALUE" -// -void AddDefVal(char *opt) -{ - int i; - tValdef *t; - - for (i = 0;; i++) - { - if ('=' == opt[i] || '\0' == opt[i]) - { - break; - } - } - - if (i > 0) - { - t = Alloc(sizeof(tValdef)); - t->name = strncpy(Alloc(i + 1), opt, i); - t->name[i] = '\0'; - - if (opt[i] == '=') - { - i++; - } - t->value = strdup(opt + i); - - t->next = valdef_top; - valdef_top = t; - - debug_printf("DEFINE:$(%s)=\"%s\"\n", t->name, t->value); - } - return; -} - -// -// Search define value -// -// Return: value of specified name -// -char *SearchDefVal(char *name) -{ - tValdef *t; - - for (t = valdef_top; t; t = t->next) - { - if (!strcmp(t->name, name)) - { - return t->value; - } - } - - return getenv(name); -} - - -// -// Search define value and Modify it by : option -// -// Return: duplicated value of specified name modified by :x option -// -char *SearchDefValWithOption(char *name) -{ - int len_name = strlen(name); - char *value; - char option = '\0'; - - if (len_name > 2 && name[len_name - 2] == ':') - { - name[len_name - 2] = '\0'; - option = name[len_name - 1]; - } - - value = SearchDefVal(name); - - if (value) - { - int value_len = strlen(value); - int col_dot = value_len; - int col_filename = 0; - int i; - - for (i = 0; i < value_len; i++) - { - switch (value[i]) - { - case '.': - if (col_filename == i && - (value[i + 1] == '\0' || (value[i + 1] == '.' && value[i + 2] == '\0'))) - { - i = value_len; // exit loop if last entry is . or .. - } - else - { - col_dot = i; // Save the last dot column - } - break; - - case '/': - case '\\': - case ':': - col_filename = i + 1; // Save the last filename - col_dot = value_len; // Reset dot position - break; - - default: - ; - } - } - - switch (option) - { - case 'h': // Dirname with the last slash - value = strdup(value); - value[col_filename] = '\0'; - break; - - case 't': // Filename - value = strdup(value + col_filename); - break; - - case 'r': // All without . file extension - value = strdup(value); - value[col_dot] = '\0'; - break; - - case 'e': // File extension - value = strdup(value + col_dot + 1); - break; - - default: - value = strdup(value); - } - } - return value; -} - - -// -// Resolve define value -// -// Return: new string -// -char *ResolveDefVal(char *str) -{ - int i, j; - char *val; - VBuffer buf; - - InitVBuffer(&buf); - - for (i = 0; '\0' != str[i]; i++) - { - // search $(XXX) - if ('$' == str[i] && '(' == str[i + 1]) - { - for (j = i + 2; '\0' != str[j]; j++) - { - if (')' == str[j]) - { - str[j] = '\0'; - - // get value of XXX - val = SearchDefValWithOption(&str[i + 2]); - - // copy value of XXX - if (val) - { - char *s = val; - - while (*s) - { - PutVBuffer(&buf, *s); - s++; - } - free(val); - } - i = j; - goto next; - } - } - } - PutVBuffer(&buf, str[i]); - next:; - } - return GetVBuffer(&buf); // pass allocated buffer, should be freed by caller -} diff --git a/build/tools/makenandfirm/defval.h b/build/tools/makenandfirm/defval.h deleted file mode 100644 index 71355101..00000000 --- a/build/tools/makenandfirm/defval.h +++ /dev/null @@ -1,38 +0,0 @@ -/*---------------------------------------------------------------------------* - Project: NitroSDK - tools - makerom - File: defval.h - - Copyright 2003-2006 Nintendo. All rights reserved. - - These coded instructions, statements, and computer programs contain - proprietary information of Nintendo of America Inc. and/or Nintendo - Company Ltd., and are protected by Federal copyright law. They may - not be disclosed to third parties or copied or duplicated in any form, - in whole or in part, without the prior written consent of Nintendo. - - $Log: defval.h,v $ - Revision 1.4 2006/01/18 02:11:19 kitase_hirotake - do-indent - - Revision 1.3 2005/02/28 05:26:03 yosizaki - do-indent. - - Revision 1.2 2004/08/05 13:50:13 yasu - Support -M option - - Revision 1.1 2004/03/26 05:06:45 yasu - support variables like as -DNAME=VALUE - - $NoKeywords: $ - *---------------------------------------------------------------------------*/ -#ifndef DEFVAL_H_ -#define DEFVAL_H_ - -#define DEFVAL_DEFAULT_BUFFER_SIZE (1024) - -BOOL AddDefValFromFile(char *filename); -void AddDefVal(char *opt); -char *SearchDefVal(char *name); -char *ResolveDefVal(char *str); - -#endif //DEFVAL_H_ diff --git a/build/tools/makenandfirm/elf.h b/build/tools/makenandfirm/elf.h deleted file mode 100644 index c360cd33..00000000 --- a/build/tools/makenandfirm/elf.h +++ /dev/null @@ -1,431 +0,0 @@ -/*---------------------------------------------------------------------------* - Project: TwlFirm - ELF - File: elf.h - - Copyright 2007 Nintendo. All rights reserved. - - These coded instructions, statements, and computer programs contain - proprietary information of Nintendo of America Inc. and/or Nintendo - Company Ltd., and are protected by Federal copyright law. They may - not be disclosed to third parties or copied or duplicated in any form, - in whole or in part, without the prior written consent of Nintendo. - *---------------------------------------------------------------------------*/ - -#ifndef ELF_H_ -#define ELF_H_ - -#include "misc.h" - -/*--------------------------------------------------------- - 型定義 - --------------------------------------------------------*/ -typedef u32 Elf32_Addr; /* size:4, align:4 Unsigned program address */ -typedef u16 Elf32_Half; /* size:2, align:2 Unsigned medium int */ -typedef u32 Elf32_Off; /* size:4, align:4 Unsigned file offset */ -typedef s32 Elf32_Sword; /* size:4, align:4 Signed large int */ -typedef u32 Elf32_Word; /* size:4, align:4 Unsigned large int */ - -/*--------------------------------------------------------- - ELF Header - --------------------------------------------------------*/ -/* e_identのインデックス */ -#define EI_MAG0 0 /* File identification */ -#define EI_MAG1 1 /* File identification */ -#define EI_MAG2 2 /* File identification */ -#define EI_MAG3 3 /* File identification */ -#define EI_CLASS 4 /* File class 0=invalid, 1=32bit, 2=64bit */ -#define EI_DATA 5 /* Data encoding 0=invalid, 1=LSB, 2=MSB */ -#define EI_VERSION 6 /* File version 現在は1 */ -#define EI_PAD 7 /* Start of padding bytes */ -#define EI_NIDENT 16 /* Size of e_ident[] */ - -typedef struct { - unsigned char e_ident[EI_NIDENT]; - Elf32_Half e_type; /* ELFの形式(再配置可能, 実行可能など) */ - Elf32_Half e_machine; /* ファイルで要求されるアーキテクチャ */ - Elf32_Word e_version; /* ELFフォーマットのバージョン(現在は1) */ - Elf32_Addr e_entry; /* プログラムのエントリポイント。指定無しなら0。 */ - Elf32_Off e_phoff; /* プログラムヘッダテーブルのファイル先頭からのオフセット */ - Elf32_Off e_shoff; /* セクションヘッダテーブルのファイル先頭からのオフセット */ - Elf32_Word e_flags; /* プロセッサ固有のフラグ */ - Elf32_Half e_ehsize; /* ELFヘッダのサイズ */ - Elf32_Half e_phentsize; /* 1プログラムヘッダのサイズ */ - Elf32_Half e_phnum; /* プログラムヘッダの数 */ - Elf32_Half e_shentsize; /* 1セクションヘッダのサイズ */ - Elf32_Half e_shnum; /* セクションヘッダの数 */ - Elf32_Half e_shstrndx; /* セクション名文字列テーブルセクションへのインデックス */ -} Elf32_Ehdr; - -/* e_ident[EI_*]の中身定義 */ -#define ELFMAG0 0x7f -#define ELFMAG1 'E' -#define ELFMAG2 'L' -#define ELFMAG3 'F' -#define ELFCLASSNONE 0 /* invalid */ -#define ELFCLASS32 1 /* ARM and Thumb processors use 32-bit ELF. */ -#define ELFCLASS64 2 -#define ELFDATANONE 0 /* invalid */ -#define ELFDATA2LSB 1 /* little-endian */ -#define ELFDATA2MSB 2 /* big-endian */ - - -/* [e_type] */ -#define ET_NONE 0 /* No file type */ -#define ET_REL 1 /* Re-locatable file */ -#define ET_EXEC 2 /* Executable file */ -#define ET_DYN 3 /* Shared object file */ -#define ET_CORE 4 /* Core file */ -#define ET_LOPROC 0xff00 /* Processor-specific */ -#define ET_HIPROC 0xffff /* Processor-specific */ - -/* [e_machine] */ -#define EM_NONE 0 /* No machine */ -#define EM_M32 1 -#define EM_SPARC 2 -#define EM_386 3 -#define EM_68K 4 -#define EM_88K 5 -#define EM_860 7 -#define EM_MIPS 8 -#define EM_MIPS_RS4_BE 10 -#define EM_ARM 40 /* ARM/Thumb Architecture */ - - -/* [e_version] This member identifies the object file version.*/ -#define EV_NONE 0 /* Invalid version */ -#define EV_CURRENT 1 /* Current version */ - - -/* - ARM-specific e_flags - e_flags Field Value Meaning - EF_ARM_HASENTRY (0x02) e_entry contains a program-loader entry point - (see section 4.1.1, Entry points, below). - EF_ARM_SYMSARESORTED (0x04) Each subsection of the symbol table is sorted by symbol value - (see section 4.4.8, Symbol table order, below) - EF_ARM_DYNSYMSUSESEGIDX (0x8) Symbols in dynamic symbol tables that are defined in sections - included in program segment n have st_shndx = n + 1. - (see section 4.4.9, Dynamic symbol table entries, below). - EF_ARM_MAPSYMSFIRST (0x10) Mapping symbols precede other local symbols in the symbol table - (see section 4.4.8, Symbol table order, below). - - EF_ARM_EABIMASK (0xFF000000)(current version is 0x02000000) - This masks an 8-bit version number, the version of the ARM - EABI to which this ELF file conforms. This EABI is version 2. A - value of 0 denotes unknown conformance. -*/ -#define EF_ARM_HASENTRY 0x02 -#define EF_ARM_SYMSARESORTED 0x04 -#define EF_ARM_DYNSYMSUSESEGIDX 0x8 -#define EF_ARM_MAPSYMSFIRST 0x10 -#define EF_ARM_EABIMASK 0xFF000000 - - -/*--------------------------------------------------------- - Program headers - --------------------------------------------------------*/ -typedef struct { - Elf32_Word p_type; - Elf32_Off p_offset; - Elf32_Addr p_vaddr; - Elf32_Addr p_paddr; - Elf32_Word p_filesz; - Elf32_Word p_memsz; - Elf32_Word p_flags; - Elf32_Word p_align; -} Elf32_Phdr; - -/* [p_type] */ -#define PT_NULL 0 /* 使われないエントリで、他のメンバの値の意味は未定義 */ -#define PT_LOAD 1 /* 実行時にロードされるセグメント */ -#define PT_DYNAMIC 2 /* 動的構造体配列を保持するセグメント */ -#define PT_INTERP 3 /* ファイルの解釈に使われるインタプリタのパスを保持するセグメント */ -#define PT_NOTE 4 /* ファイルの解釈には使われない情報を保持するセグメント */ -#define PT_SHLIB 5 /* 予約 */ -#define PT_PHDR 6 /* プログラムヘッダテーブル(プログラムのメモリイメージの一部である場合のみ存在) */ -//#define PT_TLS ? /* スレッド局所記憶領域のテンプレート */ - -#define PT_LOOS 0x60000000 /* OS固有に予約された領域 */ -#define PT_HIOS 0x6fffffff - -#define PT_LOPROC 0x70000000 /* プロセッサ固有に予約された領域 */ -#define PT_HIPROC 0x7fffffff - -/* [p_flags]*/ -#define PF_X 1 /*実行可能*/ -#define PF_W 2 /*書き込み可能*/ -#define PF_R 4 /*読み出し可能*/ -#define PF_ARM_SB 0x10000000 /*The segment contains the location addressed by the static base*/ -#define PF_ARM_PI 0x20000000 /*The segment is position-independent*/ -#define PF_ARM_ENTRY 0x80000000 /*The segment contains the entry point*/ -#define PF_MASKPROC 0xf0000000 - - -/*--------------------------------------------------------- - Section headers - --------------------------------------------------------*/ -typedef struct { - Elf32_Word sh_name; /*セクションヘッダ文字列テーブルセクションのインデックス*/ - Elf32_Word sh_type; /* タイプ(下記定義参照) */ - Elf32_Word sh_flags; - Elf32_Addr sh_addr; /* */ - Elf32_Off sh_offset; /* ファイルの先頭からのオフセット */ - Elf32_Word sh_size; /* バイト単位のサイズ */ - Elf32_Word sh_link; /* sh_typeによって値の意味が変わる */ - Elf32_Word sh_info; /* sh_typeによって値の意味が変わる */ - Elf32_Word sh_addralign; /* アラインメント制限(0or1で制限なし,4で4ByteAlign) */ - Elf32_Word sh_entsize; /* 固定サイズのエントリテーブルがある場合、1要素のサイズ */ -} Elf32_Shdr; - -/* sh_addr mod sh_addralign = 0 でなければならない */ - -/* Section Types, [sh_type] */ -#define SHT_NULL 0 -#define SHT_PROGBITS 1 -#define SHT_SYMTAB 2 -#define SHT_STRTAB 3 -#define SHT_RELA 4 -#define SHT_HASH 5 -#define SHT_DYNAMIC 6 -#define SHT_NOTE 7 -#define SHT_NOBITS 8 -#define SHT_REL 9 -#define SHT_SHLIB 10 -#define SHT_DYNSYM 11 -#define SHT_LOPROC 0x70000000 -#define SHT_HIPROC 0x7fffffff -#define SHT_LOUSER 0x80000000 -#define SHT_HIUSER 0xffffffff - - -/* [sh_flags] */ -#define SHF_WRITE 0x1 -#define SHF_ALLOC 0x2 -#define SHF_EXECINSTR 0x4 -#define SHF_MASKPROC 0xf0000000 -/* ARM-EABI-specific */ -#define SHF_ENTRYSECT 0x10000000 /* The section contains an entry point. */ -#define SHF_COMDEF 0x80000000 /* The section may be multiply defined in the input to a link step. */ -/* others */ -#define SHF_LINK_ORDER 0x80 - -/*セクションインデックス*/ -//Sym->st_shndxなど -#define SHN_UNDEF 0 -#define SHN_LORESERVE 0xff00 -#define SHN_LOPROC 0xff00 -#define SHN_HIPROC 0xff1f -#define SHN_ABS 0xfff1 -#define SHN_COMMON 0xfff2 -#define SHN_HIRESERVE 0xffff - - -//ここからはヘッダでなく実体データ構造 - -/*--------------------------------------------------------- - Symbol Table Entry - --------------------------------------------------------*/ -typedef struct { - Elf32_Word st_name; /* シンボル文字列テーブルのインデックス */ - Elf32_Addr st_value; /* おそらく関連するセクション内でのオフセット値 */ - Elf32_Word st_size; /* サイズがないか、不明な場合は 0 */ - unsigned char st_info; /* バインド と タイプ */ - unsigned char st_other; /* 現在は 0 が入る */ - Elf32_Half st_shndx; /* 関連するセクションヘッダテーブルのインデックス */ -} Elf32_Sym; - - -/* st_info */ -#define ELF32_ST_BIND(i) ((i)>>4) -#define ELF32_ST_TYPE(i) ((i)&0xf) -#define ELF32_ST_INFO(b,t) (((b)<<4)+((t)&0xf)) - -/* st_info の BIND */ -#define STB_LOCAL 0 -#define STB_GLOBAL 1 -#define STB_WEAK 2 -#define STB_LOPROC 13 -#define STB_HIPROC 15 - -/* st_info の TYPE */ -#define STT_NOTYPE 0 /*未定義*/ -#define STT_OBJECT 1 /*データオブジェクト*/ -#define STT_FUNC 2 -#define STT_SECTION 3 -#define STT_FILE 4 -#define STT_LOPROC 13 -#define STT_HIPROC 15 - - -/*--------------------------------------------------------- - Relocation Entry - --------------------------------------------------------*/ -typedef struct { - Elf32_Addr r_offset; - Elf32_Word r_info; -} Elf32_Rel; - -typedef struct { - Elf32_Addr r_offset; - Elf32_Word r_info; - Elf32_Sword r_addend; -} Elf32_Rela; - -#define ELF32_R_SYM(i) ((i)>>8) -#define ELF32_R_TYPE(i) ((unsigned char)(i)) -#define ELF32_R_INFO(s,t) (((s)<<8)+(unsigned char)(t)) - - -/* r_info の TYPE */ -#define R_ARM_NONE 0 /* Any No relocation. Encodes dependencies between sections. */ -#define R_ARM_PC24 1 /* ARM B/BL S . P + A */ -#define R_ARM_ABS32 2 /* 32-bit word S + A */ -#define R_ARM_REL32 3 /* 32-bit word S . P + A */ -#define R_ARM_PC13 4 /* ARM LDR r, [pc,…] S . P + A */ -#define R_ARM_ABS16 5 /* 16-bit half-word S + A */ -#define R_ARM_ABS12 6 /* ARM LDR/STR S + A */ -#define R_ARM_THM_ABS5 7 /* Thumb LDR/STR S + A */ -#define R_ARM_ABS8 8 /* 8-bit byte S + A */ -#define R_ARM_SBREL32 9 /* 32-bit word S . B + A */ -#define R_ARM_THM_PC22 10 /* Thumb BL pair S . P+ A */ -#define R_ARM_THM_PC8 11 /* Thumb LDR r, [pc,…] S . P + A */ -#define R_ARM_AMP_VCALL9 12 /* AMP VCALL Obsolete.SA-1500 only. */ -#define R_ARM_SWI24 13 /* ARM SWI S + A */ -#define R_ARM_THM_SWI8 14 /* Thumb SWI S + A */ -#define R_ARM_XPC25 15 /* ARM BLX S . P+ A */ -#define R_ARM_THM_XPC22 16 /* Thumb BLX pair S . P+ A */ - -/* 17-31, reserved to ARM Linux */ -//17-19 Reserved to ARM LINUX -#define R_ARM_COPY 20 /* 32 bit word Copy symbol at dynamic link time. */ -#define R_ARM_GLOB_DAT 21 /* 32 bit word Create GOT entry. */ -#define R_ARM_JUMP_SLOT 22 /* 32 bit word Create PLT entry. */ -#define R_ARM_RELATIVE 23 /* 32 bit word Adjust by program base. */ -#define R_ARM_GOTOFF 24 /* 32 bit word Offset relative to start of GOT. */ -#define R_ARM_GOTPC 25 /* 32 bit word Insert address of GOT. */ -#define R_ARM_GOT32 26 /* 32 bit word Entry in GOT. */ -#define R_ARM_PLT32 27 /* ARM BL Entry in PLT. */ - -/* 28-31 Reserved to ARM LINUX */ -#define R_ARM_ALU_PCREL_7_0 32 /* ARM ADD/SUB (S . P + A) & 0x000000FF */ -#define R_ARM_ALU_PCREL_15_8 33 /* ARM ADD/SUB (S . P + A) & 0x0000FF00 */ -#define R_ARM_ALU_PCREL_23_15 34 /* ARM ADD/SUB (S . P + A) & 0x00FF0000 */ -#define R_ARM_LDR_SBREL_11_0 35 /* ARM LDR/STR (S . B + A) & 0x00000FFF */ -#define R_ARM_ALU_SBREL_19_12 36 /* ARM ADD/SUB (S . B + A) & 0x000FF000 */ -#define R_ARM_ALU_SBREL_27_20 37 /* ARM ADD/SUB (S . B + A) & 0x0FF00000 */ - -#define R_ARM_TARGET1 38 -#define R_ARM_ROSEGREL32 39 -#define R_ARM_V4BX 40 -#define R_ARM_TARGET2 41 -#define R_ARM_PREL31 42 - -/* 96-111, reserved to ARM g++ */ -#define R_ARM_GNU_VTENTRY 100 /* 32 bit word Record C++ vtable entry. */ -#define R_ARM_GNU_VTINHERIT 101 /* 32 bit word Record C++ member usage. */ -#define R_ARM_THM_PC11 102 /* Thumb B S . P + A */ -#define R_ARM_THM_PC9 103 /* Thumb B S . P + A */ - -/* 112-127, reserved for private experiments */ - -/* 128-248, reserved to ARM */ -#define R_ARM_RXPC25 249 /* ARM BLX (ΔS . ΔP) + A #define For calls between program segments. */ -#define R_ARM_RSBREL32 250 /* Word (ΔS . ΔSB) + A For an offset from SB, the static base. */ -#define R_ARM_THM_RPC22 251 /* Thumb BL/BLX pair (ΔS . ΔP) + A For calls between program segments. */ -#define R_ARM_RREL32 252 /* Word (ΔS . ΔP) + A For on offset between two segments. */ -#define R_ARM_RABS32 253 /* Word ΔS + A For the address of a location in the target segment. */ -#define R_ARM_RPC24 254 /* ARM B/BL (ΔS . ΔP) + A For calls between program segments. */ -#define R_ARM_RBASE 255 /* None None.Identifies the segment being relocated by the following - relocation directives. The ARM EABI poses two problems for relocating - executables and shared objects encoded in */ - - -// shirait -#define R_ARM_LDR_PC_G0 4 //LDR - -#define R_ARM_ABS12 6 //LDR, STR - -#define R_ARM_THM_CALL 10 //R_ARM_THM_PC22と同じ - -#define R_ARM_CALL 28 //BL/BLX -#define R_ARM_JUMP24 29 //B/BL -#define R_ARM_THM_JUMP24 30 - -#define R_ARM_MOVW_ABS_NC 43 //MOVW -#define R_ARM_MOVT_ABS 44 //MOVT -#define R_ARM_MOVW_PREL_NC 45 //MOVW -#define R_ARM_MOVT_PREL 46 //MOVT - -#define R_ARM_ALU_PC_G0_NC 57 //ADD, SUB -#define R_ARM_ALU_PC_G0 58 //ADD, SUB -#define R_ARM_ALU_PC_G1_NC 59 //ADD, SUB -#define R_ARM_ALU_PC_G1 60 //ADD, SUB -#define R_ARM_ALU_PC_G2 61 //ADD, SUB -#define R_ARM_LDR_PC_G1 62 //LDR, STR, LDRB, STRB -#define R_ARM_LDR_PC_G2 63 //LDR, STR, LDRB, STRB -#define R_ARM_LDRS_PC_G0 64 //LDRD, STRD, LDRH, STRH, LDRSH, LDRSB -#define R_ARM_LDRS_PC_G1 65 //LDRD, STRD, LDRH, STRH, LDRSH, LDRSB -#define R_ARM_LDRS_PC_G2 66 //LDRD, STRD, LDRH, STRH, LDRSH, LDRSB -#define R_ARM_LDC_PC_G0 67 //LDC, STC -#define R_ARM_LDC_PC_G1 68 //LDC, STC -#define R_ARM_LDC_PC_G2 69 //LDC, STC -#define R_ARM_ALU_SB_G0_NC 70 //ADD, SUB -#define R_ARM_ALU_SB_G0 71 //ADD, SUB -#define R_ARM_ALU_SB_G1_NC 72 //ADD, SUB -#define R_ARM_ALU_SB_G1 73 //ADD, SUB -#define R_ARM_ALU_SB_G2 74 //ADD, SUB -#define R_ARM_LDR_SB_G0 75 //LDR, STR, LDRB, STRB -#define R_ARM_LDR_SB_G1 76 //LDR, STR, LDRB, STRB -#define R_ARM_LDR_SB_G2 77 //LDR, STR, LDRB, STRB -#define R_ARM_LDRS_SB_G0 78 //LDRD, STRD, LDRH, STRH, LDRSH, LDRSB -#define R_ARM_LDRS_SB_G1 79 //LDRD, STRD, LDRH, STRH, LDRSH, LDRSB -#define R_ARM_LDRS_SB_G2 80 //LDRD, STRD, LDRH, STRH, LDRSH, LDRSB -#define R_ARM_LDC_SB_G0 81 //LDC, STC -#define R_ARM_LDC_SB_G1 82 //LDC, STC -#define R_ARM_LDC_SB_G2 83 //LDC, STC -#define R_ARM_MOVW_BREL_NC 84 //MOVW -#define R_ARM_MOVT_BREL 85 //MOVT -#define R_ARM_MOVW_BREL 86 //MOVW - -#define R_ARM_GOT_BREL12 97 //LDR -#define R_ARM_GOTOFF12 98 //LDR, STR - -#define R_ARM_TLS_LDO12 109 //LDR, STR -#define R_ARM_TLS_LE12 110 //LDR, STR -#define R_ARM_TLS_TE12GP 111 //LDR - - - -/*--------------------------------------------------------- - Dynamic Section elf_v1.2 - --------------------------------------------------------*/ -typedef struct { - Elf32_Sword d_tag; - union { - Elf32_Word d_val; - Elf32_Addr d_ptr; - } d_un; -} Elf32_Dyn; - - -/* Additional symbol types for Thumb. */ -#define STT_ARM_TFUNC STT_LOPROC /* A Thumb function. */ -#define STT_ARM_16BIT STT_HIPROC /* A Thumb label. */ - - - - - - - - - -/*--------------------------------------------------------- - ELFヘッダを読み出す - --------------------------------------------------------*/ -void *ELF_LoadELFHeader(const void *buf, Elf32_Ehdr *ehdr); - - - -#endif /* ELF_H_ */ - diff --git a/build/tools/makenandfirm/format_nlist.h b/build/tools/makenandfirm/format_nlist.h deleted file mode 100644 index a1ac95fd..00000000 --- a/build/tools/makenandfirm/format_nlist.h +++ /dev/null @@ -1,54 +0,0 @@ -/*---------------------------------------------------------------------------* - Project: TwlFirm - tools - makenandfirm - File: format_nlist.h - - Copyright 2007 Nintendo. All rights reserved. - - These coded instructions, statements, and computer programs contain - proprietary information of Nintendo of America Inc. and/or Nintendo - Company Ltd., and are protected by Federal copyright law. They may - not be disclosed to third parties or copied or duplicated in any form, - in whole or in part, without the prior written consent of Nintendo. - - $Date:: 2007-09-06$ - $Rev$ - $Author$ - *---------------------------------------------------------------------------*/ -#ifndef FORMAT_NLIST_H_ -#define FORMAT_NLIST_H_ - -#include -#include "misc.h" -#include "path.h" - -#define SPECFILE_MAGIC_ID "#NANDSF" - -#define CRC16_INIT_VALUE 0xffff - -//--------------------------------------------------------------------------- -// Banner Spec File -//--------------------------------------------------------------------------- - -// Command List -typedef struct -{ - char *string; - BOOL (*funcp) (char *, int num); - -} -tCommandDesc; - - -// F Command -typedef struct -{ - u32 offsetStart; - u32 offsetEnd; - u32 padding; - char fullPathSrc[FILENAME_MAX]; - -} -tFileDesc; - - -#endif // FORMAT_NLIST_H_ diff --git a/build/tools/makenandfirm/format_rom.h b/build/tools/makenandfirm/format_rom.h deleted file mode 100644 index e7195c10..00000000 --- a/build/tools/makenandfirm/format_rom.h +++ /dev/null @@ -1,51 +0,0 @@ -/*---------------------------------------------------------------------------* - Project: TwlFirm - tools - makenandfirm - File: format_rom.h - - Copyright 2007 Nintendo. All rights reserved. - - These coded instructions, statements, and computer programs contain - proprietary information of Nintendo of America Inc. and/or Nintendo - Company Ltd., and are protected by Federal copyright law. They may - not be disclosed to third parties or copied or duplicated in any form, - in whole or in part, without the prior written consent of Nintendo. - - $Date:: 2007-09-06$ - $Rev$ - $Author$ - *---------------------------------------------------------------------------*/ -#ifndef FORMAT_ROM_H_ -#define FORMAT_ROM_H_ - -#include "misc.h" -#include - - -#define DEFAULT_ALIGN 0x200 -#define FIRM_ALIGN DEFAULT_ALIGN -#define FIRM_ALIGN_MASK (FIRM_ALIGN - 1) - -#define DEFAULT_HOSTROOT "." -#define DEFAULT_ROOT "/" - -#define DEFAULT_REJECT_1 "CVS" -#define DEFAULT_REJECT_2 "vssver.scc" - -#define FORMAT_VERSION "1.0" - -#define ENTRYNAME_MAX 127 - -#define DEFAULT_LISTFILE "default.nlf" - -#define DEFAULT_NANDFIRM_SUFFIX ".nand" -#define DEFAULT_SPECFILE_SUFFIX ".nandsf" - -/*===========================================================================* - * ROM FORMAT - *===========================================================================*/ - -//--------------------------------------------------------------------------- -// ROM HEADER -//--------------------------------------------------------------------------- - -#endif //FORMAT_ROM_H_ diff --git a/build/tools/makenandfirm/format_sign.h b/build/tools/makenandfirm/format_sign.h deleted file mode 100644 index 6d3d2770..00000000 --- a/build/tools/makenandfirm/format_sign.h +++ /dev/null @@ -1,32 +0,0 @@ -/*---------------------------------------------------------------------------* - Project: TwlFirm - SS - File: format_sign.h - - Copyright 2006 Nintendo. All rights reserved. - - These coded instructions, statements, and computer programs contain - proprietary information of Nintendo of America Inc. and/or Nintendo - Company Ltd., and are protected by Federal copyright law. They may - not be disclosed to third parties or copied or duplicated in any form, - in whole or in part, without the prior written consent of Nintendo. - - $Date:: 2007-09-06$ - $Rev$ - $Author$ - *---------------------------------------------------------------------------*/ -#ifndef FIRM_MAKENANDFIRM_ACSIGN_FORMAT_H_ -#define FIRM_MAKENANDFIRM_ACSIGN_FORMAT_H_ - -#include "format_rom.h" - - -#ifdef __cplusplus -extern "C" { -#endif - -#ifdef __cplusplus -} /* extern "C" */ -#endif - -/* FIRM_MAKENANDFIRM_ACSIGN_FORMAT_H_ */ -#endif diff --git a/build/tools/makenandfirm/makenandfirm.c b/build/tools/makenandfirm/makenandfirm.c deleted file mode 100644 index abdb1c57..00000000 --- a/build/tools/makenandfirm/makenandfirm.c +++ /dev/null @@ -1,106 +0,0 @@ -/*---------------------------------------------------------------------------* - Project: TwlFirm - tools - makenandfirm - File: makenandfirm.c - - Copyright 2007 Nintendo. All rights reserved. - - These coded instructions, statements, and computer programs contain - proprietary information of Nintendo of America Inc. and/or Nintendo - Company Ltd., and are protected by Federal copyright law. They may - not be disclosed to third parties or copied or duplicated in any form, - in whole or in part, without the prior written consent of Nintendo. - - $Date:: 2007-09-06$ - $Rev$ - $Author$ - *---------------------------------------------------------------------------*/ -#include -#include -#include // strcasecmp() -#include // getopt() -#include "makenandfirm.h" -#include "format_rom.h" -#include "path.h" -#include "defval.h" -#include "version.h" - -static int makenandfirm(const char *specFile, const char *nandFile); - -//--------------------------------------------------------------------------- -// Main -//--------------------------------------------------------------------------- - -int main(int argc, char *argv[]) -{ - int n; - int narg; - char *nandfirmFile; - - InitAppName(argv[0]); - - while ((n = getopt(argc, argv, "D:hvpd")) != -1) - { - switch (n) - { - case 'h': - case 'v': - goto usage; - - case 'D': - AddDefVal(optarg); - break; - - case 'p': - PrintMode = TRUE; - break; - - case 'd': - DebugMode = TRUE; - break; - - default: - break; - } - } - - narg = argc - optind; - if (narg > 0) - { - // Make SpecFile->NandfirmFile - nandfirmFile = - strdup(narg > - 1 ? argv[optind + 1] : ChangeSuffix(argv[optind], DEFAULT_NANDFIRM_SUFFIX)); - return makenandfirm(argv[optind], nandfirmFile); - } - - usage: - { - char *makenandfirm = GetAppName(); - - fprintf(stderr, - "NITRO-SDK Development Tool - %s - Make nandfirm file \n" - "Build %lu\n\n" - "Usage: %s [-phv] [-DNAME=VALUE ...] SPECFILE [NANDFIRMFILE]\n\n", - makenandfirm, SDK_DATE_OF_LATEST_FILE, makenandfirm); - } - return 1; -} - - -//--------------------------------------------------------------------------- -// makenandfirm -//--------------------------------------------------------------------------- - -static int makenandfirm(const char *specFile, const char *nandFile) -{ - debug_printf("makenandfirm(): '%s' -> '%s'\n", specFile, nandFile); - - // Check identical - if (specFile && nandFile && !strcasecmp(specFile, nandFile)) - { - error("nandfirm spec file is identical '%s'", nandFile); - return 1; - } - - return OutputNandfirmFile(specFile, nandFile) ? 0 : 1; -} diff --git a/build/tools/makenandfirm/makenandfirm.h b/build/tools/makenandfirm/makenandfirm.h deleted file mode 100644 index 21ac7e0d..00000000 --- a/build/tools/makenandfirm/makenandfirm.h +++ /dev/null @@ -1,24 +0,0 @@ -/*---------------------------------------------------------------------------* - Project: TwlFirm - tools - makenandfirm - File: makenandfirm.h - - Copyright 2007 Nintendo. All rights reserved. - - These coded instructions, statements, and computer programs contain - proprietary information of Nintendo of America Inc. and/or Nintendo - Company Ltd., and are protected by Federal copyright law. They may - not be disclosed to third parties or copied or duplicated in any form, - in whole or in part, without the prior written consent of Nintendo. - - $Date:: 2007-09-06$ - $Rev$ - $Author$ - *---------------------------------------------------------------------------*/ -#ifndef MAKENANDFIRM_H_ -#define MAKENANDFIRM_H_ - -#include "misc.h" - -BOOL OutputNandfirmFile(const char *specFile, const char *nandFile); - -#endif //MAKENANDFIRM_H_ diff --git a/build/tools/makenandfirm/misc.c b/build/tools/makenandfirm/misc.c deleted file mode 100644 index 7326f41f..00000000 --- a/build/tools/makenandfirm/misc.c +++ /dev/null @@ -1,628 +0,0 @@ -/*---------------------------------------------------------------------------* - Project: TwlFirm - tools - makenandfirm - File: misc.c - - Copyright 2007 Nintendo. All rights reserved. - - These coded instructions, statements, and computer programs contain - proprietary information of Nintendo of America Inc. and/or Nintendo - Company Ltd., and are protected by Federal copyright law. They may - not be disclosed to third parties or copied or duplicated in any form, - in whole or in part, without the prior written consent of Nintendo. - - $Date:: 2007-09-06$ - $Rev$ - $Author$ - *---------------------------------------------------------------------------*/ -#include -#include // calloc() -#include // free(), exit() -#include // setmode() -#include // stat() -#include // setmode() -#include // strlen() -#include // va_start(),va_end() -#include // localtime() - -#include -#include "misc.h" - -BOOL DebugMode = FALSE; -BOOL PrintMode = FALSE; -char *PubkeyFileName = NULL; - -/*---------------------------------------------------------------------------* - * File Output Utilities - * - * BOOL OpenFile( const char* filename ) - * void CloseFile( void ) - * BOOL CheckResult( void ) - * void PutBuffer( const void* ptr, int len ) - * void PutByte( u8 c ) - * void PutWord( u16 c ) - * void PutWord( u32 c ) - * void PutString( const char *str ) - *---------------------------------------------------------------------------*/ - -static FILE *OutFile = NULL; -static const char *FileName = NULL; -static BOOL Status = FALSE; - - -// -// File Open -// - -BOOL OpenFile(const char *filename) -{ - if (OutFile) - CloseFile(); - - if (filename) - { - if (NULL == (OutFile = fopen(filename, "wb+"))) - { - error("Can't write '%s'", filename); - Status = FALSE; - return FALSE; - } - } - else - { - setmode(1, O_BINARY); - OutFile = stdout; // out to console if filename == NULL - } - FileName = filename; - Status = TRUE; - - return TRUE; -} - - -// -// File Close -// - -BOOL CloseFile(void) -{ - if (OutFile) - { - if (FileName) - { - if (fclose(OutFile) == -1) - { - error("Can't close '%s'", FileName); - Status = FALSE; - } - } - else - { - setmode(1, O_TEXT); - } - } - OutFile = NULL; - - return Status; -} - - -// -// File Seek -// - -void SeekFile(long pos) -{ - if (OutFile && fseek(OutFile, pos, SEEK_SET)) - { - error("Can't seek '%s'", FileName ? FileName : ""); - CloseFile(); - Status = FALSE; - } -} - - -// -// Error Check -// - -BOOL CheckResult(void) -{ - return Status; -} - - -// -// Delete outfile -// - -void DeleteOutFile(void) -{ - // Delete outfile - if (FileName) - { - debug_printf("Delete '%s'\n", FileName); - (void)unlink(FileName); - FileName = NULL; - } - return; -} - - -// -// Buffer Output -// - -void PutBuffer(const void *ptr, int len) /* If error, close file */ -{ - if (OutFile && len != fwrite(ptr, 1, len, OutFile)) - { - error("Can't write buffer to '%s'", FileName ? FileName : ""); - CloseFile(); - Status = FALSE; - } -} - -// -// Buffer Input -// - -void GetBuffer(void *ptr, int len) /* If error, close file */ -{ - if (OutFile && len != fread(ptr, 1, len, OutFile)) - { - error("Can't read '%s'", FileName ? FileName : ""); - CloseFile(); - Status = FALSE; - } -} - -// -// Byte/Half/Word Output -// - -void PutByte(u8 c) -{ - PutBuffer(&c, 1); -} -void PutHalf(u16 c) -{ - PutBuffer(&c, 2); -} -void PutWord(u32 c) -{ - PutBuffer(&c, 4); -} -void PutString(const char *str) -{ - PutBuffer(str, strlen(str)); -} - - -// -// Printf -// - -void PrintString(const char *fmt, ...) -{ - char *buffer; - va_list va; - int nchars; - int bufsize = FILENAME_MAX; - - while (1) - { - buffer = Alloc(bufsize); - va_start(va, fmt); - nchars = vsnprintf(buffer, bufsize, fmt, va); - va_end(va); - - if (0 <= nchars && nchars < bufsize) - { - break; - } - - Free(&buffer); - bufsize *= 2; - } - - if (nchars > 0) - { - PutBuffer(buffer, nchars); - } - Free(&buffer); -} - - -/*---------------------------------------------------------------------------* - * File Read/Write Utilities - * - * int ReadFile( const char* filename, void** buffer ) - * - * Read a file to buffer allocated internally - * Return read size - * Add '\0' at tail of file for help to handle text file - * - * BOOL WriteFile( const char* filename, void** buffer, int size ) - *---------------------------------------------------------------------------*/ - -int ReadFile(const char *filename, void *filebuffer, int size) -{ - FILE *fp; - struct stat fileStat; - int fileSize, readSize; - void **buffer = (void **)filebuffer; - - /* Check file */ - if (stat(filename, &fileStat) || !S_ISREG(fileStat.st_mode)) - { - goto error; - } - fileSize = fileStat.st_size; - if (fileSize < 0) - { - goto error; - } - - /* Open file */ - fp = fopen(filename, "rb"); - if (!fp) - { - goto error; - } - - if (size && (size < fileSize)) - { - readSize = size; - } - else - { - readSize = fileSize; - } - - /* Read file */ - *buffer = Alloc(readSize + 1); /* error handle is done in Alloc() */ - /* size+1 for '\0' to handle text file */ - if (readSize != fread(*buffer, sizeof(char), readSize, fp)) - { - goto error_free_close; - } - - (*(char **)buffer)[readSize] = '\0'; /* Works as terminater if file is text file */ - - /* Close file */ - fclose(fp); - return readSize; - - error_free_close: - Free(buffer); - fclose(fp); - error: - error("Can't read '%s'", filename); - return -1; -} - - -int ReadFileWithPadding(const char *filename, void *filebuffer, int size, int boundary) -{ - FILE *fp; - struct stat fileStat; - int fileSize, readSize, padSize; - void **buffer = (void **)filebuffer; - - if (!boundary) - { - return ReadFile(filename, buffer, size); - } - - /* Check file */ - if (stat(filename, &fileStat) || !S_ISREG(fileStat.st_mode)) - { - goto error; - } - fileSize = fileStat.st_size; - if (fileSize < 0) - { - goto error; - } - - /* Open file */ - fp = fopen(filename, "rb"); - if (!fp) - { - goto error; - } - - if (size && (size < fileSize)) - { - readSize = size; - } - else - { - readSize = fileSize; - } - - padSize = (boundary - (readSize & (boundary-1))) & (boundary-1); - - /* Read file */ - *buffer = Alloc(readSize + padSize); /* error handle is done in Alloc() */ - /* size+1 for '\0' to handle text file */ - if (readSize != fread(*buffer, sizeof(char), readSize, fp)) - { - goto error_free_close; - } - - memset((char*)*buffer + readSize, 0, padSize); - - /* Close file */ - fclose(fp); - return readSize + padSize; - - error_free_close: - Free(buffer); - fclose(fp); - error: - error("Can't read '%s'", filename); - return -1; -} - - -BOOL WriteFile(const char *filename, void *buffer, int size) -{ - debug_printf("WriteFile %s\n", filename); - - (void)OpenFile(filename); - PutBuffer(buffer, size); - CloseFile(); - Free(&buffer); - return CheckResult(); -} - - -/*---------------------------------------------------------------------------* - * Time Format Utilities - * - * char* GetGMTime( const time_t time ) Show GMT - * char* GetTime( const time_t time ) Show local Time - *---------------------------------------------------------------------------*/ - -char *GetGMTime(const time_t time) -{ - static char timebuffer[32]; - strftime(timebuffer, sizeof(timebuffer), "%y/%m/%d-%H:%M:%S", gmtime(&time)); - return timebuffer; -} - - -char *GetTime(const time_t time) -{ - static char timebuffer[32]; - strftime(timebuffer, sizeof(timebuffer), "%y/%m/%d-%H:%M:%S", localtime(&time)); - return timebuffer; -} - - -/*---------------------------------------------------------------------------* - * Memory Allocation Utilities - * - * void* Alloc( size_t size ) - *---------------------------------------------------------------------------*/ - -void *Alloc(size_t size) -{ - void *t = calloc(1, size); - - if (t == NULL) - { - error("Can't allocate memory."); - exit(10); - } - return t; -} - - -void Free(void *p) -{ - void **ptr = (void **)p; - - if (*ptr) - { - free(*ptr); - (*ptr) = NULL; - } -} - - -/*---------------------------------------------------------------------------* - * VBuffer - * - * void PutVBuffer( VBuffer* vbuf, char c ) - *---------------------------------------------------------------------------*/ - -void PutVBuffer(VBuffer * vbuf, char c) -{ - int size; - char *tmp_buffer; - - if (vbuf->buffer == 0) - { - vbuf->size = VBUFFER_INITIAL_SIZE; - vbuf->buffer = Alloc(vbuf->size); // buffer is CALLOCed - } - size = strlen(vbuf->buffer); - - if (size >= vbuf->size - 1) - { - // Need buffer expansion - vbuf->size *= 2; - tmp_buffer = Alloc(vbuf->size); // buffer is CALLOCed - strcpy(tmp_buffer, vbuf->buffer); - Free(&vbuf->buffer); - vbuf->buffer = tmp_buffer; - } - vbuf->buffer[size] = c; - return; -} - -char *GetVBuffer(VBuffer * vbuf) -{ - return vbuf->buffer; -} - -void InitVBuffer(VBuffer * vbuf) -{ - vbuf->buffer = 0; - vbuf->size = 0; -} - -void FreeVBuffer(VBuffer * vbuf) -{ - Free(&vbuf->buffer); -} - - -/*---------------------------------------------------------------------------* - * File Path Utilities - * - * char* ChangeBackSlash( char* path ) - *---------------------------------------------------------------------------*/ - -char *ChangeBackSlash(char *path) -{ - char *p = path; - - while (*p) - { - if (*p == '\\') - { - *p = '/'; - } - p++; - } - return path; -} - - -/*---------------------------------------------------------------------------* - * Math - * - * u16 CalcCRC16( u16 start, u8 *data, int size ) - *---------------------------------------------------------------------------*/ - -static u16 crc16_table[16] = { - 0x0000, 0xCC01, 0xD801, 0x1400, - 0xF001, 0x3C00, 0x2800, 0xE401, - 0xA001, 0x6C00, 0x7800, 0xB401, - 0x5000, 0x9C01, 0x8801, 0x4400 -}; - -u16 CalcCRC16(u16 start, u8 *data, int size) -{ - u16 r1; - u16 total = start; - - while (size-- > 0) - { - // 下位4bit - r1 = crc16_table[total & 0xf]; - total = (total >> 4) & 0x0fff; - total = total ^ r1 ^ crc16_table[*data & 0xf]; - - // 上位4bit - r1 = crc16_table[total & 0xf]; - total = (total >> 4) & 0x0fff; - total = total ^ r1 ^ crc16_table[(*data >> 4) & 0xf]; - - data++; - } - return total; -} - - -/*---------------------------------------------------------------------------* - * for firm header - * - *---------------------------------------------------------------------------*/ - -static u8 ConvertAlign( u32 ofs ) -{ - u8 i; - - ofs /= 4; - for (i=0; i<7; i++) - { - if ( ofs & 1 ) - { - break; - } - ofs >>= 1; - } - - return i; -} - -tROMAddrConvType ConvertHeaderRamAddr( s32 p ) -{ - tROMAddrConvType retval; - - retval.align = ConvertAlign( p ); - retval.address = (u16)((p - HW_WRAM)/(4< - -typedef enum -{ - FALSE = 0, - TRUE = 1 -} -BOOL; - -typedef unsigned char u8; -typedef unsigned short int u16; -typedef unsigned long int u32; -typedef unsigned long long u64; -typedef signed char s8; -typedef signed short int s16; -typedef signed long int s32; -typedef signed long long s64; -typedef volatile u8 vu8; -typedef volatile u32 vu32; -typedef vu32 REGType32v; - -#define error(...) do { fprintf(stderr, "Error: "); \ - fprintf(stderr, __VA_ARGS__); \ - fprintf(stderr, "\n"); } while(0) - -#define warning(...) do { fprintf(stderr, "Warning: "); \ - fprintf(stderr, __VA_ARGS__); \ - fprintf(stderr, "\n"); } while(0) - -BOOL OpenFile(const char *filename); -BOOL CloseFile(void); -void SeekFile(long pos); -BOOL CheckResult(void); -void DeleteOutFile(void); -void PutBuffer(const void *ptr, int len); -void GetBuffer(void *ptr, int len); -void PutByte(u8 c); -void PutHalf(u16 c); -void PutWord(u32 c); -void PutString(const char *str); -void PrintString(const char *fmt, ...); - -#define READ_ALL 0 -int ReadFile(const char *filename, void *filebuffer, int size); -int ReadFileWithPadding(const char *filename, void *filebuffer, int size, int boundary); -BOOL WriteFile(const char *filename, void *buffer, int size); - -char *GetGMTime(const time_t time); -char *GetTime(const time_t time); - -void *Alloc(size_t size); -void Free(void *p); - -typedef struct -{ - char *buffer; - int size; -} -VBuffer; - -#define VBUFFER_INITIAL_SIZE 1024 -void InitVBuffer(VBuffer * vbuf); -void FreeVBuffer(VBuffer * vbuf); -void PutVBuffer(VBuffer * vbuf, char c); -char *GetVBuffer(VBuffer * vbuf); - -char *ChangeBackSlash(char *path); - -u16 CalcCRC16(u16 start, u8 *data, int size); -const char *WrapNull(const char *str); - -typedef struct -{ - u16 address; - u8 align; -} -tROMAddrConvType; - -tROMAddrConvType ConvertHeaderRamAddr( s32 p ); -tROMAddrConvType ConvertHeaderRomOffset( s32 p ); -u16 ConvertHeaderRomOffsetAlign( s32 p, u32 align ); - -typedef union -{ - struct - { - u32 sign:1; - u32 header_hash:1; - u32 arm9_hash:1; - u32 arm7_hash:1; - u32 hash_table_hash:1; - u32 final_hash:1; - u32 header_footer:1; - } - e; - u32 raw; -} -tErrorFlags; - -extern BOOL DebugMode; -extern BOOL PrintMode; -extern char *PubkeyFileName; -void debug_printf(const char *str, ...); -void debug_printf2(const char *str, ...); - -#endif //MISC_H_ diff --git a/build/tools/makenandfirm/out_nandfirm.c b/build/tools/makenandfirm/out_nandfirm.c deleted file mode 100644 index c3ed1210..00000000 --- a/build/tools/makenandfirm/out_nandfirm.c +++ /dev/null @@ -1,981 +0,0 @@ -/*---------------------------------------------------------------------------* - Project: TwlFirm - tools - makenandfirm - File: out_nandfirm.c - - Copyright 2007 Nintendo. All rights reserved. - - These coded instructions, statements, and computer programs contain - proprietary information of Nintendo of America Inc. and/or Nintendo - Company Ltd., and are protected by Federal copyright law. They may - not be disclosed to third parties or copied or duplicated in any form, - in whole or in part, without the prior written consent of Nintendo. - - $Date:: 2007-09-06$ - $Rev$ - $Author$ - *---------------------------------------------------------------------------*/ -#include -#include // atoi() -#include // strcmp() -#include // isprint() -#include // chdir() -#include -#include // UCHAR_MAX -#include -#include // stat() -#include "elf.h" -#include "misc.h" -#include "defval.h" -#include "format_rom.h" -#include "format_nlist.h" -#include "makenandfirm.h" -#include "format_sign.h" -#include "acsign_nand.h" -#include "compress.h" - -#define SDK_ASM - -#include -#include "../acsign/aes2.h" - -#define SBIN9CMD "ARM9_SBIN" -#define SBIN7CMD "ARM7_SBIN" -#define ELF9CMD "ARM9_ELF" -#define ELF7CMD "ARM7_ELF" -#define COMP9CMD "ARM9_COMP" -#define COMP7CMD "ARM7_COMP" -#define DECOMPCMD "DECOMP_PROC" -#define ARM9X2CMD "ARM9_X2" -#define VERCMD "VERSION" -#define RSAKEYCMD "RSA_KEY" -#define OUTKEYCMD "OUT_KEY" -#define WREGCMD "WRAM_RBIN" -#define ENDKEYCMD "ENC_KEYINFO" -#define NCDCMD "NCD_ROMOFS" -#define MIRRORCMD "MIRROR_OFS" -#define ERRCMD "ERROR" - -static BOOL ConstructNandfirmFile(char * specFile); -static BOOL ReadSbinFile(const char *fileName, void* minfo, void* minfo2, void* hash, BOOL comp); -static BOOL ReadKeyFile(const char *fileName); -static BOOL ReadWramRegFile(const char *fileName); -static s32 GetRamAddr(const char *fileName); - -static BOOL EncryptBuffer(char *buffer, int length); - -static BOOL Sbin9_Command(char * line, int num); -static BOOL Sbin7_Command(char * line, int num); -static BOOL Elf9_Command(char * line, int num); -static BOOL Elf7_Command(char * line, int num); -static BOOL Comp9_Command(char * line, int num); -static BOOL Comp7_Command(char * line, int num); -static BOOL Decomp_Command(char * line, int num); -static BOOL ARM9X2_Command(char * line, int num); -static BOOL VERSION_Command(char * line, int num); -static BOOL RSAKEY_Command(char * line, int num); -static BOOL OUTKEY_Command(char * line, int num); -static BOOL WramRegs_Command(char * line, int num); -static BOOL ENCKEY_Command(char * line, int num); -static BOOL NcdOffset_Command(char * line, int num); -static BOOL MirrorOffset_Command(char * line, int num); -static BOOL ERROR_Command(char * line, int num); - -static BOOL InitializeAesKey(void); -static BOOL InitializeNandfirmFile(void); -static BOOL FinalizeNandfirmFile(const char *nandFile); - -static s32 Offset; // Current offset -static int LineNum; // Line number for error message -static const char *specFileName; // specFile name for error message - -NANDHeaderEx nandHeader; // Nandfirm Header Shadow -FIRMSignedContext signedContext; -u8 *keyFileBuf; -BOOL compArm9 = TRUE; -BOOL compArm7 = TRUE; -u32 mirrorOfs = 0; -tErrorFlags errFlags; - -//--------------------------------------------------------------------------- -// Output - nandfirm File -//--------------------------------------------------------------------------- - -BOOL OutputNandfirmFile(const char *specFile, const char *nandFile) -{ - char *buffer; - BOOL state; - - if (ReadFile(specFile, &buffer, READ_ALL) <= 0) - { - return FALSE; - } - - if (!OpenFile(nandFile)) - { - return FALSE; - } - - specFileName = specFile; - - state = InitializeNandfirmFile() && ConstructNandfirmFile(buffer) && - FinalizeNandfirmFile(nandFile) && CloseFile(); - - if (!state) - { - DeleteOutFile(); - } - - return state; -} - - -//--------------------------------------------------------------------------- -// Output - Nandfirm File -//--------------------------------------------------------------------------- - -static const tCommandDesc command[] = { - {SBIN9CMD, Sbin9_Command}, {SBIN7CMD, Sbin7_Command}, - {ELF9CMD, Elf9_Command},{ELF7CMD, Elf7_Command}, - {COMP9CMD, Comp9_Command},{COMP7CMD, Comp7_Command}, - {DECOMPCMD, Decomp_Command}, - {VERCMD, VERSION_Command}, - {ARM9X2CMD, ARM9X2_Command}, - {RSAKEYCMD, RSAKEY_Command}, - {OUTKEYCMD, OUTKEY_Command}, - {WREGCMD, WramRegs_Command}, - {ENDKEYCMD, ENCKEY_Command}, - {NCDCMD, NcdOffset_Command}, - {MIRRORCMD, MirrorOffset_Command}, - {ERRCMD, ERROR_Command}, -}; - -BOOL ConstructNandfirmFile(char * specFile) -{ - char *line; - char *line_top; - char *p; - int i; - - LineNum = 0; - Offset = 0x00000000; - - line = specFile++; - - while (*line != '\0') - { - LineNum++; - - // Get command line - line_top = line; - while (*line != '\0') - { - if (*line++ == '\n') - { - break; - } - } - - // Print for debug - debug_printf("NANDSF Line%4d [", LineNum, line); - for (p = line_top; p != line; p++) - { - if (isprint(*p)) - { - debug_printf("%c", *p); - } - } - debug_printf("]\n"); - - if (*line_top == '#') - { - } - else - { - for (i = 0; i < (sizeof(command) / sizeof(command[0])); i++) - { - if (!strncmp(line_top, command[i].string, strlen(command[i].string))) - { - if (command[i].funcp != NULL) - { - char line_cmd[FILENAME_MAX]; - char line_scan[FILENAME_MAX]; - char* line_conv; - int num; - - num = sscanf( line_top, - "%1024[^ :] : %1024[^ \x0d:#\n]", - line_cmd, line_scan - ); - line_conv = ResolveDefVal(line_scan); - - debug_printf("line_cmd = %s, line_conv = %s\n", line_cmd, line_conv); - - if (!command[i].funcp(line_conv, num - 1)) - return FALSE; - } - } - } - } - - } - return TRUE; -} - - -//--------------------------------------------------------------------------- -// Output - 'WramRegs' Command -//--------------------------------------------------------------------------- - -extern MIHeader_WramRegs wram_regs_init; -MIHeader_WramRegs* wram_regs; - -static BOOL WramRegs_Command(char * line, int num) -{ - if (num != 1) - { - error("Wrong format spec file '%s' line:%d", specFileName, LineNum); - return FALSE; - } - - debug_printf2("wram regs file = %s\n", line); - - return ReadWramRegFile(line); -} - -static BOOL ReadWramRegFile(const char *fileName) -{ - int file_size; - struct stat st; - - if (FILESTATUS_FILE != GetFileStatus(&st, fileName)) - { - error("'%s' is not regular file.", fileName); - return FALSE; - } - - if ((file_size = ReadFile(fileName, &wram_regs, READ_ALL)) < 0) - return FALSE; - - nandHeader.o.h.w = *wram_regs; - nandHeader.m.h.w = *wram_regs; - - return CheckResult(); -} - -//--------------------------------------------------------------------------- -// Output - 'RSAKEY' Command -//--------------------------------------------------------------------------- - -static BOOL RSAKEY_Command(char * line, int num) -{ - if (num != 1) - { - error("Wrong format spec file '%s' line:%d", specFileName, LineNum); - return FALSE; - } - - debug_printf2("rsa key = %s\n", line); - - return ReadKeyFile(line); -} - -static BOOL ReadKeyFile(const char *fileName) -{ - int file_size; - struct stat st; - - if (FILESTATUS_FILE != GetFileStatus(&st, fileName)) - { - error("'%s' is not regular file.", fileName); - return FALSE; - } - - if ((file_size = ReadFile(fileName, &keyFileBuf, READ_ALL)) < 0) - return FALSE; - - return CheckResult(); -} - - -//--------------------------------------------------------------------------- -// Output - 'OUTKEY' Command -//--------------------------------------------------------------------------- - -static BOOL OUTKEY_Command(char * line, int num) -{ - if (num != 1) - { - error("Wrong format spec file '%s' line:%d", specFileName, LineNum); - return FALSE; - } - - debug_printf2("out key = %s\n", line); - - PubkeyFileName = line; - - return CheckResult(); -} - - -//--------------------------------------------------------------------------- -// Output - 'VERSION' Command -//--------------------------------------------------------------------------- - -static u8 ConvToBCD8(int x) -{ - u8 bcd = 0; - - x %= 100; - bcd |= (x / 10)<<4; - bcd |= (x % 10); - - return bcd; -} - -static BOOL VERSION_Command(char * line, int num) -{ - char scan[FILENAME_MAX]; - u64 version = -1; - - // rescan - num = sscanf( line, - "0x%1024[^\x0d\n]", - scan - ); - - if (num == 1) - { - // convert version info - version = strtoull(scan, NULL, 16); - } - else if (num == 0) - { - // generate version info - u8* ver8 = (u8*)&version; - time_t timer; - struct tm *t_st; - - time(&timer); - t_st = localtime(&timer); - - ver8[0] = ConvToBCD8(t_st->tm_min); - ver8[1] = ConvToBCD8(t_st->tm_hour); - ver8[2] = ConvToBCD8(t_st->tm_mday); - ver8[3] = ConvToBCD8(t_st->tm_mon+1); - ver8[4] = ConvToBCD8(t_st->tm_year); - ver8[5] = 0x57; - ver8[6] = 0xff; - ver8[7] = 0xff; - } - - nandHeader.g.d.card_key = version; - - debug_printf2("version = %08llx\n", version); - - return CheckResult(); -} - - -//--------------------------------------------------------------------------- -// Output - 'Decomp' Command -//--------------------------------------------------------------------------- - -static BOOL Decomp_Command(char * line, int num) -{ - char* dbg_str = "ARM7"; - - if (num != 1) - { - error("Wrong format spec file '%s' line:%d", specFileName, LineNum); - return FALSE; - } - - if (!strcmp(line, "ARM9")) - { - nandHeader.o.l.arm9_decomp = TRUE; - nandHeader.m.l.arm9_decomp = TRUE; - dbg_str = "ARM9"; - } - - debug_printf2("decompress processor = %s\n", dbg_str); - - return CheckResult(); -} - - -//--------------------------------------------------------------------------- -// Output - 'ARM9_X2' Command -//--------------------------------------------------------------------------- - -static BOOL ARM9X2_Command(char * line, int num) -{ - char* dbg_str = "FALSE"; - - if (num != 1) - { - error("Wrong format spec file '%s' line:%d", specFileName, LineNum); - return FALSE; - } - - if (!strcmp(line, "TRUE")) - { - nandHeader.o.l.arm9_x2 = TRUE; - nandHeader.m.l.arm9_x2 = TRUE; - dbg_str = "TRUE"; - } - - debug_printf2("arm9 x2 = %s\n", dbg_str); - - return CheckResult(); -} - - -//--------------------------------------------------------------------------- -// Output - 'Comp9' Command -//--------------------------------------------------------------------------- - -static BOOL Comp9_Command(char * line, int num) -{ - char* dbg_str = "FALSE"; - - if (num != 1) - { - error("Wrong format spec file '%s' line:%d", specFileName, LineNum); - return FALSE; - } - - compArm9 = FALSE; - - if (!strcmp(line, "TRUE")) - { - nandHeader.o.l.comp_arm9_boot_area = TRUE; - nandHeader.m.l.comp_arm9_boot_area = TRUE; - compArm9 = TRUE; - dbg_str = "TRUE"; - } - - debug_printf2("arm9 compress = %s\n", dbg_str); - - return CheckResult(); -} - - -//--------------------------------------------------------------------------- -// Output - 'Comp7' Command -//--------------------------------------------------------------------------- - -static BOOL Comp7_Command(char * line, int num) -{ - char* dbg_str = "FALSE"; - - if (num != 1) - { - error("Wrong format spec file '%s' line:%d", specFileName, LineNum); - return FALSE; - } - - compArm7 = FALSE; - - if (!strcmp(line, "TRUE")) - { - nandHeader.o.l.comp_arm7_boot_area = TRUE; - nandHeader.m.l.comp_arm7_boot_area = TRUE; - compArm7 = TRUE; - dbg_str = "TRUE"; - } - - debug_printf2("arm7 compress = %s\n", dbg_str); - - return CheckResult(); -} - - -//--------------------------------------------------------------------------- -// Output - 'Elf9' Command -//--------------------------------------------------------------------------- - -static BOOL Elf9_Command(char * line, int num) -{ - if (num != 1) - { - error("Wrong format spec file '%s' line:%d", specFileName, LineNum); - return FALSE; - } - - debug_printf2("arm9 elf = %s\n", line); - - { - s32 ramAddr = GetRamAddr(line); - nandHeader.o.l.main_ram_address = (void*)ramAddr; - nandHeader.m.l.main_ram_address = (void*)ramAddr; - } - - return CheckResult(); -} - - -//--------------------------------------------------------------------------- -// Output - 'Elf7' Command -//--------------------------------------------------------------------------- - -static BOOL Elf7_Command(char * line, int num) -{ - if (num != 1) - { - error("Wrong format spec file '%s' line:%d", specFileName, LineNum); - return FALSE; - } - - debug_printf2("arm7 elf = %s\n", line); - - { - s32 ramAddr = GetRamAddr(line); - nandHeader.o.l.sub_ram_address = (void*)ramAddr; - nandHeader.m.l.sub_ram_address = (void*)ramAddr; - } - - return CheckResult(); -} - - -static s32 GetRamAddr(const char *fileName) -{ - Elf32_Ehdr *ehdr; - s32 ramAddr; - int file_size; - struct stat st; - - if (FILESTATUS_FILE != GetFileStatus(&st, fileName)) - { - error("'%s' is not regular file.", fileName); - return FALSE; - } - - if ((file_size = ReadFile(fileName, &ehdr, sizeof(Elf32_Ehdr))) < 0) - return FALSE; - - ramAddr = ehdr->e_entry; - - Free(&ehdr); - - debug_printf2("ramaddr = 0x%08x\n", ramAddr); - - return ramAddr; -} - - -//--------------------------------------------------------------------------- -// Output - 'Sbin9' Command -//--------------------------------------------------------------------------- - -static BOOL Sbin9_Command(char * line, int num) -{ - FIRMSignedContext* sc = &signedContext; - - if (num != 1) - { - error("Wrong format spec file '%s' line:%d", specFileName, LineNum); - return FALSE; - } - - debug_printf2("arm9 sbin = %s\n", line); - - // Set ARM9 ROM Offset - if (!Offset) - { - Offset = (sizeof(NANDHeader) + FIRM_ALIGN_MASK) & ~FIRM_ALIGN_MASK; - if (mirrorOfs) - { - Offset += sizeof(NANDHeaderCore) * 2; - } - SeekFile(Offset); - } - debug_printf2("romoffset = %#x\n", Offset); - { - nandHeader.o.l.main_rom_offset = Offset; - nandHeader.m.l.main_rom_offset = Offset + mirrorOfs - sizeof(NANDHeaderCore) * 2; - } - - return ReadSbinFile(line, &nandHeader.o.l.main_rom_offset, &nandHeader.m.l.main_rom_offset, &sc->hash[FIRM_SIGNED_HASH_IDX_ARM9], compArm9); -} - -//--------------------------------------------------------------------------- -// Output - 'Sbin7' Command -//--------------------------------------------------------------------------- - -static BOOL Sbin7_Command(char * line, int num) -{ - FIRMSignedContext* sc = &signedContext; - - if (num != 1) - { - error("Wrong format spec file '%s' line:%d", specFileName, LineNum); - return FALSE; - } - - debug_printf2("arm7 sbin = %s\n", line); - - // Set ARM7 ROM Offset - if (!Offset) - { - Offset = (sizeof(NANDHeader) + FIRM_ALIGN_MASK) & ~FIRM_ALIGN_MASK; - if (mirrorOfs) - { - Offset += sizeof(NANDHeaderCore) * 2; - } - SeekFile(Offset); - } - debug_printf2("romoffset = %#x\n", Offset); - { - nandHeader.o.l.sub_rom_offset = Offset; - nandHeader.m.l.sub_rom_offset = Offset + mirrorOfs - sizeof(NANDHeaderCore) * 2; - } - - return ReadSbinFile(line, &nandHeader.o.l.sub_rom_offset, &nandHeader.m.l.sub_rom_offset, &sc->hash[FIRM_SIGNED_HASH_IDX_ARM7], compArm7); -} - - -static BOOL ReadSbinFile(const char *fileName, void* minfo, void* minfo2, void* hash, BOOL comp) -{ - const NANDHeader_ModuleInfo *m = minfo; - u32 *size = (void*)&m->size; - u32 *orig_size = (void*)&m->decomp_size; - const NANDHeader_ModuleInfo *m2 = minfo2; - u32 *size2 = (void*)&m2->size; - u32 *orig_size2 = (void*)&m2->decomp_size; - char *buffer; - char *file; - int file_size; - struct stat st; - - if (FILESTATUS_FILE != GetFileStatus(&st, fileName)) - { - error("'%s' is not regular file.", fileName); - return FALSE; - } - - if ((file_size = ReadFile(fileName, &file, READ_ALL)) < 0) - return FALSE; - - *orig_size = *orig_size2 = file_size; - - // Digest file image - if (hash) - { - ACSign_DigestUnit(hash, file, file_size); - } - - // Compress file image with fitting region - buffer = Alloc(file_size * 2); - if ( comp ) - { - file_size = LZCompWrite(file, file_size, buffer, FIRM_ALIGN); - } - else - { - memcpy(&buffer[0], file, file_size); - { - u32 pad_size = (FIRM_ALIGN - (file_size % FIRM_ALIGN)) % FIRM_ALIGN; - if (pad_size) - memset(&buffer[file_size], 0, pad_size); - file_size += pad_size; - } - } - Free(&file); - file = buffer; - - if (size) - { - *size = *size2 = file_size; - } - Offset += file_size; - - // Encrypt file image - EncryptBuffer(file, file_size); - - // Output file image with fitting region - PutBuffer(file, file_size); - - Free(&file); - - if (mirrorOfs && mirrorOfs < Offset + sizeof(NANDHeaderCore) * 2) - { - error("mirrorOfs is too small (%ld < %ld).\n", mirrorOfs, Offset + sizeof(NANDHeaderCore) * 2); - return FALSE; - } - - return CheckResult(); -} - -typedef struct -{ - unsigned long e[4]; -} u128; - -static BOOL EncryptBuffer(char *buffer, int length) -{ - const u128 id = {{ AES_IDS_ID2_A, AES_IDS_ID2_B, AES_IDS_ID2_C, AES_IDS_ID2_D }}; - u128 iv = {{ length, -length, ~length, 0 }}; - FIRMSignedContext* sc = &signedContext; - char *buffer2 = Alloc(length); - AES_KEY key; - if (!buffer2) - return FALSE; - AES_SetKey(&key, sc->aes_key, (unsigned char*)&id); - AES_Ctr(&key, buffer2, buffer, length, (unsigned char*)&iv); - memcpy(buffer, buffer2, length); - memset(buffer2, 0, length); - Free(buffer2); - return TRUE; -} - - -//--------------------------------------------------------------------------- -// Output - 'ENC_KEYINFO' Command -//--------------------------------------------------------------------------- - -static BOOL ENCKEY_Command(char * line, int num) -{ - u32 key; - - if (num != 1) - { - error("Wrong format spec file '%s' line:%d", specFileName, LineNum); - return FALSE; - } - - key = strtoul(line, NULL, 0); - nandHeader.g.d.ds_key = key; - - debug_printf2("keyinfo = %#x\n", key); - - return CheckResult(); -} - - -//--------------------------------------------------------------------------- -// Output - 'NcdOffset' Command -//--------------------------------------------------------------------------- - -static BOOL NcdOffset_Command(char * line, int num) -{ - u32 ofs; - - if (num != 1) - { - error("Wrong format spec file '%s' line:%d", specFileName, LineNum); - return FALSE; - } - - ofs = strtoul(line, NULL, 0); - { - nandHeader.g.d.ncd_romAdr = ConvertHeaderRomOffsetAlign(ofs, 8); - } - - debug_printf2("ncd romoffset = %#x\n", ofs); - - return CheckResult(); -} - - -//--------------------------------------------------------------------------- -// Output - 'MirrorOffset' Command -//--------------------------------------------------------------------------- - -static BOOL MirrorOffset_Command(char * line, int num) -{ - if (num != 1) - { - error("Wrong format spec file '%s' line:%d", specFileName, LineNum); - return FALSE; - } - - mirrorOfs = strtoul(line, NULL, 0); - - debug_printf2("mirrored image offset = %#x\n", mirrorOfs); - - return CheckResult(); -} - - -//--------------------------------------------------------------------------- -// Output - 'ERROR' Command -//--------------------------------------------------------------------------- -static char* error_type[] = -{ - "SIGN", - "HEADER_HASH", - "ARM9_HASH", - "ARM7_HASH", - "HASH_TABLE_HASH", - "FINAL_HASH", - "HEADER_FOOTER", -}; - -static BOOL ERROR_Command(char * line, int num) -{ - char* dbg_str = "UNKNOWN"; - int i; - - if (num != 1) - { - error("Wrong format spec file '%s' line:%d", specFileName, LineNum); - return FALSE; - } - - for (i=0; ihash[FIRM_SIGNED_HASH_IDX_HEADER][0] ^= 1; - } - if ( errFlags.e.arm9_hash ) - { - sc->hash[FIRM_SIGNED_HASH_IDX_ARM9][0] ^= 1; - } - if ( errFlags.e.arm7_hash ) - { - sc->hash[FIRM_SIGNED_HASH_IDX_ARM7][0] ^= 1; - } - if ( errFlags.e.hash_table_hash ) - { - sc->hash[FIRM_SIGNED_HASH_IDX_HASH_TABLE][0] ^= 1; - } -} - -static void SetFinalHashError(FIRMSignedContext* sc) -{ - if ( errFlags.e.final_hash ) - { - sc->hash[FIRM_SIGNED_HASH_IDX_FINAL][0] ^= 1; - } -} - -static void SetSignError(NANDHeader* nh) -{ - if ( errFlags.e.sign ) - { - nh->sign.raw[0] ^= 1; - } - -} - -static void SetFooterError(NANDHeader* nh) -{ - if ( errFlags.e.header_footer ) - { - nh->h.reserved_footer[sizeof(nh->h.reserved_footer)-1] ^= 1; - } - -} - -//--------------------------------------------------------------------------- -// Output - Initialize AES Key -//--------------------------------------------------------------------------- -static BOOL InitializeAesKey(void) -{ - FIRMSignedContext* sc = &signedContext; - struct stat specstat; - time_t spectime; - if (stat(specFileName, &specstat) != 0) - return FALSE; - time(&spectime); - memcpy(&sc->aes_key[0], &specstat.st_atime, 4); - memcpy(&sc->aes_key[4], &specstat.st_mtime, 4); - memcpy(&sc->aes_key[8], &specstat.st_ctime, 4); - memcpy(&sc->aes_key[12], &spectime, 4); - ACSign_GetKey(sc->aes_key, sizeof(sc->aes_key), sc->aes_key, sizeof(sc->aes_key)); - return TRUE; -} - - -//--------------------------------------------------------------------------- -// Output - Initialize Nandfirm File -//--------------------------------------------------------------------------- - -static BOOL InitializeNandfirmFile(void) -{ - memset(&signedContext.hash[FIRM_SIGNED_HASH_IDX_HASH_TABLE], 0x00, sizeof(signedContext.hash[0])); - nandHeader.o.h.w = wram_regs_init; - nandHeader.m.h.w = wram_regs_init; - InitializeAesKey(); - return TRUE; -} - - -//--------------------------------------------------------------------------- -// Output - Finalize Nandfirm File -//--------------------------------------------------------------------------- - -static void FinalizeNandfirmFileCore(NANDHeaderCore* master) -{ - NANDHeader *nh = &nandHeader.g; - FIRMSignedContext* sc = &signedContext; - u8* key = keyFileBuf; - - memcpy(&nh->l, &master->l, sizeof(NANDHeaderLow)); - memcpy(&nh->h, &master->h, sizeof(NANDHeaderHigh)); - - ACSign_DigestHeader(&sc->hash[FIRM_SIGNED_HASH_IDX_HEADER], nh); - - SetUnitHashErrors(sc); - - ACSign_DigestUnit(&sc->hash[FIRM_SIGNED_HASH_IDX_FINAL], sc, FIRM_HEADER_2ND_HASH_AREA_LEN); - - SetFinalHashError(sc); - - if (key) - { - ACSign_Final(nh, sc, key); - } - - SetFooterError(nh); - - SetSignError(nh); - - memcpy(&master->sign, &nh->sign, sizeof(FIRMPaddedSign)); -} - -static BOOL FinalizeNandfirmFile(const char *nandFile) -{ - // for m header (copy to g) - FinalizeNandfirmFileCore(&nandHeader.m); - - // for o header (copy to g) - FinalizeNandfirmFileCore(&nandHeader.o); - - // Output file image - SeekFile(0L); - if (mirrorOfs) - { - PutBuffer(&nandHeader, sizeof(nandHeader)); - } - else - { - PutBuffer(&nandHeader.g, sizeof(nandHeader.g)); - } - - // Output public key (modulus) - if (PubkeyFileName) - { - WriteFile(PubkeyFileName, &keyFileBuf[ACS_RSA_PRVMOD_OFFSET], ACS_RSA_PRVMOD_LEN); - } - - return TRUE; -} diff --git a/build/tools/makenandfirm/path.c b/build/tools/makenandfirm/path.c deleted file mode 100644 index eeeb9895..00000000 --- a/build/tools/makenandfirm/path.c +++ /dev/null @@ -1,931 +0,0 @@ -/*---------------------------------------------------------------------------* - Project: NitroSDK - tools - makebanner - File: path.c - - Copyright 2003-2006 Nintendo. All rights reserved. - - These coded instructions, statements, and computer programs contain - proprietary information of Nintendo of America Inc. and/or Nintendo - Company Ltd., and are protected by Federal copyright law. They may - not be disclosed to third parties or copied or duplicated in any form, - in whole or in part, without the prior written consent of Nintendo. - - $Log: path.c,v $ - Revision 1.3 2006/01/18 02:11:20 kitase_hirotake - do-indent - - Revision 1.2 2005/02/28 05:26:13 yosizaki - do-indent. - - Revision 1.1 2004/08/30 08:41:14 yasu - makebanner moves into CVS tree - - $NoKeywords: $ - *---------------------------------------------------------------------------*/ -#include -#include // free() -#include // strcasecmp() -#include // stat() -#include // opendir()/readdir()/closedir() -#include // getcwd() -#ifdef __CYGWIN__ -#include // cygwin_conv_to_win32_path() -#endif -#include "path.h" - -//--------------------------------------------------------------------------- -// Get File Statue -//--------------------------------------------------------------------------- - -tFileStatus GetFileStatus(struct stat *s, const char *filename) -{ - // Get file status - if (stat(filename, s)) - { - error("Can't get status %s", filename); - return FILESTATUS_ERROR; - } - - if (S_ISREG(s->st_mode)) - { - return FILESTATUS_FILE; - } - else if (S_ISDIR(s->st_mode)) - { - return FILESTATUS_DIR; - } - - error("Unknown file type %s", filename); - return FILESTATUS_ERROR; -} - - -//--------------------------------------------------------------------------- -// File Globbing & Dir Listing -//--------------------------------------------------------------------------- - -typedef struct -{ - tCallBack callBack; - void *param; - tWildCard *accept; - tWildCard *reject; - -} -tForeachEntryParam; - - -static BOOL isAcceptEntryName(char *pathName, tWildCard * accept, tWildCard * reject) -{ - char *p = pathName; - - while (*p) - { - if (*p == '/') - pathName = p + 1; - p++; - } - - if (accept) - { - while (accept) - { - if (WildCardCmp(accept->name, pathName)) - { - goto accepted; - } - accept = accept->next; - } - return FALSE; - } - accepted: - - while (reject) - { - if (WildCardCmp(reject->name, pathName)) - { - return FALSE; - } - reject = reject->next; - } - return TRUE; -} - - -static BOOL ForeachEntry_CallBack(char *pathName, void *param) -{ - tForeachEntryParam *t = (tForeachEntryParam *) param; - struct stat fstat; - - if (!isAcceptEntryName(pathName, t->accept, t->reject)) - { - // Reject!!! ignored - return TRUE; - } - - switch (GetFileStatus(&fstat, pathName)) - { - case FILESTATUS_FILE: - return t->callBack(pathName, t->param); - - case FILESTATUS_DIR: - return ForeachDirList(pathName, ForeachEntry_CallBack, param); - - default: - break; - } - return FALSE; -} - - -BOOL ForeachEntry(const char *pathName, tWildCard * reject, tCallBack callBack, void *param) -{ - tForeachEntryParam t; - - t.callBack = callBack; - t.param = param; - t.accept = NULL; - t.reject = reject; - - return ForeachPathGlobbing(pathName, ForeachEntry_CallBack, &t); -} - - -typedef struct -{ - tCallBack callBack; - void *param; - char *baseName; - -} -tForeachFileParam; - - -static BOOL ForeachFile_CallBack(char *pathName, void *param) -{ - tForeachFileParam *t = (tForeachFileParam *) param; - - int len = strlen(t->baseName); - - debug_printf(" ForeachFile_CallBack path[%s] base[%s]\n", pathName, t->baseName); - - if (strncmp(pathName, t->baseName, len)) - { - error("Wildcard in Root is not supported"); - return FALSE; - } - - return t->callBack(pathName + len, t->param); -} - - -BOOL ForeachFile(const char *baseName, const char *fileName, tWildCard * reject, tCallBack callBack, - void *param) -{ - char *cBaseName; - char *cPathName; - BOOL state; - tForeachFileParam t; - - debug_printf("ForeachFile : baseName[%s] fileName[%s]\n", baseName, fileName); - - cBaseName = GetSrcPath(baseName, ""); - cPathName = GetSrcPath(baseName, fileName); - - debug_printf("ForeachFile : cBaseName[%s] cPathName[%s]\n", cBaseName, cPathName); - - t.callBack = callBack; - t.param = param; - t.baseName = cBaseName; - - state = ForeachEntry(cPathName, reject, ForeachFile_CallBack, &t); - - free(cBaseName); - free(cPathName); - - return state; -} - - -//--------------------------------------------------------------------------- -// FilePath Globbing -//--------------------------------------------------------------------------- - -typedef struct -{ - char *baseName; - char *pathName; - tCallBack callBack; - void *param; - -} -tGlobParam; - - -static int CountFile; -static BOOL ForeachPathGlobbing_Entry(tGlobParam * pg); -static BOOL ForeachPathGlobbing_WildCard(char *pathName, void *param); - -BOOL ForeachPathGlobbing(const char *pathName, tCallBack callBack, void *param) -{ - tGlobParam g; - BOOL ret; - - g.baseName = NULL; - g.pathName = PathNormalize(pathName, TRUE); - g.callBack = callBack; - g.param = param; - CountFile = 0; - - debug_printf("PathGlobbing : Name [%s]->[%s]\n", pathName, g.pathName); - - ret = ForeachPathGlobbing_Entry(&g); - - free(g.pathName); - - if (ret && CountFile == 0) - { - error("No file or directory matched %s", pathName); - return FALSE; - } - return ret; -} - - -static BOOL ForeachPathGlobbing_Entry(tGlobParam * pg) -{ - tGlobParam g; - char *entryName; - struct stat s; - BOOL state; - - if (pg->pathName) - { - entryName = PathDup(pg->pathName); - - g = *pg; - g.pathName = PathGetDirLevelDown(pg->pathName); - - if (pg->baseName) - { - g.baseName = Alloc(strlen(pg->baseName) + strlen(entryName) + 2); - sprintf(g.baseName, "%s/%s", pg->baseName, entryName); - } - else - { - g.baseName = strdup(entryName); - } - - // Check if wildcard ? - if (isPathWildCard(entryName)) - { - state = ForeachDirList(pg->baseName, ForeachPathGlobbing_WildCard, &g); - } - else - { - state = ForeachPathGlobbing_Entry(&g); - } - - Free(&entryName); - Free(&g.baseName); - } - else - { - // Check if file exists - if (!stat(pg->baseName, &s)) - { - debug_printf(" File Found [%s]\n", pg->baseName); - - // Globbing done, exec callback - - state = pg->callBack(pg->baseName, pg->param); - CountFile++; - } - else - { - debug_printf(" File Not Found [%s]\n", pg->baseName); - state = TRUE; // Ignored - } - } - return state; -} - - -static BOOL ForeachPathGlobbing_WildCard(char *pathName, void *param) -{ - tGlobParam g; - tGlobParam *pg = (tGlobParam *) param; - - debug_printf(" WildCardCmp: [%s] [%s]\n", pg->baseName, pathName); - - if (WildCardCmp(pg->baseName, pathName)) - { - g = *pg; - g.baseName = pathName; - return ForeachPathGlobbing_Entry(&g); - } - - return TRUE; // Ignored -} - - -//--------------------------------------------------------------------------- -// Directory Listing -// Listing directory & Exec CallBack -//--------------------------------------------------------------------------- - -BOOL ForeachDirList(const char *dirName, tCallBack callBack, void *param) -{ - DIR *dir; - struct dirent *entry; - char *pathName; - BOOL state = TRUE; - - if (!dirName) - { - dirName = "."; - } - - debug_printf("DirectoryList: Name [%s]\n", dirName); - - // Open directory - if (NULL == (dir = opendir(dirName))) - { - error("Can't read directory %s", dirName); - return FALSE; - } - - // Store new files - while (NULL != (entry = readdir(dir))) - { - pathName = entry->d_name; - - if (!strcmp(pathName, ".") || !strcmp(pathName, "..")) - { - continue; - } - - debug_printf(" :%s\n", pathName); - pathName = GetSrcPath(dirName, pathName); - state = callBack(pathName, param); - free(pathName); - - if (!state) - break; - } - - closedir(dir); - return state; -} - - -//--------------------------------------------------------------------------- -// -// PathName Utilities -// -//--------------------------------------------------------------------------- - -//--------------------------------------------------------------------------- -// StrCmp/StrCpy entry name terminated / or \0 -//--------------------------------------------------------------------------- - -int PathCmp(const char *path, const char *cmp) -{ - char c; - - do - { - c = *path; - if (c == '/') - c = '\0'; // end of string if '/' - if (c != *cmp) - return 1; - path++; - cmp++; - } - while (c); - - return 0; -} - - -char *PathCpy(char *dest, const char *src) -{ - while (*src != '\0' && *src != '/') - { - *dest++ = *src++; - } - return dest; // Don't set '\0' -} - - -int PathLen(const char *path) -{ - int n = 0; - - while (*path != '\0' && *path != '/') - { - n++; - path++; - } - return n; -} - - -char *PathDup(const char *src) -{ - int n = PathLen(src); - char *dest = Alloc(n + 2); - - PathCpy(dest, src); - dest[n] = '\0'; - - return dest; -} - - -BOOL WildCardCmp(const char *wildcard, const char *path) -{ - if (*wildcard == '*') - { - if (*path != '\0' && WildCardCmp(wildcard, path + 1)) - return TRUE; - if (WildCardCmp(wildcard + 1, path)) - return TRUE; - } - - else if (*wildcard == '?') - { - return *path != '\0' && WildCardCmp(wildcard + 1, path + 1); - } - - else if (*wildcard == *path) - { - return *path == '\0' || WildCardCmp(wildcard + 1, path + 1); - } - - return FALSE; -} - - -BOOL isPathWildCard(const char *path) -{ - while (*path != '\0' && *path != '/') - { - if (*path == '*' || *path == '?') - { - return TRUE; - } - path++; - } - return FALSE; -} - - -//--------------------------------------------------------------------------- -// Go up/down directory level -//--------------------------------------------------------------------------- - -char *PathGetDirLevelDown(const char *path) -{ - while (*path) - { - if (*path == '/') - return (char *)path + 1; - path++; - } - return NULL; -} - - -//--------------------------------------------------------------------------- -// Get Basename -//--------------------------------------------------------------------------- - -char *GetBaseName(const char *path) -{ - int i; - char *new_path; - - for (i = strlen(path) - 1; i >= 0; i--) - { - if (path[i] == '/') - { - new_path = strdup(path); - new_path[i] = '\0'; - return new_path; - } - if (path[i] == ':') - { - new_path = Alloc(i + 3); - strncpy(new_path, path, i); - strcpy(new_path + i, ":."); - return new_path; - } - } - - new_path = strdup("."); - return new_path; -} - - -//--------------------------------------------------------------------------- -// Get Filename -//--------------------------------------------------------------------------- - -char *GetFileName(const char *path) -{ - int i; - char *new_file; - - for (i = strlen(path) - 1; i >= 0; i--) - { - if (path[i] == '/' || path[i] == ':') - { - new_file = strdup(path + i + 1); - return new_file; - } - } - new_file = strdup(path); - return new_file; -} - - -//--------------------------------------------------------------------------- -// Reconstruct path name -// -// - Resolve '.' or '..' in path name -// - Work around . and / to translate regular form -// -// Regular form of path: -// Absolute Path [Drive:]/.[/Entry...] -// Relative Path [Drive:].[/Entry]... -// -// ex) -// abc/def -> ./abc/def -// /aaa -> /./aaa -// D:/aaa -> D:/./aaa -// / -> /. -// . -> . -// ../aa -> ./../aa -//--------------------------------------------------------------------------- - -char *PathNormalize(const char *pathName, BOOL isTreatDotDot) -{ - int i, level, level_root, n; - BOOL isAbsolute; - const char *entry[DIRLEVEL_MAX]; - - char *pathNormal = Alloc(strlen(pathName) + 4); - const char *p_org; - char *p_new; - - // - // Check if drive letter C: D: E: - // Check if absolute path - // - p_new = pathNormal; - p_org = SkipDriveName(pathName); - n = (int)p_org - (int)pathName; - - if (n > 0) - { - strncpy(p_new, pathName, n); - p_new += n; - } - isAbsolute = isAbsolutePath(p_org); - - // - // Resolve '.' and '..' - // - // Slice the path at point of / , put them into entry[] - // - - level = level_root = 0; - - for (; p_org; p_org = PathGetDirLevelDown(p_org)) - { - if (!PathCmp(p_org, "") || !PathCmp(p_org, ".")) - { - // skip it - continue; - } - else if (!PathCmp(p_org, "..") && isTreatDotDot) - { - if (level > level_root) - { - // Back to parent dir - level--; - continue; - } - - // if pathname starts with '/', no directory to go up - if (isAbsolute) - { - error("Can't go up directory, '..' Ignored. %s", pathName); - continue; - } - - // keep '..' - level_root = level + 1; - } - - // name entry - entry[level] = p_org; - level++; - } - - // Reconstruct pathname - if (isAbsolute) - { - *p_new++ = '/'; - } - *p_new++ = '.'; - - for (i = 0; i < level; i++) - { - *p_new++ = '/'; - p_new = PathCpy(p_new, entry[i]); - } - *p_new = '\0'; - -#if 0 - if (strcmp(pathNormal, pathName)) - { - debug_printf(" PathNormal: [%s] -> [%s]\n", pathName, pathNormal); - } -#endif - return pathNormal; -} - - -//--------------------------------------------------------------------------- -// Get Src Path -// Normalize BASENAME -// Normalize FILENAME -// Concat both -//--------------------------------------------------------------------------- - -char *GetSrcPath(const char *baseName, const char *fileName) -{ - char *base; - char *file; - char *t; - char *path; - - base = PathNormalize(baseName, TRUE); - file = PathNormalize(fileName, TRUE); - t = Alloc(strlen(base) + strlen(file) + 2); - - // Concat base + '/' + file - sprintf(t, "%s/%s", base, file); - path = PathNormalize(t, FALSE); - - free(base); - free(file); - free(t); - - debug_printf(" GetSrcPath: [%s]\n", path); - return path; -} - - -//--------------------------------------------------------------------------- -// Get Dest Path -// Concat BASENAME + FILENAME -// Normalize it -//--------------------------------------------------------------------------- - -char *GetDestPath(const char *baseName, const char *fileName) -{ - char *t; - char *path; - - t = Alloc(strlen(baseName) + strlen(fileName) + 2); - - // Concat base + '/' + file - sprintf(t, "%s/%s", baseName, fileName); - path = PathNormalize(t, TRUE); - - free(t); - - debug_printf(" GetDestPath: [%s]\n", path); - return path; -} - - -//--------------------------------------------------------------------------- -// Remake the path into familier shape -// Delete ./ -//--------------------------------------------------------------------------- - -char *PathDenormalize(char *path) -{ - char *p; - - p = (char *)SkipDriveName(path); - if (*p == '/') - { - p++; - } - - // Cut './' - if (*p == '.' && *(p + 1) == '/') - { - while ('\0' != (*p = *(p + 2))) - { - p++; - } - - if (p == path) - { - - } - } - - - - return path; -} - - -//--------------------------------------------------------------------------- -// Get PC Path -//--------------------------------------------------------------------------- - -char *GetWin32Path(char *cygpath) -{ - static char buffer[FILENAME_MAX]; - -#ifdef __CYGWIN__ - if (*cygpath == '/') - { - cygwin_conv_to_win32_path(cygpath, buffer); - } - else -#endif - { - strcpy(buffer, cygpath); - } - - return ChangeBackSlash(buffer); -} - -char *ChangeWin32Path(char *cygpath) -{ - char *win32path = strdup(GetWin32Path(cygpath)); - - free(cygpath); - return win32path; -} - -//--------------------------------------------------------------------------- -// Change suffix -//--------------------------------------------------------------------------- -char *ChangeSuffix(const char *file, const char *suffix) -{ - int i, n; - char *path; - - n = strlen(file); - - for (i = n; file[i] != '.'; i--) - { - if (file[i] == '/' || i == 0) - { - i = n; - break; - } - } - - path = Alloc(i + strlen(suffix) + 1); - strncpy(path, file, i); - strcpy(path + i, suffix); - - return path; -} - - -//--------------------------------------------------------------------------- -// Get Current Dir -//--------------------------------------------------------------------------- - -char *GetCurrentDirectory(void) -{ - static char buffer[FILENAME_MAX]; - char *cwd; - - cwd = getcwd(buffer, FILENAME_MAX); - if (!cwd) - { - error("Can't access current directory"); - exit(10); - } - return cwd; -} - - -//--------------------------------------------------------------------------- -// Check if absolute path -// -// Return True in case of ... -// -// /dirA/dirB/fileC -// D:/dirA/dirB/fileC -// -// Return False in case of ... -// -// dirX/dirY/fileZ -// D:dirX/dirY/fileZ -//--------------------------------------------------------------------------- - -BOOL isAbsolutePath(const char *path) -{ - const char *p = path; - - while (*p != '\0') - { - if (*p == '/' || *p == '\\') - { - if (p == path || p[-1] == ':') - { - return TRUE; - } - } - p++; - } - return FALSE; -} - -//--------------------------------------------------------------------------- -// Check if drive name -// -// Return next character of ':' if drive name -// Return head of path if no drive name -//--------------------------------------------------------------------------- - -const char *SkipDriveName(const char *path) -{ - const char *p = path; - - while (*p != '\0' && *p != '/' && *p != '\\') - { - if (*p == ':') - { - return p + 1; - } - p++; - } - return path; -} - - -//--------------------------------------------------------------------------- -// App Name Utilities -//--------------------------------------------------------------------------- -static char *appName; -static char *appBaseName; -static char *appFileName; - -void InitAppName(const char *path) -{ - char *slash_path = ChangeBackSlash(strdup(path)); - - appBaseName = GetBaseName(slash_path); - appFileName = GetFileName(slash_path); - appName = ChangeSuffix(appFileName, ""); - - free(slash_path); -} - -char *GetAppName(void) -{ - return appName; -} - -char *GetAppBaseName(void) -{ - return appBaseName; -} - -char *GetAppFileName(void) -{ - return appFileName; -} - - -#ifdef TEST -int main(int argc, char *argv[]) -{ - int i; - char *s; - - for (i = 1; i < argc; i++) - { - s = PathNormalize(argv[i], TRUE); - printf("[%s] -> [%s]\n", argv[i], s); - free(s); - } - return 0; -} -#endif diff --git a/build/tools/makenandfirm/path.h b/build/tools/makenandfirm/path.h deleted file mode 100644 index e9956dc6..00000000 --- a/build/tools/makenandfirm/path.h +++ /dev/null @@ -1,93 +0,0 @@ -/*---------------------------------------------------------------------------* - Project: NitroSDK - tools - makebanner - File: path.h - - Copyright 2003-2006 Nintendo. All rights reserved. - - These coded instructions, statements, and computer programs contain - proprietary information of Nintendo of America Inc. and/or Nintendo - Company Ltd., and are protected by Federal copyright law. They may - not be disclosed to third parties or copied or duplicated in any form, - in whole or in part, without the prior written consent of Nintendo. - - $Log: path.h,v $ - Revision 1.3 2006/01/18 02:11:20 kitase_hirotake - do-indent - - Revision 1.2 2005/02/28 05:26:13 yosizaki - do-indent. - - Revision 1.1 2004/08/30 08:41:14 yasu - makebanner moves into CVS tree - - $NoKeywords: $ - *---------------------------------------------------------------------------*/ -#ifndef PATH_H_ -#define PATH_H_ - -#include // struct tat -#include "misc.h" - -#define DIRLEVEL_MAX 256 -#ifndef FILENAME_MAX -#define FILENAME_MAX 1024 -#endif - -typedef enum -{ - FILESTATUS_ERROR = -1, - FILESTATUS_FILE = 0, - FILESTATUS_DIR = 1 -} -tFileStatus; - - -// Item Reject Control - -typedef struct tWildCard -{ - struct tWildCard *next; - char *name; - -} -tWildCard; - - -// CallBacks - -typedef BOOL (*tCallBack) (char *, void *); - - -// Prototypes - -tFileStatus GetFileStatus(struct stat *s, const char *filename); -BOOL ForeachEntry(const char *pathName, tWildCard * reject, tCallBack callBack, void *param); -BOOL ForeachFile(const char *baseName, const char *fileName, tWildCard * reject, - tCallBack callBack, void *param); -BOOL ForeachPathGlobbing(const char *pathName, tCallBack callBack, void *param); -BOOL ForeachDirList(const char *dirName, tCallBack callBack, void *param); -int PathCmp(const char *path, const char *cmp); -char *PathCpy(char *dest, const char *src); -int PathLen(const char *path); -char *PathDup(const char *src); -char *PathGetDirLevelDown(const char *path); -char *GetBaseName(const char *path); -char *GetFileName(const char *path); -BOOL WildCardCmp(const char *wildcard, const char *path); -BOOL isPathWildCard(const char *path); -char *PathNormalize(const char *pathName, BOOL isTreatDotDot); -char *PathDenormalize(char *path); -char *GetSrcPath(const char *base, const char *file); -char *GetDestPath(const char *base, const char *file); -char *GetWin32Path(char *cygpath); -char *ChangeWin32Path(char *cygpath); -char *ChangeSuffix(const char *file, const char *suffix); -char *GetCurrentDirectory(void); -BOOL isAbsolutePath(const char *path); -const char *SkipDriveName(const char *path); -void InitAppName(const char *path); -char *GetAppName(void); -char *GetAppBaseName(void); -char *GetAppFileName(void); - -#endif //PATH_H_ diff --git a/build/tools/makenandfirm/test/Makefile b/build/tools/makenandfirm/test/Makefile deleted file mode 100644 index 7ed88947..00000000 --- a/build/tools/makenandfirm/test/Makefile +++ /dev/null @@ -1,56 +0,0 @@ -#! make -f -#--------------------------------------------------------------------------- -# Project: TwlFirm - tools - makenandfirm -# File: Makefile -# -# Copyright 2007 Nintendo. All rights reserved. -# -# These coded instructions, statements, and computer programs contain -# proprietary information of Nintendo of America Inc. and/or Nintendo -# Company Ltd., and are protected by Federal copyright law. They may -# not be disclosed to third parties or copied or duplicated in any form, -# in whole or in part, without the prior written consent of Nintendo. -# -# $Date:: $ -# $Rev:$ -# $Author:$ -#--------------------------------------------------------------------------- - -SUBDIRS = wram_rbin \ - -include $(TWLSDK_ROOT)/build/buildtools/commondefs - -MAKENANDFIRM = ../makenandfirm.exe - -MAKEFIRM_ARM9 = ./twl_nandfirm9_print.axf -MAKEFIRM_ARM7 = ./twl_nandfirm7_print.axf -SDEPENDS_BIN += $(MAKEFIRM_ARM9) $(MAKEFIRM_ARM7) -MAKEFIRM_FLAGS += -d -MAKEFIRM_DEFS += -DFIRM_ROOT='$(FIRM_ROOT)' \ - -DMAKEFIRM_ARM9='$(basename $(MAKEFIRM_ARM9))' \ - -DMAKEFIRM_ARM7='$(basename $(MAKEFIRM_ARM7))' \ - -DMAKEFIRM_RSA_PRVKEY='$(MAKEFIRM_RSA_PRVKEY)' \ - -TARGET = test.srl - -%.srl: %.nandsf $(MAKENANDFIRM) - $(MAKENANDFIRM) $(MAKEFIRM_FLAGS) $(MAKEFIRM_DEFS) $< $@ - -.PHONY: build install do-autotest clean clobber - -define ECHO_CURDIR - echo "==== $(CURDIR)"; -endef - -build: - @$(ECHO_CURDIR) - @$(MAKE) $(TARGET) - -install do-autotest: - @$(ECHO_CURDIR) - -clean clobber super-clobber: - @$(ECHO_CURDIR) - -rm -f $(TARGET) *~ - -test-utf16.bsf: icon.nbfc icon.nbfp diff --git a/build/tools/makenandfirm/test/rsa_private.der b/build/tools/makenandfirm/test/rsa_private.der deleted file mode 100644 index 06f5f4ccbac2e2f50ebc312c9d601a422754c370..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 607 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
U4<#z|> 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 V0e$D4tJkd|WOOI~ka7)h{{^{CZ=wJI diff --git a/build/tools/makenandfirm/test/twl_nandfirm9_print.axf b/build/tools/makenandfirm/test/twl_nandfirm9_print.axf deleted file mode 100644 index 3d064b38a5509e8ea9e4ce4cc5302e3f0684d513..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 288636 zcmeFa3w&M0b?-m>oFiEXVQ=}7xQ-LHu}vH>=J;)>lN>*>i44atY`{g5Eg373C7}nH z)Cotn0Tb**5GSFz@b@7lEv0F%AS9u_;a(YNLS4wU18oR}<~%qTBXd(HO;VDZME~z^ z_TJK#Y!aIG^Z$JA=O5Xl*=rta)~s2xX3d(}Teq#KS?M^A34dZ{hVh|Hd>)C*wW8g8y?y{ok4&)-+}!kE)*_4AM80ZK}?eeNE|1a_ZAb!*TkN2 z50@M_l{?>-yELCTzNCN@79Upn2eQT4;1!$|d~vpT32>|`TRarN9{@hU^LTSl>0+KU zv{U8wlw7Z;L}ruUgsyTHGLcn0}1a)(PnAI4S>TuM90H2mU+Sz|^mIyV!) ze_$Xs@4QUBlV@W9`nq#fwB?uwpMaJl@3ZyN#rGRidD>j^M!9j{h5fuGUAE}dT~iRf88d;tnMsc6C^=?p=^SJFoj#u1I!aZYcjm`@ z{M*G?+noik??7Rc`R?l~AJ5JYRc`{kd>27HJp`}ZG37t(A+9DqKs=UsKk+!?eZ-SY zricP5jtAZaJb}2A_+7+p#P25dz&m@)IX~P0TuIq#p06Y=IVNUfm$(wx9TWdyiZX3u z%6_<*I87`X=UEyvmPXNC)-%S;Wtt;Pu_=rbF{vZuNvu zw3Qjv@yABP`TL*WbKv(J_&o=H&w<}_;P)K({}l&*&~`(?*; z$i-K!zG}mYtCnAV`SKM@H(v2a;(0|%_Mtgdg`M+njyY99{8Po5Cr|e6&cu%sRHjgF zPCZm%PGJC{)V(1<@m$)Lm>bsxY z_JQNj{Bk@@Rqf$(n5bB=+rF zd!IacntnYDEz^=djlJFr`Cj+we1-d2+2ypkx72H1fR1dw*L&L9Z51(-nAS&m=%NljO+GhR-W!3x3j9@XgL^W#CsRINd7v=SJ6xKGy}A3t znbNP%J5X>u^SW<4elqrnYyat2*T4GnKeqb<#zy<5Dc?CzsBkAk``V((JXuk0?mroG zt8;pe&CX)$w&v%$C-T};&2_W+1hk%S+NeW+oO@nRM5io5GD_=GOE*}ApiooJSFMT&g^D=E|euzG)@0y37q^wEpWsJK^m!XgL zrw`*l_y^=H4R1`P^AYq9ef-j|2YwNzOQsrZzj8%mkdH;#yz3%=;F_*ttc1;d_0}a`+kUY@pSi-FNL(;0<9I$Jc@Z*?lI=cZ2tY=RG)svzM8Tp?YJPL8kd}l zPK8gx`?&kPLEOwC^jB`&Ta2?Y8;cJ77!?;D)BlSYamx2&JZ`=XzpjB7rg8!J#0O*U zgx?!2?^N&CDo?#1**IGS=P();SNnQBUe}v9J?QTYeS{v>?GNg{syLm^pF`g&+-&|w ztQ{uR%N#V!@lCe8&$E^u6XAYNX?U5c8u7rD!o%6!+Kd7fM%8bp#+djcsKz!UgPP^-h%s)rtX}qJQ6W(c? zhHqn%)xW0)60X{&%_`P9wdtZ`h4aI#gXlGULfQNuBR`~{)Y^$mWnd$yrFs(?!iLbJzA_V4}iP7@XyTciqw-Q-Qx!f zqW|s6<6Tk73Rwnf9K1IO4=Hjbk+!FS=yPz=??UpZ;hgUC|9Oe7ugS#Og%gN(>gYbMY zk?g@w_w?%yzNyh>OP;xYxp0nlm*hg6F}FJ>oZ`71OK>t)FPRiLbHceHA4>`62I-J5 z{&U|wdEp)12j1ML@n7Abb;sgOoCUAO{jIAnc_VpzO(E8UoVW+^BOWZdgyZJ>*bN6u z@m|fnbP=z2<#G4>`2ph;JmVD}#E-d{bXqB%UqM})vYMVueAw%aU%8eyhpzrV~&lX-gxG85_l}| z#l+ZLM>HOn@QmNDQhACiDR;uXmbz<;qnNL;^zB7_eEkmb8^jgFuM@k(CE|;yhmAHV z(R+6xk$q1|G#hhW(PTgR7-hc-&i+c)H`c8F6RGd#zPMysE}30kIG*}`UTs3(k;{m& zDP9(TX3_3A@L68eWs4U9Gd4c{x)47)tS)y3?#~N%-P_~d0WPhb&BV|g^!4X?rKi%j zkAwD@v*q?Ue1Qi)&#Rmlq-WB%$3eA$c5l(;F~^n4r`dFUTaz#ra!GvQ)FCjlPxw-at6bP=5E zZbx>qMdj&Pc?%i$7UBeBQvvTj#7@1*UNm2@u=K6^rnGX+N6LnI%)LpL=IoU@(JUIZR!T2b1~galESi7x>$j&_ zWz^4;l!@Z_Ik0G+0L`xZ0CV?&l2bLIXuKsk#$Zy4{%g)z**5Pf^?H5m0sQ{Scb+is zDKlQC%$6blsq>lZp7dG9&VvE<%j{u%({}B%Jf^)PwEGr$G5Vskn72CjkEH#p$}^TO zAz(vT%-6;ox1E-#Y?Ahg7x={&OzGRuDAOyC+luysAR1+d;P06^+>( zr(Wf#R4#uBbUEzND%5`4p+c4WU`}+XJ)M_SnN3W`YvR&xv0zLurj9L7IrzvpO(=R^ zb{uIFs5?&mG8x&F(i7<-=O>mg*q)UivHf0)ENpUC0Z;S}GPkhfa^URC=0_(-<&vC# zR3x8z{lVGN|LgOAep5Ez{mDDot7yzOIohlK1o>WMacS?HCaiTNce0V@fOq^;>^-3y8nxyyH{-%7T-dUc#zt^y{g~KyurP-HjrK<6-rt_hPl-{M{#0r# z=u^_{c`R=BWGl>b;FDdsmVW#F{1N!H#xhTRNwr zZe@-!sjM(p<`O2AW9;&#F8iqFLV5Pez6!H1XRJ<`z#7dO3ogwg&2#C3AO33Kl-gsi zzFa|iBAv-qwH+*+aJ%y2iIZAh_Lz2B=D-B(%!%@|?8s$GGvSN1_2J86yT<@G z`x4=Gpc$V>z?-$zzVBmQafj&v&z=eJrFsYLB(SY#1~#$y+XkJFlU6~V_}WH$UymKn zKa`RUo|bJh=@9GU*x=b=9`>4N@{~Kdn|hNC_3C;`=i%Gao~lgq%4{4*eno@%JiPVg zxZGs(*QpG!+Rz#4#DJ%?QK|eg=KLIuyLX7T*IB!2SUPYUC)HE!NG>lr~Svl(rB*=N&FRCtmX` z9?h__wyyY1bNC;ai!VPx-V@OMYtG>{ZypAY^`&yZzNEX5C4C>TNiNOppWR*BceI;6 zWQzyDdBEu|CA@fP-;{ewnLd0mNy){Y(jn4&2#?2(=G!Rubz+m;Q~G=MYtKTn@eY>G z@5>f9gL^Z$H>)1$i9YQK%&GCDOE*0PoeuGR#Pqok%E&zUV)V05F?RtJm;|8@P<+ec zUq}(pn3jp}za5`L=x1OoV{P~u>azJ?V@H@&HZS{ZvghlVHgA8a+3YVhxciw`*?cGQ z67sd5(>NZg+g~#2mAQnsvS8>#PkMjpzP|mX{dI>+hs=GYee@+!XG%RhGZ#x)@`UGp z;;+%S9q=R3w!gI4+mD=RKYBYn*ZR7&@W17UpuhWQb3Z}#4iJBtdMdNa>@Q^q54rmb z@)Pgo8Rc*5NZ)B42(3(ZFEXXUT70&^CStS9$+J zjGb7#-|Q2%dym7z4JXe3$7PWR;n>&q+req5; z-jr!bXG*(LnNo(Zn_vueXkT`O#wB6>LU)$(l-0c6Ni1KG_Wd*AHImwozOr>1+#XEm zwd176!nHtsydO{l(Hr_3)(eJ@$<#fiBzj^)P)>XoucaqekoF1s`77-? zfmZ^18do=0tYDqcJru{?J13sX&aQCx%wHDZ2>GHqm#GfzsQ(p=m-M;gEgMUn>I$!W z!h#WX9%pW{`z0&D4O&goY0^^_Lpdhlf*Kgqb~ z6Q^$|><5Q<-zJ`!9R0FuRUR97(*MG)+0u8ov?WQB9r~jB;PuF)dYY64X!N zJ25}_FPp}>_~d4H{mrj5rgh*DZ6=_tns%Vi%G>`$x7oRL!9LqQc|JU4-#F&-BquSx z7$Yw>WnX+Uc%++qIWuwGJ?xj*zX2O)kqn6zOh;(l{`;RX6$#r&%voCn=u8J)3c9%vkX zV*9Ewz+V)sk(#6OgiKYx)-fWD zxvRaNZAZ_a<5_Xjh&0yw;>AIlp6}*aaqWmS^ht3_kf!Huo)vE#ktSKtIwu~8Zmpy0 ztDfGufG+^@T7s(WBWJJ&|qagZ^MhswRb+>c|(kKjT3z{58AAoCj?9rKp4*=*AKc+{erV^Lh5H6!-5XT8`XayZh2_?N zdU-stwz$e1o{yfMk1n`;vCW5v%zN99pugImPV@Y;S<$b#_6p}|p}iqJA^i9MY9Mw1 z8GYp$}@OYC}_ZF^5K$GQur$7D{n^{LLir3Ug6tg|MmI`@|5 z**f=@Qp9$z$=R5fe7YDvjhMmi_7ar8>=!{;&zQWU;35^y05aNIOw;?-Ma%$}ibiu?sd^)AG-H zwZC}G?aSjsI#rd%H5=z^B`$zk2S4Q`*_a7i(RB?t(ghF>?J;Jw^iY1OJwt2 z1!ty|mwuA%C)~Z@mhN$ZT~GV4Y_S<0Dor@X(@&3Jb#aolCy5P2*|?X@?}Y{j-`JyG zhV#MoqQl-}PEv0kL40}s|7iU-r?|t=FFo4B-C)U)@+!dd{+|xn)myk5t@X8!I;ZK6 zNwH@Lc*>eJ$?>4q^LhFrb+M)M`=_#h)N^&_b;sLN@UY$SLm&C3cewOTa5$sFf#g&&&2+N?%PO%*Q6EOHyrffe z6|Mr-IWjWXZ|bzSIapdvns|)QG@m$rF!t7+PgYd&%-K}s9p`29+4FkyuSsvtK14s) z+qTLt$>uK{#~p!7v-!Em(<|_?TxG}f=D&}&dFmDqIZm#O z{YE!3mQTzU{}<0zKa6($wRv=~MvtzxaCMMAVYIREgs|Kgzr1k& z3pki7);|*Rs$XqzUrcwKB>&v;8a#XdDbJ$Awj1zPXX4TFjQ3#q@A2&TxGG=b*{jNO zHtV;i_O*uy^BH&BpTTs;6vDD0ZGT6ZSZs*4Zv$)ppgL!x?a2}4|68Q|*Lijvi>vY* zJcn%wm(GL3yk4Hw-?-=U4vNk;d_P>7=1E|mNH0y9n9XZFkPelJI>m3 zoH=y76rYA4dwh4^N%;A1iDu|EZK9d8VRVe>u7Pg(JBrXc-o?K{zqGeb)UAYWolo8w z(0z^Wxm4)Am~!*I*UL6!@}gDqLhI&uYzWn(jHO*?{$>jEIjeIId=R~~%^Jy?RcU!- zt}i-0_S|jKar1JX^KYB4F*;#>WS=F&mAy-H=R&ig`~}iA(3`3Ab!3J!pz=)i=%`Hg zgzh*xW)-%NshmMSBoCrTZL&YElwA|rE+Gv&NYgn%S&#K!^-qh`n;eW~1-{!#`X}8g zJEo#-Q?4TWsoW2sE!;<`KjY7W|6J+`|8wXzjpt+k&$0o@=bMyG26j|PO9lKNQ(+3D zD$?>t9eI{A&%#^Di2Bgy9iGrf8gbbSd@J&kJmKNLrHltGKT0pK)?(Jp{{57FI8r}D zec5{VMe6rZz9&+DKd@{>7ksjxs8gz;&Ti7GNV9fTAhV)LV>Od}FGxEZ4`PA75f7f5 zgB^n3M7(&D=gD(3@n0&9_zB`9Ax+2->IhkaN4TH-^gL`sc&GK?ui%x{$MAPXAa~Lu z!W;S%q~|nGK>Q9=^?Aw zoLVPkM}61rK_=JAmKr*X0fyc<^g8m9;$vAt)~38o`8Nj!z9_w-`)Q_6?fG}f zP9#s{9B*C0Nj~?Qc%U&--ayhRpx-LdU$4cnQCNdx;)lv|hG=~SDl31!i|uqG32#%_ zS?IA?4*Y4ItLx1D`BI#aAXKCdmN=IzO_wjTFN5Ba?RcY(psznpIyPUwAzikO;jA4U z(Qlx`u&+Cj{AIQ5u#3P69{O_+<>e#MUdUySc+l#LIJ6p5SFrNu!3)xVyNHL4PKQHOBO%e=qT4-XZQ0#AtI}5gTNZ>c1J6 zeqAT~{N({xG6kRAv-5ctI4^*9wT0ZGN1iXKKeE+E_D5wnGq!y~CUNIK|26et*HqeL z{KGy}aUQHb+>@Mc`%slWvk%(a***|I>fVb^*FA}~whzs=pTcL3?cljA7~7BXd_H5R ze8#hKI&IhRth-9|fqO@mPsfmj%J%_(99YlD2=}92!FGVh@L%_*66X0b`r}AWlot>3 zbcYK0nFM|Kk)OBYBpEp;fZ>a5XPYM(VJ))HjB!7AeeAQ95qK$`KpWMP@p@=sEjhLd zS-65{@EluW))(;MrSG8bQo=sMUcw$ins6!MO2TH!zn6aO=6M^>$ilHY;9bBCW*KMN zzAq3TqxFX^A@&H|gXwQ2Xbsv)XeNA&@KHhoK|YKXgzbbz!Zn0#gczZoKpU8_+Pl5V zySDg`(L-hMZ3}J3NK^linK&|0wuv-Dn$BdEW+=Cg`l_ome0k$W5ztlR5`+-f>Ig1$ zo5i)9dLe%N8aD0i@Zf(O#I=BW;hlw$u6I&z##v~X3a(vAbQ*FIXIwc4ENUF%$dBYg z^MDD`pKxC-p(Bw|?h4Rn2j)P|t7<1>wa)h z=XvA$UtaRl!|2Px>6$N#NR<@pWvdQ-5nWNIlcFxwcakg5A9yN`nWg0u~ zdalU4ik>=HT4f$6E$MwV&{vz{$R_(0%G^;q~;yv{AD-T?1le0Ge869N(Myb*G7JIl)6u^stE3r#W78|(duE(I| zh}zo39m<70cR|K=*uae?hrPl7mL5glGaiF{IBx!-ntMRwl8h%joIts;sX(^HFUehn zcnr_5kK+z6M7iLgok1Ki(sXa8jQ8BFAI7~ihm7Rm>r;%?)A03KJ+rnR9mQP-`uGU# z6-AR^jUDUs5#c3o5U-^vvx562jT1uoza*ejeQ>bXFGfD8Uj{wM=k-M|fHj^P*XWo= zWoaU^BtEi_vb>AcNrn`*mo{4&xt6gz$hi(OWv+|sUV&t419{_-F|BoL$YcG^uSMQ8 zcHAW@gHLZOXA_}Ec21P0P|jfBpqx#kFBdZQk~8FmwcnRB$)M&TYlW3Dbf=Xu}vu{X7&A!+|vu~_;t~rgp zn1^o1VLyoP0yVS|{d9eNxV-*jL|(T~pzPS1Kwh=J=^nnuZM+@BH2m|>5VXO(DAn zVbMm$_ImW%kgO>`HkkiF=_}adD| z$v$5?((`=&uduy$(7$Htep&Bgc>Z|fi?sfTADwGXVZTh8F%RCcPd45Q_zGT78-;Rj z70-S64_+w6NsHm{kgp>FTn3x~E(3n+iXk0b&A6_H2PtsA!hJ>QAP?DHg3q7~{H*_z z`sQ->0RFHo1D>PgsC0vyiZeusC_JltNcuhK(`G-Bx(P z`;+_$^C$VZ`McM3_ThMc_d4H3(K`=Envk^}*gQS=;QQgMrF(KFKM(nTu>YJ~Mc%{O4~Klwe*AnK8YHtwIKxrgGob)`|&_6{;@$)@7DneM`lzJrAe z(9uceR0^Gr-SEh>)vvrh%Bv`hN^UKzoyyvtUB#XHXN#k<$Iz{7^UpqbAUEK~IET}o z{<=~OU*WoO-T49b6JrRJDJI?SIlyz!kC%&vO>TD#IJVI39!reMxAuMB$z6q>zo97F z5}8$nSNU!X`T%{qF+R(udBSXX$#-h7=dUU5qA#0Ck5OJaP4!-JHUHKYFA2&s=f*OI z6Io-&vaVNae|a(WC|gDz=MPU-kZ1STyx&vwhVly0v6s%;mBAlF*iYyo93tFD$PykV ze1$N8QnbDqXrRB3Xx)}CRWhJ?Ejpz?VJ}a2b1Y$2*XdU*trxJ+J*+ zd~r6vj8MkdW0Or9-A6v>JG$o@Vy(`-5*By0}e2P7~ z*6p=L{2G+8_p~d2j1R)`_>PXofpU)}`|_c#R9{v8zd@&XAXv8YX>8@0=>Hw)e{bR8 zQayUV7QO#R=>0hB0Qx=euqMPwP|d zG4BypFkjAb(YxG@X6<8t|7z)H$cV%JEC=70?(~1%eV+ZVd=J*Q{KXS)8+=_`{8#8b zhx)<&^GfM>a8ydaT~GX9Eg!PQubb!dU(qxDm%X8R7fWJ8@GkE~ysxEu=w)U#vMnFN zHL{nFNG_N&{WITnxO4|JKjz+(k4^UX;PRtPT)?^8zhk|CFV=q}zff-e?_O85Cf^;xcqmh^J1{J!qCd!#M76?pGl{9`XcN7@5The8@;XQ+A$6p0OX9SI?Fjkq4N4Y$m$w3ZB2u^9thcA;a&7&Xqjh zLaaRW9p@GDXIL3Ob`$XPz&8T_J^D*+jlw=fm%Pj##lD;MRqj&$%zKr!E=POoSc}Y& zQNHiY+N0Dd(_YSLOT~nzu`U~5QK$E9q=WSC@}9AVk6_?CndHymJq6RYR`0tkTT29}{&x3qBEc0aE+bFbzvmhQ-^pEnduuH~^ydb3~cV~uAHOW*eYHSZvOcGh#bnxoyh zp2<(4d#}nRUB0>C?kJ6B&VF|6cXD5%%vE{byU2bD-rZ2tyDKsFviJgzIK8V%vAP|c z6|BysVw`CQ`^~fIGM{$Y<7?$Nd?aQ>bBcF&(spgN`%tq39BT_Y3sU)W;Gx6!+mwbb zf%omKGi#~0L;F;8bFg;Wz37e!(q+mE=aFy6@0id4@9es0_oO?@>cC~!!T`qK)c>>O ztLRqg<)xM;^w+Xc(8@TxJc@T+HJ*;UH1}cg_AF%`^I7_qUAAa8e5lLh;_Ro-#)osz z<4)ZbIn9}vw>M{cST|`SnPgqT?_SQ{%Sqb)9Wiymd!npo+M_Go0dGa})vtm7(YG`P z;XYpVRYv>xuztuNYb)$vzm=B1x>CH=o>Je#)4GLR`|VTDjuUq(l;@a@_Iq{6p&hdm zE_9G5STdqL6*7k(99(DNJ9vljJvM^x_`JlULUfMH4w1j_)RPWeF_O#YKEoPV$|**jSH z7I%cEXe^++o^ilXJjSF)53QBI0srk<>%WDM{jU-Ji1#wL5UwYD3;1sd&k*!}?OJHw zNV?vwZG)C|Ja_So58@c_<61n`l$EdS8-%YDzD8I@Ir+*~60aaECoCi24Cuds^c3-j z2_GW73cQ$jGqK+Hok^REfOqlCupL`RyYqktfaef<%t!enk?%=c#`^E&ZyAgKCS6^c z4i5aZ^6l9??wuF5T!7ER9b0nQD*PS>uB#^Hks!wSx5BB&pa7j0M1E?RJb46chV#e$?pWs50vh{^k88n_gG9@ zZ~nBE3)+vAy_@kbL%yoap_6~X{SuY?UzCeg9V}eT`Oc`iRPLwH^?y76rUd*ONSDR_ zJ-qw3fF}?B7T#SKl>5R6-u+p?JDn+Pi9Il(!eqv7i5P~iXQ>Wr?M(B034Mt^^`BKn>F8y9?(=!|hck8j@!S=a9MLBI z57&sZ>3gji3G=C3bj_FyAIekmUGUu&jWscAXxzh&`2%Rsw*f9D?Gkj2N6;GeeaC-K z7(QTU`rpWLyln9|wJrar!`+@~b{se8ee*|D_YYjzRlm8e>gXE;?0@sveAuej=uFYB zahyZu%YRG1)kpOYdxN_(lA{gWpD>Sj@N*)3jrL(;-Seg2)Q>1Fyw`dp!Fqe#u*QS` zoL_Tqh(3wWQ6Bf=t9YCc-uJ9vPRG(3uS2CWvo{CNseh;xPcO~rygQC>`G0bkwSs#= zj*$+!EP*8;crRWZ{yI0 zo1F_h$GCsHkhDeeC-6R?Ydm}y-jWIA6-Yn1<=RZ#c)8*U_jpb|63u1VxH0;sJ+JP1 zn4DzBeg~#PcPmEsK~M5KugOm$Uq(5+cDO^q9k>eZza95GuL-vHG;Qb^{!P*yxf34k zaL;WCK{(48TfN7NO>TWf%2&F7AH&`e!RKQ0?6-6h$iHlvSoP6jjQfAa?FNt5c+Oww zlW3NG#(7O4p?8jhvI*{9M)T!M(p=Kr^%%U3&DML_>{+~h)LD=HjT|C3dO|Wx=JajI+p>XyF_{<)Ro_H=*rsTI5ASJeF2l>04Kk#=5>-j? zF<+|qj^NwTuQJc_?r#PCGA5o&9qY|=zBwu8JYD3Dgm_R!pE=eWvLnNG53%16zc5Zt zImv83Q_Z`)_WN^j`os8E%4Y-*k_6`9g1!{Chk2xd_8KVruh1Or=LXWbb1i#+kk`T^ z+`N%8tZYL5JiDh}hb_am1%m#L2gi7Dcj^vNP*?9Z8`8cvqCLqNZM}Swa~}1{zArba z+kQJJO4s~g{|sM_>293#Nwm!@X<2Y=inMuvv;(9a8PR4)XC3)^Z|=%S9o>PeA?>e5 z)X{ujz@1`^k8^njo<6|4ilT$FIe7cvi1MMl^e!G4xb|P)dg}a^FFW#`-rr^RFMe&| zCnZPerwu>cJ3&rayBC*O67$)CyCFwZYC-Yc|i z%j$kuwepq6p73({Gad9<8Fxb+?(~8WHEi#he;1{N>X%?sKIdbGJ>t#PH6n3bYXyMNiV9J>41Yf1bOw0&srUAe!whjwYRGMg=a@vgga6+O#oXL~6DFYcSWFZa-r zY@RcTV?R!w$p6^=E@knPBP$wrY{*I{wSAZ@h?k`IJKjIO7I*Q};1@6B+i{-nSAS#_ zwj*acmn%*kKX^eR$+_ZZo}6Lae`F0_TO@4`@FLl?j;A{a0l(pO;FlnMk4>j9$n`bw zyIS>P)T>Bv|5t_S|@d{Q){&8<6IN^v{rJb6`4O!(78hyK7Nn)N@D226|Wx>fkKdZMUo$z#jd7a+dVZPMhH(}nnCoG-9 zAsVMZqt;y65jDt%=F2?RCdsnq3HXjJfR=O3Qt)rcUjlw?&3@0_SC|2x^ewD=ftjGZ zZ)y5JL-;h|AmIQ(_VcF*vY+=8?j+nnxSg<%u$Qoh@P0yuz(Uq9`VFO_^VGE&-&_Gx|*1sb@j{f}@`dt&)H%Zc` zGnSu^qG?%m_X$K-{hO{}P-5E(c&03&>YL?rEakhUw5))%Dd zUD%MmUee}Kw@IVC4;n;ku)zz)3+4=XA{YB6zJWYxP*4{jMJGcD<5+jK5WqU_Lq6l=^<~W4z17d0T<`&U-_$M>iDp zewXm0BVN`zD;~Xzc4ElMDhua|V}WHyUx=Nkwc)R5H|)z3*zYF^Za3ffAS@!J2&)Kb z!e+u2LLH%ju!GP{Xd`qIb`f?HGK77E{RG`9-mE#8VeZwT57EWii)gR^XWHMfPOaoCSB#mm)d_dohU}z)@nER(W!(Jv) zcd+y!Xqlg>$@Wf5&V4n z9it=K^JN+9-QM9+_lNg#))~*m`_j1wy;!apJ1~|!nw!bpg82FDdAzEeVK3o$_Y%i* zQyoM6VD18a4{UUX{CjhHr+UiR2XiJF!zOofQ+fX&F|~)m9MBWk=l~eIfaJ~LEv9rMEv1Y_D?;&Q|9Fw3gdowZ+@4D#m7VsBcPT%{LKlX>cdBt-mGj7(N{M>nrh3A)zyN~9WN0-YMa8jmF@Al^F z%)b1Ae#W5ulf}KXo4KerpM}=$%8b_h+?02*e}n#*Gq$Kb7~|sX;jF;%+*k-ZrU!fa z!GiWI8n@WF*cbWipPC%^*#G{O;so$^r+V^R85h6bymuM)8=h<;AHEdvyG`1gx;MWb zn6&=bx!my_#PeJ+_K_FuU2T=QnzE}YBfRLAN~aGSn*I3M@QddU!S7jD?#uJOY-Mcr z-r}rd2l9W49Y2*Z+B*Sy=;NMXj4ll5!6uj_{FegD9#Fee)mDnOW@~?H?-X1oT*Cbs z@M%oM=foL&#zr^Dxon!gEnhm5&!4t@4te^U_#H<#AjkQT-yzQ7<2H!Tj!Bv|$8kSR z`^a@LPQqi@TgIyU2Gd5u(Xp&L3l7bVm{VPR7rff#G1o6zm*bq}ND8|U-`ykKe+#Wg z4-~WT$RjO|OncnV(Au#WJt29?%+KZ*kL5jFV9(oHm>l!psd$WxFeTHeIaM+{;Y6Md&WMOo8H_#9ebFEU&2=Jk^U=`r4FHkGfZPE zA4hbrhrKRq&V#v_=HB0LDQq+5O6Egl)km41qpon#_>4(DJ9hjS3v zpM%W1@!;>S>&bU9HfPKW`U$(3cU{FD5Wi^)XJmr#_-jG+yYKE2~>u^VRR_&3kp*3(0qN+t@8<{p_pBosAap zoOd$^dH$g0CUbT#vN5PDp!qu570uY*lSI=p;16nULcjEe=BE6CmL_y&ED23sws>%0 z;L35(G;V=U)0_o+Elp!Dgr?N;-0ieC&+INv1qXKjm5#^UU>%&7I#7@+ij&pPlhiTy)9)!`?qwQSB_TfAzOb^pSc=B2Bk1V749(SkY;z{z-d2{!Zl04RpafSszBy_Pfx`c$p4((k5kOg{G1fnwF^8Fu|X(3i=_`tDa= zTyirapZe>i`-b81@0X^F_#Qu{cJuhSc<&Z6*6CaFpTZZ{AJPUtEp6BpXQPcK!}o-J z+MJ`$ok1IYh(mvrmce>D7t;RdhXF0Le>vZ|x3pj{ehS+9PjB{py_^ebZLx4XH6`~< z3frBaHPfN*r#JiSZ?=|oJ$-xbORemc>h8#u*L^OJEKG`_hgn-sIjQjlXsYhxj#*g8 z&QtC4_!~XO&0{mzJGze;uf1TB>|N9Moxjc@e^=^WQViW1PkuGWx!HAP zv?p9;*kRm>61|l=3-xV~N97y6&a{bFgkHV>h99%<064EHpp#IQvQ-|yc&Wj6O_|_ zI84|0nUvN)f9$LcKVr<{@b}A%yT<4)#>j6gTP=Jc9;c7B?r0Uf)VpYPkHNRc#B1Z$ zKZc#fIifxHMBQZP-ozeYvd2BH_IP`8u^)W~USk6#AI&+*Ww<4KbH9K7|DF$4N6((jxYUhxlEiMk-Z#i= z+&5zzoX?1 zoKt7`S+pnrg4#%*b$@1J}pOfaT>oV~tdG?&7dHnhSKhNL1 zAroH`l>a5q&+B<0ZJw>o#BZlFX5hG~sn5h8P&#y;H6?OV+Kq%}S4KOyiP8k>HI=Z6T76P_W2W&g9{$+I%?nPW3?NHxk`8a_BZxoETJP2Yy4lJ)|~Gd1gm zp3}?xXVvk%W$E?nf@1539+#zO&$p@KAEC9Qw!N{Vv2zx9yIMZh(t1max2<*O&ia-H zlj6HN?<9<;98H?(9MmmYvpc{)68^pp?SZVVLrgId9@j9#+mVEf_ayDx4GC{ zVlFka&0I6zEHsyyKQtdSA2v(OGPA;5VOE=um^J2Vv(~IP8_gzjt-0R(k(p@z08{!s zhFc$IrkQ1uW{#O>7MMlma*+D%ZY_4S)j z*-hxGZ@+c-%EqkxOMlEt{WA)I>6r8 zrqJ2Ab8BP!?yI+TDzxhPs@9to{EX#|+jbKy03FF)$uhJUA~1MVvY9_`&g|su3)Q z=Pa6=Trh9$g86e7Ex2q!h++2pIrA4S97Jd428b6fvegVIZ96^|V+1KjiMD-c;0zrJ zVr>#V974<`VF3w{NjVbE_A{$vM@MISXZ=<)tD$jg*NwIHTer41-aH7k*SFl**b#!; z+v|5Wh5&qQ4WFBvS_adbTepSDJL|VaOSN@vZ2`d`ItH)38NrzqlF)JMPLa}iOLJ{Y zYy0-5_MMm2A}TGNW>$M+bNyM;&yuuy!?HET{#vdl`)g}c3nDpd$;J&=*Id11c`b5q zwFwf}Z&P%b zTPX54lwry8%S7o~bM^9#H7jaYuC7_J-fY{^xb0)JY)SvomJ9}O+D?;Nlw5e3elJRz zY4v7WgZ<6Ji2tOI_#YNnmabjb*wNYA-ngu_rL%EY=TOO6TRSv7^_^kakyr=QN8pZt zSFdlXUEO}uvij!ct@YbJwi-EE-O|vw%UI-19jjZKI-Ba7n?ByyFm2(&`AMS+%Ud_L zAUPjfdh4dv_J$y-W+>q-bc9X%)i<=?8Yym@LadrvZmezV>a6u2;oAJm7TDjjgI-3; zY}--aZUT6FQ*(2zO*l)#gFFZyu3lf8?&@4`n^W(G_&GQPTH#t-YPWW6-`?0x_l7Eb zWX-Z+@RIhXjxz?c-g0Eaj`qg-hSd$rTDzDN>h~3mof})aIvN|oEStKnaVK-Drm5v) zE8AOluI*~KMTe z3$DMlgJp(%q|hHGD@7tH!nozkoc7jR&Bu@spT+>=Q2(u9o^=ul7jv$ol`h=c*0`*m z{tWe^wPnT5u4zo~MH+t}fzP_Z33C>~i1ySHJV;1NE0pcpMtDDH?ybVoYHn;t0t_WC zn-lONFb0EMn>E+|_SH-%>tI){*>8*2X3w*~=MVJ_D%F+cO&x8h{1v-G&7;Kijh(|2 zkm@BZ4MEwkWMnYHB#TkY){TwrA>B$#vxGIZc6D4cG*PZu(p=vjOa(E>C+C`#TG9Mc zgZN>VUmA0C(IR-j?|GK`Wp)yWiY*umHMrU;HRQ7~ocn&NO$n`QU;ioNW?E%9n!7rh zZuV!UQl!3CBRiJ5$Vl2%z*jCo=E|n+t?L@M-5gS~!LCGuU{b^AQt3%hoKPJ=+2|HilUgBAIo%vljgmW@<4tbP$8!W3?ac ztiQ2#TU%FCg9(cH86n#AhA38^hgWRfDN0E8XM$+)o39C~`E&|8qap=K-oAZn^T*oG z%w@?s zw(HFtI>$3209Nvw*fBt?O+*B2BEv8zOk?0EZWkQ3LwaV^_>yf;Fw7&TrE8~f*Rt(sY;S=>ev@6z&0&*>HVw?R)XqI)b&SfmiqR2%Lpi@Kt+Va# zxlnAIKC?XvhAU^lgCQQxww;@;&V@{Vy&;rywKOfg39_<5*g zIQh>^q5Ff0gAaZ;wy`6yda+5|4Q-lsf9^JzA#q-_dYB$rzx*S$gIl+n)$2FZuDEJB z3v%s-v^Iy^jS8$^v24TYtFNkEvTnsyOW1MMqGi`@uvvq3*RQ^A#jq5+&6>4*$%ZAh zHgEW}u7%vL?O33-4Z~|`M;56SDpOQ`duQ$T7QQqJL04b1VqMLWYipOUzGB57$xXE@ zyIQtwXl&ofjug!yYrwZ6wM{a$4YlZEXx^ZCJ6{XM%>lc4upY z)HG}M_U8JI9jYGe?^d@U!|h#dogHt7#OG4Dc2HARf=`iIzhSxP@HJgcW6O=5J4|iY z+&Q%kO*hy2Tn|}0%d%wY`t^2bq66l$_^dg$&g$i6{WZ(f&a!pO@LPx@0L!u9wpkID8jnxpEJ1o!NNQQYbP-{0_6G#Zp>2QZ;S+V}w^^%ZfAJMoo_*YzI$=Foi z)CtqtEwHhrO?!bRxF^Q6-?UtNeZS4YZOd60>&ufBKjz@p&emJDVJB^CZMj)^RyPlKLe14w+1AN+qjqO~+cLlRekF~{nbX7{ODkf2rfB2b z8sd>tcvyc|T;ICA(>Lff_Dl*1mbJ5^eTni)$^{#1o7R@vVSFCZ zv*DV-q&K7Pg6)f}dfDq&wRW!9+17dMFfx4}TM9#!qrOPtu)d)+v6;7jXMX!AW@xV>edZS%ktL$q3TLt9lnN>9UJUTv`B1h2~jU) zrruI-Jx6qL(2ume9@9|r>u>JE4b$qD^|v&2Zrc$kI-#8~)sp7sHC?b)y_C!Z`$#*1hCE`vlxRvKCX{5OE5RC4*3va>fLAu%1YdS` zG_&t%X>4cJ+$P6QEd+Mp*=7B2ZfsH1vaL;ON!5n7!CC``yGw@2#Z?>EEXCg$P4iVX zvvr6j)}YSDZ8{{{NOzznuvUz(vsexgA(n%);ITp<>Z4#X2U^NkE77I{(e`y_Lwm>B z=B>ZHGIN=otLmGF%lXhUGdLuxhbxK=oA}~6RhKv2jE9M?G98DdWXV)xku5aN~ z0VB;H5wxC+YAGo{r5TMC%m^!j!*&Ld`AT(}okRZEk;L7?-o!3A!fTCzb&WT1Kq^~c zO?`*t^-N1UqP*9vu3djieVaYeIFk~)G6$MNX2Z5t=DS@G2DRHTE0xyd9OwLC{jEE< zwo006uUUUpWDhiGb`382Rv99H))Hz6?WAB*`esQm-F>rkguWjd8diLyK*uTAvGQLJ zA8|D}Yfug$OoQ&5PZ2FJDByu`s@%G@zEu^}x$5e5wx9Oi!bl<4YO*XXCJZ~hinOp^ zPAF@Jf-gD;hZOJ1dX65pwYJ?VGn#cQ@E=hgVG!9?u`$B~ieycM3r8>nI$g2r{P0r} zJ8eO5%?S7IFvMugP?DE&V%6Ffwqu(e^zb!-r`GoghQ^faLRq`pSpsV9g$-;01gC!F zVAwemuDqd4_&Q3dNTs@|c7y3Wv>8#K2aSkeXX>j8gJzc!5b;AQauo+9+}s$hB?p>`XRF;y2GbD zOb~V9X!+*0oxQ%TEuXR-0^icxRR6KYuC~EtA9sl^@U#SKFO6=L)X;;GM+G7>Xm-dq z;2YJpiQ&UrbKS5NQ2MO1wT<;B@Hf;5-LQk($SC@ZRGr4oO-zZUsBM)8q|0`#UZ%5d zjBTB?`ufjq(UzU zJ3HKdj=-7mLmD2(0@Y*$B+L4yHK*>tfey5&RznJ~?`b-W2eGNPA-Jya=qzF)Hs7i$9x* z6WmK9vM}FDHZMi+-2l8VQokNJ+wGT+bN@}3Y;y3Q$mmX7GqLWz2^RiVV%>)e;dUN$ zM=pfBcz7`a?*i66xiFvaIT+oY3t_(XU>=IV-N1(;@IK(G2z)27?%EMqdOk($M(8`J zj0oHV$lpjFEdN>HTm=3+@bL)zC%}CX__;_n;8Iq2s*78d>maUc0a7XB4+Zv@taQvEQW%W!69 z1TF^_zA*nBVE#tmAY29f%}Dt%z>6X<-`X_CBjqOmiyp~^==}h&`Xl_3pIN}2<1=x| zq4HC}yZL*{;e1{RybCx+zW7rE+y?B|Pw*BB<25c5*WEAG-wN!3Z$kig06zz;^2)y% zSnY-ItwH$^-VH2#A$%L~fe5?@xFG`T-tFQDydStC0^be%BKI>xe4hq>I0D}ToQc4P zfOVfUEdPZ74*T;k@bdQ#<^Lt{YmxT;8hBm=eiYb5;KzXLLd1PgZ8HazXUA3DSG}8xZwisc?R$%;Hvix$-^$-?6e{N{V{NJ1m>^Rn?(`0 z8+b+p-Un91r~op_;FzIKZL&l zEPQn&i2vUK7Qdv=1nWM$+FupGzW^3}&j#=qFx?;F=UCt!5qJXdvEa{ z2>d?apG5dI1^9^wJPo)m0>2-4Q3SpS*p2Y_65zKY{7eGRi@IG4a_oATx*8)$D0h4W{A3J%HyoB<6caR^h2loTlP4~----m(6N8m33 zKOEuTmw~g9{D*m|>-hX@8Ub%_UaPp#| z{*(bvj=&YbogWy=KNq-X#t=MO^&@aK@XYrQ<&Ot85q$3k-VnjZhuO^jNd5P!egyWE z553{|Pgng2z8S#FBk;w*4H0-2@O||EeIU?!IS;re(*HE@i{w`Y`PTryLjBO5_!w}G zeA(5ie-rQ%z@fc;3-C`a9_sJMfg2+5CxFutI0G#F>W}1eFK}}Nz61E#2t5aY4@Btw zGVq(^PYvk#OJMht{Eg`VeiZnnnM3#=2R_EXqVD)Ew0RIwL^Z^>pPp1ri180D>UXB4i6rq1A@Z>v&b}}%t-nF9>BscemxDGjP&Opfad{^C13n|4ftdP z-|N8RdB;WdMPGkVU$F4~3-HWH{*Qt6PE1(-r@&jz&BP~=AbEDm(f5)31aM6R9wiuh zGPZoVc`xuQmk#0cfS-uKQ-PZ!@P)wX2)+*hznL7WKNI++Ncl^Fdn521)sMjQfmcQN zxio;)KlT3#;GabBUkPkx54E=jI1z!2G^`LH&uq zZlwODz%NGRcLDH8`XAC$11$Q4U+rHFtp0`YI^ghKCgpDgerf(t{$}7l_!pMH9$5Sg z;TwPx5x5>${0#FOR6YXV2(12v`5y%qe?oXCu=*RqZNM6@5bgjLe?$0YVExVW5WW>S z8-aHNXCm-zz;zLL53v4LdRYH9lFz;v@cs5|(+cfa8fMXv0J%AteDJ7C@suh;3n3z&DqpTInl`uZ{8m%RG^67bbt{!aqF!h`v6 z!A`(PF6Dim{EWAcAIf_Xu*Bcj@E-y5&bgug2{7-Y8~87PZ&~i(S4l_t4E^tbS$_ln z6EN#z;1C}QGf!~v1i(AI^6~!fVoyIa0pA8XrrT2fBLUw680rytHsBk*^t_yWy$9o+ zzF@-XF24nU6JGrn0iNpB_XNO0Uj0r6{GeCA4+DN_iIcY!@YP=ZY5-F|v-S5u9I&~= zPkpZe{F>K(=K!XDIS!NlF~HQ%4j2UC3jr6r@{a(X?ZFoVp5(!o0=~tAcLILYgFgkB zKgRyQ0Js|ZCXV)h17OAzAk6%~3i#SH9Q-xFF^~T{fcazOeIGDm5D>@o_XB?TOb7o2 z@RCige?0`4aR-Kwg8YvIUhdJK0Xzq=S>JsQFk|6DUDE!409-(MO#ZI{UJbgj_i^~J z8T9DW0Iva^1*CsE1Tf?2n*KKnFk|bQ^zQ`R0od5v9Kh>5`2BzxXJLu1?+Jjr0LL`E z95CZ83>kX>yxJ>I8~M}te$ezj!0SBvX26W+Yw{lk%-FuB{FgAjNB<;X#%nDBi?0WVLv^5T8y z;36;m>wtfc{EpS~_kkfzgFMcUnBNq@)DQP*XrFilUi7g`!$$$W)|2->z^s3lrk@D- zGK0{A|_ z7lBUxGc;`Y&jMWE<@i&8V}Luf{Iwc3{AUBcrPuLy1HKLLF3q3Uu;K3qd~V+HZv;FD znEGUS&IdfJ;L5i}(@pvdHQm4?fUgJt-RLh&e<|Q~{c3%J@TWB0@L#Fv2L3GITfjdR z21)*FG;HYC0lsr!aQw4c{*4+o^qT=+{ZVDVO#clH8~Po9Z}IHmmw*{F#n68Rc$Wu1 z$@CbH)`8(|koO#5em`@*PxuwUcfcN*ep)akm|UTx59R}= z?ed5G)j~J$zQG#69Pg`vqWm7fv=7BUA^2#7e{yg+;Mer`#&pd0uLpdQEzgADyMVdB z#{N7V@*V;_7wgfS@00&&z_eE*|2e?i|3S4>{Qw7puS44`@4mtG1K{t_J_??Ihmj%g zJSYDcz}ydF9a;X90Q>1z0$$?ruOYnx_JJIvzJU3?K>ZQE05IDdAo9mcm*fw)t3!Cd z;LC(<`6dPT0G7fEeRA*%z=!DX1Ey!tTdr?onk@4F0+{>R)Ccq9M4J2E2A&R>``HFQ z3NZJ(4g5a9+#g(s^la}F02e%c*8+CsIXE~I@Jsr8hUGaM@R45mHUj4UHrtEk*#dY8 z+Ust>Y_FYwU48crz6O}{@5P$`9>86*Re6~HVZfZP8+&~=l77G7Z-5yW3CTsj6Hqbw zKf`|@VDtUL@*d5KZ!`P{1jidXDoOjQ27I-(KfD-9e%oG?gMPrrp+3qUCk7Ws==%lN z3d}Uh-o6Fc$(s`VB*H&A_`T2#|AgRGzzaS5LZM`T<2bNTA2R^ce=7MCf+GOSH#q(` z4e?^$2Y6Snqc323_zS~-D*5#f`@>qm=KGZT=>yF3BF6r=MEEBMUjRIW@>M_v^>riQ zyFLBi3)t_!j{xR+VLmr31IFoRRc?X zGy$f+CKt=!%Jg1&dYIn!ul<4x0WbFSdl~70OMgA-ST8m8{~F-;d-nZ3z*oaQP5=89 zV2;08NMU(?&-CD*4Ve0Q4RFHCZyXK)o$SF=0oR9v<8RdI-vyZGA800&HxDr9*A*IG z1bDV*f31MIUTXZ!dcfDie%FAX{q20f=4TpWMO_Y<`%@y^%=P}|8vZ6=o>#e0 z!#@Pf?|0Uh_4zqq?w_0f^(VlbU+mQU`-8ym1+I5e{tUqUo``997GR$LS*hXo0Oo$R z;XehiI7iT@q5RE&&5zhCVD3K|{R{%;eDr!SF~9AA`Mq!CT?&}vH)YU1t_1AtVc*~z zfcbrI=>I{wXK%j+%=w3*zfi=#4;J!Y^ZelfT-et?)6g;B4Ve3t)E~>Y1n>mUo=ye) zXV3nVfStdX7~}xI5|2klvcQf!5ILbBrxWy0q>rsIH`Pk8bpXhb6J`x{r$edt$?||o7L&R z2l!d9eI5b)pa=h!>Gco&&1-;P@%s0HIH1Y%l^21B<$VWWp06?Gp9k3G|F)nJFwY+p zH2)f=_wvgFj(O$Z2$<(R&3L~9FwZZsSj_Kcz})Ym{Sp2SV5hHxf=2-}{ue|JnEmBN;b$7Q*8#yl0dsws{f+VtI2_~gjKT5eA_MXt0oeSo|1BcjYtIh>_U9v2 zfS;x?{IEZ*1kCdR#$K|3xu0a_0~Y}{KQbQ%%>CX3kSxz_fSo_Y_qy<7z6dAB@;w0f zC5-oj;Aedw2h8)di*@?n0p@wR4#4DpiRtb9Z(=b12#jawFUGzO0qoCb-V2!LSL(IA z69FIK*>4?Su7{cSZwAcu=K;-s24J4wxL(8EfO&p#mxeb24m^3A0Q3CQTuuKRVD3LJ z)bMS9dH&;B4gUb}i=KTx0+{DNCO|*b-){hOKM!w<3;Y+rG1$W_4Ud}@_1}{LXZ89! z^?4XzXV3cvA0X`Y&lA1?sx+t1~IdH&nz=W~Fshkm*shV63`V4e?P|Db(- z8!*pzoA%$u^d9^qVDrQN@@K%yJ^%4KVD3j$fQj-a;@}O>`>oUPA%N$2`g$*5o)@Us z^eVtS?>Ixlt$^!2`E7uY@!IQrz!T8^=W71#fU7QIp~5$X?+>O=d)u^=_BnB%x@jMtx@7$LNg)JX z5Ka#dI*^oU6RReUpLF!3Bfz~GQGPnv~XF9{D0 zDQAb22QO1W-uOwxToxV*ZoJEDbDc7A{{yGuTX!dT$nnW=oR)WaI14ibmaQIZjm1CL z0HNm76D|nH(GtyV19Eob(#ZSUgN8KjWNt|3*5@m#K2Y`E_f{atN(BPV2304nMtnp5 zCK(G6*PGMHw$%F7ZGD-pj@3FsqWS;(vW$hXngME8qn)HA{k;giv?(9R`Lwh!#3j~7_2Ge1;8sq>&hJ03$Pu6gk zrZ3TOwmq3en5~71tJ(z1tf9VlZKhpAwecnu+Ow`&W1x^) z>SHUqsA{<_p|tW4`cHsMeMU33`ENm+;JPj^oFf-Oql*Uy-I4C;?N(^?M?vR#!CDw+ z0<%AwjOh{IAg!>Rdk{-Lg+}4n^e*?okaGSh)jBM8xo!$;CWr46v-F=wu}PAebLk=v5NunG>+*19n(&uFNoVX3QD& z@3dfD%;?S6X35*In7lEcd)_M!BFJPZk<$2${(4lRiAlY^yBS%IwpC*uLaM;7mBA>eCvQZ4I7L-93X`W zc}d%1)+;dVMPN*gdl9H{qrzgC2wIUYo9m@p){_gi&zZm?z5}8qOLBfywFAXqrV29z z%y)q4#z-=tP!|IAfI+E{C6agt@U$}&xP5&B*Zc*$)5k9DEg`^Dx}CP8IeI1 zo0;8=hCwIqR~Q!Y8^DOcpayJPQv*q7q_b+n;h{&1M@lp+Kcvp zcK~C008K=TQR$R?_3u_0OcsNEi_8(NtN*DKf&VteC4ey~+ygHiA$oze$!N=_E}YOR@fS#%qYcv#&wmh>m#{9AP ze%>CEXA{ecp~Q4>Ov_P7=lLj$t8@?4Qke04GNg^Q-}^T_#c{wiH;9>4ZfL0#OOJ zEg@qKpcR(^FcXhB{w{6$vnka~3#dEpAbt|%h&HqeUU)f}w}s^3zQVN;u1LT$F8H9m z$e{;xOb8goeyZ_)8W|o31|_*5ryrE&Bq5ECK`xs@?rCse zWLH_Pc|pB!k%PMnMB+g2mtq67W^7Loflafv002;RjQJd^Xd= z$TVZ!A)X5!SM3ce=gs`ca}D@NqYvFjuYWvtI9!X?Sb!@AOaX7rL1an6T=Eo(NCoE=D$i{gZzrTg%{2qr78rCM5gzv&_ zAvt)m;FR$3fJ&l|qz9?)C6j*j;$pCF56Qy%fn_CYjw&i7PbUD`N@P~!E>^e|?Fa_Q zxjgY7h5+4XTRK#1L531UDOdu=duY|A(8GXNgjb~qr0XKYY!QgOQe`JdW<}i98t00D zoR|w&p3l=cx%x)J#SG$;b9+dplI)1Qv8cwx-CCx`=L26{Rs13 zQivC&5acK+1d(?Y)tR{a%GH_qu$w-v^Kx~LK2EX&yVl!7a_Rh5SshDKC0p8_IwtNH z3fJm%yghsZcwOlgrkPRck?_|p{{%v6iWy4x34$+TtZ{yYh2?g`xg9Vp{J^isDstyo zdzBj|yclG#cg?Yr=Lu=~v{n}%X(S|1pXT8iIEM>4)2U^Utsz<^;DX2&d>vY}StC&^C2#EC9U-rYM;w+}pkXhj1MBV6 z(|D*qIB8}O=yzb?qkfCBHN_=}TRfe^vZ;Q11O-LvbHIy&a&ml`Obu-|G@ZQ5bqI{@ z^m+C8L(6Ne;)^z0C7r4<0%#-q*B&}(qQW8~`2D4}NmXvvG2r0VR*qHQXFkZ$U*)M$2&N_XYkr-z;V1s>o zNS14uEDTy`4o+G&c9}w}+(O6A?zt4~vCS5DzF{8x<5faqt2Q#_B7Dhg4@sV(^MS9> z7?BJ+!7Y{^jXGR0tx_h=P64AHBf(BBrwe>$=8BPdm7^AMoi#{8Ir(g!ZSp!1f2N32EQnJTMOebBwA*YnEdc za1S`Hgggue+?^h-9q?+v$EkG9SsgTUBs>FHV=s8AM42f{=Mu+qsg4Xk)jZq^EQGXY zWNIA2pS~f}fx!L|Tnio&SPRr*h@}5!SDvaJ9Z>UCkz%acLYFJ5fjl}T;{`x3CL5iA z#m;xkF;nMxz}0EanN$siOH5JREQQ9!AVcS$3lgdL`jMrmv7M!qEMdi(o2u|KUrn+l zjzHP`-j$Uti>}3F3*UZ4SbXi{=tnUYVHG9#U{pfo(x&DF9uO_&ZfUHpsm0@<#dw5+ z#iO72*%VSKJc&0HtQM2iy-u&IyU>nXE67bw-mADG%5B!n9s4)HzAYr{h4{TO%C5t% z);adSf_-~v*l6!+eHK|VJ&(>k5|vSsr57%D{yUgC6Y&no^U;JQnR^Kbk#IZK*p(_G z#h@e_&q3kp;6~_9>j|M=5!+KeukjV64xYoWGdTc}ADA41YvvF%b`LhU7aNCeH%!hy z45CChv~AB8$Ob45AiUFVF)zjp%LlpFO4w`=S9W%Cgo`5a;^)$CZY7hm&xq*9U%|^* zigZ<_a<0dbsNpTD#;9sR7Wl`!rXyiu@;S=Cat@DUP$h5ZDVEn~qn*IQle_#Xg;+SVjg5vJo_B2 zNdnp)s}$EY&!t`<2B z9|8y~QC#7ss3k^}4a8o=5DX~^MUm!}l>TFtl)E*Pd(2Uq4AcGr7?t^VI%=s_rH5oT zZ&uaqCk>bL&vDx?{8q{#jWS2|DZ<@we#Xl~2nt2VJODP?rLh?>G4_>Yp+34Na4&e> zmJz>g?gvJ83D8|A$xr4l(+`EmfgAc%OYyecIcQrQ($U{X6#7XZOZI>5Hx}!`nFF@i z^=1>+U4qXbjTA&gbKLy`Fs`tez)7ks9)sxBdt9?M4vrV6NvLcjF(1Ef2l*0UZA++D z;kE)cw()N%`(2KGNLH=QK8b8o+nVzuG?Q;kr#o!d!@iYj7rGdss(fdz}-Y1H3JjF11aCrnXC ztHgy~R-JgwAh-sIOT$8M@D-JvUq&(yhw5L2XGWVsjuH&~_=oTuGxe6`ON^sM@6Y}> zBy0=G%fOK*jyosVhIYi5Ed1qOrcJ$@qc=G}t~g`L356mqrn&ynyfpuVY4ab2`C zf%=Z8 zF{_vG`xpo`6{GXI(wBE1mW;^wxE5;b`UH^AC?xBO;oxy#o>Leca75!W6GrX)Yf(mJ zAMX9|ds!#4{-HRl*MNLkA)8fJe+TBT3UiudCBaK^!T0d-(K=aoW8%tx6WQPx1K3_y z>078KHSTG`J~a0*SfO2yr5%MtQxq*B$5>$R0rKR*_k_+@HJzMN(&?T;hTB5&RKIg@ z{6kT`NXYxIV$|3kl4H8cWu;d3_V8yw9;%QnJXixhqE1vO90ORZF-sI?1-yLwdW|#R z&NBrm8!#%lAy(QuKA3qImYM%(+l566_C4D*Vd|l$a;lLu)dH^$&7NkW>o3HmqZ{LnpIkyS>Ok2 zJ1{FX#yjFL61IVGmL^0E02wkf9@F12YKBR9QU=dHzl@AW!i`|;(1k9MMoGMsG;?A^ ziII@~tKUzBkmGD6rq%eolYqHQ2UWYw^lsuJ%I8l zWHb_H!Evq;N)=3kH$f zwvdcn_&rC9*A>;Dq3+>}$G|-j7F;0`YKl1$<{d7kbl*Y26nZs&hogek2e^}qGtZEF zk&|KNjyRkzmol%%?>!)UErT;-%JFz_8;wBr_K=LNbfZW?)yM&j)uv{sM}{m(vT z!JC`gKLHYc@Y$!2V~qKC->{sf_y5J}II`!(t}F4)?$wfO_U6>``Ix$G4?hEjeK?8p z&WmghuX3OIr}d;aWa&6R=Wxxy<+E%h=CKC94}(Y-Xu62^I@5P0A2LiS$_MG0mTDS@ zE@X2UY=te33KM)B);(& zU|GH@-9txJ^6;fpi*^7n(>s1Nw}I;+iN# zQXE5Pd{L8hOJD+t2Iqr9atgdoB;MqbH}lXsXP`{WP}9GPq%VFev=8Ywh2-P4?eHdbM)!RYlNGeY?dQ;&&~Ja9!7%Tgh-=GOM3sHBjLf~d}?ia4{iF!mx_kM3S@+@ zQzc)`8SS^2{d$h`6u6)#f!(612O0BgD|5M&J{dU!Sbkjts}@j% zcc#YTTNN)~$r&KQ^J|pcI5LPACGjvJKhGK$mXvTfoPwOxXHD=+Byx*SRQqwq4vxR( zYe3_N%Hz?>F<0HN99LA|Z7vA2h08pdDnKrMDa{tl3rC}d1Z z4EnYBo_AGawRrV5bssAxRm1(Qp41+y_J(`#hW z8mn~?Y-@96gFI=A-J4PZ3KHyF9xnxCFYvN$s9edj?#3cZKeyGIDb6d!FxRGg>c$IK zyj{hmRG>9NOkOTP5wEZ2*gH3yLK*d$hBvf6 z0>*72nRu7^1~7j1csrEAfpXLok$79|+u+?ElIO-ns3To6=TY|oVP;p@Jdx!&JaIM> ze$OM|c)1}UKjtN|9L7BsTvI+jNO)E9n*km#Kcr?#MoKsxlmQk*T~EL?#+0=71eTO^ zFQr0!1=+Fa7{*a0NTVcnrmphRP>!77#d@3aUsLmOs_M>LdqmMPY8JPk>Xn zO(>!${JThw2iWu&z<%+4V5GXZKh?n;(m+^Iel9ygjt(LU{}-2|zkJB92+V`N2&ce_ z)W=hpPwPos4TbxIfnk|a#84e)8hnizvp6!f1G^3a)X;=d{RE{_7r*p18Jd*oxh!(< zG=81)rLFK@c>YnK@qpVN6(_!>#S6-F% z{NRuev44|O91r$^vsu36jH3PmwQv<-B^U(hf#;C-?~|JMlSe|brZg+x%;2zDj~2`bMwUqa+@d0qcR`XTzn^jTr~sc zi)T1o2wLf4JoV?_20McijP<*oup=A<-uBS4S7<1zJv;A%iftYEiOJh*)|jdb2K!_^ z*enuZ_>c;oLzW$Uah*P*8vsh~3a$>eQ__}@gFLL8jrs(BpN(2KhbpV<;9VakE7|y{ z#@n?~!Sl;nvE?)RYZi90@=cC2ir6s_R`ztD`((RP8;wf0ND{L1S&xCDB(PgoiCe(B zEhHO_@kd3hTCQV%3G5@`F0je$OWk)1IFEIfO;z|mGPdAK&K|7#jgKvZayLuPWt;2D z>z2UR56Jao{@KqL!#9Tp%bVK#o7jM_Fu6jr_KX4Z*_Tz(QD}U^y%nV%39H6Grp~~k zJMtY9-N*E^>59%_jNO&*rjQ=PeV$BjUw(!9=7=)!aTGGGsD-D&1I+v?Q5;{cRAOcu z4%x(0-%#fCc}8Vi^kMZ3QergH-&7pq`l_%iDOcNu!{{=pA+mIvg;WVK9ckFQV&dqW0ZLZMMD$ExdVz7%34XEB zTK)aQ3XQ`Vf=pg-(#_Vm_Eb+h787M+zdrFv z=jATBRA|8dX|4w}_I1}_b#Wu?lN>-}O|lQqx>{Jx%JqE%@=%^?2mfDOwa|vVvvdNk zt8ood2P&2~{sd1w#($i)N~};Yx2ATP zTXE*@bMfgNT6bNZepEQ&KUrix;ximP=}$cz%l2w|HnOm0cW5@_X8AeO+hZ4Le*)(1 zA(?1}oP~F!3Mu?`Gr)0FiRelG@cx0G)O`#L8)NR?hQb80YKk|>jSo98F?)V{;XUxR zeOPc&9f74LwlmewOP_E8U0DB=9>L-tT#IwdnOtFAhv_*JfL#qN4wSBMw4Ls7V7Yy5 zu=VMlwPq8W{iqu$cm^Hkf|T%Poj@ZsKkRl{O|1NvK z6zCGsm$yFwxg+66z$ar!7{u{08T3KUZtb{zU1pEVGO)DCFkObGX6!Qa&m}_!JwfVo+Ynn_S9IVBv?~TGAF9WyNLE%m^}~<2Z;KG~>rzm7rd4ttggf}@?B+Qx+!FG0Kvde`KjxQmsP=sin$$5eur*dTG ze|I@bOA_}(ESUMNOPpz<`6}r|jY=+XqKpB|_i+E^L`exnJPd`W1aXay;C`yb4265X za@U=RajMA-t=%bef>OSrBsVN6_W?2S(#uGl9S zzEYoHDCK;Dp_TdsLvcP~6f-IE`jfU;(?Ds z1Uu^)n{N#__ZSLiAZG-S(Bkz4Lu-bAjLG+CLn@~uXP7CMjIhGSkIUdR|JvdfBq|Z9 zW^25fvL&3(Bqg^kgZqGGGpMf!PDdH<{nQGS5I^{eK-iIP%)b!M3oEu`vkLE2u_gJJW71tj{U)l3%^O{?6QgX)Q}_~n3>?7^@$2frIxwzlH9sctlO4!N2(33i zrG_LEJWE!ZN5W%*{vgYb4a}JNmMKoWx37;E5dCp2^nEZ0ssW_UHif2W3z5uJIJUA* zrpv*#l*30!T~$~Oh6KIv{jMsVnX&k&E3L|Bu=&JZ%c?BLKaoDpDmyi!HAU=xB-xP+1e# zcd(cS8@{$xg9>nCwTKo{+V;HKm87>IlNM@l$4i?R59^PU&z(L?=EkS_X zY0~<yw$#@L|13jouBlofN&hh_u_2aN6}%QDH#Q}!D(mZ)R#u&wtZ7U% zuL}MS27JWR%P{cqIo{eF+loD(Dhozh`R)EykoC9wS-cN<6JWjEzPga#>C{(xb)0`sklH3 z^k11LZ|AZoI1~hkQwcX%umFrdJ$EV9k43Re5=Yd=V1J`KI_gD@y`e5CCqmd$lQ1vI z`r^=_=PjDI2p{S!Q4w;!_RfYA0*)5}<0%50Ke{^S1n;pr1uqPw6}4KLLTIt)SJ5!Y zupEC;XYD-r6#N;#PA}96--YR|wR-93-qX>ay;xH!Qp>P}ARd;;tJ^}8>EYwuIxtIL z=*=S3Qt-^_EIEm$ub@a+Lm0u;>?eaHsH{yE@Y?~WH4L7ro&vG6TuNu(!Glnpt2gV+ z_st$zW$T@0EX_U4gZ5?{*Hyj9^`VM2E2|qSmo2SNuBxw2R;{Y4ufY(_A8G$G)Ok|b z(Wvu59XD#)g`kcfmAV+z38PZ6Q^Cp3Xc;3M5-+HaM&@1}hWF9P^X4=2Nu$znB^30@ zqtZV(kJ;}xDt+FmAWs>UJfGyLqmmbry#J`=#UvjvDtX=_(hnS!j{DM;E%gcTU^2Ty zVoKZZnZy`3K~mff^L(TJ-iCd z1FrTfi76QGp_-c}f}N=oFmw+m2K{FuucQt#TeU9Lg98(JjW5RfoBRk+qI=iTLBVrR zxF5@HZ1ggTSc?;B-$4Dghvd>dy(N`v)0h=!pg0&OH+FH1Jl64eefk%ugX`1akNm*L z!zm=!4sfFb2jlk8x8Jx|+YweEL(v^G<^Y_@FYU|gjZV&gST7U;-b>g_6XFX=AxzsL zs)XINVZ*(Y#L}s`b70%-pf%oxESu{vAUNdV6oKCL<&Mv0jb-2>Hsl8(tf4NmY$a4L z3#)ldEMEcAe0sRsm-{1WWM4Eope<7q)H=+Nl2uKZq*d3&E0@;SAQ63737PQ$nwMAB z*Xlv8grPOo7bjUA(b6-n^hw*uH@+aK8)xMEI(&^9D|Xkgtc4J#@ZPw2VCs-imy=E=OYyi zf)^me)rO7a|DeGTlq3BXOt^|p`*p(LGw8`!W&83W%ZvX>svp%PMKnuhN7EvT-cj+14DGt+1Gx-N*jM1l|EGatu8+7a&d z)4*LCV&0YwJ}-aD>9cI`B>+gmEn?rj4u@YWBjg7@^Us8V30*GF`3x@$16MR0!z5J3 zW;X-CB{FGq4DWUf!G3#c?)Fsft#G((k|KvI>sPL&St*WqNfTSy>|i1MPKUko&1OG5 zExtKv{VdwLoW?Y=Ns1MK>ty;33 zYS!SLb>*iiU6D6ypa!Tbq7yJZNzU~YnvF(cLap#qG@j9R^kG@Hgy`BExwvA|kK7sR zNOTR2{yX%4a@Ip_o>hMs$7%uq>5IZf)*Rjn)z@p7S2Ex53Nvw7JMQ z49EjeDx(X%HJDMiVY|KaS9pOY|Wv!Kk>PmO&-5*A{P&Culc>QKw36TX>owu{lh-DNr zKV?@TUJ_{n)OG_@NIfOcZd~@3dB6^djbh8e#;(n!&r!J>K}Il(%$AQurovO! zC-vGYK8S_2PATGEnG$cybo6eBA!M4=->6feaiGd6;Z{_!{&cl9r?vqk1-}-k6dnbfB^cwm^wk0uaaax?s(*vakd{SJTUMM+{vN;8XVVm9(#)CB9_;ZA zu5fG$O*YYQJ+*6ddKdD25mj=fVu_aHA;otWRH=INxLG;|WkSfkp7mw}3LlKGjb9Ud z50_|omy8cb<3JZV5FM){+1bM-T5|A{jU0U1Q_(xHvxi0P9xgYL;{nLvuFu2Z=qn5oBJg#2#6XNCk{A(i zzE#P1L{s_J_u6!UuM}v?Gn&Fzs#UtB^`~mujB}Jsz95ZMkm+d4G>xy*D_Xry71tEL z%cmq7N>)?&f}o;Z?ytn)ljVo zPiX=lAxoeiR zW2z&UG;PE7B^%#e_Sy35GM$Aa!!r89_6~1 z5=M(24u1q&HIaoM!QVq+1v;5nt#U}P*dT*acXrBIVFdBjg9XQ0ZpMPZLmZhl#m}LZ z?hfcq?qVqH;U2aF``-#X3)qh;*`4x*D}Js5*lQJ5-jBl2YVz75$3pd#&kiHZuB&&0 zl4<BmRs{c1_LIp!ETB>9vHeww_wG-M*ydA7nAvnB|#U5SeutvnXUK5&mnn`0qP;>Am zOFpgF#%O&+bQ6O?@Ey4zSRqcFPFn17Q^@h;CH!^;%9~@Q;!M*w&c?nG=V8hzKZoSF zQ4QW#@tXrbYg(2co+o&Bo(mvkV;L}lU7F3!<%tWX4(9XeUQH^OBYa)35)w9rWSxZH z^Y&E0dGmtpNP#%W;GTxxp*<8434SVtBx6w_nSLgIw;R$Zg@laPrI=){!0(Pxi<#}i z7xi%k)`^UB@p~nh#l9eYMSWEgwU!Y|MU^5)48NZTmr*sjl)v8wN!vrxw1h-EE6)UL z@cU&DXv%CKorr_M-I9t#ok}12M*s{Y8pQ8Spq1p7tPlQMQj#jF!pd?x^J9{$@q4=y zX{r)S1jqGpEAkFUQz4X@;12xW?WDOx$g5qF-Rr1Kwkc$iUHJX6lV_4qZD@-TB-|E~ z=SBQJ0KSr{fa_jxZ4XI}sE$cq!|yLaC{-QO{X^1`T&z4Mo3&sN8)s#5Ox7dqqJHK{ zdPIFpv>3m?b3#p(VysX%l8uDFcT}Z7CW+zqB`41%ll-oegnx2$m5_<9!tXypFsi}A zWReekWP=x_kfi+s&JCs`5wHpCLdQB_1&G`V2@@6$j-MVnDcXMZT&aEot4lgO1tqOO zz+W!p5~YQ;v~#9+kV9Bor0f`e-{oj$qHpL@UM8|ho2+EZUgpt`SC^6!?#A!QpqRSa z{v$KGKZzvL4^)y`bt#F`rCcGUJjEeeFlMKy1E( zuqVMMQHbp!xer#koel<#(e`$RjQk_v7BC&5m`>w_c~EBoMXr(=3vlN<+)63qc@EKv z>-_$!(yx`Bi(1|cV#n;K;QdtQ=(r|=`2#l^J6Xv0xRi!daQ zLYlW&B6yT;zemN-PcCA{<#L{%TqrqX3eBmEq~k@Or5ka5+>2a5v!@2lJetbjLI?s> zP#ZHpR+=_=4QW_(^_4Dvc>hSd?#+qPz4=gAMk1$5G0(mm+1MszDWxY?c64x=%1z`x z@Nc|JhW%nJap0|Fy>odr5-$OzkSTPf-Q}|zfu^Xna)}k^aU_FVfTiVi;{oQJTb{WU zXm-6!o+f2iZN9G2-H7#s_|T4Un>70a>7b*X)30$b_O1tZEcL6Vj@9pU8N<%yv@;9a-^@{OU1ol#O z*@D1d_)!nzsq?H;6k@#Pkk(eqO02%VdcFh0qTe7?uD;fKHwcdcc421k1LoJjaQUJj zFP3c%^MJ)NGYMd%-*1&hW<1m_>^PjfGu2Qy8-EKgS-E}$DS8>1Y>%IZ%qdnhgO&^a z35?ws5iC0bn;Ht{HCMrLT0h}@&hyP7f@#3)2Mj)x70V2rtk-)Za;C<)??iq*PNN`m z*r5UlabD?mzO1ceL3v_8ZFZ0SUBDcIbh2f}mSS}y6@?0(L0!ydmfPxn6HGF=vgX>IAccuyJE1f@M>$+T=`Ab}P`~wcS^)ZNttIhSd&S0%Z$@ z>K2*d=)hx^?S)uhS6350L4;wV$mRNJnI2`@#CAVu;8>_bG@#yhmc_yyvP5mmJv11- z_XXiWh*JA^!H8qcvCNJ>AoXB*h(dd`$%AG@?4xd^8Cr*W#;ZnmO`=1mFjheyJAJCC znAOGa2K~<#s7OO&RrAuVgy276BQ%rU`Tzb*+aBf!7|(OP@558ks~h=Oy!zDDZGD-p zj@9nHXwUo0*#;GUC)SXWS5~X^=@PLIYZ>tiin~3XK|ipOKmg|gA-DBmZ_jSRvVKFU zOss!^t91D!3oQB17iz9Pou;3B(r9non_H3sNk@s6TmUy!FN7oFH+c3 z2RGxYMvsS_4dkUnVoA%fo(wF9@(f>3kcY2D!V;iWcG+~Q;M`EP#+&lBOY{awvK*u@ zLO!;?RWHZaE`l`ii5_#B2P(S&Dp*msG=q+wPfG)+XQPfao5N!A`Khuc}( zY;7W}Du0ie_ZJ2l`er~=3ffmG2hH;0eGaLQ;GUAq+p zzC=#^UK(Nr54(Ky{`ebb-wL4VF?Ki{1aOfs4u=<&O$63234u+>3hU_nj{#mhbvM?M5sE%<{R>&bhg2v>-;X6GJzbcly+UJf5x2kM*9bcYPe{)K7 zE@+pAeCts58cDE4B`_o>LPeq0S|gS!U9z{^?R-EZVEr&dQWZO6DeXEEaQ<%@Acz6E(_nm+UR%!pU#N z!viR{qU2^4&nX>iSCTdS4qb|xo1t~-F)8g~FzbEW(Y`z@)t6_v4^KlX{q8iB($7vq zF<+g*KT)vJ-CZh;xP95o9)|b5`MQIo)#}?$y?lYoMA46b^L46J%NCity?A)1&Jw^D z&+3Oq94GE$vK{Uk#*5E7kKu3;5}9736I0HmAtwr(ky?L#BSo|NVz@ZO-^u2hIL<#K zD5rn@r<9OPG`G~q47gmfWNl@AyhgMfAunx-uaa;72)3@izGhiveKJ;wOKdfGsa>ut zMOe&@qo!tT_Hs$UD^XqJipu&roY!w^XsE=!HQI5MLCfbNZc7{o-;3zAl?mjI`%I8d zeMb_Pjq+J^BIzlpGtDNr1b_7L_`LeF-}}3{W*LVzM|6mO^bNWMHN6;*zluL(PQFNI z@DeiU?>k`;GT@(DMk&mvoyb5|_3f*KE4%MUha9~JbPgoD3j_1#@1YCq#SFJ|V71I_ zFN+@Fs{459rwmWPCFjm{T|puAA{JXk5Lk?o5tr^xA-qr}J0VwpiBgBR158QBfc6>+ z1GT6V6iZFpso9&zRyW$0kc)O`%EM8lMKCjkkY){L!T9#1`2`EcQuDL@>dw66U)KCw zePqjNUN?oQViMa4qE}9FRNLqz9N7dhUnk+rMIm&O3X9N500(!VuwHZi3ZOLS;)`{2 zE?9u(jMPtr?%9g|$LazbVflW9qHj^B&{St+IW2-53PCf+XZBqDYc2GjJN^%8GE`ZD{-QJl%%2FVE95DvS)% z+pT8iYZ=xs;E$y`)-X(T5>s<)OAC!qV@r!ILd)Q1q!b-q!RjctGh$pj0g7==xXc*W zLKxQ)B(+II#=qb~{x4G@43uiw42@X>HP&Gf4=V_$6eqBHdm)z)OoafpNFvV}E)KLV1{ZNzqYV9@x|cW*G>2SH%cQfmeJ|7nqkY z3wtQ=*bU_>&T0~OyLf%`u5fpXT04Nfqrw;j;#;d{a62Rrpl#Z_KZR*1Zp84=H=1zp zat8Y1^O{(2Dq`j5V^@2J-jt(WiD}cD8#D~U2oI+$#e9S!OziOrLt~L|(6nxw{Tw3J zRq%E?$kpDJtLxUn&DrF(wKW3;$4WESc}DOsWWi%UHfhQ?!^7D!9^xU3WSft8$^gHS z4;|g0bi_Cv&{`6o#?Zy+roMK;7_2b6)?+;2#g=&3K4OX5_e>z}&}R_)aYH+4^Z zTW_I&2mb`eKF*H`{{{qA%CA{TI+t>BN>)BfPeE#2Y^;}6RI`J_&8fwgLNtEJ@Y zsmRN{#bpZK3u_zQO!C-ol_6ajV_|R2o4Lp`qnQO1dId7%^#URiYGCh&2Pt5h)&nmP!nNKIv zcV)CJYEgxyLzJi7#@eFNKt}KoN|Vp5MG&Yy^E#?=IBhuA-<0F+B5N@83H|;KG_9Y- zV@2J99_^p3>*R8h!y9kIz1F2Xbbxbvn?ow9Tp87Nv)Ygz&$6nM43d0WMYhU{ zF7>!YF75!q0xJY!%)DNTP@7}XPSP;aKu@|$pGdhMw2vT>ccbuV$XAtH`6u=Sk(_f@3 z#$i6>s<8YVC03+bEFB|9LzkE0ren1DY^KnzPtlmq2`X2Lrr0@E;YWpN28SCFdEeLq z2NFl}Cm{3=(jWzS*Hp^>c8$yTp&iUA_9KC$_x3WZ(5M_D)N?mT5<@jg(|q|V>FH%a(ZZ)1Juu8vQ(Cv#KMo(kE zigcwxIf65hqinjP0=+p0F4_hH?#CE`Q7-aoT%HT#B=+O4p^(M}Vf98a0E2m`t2Y6q z{i^1IONbf+Etn)@ArMV9Yk@=J%oU&}a#CGpK|8^%99{tsoay%Yti7B$PP3_rp>U1Y zD6iWgb5}U}Ar{`xQf75N>8+7-jT zJ0G*5EGUd21>@f6K`n2zrx~A#k|uRYE5Q9-9WyJG z@)t;^18fe3OCSg75;C~Ikru~p(z02yxwU4RVywis ziKw0EF`kA(Z!1GgvJGcbRaV>pWm$>wrx7$E;Wr~3=LAH+(%j&0KANNEX9j;^bz?lo zerAPRi+1|PwL;>&A(&GEq9Q{zri_A&jLTf4A*bsi2LZ!EVuIL{$5Avr5_1|MjM7|o znsaaj?as|`O^1_|l0lh$h<+XCNR{?XZ}3}FQ7XX7@mtJNI^}F&8Zc9Bv-65M8iVy0 zmFPGi;$Yzb%sHl+`=bw|a267Z~-&UV?uiN1i-VJV6r22AXjoqUJP+GozEEHN}L)Do2yWnrm>Np+=}wK$NP4YMyFgLfMO$ zVwEj%C4kB*5^!pr%9&k1N{ZE2u0n8OIZmNZLqLV*d<0HzFp8?8vRR{v8(I=IibbD= z@RK4&W>XbTOCY3}8NhYqU!P0oPuBY6ippjk2Dl8%vihc_nup&M(UK??CF&Y*AcUq` zOoiqZasN_cO`;`cN|=n{d00B4A^}mJ_%afH38jL zIeKM14g=|E!hRlRBBbg(#=UN{?O6rluln5P2ALyh_$eD)YnucaD3*l5)N3wsiq|uZn#K5OJjuL zh!Tc)0`080YGA`^)`*~P#e&p>zsc67=2HWH`9;gA&j?k*w%L*C!$)OUTG@CiqP6da zqqTBHO;Az7(OgprHRCB`sI#uIwkdcASl~3NHnh0*FV1aFzeTU9$ymWIeg^!ZahmjJ zhk}FWwcx?Ob8|$lD* zUP`35va|-JeIB^AUA=9ot`(_VMvj(4*VjVr(Ryr^M{Ct!!UF5hk1ry*-Ta&lw3M6l zM?vW~A_ZFkECq1HlBG&45I_vkoOoz4C5YgdJ+`QN`KF$n`L7NpOG>l4N8WD*3H1PuDm1c+FIgo0OGP?UgGl9id=Yah; zNMQusz3p>p^Q}@8d$?L(6fN108Saazb;4RM6ViIZqaswUt2)||R+}_%f0EDnyi94$ z{M=0B`C+D1N~aOKO%^P5pMYLJ3r!W3&Q5x2diph^@`p8zE0UFo1ZD`3WLzMTYWRRH zYR5@jyai)4UUjF^UGioO29+2nIiG>|qY)u@^;P~xRg>j+_h`D2C1J#pYOpuss3B_2 z`{1QUs5D=Zo+WC%`KFkpEq)71jFx&xw!ndtkJV^TV4mI=8ud|}C$-^l`U{Q5V876o z+7C4IHOCLMX1B~+w*AX|`j{#^voICLa=*I^!#WS#Zrv+uy%|?GBQ-4fk`F5O*vYsi z@D_HmI&2n3HzTQ5w`NZhB?h%;j6>bPY?8Kb5{qLCtm-%bsH&A_mm`TOTB|$s4u1ib zjm8X0SKCdy`Cq%H(Y&u+(`_SPyQa}1U%RH=xW8b z>qhu!Hvlpf-rrFO(FezM-verR6%VTj{Vfc0UgYU9-GRsy-ezTo>7e?h=&fHd;3DocJ34(L_(tSF= z3ZVW96dvZts&sRKdHr7d3DEW(TR_#%RcYNGIoN|%ln=|<{YnCT6)|S(p7rrk4TqFD z9JT{Jgcrz3#0iac*wj?%De(}LT!Mqyi3xQe5(Q(l;&NrD*@fXn_At+JIuIOGmDIRd z;G_Cv!Bk{b0HbtnE}GBLJZ=f?IFrigoN5v=knCwCnH0YwM7t<}oH&^wd)wBZ30M$u18?FcXLfF9uURU(+G0k4!w}yvL0Dlws z7eY{W%nBV|F8{D^`^c)w#wyGgtM$zp3HAJKgtDwAAq3kR zCX=REO(RQPi_S&N|CEyTEivO%Bn=& z3aky4rmL%l-Z@c@N^6Ou3e|yHv-HZw%X3(xqyLL0P}wt$TCDWa=%p!Hp+rArrRXPh zfRLiAQ}4oPz~gAHj~9UH$Y3dfQt@AMg~dd%mLpojrmYh6Er)Fh)CwWIlLO#)yAtcxftNfqOpt*x=;Dr zs3tmr6?Yp&?*uxZPOqnutY>^uONb!TKae%5j%>gb(&;2YRWE%We13WEwj_8=WiMaVQtA4`1U!Re1``q|}pzB2tYhnZqhyV6{n$=EU+{Hi@p9y{eII7bcIuZmdBb0A(##|9V zLbVCrCQ+s2e2rGe2~LuFm9ozO_HPiZVxn#i|69t3veigciq0L@On|g9R{k zfHv+z&T5i|y(sl6r5d@8(jGU(c zV$MByT%oW|T2zG>Et+ZkFX<`18@dG;sFssSs$)20xr(guoiKj{z>8WV5Kiw@6J3Qo zq2$nXz(ngNML}Kd>lk&&*swWV3tDYF6GxzF_FJ_cVZJ1&COb{7ZA?V0%Ho3EZCG8>-x!rK_w?1riA)>?XT2pIbvZ-JE@2c21s z-}4i57+&EjKztcE|BT&i;9f@+#LH<5`uLBfOR7TZKEt$DFtuVf4`?WlLnv17l33V7 zSJG#kXll~AKyV*_#^JZ+^B$JY@EHin%W+ozqcWo-jN%!GUeWlWPWi?^%gX&Mjl@^J zJR*Vkf-K-n^(45V%4aR{DC6evcg5A!r~A#NnCDQi;qVXmR|OG@o-apWMt+UpMb@Tf z|7F=?ynbC)EpRooW~#BslRZLh0w? z&obhMg)kgm3v%fe&3AxBod)c`!Rz?b*({@V-iP11K`0nM?L6s%b+Lgl@NDf_wJe6{ zF!*Ls|85JJJt^)7yHBumrui8Nott zU%Nh{ZG16qW@S2fC>)k>(oYeQBqocdMN<);eHzf0ziChcSND3)z|g3CY+a9Dr<$q> z8+CH_R5EUiBxgVMu}qEJAVcz{|c$}(t&fYIBwJ2M7%SEG%q;t}D|r08z@t_QhHWsZ`uRtG(V?qx!p ziHBud%>J3fGK!24*cQi;UH0~2**2UcTjf1S(utU9&U4Py7%PA-a}kjEm`QTJ2X)Ov zflMitV*^yr5;CrARZC~9!%#@&basX;@Xqi^O$ zkU$q*i7Ok|hEg>_R;TEOBJ8E1X_$9}#S2XXM-!zLho)gmL=qeM*hgh(8cfuqbU!o= z%`lRfs@NCEh>KNf@tv;Kcbt0|_~K$58Z9Ya*$}I*Yh0F0tcukn7cZ^Dga|(>n<#PK zd{Ui;qSScZvPPWG5eZI3WqFh!r>iKFQ1Q%qJr5<(BAm{mj5@~>ey77IKea^_V)n=Z z8ckn`3pmPG*eS=!Fd(;;$gF8nFyc;gorB$m^MTU2hC8Fre!`C~IlJi}jHCnG_hHq6 zT*N`iot=hxv2P{ynVR=WxO5%}=Rwg?4X@Rsn#U6Gd*Eb&tC7 z8-C%Gsj5YLyz`f~T4GDIzn=qV8pEo61_)xjY3w`owCiO=GsX2j!q`I|g9N!-oa@W# ziE;(d_pu26&;U(71x=dLfSmJ2aBc4t;8jZ2EW=JJt8(YvrR$KLf@WMRar(Ev~@i5G_~cPm!?ahM0^x>uo{ z=>9FX0j~%Hiwu2iqNOHIv{Sl>XsxMkR0QSSt(3&_mS#zyoVmrUe z)re=gtzOmF4e$y3=n;!ewYUdtn3X6h(}U|EuCow_Ad!5L8LBzpF;R^OQimBJwmG#y z9g3Ro-nyheL2t+>+BV`t2W^Uu(9>Ht9 zlQQA32xUWBsu)J=E(Im`#J5GbQ=Rnfy;xZxF`OPDuG6BXMX+~-5^)(l+U%q;SqdMOGF#ht5i|L`mGUdJxQbL6-E`I z9RYPw)Pj;m)eQTEo5OEDVQMB73El=5H~K^&n;U~qJqR%;tJ!~I%~f%n(^-#GNOrz@ z=C8Ra2M42ZtOzG&Zgy&VV|yx_l6&2#%RirtNW-cv#HhAHCNau$S;+UW0$E@A5T-(y z#&QqI`DlWgPlrUS%20` z>MD4bhO?av()c?=W(MBF8@62#A7!VgTzYLEdYz%6Mpx?^MXG@K$0)lx#P8Qn?F89| zphV@|^tvG{$R6V2b+B%9?Ctht4eo1DpY6Rl?i+Ab*Vgt-)Tkr!Y=f_z4ukiip?2FVlBuq>y>f`F zx982zqP-rn97Xc0R=qS?C9_m#$(R3cC<Ncmd}sW z%VKBOt3x_Wi9S0wE17!qA0W0g{c7PNlTJEG-Wm@TsxNTrP8R{($4?4P2$#m$|!5G@zLDR0*mS#o-d@0cUVG^C#F@OZHXnGm=>M2T}FpOUsIb#6uTgxsA(ivt zbgt(?l<%nN*GnDsxzN!l#eB0?JAe$;szXr*@@-tAjHdr5T6Lrzt?GtUuIlX4ABU)1 zT3tVANEg=i>iOj)Ez-~u>+lz*4jt_6L(tdm3i{^Mp_Y&!9}9VMEkc*;;t)74=y6k_ zCW%n~%bTi`jZKX;tR&Wt%8{$6vU>BFKsh?jiDG#P*KYOc)N(wy zNZ$mPicaRP zC~L8UqN}+NEUJ8w(UETE$Cl)ejuoIhXepkH!5|2GI`swZUq;i|zc$zfSRCG)&xJ0A z>>R_d1)N+g<0|SUFlbpCR8VFXXcCl?g5b8js~L_$^>n0i9dCK%u%0Oym9L4V1|LEf z*^3W2948!uaHIC~t*m-+3^9%3mTM{@*{M=9R&&?(U`DE(u@LQ)i6c&ze7WJA9X|b> zpA;7M=3*A<7&QACe-yKi${!7%lzf9z_D+HMKEx^M{2$O_++;M0Djj_^eL9XYQEJCa zWt5t9nFJ?dS!8q*Y)5Yyv-JZCE4l@?1_r@{b{Vc7pwHO7GvI@1f0Du29*Cgz{0%s_ zWz2zqGZS-eZK{UtDQr4>GT4*ebm>IENYw`k9eCrP;lQ)$c3R=O|0*q!8iJRk`Jmjz zAiyT>~sllnr2Slk*!S!*Orh4bMW&bI@*h7Hb|@!Kiu7Tcnu|F3*IJ;>r0RT%<}p9IIB6W4h-QH7^v6ORRQ|5BYX?`&#q+B;Zjteht^lU~qm zW9(ReS<91~Os3=;t5^5q9G=F{d>uY1MN_Fbfgv@`$NiGHr>HMVR+QlVRI?*g*2vt# zoKuG4r#vn~ccq*QJdd062q~WJHnCwvqw_%f?O*tzD)-Oz*ZD#%sXdj|3lfWgdByR~ z=OsOME_IPu9AL@q`=PJ`1a>8HPiDOsse;2^#X7Pd&z++h_vzuol=9eiTyEfrf+Q~E zm=i5*JQ)Is&!zSGd^X)&$P{kxmMR-)nZf%HkS2trX8%OGwSc?PN^bN z-&aC-E`3hY`BZ9~1td0?ws%RW(wTo#XxWq%^)CkY8eq-Y2PK#vjJJDOIbkFGOF+33 z6h5!)-N&p3`YEFES!LptOh9E`qL98^((b(j$4W9D9jMK(kXIXDVR9c14+e{}HQ%I;0~RJlb`#{%OfO}mVckNE88*r;+V;=E@-n_+Z=#HHDV>wzIDs$Z@U;)bMGY&IuZP0JuP?Lwi z!m&)i;K?#zQJ0_HKjf7uYDaL?BXOOX&fXIWy*f3AaDzR*(0hX7r9!yOk3rW&ls!bF z^6jafrk<{iwG31xf@gwKjd7|cPQofiqe?n5?BcDl;7j^VFTvv%MH-tU>oi5LBMcKy83f^tg1cKiz>z z*yivdSVL2CaFKlgKzcfYy zVWJ`$j-GMTaZqbZF(;|aW{l=oFHWxT<}E3zn5-0$GzhtpgQHwp3~NS`iE}K4XSImz zXzx^^Dg;YQBX)h>L(-xQYaX|(oUL&JNy-Y|DRk%xpi@)AU_;jm|8bT%K#LKi+9UY) zXnd|Sf<6xD9Hg|hWh3~xMobpdEM7R|+O1LoX5=ad+)7%P>FRJ4&O9Y=lc*sz;HZln zRnkR>iye`*cd1Tv1e^uwcLYvdb!ON|k4F-n5}{$8%1gJz(NxV=cw53t9Z|~Y)2ba! zC9K1xrks78sn(GtX_UGgR7T;2c|;Q@5cW{%HRf0%0vyLmmjw=W)neYSQl9Scoff&; zA)z0~e3rxaGZ2lu_LKJPZA}q_Gr2ZUxRr`Zw7Ym|9S+-->CO~9b)v7DHi8F&D|52e zIT8cp@C|q0mz^CYw|4t){&Yo&i2)NB2)92?eiX{10BWIM=_%{Tv?chGID$b*pUjn# zticyR+l)SfYU^Yw&AGsH908s-Yu)6alcn*_YAgWMWhRk;c~~&nGwTvv@0A<-}P?hhp%UHS2_;7y@9)j zwWxMi4I@lBF;^8cv4LV}+;!>p^^WaxjxCF#I^|s*B}n#W+2D(yT?4D2&+ov9RoS8A zYg`Y)ZJI#4V0$P-x>1W`5>lMGeAS~Ao9r#1eOt?m*ySB%5?N#ZwkFC$cZIcPxVuxM zu^+d-K8?q2RLSnrXf$LqUMx|_yEQTgOr+}fYC>B&g*gh2<7L`0%sRE*r|BEgSwuCf z({q#`Xl!;vu3@cb2loTN>_9hnNoxLGnqS64zc2h$6X23Dxk<|6jOW)L1ew#P{$wGq z=Z6pbC>PP{QH#!{yY21ZC!*rp{TFzC4cbb-ta_|`8u$$G4XO4@|91B8w5)F1Eq)Ko zN5PrJ@PJ5+((&hTvd38whuLBg7wFlZ5R+}*Ja7nM~GXLpn33OloCbu2Z0OT^G6nNKRgW^d>u3k@XPFUBnPnWna|E zb9QF-pBe*Kp6W(eFva(h#ung`^!L`EOj7!SdX7Pg_0Jlw4xs8Nw2JhKCSm^GyCK~X zp}h*)ktiJ}>hbhB=4;^9aY3*IX!g+47@p2`;8!Q&JRRozmW1KfJL&rx$iMcSPWW#sWQf+E(G#u#t`S` z4tId4Cm>y!&NN3JA!0Jk$+Dd$8&H2*m04Mspl#Pa<~|9CofseOHJ&R04B@IcXWtE3 zmcv>haKXWFTDg3`UIB(~WXx8ZkxB!Uc#PuGr?$9Q#Mz!6G%=^gQh;=lshUzijXd-L z8clOb(o-q!X+R&ZBri~y8Ne)8n1u>66PQ)NXz#7RFOLNF?Eja&cY(9~s_J~tsp>p{ z5S!}Q4c(zrBq0fTG$Dx)9-~P=(zJ9XZFfU(EIrh-`rvb|3~MDvn;! z4|m2HNAxp;ii%@Y?x3S{uilFzdKoWzaYV;ae2fP-M~-s#%FO-w6LL2aOr>8@%^Eqmp&zwxJSo5Q!3u`16(Cs8>avg8gQ0$LJb>XQ%&8}%%7q+5 zF3cc74O(uyBKnI$A6UOi#nQ0(4IB^K_rLEQ+dnniHExvGtRx%&Q0sct>enyrXE6Pq zhYEvfow4y39x#jzjf7zq@bYf=`U5}&~d6>RWVN9#$wx#bzP$$ zs#ezIaE4Ie?)L3!aBu1=N=Hw5w%*$zQMIiztS`F~b?vu%$Bx+U!EfBOR3?cz7^q%8 zsLo;&^6rY6mOiC;9#?|ud8%rwVRRyiDrv$ePV7%p8P4K{=DKRl@#lcqr?Npa61m(~ zxA!hCuI30@3KZcr$6A>gL7;slQv*XGUDDx$ZtbXlwiBP5*?jW?cO{%VofF2NrnF*D zmD}oVff={s9w+A@2NXWH6X~d@t+hb{#Jyudgow_vhk6W!*hS+Zt=u3^>_1vM$Dq>DK)xv-|SKu_7#~8w6Xsb zS*MpPuL^!A!h|TR^p(MHarNZP@`1S-0e;1S<_^4PsY#5gepY+mJ4SO^OGkHX`L4P8 zXmgZAd^TSJ#YMN8+@^z^Hj*b++M&~82d$i1k_aR)@GPP39jm8vj5$AXqCIu@srkux z0*Xt=1CgO6MY;2piB)~uFE0o6%#I^3A4@b06mzX5Ll;DU$PHroCPF;LQG?yhKWobt z8hXp^$@K6t2I^qPwWY@-jEhY7B-9ML9)Y+lgm@G1%7S~f<+F?rDye>#OMj|=i{_1t z)aCE6uSur<+OT$HVNH;0hkp7J%#=j$vMF9&wnr_R2FN4Lm&yC_I-U22I;x>Pb#>ye zz>UrCTrHTt16ON1Aaphggd@IJ{IuL5^6NEG zahl6R()1?0Y;iEIq;q|&7;qwp6QLS{a3Loh1 z!8l6@ooiALt4lONQj{)+ZkV+2JkoqKVaesk`Bn8FX@-$@M`EBgq!41LW+|8V!th*v z6p9scKfhjn$#U_2ryfb%CB*$LRv**n`Q2k2O~vg*97uV{X$a}GwOk&nG)U?$jpL!* zdEc;!Bh?g8~URmOmW*pt6Q|SE~u`?{{Y$L%{%Uk9D!G& z)=u0Hk)XW!?ua=#%&%j2M#%PNPc?k9IX({CjWifTB0m0Cptis?KlQ zKD!=0J-2UOU(mCbi+y@}?r32|DlHB9YAUV@slVb{P&QXw3Qo^)`b`&I>i+NA)!nmE zn)MAXH=|lWJ#M?3v1!29(O375F&evDA$pQ$w`W%i$5Wk!c6s#k)t(=_yt`52TuJR5 zCra7Qnk#=!(w}2E$N?Wtj4NlRT!&dvb;7Y zC8_hW@O=GlEi-;|>P)RQCoV%M^xEVR3}cyP_-{0@ zmbi$RjIdB#i(>ha{dt!7e072~bkS6izoM~R@E>hzmG-t~yXYx`XfAsQLrETPUI!!Z zW1n4je0Hlw-ZJ8{(J7_GrK3|yiSwaTN=efquFSn9iQ}WSEF9OCEUZLMxjC(|=X8rD zqqJ}oOKeDJ0%%BtYv8m6nCCUwvvYrVoblG9tKMPVZjp)W12BnMkrPVJR-q|z@7UAX z(G1*grAdoS8lPljYH;?ph-}I^3+KVoMu%#S#!*Cc)ynlEQ+B4xrY`9~U*Q-#Ewphf zTv%i)Tv}X+PDb|1VOEo%41FJ7RcKn)}?HRSdY~+h5W5*{EsU$FnAkutVJl!LrrITJp%Jl z`(~Ufm}>H{)#RQ6IS9bCs-ktND4&+F>8lKx@&c<4r(n!D=AZ@gAFL>KdOg&y&l2-d zVg_-z!|0syjdHFsmAh;dHR*>t3-SjrCKsnMrP{UZy2@JP-?G9g>e^%eygeGL#(jjh zM#-7Y1Jxfk@DlBuzM6dtcDm$9gQLXv;_zUV3b#$VgYllwFnQJsD*#Mu^X0H41=BI# zNFHV8k)wRQI6Xv#xL!YEixg{>7WT0JsUAn80tsxNm)!@H3i(pSx@sH8c(00SsQ-4V z81=XbM@I=F)3)DOtghO`6P5xTIMZ(rsCnp?Ea%2v2-V8gcs8oVCD&HnleS1QI4--P zwqL{s??f%NPd=Xnvg~+UXmN4ICRV3T9(I%Fmds1>+(U5s-o%zawnkH3V$C0FIM6MP;o=shBQ`m$=?umK|>ocy(xum}0n*xF)bC zPOYA_%X_BkkI^ilEsCN>zBNX{?>d+??gf=ucfFoJ4>rB4mD(-Xva=uQSRX#bHZ-5U zh8jC1=+MdHXVCAAtAn)Y3U;wJNRO`Yi9>m*Lq{@7-1#_d6FUmr9=z5Nj4O&oslDP1 z@Mxt@Vw?pQsr1k^(4b#KOG*N`7KUC5TF(o9y|uF>rrQR;rgGJ;DukBaO0$ZQb?NmQ zS+SQYaA536U-Kbp52!ESd?WL>M8niy>hi$MtG~KMp`|^Mc55}fLI-9Jt;SVRX?FiM z>IZK~Gs4U1H{1_5M+wPPL5s~t-VBPNebu8nT&pfseveSpUdc9ogn6~@)S6y7?|S*8 zv?|xv0^j(KIUseuY@^(bzuSXA8--7TKJ;QW^Znclg%t{(2BbY;EG)G>Gw{{=1^be~ zmTpYJzBI5oK$Oz>*1*=epxj7DV&WiU+{KlbRF@S|=(sZ0_TZHd(9ey57f+#wl(n07 z2ELT(K=h9l^}RfJu}-drwRbnHchW3z?Uh{DzDZr&*{YGx$3ZEZMr!1sHy1cuU69@- zq!*BG)V>%KA+h+y6m^Z7y`#Z2c*JIg%^Pcv5(_mQSv zl_0KDjKI)EUy$EDgxrnB$N9JJaJ}#R57(>7^WHIUE+2s^iAq(D%G3@K(ZIj)rkk7g zMPTawT*!OJyc?1;BE8cc!p>p8P}{txBaf>=xe&`B zYO5wQ(;apo;*MAy17e5Id!}}dp>>)sQDb$NB>IHlMHw5uO}X@H(_&0ja0Ys7Eum(?NlUm4(7E|>@Kx0^YKuhAR%qpkgS z9=|hu^)dS$EBth;o)bRywa1Ph7;Ejj^YG!ldgH3yH~StrdH}l$2U=#2+)~!d&Frtf za6<`_no9n$z}KY9d^eBK&~DDn<8}Nd2v56v1SB-l^(c7K9&oQDU{7tbaGPJ)>-%_& z=N&ky=U#=h&CX|haiDs*`8b_L7zAN`o+oEH_fkD(Dqfi@-xs|qFpHd0p>sM4}GJ-{Ait zVpPgqpN6U8NnN$&kLGhZ^?X)6XP(|&sT1+CC;N)Wdfr-CYz1}Fi+gy5L(V05DK|v; zN?&>_{Etwy$+nE^1@Mplf3x?0?AvqAWjgiY=6h&s>vHSedK(vg^Q5EG64_)0J?&Y?Neg-AN8Xow`PhFR>k z`Hn8re3YLJ6oy*ep_-K%Mo2Ts?u&-!OI6`&&`OTJ2X3h!Bi@0RYalNKts`+BhhsfG zy@-t?tG3wJzk+eIJfq`}y^pX#nZ4hFwq`*s?c50q*qf2?X>)DvDsaiYe;A?Tp7 z@Q&tN$SyT^T|j(#6;SMT3MlU$1r$3Ku;YoeS``B}twp{7ndTQWCC}Qf39E5nFS8!( zp3HFzXXeE@Lg-1FT656=rvFG2F#Zr5^u|)}4AXsvi+7rb0mJCf>X1*GoHX?c>5>$m zptN;!KOLFU>ZoTG)f!#ZC>Cd%*xnr))#@l;j^f9>HF{NTeL}aZP4Z!TdRl|vy;`155~kNGZq!hL`P_K!EKlzv;K@Qo%fvES#( z9WlP2=*l$zxJ*;kKiB+gSltiYpU>V`K6t+hcbL=Xnp%Q=IgN%FlnA9}P8}v-y2ZG< ztod1dtVLI`6kZr0Z(|BBw59-54Z+YL$8$iK*54L4ZiwEh6s+*-y|!wyYq;6g*E`5C zL0(T$3KIdEJ!&M+G)+qDON|lDtkTanPW7tlT2)?ZAH<}@A+RxUcW%pyo=umr+ewS8Lm!Dn5&y_12!)%j7UkW(@ohF_Ola3Z|MpVv7k?)B2X0;4T^TFXYdc-O+4F*)ED- z>X7|+)_bscx9&ClzQW3Yg@h|9DeunWzTdcfI5h3q;vU@RVQcYKKEE1#*o3_$@~$rL zH||%&mDU>G|Brd!pS-<$6mjf89Wnd-96l%*Yr-w@IpbxGl)v?6_i-DV$-n848qe=n zJDc#mG+`yVX(oIMW>~&#UTGS7z*Bk+t_;=my_0^}X4R3ycOJj%o}*)}!v}8nqLW7B z50&tPKt-gW1glUzrlXdKBFsx(nv=SfevV10ymhdy>(zHOwU?z8zk5Wec>B9Xgt*-! zLfqaXLO$z^2zjqFBIMnBM98Q2h>%bBhr0!qWoD8FRqC-q2dAbgyoR@`>cg&T{Nwh47QQ##Lv2Jz|DW zx#anGYd9HFfkvCu;;d21#jGJ%m$G@+sPP``k!zY+xx591PmY;nSg)Y(LDYCQNnlRI52R?gaXZFIMiit#DPi)^{x0NsaN7e_+q~IA2>z{os<|q9t zNROL7Q~FYrR<_xR2V`}Rr!RAubkzLZvZV^ZOPmL1mU$>(e!h^2ROAJoa+KF0s?0+N zk%;ufgXY)*J+@big9IvOhQu?6!EHT#+>{E^sDIn5*{v7nu`-OMht-qe)vm_pcj6OY zi3GO9)X3%zba`=_Z*(JD6>oi&UK>;x7yq0Zw|&1#zi#5^zs3?Pnpjns zjUB6TAqGdcg+)!qA18BfN=Bw06={)Lt1TaHjuL-tZ~Hj95SqNe0l}ad{KiMf+m1c9 zR46MAO4;hP>x$+T6+c<_RKP2|fi!)8msDgl)H#OG9PUH})yNmYWhwNV^*ux?%EcrS z=UnsS{C1!A{|;^y#NP#}wBataRzr`J6(X5$m#E>R0Zs&@+)>mTU7SD z#&l|$YT1%#y%`sn$Za7Yc}{k2CVaZ}weUBS%1O8e@X?RYC0`m~pA4JY8TDNACcHbw zqm^Vi0H(1DDJQl59Yk6x;W3M1chKbWu_6~+yrVThrKQCyJ(`Nk<0DOb5#tb#N|YM7 znkdS}bWmErVbnAz0>mQb)>9c3cyV@iCEii1jWyF&{Ci@6`QCDxk$~PqRxCCBCmB{-t*-zF7i7|4J`q8qXqYMd>YXuvc51&fivz2Iki?0VnsG zft;gYd7&g#nNLacMmvkTC_hA3K~*L81U`n{?XSj`Kjv@R)7{=hyy}}N z-oC4240v8VeV8Rgce))a%kH~+m%eyrK`ezLkowUUCz3bzYcT`u-JxanWA}JhT3t1I z{v1Xe|39YA>28;0dJ)W$r^ z@Yl!;t)f@hx$Pegp4@AQS$n<(Pt}{4E=uHh-;S5sEiOJqYrQqZ>ae)<7;H@jf1@6s za(+kP@?DvkJa{}chPK+HM-v2($*#8Htv=<=G4h<*e^k~o&#*aKqr4sw;oZlYjRzKa zy6vnVC#GsUxx6?rJ;epw%yeh1{~g|{gZBG7d3Ws*|9#*}|6=j3oX7i0{_Ao^KN0w| z2sW`DeiGilJ6?>V_rtJWOU58R0OywoqMd9>>xTNjsA^!OM&bOgTILW%(HNwSS5SS) zn_h`gW}yT#7vi1wQh2H^`m7zIwoZ-?cm*1hy+E~XleC8?v~l+l~Zex@XrQ3{&p7$r6@ zsi>To=^Tq%_8upt`I&5>fZ5XcL3om`twbgd)7Tp7W2sqFVS~rsIFFJ?j}}25vjLKf zWoThlC6j#(RmB;qC31`gXuOQnSbk^oqZAI0Gk8DT97Um$eNW>1zIzv!i>G~0yv`BI zI5_X%iwecM1|AdI8R=w%j+mZnX)?7F*!^)l{@K@(h{SNLs+VsEKY^ca%ct!6!c6&x zZu^ty<1b@lr@d%aDMWvQ)Kgs*me}l&84pqjwLg8t+3M zYN|+eDIT?ZY46Av5R8r-<<}WzLE~KWR~Y|27DB11`7-wzMkO82JoR$&x3QC1MCZ16 z?~9&8eHOSO_-R1+5)e-W!Y4EVe2k+bp;G@F`kyhmS8IiuF2ZxMipdC?wgTU*v;v$j zC+=hU%u_;bq)K7a;UwSDDtwsE<^vj6d__dvqVVG8a~hx2X?#D0iKo`qonA;izgFm# z#o5(X#G!1gF@nrTcW-<~Wd7wXTR=f2CJbe4Ueq(#%Q}NySOse@=yOllOJAP$R4%Bz zr`s#CyuNR4W@344W`1$`!6O_NY0*Y=i#6&fq(-aEc(zo80UomN2AL~(O&cLeV2 z!fI8u{RKaVes$zd)S(X-{2cm7;9B!6K2S$F-szd+y*_xUq@B^mJN$C2H{kOhseB%B z;d16|h@uO&9QjU&j_@98k(B?jNVS2GOw|FAp3FEY$W=!SPnp&QUm#0Lt z0KOBIK5xM1Z_3;_(>>Ju1s1BKi_u!6KhJd(MT)R2Fdb??Q9(g+T}k_*>MN0^5i!-< z&UmFWzArKUg)>GI!=m&+ifl%AqD9ETT6Dd!;*KF^`W#VQZ-gsR$!E5-ytc#MpBMmg_E;TCv)!$megleAui{MW7(Bo0=Gg?c3@=xvcTh`4iv9kS{FJPfIy6t9&l> zbhJy^($;Z4)wYrNCi;7LZGYm|Cv`RHk1<^0DeIGJz5r}sgzF^UX|?|-;fljHUR<)o z!!|o+6<8w|6Y3sY&91y9@CuBG(zj%-l0P)>uM-6-rh8dP?Ahf3!In zl6#~%0o7ND(g7{yt1>-rvN!~*AT|%%w~&Z|aqcvAUzMl3G0mhoZA6?a(5 z6=@r74{LS-oyO`IdGT_>5R+o$MY*N3_azc2oyaeH|2e_09<34<&QLr=SIzaqG-Qtk z@FQycRSsRaT;sVYkqnXAnouf6DJJV(2@Qf@O0SrWV9mgjpuE7U3;>_tH`6l#M1=u z?*=6Nekide?9&>tUl(fm^WZppJFZ}QLzgIcFNuh^w{ ze4VB3=ck*U{ao0#-Y^Ns@>qH$u`_stvSg3T@t7;hV<2yn_>S5>{I#v=5|;gfOR6X zULBKkt;6F9Vf<=5{&SIPkW=0O`*)QpO&M1KFUH64`7?aVn^N)A#Iu6agH8alI$C5N z=l6qu`Eujq@N~r2i+Y5Z69qEyiNcFp3;bsQdlDS-C&AkkN~8~;A6!lsfxtfnY=}7WPd_9k!SHN>-M*CcIKM~^nqRbq=7IzTMy0lYJAudAOwXF*I z_NF2}mLs~okggTd73sYUc5?3eishrG$l)P${-W4t`Sq5trg^+M`rM+W*Bd`ti{)RA zADnBAAMJ&4X!RIBk_qL#_W04>(_{RM!tNSBJ!;;dULRqc1?>4@I~Fs%kZnxZOufJS zjrBYt{le0wq+iEV6RCJLa)!=7IG5*ueJx9+Dhkpu7&nu37={|Z z2|!m#igEdH^ZhUi3lvE&KQ(|lwO>P$Pu+mn3u%T6$Zzq*b+sEp+UJb;zKFtTYiqAIa3NpgkYZ&TK@zPaCmn^6e z&#UM53il)W+FDBO>Fx+n2!9CS?HiwMfpmnDq}ST4!>^|)dzLcVCFAY0b&zo2F?IMrJEAwr9n6_M3Hk7`|`4kL4PKK$UW*5NJPP+R^JWk`bYiA4bK{(Pi zL1y5J0JRmW_2q;J+9(Fx_xKE_qBL~7yKcQ^!RF4l4gq^WtEgS${tj7nlnOluW+g7Z zo3Van2&v1iBu74pM{#A8_-Cn_Y))x~Wc7>hN#70o;blJDGM{fWJ_s+~Q{=V!ci?`6 zknyS{h+ZFs{YS8sZapw15M8{2kIqH4m*k!g(cW2mPvVYL2K+R06v-GlF&RJo)HmeK zOmdR<{ig$$p4Re^rQ-(eX`34WatggAFbSQHrx(LiK^#v%m?XkW;A=T?zOEeNf&9|o z(|wD!6`yOVFCgmV;>t|5V%f;Ni~z47Ky1NVG&KLxhUQ(2t1vRv-6~SLUOY=VoN)zg z_MDCoE}lHzyc*9mN4}FTnO~|~opc&MtFEF6(zwt%`3o?s(G{fwTYBs3rMPE=MDl?l z?i*bviMVqtNsMPR@Ipp=Hul+*#6@VZcDMTgrOk=g!$(!g`T78Hd5A#L>8v40+qX4c zf|iGh(cn`arI1q_AEE(buc%XA&deIyd+(Ta$+_mc@Qy-dhnV;icm?^=ZO6oKq-Ys& zIY6C8uXQlaHUBK7`p%|``_ASNgCiw&DUSLQIe6=K8D+A<+dLet^ehdneB7S0r4gYl zSlHuTpo$|_yyLQP8X+$r;kb2s(`$&_N{dA88XD*|1RC3`QCki3j;Ewbe;vt&bpAt? zj;V5`G28g>_e-Lo7or1jr%dW=Z_NCKVAGL++&lBJw3EN zBGpn&tw);*`w{$-+Q2CFsOGg0VQ2Vd)%Sv{tzF&e6X!$29DVI^J%L(Wa8+~EIVi>c zgU4Szv2yYy`#OyteA5HnviTqM;Heq`ZqX2uGkgbDV@J+_Pe&*^9Ov$|*3y~!4t`Ub-A$uFRnz!6-IEXiNt$=?>nq4tiSe)j z)}ftliLICNP}GwFV2a&-GKdAS-%kcCC3gJD@FAvH`jfYLnYBqMy}QG!QFWxbgPf;z zUR%1Zh^+vlFdpE1XUMj3-T>#@#5pxT|DbyQZ489Y!aG;v;n=J1Oas10Q>X&UFg%iP z=&ot)*~y*Ld02<4RoHz;_ucN-;HmWwJt(zoeMOI|J{w0J4$y_T-kG1FE_9~K z9|FDPr5&k#Pnp_3&8fwJBu8v5=s_cdlNvR0FH-7MCXNUiUf6x9-T9N-&R;N+^kxjSFH8U85d+nO=Y-)#JjO%!wqzy8?q{Vm?09kZ;%x&LpzsoD7Urb7J?6oc{zC2Rci z=5K{~aE@{>+4$vk2f)k%I$h`K`}Cw$7>;r^q62ro?&!?Q;;H4SLY48qzKI(kPz>)q z^{jfFoyi%o-|~YGjivvWNW$*vyk*ET;rO2D48i<7U--&q9p7s8qzTZt^P64gHRpa1 z&cyQagspCWR3{#zpKHnkXp>)8Ln`t(q!-O;1yKem9schB6*m7(EwA3Z!MI#KJvYw3*6HPmrIqRX^d;9YYxBTt zqcG?F$Y}cY#veDvzlAmLg2wRe&pJEox^FEEqMgz+HO{*$>~B|-`#hn-3)S+<-sx|p zglC6uZ=N0gN)l8*X;^z=jdv6C+nVw`%)bwW0F2+SKXmt@FYa zL~EP|z3o%ZS|J@+UnA@NOLefLE4rB>7v=CN{{2N!jIl%Q)@v7}j-v+|doi(bT3R$? zmX`uP=m{U0TwGmUM3w4Wn@ZwiH2u4pUKgmselA)c76?rXcFYZz+P^bFAGuIx~ws+6U(+F@N=oglt^Mzq~Y2`|3ZGxR)o^ zwGO!d730gdwkYKC;w|I$rxiY2Hokajb?KCKdh5WQdk?ja`3KF$=U3*&$BrFt9k9fW zly)sr?y=>maYm_nVS0uS1qb?68*nJl9QqU8#_m+)>q09zc%S#i?3$8ln)yjY;7Lk| zrsd)E6ct=p!ME|dNM@-ew0u%vy024 zcOD&Ud=||?GCkVjT|cCQ;3^NA(DlFFY7tnKqcxknH4l~+rGK;Bc)}Dvx%h2QX^YW^ zeB&*tYWS*u#_4eqJwRVnw1ylNOUnC!r$yxT;&EmVEJ=gk0Bb47lt4HwRuNM|;WvtB zG3mY^WWMG?`11OYJ=$d7UH08NF1r4dv-1~_8Q@~NJdjgiBZSou^+Dz(koyz~7T$7}MTkLSDWluFHbj&# zk|KH!i$$?OcUD!`6rvark*5e}Sp$Lc(Eghv^gAB{;+mK{m6}S7&}y0utwVPoX9eU{ z1`ZXt@UtA9@r0ohvrCK7#4K5yyd%CND~6Af!6=;enm-~ZZ%##XH&o0)-lt1{r5Bs* zrMFp|2NsId$>}jrBP7Kb!&;(6kdz~yNcju7r@c$#8tY*QqP=^an>y1+l(o<>XDc{jrQYU0n%uj)E{C9wCv ze%)Ir=%NoY5B%c5ojEf#v!r+D1V=dfMjGS^GjqE%(JmyS_rjlTGci227Bm}vGu+fn zYXmByndb9L#&ga0!HCe{9qa-U7w>5NA>7h>)s2+*?M+ADlwjj+Hl^Ii-($@gcEp*M zyYR#YW}8(tay0oKYfddLJxG;9C>wLb2GE6jZq^Pr&b$x7`5C! zagqhX=#{B9N2K;FUmZovAjZnc#naLdvMJ(D+eJ9DL~qSwWry#5?WNN=$n3G^DYkuW zE6NYo5;mE5m_|Z($UQOrji**tXWKJ#(~Tdutd)zqzuMfhDAI=jThx5s++k>t!imMj zX>ehDl-}foITVn-Se%uQ8kmORTZVF}X*SyVUUsf)=Q}J`v43gjJ1Sni^SvHc$IkZ+ zVihqpyQam9JKw)xsE4&q4aHEv_pEjKMW=o93rzRw{%wq-v|!_?fpWanP_>Nzsj)ui z!pRdhE#~>CDb43pCZ^^0#vLk+hLC zm@j-=7sjX!&f1CQWAFDAqfTAnfx`35GUMsAhhULvyp_~W@iJ|7O3-kMtX1**qu1%$ zPyMH>z(yBf?r9-%E@#mC+E=d4+!T)p)!w1%XFS|}KxEo`$A zU-0+C|2p_c(ky*B{Hx)wSTeIHPk{?O)ZF#$&4zXQ6E;d)_GqJ}4qj=Pb}&&IKe2@9 z!0a%-&DWvbm1lb~dkycZyh815$Y}fwJ+JbXVsVRm#A!=*czd@erdeoM|2niKa9I@w zGqe-DL})Ks0?lpINkg=%$U{xlp!Hf8o_uc#0bES0Qlv7@Rc^!2ul)Gb#Y`NR@@`&U z;Zm$`-j~{jGzmDpU{Z!MX_8b~cHLRI%_OZf0Tp#?1M&As68H`i``*r$!i?1LdwVku zmd4-W|MsRevo^uEHuuEX|NK0MS*oWWS*$|~#cgX0N&^?}zs@0v` zx#mQ#L_?NOn1;TeYr@jk_^u{!f)?$@FA}qv+EFeK$ttO)dk{v9^h8s$BzxyXv|H!d zciDF!HUqG6!f>W0osK6o-JFTL%0?NSv-H<5;54b_0?L(3Kmm8cIK9~t{#36Ls`pa~ zmCtD}qH=h`E)YV-zJ2s;LoLa58>Xg}6nMhA)|%kwNL99YIA(5;dTs!vUN^v6sqaGL z_;gNQ5z)z6VnNK$RN*x~NVxgXOPW$T@hAiV)%$P6yNq|P`42Qw;{ZX|-d~B2QKQfC z@jzqQyN5PSnh~nv+uqL7ZM7MP3ch|ui+~fgHEH>~n!{mM{Ck2*E>f}`p;~ROM{~$O zS4isyWj6GVAZC-HZ~16;3EtO2Q7=jp}eX`KuF23@OAcwy*8nOj6LcQtP{3c$g|)>gNmqg=$bW0Uw- zcm^WHFHS!iV}C}Tf&@qYY6 z+TOBvOrhdg#8@MN&<|dQl{eH8%wwc~bV+3~vOnag*04kmzK;hv9FE!maT2cwLqES1x#1vIlm-8Ipa`gHq5d)3zD ze^5(=l%8l_gFmkJd^Ago+tWP}(ERmMojDWUdZmXyQPc&(hMrU)Y zp~|al}4B__uzwS5HdX{2bR?i{0$01+!vT z>~4QSCG*t1_Pbf(B8H+a+Y1BX#a7sN6I3ZgAWSXEfLcJ`ZF#0ha)dZ>fefGhVg+92 zCWCe3COmz*#KJh}!}!q}qh%)uX}%7$1plzWB2^0**XTW_GTE`32;skHpr=06_#d2Q zwlqJp_|px`(B|NnXX%z_QKTMsp%Q>E5iVz%yT_~D9Y7M3?$}wf1wsv;;mzU z;ZL3pcR_uWbAoG4p!JtmMJcbEVtG|z1@<=EFt}Y-jBlnS^X>i!jn^>L$3a6fw=&SGd`g z{=%{P_ZRTQnf}5}E%g^J47d$jX133Kr5(^$%b>s3UqGy$pX@Ir7j4rg@dMmQ z!}niVr0dOsv1`+nJtuX#T6lm)ghb+1(?Sh{ zXa-OFiw_^DS_1xDRzRdmp3P$*1)e8SItl!MbbH(f83uwQ)5>WJjOG%D!kJ}d13lZu zq=Qi&km9r#muF7E<7gL2xNP^>Oqra*10mB&v%*FD%rp#4V;CdUp3q6m|<2m*FCZ7cO4h2lcR%jZ0Hv z#7ta5STn-2Sw<3Qy&@_^y|RH@!Y{niGkmzrarcT(z{0lGNj$OI1&Wz7Z6DGy;6fIB~KSK zv}An@FFDkM_P0H+&_=4!jL-muphvLf-nu2mxuvyeD;Qq3WV8;xo`B43k_H*m;npJt z-&>BkcMM!RHEKNWQsSQI2}Q_R-x~A2HTZ{IR544Izcx@7 zXdZR()tZAgD_;n%!5oJN<*kS(LXSt$eIWMbaWGl6VLBT-(I>r7uxD4C8Bzp%3MpP2 z+vdof`w2oxmgaL0;=82gzK${2R(24p8Yui_sL$HOAP^D{Op1?i0`a0qzzK8qdaVT9 zV#;a&A#hfX`Sx^s$&BQ?C-z93n4b^9g&{g?a>8~IC6PK2$HW{+gogk>)jk6=t>+4` zJbx!`g2xS1TDkGF9Cbl*uoihM<{Br zDxlEga5LVX(41!x3t^zh$+RV%59lIeW{g~^-C59*UOF{5ch4z}2DC}i!EO~iS{M<8OsYWc;n1m-a-PIz84P=no$=vn|A7g!c#i{%2PmVq9XE9M zl!umAh-bmn=b9O(wD8~;v`E~+t+5jeOcAFH{#Q*s9j>H(t;8uvIw;J#zZfesd{kYH zO8^yt>u@M^)n<4I;cPD{m$~gTxh}*#XkwyfLP&fnK9O*irRF5UIs~^pK}x>WCo-G& zO^CxYqu{9gS$R=|+g4k6rW#)X^tt8FnvDyFR#6-u-qsx1wtf51Fwo~g_LHH;pANv# zgzyf)P~olPHC!1FhyyS*;^ub18Xth6Yr*paFtqE&;`9Iv^=D4?92$V3>)dh;z|hYQ zYu)#`21E1XyP{Y6nDChtM)vYoZ>1I$+5LkiZu2xW@q2D7k^z!ELr9(|L{`E85=g$^}v!Abm z8scS2^B(|FhZ@75J(Ri@$R=bmDaLGs$PHl30gO35(CNIpxAHL8Dg7y64q(gyj9IF` z^;(<#DqsL(4q!}wC-RR#r?XPoEXQo8>AMo7EVL=31|a%~t}ltQWzf$Uh7}bnp@aU9 zxTZ5mjHvU0`er2IQi`ZpiI!%qSc!sWsaS~yfjM1^Bf5eTO>`zjoE}=DU3!+vQAg>h zZ%KIy%}Vq-3)eHLs+-|6z%D3l5;JiLVS1MEqWY?>0c0S3iBjM4+2;0~D}76pCtTl> zL}F`0y1pfZ=}4lz*{N^otf+74u0r1uhAF?1LO>eP__Va(bm?0@$28Znz9ssd9r~7p za1~3UXH`V>zkbgG*XvP6nhAN7lEL%4pQLG+K%*RV5h}QQy+|LEjSnB-gi01bUpVZz&?{ zTT0i{^erKRz9m%Dw}cG(mf2g`l=_zFgjV{N$sN_M5+iA6!Et@d)CaC_nUYROBYLAz z-x5#Pw?y@`(zir=(>)X->RSR)R{EAw(iFIja%Q1#Nf&2*OF3>Oi2ZeaOCzO+V?U>st~f>svBegYF#ctZxb1 z^ethA6j5ReDPA4h#`P^JNvUs%ujyN&=jr;E5T*KxTJ6C+^`$5sCMXE!YTDFaYlVh$U@%|SJJnX zPpNN-JL_BG=+?KiA#VDXv`ndQN$99=37PaQq2q9b4EmPF#EJuL1sO&JRH<)?GwNH4 zO!}5MlD;K$rEiHl>RUo)eM^d3>RUc5>RVnH`q}j@neo0tnZ9LmxxQs`y1r#{n!aUn zxxOXNpl^921uT(9F!-!*iLP&@Z;3nVTSA6-re9p?TjH1XEpfQMB}CA-R9rJaO6!W2 z`ee|z#98ZG21e4i#2xf4p|ZXuj&6NR>Qd=jhO|n3OIVh@m&B3A7n6lAF&$c#=%O0F zi1xSX#ZC#GY;5@>X``3@$!NChDjD@pngiw?>prB+2eY6tyh1O#pvT*z4Gk4y?k@(4;3q$_Y3=R zDGyXgCwhv-XY-NkZfL<__a5HcurSA%~kmNx@}tX9H8yYo8%oB)h5B} zoc2HHyi1TPyK~rIwT2h37jQ<2fb=3sjC^S0Xq*prII@t%JWfYmW_CQK5<8rUp(>$* z{VK^m&^cL^J-jJogY#M+G+{lKs^!vaa@t;&Tn8n(XP3$K$>|$ia{5M>oOWW!E)(Jl zXPK_;iOJ9RM4Z+w=?y4ne`Dy}KxFo0bGiT&T|xeovv|Ksb5*;lu!8i80idATRdL5% z6*BFr(ABPrJMXGEd{>1CyDC)LRYe!OD$aUW4UDv_;tsniRNhr_bnmLvrP@_PTIH?^ zEAFb0Nf^=)l_(z`l`zosBJx)CIP<6Xo_ne9xy$#z+U#O3V`?AZqp{^q_T1aFFTK)l z@|CpTNb2v+?G*+0C@vp*Ac`zm`DywN%ot1rkm-rDcSTTVazT zLXcF}OE-!L8@AD=8no`MFF^^R-u5dAp;HDZj@)cE@yHDscTBd8PLN8wl4IO>b{)-? zOgNe=nJMj45II~rnmad(4jo7HZeb!G&G9LY=GxxfPMOwbSMBaKmkxC6o4~A0U{F=pkUd^1Fmu}?2`GyLrj8I@>C`NWoeFmI0w_F ztiDJxB@G@&6@umWa57+% z%cQd8a;XewDTE;o6hc^Z1tAP)DPPdDS;9qVs3bCQ)+~{6^-)P=xT8b{nItmkN+QFZ zB{Cc?kwFBB3@S-vq6>)(XDyKhMv};I2Z;MJk{M$k{hTreI8YsHtx+$3EB*m{?A+kqjno;C>1Bt z4QEk(#MvP6XG*_7%<2&a{L zQF2EugTzS62yk4zNc|y&I{mF7ZcoyeQUXXPOqqIE*Cvw6L21?v#Vq$AwWMZ*QdXsA zB)d>TGEkQ)Pyo6;s~O25Z5;mA=U%j;PTcBxM;0dB;GeivdPi_dy(0yPdPmUVkStqk zN~N^(mVNCi1Me7EdPmtQDBI&ky(40FLOQ5pnck6Q@1+W<+2L66P46gYs+wA|{8iT` zy(6@^f|d~aTUrtb0Ofi|c)H#ZQL^5VPm5Ou-VuK(soQxYkn0_hzN;HaSHujy!3latC`y%jM>wLd{$Bbqq60ZJSG5uhwVNkT`-05SoQ&~d0j1|ZUy4n#tR(E?QhkvJm|DKY_(3YLLL zTnUJTu7F6~Q9}u`!X8U-jXljR!ZA;xEOKoa9F8oqO!%r{P-1d9T9}-U7AB`bfXU?$ zAWm!la1VQ3aQY~St}q{Q2F0cqQLj?5>3TJ9G$eNe?OPg>!yN%X$Pmx0-Bo}eei`t? z;ea1R0Q?j;DmIBO06&~H;1?JP@WUMdKd21&;phhZs7nR-g|te*50+)mM1>4XSBE~+ zjh0aw^;5D>+1T=bOP%R5AzXg|7H8nwFE#|weYLPTQ(Drc<;d_Uxt$cCcg0SCyWysO z;eT_2^vwAT@lNX}P=*5Xb0OhIhIdJ8%I-Za_m3&}pSK_vHivarI{YSn_82l~FEG87 zH$I1O9~lY=pGAF@Sf3%PfW|9^pR2fY{9L*^# z4r1C~nVvj>xjlqg^jPBKRq)by@__U=sTUyj_VrZ|V#L!c&_^WU>UjFJeHEm@&&VoZ ztWcdF3E@C(n47%vvF%xv3qUdDllgl9hftCYTA_St?$3jG8bQzbU%MbxwhKlGiWI&g*x3VwMWq`&C zT~6+ZB_&3JoZw`1xtJ9xY2OW~D{y8Psthz)p~}E3-Ka9~V}&XMINFdC;+H=bLKkOL zSq@>X_SZpVBLyNGp%nAA2+1Ehixa@?-tJx_K+2ckKnV6j* z@|8+F6iX3u;szoszJbUEKPJmxA3!vZOx^=+2FUknUs2&fIf#sB4-i?`1wBAy*c~7; z$YB7H0nNN^97LvoC5Vi#fymctAyach7>LZ@1R@J}vyX*Pe8-M~dpbd6aGw%H#+gB6 z92JNxjL1F~A`b(RAp(dD6+mRD3?k!*$Q)z^(SP4Xi&LA=vP?~$t1&B;A2azEh zM8-eOXy^bUiwYpJ5{Mu&bQm+lj~gyMSs}-GRmd^!u%AN()j^!PY zV@Ssgt8fW9c5Xn9SyVfaV>l&pj58v~kO@PxXCetXmQM*3i`6m_1;&fB#&`oG zVZ68l#tW4(UL4&RFLkLf-jG&_@xqE2FC?cArus|BqUYn)TP(-Ww^NN<1@-=kpxzrt z&JGWM`;a|7)$cQ3d2xcd(uLlRmh*kS759?pfN4YUEBR3sfGDrh54PKrgT0D zDYeb399uQ-56k=8K#6zm_P49Xy?7hkcXV=JCGL9wU6s;RMeu2P{Adr4x60$co5z;s z$nGn*?{tk(%jA>t{MQ#WcV4-(DA4F-aDVIqFlZs!!={vKh_yeI-G1fHT}9|sh5os< zLtj&c{xwS*1p67Z=B{f2nlET>-?>vSfrh}z!JKJs<+DAi#a`OnWzUO%ruBMg$Ig+U zJ3Bn|OzFiAH@A+!^jAf+i!m>3Zr`T=c_J4LUDe#WO>dVhiSX{ovfO5wZQHhcx1ra2 zu22+^{H=uF={&++NFHSn0o~hSsU%yHUM_9*&D26Ap{a@1Z0_1=&#gS6tp?l2+*Qe8 z)BhFxzhnFE?Yk|CT@xramjF9<>>AmsS5P~)yPwkR74lkwZM8TS?us4TiM8GG-a10I z&+uV~Cj(Gw#M>_On(tEbgrgQVI8#4w-M)QuEu?=B}N)`Jau}3!kAYfHz(IbYB5%h<|KKcW|>PbdAMq zjDZloe=Me7joZO{E&u-ehC`w5t@`rl3+;2aPw7SXIxtfqRRS|bsS>gPK041~_-5p# zOZrqYgZEkbVD8|3R;{OYVIEb;%Kk4M2s`Qb+ZkAzwux?xf2nE}M#L zi5jphDhz`AW2RDh9 zz)k1?Zi))vCS(FPp)(*JC=!k^CunyhhdK~XLRE+-?tplvg0Xu+2lP|ippIY2tDG^T zyb9SVq{8YFO%)@ErjQPdR^bvb>f8W~(#0LXsL8nbE6O+{Fsk8@Rcdi1U=+Gmsby!V zkWvCH#b0#-S{b2o;@T@xTVr9=|wCRGGVFE5le*(SgJ7{ON9*M5~{>f zaYigvWWrJvEZ^SZO2{g7g{s&n z!o>;BQYV=uCttm6rHM;y82K+_!(3EV*s$)iJhY6|CV>*V5-4$Jff9!cln?h z7CtHA?N5PGhXKSK+ZFpGV*l)xCfcvtr2pz5FQT6dlnQdmZi0N&RAa+WzSu?OhQ;Y;WJi(S8xqXzsX-bOqa8YrrFDsLUxE9>_a= zGsvg{ep12z765l^2u^xbRC>HShNTn?iRNz#fBO}L|K1C+QE;Qe-Ro%z0vx_Z@L~(b z&K<+pXKD_gQ1s`4pAIh&b_W@3;aAvZ0A8)8j$^AVjZxD6Fu^ZW?Ehjq*6)3@=xig> zC<8*bkAOMi7Ya#MsmZAEMQ%RQ>V9PaDuV?DnsoR%in*xrStJ>Vv^qN`E7;PV)+-l+ zpzho;v{jZBRL)nwfO7tyGoUwBrC zR6KKrAkgGtMj}kNI@pY$d@5uBh6Ox(8o3S!p1%Cg<0hXq)htFV2$nW6B(DbP4~(US`NF{NaB>O`@8NAdvqltTP}3Sk4u+Cr3uHKnw!OGZRLRPEeq5dp zJ-a!w9h05}O4Y2sT^@h#9@r4wRhD~Be&?P; zHaoUe9`BaNFX3UCUt>`CSwxA?^8v75mEZCt)k9p4s&3}BX~pdtgzf8~_C*hwuh$Cl z>r01yQ-|fc7rqFf@E+szd>!jLPDsVc1EDLPJRqY8$|~$SSluS5|D48j} z|Aolm(s9JO;W)x+sN*;Sr_|HH8IL27#c>2zI*vfs#}STm)p3LXCchTKD9&di4w4mRNs!n)5$<1mvCFG&B@;RSa*yg;VI3v_jO!JQ8; zIKD8^a9t&>F3*@nUg!wy^giHl^5K9JM`Qtq|FDFUcT2jGNTo}Bm+SIhGui4t1z>*J z3yJ3#xX18lo(hpIH6ZpNRS9E%gQB2bW0?g1B36hpyp?j8DE8kuh7C1__}!$W6gSC@ zHqyZpz3PcxUvfo#4X{xQ_aC~K_}F6?kJ4seWkrv_KVb>I{{8|EzAbro@AreOwf(i= z;2mGr6S33t{i^}BkpCUd@2|N@do#f|b=Di0RvVaBCf{xF@?)5jsSyiOS<^ViP6MZTFLf)N()x+mia^C$E_nCgx>k z?|Noc@jMS_z}KJ(Z5Laxr`r?yXq4V!vcfy1$l-Y&{7%IdSPABU&WbHJShlG2kP396 z&_b}mw z-Cd>#l3cFqk({pUk({Q$kzB68fphR}Nlni^^p7+^oCGw2c(G4k%t&_FV&egyls=-m zQ2A-e_Xt7!(}o*DyUMUbez+x0H|YL~Y@0t}dq7@(-M;NIzj3z9X1iG)dWLR-?TeLn zTtl)y#Lc?dSF?L}rRr(fb$dYu{SD!lerfJ%8{AW;^xmiRKAkR(Esqa~_Z>scTl|*U zc%KmOM*&3bV)$pkXongP^V0AD2N zp*_E}8r56$Mmi@J1z8BZs{*;CGZJllRUj78MATm8oT} z_3c{%gm9}=M31-7ZiU{ze}I^t)w^++RVrl}zkk3Dw<(n%vuCSR@RyWqb-^VSV z^@ko@=x<@EDrMno2?3;M9ln2nryHa~#k#Uo#Ub526aqVQX3hw#GMv`9=prGRx{>}9 zhQJC{BDy_Ws**#Ns`y)L(&(EB;rj;`Mz)lUkm)K2y6x1|YU>ttnE26j6?9O$(f1GR z%L}b+^(gzAQV!lR@G%b^oU%maaii%fVs{{C~sDoE?ZUoiITs6kYDP+&fhEO0Vig)^WWPz5$dob>36l`e#VDzGtJo!A(xgpEOGZ0u?;qhVvv z1vW-7$HpN1br=3=szZm@U82J4E+r66S3!q2UBtJcK=&{VB1uImD^`T6-gMy(*IrQJ z9T!xgMJWhAeE&e$`|{$de`-E_|3KbBI}*~hBdc&pJJPvfA7c^j(2j&tYDeOXFqszY z{8$TDg2|w5jY;1>cp*Vc+>8JjH^b45o7wO;vsN@!iJK8R;%1NuH-nBt6*Ayv#&p~a zGK?0e5;wycaWjz#H&d{Pt=K1f5{iaTg`(k(C>mr&(I|L{qH*!&C>rx5$|Bc<5#bN5 z;`nG8pq5+?s3oTZYRPGUT5>s{hSS<#>nP*y+Tiq25M5zD;tb&1b=0eT|MVg?Z?uhd zJ?&fC#=;#{2q8l}!?-IILj1A{Ar4m|gb44S6gPhVKy>l`31|KODKOIeC*0xv6I6cx zgrocY6LqQHKZUf)_fN1adm0QfEL|O#+YOeHkC&;&jSVoU-X^^q4g3|24 zi#=}%c$;1sZF8$om$IJ^HNJI#Uag}Of&|>(A*x>+KK(x7==U-H0KFPFxwU_NtPtKM z-~Kumsdp3UEA*yP|C}k4ZG5^fv49?@509~DsBF6x_ibtdYbmbV8SzRAMR|DuuRu2czm1&<2pex~71L!J( zRRid1ZgFyAPM>D@te`8$ZcFIu#%qDD{!&U>&%-9j@O|iO*$Y!Q*)H`hRKqau!mru) zF$3b^=cTTsWf0iS*OAT#K)TQ=!+W<3%&aK(vw_51>C3`Bu5dp>QkJwCB>&BZ!u{x* zJ+F(K!@q8f_Zj2YjQ%O3f5qsZd$ZX(k(q7(K z&(;xFXS0&5zKD{%(@cBgZ6(>GfXDSSJVZHOBy?AFh; zelF*SOfHs=n`LtO^8b19JUQf=(OPs&2Inv7Ukb%FnI+N;8?Wq4mn*5{@gL zcnJp?Z*`=W!p+NpGgEV?R@x8fiW%Q^OqnQ|An_=fDP7t?kl`-Sm@ZI3hPyzh@-7f(ybBbW?gAAo z-v#1IcY)B=T_Emw7YNB^e)!}Xj(jmlvt%V6lwoo(9M%`nH~fbPf4NnT$}X`rxnvR@L)?XvytVvEd@92f6b8j1OClUu%RAh%S; zK?ZV*E+>}kif=u6NPc}urJHKdTFN}Kym*3rc=WFJ+|0`O7v#4}dWeWUZW{)2OHk7t z$SnvO1G(j7BMPc~Div8eyG&oSaF(8?NtOIulL}|4NreuVIbB4LuHNR^kVvy`B)2}5 zZWW5hS+@$s;Yznks>L39@UfD)_QK5Q^vo=OR$e59X%xM(+!D@3h2%0VDdi91TfzT? zBsA1`^FT%!$SAMrc+=CbPS_WdNU?$Sp3Tc-gYT)afw1Kcpp|e}MO*yig;q*!>}q$G zMt7%9_tOx;39Aq^!&xOxH&tty1$DmSxXahOFKptbr=52~r`~e9?eZh+&1W7hOTv zlZ@8$tH~~+WK^+`P39z<{5OoY>UxPAF#9Tj*;0@>{$QsenP{*JvYkU0=qgG0%SRRa z2c$}l*;xAkgMRF@y|UIIuCCOwL0WgpVE=GT+5al#Pq5 zkfbt;DY}Q};p{I9`Fh|YqTdUu)PJRPe^$ zI0lv<29_U~7z4`>1NC`^0ag_TmLCS{^Lk)3u>3$Hfand>=LeP_7zr=xz&}4L_4%M; zSnAJjxe0*lod8$EUnUI8RNl?js^MB0%@anpbDIHU{{$OPLyh0-jbp8+G-J|me`+&* zo%%4u)8`qqujH`B)?eWUc2U=Q!``nZJ9vG6Ov4zl22hM6|cfjs=M4!YVt8d zsmW!AQj?1=ahmd(q151#p;RY>p;R2%P%8KJ$xy1%8Vyw?bzN`9^zh)mJsL{2Fu_nN zx6^JYH4zA#ZYWhmHk69X4W&W^L#a^FP%30Fl$yPjO=&0y5HsneAg$e;Mnr0ji>-JEwfeOL5T0@q6!sU#N z_N+cdfhk5U1x~r4R6N~KDp9hbROWOxkBY<0qY@&dBP*w#4wg*4SZ*Gb{7dtwvU92z zaIzWNRwF~0c~pU1(L5@FxDmsX^xZ1z3nBq0m`7zrL=hvIN5xq=D)Xp#x_MMBqw}(+ z3K7hsLIv}vP}w{xj`+?DGMGmdGnqual8P24QLj=37*w{x6ENtKK)Fd&N}f%kUTuMs zNmQIcvkIy(iAtPg5|uSAgt1p;>2pE2I_*lpO3#I$vq@A;b*3o=U6@2An43g}aFeL` zr%4SROrnYkCQ+3@G>HlwHZ9^?_tVC7eI%(!WfGN8l`0bMU=kH7m_&stUSl%)<7-UF ztR);wqRKnGvV?RM?kZe*W$E0oQ?cB3m_&tBzOuv_Us-Bt&L&ZDrB{~Fwwff9sMip* zG>J-p{GJj=_wz^_@@5j1rYfIA5;{JKgiOyMq2us`49_5q>CYe`!)SrZ3QML07N0@l zlb;hPSbheHD?NjRuAV{Sj?W+=tCx?Z5+1vkn?${m@Zrmk*M2x7$~|>48&P01_nk_48$E21EI2FAdYUuK{f0cRE!@|hU2_t(>!pJUgH8@nw zwqPn^r|YO$=yxmh`|)@dkl9tk&sUT--J!;31MI9z%I+bwTi_1B&^Et2D z&k+!l1R~lt!+qS^xagI$p;&1fg|3Bi3L3NGNN8ma59DJNd?QIN7dex&{&w9#EpN&1 zVErA>^*?N956yB^leY_JneH0jz^mm0MD%jQdRB1yh8105!;-T;KUKRHQc~WvIBZtC z7VfxfL8e^`y4tmH=Uoej?^+OH*MdsBmgr*F!ddTHfsuAC++o*(%DWbh?p=$zRJ&G4 ztK79<#a#!d-c~0Z-ISmo!wBkldRCFFw&gH z9p*Gtp3^wG=QMSx=5$D_oYS!4oQ6zuno0Z=b{Asxp6Bc!6qPk%zP&K9I-`fCQ+uX_ z?KHMr!9>4&4-@^`_&CBJPl$h`_^;&cg0b!({7_>zzda`YhQq6`o7N8H;f?2XM}!Sa z(XR!pbh)r$ib=TXQxYns=IYXl^d44-#giUt&4SNa&KI_dO_Z>yie`i@CCol zuh)+9>uX}Afzj^@Ura2Q!Xw<=;~Ix^bM!54a>4?JXU6_m?c>4^zm)B81~`?CqJRP6 zCm2v-C!@qgPUcbkYB>B(7!Xzx!l5$^Xo7w~)}ifANO_zYix(&acQ_Ej;XuMAI1oC( zfuaH&2$|qO=l}c6%QzIt-JUt;L?L0#IB;)F^Wrx zB-DF9cH@DF!oge`sU=_>Zix+2zK9K~67k*$!8qZB@FPwL8E`^lI!*`~h7(kY6XJ|G zp~z$|O~Eowh^ySMt8*TH5hsMqM?M_+$V%<<0n}vlXjKhIDbiD^EJq=;SI138X&7%% z70`@30LxGTSQf8*5sa*##Vsz?DsfA1K|S;rr@aolqoWtLSPCI!gmz}(`%TC_O=_l{xbhtM;?c|+ZcJeNqOrPYklXr4CGK{l4XmdGfPG3i& zD;%_Sm&tm%G~plCVwnyz1In*7Z7PyL*XP=~!X!k?!cR50yliZF0MYSwiH^6qNXhw8 zhD(M(INw7~gQu>`i|akP8+;~ePKaxZC2Oho>$Ob^jss=BfihnoF!kW6>$=NQeHPvD zv^G%wix2s=HQFid3;QVgluwQ}RQzmEDeWO!xY8aczDj8iA=Q=k@ECmMTwi}Kl=nD3 z70P?=8hqs(`L$Hu)5*o$D=yF`cRaBtMmpHTaY>g!H~7kVeeg-2;q{xt?9{a)E)@Tw z@*ab=6WcJIL;~VcAw8hqtkKq=5s3H=$8G_x?_J_YoLM}q#K4Jk+}eJ_jvTY&xukX8C{bVGQ9ubihf za`2V&nU+T4^^B^OxmLPJ#T_nEq4Gs4j_!-p7g^kF>o25LUZlc`7pah17P_IT8yu># zdxr9<>k(m9e~zAm8J-)q4>0Z8;Rf8^Bn3U$Y}>x8gE6vm_#$wvT|4dLNN4~O(4NIw zlrxI5gA_4Am}!dgnW>nk!_Z3{#?}+!QP#HYU%xo z^*7Dt^~IN}J}TZ{Vgygc@`Sc3wRt&JsHyltCo_~c)ZDRS$8I-ncOiLi-9CKr(3gSJ zNfYsv$lybbEBSq@cfDWOhn=VCGS}7MHqa>S`%-T+8XJW5y>i^I^CH9zu3KFQ=unn4 zff0qP3jy5mLI5(vvj+v0{sn$n{{n~WUqA%?3&oB47orRO3!Jt7MPQ_519w<9pz^YT zqkGw)E|va8NUK~nV8vwvGTrAe?(_AfZHDPJ8uxp#?YMR;uLtmP=RJDil3ad0keqfs zkX&{>kX?2?ket4CB&S~wB&S^uWS7a(g|jSzT@NHbzaEIrA{->cA>0(%y;ZMO6!Cq& zEpT=o6%sBP8e6Uh@BgctwfHoe+igLbG?@Rn{PtKr*1OO)tf0Ru?G5g|*YNKA%0!+Q z(eB+E5u>-45a6P}QUYZ37jVAM1ZP+JOK)(CFt|ln9OvcWCZ1p`bl4^Ongyrl`%j#& zVsAF>q9_}$8A-#X&#gOc#WtbWyN}boz~(}4s^EpDO<#@Pp=PyV@fE)R;tvdF_P%ng zZ$H)>j(v-7<%nG`LEmw{#BLGtzU=bqCQJxedm+n6+-tXzE?0H;fb`>c56Fns-2*b6 z-#y^*xi=UP?HtG`zRv(y z69Q1_7_9)woWNC_oC|XTVEK}u+?)UbgOVCl4|4)9w7^Mq4QEhYgDUihhqSIwwmK_T`CYUq*a25up)>E8J4b_>M#7=L^3XnPBr!j zG&7R`TV8T@c=&rSY;GR`?B~NVmk6p~1*+eU8}k76$r{~0Y}@%_K18CciGWA(%!vkzt&J6?ib%YKj-7qmN#QmXdpT#S% z4NEb2r?t2|diSBbj~}>u|2?DokBz?WmOVEM(r6vHbMK+nu~SP+i_5Fy%+m3(V~1P& z>=*CPxn;aw6J%|?Iq&X(?s21McNenWnwXSE2Di3p=kKAw;0HcC}N;5tWz@o*x0hl?de&`fiJ|4`YxC3jtw0+- z=x9T{UE<0~Myq$4kasz7;85c?I7mGuA+I07tuJ(<7Fsrv7yA!wN1O3F{D#M!eoLIx zEY~Zqm!Q4_>nnUpeZ%seZxOEF`?Afdrf$NbU;mY_TlNbZ;W8+y*Wl>9R(gQj=KGR< zwc$HLYfFQ;3IYTZ*5Fs?tu3Cm=5PcGt5XG$tGE%%XfsCmWzViYF->wT3 zMGhAziae$3ttwo)KyhxkK%p8P7btMb3lyC30tK?TK*5zRP@qlDP4{dpe_qKT;t(K; zI2?Z?N!9W@Sc2H)3er%Aq*&awaPyKdEf(6Rc-KN!5nF^z_bbrxeg!hzuNc$sS0Kav z3RHQ&f-~N)h)nk@I1(-gU5PljhB8Jjg2IZsY|OO;$- z7^c>^F0#t`D2}dhE!%OI#KfxZk}4qUOZq~kx>aMcq$^|ScrzR|wAZ|BSzKX3l2cF{zrtgwutpfv3R=XD3`H5CDz|mti~;{K2xzS7V8n7>YC(a5x0u<&nwn* z#d-%&wDfp#$WgJsmyp{t?`H9Sz))-CvBKksJpL7dgDGaq>kVT5Xphima_ISTM{uAlD5NOH&nt1<5kL3SE9>3L5m`{uOUweeU{8l{vTg-Du&hvJ8 zd@_0zg*hUR&*&2=&!)wOACUSJPm>W-zX@_=`}QJ{?^D>f^9p&TbyB&O9yMfAezvA8RCZL?S6p4#xGL(lRL zFOO{7wS6~zf8|bpoo)T|k*^^AU%p65n5NipbN9&BYeq)45|GkGl9E!|k=-PGL6i6+ zAh{O*vX>G6&n`muY0f(q z(@*gF{=T?1?D!^a;Z5}W_41JVrXKk9`+oSddiA*BcQIl1SyF)7f$e9yjn_8-u+_J)*yR4j;PvHLXL(_U}1*;P8Pvj~&=^{Mep-9GZ1dlUfI)u5U28)1h_IshH8N zy}_BJ((lM>A4;xN2$6ev9gULGE32R+t&~bvrBjh5oP?|zh3-qIT1=%gQ=OiuMtGmV zLER2y;Rtq7bv}!(pi_&}HS$d3ExBBCE;$|OPEOOvOD;RJ;_`1mf+dv7gPdja0hxgi zPtowJ12*n-_=YZU8C>~{E(c#qK0|ja)S0Q7rSNfWoZ+|+h53Iz`C?%LFknoMp3Y1l z0_=z_K$aSwII~&)ZsY>oBZDCdTWX}@?gCg6`eF&U7Y;8@>AM2BB47hqLOD1)upT%7 zNdXFSNBD$7LW@9L{1^@q0Vc>U{7K#?`8p0IfGkigTtQb;XVB9V`pUJSn^NZ!cctlx zJ7PppWs+Eoh@csYf6_rlk2b0%i*&_qsHDXV?RSk3>0w!+5=~;hMUn+UvNko2^32?+ zh3)a8nzo9}GUSy@O5Jb^&2QDk!x)y6?ZxBd_Ge*YULRA&;m`C4o-vPbLdQP>AhQ!w z3XcA420)lA2@xV(csB?Yfi1}V$Ph<(dk7WYBSQHTMF@YiC{BC2O+6l*S@!(%Q%5|@ zXOK9OI>&0nMnlPdJ+bs3sVMedO8x=8t&CJJOaTSPTW> zqn<$c?g{N?AC@Nh{8SWu(J*FU=Py#j_U}|HuoVh`BczB4{*WRR1!c8Sw-Uf!!V<&R zw}bjbHU)9xn|x(Fvh_7@@nx$Mw#DLaCyL9&DBj-Y_=-mKkeaC@XQyd7EAjGE;W=)~ zy0vHz9PnWXpPE{2-6DMioF{J8SILb~a~si~*D3~CLyF2qbyS!$t+~aCn8cYhU+}We zruY1uddpiD^QHd%by^N0_bHDu-GfKQCXA66VchU+%7Radmv}G%;%6t^+-!=GCOpOy zJ&m|7Bu21io7}4tD_Syfhi}}ISop9#A0>}pyN3+kP_wfd3=mT%XQu93Ii;49Ygw%c zf$Ucje49Dd1e%>@MgHXD>pQeo>GbJL9PGg%#OiW;L6c-u%Vk?Su_t zXiW{|;(}%H|F?HO@KGLR9-k~x(b9^PDqc}j#7b*u6G%&{xyqlUO=_T_2{o;FOUN!s zG$iR}1EIy5ehzCqsp5&1R`jUlu6UwS#S@h(Rcfi?9jAEGJ5FN{Jx)<`$|?3x?)RJL zdEc3L-_5d6&eQw!ZI^uKnP=vmnRniKXP$Z9T?wts^0^lBEOxChG@I8}Lh}8`VN8{a zK@L?_qSrAysrNRnx;51!fp3ks#VGM#0-$5zZT9W~VQz|y5YI1X=x@*9g=JgRX|{Xu z?r86!26B&meFJptS34lJ`(819ZsA_GeUNd>lN}gDyL#;J)4$RR@Kow%gGy*c+gsDg zh)AMVFW15a+b+n>8b?{)o>f}#o>j^4vQ5Vw-Nkze8j-KYcvUzbHJ8fOkGtKzI@CD_ zbJmsZcGjv-h@AH(ai;b@+;j5NIPI8&!}4^PKfYW~yVM+-L}BgX{{*pQ+4y0`e-{Q@ z8vzCUC-HYlfG)?J8{Pv!<(__U?gH@Z$x~ zny%gu8l0trJZrkjX%I0)$uyxjbC9I?|7E%wd)Fd5zWg7XxQczb3A4Ds8Y#9c+xca> zpm+`*{q`*%oXVQ3V7baQSBdEQ?%w5X-TgQ@!f|sI%v{b~1r0S?POdI?fF*q<+0VC!rgq^v{rJ55T!mGWZ?3|M+?lH|yARA&kVni_ z2#4k>uxGA9$eF7cP;(WvJaZL-YFq#X<|?3?tE^DWRlv|(1rE$rK;K-2pqi^t>eHC3 zsOy`n5RRIw&?up~%4Qszs}KszRY2cdgGbMml%1RvN4l1lDlX}h+;h}iuEHZdc9k$U8UHC zcCl_^#rme;t}d>ri*}zW-XrHs4JK!9lEGBr3|#Q2eJ1zc@9&2K3fxfP{a3u<=@~h} z6&g9DENAR@2v5H=X?EJOi?8gnU;Ur|tN*!(w0HjhvMca8&VE7sdtD0k$kR;}q{oU6 zT)upA-$=8qCY{f-AaS#iuc~3@hZ$5b;R9k00vT;$;$l+@QGdU)Y;NI#opD{yfZQ?%fncjX+`h*Q+HUD%KJE7TaUSo7lj#>Tn507hSJ@I0$AK`$ zx)g*V>uwN+!ZawK-S?LmTM|L_X+XevJHQzrTvu9F-w0Pp^a{_bLPmF-3mz%riV*^S zQBu4#2+nx}A@S(|sGA2U@cjVl3fo1qjr|`>hJ%ZQ)x9JP2mU9aAYAi95_+%rcSV?W zSPwYK*v#eHhW;`U%LH6xB!WE?-+gK=L~v?R!!x|Pks7`!w#&f_#e1O=m)QCCFu-eT z|B6$PMfJ-P*C9xJmm(_6Qu7TsFaseM-0%^zkBhZdp< zV$L3io7H)hIqMz7fd`uAh_$~O{;*D$0*V70O47H|xk4e135OmIZ2t+*j5Ed6dM%dpa0H_}zNPPoA&SemRz?BfF z{)M1$n5RPcy96^(Y43LlE@Ne^bpbVmqCP4>p~ItdgS^}-hrdgJpc1t+Y*DA z>VR;jz&8`2T<1-Q(2LX7Ne=9sK3^kcw7*LL_WVSlChnsEaVSN6ct?ZP_mrgHmCFo* z-z5NRpF#TIfs5-FaePHo#4#3OeV&8VjTYp&*TOdpPZ{fX3yittGFo2?2g;K=q8B>) zid3IQ7*uoiULf%|XAlgwZGh;Op8IjQ)592lTL|HZi*tNe$#(HHZveE6zZ-?5!9Eo* z+`a+_-4W<}W{2+D+9MF{@0KAL?4uFGSGExdx8cB2`~}!fLy-^;cJF}xCf|9%<{vwJ zFZ!^2|155D2}OUiQZ^IA$ef?09OJhp)f2xQWs;3j+4P*r#z=N|*(d51XpNr!u4EtX zK+Xmc4t7$3n$C(No3Ds-JF^JLel0+^aG5sP*d=>kdWm546$TZAo5l$1b~4EAG9wV* zhelnHncJ+^y!_WMAhM^I%3&G}xDuy;Yoz_Uh6=JBVRGEyDiOiW;dV32z*zWW+7pc# z8aM7yIJnt2izmqoq{s> zBY2w@8OSTNR@_MON&CjIEfJ&b$G+`)ArS%z=nov|Sv1Pe>;yC0JPy_7&ozhY_NNjq zaguR(qZqOB@AJu8CrzQ1vN4jAyg3~F`&^rxZy-;y?;!`L<6GSDGdw@6^GE{a`9-O| zGHmO6grcG6hzQrqa0ikL9vlzae+>=aDp`Vw{#t~Vv~(rs*)`7s*`TnRmfMy?AL!0n1()?hHte4)g=Gv6Jcc!syCGSF(2dPq$%f2rEuDCXq!tgP2h!9tSK}k) zya+e=M-fs*jv;(lG{862?6dM@!%d4@+Lm`qN>_|ltVVcTg^%QQ5bK2jgqYWLctEtI zGb=IXXVd0BD@`^HWSi~w3xa<6pDeWkulX7zM>C2D!H3b3A3}(kH)m1A>v}V_aLuLL zcyGq+)hM(WX3eRA?(~A*fu5|n1tYXgVn=vaz2?>Usku&R7qecK77S!E82Uxpl+BpW zXhcK5$QrOR>uT%9Fq1OlP%h>i#Gt{ZtEeH>oz|@DRMgmp2I)*^RQ#5hrmd502G_(F z&w4g4Z_1cl0oUL}$gADfv>Pp^3?QuPgFn_7}~f@$U; z+>y>Ux6ErXi^I72jc+h3B?g)dy(I@M)OF>{cCVaY_c&sB(lL@2SM{f6xE*B zyjp0%!df#Im`tX#v$Wv-*|w}{&k?q-Ol4B$opI^vOuyNlBgR|GZK+JM(|kK8qQA3i zMK+l+zsW1_Hm^X(^@}1InOca0W<}{TS=+F@0`8vt3>Ju+AX(6IQ|!Gqmf zupE``MW_SIXHS&-m#Psa79MOPiJVeq%v}hr=*Le#rB}4!k!{z^*q?^fn1%R==6lc* zd_q!_%PhRE)c)3FSIRu1!roQcYs?`Rm}7pa0j%GXSkEEkH_y}4tiZdPlVii<&teUh zU~O=?NVw0jYKiGA<5Vl6Qx&^S?vFhOGneP4x|a744tK5{Gjk>Pl!?SW_`izf z{3jq>I6v%}jd($>Io;8SwV2g*8UElJN&aH|k?y*;!k9nDpt5p#dyek6m<)$Yor)Ft z%Gk}cB-Vo-h~@JqvC-%$ePWg2d{VA&pid1Vgtd0>K&CxCFOz9ogRp;7ei`>cA0)iE z7*iMaa!%OP1_NEc)pR8v)gH?JCi#CJU27xL-rCa8oUObH-KeXbz82{FR-_yL#rsDm#PA^1Uz{uWOV@*C>8`n5zkJ z;?rD=!2(&Y&K-JIqmzHmW$j(Pv%eG4;lU+TS zW{))v)|s}vsVk8HORRK?3G>yW&TPw@Fn-$nsgG-F-03o2V-(6iQkP55&8gm;pnAOn zS*>6G6RpwYkrU-pH4hhiqI?gOI`ccd!~E`BhKV@4boA0h8aIDt9hwmRXLbgbk*<|# zuGe5Xd9TDohsaNh5JTkYTJy*GH1jscG%RZE{TwU84HCn%xu@02P?%fd4@gWybFcZN zDxJaY{PVm?&i-y$h*^ytWxC9Y08vBfguOBk$lK%1gE4i?$~ei$uRbE`yilj<;Zrcj zl$Q21^InrC)ja*EG#utxRNWqnsTZtU0+T$H_~zy=b8&#hHDYT_z2J#H9;o-4y@F`Z zBIjS@@OaV=9GkG^ZQc2r;0$`_{Xvq**c-XQ^PQ^B{NVHn^N$QOurI_~MTeC5u$w=1 zw#d}^3%w_A>Y|6@^RdK;7d=n%{AIsYl5;*CyPo+{nEQ~R9nS}|gV5dEVIC)795vqq zthRB#vc$*>u&`TgV=o1@s8Chrg&o&N8Rq;(!)wO>&y~;|uc5S7(O8%1ZQ2tY_uv-|XbG(6f`hE0S;} z>PVa0y@>8~Pe-;>Q#_y%(LwF(d&4QoFFOC2CR19D&5`2PJ9)IYy=3xZ0nKj95uY{>K6@`!lZ@b)>4?t4fo$yVk=`D;3 z*7t(2+j~>d%Am{p59L{vS-Y*849rk+f7ID+4VDjGWmcpQZ49!JakO&I@-}RvU}KQq zw!vv%ARyOrx_xubTt^6sf>A5`U36ZTj=4uNzT57I6ef&;CVyi zO1_vdCr+I@HAMb-iREFBH-Pc|QTEtK#zp3_nL6K)v|Grp7v4&KOn4jlyTaSaR|@YS z|5|t_d9&~?^0$O{lNSl^A@393OGbfM=6z&XbI3=)iMynr-4noH5bh(tL3rKyPCiUN zDDp!WfHm!5@^3JD;20slTXc?)Y3s*v3|#UhIdAvdAiq#_Iz3K#yv*aJ9=Cej;&GG5 zjULx~T!oZ<$zK;9MCJ7p4B^C=^1K7G87Ka%#$k{3&!Rn*aZYRK4T;CZ{fv{`WCR?#0M&lg@xzD0Nk z^;42|4;fBH%x6FOv%*Koc=}UrE=1Z^Nn1+RJg0(7J|+59o=&x=(?XrKqO+EKf$(Os z)@3_+jmYKvVr?Z7zEBbpqKIrMx zPJzzrMW=XX9V}$n2S&+mnoHb<4e<@khc7lVneV)z+PiM2Iv-DNa*Ez-(GUgRLc7ucbCtm9EF9RnwSryYt z`SYbb%g8#e_K|0Ze7mPV;nk2oF7hd4y)KR9Cq&*##!`lLTt>!9h1^Ykm++v+>pcDS zWX)%jC*MNWe72J{pPiom9#4Otr+?7XKkVrr_4G$Q{ga-4=?qt%iDa$U6tb3QI$6t8 z4o>WlwymaI>rzYBw2fp<+e+57-Q=y(K11ZEgonY2t&-T=II&-JS}5NqI<4f#g-5CL4beGC`5Gx_Rk`CPkC%De=kc(| z8$8}g-YIz=Am1W<2%Oj{=RHjRyzmGa<>5Gdgsk;FO8&Cw93%go@F;ng@Nx2^!Y9aI z5jHcyTE_}-Fh8uPoQ6Rhos{dEWi1(w&cTz=>Z-o~`7g!YOiAx#iaU`%-ooHf<#DygH6G9P zxYpx(j~hL1^0>w0R`ToQywhi)Jm<+gr`qFsGK^>Jhb`o5ggZT*K~HC$C*MG>7X7WB ze1|9BO`at>2R%MQevZgT$>W4eXFL7LWYsD2&Q!l2j32El5=Ir9~bT;R|+>(ga1KzBe>*EQpcU-7U3<|Lg(e8v-9qzbp-azgY-bh|6yosC<-b}tt zcni5tcq{oX;cet0;p!V)*>;ifz6{5Z!wbQ9Pk`LC$no|Y9Zy`0e6&p_leL^v$Xd>+ zWG!bIS<5+{tmT|R)^e7UwVV}XEoUFNWRsL_9l2Tf1o<8*=fP%hm+(olw&%npPF_t` z`4%$XNMaqw-wf{2`jWpY`R^rvNB9s~&%5o7j$3X)Io~er*-E}sco8;TDrRcQ03Gz>?4tc)t5pvKsmO7oa9&aPRU&}`RitsT{r}52BzKpEr8uH{DJ^5ab z5C0kTpO7*iCx1-1B?;Dk-bdDcUeo4uMm#>W9P+P8+G8G@b|;_g@eGe^JZ|zhpkA$@lKETd3@O8QIAVgu5430F86q@$1NUrdc2OjS?a!#{I}W;p3X^+C#0Ru6ma4Z z=_gakdxgu$j|opFe?)i&`LBe_$sZD~Ab(i6io8|0n*7(oHRK0`=aL^3t|kACa6S1U z;YRWf;U@AIgj>j;6mBJdN_Z*xOTx>@dxTTuFA8^(cMA`LOD>lFyo0Rw!U$RKk?|`W z*N|T$`Yq%qg*TFK65dAEYq5*mFY?{w<8od0lOGp8OxEjlk_^Xdjulfoz}tj(b%Hla zK8Je2bA*p)!M6!-S_SSE-a!6-iG4rSKHQ4IIfW4bCZhlgSp8EIVLxwXPfm8wJ(*j1aj;?n@91{{E*MkIM%~I$`D{YmqCG^89G%mmfn*^>V41GGj}G&%J1Kb z)Z;QIEFU;GKh~M?oH7=pHwjAAv)AsO@pcLFySzxf1-_oScFg*6dR6GWWm^8FzFvX+ z-s0;OxNZZ!UV-Z|6wxzdwlg>T@jv^iJ;u5o92%(?+#_S@od+H21xFJ)ZAeSPK|qOup5|MI#6nP!pcWqrDlv_MgBgPzgoI>> zRyUxnLeeNnoQ%F4jWd&QlXqHTGF~P;Z=ohS9ms9eNtBVvIaSt(O~#A)8j_pX@9%%A zswrDc9Opjo^W5i6la>9w_S$Q&z4qE`?^9Y&`Gw?@+lt>cFNelt3cu^`Z~lxi#~O`a zFvrJ)KQp_E{ikK~rq>S}%6TuA^U@}rkM{!R1BH0+<@VFguA=3ngV9mF^TT-WoV+3a zb>)A^FSLMHX zrhO`O&Km7JRru=g+SjLzu6_L@fa|p9RsNg){=M_TV@!K-B4Pgr+Vit1n+ZPU-TXmw zY$N#B5Kf?cLa?h?9z#QY|M~QDyKRz2e+i&==Fn{H!Tx@G>S@{7dg8{A$h8M`^ktcc zpMaLVAB@^%3TGRWI&LPtR%4vkY&RQ>nVk;$N9-?%FLv6e{*tiCn8Q})wqml?FIcTt z=S6SUG%+^QY?<4Nmbsxg#F#!SN4)K}V%_??!r`BLreL?-m3MR7^0nrWZDx*^M0`1J_8k?i&hYxzzscAwlOt}uu69lE z@^nBv-3hOp;We*!5!MrKBWxh-By1$yLfCAw1q&EKdL!v3!u5ow6Sfh)kI)5g%kUwu zFD0F#Zawh@FC-f{L|l`IPfP9{D}j9;=rFc@Fx!Z z|B3@YZM!rEm^0(i|0nqW8em8S$x&^W4kcCxoCXX7h64^z4>SOczzCoTz*=h0#-0Ea z3d~)y3ytwMnE05Q+`s;7u4c@2OXhv_+$%1-V(Ge7#?PBJa~&>XA7 z&iN0^97_`ZN?~^2(cGqNtQSz7e2qEwXwn?RC_LuYnq#%JSqyxWc>54@EJIl*a9Y9~ z`#7Q63#W1XLfpv`W{a|YMBjc>*s@*~|{#gW*Xn=Z^2-#l$w-g3>WCEM|K`}5cQ%kQr{@|(Ym&IQbk#kpzBkGAEL z&M0VKR500n$r|(EQQN5x6t`P^Y~5SKDbAr#XR0ZVAI70|v}vOa)LvhK4@}HxR7-zeryDe{=`y%=uuQ^n2nM~svXGha-!KpSnkK9+T zOZ!*i^i96b5ve*)@gl2-OO@3n|AYhcN8o18~3rIef;Jy z9qcIf-|+_h_~G!(q@(cvsAS&ToQ=(&k&PW4R$5QvQ>-~~b(=$>J;aI5x>_??WK8os zlXWy{fTI zC9X3|ES1flIKQiyaF}PeBRp|F>yb7yv-?KIq4To-{$s?CYCQzZ|2GMBj_D?hGjHl| z6!_|fm(r|>x1{Ys>DZt&eY~Z9Vo?GA4~(>+p8!n)GJo zxV?A*`lvIr3;)4CBWD?SV^Y>f(LapwkvIE)TgjJ9t%}AK6pTSWX8NJyAb;SR08Yv7 z#ptkk)X{uvtw;S(X8+k{*8Tz3_{(9|E5&EiuS2~%L<@D^M_T+$c4TA6Ii7a|apv{- zoJjA57P`)E^}|@k4@-WCOyPL@z85RBeg;~T&|J$pt#O%i&kxTAr^fVa&ehaC8qEtb zs(A?x*O&BqthGBdUFh#DV}u^H?JKuEqA=r!Ll|4q z@xwRRJ50KpHE3Al%cA~g(EsCI&qnkhCsF&KmfJr^sJWE>mRtzevnosb;frz6mnq;w zX_{aFXIH{CyAs-aq(_A-?(B%xym0(Kw9_1A8?v#s&$Aa0_PV|FySTvmvoxQ^-CsQ9 z9*^?yZ8S&v_jrHYQQ!1g$6lvC9dxX4UdTR(Uc)EkhkuFukbhKrCo&PrXEc)aXpQm< z->fgmi}u z_PpqSr+VQj>Q#8mS_{|0uSmCOe2gbg{gLIqMwa_}io8*b>0eYvXiQhpqtBUD{cmD? z8v%{e;7b#~jKLuXR`-v+jz2@~^p0~S@6K6Yq#O*}~=ru24H*7D) zy0!K)g?`JVdYzZTeq-fbYPd@CJ32XLa43|9kTP z-76cRpbO|sW|abA9{W$24T>EDDdz@0U`U!W8umIoHs3QK6RgYG<|<@bUFogs%}M312022#bX0&<-1|Io^G5 zKJK4U6wSt5TQL47_E7iR;OtAWzp-ca9ZJ6xe09#a!1L$jd($t4>J$3*UO8z8wFYm){bk{9eP`Tjz@@$O7D8w)kM%d9^3$2EjnHme zE4Ieq3q1HusCsTWKbzSa6MZ+6hkev@BO&$no&}y&#K~{mLHusoYOcihJ4kOOy___A zMXH1N+H%rme_exqyrn5n97QLl+Q)i@HQHTM@Glj=+T#@o&)qCX|$yL-(~knKzX`AS*o zE%_JBSE97^t;VLj8m&j_R?1j=%@NK1f!R})a@ki+^W$yTp@V#_(3L(|9O51wY+EX`IRX2yd64}G_HM(3! z=ULsCau1gu!QH0H>p1sT>^$Z8xy(I z9`6jI19}JOsMMFenbA2Q=NBe&t{>(x&%&Ma!!@4Hqa~k1n|pt;4H`rv_R1{LyvBL3 zX^oR@T4S~~VP}q%pJh#uElz|lk*yD3W=CfXaC0sZUJIJ>d6apxsJ`U;SX@|Ry1>)X z1Yhdc&`%uOdSclo7Ju8I^KtT$l!>ox^!Hu6H+(cL8$2W1rg<(*WRXuX#`GwY&Y;pORY;gtQ0e4sNfOt(@Jem;6+Tz0Z%&vcCEgpV?vL~SXP43~f zZoW?1&ZUDlC$;B&^0$yS-bF!YOM7w4{&vRT7q)?Oo7G;7yRqVyF*}Oc9KIM&a?w%T zNq!gbxV=AYquzH3jn`59A?LMcq1m|Gi=%UXVL7;$gL}E!ksr_LOkj?UAYZ!aQRuV? zA0TAR`HGB8g)c^bTNLsZK)@oX_yEN>AOAv{aKgB3taB?qhl-zpxwPBxGqn2Qo7fR1 z?T50@M!6*&)8=*-Z!w+4RZb`C$`98Q&Y@iAInCqF*3P2IToT0HOY(*>bY(h=59B(F zovpiyJIw>dEsQ1JYKmRNS&K!VGU0iU@H>oc4g83=brxs4oydvKqg&y*_ScK@|1LiS zi8m2P`A2P}Z@a1cBgQ0ONQD>k&Me8$Q{-2C z&l8Ys)>g?M4UcrDoey1-^SFDT>=I;sab$nWS9TY5t7mQX1>y&gP=l#$Q8UHBCB$E<_HZb(rod zE)Wgi|25%8qji)iP(KxCPM)Bx%Kj%Ic4FZ{vn9XE*@8|m$1VdncO3gRXLYB%uH+Ze z{(U?3jq?@OxyHMwpuIb?xiiRUTDBnbO`TPlY;j{cTg(ER0ApxF|FR=AFY(APbXPH? zuGaM@3FQmYxql+OMpFCGS5cc)P8TNhqDJYl%3h$cUME`8e%MQ>v8*5zy%m4M5~bmz zm)=qI&=X6`^~87aT6*GQ@;=Wvf3Gtq=}SnvnpY<%B-tnQ4#jddPmZPimZZ}$ZEhJy zg)eGzf!ffI#-C)qq|YsPZUb%VlWu#{^g(SNXKiX6@~fnY&qEibk>$8)D8${18fKEV zocjEQj^8+%JuTYjm?PQ!NuUmJfDyn*Kzhst#sSh((pMfZ6_^dEFAF;5ua+NDK3yxl z?E8CD_Hc`I{~hf|lje)~5lZ??c;tJo;PT#ri~Spa(euc; z>;?AHSFGc=g0HJMJLtlf-FuXI597zL&v$}Dyl)fFOu)FJy(+{8ZvHpyniaWS#T6c) zdB|amVE?r~dw2$LEF+ct5WsMF#xt0z8{r8&FR&aLw+exNUsxBr1| zi`LSaTcZ9cE2YP5X=E)oTk#PEn=*UMme?rpNH=$LXJR=WoR>Jikv7mG84@kXwQa|B zEvELWYE$1nIFL8w*AC!kaDU2!S zDc(+8;Z=k3Bn#T-!~@Z-eNq7Pw(_NfAEIS zdOcciQ93t}*1JLFYb^2$pH&n2PiMvAiwg72u4(A$Y3PDkv!il&$hwclQ68_(r{mnx z-K^->T6>xMw2HkUJt6!L{=VPdhK#;^4!rknx1;-}@;&PCz^~`trhaK|S8;gj#Mdly zTE4EAwaOW5v}5JpXIix1H*@YmmQCLoq?xp4_UmK1Bd*-XzRBGu@)T+h9G+os1c&gTQ=Dy<8sLg%FG+}hs^`vz#zh37! z&UOEd{8i+AgAkcuJSADj)=Zv8zYD=(F$M#_Z$S3Pk(Mk(`=QI72XWbXAE!+A=>x34 zCx8bTuVms`;x7OJ@H4=U^=s$%Xikj@4!Gjiq&e%-)Xf+)keQV^2%z9M64t zVFP*EYbJuvpH!mljyn8oaX)mE+?i5e`boB*aCd`Sy2l~yxH^aVg)-Z1n@k9P4kSaPJY zBzVsL)k(X01#hFZzvgIjobi}6XNEFQ*|VB07kb?iPhX%dwshDzmh+?H_1RY~w7?Kaqe4L^F1oFbG#p5e;S7Wua+|T6s(MY2>o+7dY6)0n6H#$ z6QsC@$?F~l*$6usv*v9+d^6Y^3&p>uIYL?{j;@Mj2_xGBo`5s_4D}~6o{7*GU)27p z?tMGQ-ruA-tsl`*Uq2$SNGB}EHl2-|i*056!YllGt70*qR((g%*|?+FXzDow`!Q^X zk}rokCoY}z8t?M+v20Km%+L8WvH*X&xf`>13&9vuQJk}1Y)F>; zf5M+=`Yxy6ZthyFy86hka0O}IBO`--rd4N~?ZwN;6OZwkhVkC*_KCapB~!$?n@Zhz znjiY7b%(D=Z?^1YoJ*p#9?6j;P!Fi({JXT|SzWZG1g{6gA6Q3+}pSwR)+WyeVc=s8HSU>nZqqcU? z?R4a=u^oBlgLexZMQdz3esJcQIOn3`?|)l5dtpnoSL{*rLils?qk8UE^iF&67o;Uq zW{!#5r}*BW%UID|Yb`SGg=f)yTBGpbm~Humnvs6t--t*0VVG0en}?P6=wbCyy1ty> zG|WWlrb@lxrTW7CKf%FTiTooKUiGOD-izsNljNT_UITaUzalO=qJGP~)tz{Cedc?h z{!fToC0wZ&iMw?^ceADb)W6OUm2&1i8qYw!W%8A}725uZI<|e1wr5D|{Gc|cqHW)x z`u|u}|GUI3E5eof2jZ2!giH6qm9lQ)8gI;X_y$FH8znznLhGb#pGYr_8R>`G52Qoo zZyqxa8FL9IU`s3HZY)N=%G>Bey27*~&*%qaY}S0%uY-R=cl@%yYv8@!5yUeW=T#@( zdZ+Fm&XGQ8!vocrdyOCzfk9zD4F{eUv=}tDHnKq(9ds%d* zN@gRPV_t93c6-@-dRarg#n?Ff*dy9QD_$x;A)2Arw25Z!hS4#idm(ho-%)_p5f1(p z#-+1$y!8_3*8SvNWxB7{JC~%si>Wa`c{Q;#8;Vw~3+7&AYH?FGP zsPbGU@!h5vpLDD2m}J|sAnD%|{1n&ODbGyBHiUQD555Jj zB7F>hCzRz*dPI0D{siectrPh%9W&`Q{E$aSIsVb^{flUW-ZwjV>*ybi zTrRX+JHLnfYsZw%2VL5OXgd)cqns|c{3 z|B2>6Y4jDo#ZsQ+tB!d~;?I>&HHkB<4f7ajsRp}MI zPcu37S9(i!$U78R?&7@V9e71N&>X3(-?Q@Qw-oy8l^8Y(d$28js4jPik*`2?<Fq`CC5z+b%gklbTe2Ou=M&z+;&9V-bh!CK z^cKuA+wwY_*vysoOgn>)Y(*c#8+1!}F6}vc_2A>!J(lLgo*1D-*Dwj64X8B5=0!aeRz-VxaJxwwE0(yaDB zi%GvOmVJJ>-;qqgXXn&>J`bE{Lc97xZqXwLiyDt?wZY?29qx>yF(H$<^ACPUW7s&B z{+R#D80xqW));npaVz+?EY_fv6mFu`~%$%)Eh zzzMRDf1kGDQiJdzQ3DV;zc^^)>vVnTa72iDl#&@^mMwJVU+3v{zf@;md2R1<+NEaiD_hvMOBY zwg}fe+Ewu5*NF1o2@n3q0bJ8*S9!Bgq3hkWn{Wym#)503hfYH-V$3V|fCbHC4Ed2< zXdSRX`r^)!B03To<*fi?MxF+EgFMF=XCpjoV(uee$X`^c3&Z$d#Mh{ffg=1ogkS4vOn?W}a=_x>^)`#lx)hE}$obh7cgL)NHtaJQq(6IY&mw|g^X=$Rh$ z!0zS5A)|-&mXgnQ6>05R@-qkra@CVeBOBd*4BvR)M)L6C_G}WQkx_b|_ z>{VaOctbg(>u$)n78`hV(c*0I@6w~_d*)++554A}>v;#%=rN!0u!(vN>9TB#Uy{3| zcnr_5k7E`eL^NqpoS74gn)l?(}PDlU&?yetmz*Il?ENJ^oa)-|lRYc22~KA+2*uGjLCKfRSkMkAk@_Ov8zv}V;# zY2kps18Ik}J^Pp`Wgcy;WX+TqUnJHBq-=VOd_azv&&m=50hYhZ*=+niJ**`!$X1 zZihuzF}K&D*G|fs%I$&jhl=0C9GNCL5rSL+0dCUc~?A$_E{23zJ9_o3pv%9t)axkj0Pg?(_Hxo>w3F z8h1YN9R7pni!t(S{2lUj#7QSe$4MthpSbj-4z6cjFM|hZaK6lYMd=_H*`0&WAOU{% z|K{8j?jFEj>C1rUl>MlWLHIlW3vES192!`k&GX(Rp6aoUcn@u^_#?b{dh&bc#kT)K z+iG6Sf0uZwc`@=mv`Haz7VB*ldSgx3_WV?AmubLsY?&FrOklRRy_iN)e=s z-uSIjzOo`sfWZd&#oG&}@5tO>TSs zOmwuzno6V7u^V)nuFG?u;HpU<26XA8A{54v?x`0T^mf_}&59!_Wa zYl}9%!o`j4VL#`I;Q)0Cp3^>=^knqoEYYycX}3w+Go1DYLR5Za--lLk1$zGaf@q6p z=jV^`yD{hk^zBu#^GY-~wZKb$rv`ie>cU3GvYdRI`qF7?_p+n)x2Q0wT%R@9z#NWb zk8NOIuh;qVT-s4LK^gZC`;wGJ=WD+2DYz%g^3`)MowYHGKL+Rox`3U)1Aq^F9rz~D zk5Y_$Gtj_zcWd94FI6(2buBujKjfo{2fg^Gus^cq4F1Vzd2l zE|6gEvB{c;IiqXeUR1!Z zL7nKGcIxN&AS{>P(a}6mZ;zJ?E4or+RsDa2PVqo#*~-VUl_#SA*P#F18M}%r(fc1q z?|%%vA7dXtzlRokg3W$Bv8?}(SJ`M9kK3*Nm^a(#fB8+5=z5boSlrWnFg%y<2$QUr zAr5+%x6$l6>`^uHv20yvNxQ+M`NmaQRV2PUqh3Ke1oHm&ku3zfdsky|)#u@pqs#+w^u?W%sRr zm;F`KIPX2Qd7-?w!qC(o;^~Vc-cF}@`U3m?d*$ha|An@Hh^G@zL92M`z03Zpd1~H6 z8?BFMJ!B=H>1drup0OWUSI-t#BM&gUXCk`nQsOTWznJhR$ne?Fc?t2)5ULD)$9;wT z8Ig?le2Vlz(tl3+hv+Z$Rf~O!E;-B@CHgk&+q|XxwR?oUE}*}~>_uj8ZOL~Q*`u^c z=qzWorETF^-Rj3KZq@fT(n0!mxue1GBN+HjnoDcABX8Ok>3f&Ci>RYME$1%AmJ#l# z-!H4r;7E9`bce5TUSBZ5+C7uH{cq>k<5|Pfw|)ON-yq$8-hp7@{`R12)RXAmD+15q zHy4~W#bK=3`x|}~JVKo-LcY83?}2yM7xe9l%~=*-;9jeHe$j4S!(G8;LE7d{yL{d} zl`bpME_-~D{D!-2Bbw8EyOW9b*618+)_`MCUUxyNKLj3H{C=DA&?WGG9sA58+O5$! z72RCkJEODcnkMNol~vYJ$&O#svRRT0#^%qR*#aM0vq6mW^r`qT1U+uGUK(i4*zV@Q zbg^&Jhv%`c;CHX#>}7e;`1YFC@^_-_XF8)R-vV#aJMtayKXyWMP&vn|z3S*3Uuj?A zPh=~s;k=cRzd9w}>P)HM!_&TnT$lQ%T{KU;sZg0^u8MxI4mphG?2rQ;lqoG4(U}UF z!w(LwQ}7+UZ{fQ=i0}Bk#G`!m8kZd+f72hcL;n1xn{KM?vG@M;^1RFV?QTDOKlWy? z`!6AUjrLagt+fVz#W%#dqZ{w=#*_Ec@)L+3I=d);Gqs} z7>YeCdi2mD`5W-xE{goO@Uia|;A4E3xdONj_yOtf15X3`zIG8bUq!yYt!;yr#l$xd z#|P2F_qY+Bdg{to_7A{!f$sqGsV86AC4?6P^MJVk&Vat_$xjnr2z&%MLV7mgazcIY zJCQzTlHN$1Y3o@`zf(!~lb%fIvL5A+M82C>G?c!}U(ta7CR1M=4-Wja^6f=sygSdY zI1`_T(@=CcE5r%q-@&KSr+1ovte(b(?mcB+=y&wwsmstSeS>L}KRGedx8^MOEuH-n zqlmBYEzv7K^C)xyIGf|?%6VkVQRD5D-wB!@D&Bkk_WUKhV=-;r;qgc==)bD&z07|C z`KmKJkA8#qC93yt)U)fh=g;MSr?xd6{0h4MPv_s5GXMHB3Hv|8yZcuCwqb?69Ul*}X5&YN$E5M6I(*0D@D>mIx@vwjm%7i?eW&Jf zsNT0RN1q?m&$j=~{d}q{GdB+EXI;6U1mi(3L}RcgYTqc0BknkSgCgC;U2fy9#2qJ~ zm%7*odndN>yBM_BxCiPp?$NAG?Vm5K+m%pV))#kL?4PYaLDggmSCO88JhM-Q>_huy zYpA?ZcS7q!B_6qv&#BN^?i1N{E}^dY*Q2+Ut$uis`e*%1p7jk$qywCK=Am@2bZ=DO z^xa(!W&3D7Z!M>_euo0aZ!cyEyZ!zAE=?(|J1gb)4Cn05y{PW2l>T%%TtBEB-5Bvg zd>P;ecc~V8?L>31h`vOhmg1_TeDrd3@AGAihdXur@w^q49MLD^uj~=0()Zdk;^v;9 zde0aIA8OL_UGTdtnrlM#(3p!I^L}X1Zv&i5-XwI53uupe$try(3?HyFOTUq0xqjgf z^)3IW#oL~7(L65I_vX9R_Wh3Rsz2OTZS)%ioPR@XK5W&ib*C8Zaoj_OHGgE>8l%RC zy}{cV$?JOqD<^Z14erGY3xhSjq?ijx1|G`_>BYT=Y6o-G!dLwtpr61n8%>jfn!QARQUTpHn zSEO>~m)>JUZ$$99L}k%$>BNzL*)n$h{({Z>KjXB6M|(W?FN{ev%Rb}2CLh-~$K|?l z-d67P!V_8+7+sNBS-rhldR_JV{T;I(tsA{7(a0|)%)}S_8@6&lxtogBKW#Q>V ze5)urxSNBw4-cwek(ch-{r%Vc;>44q*Zz$q-|2%JOy}%ZX5210$~zbYL&fpr+45&HH>~q>jQcWuM|Jf+tX}0R<4ib9{!9yf zmf&ru#hYI6p@yS(W?|HqvpKMGb6B%lXD@Tk7M_mD#vGWY{)8vN{L80noCC$5^R`XC z#LAml%USpedZdrKq4aB{6VZ**ZRpDvZaq22`a(C(VpNOV)G6%-KEH4c| z7mE+)81p=9_&Ip_u2r^ zEZznum_Ms^bH1icW5_YKs|sV0{Y227Pjq+S)&EbrP^^m`o2dvNZ!0Nvg5iibafzISfE zJNU*9`lZj5?-#y$_uWCVYaadFRE)!m2c~QZ9-ZTd+)4EO+&dKh+rnOwXK`8SZUYGq6D=NyXY6b{ii1{$^J%8powd}zH)Wp9!!Yn_0v zXF9YDH5Y+@X*db|*qVK=vn4+PKIylx?jy|t<$Fuh_eJ0fz;<98Ap7|qK=yMda2IeV zuoc(>Yz8`jvw9;E?{W|2?v}M~F z$TQ`<8C7|<70>&lw*+T#ZrqP<)V_I^Q}RpDclbm6oR%3;0B>Z=MtUq4{jMJ0cD)?# z;lEW9XFXZil=}VPJ$%c>eOsRO&UZtyN0%1#eV6c~BMxhy6^~A*9~(KDAEkpr18LdO zXJIF5Z}=AdR>txK_WM!5Y3DaSfSEuVm=9!t<-iJ{6<7tV0d4`>fc3yeU=xr9wg8=g z-V`s_8qBixTG5B-Vx2{F*8f|b@7Sl<_Zrz7W7b0HOY{h3x_7Jb{BYh1Km059dbaXr zlX*tA9rvHlU^nYL{!DQ>@}6*>DeB!^1@D)@E4xs7Bx(a6_PDemtkj9S&lFk5@H|tv z!uYYv*s~*C;1n+DZT9`tV0vzl-;%Ldj0HO{I#+2dXX`AIF6Eot7WVl~d29NejHQ5% z!Cv&RW1Mu}&ea9b0sRjKw)3^XaF&U;ZZCcWTBc=Nxnq}|4_ z`7Il@7mp@WFGZbN>P%)%>!3%!HK8$UEES9$M?ZJmF}D4?hEV>TcDdg(|tO6uTrUl{O$d@^McMXdC8kGbAmnm z=8wuXx3W)cXG@SU=xEw|_)ugcl**&uG1{v$pU+%xa(5NmFWk&sXDo>2GQq>H9o&K) zXnXsEiM%a{jpoeb)&+*Mgyr5x7z@T)hVbFwO#L3%uq@^G1^T9XOvA&0@oa2zD;Uf7 zKXx5u&i%oe;~ojd@Xo>J+a7+qAviPnNPx{B^z%)N?5nHzo5J64{TaR`#75S6tNIKT z#}-{qAI512hD0*5h_e^p&nwR~Aj6y;;6LM!A*cN2L-hSYIN=oKtii@uxtuvDRQi!U zt5c88Jh5C$V7H9D=o!l_u;EKAID}oo?{+fQVcyqxkC6$6Ir{@U^b2Epc*D{3h0w>Q z&nEb-n+5pTYt}ci-=)Sb;QQBUUkD$WwK?n>^y5RR?dHhAQ7<-?}8(!}Y6;7s3<9Qw7l&Q>xTdEs# z9t&7Uvt$ccX_H^+bcd~GOSr9%IjFh4u$g|d=X8fYw6>?R+Vg`kr*nRTe%op&=nTfZ zSRLFISgvDN(w6DMo_;v5GmGZU9*TVt`d>2v@7RC%a-j*l?dh)Y2Ii$SZoa#$j2oUT zqa3~z@Vhl{PTvz13EoE2(=Kb%Yn)lCpBx(45Clg z6n>w#U`xpNvMIY|bK$(6ZQ<9jF{c!%UVBYalk#x z-ZXY0zPsJ+--p)y+X_BBa>V=3AWVeEs&1XjYw%!1Uu`gX{rM-?-zT*GKHWG&^IP9uuzz^q z?ecQ1>TGCCs}6EvfAr}>U2aRzwHUbV&LE!tN?=<5Hos$CHj3An?qJ7l9jwDgu+_Vy z|MH3SPIPdVWgN-JUcKw#tjnJBaA0fg{cuJ8Mq?JR9#VCmV13qnTEDll;GJaRczNAP zCMxmD8my!%Ymjtl4YKY=fWN)9E8M``ylq`DPT0k|+fZ0T`R2@h;Z3AJp>>zJKl~(d z=rd|v-PW7(-s$a8 z=+v-(<`xF0qD4IC+spx;KdiOMn%#_S4Co4IzLtJPGq!iLXqrpzr*DpEYB&p;(({6?^f%RPDvSjOcK-s)Wo@tzPEBvi zOBcsn|6$V7!;iQb^ep;y%J`13ajJA-M`K;?7V7c6zM-B&z1+e_-1IGZk8g?Viu!XoBad(BXV|*9iE3x^zQe_jm$%7{@=PsZXsWLq-65l z?U5PQ#!#;>D!0)mLCfE_OzEgF5=tA_8^p4ie zNN9?kYVBOf+8KeIrdQ=XzHL_MU^m5CJNPG~`|)=pZ%$bkyqo=DFm3OJF80Cw-TDpH zcd-^Kv{mmf)waR{`0}>(kF9Vae3Y%gnvZM+<}^j#DQyLpGVR$jsM|uF|B9`!@*Ql2 zk`7%T-AxMr2k48vFzV|}`bQT=b_4eNfZb5B7Z!r^z3k=bs&!i7W3?WrW)u{ z_U~=EY-r~mR9Q@NGpL;QOQieWf~WMpG*iI$c#rxG@p19pEo3a#Z^_?-FRrgb8~luD z!>%|LZFE`rPPjyywg14|Xk!d9=&z<_pq=i8bUu2$Obh+b;&<*NTCf-IfwsQm%S*mq z?gh2CMCn+1Oz?CX+a1uJX)*TW%S-#O|8e&9%+}zMTRAJW-Wk-ieknv2nr-wjd+RYP zJt7ZH^*P>{RoX=BROdYY8$HGeu^FN_y1R|LE^j=}u9+R-CCCxJvx3!H+UJnJ1$vic zqg!L%w*&6Yu1(ONa3!$AcoQXhQ@RT+*&vU}H+rpU6R&`7egB3ZGq(+#SLe}5s7l!? zj|H`D|A1aE=|t1^lYCw7!C+|je*^cj!q4^J{iHsXtLpz9^-K1zY5Tjk)aP58-Lxs& z#}5Zq+X%i}@GagMSvt45ZCB-6YW;^fyX|({R_8rz@%mc!O>A@c+D92@M2$Imzr6P( z&q};HnWj#;p3cLSe9fOpYyT_FU1Y-#nzI=E{Tt?8b96UzRO-vG7rqJ}E5}~9zYbpN zTeQ|a@NJKHZJd>Ru(P;FjP5;AH~y4QaRwOW@{W13AC9fzEx3Epb7N=vhsN5xty6re ze@JVL-;sQ7>}3CtgZ&GhXr4OUj=+B7i|`s7$a^fXyt%j~yMsT)|G(!$q@!C#F)ytR zmPhEU)b|FV=Dnm-PR=>$mOst;|M_yNIoBKuWY>;LV|$}J^cyJg(%TT$|4v*RnMS=6 z(032tM2A^nMP1FYhF1=PpZNE#&&KAI>;I1ULB;zs=Gl*DV_O-F>F+fQS7u`mDIYqI65q;ZVPf6pmetu< zyXuS%%+GGh#=fB{^!q4uOj6u(O#E&CYOHwW-`mRGUi%`e*ZiS>%j0kV_tyH0YO4O( zi{910Y7C!>SN$`edRPA{?U^k8Qgaqxet~=2`jzX}-*%oh!zjIa?W!ncOwtTtgB)sN z@FQVrOp^beS_NJp{tEC*fZw5s@^=z{6nGqX8mQF$-xZEJFB_ZKkc~mA8GqZX@vGd- z%C$G&I7?&U_XwgtP5U|gxfgG|adq4Jn{Qp~UU}n<8`iB`y~rlER~E~PPt~`;*;^r+)`X^Tz76}$>MUgB`2eEGcD7iT=5UM^|p_%TYcN=_2+?i z!`i=Cd+TS`x;NhX$xp6ayUL{bU7dFWBdAB0W;_>lb1vVMxt#dV$Q#F6bcwG8^!F&g zrLzj?0jq#k(hm?G2UZZbj6E=awF5I+XHGN2_+0?Uj4@}Lv1XhZZ_YAjn+fJa zT$|UM2GeLpm?m?&d7nAgOfu)27Bj_6Gc(Ku=FiNB&4p%;nQJaKmzvAWN6qEtO0&o; zF;|&o<{ERI`Is4L-j6ALhT+wRnP|>4o|$Z>n(1bynPq01kC?Q%$jmdBnE7UbS!nof z$t*TY&DCbPxz?;O*P9QR51P@&rSpH>}+RtXlcmO_$%gR-ow84XXvWDZXs=D#6-PYU!E{n}Bsu z(Ix9{-UO)Dl9lTP8`hD46tiIE+D*WQmFqsc>5|nq2-Zc3%U7=31l+i0)10<-f}3w4 zP4B=0hyhmff42xeyJ^mbKNoDc4eYDi1nXCS@`lyxHeGq+dcm!VUvcZF1*L*{t8d%{ zL<#8dHhOIsRA$m;S71^T-n{lEg-R+q>54g5MEPr1Mxvr*IjU?kZR+F}uf>}=ee%@F zGp0?R+%m)Srp%Z;eX8e8oig=;8Q#ok(`K|xo_T>ceeyKwx3si)lP6E{CQl{ZGHv>_ zsovDdQ>IU8nLd4{cY!x^vNxqg6(>)bJadXSed?6y)27Uve!=t#hL&lQr_G!(fX+-Q vBc3rcYGyzg^;5!Pj8ZC5X4F44aEFcru{VhxE+M9nF`W#^q#hZk`1^kW{83d1 diff --git a/build/tools/makenandfirm/test/wram_rbin/Makefile b/build/tools/makenandfirm/test/wram_rbin/Makefile deleted file mode 100644 index 63e58e5b..00000000 --- a/build/tools/makenandfirm/test/wram_rbin/Makefile +++ /dev/null @@ -1,48 +0,0 @@ -#! make -f -#---------------------------------------------------------------------------- -# Project: TwlFirm - tools - nandfirm-print -# File: Makefile -# -# Copyright 2007 Nintendo. All rights reserved. -# -# These coded instructions, statements, and computer programs contain -# proprietary information of Nintendo of America Inc. and/or Nintendo -# Company Ltd., and are protected by Federal copyright law. They may -# not be disclosed to third parties or copied or duplicated in any form, -# in whole or in part, without the prior written consent of Nintendo. -# -# $Date:: $ -# $Rev:$ -# $Author:$ -#---------------------------------------------------------------------------- - -SUBDIRS = - -LINCLUDES = ../include - -#---------------------------------------------------------------------------- - -TARGET_BIN = wram_regs.rbin - -SRCS = \ - wram_regs.c \ - -#SRCDIR = # using default -#LCFILE = # using default - - -include $(TWL_IPL_RED_ROOT)/build/buildtools/commondefs - -INSTALL_DIR = . -INSTALL_TARGETS = $(BINDIR)/$(TARGET_BIN) - - -#---------------------------------------------------------------------------- - -do-build: $(TARGETS) - - -include $(TWL_IPL_RED_ROOT)/build/buildtools/modulerules - - -#===== End of Makefile ===== diff --git a/build/tools/makenandfirm/test/wram_rbin/wram_regs.c b/build/tools/makenandfirm/test/wram_rbin/wram_regs.c deleted file mode 100644 index 88332abb..00000000 --- a/build/tools/makenandfirm/test/wram_rbin/wram_regs.c +++ /dev/null @@ -1,89 +0,0 @@ -/*---------------------------------------------------------------------------* - Project: TwlFirm - tools - makenandfirm - File: wram_regs.c - - Copyright 2007 Nintendo. All rights reserved. - - These coded instructions, statements, and computer programs contain - proprietary information of Nintendo of America Inc. and/or Nintendo - Company Ltd., and are protected by Federal copyright law. They may - not be disclosed to third parties or copied or duplicated in any form, - in whole or in part, without the prior written consent of Nintendo. - - $Date:: 2007-09-06$ - $Rev$ - $Author$ - *---------------------------------------------------------------------------*/ -#include -#include - -MIHeader_WramRegs wram_regs = -{ - // ARM9 - { - REG_WRAM_A_BNK_PACK(0, MI_WRAM_A_ARM7, MI_WRAM_A_OFS_0KB, TRUE), - REG_WRAM_A_BNK_PACK(1, MI_WRAM_A_ARM7, MI_WRAM_A_OFS_64KB, TRUE), - REG_WRAM_A_BNK_PACK(2, MI_WRAM_A_ARM7, MI_WRAM_A_OFS_128KB, TRUE), - REG_WRAM_A_BNK_PACK(3, MI_WRAM_A_ARM7, MI_WRAM_A_OFS_192KB, TRUE), - }, - { - REG_WRAM_B_BNK_PACK(0, MI_WRAM_B_ARM7, MI_WRAM_B_OFS_0KB, TRUE), - REG_WRAM_B_BNK_PACK(1, MI_WRAM_B_ARM7, MI_WRAM_B_OFS_32KB, TRUE), - REG_WRAM_B_BNK_PACK(2, MI_WRAM_B_ARM7, MI_WRAM_B_OFS_64KB, TRUE), - REG_WRAM_B_BNK_PACK(3, MI_WRAM_B_ARM7, MI_WRAM_B_OFS_96KB, TRUE), - REG_WRAM_B_BNK_PACK(4, MI_WRAM_B_ARM7, MI_WRAM_B_OFS_128KB, TRUE), - REG_WRAM_B_BNK_PACK(5, MI_WRAM_B_ARM7, MI_WRAM_B_OFS_160KB, TRUE), - REG_WRAM_B_BNK_PACK(6, MI_WRAM_B_ARM7, MI_WRAM_B_OFS_192KB, TRUE), - REG_WRAM_B_BNK_PACK(7, MI_WRAM_B_ARM7, MI_WRAM_B_OFS_224KB, TRUE), - }, - { - REG_WRAM_C_BNK_PACK(0, MI_WRAM_C_ARM9, MI_WRAM_C_OFS_0KB, TRUE), - REG_WRAM_C_BNK_PACK(1, MI_WRAM_C_ARM9, MI_WRAM_C_OFS_32KB, TRUE), - REG_WRAM_C_BNK_PACK(2, MI_WRAM_C_ARM9, MI_WRAM_C_OFS_64KB, TRUE), - REG_WRAM_C_BNK_PACK(3, MI_WRAM_C_ARM9, MI_WRAM_C_OFS_96KB, TRUE), - REG_WRAM_C_BNK_PACK(4, MI_WRAM_C_ARM9, MI_WRAM_C_OFS_128KB, TRUE), - REG_WRAM_C_BNK_PACK(5, MI_WRAM_C_ARM9, MI_WRAM_C_OFS_160KB, TRUE), - REG_WRAM_C_BNK_PACK(6, MI_WRAM_C_ARM9, MI_WRAM_C_OFS_192KB, TRUE), - REG_WRAM_C_BNK_PACK(7, MI_WRAM_C_ARM9, MI_WRAM_C_OFS_224KB, TRUE), - }, - REG_WRAM_A_MAP_PACK(MI_WRAM_MAP_NULL, - MI_WRAM_MAP_NULL, - MI_WRAM_A_IMG_128KB - ), - REG_WRAM_B_MAP_PACK(MI_WRAM_MAP_NULL, - MI_WRAM_MAP_NULL, - MI_WRAM_B_IMG_128KB - ), - REG_WRAM_C_MAP_PACK(HW_WRAM_AREA_HALF, - HW_WRAM_AREA_HALF + 0x00020000, - MI_WRAM_C_IMG_128KB - ), - - // ARM7 - REG_WRAM_A_MAP_PACK(HW_WRAM_AREA_HALF, - HW_WRAM_AREA_HALF + 0x00020000, - MI_WRAM_A_IMG_128KB - ), - REG_WRAM_B_MAP_PACK(HW_WRAM_AREA_HALF + 0x00020000, - HW_WRAM_AREA_HALF + 0x00040000, - MI_WRAM_B_IMG_128KB - ), - REG_WRAM_C_MAP_PACK(MI_WRAM_MAP_NULL, - MI_WRAM_MAP_NULL, - MI_WRAM_C_IMG_128KB - ), - // WRAM Lock - { - 0, - 0, - 0, - }, - - // WRAM-0/1 - MI_WRAM_ARM7_ALL, - - // VRAM-C - 7, - // VRAM-D - 7, -}; diff --git a/build/tools/makenandfirm/wram_regs.c b/build/tools/makenandfirm/wram_regs.c deleted file mode 100644 index 5f09a868..00000000 --- a/build/tools/makenandfirm/wram_regs.c +++ /dev/null @@ -1,96 +0,0 @@ -/*---------------------------------------------------------------------------* - Project: TwlFirm - tools - makenandfirm - File: wram_regs.c - - Copyright 2007 Nintendo. All rights reserved. - - These coded instructions, statements, and computer programs contain - proprietary information of Nintendo of America Inc. and/or Nintendo - Company Ltd., and are protected by Federal copyright law. They may - not be disclosed to third parties or copied or duplicated in any form, - in whole or in part, without the prior written consent of Nintendo. - - $Date:: 2007-09-06$ - $Rev$ - $Author$ - *---------------------------------------------------------------------------*/ -#include "format_rom.h" -//#define SDK_ASM -#define NITRO_TYPES_H_ -#include -#include -#include - - -MIHeader_WramRegs wram_regs_init = -{ - // ARM9 - { - REG_MI_MBK_A0_FIELD( 1, MI_WRAM_A_OFFSET_0KB , MI_WRAM_ARM7 ), - REG_MI_MBK_A1_FIELD( 1, MI_WRAM_A_OFFSET_64KB , MI_WRAM_ARM7 ), - REG_MI_MBK_A2_FIELD( 1, MI_WRAM_A_OFFSET_128KB, MI_WRAM_ARM7 ), - REG_MI_MBK_A3_FIELD( 1, MI_WRAM_A_OFFSET_192KB, MI_WRAM_ARM7 ), - }, - { - REG_MI_MBK_B0_FIELD( 1, MI_WRAM_BC_OFFSET_0KB , MI_WRAM_ARM7 ), - REG_MI_MBK_B1_FIELD( 1, MI_WRAM_BC_OFFSET_32KB , MI_WRAM_ARM7 ), - REG_MI_MBK_B2_FIELD( 1, MI_WRAM_BC_OFFSET_64KB , MI_WRAM_ARM7 ), - REG_MI_MBK_B3_FIELD( 1, MI_WRAM_BC_OFFSET_96KB , MI_WRAM_ARM7 ), - REG_MI_MBK_B4_FIELD( 1, MI_WRAM_BC_OFFSET_128KB, MI_WRAM_ARM7 ), - REG_MI_MBK_B5_FIELD( 1, MI_WRAM_BC_OFFSET_160KB, MI_WRAM_ARM7 ), - REG_MI_MBK_B6_FIELD( 1, MI_WRAM_BC_OFFSET_192KB, MI_WRAM_ARM7 ), - REG_MI_MBK_B7_FIELD( 1, MI_WRAM_BC_OFFSET_224KB, MI_WRAM_ARM7 ), - }, - { - REG_MI_MBK_C0_FIELD( 1, MI_WRAM_BC_OFFSET_0KB , MI_WRAM_ARM9 ), - REG_MI_MBK_C1_FIELD( 1, MI_WRAM_BC_OFFSET_32KB , MI_WRAM_ARM9 ), - REG_MI_MBK_C2_FIELD( 1, MI_WRAM_BC_OFFSET_64KB , MI_WRAM_ARM9 ), - REG_MI_MBK_C3_FIELD( 1, MI_WRAM_BC_OFFSET_96KB , MI_WRAM_ARM9 ), - REG_MI_MBK_C4_FIELD( 1, MI_WRAM_BC_OFFSET_128KB, MI_WRAM_ARM9 ), - REG_MI_MBK_C5_FIELD( 1, MI_WRAM_BC_OFFSET_160KB, MI_WRAM_ARM9 ), - REG_MI_MBK_C6_FIELD( 1, MI_WRAM_BC_OFFSET_192KB, MI_WRAM_ARM9 ), - REG_MI_MBK_C7_FIELD( 1, MI_WRAM_BC_OFFSET_224KB, MI_WRAM_ARM9 ), - }, - REG_MI_MBK6_FIELD( REG_WRAM_MAP_CONV_ADDR( 6, A, EADDR, MI_WRAM_MAP_NULL ), - MI_WRAM_IMAGE_128KB, - REG_WRAM_MAP_CONV_ADDR( 6, A, SADDR, MI_WRAM_MAP_NULL ) - ), - REG_MI_MBK7_FIELD( REG_WRAM_MAP_CONV_ADDR( 7, B, EADDR, MI_WRAM_MAP_NULL ), - MI_WRAM_IMAGE_128KB, - REG_WRAM_MAP_CONV_ADDR( 7, B, SADDR, MI_WRAM_MAP_NULL ) - ), - REG_MI_MBK8_FIELD( REG_WRAM_MAP_CONV_ADDR( 8, C, EADDR, HW_WRAM_AREA_HALF + 0x00020000 ), - MI_WRAM_IMAGE_128KB, - REG_WRAM_MAP_CONV_ADDR( 8, C, SADDR, HW_WRAM_AREA_HALF ) - ), - - // ARM7 - REG_MI_MBK6_FIELD( REG_WRAM_MAP_CONV_ADDR( 6, A, EADDR, HW_WRAM_AREA_HALF + 0x00020000 ), - MI_WRAM_IMAGE_128KB, - REG_WRAM_MAP_CONV_ADDR( 6, A, SADDR, HW_WRAM_AREA_HALF ) - ), - REG_MI_MBK7_FIELD( REG_WRAM_MAP_CONV_ADDR( 7, B, EADDR, HW_WRAM_AREA_HALF + 0x00040000 ), - MI_WRAM_IMAGE_128KB, - REG_WRAM_MAP_CONV_ADDR( 7, B, SADDR, HW_WRAM_AREA_HALF + 0x00020000 ) - ), - REG_MI_MBK8_FIELD( REG_WRAM_MAP_CONV_ADDR( 8, C, EADDR, MI_WRAM_MAP_NULL ), - MI_WRAM_IMAGE_128KB, - REG_WRAM_MAP_CONV_ADDR( 8, C, SADDR, MI_WRAM_MAP_NULL ) - ), - - // WRAM Lock - { - 0, - 0, - 0, - }, - - // WRAM-0/1 - 3, - - // VRAM-C - 7, - // VRAM-D - 7, -}; - diff --git a/build/tools/makenorfirm/Makefile b/build/tools/makenorfirm/Makefile deleted file mode 100644 index 8f624c9e..00000000 --- a/build/tools/makenorfirm/Makefile +++ /dev/null @@ -1,151 +0,0 @@ -#! make -f -#--------------------------------------------------------------------------- -# Project: TwlFirm - tools - makenorfirm -# File: Makefile -# -# Copyright 2007 Nintendo. All rights reserved. -# -# These coded instructions, statements, and computer programs contain -# proprietary information of Nintendo of America Inc. and/or Nintendo -# Company Ltd., and are protected by Federal copyright law. They may -# not be disclosed to third parties or copied or duplicated in any form, -# in whole or in part, without the prior written consent of Nintendo. -# -# $Date:: $ -# $Rev:$ -# $Author:$ -#--------------------------------------------------------------------------- - -TARGET_PLATFORM = TWL - -SUPPORT_ECC = 0 - -ifeq ($(SUPPORT_ECC),1) -ECC_SRCDIR = ../../libraries/acsign_ecc/common \ - ../../libraries/acsign_ecc/common/algae/common/ecc \ - ../../libraries/acsign_ecc/common/algae/cmp \ - ../../libraries/acsign_ecc/common/algae/ecsource \ - -ECC_INCDIR = ../../libraries/acsign_ecc/include \ - ../../libraries/acsign_ecc/common/algae/include \ - ../../libraries/acsign_ecc/common/algae/common/include \ - -ECC_SRCS = acsign_ecc.c acsign_cryptoc.c \ - \ - cmparith.c cmpbits.c cmpcnv.c cmpdiv.c cmpmem.c \ - cmpmod.c cmpmuldv.c cmpspprt.c cmpsqr.c cmpvectr.c \ - computem.c ecfpatbl.c ecfpsmul.c \ - spcprime.c secfpcom.c \ - \ - p224v1.c p224v1a.c \ - -ECC_DEFS = -DRSA_PROTOTYPES=RSA_ENABLED \ - -DRCOM_BUILD=RSA_ENABLED -DRSA_FAST_INVERSE=RSA_ENABLED \ - -DRSA_STD_MEM_FUNCS=RSA_ENABLED -DRSA_STD_ALLOC_FUNCS=RSA_ENABLED \ -else -ECC_SRCDIR = -ECC_INCDIR = -ECC_SRCS = -ECC_DEFS = -endif - -SRCDIR += ../acsign $(ECC_SRCDIR) -INCDIR += ../acsign/include $(ECC_INCDIR) $(ECC_SRCDIR) - - -include $(TWL_IPL_RED_ROOT)/build/buildtools/commondefs - -TARGETS = makenorfirm.exe - -SOURCES_C = makenorfirm.c \ - out_norfirm.c \ - misc.c \ - path.c \ - defval.c \ - compress.c \ - wram_regs.c \ - acsign.c \ - acsign_nor.c \ - aes2.c \ - $(ECC_SRCS) - -SOURCES = $(SORUCES_C) - -OBJECTS = $(SOURCES_C:.c=.o) - -HEADERS = format_nlist.h \ - makenorfirm.h \ - path.h \ - format_rom.h \ - misc.h \ - defval.h \ - compress.h \ - -MACROS += -DSMALL_CODE_SIZE \ - -DSTANDALONE \ - -DOPT_32_BIT \ - -DNO_SPLIT \ - -DNO_FP_API \ - -DNO_R_DIAG \ - $(ECC_DEFS) - -INSTALL_DIR = $(FIRM_INSTALL_TOOLSDIR)/bin -INSTALL_TARGETS = $(TARGETS) - -LDIRT_CLEAN = $(OBJECTS) $(TARGETS) version.h - - -VPATH = $(SRCDIR) -TWL_INCDIR := $(TWL_INCDIR) $(addprefix -I,$(INCDIR)) $(addprefix -I,$(FIRM_INCDIR)) - -include $(TWLSDK_ROOT)/build/buildtools/twl/modulerules.x86 - -#---------------------------------------------------------------------------- -# build -#---------------------------------------------------------------------------- -do-build: $(TARGETS) - -$(TARGETS): $(OBJECTS) - $(CC_X86) $+ -o $@ - -makenorfirm.o: makenorfirm.c makenorfirm.h format_rom.h path.h version.h -out_norfirm.o: out_norfirm.c misc.h format_rom.h format_nlist.h format_sign.h elf.h compress.h \ - $(FIRM_INCDIR)/firm/format/sign.h \ - $(FIRM_INCDIR)/firm/format/wram_regs.h \ - $(FIRM_INCDIR)/firm/format/norfirm.h \ - -misc.o: misc.c misc.h -path.o: path.c path.h -compress.o: compress.c compress.h -wram_regs.o: wram_regs.c -acsign.o: acsign.c ../acsign/include/acsign.h -acsign_nor.o: acsign_nor.c format_sign.h \ - $(FIRM_INCDIR)/firm/format/sign.h \ - $(FIRM_INCDIR)/firm/format/wram_regs.h \ - $(FIRM_INCDIR)/firm/format/norfirm.h \ - -aes2.o: aes2.c aes2.h - -$(FIRM_INCDIR)/firm/format/sign.h: -$(FIRM_INCDIR)/firm/format/wram_regs.h: -$(FIRM_INCDIR)/firm/format/norfirm.h: -format_nlist.h: -format_rom.h: -makenorfirm.h: -acsign.h: -acsign_nor.h: -path.h: - -# avoid to warning message -misc.o:WARNING += -Wno-format-y2k - -# - -version.h: $(SOURCES) $(HEADERS) - @for i in $^ ; \ - do \ - date -r $$i +'#define SDK_DATE_OF_LATEST_FILE %Y%m%dUL'; \ - done | sort | tail -1 > $@ - -test: path.c misc.c - $(CC_X86) -DTEST $+ -o $@ diff --git a/build/tools/makenorfirm/compress.c b/build/tools/makenorfirm/compress.c deleted file mode 100644 index 0d7a555d..00000000 --- a/build/tools/makenorfirm/compress.c +++ /dev/null @@ -1,293 +0,0 @@ -/*---------------------------------------------------------------------------* - Project: TwlFirm - tools - makenorfirm - File: compress.c - - Copyright 2007 Nintendo. All rights reserved. - - These coded instructions, statements, and computer programs contain - proprietary information of Nintendo of America Inc. and/or Nintendo - Company Ltd., and are protected by Federal copyright law. They may - not be disclosed to third parties or copied or duplicated in any form, - in whole or in part, without the prior written consent of Nintendo. - - $Date:: 2007-09-06$ - $Rev$ - $Author$ - *---------------------------------------------------------------------------*/ -#include -#include // atoi() -#include // strcmp() -#include // isprint() -#include // chdir() -#include -#include // UCHAR_MAX -#include -#include // stat() -#include "elf.h" -#include "misc.h" -#include "defval.h" -#include "format_rom.h" -#include "format_nlist.h" -#include "makenorfirm.h" - -//#define ADD_HEADER - -#define DIFF_CODE_HEADER (0x80) -#define RL_CODE_HEADER (0x30) -#define LZ_CODE_HEADER (0x10) -#define HUFF_CODE_HEADER (0x20) -#define CODE_HEADER_MASK (0xF0) - -//=========================================================================== -// LZ77圧縮 -//=========================================================================== -static u8 SearchLZ(const u8 *nextp, u32 remainSize, u16 *offset); - -static u16 windowPos; -static u16 windowLen; - -static s16 LZOffsetTable[4096]; -static s16 LZByteTable[256]; -static s16 LZEndTable[256]; - - -static void LZInitTable(void) -{ - u16 i; - - for (i = 0; i < 256; i++) - { - LZByteTable[i] = -1; - LZEndTable[i] = -1; - } - windowPos = 0; - windowLen = 0; -} - -static void SlideByte(const u8 *srcp) -{ - s16 offset; - u8 in_data = *srcp; - u16 insert_offset; - - if (windowLen == 4096) - { - u8 out_data = *(srcp - 4096); - if ((LZByteTable[out_data] = LZOffsetTable[LZByteTable[out_data]]) == -1) - { - LZEndTable[out_data] = -1; - } - insert_offset = windowPos; - } - else - { - insert_offset = windowLen; - } - - offset = LZEndTable[in_data]; - if (offset == -1) - { - LZByteTable[in_data] = insert_offset; - } - else - { - LZOffsetTable[offset] = insert_offset; - } - LZEndTable[in_data] = insert_offset; - LZOffsetTable[insert_offset] = -1; - - if (windowLen == 4096) - { - windowPos = (u16)((windowPos + 1) % 0x1000); - } - else - { - windowLen++; - } -} - -static void LZSlide(const u8 *srcp, u32 n) -{ - u32 i; - - for (i = 0; i < n; i++) - { - SlideByte(srcp++); - } -} - -/*---------------------------------------------------------------------------* - Name: MI_CompressLZ - - Description: LZ77圧縮を行なう関数 - - Arguments: srcp 圧縮元データへのポインタ - size 圧縮元データサイズ - dstp 圧縮先データへのポインタ - 圧縮元データよりも大きいサイズのバッファが必要です。 - - Returns: 圧縮後のデータサイズ。 - 圧縮後のデータが圧縮前よりも大きくなる場合には圧縮を中断し0を返します。 - *---------------------------------------------------------------------------*/ -u32 LZCompWrite(u8 *srcp, u32 size, u8 *dstp, int boundary) -{ - u32 LZDstCount; // 圧縮データのバイト数 - u8 LZCompFlags; // 圧縮の有無を示すフラグ系列 - u8 *LZCompFlagsp; // LZCompFlags を格納するメモリ領域をポイント - u16 lastOffset; // 一致データまでのオフセット (その時点での最長一致データ) - u8 lastLength; // 一致データ長 (その時点での最長一致データ) - u8 i; - u32 dstMax; - -#ifdef ADD_HEADER - *(u32 *)dstp = size << 8 | LZ_CODE_HEADER; // データ・ヘッダ - dstp += 4; -#endif - LZDstCount = 4; - dstMax = size; - LZInitTable(); - - while (size > 0) - { - LZCompFlags = 0; - LZCompFlagsp = dstp++; // フラグ系列の格納先 - LZDstCount++; - - // フラグ系列が8ビットデータとして格納されるため、8回ループ - for (i = 0; i < 8; i++) - { - LZCompFlags <<= 1; // 初回 (i=0) は特に意味はない - if (size <= 0) - { - // 終端に来た場合はフラグを最後までシフトさせてから終了 - continue; - } - - if ((lastLength = SearchLZ(srcp, size, &lastOffset))) - { - // 圧縮可能な場合はフラグを立てる - LZCompFlags |= 0x1; - - // オフセットは上位4ビットと下位8ビットに分けて格納 - *dstp++ = (u8)((lastLength - 3) << 4 | (lastOffset - 1) >> 8); - *dstp++ = (u8)((lastOffset - 1) & 0xff); - LZDstCount += 2; - LZSlide(srcp, lastLength); - srcp += lastLength; - size -= lastLength; - } - else - { - // 圧縮なし - LZSlide(srcp, 1); - *dstp++ = *srcp++; - size--; - LZDstCount++; - } - } // 8回ループ終了 - *LZCompFlagsp = LZCompFlags; // フラグ系列を格納 - } - - // 16バイト境界アラインメント - // アラインメント用データ0 はデータサイズに含める - i = 0; - while (LZDstCount & (boundary - 1)) -// while ((LZDstCount + i) & 0x3) - { - *dstp++ = 0; - LZDstCount++; - i++; - } - - return LZDstCount; -} - -//-------------------------------------------------------- -// LZ77圧縮でスライド窓の中から最長一致列を検索します。 -// Arguments: startp データの開始位置を示すポインタ -// nextp 検索を開始するデータのポインタ -// remainSize 残りデータサイズ -// offset 一致したオフセットを格納する領域へのポインタ -// Return : 一致列が見つかった場合は TRUE -// 見つからなかった場合は FALSE -//-------------------------------------------------------- -static u8 SearchLZ(const u8 *nextp, u32 remainSize, u16 *offset) -{ - const u8 *searchp; - const u8 *headp, *searchHeadp; - u16 maxOffset; - u8 maxLength = 2; - u8 tmpLength; - s32 w_offset; - - if (remainSize < 3) - { - return 0; - } - - w_offset = LZByteTable[*nextp]; - - while (w_offset != -1) - { - if (w_offset < windowPos) - { - searchp = nextp - windowPos + w_offset; - } - else - { - searchp = nextp - windowLen - windowPos + w_offset; - } - - /* 無くても良いが、僅かに高速化する */ - if (*(searchp + 1) != *(nextp + 1) || *(searchp + 2) != *(nextp + 2)) - { - w_offset = LZOffsetTable[w_offset]; - continue; - } - - if (nextp - searchp < 2) - { - // VRAMは2バイトアクセスなので (VRAMからデータを読み出す場合があるため)、 - // 検索対象データは2バイト前からのデータにしなければならない。 - // - // オフセットは12ビットで格納されるため、4096以下 - break; - } - tmpLength = 3; - searchHeadp = searchp + 3; - headp = nextp + 3; - - while (((u32)(headp - nextp) < remainSize) && (*headp == *searchHeadp)) - { - headp++; - searchHeadp++; - tmpLength++; - - // データ長は4ビットで格納されるため、18以下 (3の下駄をはかせる) - if (tmpLength == (0xF + 3)) - { - break; - } - } - if (tmpLength > maxLength) - { - // 最大長オフセットを更新 - maxLength = tmpLength; - maxOffset = (u16)(nextp - searchp); - if (maxLength == (0xF + 3)) - { - // 一致長が最大なので、検索を終了する。 - break; - } - } - w_offset = LZOffsetTable[w_offset]; - } - - if (maxLength < 3) - { - return 0; - } - *offset = maxOffset; - return maxLength; -} - diff --git a/build/tools/makenorfirm/compress.h b/build/tools/makenorfirm/compress.h deleted file mode 100644 index e3dc58f0..00000000 --- a/build/tools/makenorfirm/compress.h +++ /dev/null @@ -1,38 +0,0 @@ -/*---------------------------------------------------------------------------* - Project: TwlFirm - tools - makenorfirm - File: compress.h - - Copyright 2007 Nintendo. All rights reserved. - - These coded instructions, statements, and computer programs contain - proprietary information of Nintendo of America Inc. and/or Nintendo - Company Ltd., and are protected by Federal copyright law. They may - not be disclosed to third parties or copied or duplicated in any form, - in whole or in part, without the prior written consent of Nintendo. - - $Date:: 2007-09-06$ - $Rev$ - $Author$ - *---------------------------------------------------------------------------*/ -#ifndef COMPRESS_H_ -#define COMPRESS_H_ - -#include "misc.h" - - -/*---------------------------------------------------------------------------* - Name: MI_CompressLZ - - Description: LZ77圧縮を行なう関数 - - Arguments: srcp 圧縮元データへのポインタ - size 圧縮元データサイズ - dstp 圧縮先データへのポインタ - 圧縮元データよりも大きいサイズのバッファが必要です。 - - Returns: 圧縮後のデータサイズ。 - *---------------------------------------------------------------------------*/ -u32 LZCompWrite(u8 *srcp, u32 size, u8 *dstp, int boundary); - - -#endif //COMPRESS_H_ diff --git a/build/tools/makenorfirm/defval.c b/build/tools/makenorfirm/defval.c deleted file mode 100644 index 679fb0e6..00000000 --- a/build/tools/makenorfirm/defval.c +++ /dev/null @@ -1,315 +0,0 @@ -/*---------------------------------------------------------------------------* - Project: NitroSDK - tools - makerom - File: defval.c - - Copyright 2003-2006 Nintendo. All rights reserved. - - These coded instructions, statements, and computer programs contain - proprietary information of Nintendo of America Inc. and/or Nintendo - Company Ltd., and are protected by Federal copyright law. They may - not be disclosed to third parties or copied or duplicated in any form, - in whole or in part, without the prior written consent of Nintendo. - - $Log: defval.c,v $ - Revision 1.10 2006/01/18 02:11:19 kitase_hirotake - do-indent - - Revision 1.9 2005/02/28 05:26:03 yosizaki - do-indent. - - Revision 1.8 2004/08/05 13:50:13 yasu - Support -M option - - Revision 1.7 2004/06/29 04:55:40 yasu - Use VBuffer to resolve variables - - Revision 1.6 2004/06/23 07:51:02 yasu - fix a bug as illegal memory freeing at ResolveDefVal() - - Revision 1.5 2004/05/27 00:40:49 yasu - care also about current directory (dot ".") - - Revision 1.4 2004/05/27 00:25:46 yasu - care about double-dots ".." for defvalue option :r, :e - - Revision 1.3 2004/05/27 00:11:19 yasu - fix a error when searching a "dot" of file extension - - Revision 1.2 2004/05/26 12:02:47 yasu - support :h, :t, :r, :e option for variable name - - Revision 1.1 2004/03/26 05:06:45 yasu - support variables like as -DNAME=VALUE - - $NoKeywords: $ - *---------------------------------------------------------------------------*/ -#include -#include // getenv() -#include // strcasecmp() -#include // getopt() -#include "misc.h" -#include "defval.h" - -typedef struct tValdef -{ - struct tValdef *next; - char *name; - char *value; -} -tValdef; - -tValdef *valdef_top = NULL; - - -// -// Add new define value via file -// -// opt : "DEFINE=VALUE" -// -BOOL AddDefValFromFile(char *filename) -{ - char *buffer; - int buffer_size; - int read_size; - FILE *fp; - - if (filename[0] == '-' && filename[1] == '\0') - { - fp = stdin; - } - else if (NULL == (fp = fopen(filename, "rb"))) - { - fprintf(stderr, "Cannot open file \"%s\".\n", filename); - return FALSE; - } - - buffer_size = DEFVAL_DEFAULT_BUFFER_SIZE; - - if (NULL == (buffer = malloc(buffer_size))) - { - fprintf(stderr, "Cannot allocate memory.\n"); - return FALSE; - } - - read_size = 0; - - while (NULL != fgets(buffer + read_size, buffer_size - read_size, fp)) - { - read_size = strlen(buffer); - - if (read_size == buffer_size - 1 && buffer[read_size - 1] != '\n') - { - buffer_size *= 2; - - if (NULL == (buffer = realloc(buffer, buffer_size))) - { - fprintf(stderr, "Cannot allocate memory.\n"); - return FALSE; - } - continue; - } - - AddDefVal(buffer); - read_size = 0; - } - - if (fp != stdin) - { - fclose(fp); - } - free(buffer); - - return TRUE; -} - - -// -// Add new define value -// -// opt : "DEFINE=VALUE" -// -void AddDefVal(char *opt) -{ - int i; - tValdef *t; - - for (i = 0;; i++) - { - if ('=' == opt[i] || '\0' == opt[i]) - { - break; - } - } - - if (i > 0) - { - t = Alloc(sizeof(tValdef)); - t->name = strncpy(Alloc(i + 1), opt, i); - t->name[i] = '\0'; - - if (opt[i] == '=') - { - i++; - } - t->value = strdup(opt + i); - - t->next = valdef_top; - valdef_top = t; - - debug_printf("DEFINE:$(%s)=\"%s\"\n", t->name, t->value); - } - return; -} - -// -// Search define value -// -// Return: value of specified name -// -char *SearchDefVal(char *name) -{ - tValdef *t; - - for (t = valdef_top; t; t = t->next) - { - if (!strcmp(t->name, name)) - { - return t->value; - } - } - - return getenv(name); -} - - -// -// Search define value and Modify it by : option -// -// Return: duplicated value of specified name modified by :x option -// -char *SearchDefValWithOption(char *name) -{ - int len_name = strlen(name); - char *value; - char option = '\0'; - - if (len_name > 2 && name[len_name - 2] == ':') - { - name[len_name - 2] = '\0'; - option = name[len_name - 1]; - } - - value = SearchDefVal(name); - - if (value) - { - int value_len = strlen(value); - int col_dot = value_len; - int col_filename = 0; - int i; - - for (i = 0; i < value_len; i++) - { - switch (value[i]) - { - case '.': - if (col_filename == i && - (value[i + 1] == '\0' || (value[i + 1] == '.' && value[i + 2] == '\0'))) - { - i = value_len; // exit loop if last entry is . or .. - } - else - { - col_dot = i; // Save the last dot column - } - break; - - case '/': - case '\\': - case ':': - col_filename = i + 1; // Save the last filename - col_dot = value_len; // Reset dot position - break; - - default: - ; - } - } - - switch (option) - { - case 'h': // Dirname with the last slash - value = strdup(value); - value[col_filename] = '\0'; - break; - - case 't': // Filename - value = strdup(value + col_filename); - break; - - case 'r': // All without . file extension - value = strdup(value); - value[col_dot] = '\0'; - break; - - case 'e': // File extension - value = strdup(value + col_dot + 1); - break; - - default: - value = strdup(value); - } - } - return value; -} - - -// -// Resolve define value -// -// Return: new string -// -char *ResolveDefVal(char *str) -{ - int i, j; - char *val; - VBuffer buf; - - InitVBuffer(&buf); - - for (i = 0; '\0' != str[i]; i++) - { - // search $(XXX) - if ('$' == str[i] && '(' == str[i + 1]) - { - for (j = i + 2; '\0' != str[j]; j++) - { - if (')' == str[j]) - { - str[j] = '\0'; - - // get value of XXX - val = SearchDefValWithOption(&str[i + 2]); - - // copy value of XXX - if (val) - { - char *s = val; - - while (*s) - { - PutVBuffer(&buf, *s); - s++; - } - free(val); - } - i = j; - goto next; - } - } - } - PutVBuffer(&buf, str[i]); - next:; - } - return GetVBuffer(&buf); // pass allocated buffer, should be freed by caller -} diff --git a/build/tools/makenorfirm/defval.h b/build/tools/makenorfirm/defval.h deleted file mode 100644 index 71355101..00000000 --- a/build/tools/makenorfirm/defval.h +++ /dev/null @@ -1,38 +0,0 @@ -/*---------------------------------------------------------------------------* - Project: NitroSDK - tools - makerom - File: defval.h - - Copyright 2003-2006 Nintendo. All rights reserved. - - These coded instructions, statements, and computer programs contain - proprietary information of Nintendo of America Inc. and/or Nintendo - Company Ltd., and are protected by Federal copyright law. They may - not be disclosed to third parties or copied or duplicated in any form, - in whole or in part, without the prior written consent of Nintendo. - - $Log: defval.h,v $ - Revision 1.4 2006/01/18 02:11:19 kitase_hirotake - do-indent - - Revision 1.3 2005/02/28 05:26:03 yosizaki - do-indent. - - Revision 1.2 2004/08/05 13:50:13 yasu - Support -M option - - Revision 1.1 2004/03/26 05:06:45 yasu - support variables like as -DNAME=VALUE - - $NoKeywords: $ - *---------------------------------------------------------------------------*/ -#ifndef DEFVAL_H_ -#define DEFVAL_H_ - -#define DEFVAL_DEFAULT_BUFFER_SIZE (1024) - -BOOL AddDefValFromFile(char *filename); -void AddDefVal(char *opt); -char *SearchDefVal(char *name); -char *ResolveDefVal(char *str); - -#endif //DEFVAL_H_ diff --git a/build/tools/makenorfirm/elf.h b/build/tools/makenorfirm/elf.h deleted file mode 100644 index c360cd33..00000000 --- a/build/tools/makenorfirm/elf.h +++ /dev/null @@ -1,431 +0,0 @@ -/*---------------------------------------------------------------------------* - Project: TwlFirm - ELF - File: elf.h - - Copyright 2007 Nintendo. All rights reserved. - - These coded instructions, statements, and computer programs contain - proprietary information of Nintendo of America Inc. and/or Nintendo - Company Ltd., and are protected by Federal copyright law. They may - not be disclosed to third parties or copied or duplicated in any form, - in whole or in part, without the prior written consent of Nintendo. - *---------------------------------------------------------------------------*/ - -#ifndef ELF_H_ -#define ELF_H_ - -#include "misc.h" - -/*--------------------------------------------------------- - 型定義 - --------------------------------------------------------*/ -typedef u32 Elf32_Addr; /* size:4, align:4 Unsigned program address */ -typedef u16 Elf32_Half; /* size:2, align:2 Unsigned medium int */ -typedef u32 Elf32_Off; /* size:4, align:4 Unsigned file offset */ -typedef s32 Elf32_Sword; /* size:4, align:4 Signed large int */ -typedef u32 Elf32_Word; /* size:4, align:4 Unsigned large int */ - -/*--------------------------------------------------------- - ELF Header - --------------------------------------------------------*/ -/* e_identのインデックス */ -#define EI_MAG0 0 /* File identification */ -#define EI_MAG1 1 /* File identification */ -#define EI_MAG2 2 /* File identification */ -#define EI_MAG3 3 /* File identification */ -#define EI_CLASS 4 /* File class 0=invalid, 1=32bit, 2=64bit */ -#define EI_DATA 5 /* Data encoding 0=invalid, 1=LSB, 2=MSB */ -#define EI_VERSION 6 /* File version 現在は1 */ -#define EI_PAD 7 /* Start of padding bytes */ -#define EI_NIDENT 16 /* Size of e_ident[] */ - -typedef struct { - unsigned char e_ident[EI_NIDENT]; - Elf32_Half e_type; /* ELFの形式(再配置可能, 実行可能など) */ - Elf32_Half e_machine; /* ファイルで要求されるアーキテクチャ */ - Elf32_Word e_version; /* ELFフォーマットのバージョン(現在は1) */ - Elf32_Addr e_entry; /* プログラムのエントリポイント。指定無しなら0。 */ - Elf32_Off e_phoff; /* プログラムヘッダテーブルのファイル先頭からのオフセット */ - Elf32_Off e_shoff; /* セクションヘッダテーブルのファイル先頭からのオフセット */ - Elf32_Word e_flags; /* プロセッサ固有のフラグ */ - Elf32_Half e_ehsize; /* ELFヘッダのサイズ */ - Elf32_Half e_phentsize; /* 1プログラムヘッダのサイズ */ - Elf32_Half e_phnum; /* プログラムヘッダの数 */ - Elf32_Half e_shentsize; /* 1セクションヘッダのサイズ */ - Elf32_Half e_shnum; /* セクションヘッダの数 */ - Elf32_Half e_shstrndx; /* セクション名文字列テーブルセクションへのインデックス */ -} Elf32_Ehdr; - -/* e_ident[EI_*]の中身定義 */ -#define ELFMAG0 0x7f -#define ELFMAG1 'E' -#define ELFMAG2 'L' -#define ELFMAG3 'F' -#define ELFCLASSNONE 0 /* invalid */ -#define ELFCLASS32 1 /* ARM and Thumb processors use 32-bit ELF. */ -#define ELFCLASS64 2 -#define ELFDATANONE 0 /* invalid */ -#define ELFDATA2LSB 1 /* little-endian */ -#define ELFDATA2MSB 2 /* big-endian */ - - -/* [e_type] */ -#define ET_NONE 0 /* No file type */ -#define ET_REL 1 /* Re-locatable file */ -#define ET_EXEC 2 /* Executable file */ -#define ET_DYN 3 /* Shared object file */ -#define ET_CORE 4 /* Core file */ -#define ET_LOPROC 0xff00 /* Processor-specific */ -#define ET_HIPROC 0xffff /* Processor-specific */ - -/* [e_machine] */ -#define EM_NONE 0 /* No machine */ -#define EM_M32 1 -#define EM_SPARC 2 -#define EM_386 3 -#define EM_68K 4 -#define EM_88K 5 -#define EM_860 7 -#define EM_MIPS 8 -#define EM_MIPS_RS4_BE 10 -#define EM_ARM 40 /* ARM/Thumb Architecture */ - - -/* [e_version] This member identifies the object file version.*/ -#define EV_NONE 0 /* Invalid version */ -#define EV_CURRENT 1 /* Current version */ - - -/* - ARM-specific e_flags - e_flags Field Value Meaning - EF_ARM_HASENTRY (0x02) e_entry contains a program-loader entry point - (see section 4.1.1, Entry points, below). - EF_ARM_SYMSARESORTED (0x04) Each subsection of the symbol table is sorted by symbol value - (see section 4.4.8, Symbol table order, below) - EF_ARM_DYNSYMSUSESEGIDX (0x8) Symbols in dynamic symbol tables that are defined in sections - included in program segment n have st_shndx = n + 1. - (see section 4.4.9, Dynamic symbol table entries, below). - EF_ARM_MAPSYMSFIRST (0x10) Mapping symbols precede other local symbols in the symbol table - (see section 4.4.8, Symbol table order, below). - - EF_ARM_EABIMASK (0xFF000000)(current version is 0x02000000) - This masks an 8-bit version number, the version of the ARM - EABI to which this ELF file conforms. This EABI is version 2. A - value of 0 denotes unknown conformance. -*/ -#define EF_ARM_HASENTRY 0x02 -#define EF_ARM_SYMSARESORTED 0x04 -#define EF_ARM_DYNSYMSUSESEGIDX 0x8 -#define EF_ARM_MAPSYMSFIRST 0x10 -#define EF_ARM_EABIMASK 0xFF000000 - - -/*--------------------------------------------------------- - Program headers - --------------------------------------------------------*/ -typedef struct { - Elf32_Word p_type; - Elf32_Off p_offset; - Elf32_Addr p_vaddr; - Elf32_Addr p_paddr; - Elf32_Word p_filesz; - Elf32_Word p_memsz; - Elf32_Word p_flags; - Elf32_Word p_align; -} Elf32_Phdr; - -/* [p_type] */ -#define PT_NULL 0 /* 使われないエントリで、他のメンバの値の意味は未定義 */ -#define PT_LOAD 1 /* 実行時にロードされるセグメント */ -#define PT_DYNAMIC 2 /* 動的構造体配列を保持するセグメント */ -#define PT_INTERP 3 /* ファイルの解釈に使われるインタプリタのパスを保持するセグメント */ -#define PT_NOTE 4 /* ファイルの解釈には使われない情報を保持するセグメント */ -#define PT_SHLIB 5 /* 予約 */ -#define PT_PHDR 6 /* プログラムヘッダテーブル(プログラムのメモリイメージの一部である場合のみ存在) */ -//#define PT_TLS ? /* スレッド局所記憶領域のテンプレート */ - -#define PT_LOOS 0x60000000 /* OS固有に予約された領域 */ -#define PT_HIOS 0x6fffffff - -#define PT_LOPROC 0x70000000 /* プロセッサ固有に予約された領域 */ -#define PT_HIPROC 0x7fffffff - -/* [p_flags]*/ -#define PF_X 1 /*実行可能*/ -#define PF_W 2 /*書き込み可能*/ -#define PF_R 4 /*読み出し可能*/ -#define PF_ARM_SB 0x10000000 /*The segment contains the location addressed by the static base*/ -#define PF_ARM_PI 0x20000000 /*The segment is position-independent*/ -#define PF_ARM_ENTRY 0x80000000 /*The segment contains the entry point*/ -#define PF_MASKPROC 0xf0000000 - - -/*--------------------------------------------------------- - Section headers - --------------------------------------------------------*/ -typedef struct { - Elf32_Word sh_name; /*セクションヘッダ文字列テーブルセクションのインデックス*/ - Elf32_Word sh_type; /* タイプ(下記定義参照) */ - Elf32_Word sh_flags; - Elf32_Addr sh_addr; /* */ - Elf32_Off sh_offset; /* ファイルの先頭からのオフセット */ - Elf32_Word sh_size; /* バイト単位のサイズ */ - Elf32_Word sh_link; /* sh_typeによって値の意味が変わる */ - Elf32_Word sh_info; /* sh_typeによって値の意味が変わる */ - Elf32_Word sh_addralign; /* アラインメント制限(0or1で制限なし,4で4ByteAlign) */ - Elf32_Word sh_entsize; /* 固定サイズのエントリテーブルがある場合、1要素のサイズ */ -} Elf32_Shdr; - -/* sh_addr mod sh_addralign = 0 でなければならない */ - -/* Section Types, [sh_type] */ -#define SHT_NULL 0 -#define SHT_PROGBITS 1 -#define SHT_SYMTAB 2 -#define SHT_STRTAB 3 -#define SHT_RELA 4 -#define SHT_HASH 5 -#define SHT_DYNAMIC 6 -#define SHT_NOTE 7 -#define SHT_NOBITS 8 -#define SHT_REL 9 -#define SHT_SHLIB 10 -#define SHT_DYNSYM 11 -#define SHT_LOPROC 0x70000000 -#define SHT_HIPROC 0x7fffffff -#define SHT_LOUSER 0x80000000 -#define SHT_HIUSER 0xffffffff - - -/* [sh_flags] */ -#define SHF_WRITE 0x1 -#define SHF_ALLOC 0x2 -#define SHF_EXECINSTR 0x4 -#define SHF_MASKPROC 0xf0000000 -/* ARM-EABI-specific */ -#define SHF_ENTRYSECT 0x10000000 /* The section contains an entry point. */ -#define SHF_COMDEF 0x80000000 /* The section may be multiply defined in the input to a link step. */ -/* others */ -#define SHF_LINK_ORDER 0x80 - -/*セクションインデックス*/ -//Sym->st_shndxなど -#define SHN_UNDEF 0 -#define SHN_LORESERVE 0xff00 -#define SHN_LOPROC 0xff00 -#define SHN_HIPROC 0xff1f -#define SHN_ABS 0xfff1 -#define SHN_COMMON 0xfff2 -#define SHN_HIRESERVE 0xffff - - -//ここからはヘッダでなく実体データ構造 - -/*--------------------------------------------------------- - Symbol Table Entry - --------------------------------------------------------*/ -typedef struct { - Elf32_Word st_name; /* シンボル文字列テーブルのインデックス */ - Elf32_Addr st_value; /* おそらく関連するセクション内でのオフセット値 */ - Elf32_Word st_size; /* サイズがないか、不明な場合は 0 */ - unsigned char st_info; /* バインド と タイプ */ - unsigned char st_other; /* 現在は 0 が入る */ - Elf32_Half st_shndx; /* 関連するセクションヘッダテーブルのインデックス */ -} Elf32_Sym; - - -/* st_info */ -#define ELF32_ST_BIND(i) ((i)>>4) -#define ELF32_ST_TYPE(i) ((i)&0xf) -#define ELF32_ST_INFO(b,t) (((b)<<4)+((t)&0xf)) - -/* st_info の BIND */ -#define STB_LOCAL 0 -#define STB_GLOBAL 1 -#define STB_WEAK 2 -#define STB_LOPROC 13 -#define STB_HIPROC 15 - -/* st_info の TYPE */ -#define STT_NOTYPE 0 /*未定義*/ -#define STT_OBJECT 1 /*データオブジェクト*/ -#define STT_FUNC 2 -#define STT_SECTION 3 -#define STT_FILE 4 -#define STT_LOPROC 13 -#define STT_HIPROC 15 - - -/*--------------------------------------------------------- - Relocation Entry - --------------------------------------------------------*/ -typedef struct { - Elf32_Addr r_offset; - Elf32_Word r_info; -} Elf32_Rel; - -typedef struct { - Elf32_Addr r_offset; - Elf32_Word r_info; - Elf32_Sword r_addend; -} Elf32_Rela; - -#define ELF32_R_SYM(i) ((i)>>8) -#define ELF32_R_TYPE(i) ((unsigned char)(i)) -#define ELF32_R_INFO(s,t) (((s)<<8)+(unsigned char)(t)) - - -/* r_info の TYPE */ -#define R_ARM_NONE 0 /* Any No relocation. Encodes dependencies between sections. */ -#define R_ARM_PC24 1 /* ARM B/BL S . P + A */ -#define R_ARM_ABS32 2 /* 32-bit word S + A */ -#define R_ARM_REL32 3 /* 32-bit word S . P + A */ -#define R_ARM_PC13 4 /* ARM LDR r, [pc,…] S . P + A */ -#define R_ARM_ABS16 5 /* 16-bit half-word S + A */ -#define R_ARM_ABS12 6 /* ARM LDR/STR S + A */ -#define R_ARM_THM_ABS5 7 /* Thumb LDR/STR S + A */ -#define R_ARM_ABS8 8 /* 8-bit byte S + A */ -#define R_ARM_SBREL32 9 /* 32-bit word S . B + A */ -#define R_ARM_THM_PC22 10 /* Thumb BL pair S . P+ A */ -#define R_ARM_THM_PC8 11 /* Thumb LDR r, [pc,…] S . P + A */ -#define R_ARM_AMP_VCALL9 12 /* AMP VCALL Obsolete.SA-1500 only. */ -#define R_ARM_SWI24 13 /* ARM SWI S + A */ -#define R_ARM_THM_SWI8 14 /* Thumb SWI S + A */ -#define R_ARM_XPC25 15 /* ARM BLX S . P+ A */ -#define R_ARM_THM_XPC22 16 /* Thumb BLX pair S . P+ A */ - -/* 17-31, reserved to ARM Linux */ -//17-19 Reserved to ARM LINUX -#define R_ARM_COPY 20 /* 32 bit word Copy symbol at dynamic link time. */ -#define R_ARM_GLOB_DAT 21 /* 32 bit word Create GOT entry. */ -#define R_ARM_JUMP_SLOT 22 /* 32 bit word Create PLT entry. */ -#define R_ARM_RELATIVE 23 /* 32 bit word Adjust by program base. */ -#define R_ARM_GOTOFF 24 /* 32 bit word Offset relative to start of GOT. */ -#define R_ARM_GOTPC 25 /* 32 bit word Insert address of GOT. */ -#define R_ARM_GOT32 26 /* 32 bit word Entry in GOT. */ -#define R_ARM_PLT32 27 /* ARM BL Entry in PLT. */ - -/* 28-31 Reserved to ARM LINUX */ -#define R_ARM_ALU_PCREL_7_0 32 /* ARM ADD/SUB (S . P + A) & 0x000000FF */ -#define R_ARM_ALU_PCREL_15_8 33 /* ARM ADD/SUB (S . P + A) & 0x0000FF00 */ -#define R_ARM_ALU_PCREL_23_15 34 /* ARM ADD/SUB (S . P + A) & 0x00FF0000 */ -#define R_ARM_LDR_SBREL_11_0 35 /* ARM LDR/STR (S . B + A) & 0x00000FFF */ -#define R_ARM_ALU_SBREL_19_12 36 /* ARM ADD/SUB (S . B + A) & 0x000FF000 */ -#define R_ARM_ALU_SBREL_27_20 37 /* ARM ADD/SUB (S . B + A) & 0x0FF00000 */ - -#define R_ARM_TARGET1 38 -#define R_ARM_ROSEGREL32 39 -#define R_ARM_V4BX 40 -#define R_ARM_TARGET2 41 -#define R_ARM_PREL31 42 - -/* 96-111, reserved to ARM g++ */ -#define R_ARM_GNU_VTENTRY 100 /* 32 bit word Record C++ vtable entry. */ -#define R_ARM_GNU_VTINHERIT 101 /* 32 bit word Record C++ member usage. */ -#define R_ARM_THM_PC11 102 /* Thumb B S . P + A */ -#define R_ARM_THM_PC9 103 /* Thumb B S . P + A */ - -/* 112-127, reserved for private experiments */ - -/* 128-248, reserved to ARM */ -#define R_ARM_RXPC25 249 /* ARM BLX (ΔS . ΔP) + A #define For calls between program segments. */ -#define R_ARM_RSBREL32 250 /* Word (ΔS . ΔSB) + A For an offset from SB, the static base. */ -#define R_ARM_THM_RPC22 251 /* Thumb BL/BLX pair (ΔS . ΔP) + A For calls between program segments. */ -#define R_ARM_RREL32 252 /* Word (ΔS . ΔP) + A For on offset between two segments. */ -#define R_ARM_RABS32 253 /* Word ΔS + A For the address of a location in the target segment. */ -#define R_ARM_RPC24 254 /* ARM B/BL (ΔS . ΔP) + A For calls between program segments. */ -#define R_ARM_RBASE 255 /* None None.Identifies the segment being relocated by the following - relocation directives. The ARM EABI poses two problems for relocating - executables and shared objects encoded in */ - - -// shirait -#define R_ARM_LDR_PC_G0 4 //LDR - -#define R_ARM_ABS12 6 //LDR, STR - -#define R_ARM_THM_CALL 10 //R_ARM_THM_PC22と同じ - -#define R_ARM_CALL 28 //BL/BLX -#define R_ARM_JUMP24 29 //B/BL -#define R_ARM_THM_JUMP24 30 - -#define R_ARM_MOVW_ABS_NC 43 //MOVW -#define R_ARM_MOVT_ABS 44 //MOVT -#define R_ARM_MOVW_PREL_NC 45 //MOVW -#define R_ARM_MOVT_PREL 46 //MOVT - -#define R_ARM_ALU_PC_G0_NC 57 //ADD, SUB -#define R_ARM_ALU_PC_G0 58 //ADD, SUB -#define R_ARM_ALU_PC_G1_NC 59 //ADD, SUB -#define R_ARM_ALU_PC_G1 60 //ADD, SUB -#define R_ARM_ALU_PC_G2 61 //ADD, SUB -#define R_ARM_LDR_PC_G1 62 //LDR, STR, LDRB, STRB -#define R_ARM_LDR_PC_G2 63 //LDR, STR, LDRB, STRB -#define R_ARM_LDRS_PC_G0 64 //LDRD, STRD, LDRH, STRH, LDRSH, LDRSB -#define R_ARM_LDRS_PC_G1 65 //LDRD, STRD, LDRH, STRH, LDRSH, LDRSB -#define R_ARM_LDRS_PC_G2 66 //LDRD, STRD, LDRH, STRH, LDRSH, LDRSB -#define R_ARM_LDC_PC_G0 67 //LDC, STC -#define R_ARM_LDC_PC_G1 68 //LDC, STC -#define R_ARM_LDC_PC_G2 69 //LDC, STC -#define R_ARM_ALU_SB_G0_NC 70 //ADD, SUB -#define R_ARM_ALU_SB_G0 71 //ADD, SUB -#define R_ARM_ALU_SB_G1_NC 72 //ADD, SUB -#define R_ARM_ALU_SB_G1 73 //ADD, SUB -#define R_ARM_ALU_SB_G2 74 //ADD, SUB -#define R_ARM_LDR_SB_G0 75 //LDR, STR, LDRB, STRB -#define R_ARM_LDR_SB_G1 76 //LDR, STR, LDRB, STRB -#define R_ARM_LDR_SB_G2 77 //LDR, STR, LDRB, STRB -#define R_ARM_LDRS_SB_G0 78 //LDRD, STRD, LDRH, STRH, LDRSH, LDRSB -#define R_ARM_LDRS_SB_G1 79 //LDRD, STRD, LDRH, STRH, LDRSH, LDRSB -#define R_ARM_LDRS_SB_G2 80 //LDRD, STRD, LDRH, STRH, LDRSH, LDRSB -#define R_ARM_LDC_SB_G0 81 //LDC, STC -#define R_ARM_LDC_SB_G1 82 //LDC, STC -#define R_ARM_LDC_SB_G2 83 //LDC, STC -#define R_ARM_MOVW_BREL_NC 84 //MOVW -#define R_ARM_MOVT_BREL 85 //MOVT -#define R_ARM_MOVW_BREL 86 //MOVW - -#define R_ARM_GOT_BREL12 97 //LDR -#define R_ARM_GOTOFF12 98 //LDR, STR - -#define R_ARM_TLS_LDO12 109 //LDR, STR -#define R_ARM_TLS_LE12 110 //LDR, STR -#define R_ARM_TLS_TE12GP 111 //LDR - - - -/*--------------------------------------------------------- - Dynamic Section elf_v1.2 - --------------------------------------------------------*/ -typedef struct { - Elf32_Sword d_tag; - union { - Elf32_Word d_val; - Elf32_Addr d_ptr; - } d_un; -} Elf32_Dyn; - - -/* Additional symbol types for Thumb. */ -#define STT_ARM_TFUNC STT_LOPROC /* A Thumb function. */ -#define STT_ARM_16BIT STT_HIPROC /* A Thumb label. */ - - - - - - - - - -/*--------------------------------------------------------- - ELFヘッダを読み出す - --------------------------------------------------------*/ -void *ELF_LoadELFHeader(const void *buf, Elf32_Ehdr *ehdr); - - - -#endif /* ELF_H_ */ - diff --git a/build/tools/makenorfirm/format_nlist.h b/build/tools/makenorfirm/format_nlist.h deleted file mode 100644 index 6e5ba825..00000000 --- a/build/tools/makenorfirm/format_nlist.h +++ /dev/null @@ -1,54 +0,0 @@ -/*---------------------------------------------------------------------------* - Project: TwlFirm - tools - makenorfirm - File: format_nlist.h - - Copyright 2007 Nintendo. All rights reserved. - - These coded instructions, statements, and computer programs contain - proprietary information of Nintendo of America Inc. and/or Nintendo - Company Ltd., and are protected by Federal copyright law. They may - not be disclosed to third parties or copied or duplicated in any form, - in whole or in part, without the prior written consent of Nintendo. - - $Date:: 2007-09-06$ - $Rev$ - $Author$ - *---------------------------------------------------------------------------*/ -#ifndef FORMAT_NLIST_H_ -#define FORMAT_NLIST_H_ - -#include -#include "misc.h" -#include "path.h" - -#define SPECFILE_MAGIC_ID "#NORSF" - -#define CRC16_INIT_VALUE 0xffff - -//--------------------------------------------------------------------------- -// Banner Spec File -//--------------------------------------------------------------------------- - -// Command List -typedef struct -{ - char *string; - BOOL (*funcp) (char *, int num); - -} -tCommandDesc; - - -// F Command -typedef struct -{ - u32 offsetStart; - u32 offsetEnd; - u32 padding; - char fullPathSrc[FILENAME_MAX]; - -} -tFileDesc; - - -#endif // FORMAT_NLIST_H_ diff --git a/build/tools/makenorfirm/format_rom.h b/build/tools/makenorfirm/format_rom.h deleted file mode 100644 index 3cb717fc..00000000 --- a/build/tools/makenorfirm/format_rom.h +++ /dev/null @@ -1,51 +0,0 @@ -/*---------------------------------------------------------------------------* - Project: TwlFirm - tools - makenorfirm - File: format_rom.h - - Copyright 2007 Nintendo. All rights reserved. - - These coded instructions, statements, and computer programs contain - proprietary information of Nintendo of America Inc. and/or Nintendo - Company Ltd., and are protected by Federal copyright law. They may - not be disclosed to third parties or copied or duplicated in any form, - in whole or in part, without the prior written consent of Nintendo. - - $Date:: 2007-09-06$ - $Rev$ - $Author$ - *---------------------------------------------------------------------------*/ -#ifndef FORMAT_ROM_H_ -#define FORMAT_ROM_H_ - -#include "misc.h" -#include - - -#define DEFAULT_ALIGN 16 -#define FIRM_ALIGN DEFAULT_ALIGN -#define FIRM_ALIGN_MASK (FIRM_ALIGN - 1) - -#define DEFAULT_HOSTROOT "." -#define DEFAULT_ROOT "/" - -#define DEFAULT_REJECT_1 "CVS" -#define DEFAULT_REJECT_2 "vssver.scc" - -#define FORMAT_VERSION "1.0" - -#define ENTRYNAME_MAX 127 - -#define DEFAULT_LISTFILE "default.nlf" - -#define DEFAULT_NORFIRM_SUFFIX ".nor" -#define DEFAULT_SPECFILE_SUFFIX ".norsf" - -/*===========================================================================* - * ROM FORMAT - *===========================================================================*/ - -//--------------------------------------------------------------------------- -// ROM HEADER -//--------------------------------------------------------------------------- - -#endif //FORMAT_ROM_H_ diff --git a/build/tools/makenorfirm/format_sign.h b/build/tools/makenorfirm/format_sign.h deleted file mode 100644 index 782a5d2b..00000000 --- a/build/tools/makenorfirm/format_sign.h +++ /dev/null @@ -1,32 +0,0 @@ -/*---------------------------------------------------------------------------* - Project: TwlFirm - SS - File: format_sign.h - - Copyright 2006 Nintendo. All rights reserved. - - These coded instructions, statements, and computer programs contain - proprietary information of Nintendo of America Inc. and/or Nintendo - Company Ltd., and are protected by Federal copyright law. They may - not be disclosed to third parties or copied or duplicated in any form, - in whole or in part, without the prior written consent of Nintendo. - - $Date:: 2007-09-06$ - $Rev$ - $Author$ - *---------------------------------------------------------------------------*/ -#ifndef FIRM_MAKENORFIRM_ACSIGN_FORMAT_H_ -#define FIRM_MAKENORFIRM_ACSIGN_FORMAT_H_ - -#include "format_rom.h" - - -#ifdef __cplusplus -extern "C" { -#endif - -#ifdef __cplusplus -} /* extern "C" */ -#endif - -/* FIRM_MAKENORFIRM_ACSIGN_FORMAT_H_ */ -#endif diff --git a/build/tools/makenorfirm/makenorfirm.c b/build/tools/makenorfirm/makenorfirm.c deleted file mode 100644 index 613efa74..00000000 --- a/build/tools/makenorfirm/makenorfirm.c +++ /dev/null @@ -1,106 +0,0 @@ -/*---------------------------------------------------------------------------* - Project: TwlFirm - tools - makenorfirm - File: makenorfirm.c - - Copyright 2007 Nintendo. All rights reserved. - - These coded instructions, statements, and computer programs contain - proprietary information of Nintendo of America Inc. and/or Nintendo - Company Ltd., and are protected by Federal copyright law. They may - not be disclosed to third parties or copied or duplicated in any form, - in whole or in part, without the prior written consent of Nintendo. - - $Date:: 2007-09-06$ - $Rev$ - $Author$ - *---------------------------------------------------------------------------*/ -#include -#include -#include // strcasecmp() -#include // getopt() -#include "makenorfirm.h" -#include "format_rom.h" -#include "path.h" -#include "defval.h" -#include "version.h" - -static int makenorfirm(const char *specFile, const char *norFile); - -//--------------------------------------------------------------------------- -// Main -//--------------------------------------------------------------------------- - -int main(int argc, char *argv[]) -{ - int n; - int narg; - char *norfirmFile; - - InitAppName(argv[0]); - - while ((n = getopt(argc, argv, "D:hvpd")) != -1) - { - switch (n) - { - case 'h': - case 'v': - goto usage; - - case 'D': - AddDefVal(optarg); - break; - - case 'p': - PrintMode = TRUE; - break; - - case 'd': - DebugMode = TRUE; - break; - - default: - break; - } - } - - narg = argc - optind; - if (narg > 0) - { - // Make SpecFile->NorfirmFile - norfirmFile = - strdup(narg > - 1 ? argv[optind + 1] : ChangeSuffix(argv[optind], DEFAULT_NORFIRM_SUFFIX)); - return makenorfirm(argv[optind], norfirmFile); - } - - usage: - { - char *makenorfirm = GetAppName(); - - fprintf(stderr, - "NITRO-SDK Development Tool - %s - Make norfirm file \n" - "Build %lu\n\n" - "Usage: %s [-phv] [-DNAME=VALUE ...] SPECFILE [NORFIRMFILE]\n\n", - makenorfirm, SDK_DATE_OF_LATEST_FILE, makenorfirm); - } - return 1; -} - - -//--------------------------------------------------------------------------- -// makenorfirm -//--------------------------------------------------------------------------- - -static int makenorfirm(const char *specFile, const char *norFile) -{ - debug_printf("makenorfirm(): '%s' -> '%s'\n", specFile, norFile); - - // Check identical - if (specFile && norFile && !strcasecmp(specFile, norFile)) - { - error("norfirm spec file is identical '%s'", norFile); - return 1; - } - - return OutputNorfirmFile(specFile, norFile) ? 0 : 1; -} diff --git a/build/tools/makenorfirm/makenorfirm.h b/build/tools/makenorfirm/makenorfirm.h deleted file mode 100644 index bb8eed65..00000000 --- a/build/tools/makenorfirm/makenorfirm.h +++ /dev/null @@ -1,24 +0,0 @@ -/*---------------------------------------------------------------------------* - Project: TwlFirm - tools - makenorfirm - File: makenorfirm.h - - Copyright 2007 Nintendo. All rights reserved. - - These coded instructions, statements, and computer programs contain - proprietary information of Nintendo of America Inc. and/or Nintendo - Company Ltd., and are protected by Federal copyright law. They may - not be disclosed to third parties or copied or duplicated in any form, - in whole or in part, without the prior written consent of Nintendo. - - $Date:: 2007-09-06$ - $Rev$ - $Author$ - *---------------------------------------------------------------------------*/ -#ifndef MAKENORFIRM_H_ -#define MAKENORFIRM_H_ - -#include "misc.h" - -BOOL OutputNorfirmFile(const char *specFile, const char *norFile); - -#endif //MAKENORFIRM_H_ diff --git a/build/tools/makenorfirm/misc.c b/build/tools/makenorfirm/misc.c deleted file mode 100644 index 7706d6be..00000000 --- a/build/tools/makenorfirm/misc.c +++ /dev/null @@ -1,628 +0,0 @@ -/*---------------------------------------------------------------------------* - Project: TwlFirm - tools - makenorfirm - File: misc.c - - Copyright 2007 Nintendo. All rights reserved. - - These coded instructions, statements, and computer programs contain - proprietary information of Nintendo of America Inc. and/or Nintendo - Company Ltd., and are protected by Federal copyright law. They may - not be disclosed to third parties or copied or duplicated in any form, - in whole or in part, without the prior written consent of Nintendo. - - $Date:: 2007-09-06$ - $Rev$ - $Author$ - *---------------------------------------------------------------------------*/ -#include -#include // calloc() -#include // free(), exit() -#include // setmode() -#include // stat() -#include // setmode() -#include // strlen() -#include // va_start(),va_end() -#include // localtime() - -#include -#include "misc.h" - -BOOL DebugMode = FALSE; -BOOL PrintMode = FALSE; -char *PubkeyFileName = NULL; - -/*---------------------------------------------------------------------------* - * File Output Utilities - * - * BOOL OpenFile( const char* filename ) - * void CloseFile( void ) - * BOOL CheckResult( void ) - * void PutBuffer( const void* ptr, int len ) - * void PutByte( u8 c ) - * void PutWord( u16 c ) - * void PutWord( u32 c ) - * void PutString( const char *str ) - *---------------------------------------------------------------------------*/ - -static FILE *OutFile = NULL; -static const char *FileName = NULL; -static BOOL Status = FALSE; - - -// -// File Open -// - -BOOL OpenFile(const char *filename) -{ - if (OutFile) - CloseFile(); - - if (filename) - { - if (NULL == (OutFile = fopen(filename, "wb+"))) - { - error("Can't write '%s'", filename); - Status = FALSE; - return FALSE; - } - } - else - { - setmode(1, O_BINARY); - OutFile = stdout; // out to console if filename == NULL - } - FileName = filename; - Status = TRUE; - - return TRUE; -} - - -// -// File Close -// - -BOOL CloseFile(void) -{ - if (OutFile) - { - if (FileName) - { - if (fclose(OutFile) == -1) - { - error("Can't close '%s'", FileName); - Status = FALSE; - } - } - else - { - setmode(1, O_TEXT); - } - } - OutFile = NULL; - - return Status; -} - - -// -// File Seek -// - -void SeekFile(long pos) -{ - if (OutFile && fseek(OutFile, pos, SEEK_SET)) - { - error("Can't seek '%s'", FileName ? FileName : ""); - CloseFile(); - Status = FALSE; - } -} - - -// -// Error Check -// - -BOOL CheckResult(void) -{ - return Status; -} - - -// -// Delete outfile -// - -void DeleteOutFile(void) -{ - // Delete outfile - if (FileName) - { - debug_printf("Delete '%s'\n", FileName); - (void)unlink(FileName); - FileName = NULL; - } - return; -} - - -// -// Buffer Output -// - -void PutBuffer(const void *ptr, int len) /* If error, close file */ -{ - if (OutFile && len != fwrite(ptr, 1, len, OutFile)) - { - error("Can't write buffer to '%s'", FileName ? FileName : ""); - CloseFile(); - Status = FALSE; - } -} - -// -// Buffer Input -// - -void GetBuffer(void *ptr, int len) /* If error, close file */ -{ - if (OutFile && len != fread(ptr, 1, len, OutFile)) - { - error("Can't read '%s'", FileName ? FileName : ""); - CloseFile(); - Status = FALSE; - } -} - -// -// Byte/Half/Word Output -// - -void PutByte(u8 c) -{ - PutBuffer(&c, 1); -} -void PutHalf(u16 c) -{ - PutBuffer(&c, 2); -} -void PutWord(u32 c) -{ - PutBuffer(&c, 4); -} -void PutString(const char *str) -{ - PutBuffer(str, strlen(str)); -} - - -// -// Printf -// - -void PrintString(const char *fmt, ...) -{ - char *buffer; - va_list va; - int nchars; - int bufsize = FILENAME_MAX; - - while (1) - { - buffer = Alloc(bufsize); - va_start(va, fmt); - nchars = vsnprintf(buffer, bufsize, fmt, va); - va_end(va); - - if (0 <= nchars && nchars < bufsize) - { - break; - } - - Free(&buffer); - bufsize *= 2; - } - - if (nchars > 0) - { - PutBuffer(buffer, nchars); - } - Free(&buffer); -} - - -/*---------------------------------------------------------------------------* - * File Read/Write Utilities - * - * int ReadFile( const char* filename, void** buffer ) - * - * Read a file to buffer allocated internally - * Return read size - * Add '\0' at tail of file for help to handle text file - * - * BOOL WriteFile( const char* filename, void** buffer, int size ) - *---------------------------------------------------------------------------*/ - -int ReadFile(const char *filename, void *filebuffer, int size) -{ - FILE *fp; - struct stat fileStat; - int fileSize, readSize; - void **buffer = (void **)filebuffer; - - /* Check file */ - if (stat(filename, &fileStat) || !S_ISREG(fileStat.st_mode)) - { - goto error; - } - fileSize = fileStat.st_size; - if (fileSize < 0) - { - goto error; - } - - /* Open file */ - fp = fopen(filename, "rb"); - if (!fp) - { - goto error; - } - - if (size && (size < fileSize)) - { - readSize = size; - } - else - { - readSize = fileSize; - } - - /* Read file */ - *buffer = Alloc(readSize + 1); /* error handle is done in Alloc() */ - /* size+1 for '\0' to handle text file */ - if (readSize != fread(*buffer, sizeof(char), readSize, fp)) - { - goto error_free_close; - } - - (*(char **)buffer)[readSize] = '\0'; /* Works as terminater if file is text file */ - - /* Close file */ - fclose(fp); - return readSize; - - error_free_close: - Free(buffer); - fclose(fp); - error: - error("Can't read '%s'", filename); - return -1; -} - - -int ReadFileWithPadding(const char *filename, void *filebuffer, int size, int boundary) -{ - FILE *fp; - struct stat fileStat; - int fileSize, readSize, padSize; - void **buffer = (void **)filebuffer; - - if (!boundary) - { - return ReadFile(filename, buffer, size); - } - - /* Check file */ - if (stat(filename, &fileStat) || !S_ISREG(fileStat.st_mode)) - { - goto error; - } - fileSize = fileStat.st_size; - if (fileSize < 0) - { - goto error; - } - - /* Open file */ - fp = fopen(filename, "rb"); - if (!fp) - { - goto error; - } - - if (size && (size < fileSize)) - { - readSize = size; - } - else - { - readSize = fileSize; - } - - padSize = (boundary - (readSize & (boundary-1))) & (boundary-1); - - /* Read file */ - *buffer = Alloc(readSize + padSize); /* error handle is done in Alloc() */ - /* size+1 for '\0' to handle text file */ - if (readSize != fread(*buffer, sizeof(char), readSize, fp)) - { - goto error_free_close; - } - - memset((char*)*buffer + readSize, 0, padSize); - - /* Close file */ - fclose(fp); - return readSize + padSize; - - error_free_close: - Free(buffer); - fclose(fp); - error: - error("Can't read '%s'", filename); - return -1; -} - - -BOOL WriteFile(const char *filename, void *buffer, int size) -{ - debug_printf("WriteFile %s\n", filename); - - (void)OpenFile(filename); - PutBuffer(buffer, size); - CloseFile(); - Free(&buffer); - return CheckResult(); -} - - -/*---------------------------------------------------------------------------* - * Time Format Utilities - * - * char* GetGMTime( const time_t time ) Show GMT - * char* GetTime( const time_t time ) Show local Time - *---------------------------------------------------------------------------*/ - -char *GetGMTime(const time_t time) -{ - static char timebuffer[32]; - strftime(timebuffer, sizeof(timebuffer), "%y/%m/%d-%H:%M:%S", gmtime(&time)); - return timebuffer; -} - - -char *GetTime(const time_t time) -{ - static char timebuffer[32]; - strftime(timebuffer, sizeof(timebuffer), "%y/%m/%d-%H:%M:%S", localtime(&time)); - return timebuffer; -} - - -/*---------------------------------------------------------------------------* - * Memory Allocation Utilities - * - * void* Alloc( size_t size ) - *---------------------------------------------------------------------------*/ - -void *Alloc(size_t size) -{ - void *t = calloc(1, size); - - if (t == NULL) - { - error("Can't allocate memory."); - exit(10); - } - return t; -} - - -void Free(void *p) -{ - void **ptr = (void **)p; - - if (*ptr) - { - free(*ptr); - (*ptr) = NULL; - } -} - - -/*---------------------------------------------------------------------------* - * VBuffer - * - * void PutVBuffer( VBuffer* vbuf, char c ) - *---------------------------------------------------------------------------*/ - -void PutVBuffer(VBuffer * vbuf, char c) -{ - int size; - char *tmp_buffer; - - if (vbuf->buffer == 0) - { - vbuf->size = VBUFFER_INITIAL_SIZE; - vbuf->buffer = Alloc(vbuf->size); // buffer is CALLOCed - } - size = strlen(vbuf->buffer); - - if (size >= vbuf->size - 1) - { - // Need buffer expansion - vbuf->size *= 2; - tmp_buffer = Alloc(vbuf->size); // buffer is CALLOCed - strcpy(tmp_buffer, vbuf->buffer); - Free(&vbuf->buffer); - vbuf->buffer = tmp_buffer; - } - vbuf->buffer[size] = c; - return; -} - -char *GetVBuffer(VBuffer * vbuf) -{ - return vbuf->buffer; -} - -void InitVBuffer(VBuffer * vbuf) -{ - vbuf->buffer = 0; - vbuf->size = 0; -} - -void FreeVBuffer(VBuffer * vbuf) -{ - Free(&vbuf->buffer); -} - - -/*---------------------------------------------------------------------------* - * File Path Utilities - * - * char* ChangeBackSlash( char* path ) - *---------------------------------------------------------------------------*/ - -char *ChangeBackSlash(char *path) -{ - char *p = path; - - while (*p) - { - if (*p == '\\') - { - *p = '/'; - } - p++; - } - return path; -} - - -/*---------------------------------------------------------------------------* - * Math - * - * u16 CalcCRC16( u16 start, u8 *data, int size ) - *---------------------------------------------------------------------------*/ - -static u16 crc16_table[16] = { - 0x0000, 0xCC01, 0xD801, 0x1400, - 0xF001, 0x3C00, 0x2800, 0xE401, - 0xA001, 0x6C00, 0x7800, 0xB401, - 0x5000, 0x9C01, 0x8801, 0x4400 -}; - -u16 CalcCRC16(u16 start, u8 *data, int size) -{ - u16 r1; - u16 total = start; - - while (size-- > 0) - { - // 下位4bit - r1 = crc16_table[total & 0xf]; - total = (total >> 4) & 0x0fff; - total = total ^ r1 ^ crc16_table[*data & 0xf]; - - // 上位4bit - r1 = crc16_table[total & 0xf]; - total = (total >> 4) & 0x0fff; - total = total ^ r1 ^ crc16_table[(*data >> 4) & 0xf]; - - data++; - } - return total; -} - - -/*---------------------------------------------------------------------------* - * for firm header - * - *---------------------------------------------------------------------------*/ - -static u8 ConvertAlign( u32 ofs ) -{ - u8 i; - - ofs /= 4; - for (i=0; i<7; i++) - { - if ( ofs & 1 ) - { - break; - } - ofs >>= 1; - } - - return i; -} - -tROMAddrConvType ConvertHeaderRamAddr( s32 p ) -{ - tROMAddrConvType retval; - - retval.align = ConvertAlign( p ); - retval.address = (u16)((p - HW_WRAM)/(4< - -typedef enum -{ - FALSE = 0, - TRUE = 1 -} -BOOL; - -typedef unsigned char u8; -typedef unsigned short int u16; -typedef unsigned long int u32; -typedef unsigned long long u64; -typedef signed char s8; -typedef signed short int s16; -typedef signed long int s32; -typedef signed long long s64; -typedef volatile u8 vu8; -typedef volatile u32 vu32; -typedef vu32 REGType32v; - - - - -#define error(...) do { fprintf(stderr, "Error: "); \ - fprintf(stderr, __VA_ARGS__); \ - fprintf(stderr, "\n"); } while(0) - -#define warning(...) do { fprintf(stderr, "Warning: "); \ - fprintf(stderr, __VA_ARGS__); \ - fprintf(stderr, "\n"); } while(0) - -BOOL OpenFile(const char *filename); -BOOL CloseFile(void); -void SeekFile(long pos); -BOOL CheckResult(void); -void DeleteOutFile(void); -void PutBuffer(const void *ptr, int len); -void GetBuffer(void *ptr, int len); -void PutByte(u8 c); -void PutHalf(u16 c); -void PutWord(u32 c); -void PutString(const char *str); -void PrintString(const char *fmt, ...); - -#define READ_ALL 0 -int ReadFile(const char *filename, void *filebuffer, int size); -int ReadFileWithPadding(const char *filename, void *filebuffer, int size, int boundary); -BOOL WriteFile(const char *filename, void *buffer, int size); - -char *GetGMTime(const time_t time); -char *GetTime(const time_t time); - -void *Alloc(size_t size); -void Free(void *p); - -typedef struct -{ - char *buffer; - int size; -} -VBuffer; - -#define VBUFFER_INITIAL_SIZE 1024 -void InitVBuffer(VBuffer * vbuf); -void FreeVBuffer(VBuffer * vbuf); -void PutVBuffer(VBuffer * vbuf, char c); -char *GetVBuffer(VBuffer * vbuf); - -char *ChangeBackSlash(char *path); - -u16 CalcCRC16(u16 start, u8 *data, int size); -const char *WrapNull(const char *str); - -typedef struct -{ - u16 address; - u8 align; -} -tROMAddrConvType; - -tROMAddrConvType ConvertHeaderRamAddr( s32 p ); -tROMAddrConvType ConvertHeaderRomOffset( s32 p ); -u16 ConvertHeaderRomOffsetAlign( s32 p, u32 align ); - -typedef union -{ - struct - { - u32 sign:1; - u32 header_hash:1; - u32 arm9_hash:1; - u32 arm7_hash:1; - u32 hash_table_hash:1; - u32 final_hash:1; - u32 header_footer:1; - u32 wl_check:1; - } - e; - u32 raw; -} -tErrorFlags; - -extern BOOL DebugMode; -extern BOOL PrintMode; -extern char *PubkeyFileName; -void debug_printf(const char *str, ...); -void debug_printf2(const char *str, ...); - -#endif //MISC_H_ diff --git a/build/tools/makenorfirm/out_norfirm.c b/build/tools/makenorfirm/out_norfirm.c deleted file mode 100644 index 2eb98bd8..00000000 --- a/build/tools/makenorfirm/out_norfirm.c +++ /dev/null @@ -1,984 +0,0 @@ -/*---------------------------------------------------------------------------* - Project: TwlFirm - tools - makenorfirm - File: out_norfirm.c - - Copyright 2007 Nintendo. All rights reserved. - - These coded instructions, statements, and computer programs contain - proprietary information of Nintendo of America Inc. and/or Nintendo - Company Ltd., and are protected by Federal copyright law. They may - not be disclosed to third parties or copied or duplicated in any form, - in whole or in part, without the prior written consent of Nintendo. - - $Date:: 2007-09-06$ - $Rev$ - $Author$ - *---------------------------------------------------------------------------*/ -#include -#include // atoi() -#include // strcmp() -#include // isprint() -#include // chdir() -#include -#include // UCHAR_MAX -#include -#include // stat() -#include "elf.h" -#include "misc.h" -#include "defval.h" -#include "format_rom.h" -#include "format_nlist.h" -#include "makenorfirm.h" -#include "format_sign.h" -#include "acsign_nor.h" -#include "compress.h" - -#define SDK_ASM - -#include -#include "../acsign/aes2.h" - -#define NANDCMD "BOOT_NAND" -#define SBIN9CMD "ARM9_SBIN" -#define SBIN7CMD "ARM7_SBIN" -#define ELF9CMD "ARM9_ELF" -#define ELF7CMD "ARM7_ELF" -#define COMP9CMD "ARM9_COMP" -#define COMP7CMD "ARM7_COMP" -#define DECOMPCMD "DECOMP_PROC" -#define BAUDCMD "BAUDRATE" -#define ARM9X2CMD "ARM9_X2" -#define VERCMD "VERSION" -#define RSAKEYCMD "RSA_KEY" -#define OUTKEYCMD "OUT_KEY" -#define WREGCMD "WRAM_RBIN" -#define ENDKEYCMD "ENC_KEYINFO" -#define NCDCMD "NCD_ROMOFS" -#define ERRCMD "ERROR" - -static BOOL ConstructNorfirmFile(char * specFile); -static BOOL ReadSbinFile(const char *fileName, void* minfo, void* hash, BOOL comp); -static BOOL ReadKeyFile(const char *fileName); -static BOOL ReadWramRegFile(const char *fileName); -static s32 GetRamAddr(const char *fileName); - -static BOOL EncryptBuffer(char *buffer, int length); - -static BOOL BTNAND_Command(char * line, int num); -static BOOL Sbin9_Command(char * line, int num); -static BOOL Sbin7_Command(char * line, int num); -static BOOL Elf9_Command(char * line, int num); -static BOOL Elf7_Command(char * line, int num); -static BOOL Comp9_Command(char * line, int num); -static BOOL Comp7_Command(char * line, int num); -static BOOL Decomp_Command(char * line, int num); -static BOOL BAUDRATE_Command(char * line, int num); -static BOOL ARM9X2_Command(char * line, int num); -static BOOL VERSION_Command(char * line, int num); -static BOOL RSAKEY_Command(char * line, int num); -static BOOL OUTKEY_Command(char * line, int num); -static BOOL WramRegs_Command(char * line, int num); -static BOOL ENCKEY_Command(char * line, int num); -static BOOL NcdOffset_Command(char * line, int num); -static BOOL ERROR_Command(char * line, int num); - -static BOOL InitializeAesKey(void); -static BOOL InitializeNorfirmFile(void); -static BOOL FinalizeNorfirmFile(const char *norFile); - -static s32 Offset; // Current offset -static int LineNum; // Line number for error message -static const char *specFileName; // specFile name for error message - -NORHeader norHeader; // Norfirm Header Shadow -FIRMSignedContext signedContext; -u8 *keyFileBuf; -BOOL compArm9 = TRUE; -BOOL compArm7 = TRUE; -tErrorFlags errFlags; - -//--------------------------------------------------------------------------- -// Output - norfirm File -//--------------------------------------------------------------------------- - -BOOL OutputNorfirmFile(const char *specFile, const char *norFile) -{ - char *buffer; - BOOL state; - - if (ReadFile(specFile, &buffer, READ_ALL) <= 0) - { - return FALSE; - } - - if (!OpenFile(norFile)) - { - return FALSE; - } - - specFileName = specFile; - - state = InitializeNorfirmFile() && ConstructNorfirmFile(buffer) && - FinalizeNorfirmFile(norFile) && CloseFile(); - - if (!state) - { - DeleteOutFile(); - } - - return state; -} - - -//--------------------------------------------------------------------------- -// Output - Norfirm File -//--------------------------------------------------------------------------- - -static const tCommandDesc command[] = { - {SBIN9CMD, Sbin9_Command}, {SBIN7CMD, Sbin7_Command}, - {ELF9CMD, Elf9_Command},{ELF7CMD, Elf7_Command}, - {COMP9CMD, Comp9_Command},{COMP7CMD, Comp7_Command}, - {DECOMPCMD, Decomp_Command}, - {NANDCMD, BTNAND_Command}, - {VERCMD, VERSION_Command}, - {BAUDCMD, BAUDRATE_Command}, - {ARM9X2CMD, ARM9X2_Command}, - {RSAKEYCMD, RSAKEY_Command}, - {OUTKEYCMD, OUTKEY_Command}, - {WREGCMD, WramRegs_Command}, - {ENDKEYCMD, ENCKEY_Command}, - {NCDCMD, NcdOffset_Command}, - {ERRCMD, ERROR_Command}, -}; - -BOOL ConstructNorfirmFile(char * specFile) -{ - char *line; - char *line_top; - char *p; - int i; - - LineNum = 0; - Offset = 0x00000000; - - line = specFile++; - - while (*line != '\0') - { - LineNum++; - - // Get command line - line_top = line; - while (*line != '\0') - { - if (*line++ == '\n') - { - break; - } - } - - // Print for debug - debug_printf("NORSF Line%4d [", LineNum, line); - for (p = line_top; p != line; p++) - { - if (isprint(*p)) - { - debug_printf("%c", *p); - } - } - debug_printf("]\n"); - - if (*line_top == '#') - { - } - else - { - for (i = 0; i < (sizeof(command) / sizeof(command[0])); i++) - { - if (!strncmp(line_top, command[i].string, strlen(command[i].string))) - { - if (command[i].funcp != NULL) - { - char line_cmd[FILENAME_MAX]; - char line_scan[FILENAME_MAX]; - char* line_conv; - int num; - - num = sscanf( line_top, - "%1024[^ :] : %1024[^ \x0d:#\n]", - line_cmd, line_scan - ); - line_conv = ResolveDefVal(line_scan); - - debug_printf("line_cmd = %s, line_conv = %s\n", line_cmd, line_conv); - - if (!command[i].funcp(line_conv, num - 1)) - return FALSE; - } - } - } - } - - } - return TRUE; -} - - -//--------------------------------------------------------------------------- -// Output - 'WramRegs' Command -//--------------------------------------------------------------------------- - -extern MIHeader_WramRegs wram_regs_init; -MIHeader_WramRegs* wram_regs; - -static BOOL WramRegs_Command(char * line, int num) -{ - if (num != 1) - { - error("Wrong format spec file '%s' line:%d", specFileName, LineNum); - return FALSE; - } - - debug_printf2("wram regs file = %s\n", line); - - return ReadWramRegFile(line); -} - -static BOOL ReadWramRegFile(const char *fileName) -{ - int file_size; - struct stat st; - - if (FILESTATUS_FILE != GetFileStatus(&st, fileName)) - { - error("'%s' is not regular file.", fileName); - return FALSE; - } - - if ((file_size = ReadFile(fileName, &wram_regs, READ_ALL)) < 0) - return FALSE; - - norHeader.h.w = *wram_regs; - - return CheckResult(); -} - -//--------------------------------------------------------------------------- -// Output - 'RSAKEY' Command -//--------------------------------------------------------------------------- - -static BOOL RSAKEY_Command(char * line, int num) -{ - if (num != 1) - { - error("Wrong format spec file '%s' line:%d", specFileName, LineNum); - return FALSE; - } - - debug_printf2("rsa key = %s\n", line); - - return ReadKeyFile(line); -} - -static BOOL ReadKeyFile(const char *fileName) -{ - int file_size; - struct stat st; - - if (FILESTATUS_FILE != GetFileStatus(&st, fileName)) - { - error("'%s' is not regular file.", fileName); - return FALSE; - } - - if ((file_size = ReadFile(fileName, &keyFileBuf, READ_ALL)) < 0) - return FALSE; - - return CheckResult(); -} - - -//--------------------------------------------------------------------------- -// Output - 'OUTKEY' Command -//--------------------------------------------------------------------------- - -static BOOL OUTKEY_Command(char * line, int num) -{ - if (num != 1) - { - error("Wrong format spec file '%s' line:%d", specFileName, LineNum); - return FALSE; - } - - debug_printf2("out key = %s\n", line); - - PubkeyFileName = line; - - return CheckResult(); -} - - -//--------------------------------------------------------------------------- -// Output - 'VERSION' Command -//--------------------------------------------------------------------------- - -static u8 ConvToBCD8(int x) -{ - u8 bcd = 0; - - x %= 100; - bcd |= (x / 10)<<4; - bcd |= (x % 10); - - return bcd; -} - -static BOOL VERSION_Command(char * line, int num) -{ - char scan[FILENAME_MAX]; - u64 version = -1; - - // rescan - num = sscanf( line, - "0x%1024[^\x0d\n]", - scan - ); - - if (num == 1) - { - // convert version info - version = strtoull(scan, NULL, 16); - } - else if (num == 0) - { - // generate version info - u8* ver8 = (u8*)&version; - time_t timer; - struct tm *t_st; - - time(&timer); - t_st = localtime(&timer); - - ver8[0] = ConvToBCD8(t_st->tm_min); - ver8[1] = ConvToBCD8(t_st->tm_hour); - ver8[2] = ConvToBCD8(t_st->tm_mday); - ver8[3] = ConvToBCD8(t_st->tm_mon+1); - ver8[4] = ConvToBCD8(t_st->tm_year); - ver8[5] = 0x57; - ver8[6] = 0xff; - ver8[7] = 0xff; - } - - norHeader.d.card_key = version; - - debug_printf2("version = %08llx\n", version); - - return CheckResult(); -} - - -//--------------------------------------------------------------------------- -// Output - 'BOOT_NAND' Command -//--------------------------------------------------------------------------- - -static BOOL BTNAND_Command(char * line, int num) -{ - char* dbg_str = "FALSE"; - - norHeader.l.boot_nandfirm = FALSE; - - if (num != 1) - { - error("Wrong format spec file '%s' line:%d", specFileName, LineNum); - return FALSE; - } - - if (!strcmp(line, "TRUE")) - { - norHeader.l.boot_nandfirm = TRUE; - dbg_str = "TRUE"; - } - - debug_printf2("boot nandfirm = %s\n", dbg_str); - - return CheckResult(); -} - - -//--------------------------------------------------------------------------- -// Output - 'Decomp' Command -//--------------------------------------------------------------------------- - -static BOOL Decomp_Command(char * line, int num) -{ - char* dbg_str = "ARM7"; - - if (num != 1) - { - error("Wrong format spec file '%s' line:%d", specFileName, LineNum); - return FALSE; - } - - if (!strcmp(line, "ARM9")) - { - norHeader.l.arm9_decomp = TRUE; - dbg_str = "ARM9"; - } - - debug_printf2("decompress processor = %s\n", dbg_str); - - return CheckResult(); -} - - -//--------------------------------------------------------------------------- -// Output - 'ARM9_X2' Command -//--------------------------------------------------------------------------- - -static BOOL ARM9X2_Command(char * line, int num) -{ - char* dbg_str = "FALSE"; - - if (num != 1) - { - error("Wrong format spec file '%s' line:%d", specFileName, LineNum); - return FALSE; - } - - if (!strcmp(line, "TRUE")) - { - norHeader.l.arm9_x2 = TRUE; - dbg_str = "TRUE"; - } - - debug_printf2("arm9 x2 = %s\n", dbg_str); - - return CheckResult(); -} - - -//--------------------------------------------------------------------------- -// Output - 'BAUDRATE' Command -//--------------------------------------------------------------------------- - -static BOOL BAUDRATE_Command(char * line, int num) -{ - char* dbg_str = "4M"; - - if (num != 1) - { - error("Wrong format spec file '%s' line:%d", specFileName, LineNum); - return FALSE; - } - - if (!strcmp(line, "8M")) - { - norHeader.l.baudrate = TRUE; - dbg_str = "8M"; - } - - debug_printf2("spi speed = %s\n", dbg_str); - - return CheckResult(); -} - - -//--------------------------------------------------------------------------- -// Output - 'Comp9' Command -//--------------------------------------------------------------------------- - -static BOOL Comp9_Command(char * line, int num) -{ - char* dbg_str = "FALSE"; - - if (num != 1) - { - error("Wrong format spec file '%s' line:%d", specFileName, LineNum); - return FALSE; - } - - compArm9 = FALSE; - - if (!strcmp(line, "TRUE")) - { - norHeader.l.comp_arm9_boot_area = TRUE; - compArm9 = TRUE; - dbg_str = "TRUE"; - } - - debug_printf2("arm9 compress = %s\n", dbg_str); - - return CheckResult(); -} - - -//--------------------------------------------------------------------------- -// Output - 'Comp7' Command -//--------------------------------------------------------------------------- - -static BOOL Comp7_Command(char * line, int num) -{ - char* dbg_str = "FALSE"; - - if (num != 1) - { - error("Wrong format spec file '%s' line:%d", specFileName, LineNum); - return FALSE; - } - - compArm7 = FALSE; - - if (!strcmp(line, "TRUE")) - { - norHeader.l.comp_arm7_boot_area = TRUE; - compArm7 = TRUE; - dbg_str = "TRUE"; - } - - debug_printf2("arm7 compress = %s\n", dbg_str); - - return CheckResult(); -} - - -//--------------------------------------------------------------------------- -// Output - 'Elf9' Command -//--------------------------------------------------------------------------- - -static BOOL Elf9_Command(char * line, int num) -{ - if (num != 1) - { - error("Wrong format spec file '%s' line:%d", specFileName, LineNum); - return FALSE; - } - - debug_printf2("arm9 elf = %s\n", line); - - { - s32 ramAddr = GetRamAddr(line); - norHeader.l.main_ram_address = (void*)ramAddr; - } - - return CheckResult(); -} - - -//--------------------------------------------------------------------------- -// Output - 'Elf7' Command -//--------------------------------------------------------------------------- - -static BOOL Elf7_Command(char * line, int num) -{ - if (num != 1) - { - error("Wrong format spec file '%s' line:%d", specFileName, LineNum); - return FALSE; - } - - debug_printf2("arm7 elf = %s\n", line); - - { - s32 ramAddr = GetRamAddr(line); - norHeader.l.sub_ram_address = (void*)ramAddr; - } - - return CheckResult(); -} - - -static s32 GetRamAddr(const char *fileName) -{ - Elf32_Ehdr *ehdr; - s32 ramAddr; - int file_size; - struct stat st; - - if (FILESTATUS_FILE != GetFileStatus(&st, fileName)) - { - error("'%s' is not regular file.", fileName); - return FALSE; - } - - if ((file_size = ReadFile(fileName, &ehdr, sizeof(Elf32_Ehdr))) < 0) - return FALSE; - - ramAddr = ehdr->e_entry; - - Free(&ehdr); - - debug_printf2("ramaddr = 0x%08x\n", ramAddr); - - return ramAddr; -} - - -//--------------------------------------------------------------------------- -// Output - 'Sbin9' Command -//--------------------------------------------------------------------------- - -static BOOL Sbin9_Command(char * line, int num) -{ - FIRMSignedContext* sc = &signedContext; - - if (num != 1) - { - error("Wrong format spec file '%s' line:%d", specFileName, LineNum); - return FALSE; - } - - debug_printf2("arm9 sbin = %s\n", line); - - // Set ARM9 ROM Offset - if (!Offset) - { - Offset = (sizeof(NORHeader) + FIRM_ALIGN_MASK) & ~FIRM_ALIGN_MASK; - SeekFile(Offset); - } - debug_printf2("romoffset = %#x\n", Offset); - { - norHeader.l.main_rom_offset = Offset; - } - - return ReadSbinFile(line, &norHeader.l.main_rom_offset, &sc->hash[FIRM_SIGNED_HASH_IDX_ARM9], compArm9); -} - -//--------------------------------------------------------------------------- -// Output - 'Sbin7' Command -//--------------------------------------------------------------------------- - -static BOOL Sbin7_Command(char * line, int num) -{ - FIRMSignedContext* sc = &signedContext; - - if (num != 1) - { - error("Wrong format spec file '%s' line:%d", specFileName, LineNum); - return FALSE; - } - - debug_printf2("arm7 sbin = %s\n", line); - - // Set ARM7 ROM Offset - if (!Offset) - { - Offset = (sizeof(NORHeader) + FIRM_ALIGN_MASK) & ~FIRM_ALIGN_MASK; - SeekFile(Offset); - } - debug_printf2("romoffset = %#x\n", Offset); - { - norHeader.l.sub_rom_offset = Offset; - } - - return ReadSbinFile(line, &norHeader.l.sub_rom_offset, &sc->hash[FIRM_SIGNED_HASH_IDX_ARM7], compArm7); -} - - -static BOOL ReadSbinFile(const char *fileName, void* minfo, void* hash, BOOL comp) -{ - const NORHeader_ModuleInfo *m = minfo; - u32 *size = (void*)&m->size; - u32 *orig_size = (void*)&m->decomp_size; - char *buffer; - char *file; - int file_size; - struct stat st; - - if (FILESTATUS_FILE != GetFileStatus(&st, fileName)) - { - error("'%s' is not regular file.", fileName); - return FALSE; - } - - if ((file_size = ReadFile(fileName, &file, READ_ALL)) < 0) - return FALSE; - - *orig_size = file_size; - - // Digest file image - if (hash) - { - ACSign_DigestUnit(hash, file, file_size); - } - - // Compress file image with fitting region - buffer = Alloc(file_size * 2); - if ( comp ) - { - file_size = LZCompWrite(file, file_size, buffer, FIRM_ALIGN); - } - else - { - memcpy(&buffer[0], file, file_size); - { - u32 pad_size = (FIRM_ALIGN - (file_size % FIRM_ALIGN)) % FIRM_ALIGN; - if (pad_size) - memset(&buffer[file_size], 0, pad_size); - file_size += pad_size; - } - } - Free(&file); - file = buffer; - - if (size) - { - *size = file_size; - } - Offset += file_size; - - // Encrypt file image - EncryptBuffer(file, file_size); - - // Output file image with fitting region - PutBuffer(file, file_size); - - Free(&file); - - return CheckResult(); -} - -typedef struct -{ - unsigned long e[4]; -} u128; - -static BOOL EncryptBuffer(char *buffer, int length) -{ - const u128 id = {{ AES_IDS_ID2_A, AES_IDS_ID2_B, AES_IDS_ID2_C, AES_IDS_ID2_D }}; - u128 iv = {{ length, -length, ~length, 0 }}; - FIRMSignedContext* sc = &signedContext; - char *buffer2 = Alloc(length); - AES_KEY key; - if (!buffer2) - return FALSE; - AES_SetKey(&key, sc->aes_key, (unsigned char*)&id); - AES_Ctr(&key, buffer2, buffer, length, (unsigned char*)&iv); - memcpy(buffer, buffer2, length); - memset(buffer2, 0, length); - Free(buffer2); - return TRUE; -} - - -//--------------------------------------------------------------------------- -// Output - 'ENC_KEYINFO' Command -//--------------------------------------------------------------------------- - -static BOOL ENCKEY_Command(char * line, int num) -{ - u32 key; - - if (num != 1) - { - error("Wrong format spec file '%s' line:%d", specFileName, LineNum); - return FALSE; - } - - key = strtoul(line, NULL, 0); - norHeader.d.ds_key = key; - - debug_printf2("keyinfo = %#x\n", key); - - return CheckResult(); -} - - -//--------------------------------------------------------------------------- -// Output - 'NcdOffset' Command -//--------------------------------------------------------------------------- - -static BOOL NcdOffset_Command(char * line, int num) -{ - u32 ofs; - - if (num != 1) - { - error("Wrong format spec file '%s' line:%d", specFileName, LineNum); - return FALSE; - } - - ofs = strtoul(line, NULL, 0); - { - norHeader.d.ncd_romAdr = ConvertHeaderRomOffsetAlign(ofs, 8); - } - - debug_printf2("ncd romoffset = %#x\n", ofs); - - return CheckResult(); -} - - -//--------------------------------------------------------------------------- -// Output - 'ERROR' Command -//--------------------------------------------------------------------------- -static char* error_type[] = -{ - "SIGN", - "HEADER_HASH", - "ARM9_HASH", - "ARM7_HASH", - "HASH_TABLE_HASH", - "FINAL_HASH", - "HEADER_FOOTER", - "WL_CHECK", -}; - -static BOOL ERROR_Command(char * line, int num) -{ - char* dbg_str = "UNKNOWN"; - int i; - - if (num != 1) - { - error("Wrong format spec file '%s' line:%d", specFileName, LineNum); - return FALSE; - } - - for (i=0; ihash[FIRM_SIGNED_HASH_IDX_HEADER][0] ^= 1; - } - if ( errFlags.e.arm9_hash ) - { - sc->hash[FIRM_SIGNED_HASH_IDX_ARM9][0] ^= 1; - } - if ( errFlags.e.arm7_hash ) - { - sc->hash[FIRM_SIGNED_HASH_IDX_ARM7][0] ^= 1; - } - if ( errFlags.e.hash_table_hash ) - { - sc->hash[FIRM_SIGNED_HASH_IDX_HASH_TABLE][0] ^= 1; - } -} - -static void SetFinalHashError(FIRMSignedContext* sc) -{ - if ( errFlags.e.final_hash ) - { - sc->hash[FIRM_SIGNED_HASH_IDX_FINAL][0] ^= 1; - } -} - -static void SetSignError(NORHeader* nh) -{ - if ( errFlags.e.sign ) - { - nh->sign.raw[0] ^= 1; - } - -} - -static void SetFooterError(NORHeader* nh) -{ - if ( errFlags.e.header_footer ) - { - nh->h.reserved_footer[sizeof(nh->h.reserved_footer)-1] ^= 1; - } - -} - -static void SetWirelessCheck(NORHeader* nh) -{ - if ( errFlags.e.wl_check ) - { - nh->wl_params[0] ^= 0x80; - nh->wl_params[sizeof(nh->wl_params)-1] ^= 0x80; - } - -} - - -//--------------------------------------------------------------------------- -// Output - Initialize AES Key -//--------------------------------------------------------------------------- -static BOOL InitializeAesKey(void) -{ - FIRMSignedContext* sc = &signedContext; - struct stat specstat; - time_t spectime; - if (stat(specFileName, &specstat) != 0) - return FALSE; - time(&spectime); - memcpy(&sc->aes_key[0], &specstat.st_atime, 4); - memcpy(&sc->aes_key[4], &specstat.st_mtime, 4); - memcpy(&sc->aes_key[8], &specstat.st_ctime, 4); - memcpy(&sc->aes_key[12], &spectime, 4); - ACSign_GetKey(sc->aes_key, sizeof(sc->aes_key), sc->aes_key, sizeof(sc->aes_key)); - return TRUE; -} - - -//--------------------------------------------------------------------------- -// Output - Initialize Norfirm File -//--------------------------------------------------------------------------- - -static BOOL InitializeNorfirmFile(void) -{ - memset(norHeader.wl_params, 0xff, sizeof(norHeader.wl_params)); - memset(&signedContext.hash[FIRM_SIGNED_HASH_IDX_HASH_TABLE], 0x00, sizeof(signedContext.hash[0])); - norHeader.l.boot_nandfirm = TRUE; - InitializeAesKey(); - return TRUE; -} - - -//--------------------------------------------------------------------------- -// Output - Finalize Norfirm File -//--------------------------------------------------------------------------- - -static BOOL FinalizeNorfirmFile(const char *norFile) -{ - NORHeader* nh = &norHeader; - FIRMSignedContext* sc = &signedContext; - u8* key = keyFileBuf; - - ACSign_DigestHeader(&sc->hash[FIRM_SIGNED_HASH_IDX_HEADER], nh); - - SetUnitHashErrors(sc); - - ACSign_DigestUnit(&sc->hash[FIRM_SIGNED_HASH_IDX_FINAL], sc, FIRM_HEADER_2ND_HASH_AREA_LEN); - - SetFinalHashError(sc); - - if (key) - { - ACSign_Final(nh, sc, key); - } - - SetFooterError(nh); - - SetSignError(nh); - - SetWirelessCheck(nh); - - // Output file image - SeekFile(0L); - PutBuffer(&norHeader, sizeof(norHeader)); - - // Output public key (modulus) - if (PubkeyFileName) - { - WriteFile(PubkeyFileName, &keyFileBuf[ACS_RSA_PRVMOD_OFFSET], ACS_RSA_PRVMOD_LEN); - } - - return TRUE; -} diff --git a/build/tools/makenorfirm/path.c b/build/tools/makenorfirm/path.c deleted file mode 100644 index eeeb9895..00000000 --- a/build/tools/makenorfirm/path.c +++ /dev/null @@ -1,931 +0,0 @@ -/*---------------------------------------------------------------------------* - Project: NitroSDK - tools - makebanner - File: path.c - - Copyright 2003-2006 Nintendo. All rights reserved. - - These coded instructions, statements, and computer programs contain - proprietary information of Nintendo of America Inc. and/or Nintendo - Company Ltd., and are protected by Federal copyright law. They may - not be disclosed to third parties or copied or duplicated in any form, - in whole or in part, without the prior written consent of Nintendo. - - $Log: path.c,v $ - Revision 1.3 2006/01/18 02:11:20 kitase_hirotake - do-indent - - Revision 1.2 2005/02/28 05:26:13 yosizaki - do-indent. - - Revision 1.1 2004/08/30 08:41:14 yasu - makebanner moves into CVS tree - - $NoKeywords: $ - *---------------------------------------------------------------------------*/ -#include -#include // free() -#include // strcasecmp() -#include // stat() -#include // opendir()/readdir()/closedir() -#include // getcwd() -#ifdef __CYGWIN__ -#include // cygwin_conv_to_win32_path() -#endif -#include "path.h" - -//--------------------------------------------------------------------------- -// Get File Statue -//--------------------------------------------------------------------------- - -tFileStatus GetFileStatus(struct stat *s, const char *filename) -{ - // Get file status - if (stat(filename, s)) - { - error("Can't get status %s", filename); - return FILESTATUS_ERROR; - } - - if (S_ISREG(s->st_mode)) - { - return FILESTATUS_FILE; - } - else if (S_ISDIR(s->st_mode)) - { - return FILESTATUS_DIR; - } - - error("Unknown file type %s", filename); - return FILESTATUS_ERROR; -} - - -//--------------------------------------------------------------------------- -// File Globbing & Dir Listing -//--------------------------------------------------------------------------- - -typedef struct -{ - tCallBack callBack; - void *param; - tWildCard *accept; - tWildCard *reject; - -} -tForeachEntryParam; - - -static BOOL isAcceptEntryName(char *pathName, tWildCard * accept, tWildCard * reject) -{ - char *p = pathName; - - while (*p) - { - if (*p == '/') - pathName = p + 1; - p++; - } - - if (accept) - { - while (accept) - { - if (WildCardCmp(accept->name, pathName)) - { - goto accepted; - } - accept = accept->next; - } - return FALSE; - } - accepted: - - while (reject) - { - if (WildCardCmp(reject->name, pathName)) - { - return FALSE; - } - reject = reject->next; - } - return TRUE; -} - - -static BOOL ForeachEntry_CallBack(char *pathName, void *param) -{ - tForeachEntryParam *t = (tForeachEntryParam *) param; - struct stat fstat; - - if (!isAcceptEntryName(pathName, t->accept, t->reject)) - { - // Reject!!! ignored - return TRUE; - } - - switch (GetFileStatus(&fstat, pathName)) - { - case FILESTATUS_FILE: - return t->callBack(pathName, t->param); - - case FILESTATUS_DIR: - return ForeachDirList(pathName, ForeachEntry_CallBack, param); - - default: - break; - } - return FALSE; -} - - -BOOL ForeachEntry(const char *pathName, tWildCard * reject, tCallBack callBack, void *param) -{ - tForeachEntryParam t; - - t.callBack = callBack; - t.param = param; - t.accept = NULL; - t.reject = reject; - - return ForeachPathGlobbing(pathName, ForeachEntry_CallBack, &t); -} - - -typedef struct -{ - tCallBack callBack; - void *param; - char *baseName; - -} -tForeachFileParam; - - -static BOOL ForeachFile_CallBack(char *pathName, void *param) -{ - tForeachFileParam *t = (tForeachFileParam *) param; - - int len = strlen(t->baseName); - - debug_printf(" ForeachFile_CallBack path[%s] base[%s]\n", pathName, t->baseName); - - if (strncmp(pathName, t->baseName, len)) - { - error("Wildcard in Root is not supported"); - return FALSE; - } - - return t->callBack(pathName + len, t->param); -} - - -BOOL ForeachFile(const char *baseName, const char *fileName, tWildCard * reject, tCallBack callBack, - void *param) -{ - char *cBaseName; - char *cPathName; - BOOL state; - tForeachFileParam t; - - debug_printf("ForeachFile : baseName[%s] fileName[%s]\n", baseName, fileName); - - cBaseName = GetSrcPath(baseName, ""); - cPathName = GetSrcPath(baseName, fileName); - - debug_printf("ForeachFile : cBaseName[%s] cPathName[%s]\n", cBaseName, cPathName); - - t.callBack = callBack; - t.param = param; - t.baseName = cBaseName; - - state = ForeachEntry(cPathName, reject, ForeachFile_CallBack, &t); - - free(cBaseName); - free(cPathName); - - return state; -} - - -//--------------------------------------------------------------------------- -// FilePath Globbing -//--------------------------------------------------------------------------- - -typedef struct -{ - char *baseName; - char *pathName; - tCallBack callBack; - void *param; - -} -tGlobParam; - - -static int CountFile; -static BOOL ForeachPathGlobbing_Entry(tGlobParam * pg); -static BOOL ForeachPathGlobbing_WildCard(char *pathName, void *param); - -BOOL ForeachPathGlobbing(const char *pathName, tCallBack callBack, void *param) -{ - tGlobParam g; - BOOL ret; - - g.baseName = NULL; - g.pathName = PathNormalize(pathName, TRUE); - g.callBack = callBack; - g.param = param; - CountFile = 0; - - debug_printf("PathGlobbing : Name [%s]->[%s]\n", pathName, g.pathName); - - ret = ForeachPathGlobbing_Entry(&g); - - free(g.pathName); - - if (ret && CountFile == 0) - { - error("No file or directory matched %s", pathName); - return FALSE; - } - return ret; -} - - -static BOOL ForeachPathGlobbing_Entry(tGlobParam * pg) -{ - tGlobParam g; - char *entryName; - struct stat s; - BOOL state; - - if (pg->pathName) - { - entryName = PathDup(pg->pathName); - - g = *pg; - g.pathName = PathGetDirLevelDown(pg->pathName); - - if (pg->baseName) - { - g.baseName = Alloc(strlen(pg->baseName) + strlen(entryName) + 2); - sprintf(g.baseName, "%s/%s", pg->baseName, entryName); - } - else - { - g.baseName = strdup(entryName); - } - - // Check if wildcard ? - if (isPathWildCard(entryName)) - { - state = ForeachDirList(pg->baseName, ForeachPathGlobbing_WildCard, &g); - } - else - { - state = ForeachPathGlobbing_Entry(&g); - } - - Free(&entryName); - Free(&g.baseName); - } - else - { - // Check if file exists - if (!stat(pg->baseName, &s)) - { - debug_printf(" File Found [%s]\n", pg->baseName); - - // Globbing done, exec callback - - state = pg->callBack(pg->baseName, pg->param); - CountFile++; - } - else - { - debug_printf(" File Not Found [%s]\n", pg->baseName); - state = TRUE; // Ignored - } - } - return state; -} - - -static BOOL ForeachPathGlobbing_WildCard(char *pathName, void *param) -{ - tGlobParam g; - tGlobParam *pg = (tGlobParam *) param; - - debug_printf(" WildCardCmp: [%s] [%s]\n", pg->baseName, pathName); - - if (WildCardCmp(pg->baseName, pathName)) - { - g = *pg; - g.baseName = pathName; - return ForeachPathGlobbing_Entry(&g); - } - - return TRUE; // Ignored -} - - -//--------------------------------------------------------------------------- -// Directory Listing -// Listing directory & Exec CallBack -//--------------------------------------------------------------------------- - -BOOL ForeachDirList(const char *dirName, tCallBack callBack, void *param) -{ - DIR *dir; - struct dirent *entry; - char *pathName; - BOOL state = TRUE; - - if (!dirName) - { - dirName = "."; - } - - debug_printf("DirectoryList: Name [%s]\n", dirName); - - // Open directory - if (NULL == (dir = opendir(dirName))) - { - error("Can't read directory %s", dirName); - return FALSE; - } - - // Store new files - while (NULL != (entry = readdir(dir))) - { - pathName = entry->d_name; - - if (!strcmp(pathName, ".") || !strcmp(pathName, "..")) - { - continue; - } - - debug_printf(" :%s\n", pathName); - pathName = GetSrcPath(dirName, pathName); - state = callBack(pathName, param); - free(pathName); - - if (!state) - break; - } - - closedir(dir); - return state; -} - - -//--------------------------------------------------------------------------- -// -// PathName Utilities -// -//--------------------------------------------------------------------------- - -//--------------------------------------------------------------------------- -// StrCmp/StrCpy entry name terminated / or \0 -//--------------------------------------------------------------------------- - -int PathCmp(const char *path, const char *cmp) -{ - char c; - - do - { - c = *path; - if (c == '/') - c = '\0'; // end of string if '/' - if (c != *cmp) - return 1; - path++; - cmp++; - } - while (c); - - return 0; -} - - -char *PathCpy(char *dest, const char *src) -{ - while (*src != '\0' && *src != '/') - { - *dest++ = *src++; - } - return dest; // Don't set '\0' -} - - -int PathLen(const char *path) -{ - int n = 0; - - while (*path != '\0' && *path != '/') - { - n++; - path++; - } - return n; -} - - -char *PathDup(const char *src) -{ - int n = PathLen(src); - char *dest = Alloc(n + 2); - - PathCpy(dest, src); - dest[n] = '\0'; - - return dest; -} - - -BOOL WildCardCmp(const char *wildcard, const char *path) -{ - if (*wildcard == '*') - { - if (*path != '\0' && WildCardCmp(wildcard, path + 1)) - return TRUE; - if (WildCardCmp(wildcard + 1, path)) - return TRUE; - } - - else if (*wildcard == '?') - { - return *path != '\0' && WildCardCmp(wildcard + 1, path + 1); - } - - else if (*wildcard == *path) - { - return *path == '\0' || WildCardCmp(wildcard + 1, path + 1); - } - - return FALSE; -} - - -BOOL isPathWildCard(const char *path) -{ - while (*path != '\0' && *path != '/') - { - if (*path == '*' || *path == '?') - { - return TRUE; - } - path++; - } - return FALSE; -} - - -//--------------------------------------------------------------------------- -// Go up/down directory level -//--------------------------------------------------------------------------- - -char *PathGetDirLevelDown(const char *path) -{ - while (*path) - { - if (*path == '/') - return (char *)path + 1; - path++; - } - return NULL; -} - - -//--------------------------------------------------------------------------- -// Get Basename -//--------------------------------------------------------------------------- - -char *GetBaseName(const char *path) -{ - int i; - char *new_path; - - for (i = strlen(path) - 1; i >= 0; i--) - { - if (path[i] == '/') - { - new_path = strdup(path); - new_path[i] = '\0'; - return new_path; - } - if (path[i] == ':') - { - new_path = Alloc(i + 3); - strncpy(new_path, path, i); - strcpy(new_path + i, ":."); - return new_path; - } - } - - new_path = strdup("."); - return new_path; -} - - -//--------------------------------------------------------------------------- -// Get Filename -//--------------------------------------------------------------------------- - -char *GetFileName(const char *path) -{ - int i; - char *new_file; - - for (i = strlen(path) - 1; i >= 0; i--) - { - if (path[i] == '/' || path[i] == ':') - { - new_file = strdup(path + i + 1); - return new_file; - } - } - new_file = strdup(path); - return new_file; -} - - -//--------------------------------------------------------------------------- -// Reconstruct path name -// -// - Resolve '.' or '..' in path name -// - Work around . and / to translate regular form -// -// Regular form of path: -// Absolute Path [Drive:]/.[/Entry...] -// Relative Path [Drive:].[/Entry]... -// -// ex) -// abc/def -> ./abc/def -// /aaa -> /./aaa -// D:/aaa -> D:/./aaa -// / -> /. -// . -> . -// ../aa -> ./../aa -//--------------------------------------------------------------------------- - -char *PathNormalize(const char *pathName, BOOL isTreatDotDot) -{ - int i, level, level_root, n; - BOOL isAbsolute; - const char *entry[DIRLEVEL_MAX]; - - char *pathNormal = Alloc(strlen(pathName) + 4); - const char *p_org; - char *p_new; - - // - // Check if drive letter C: D: E: - // Check if absolute path - // - p_new = pathNormal; - p_org = SkipDriveName(pathName); - n = (int)p_org - (int)pathName; - - if (n > 0) - { - strncpy(p_new, pathName, n); - p_new += n; - } - isAbsolute = isAbsolutePath(p_org); - - // - // Resolve '.' and '..' - // - // Slice the path at point of / , put them into entry[] - // - - level = level_root = 0; - - for (; p_org; p_org = PathGetDirLevelDown(p_org)) - { - if (!PathCmp(p_org, "") || !PathCmp(p_org, ".")) - { - // skip it - continue; - } - else if (!PathCmp(p_org, "..") && isTreatDotDot) - { - if (level > level_root) - { - // Back to parent dir - level--; - continue; - } - - // if pathname starts with '/', no directory to go up - if (isAbsolute) - { - error("Can't go up directory, '..' Ignored. %s", pathName); - continue; - } - - // keep '..' - level_root = level + 1; - } - - // name entry - entry[level] = p_org; - level++; - } - - // Reconstruct pathname - if (isAbsolute) - { - *p_new++ = '/'; - } - *p_new++ = '.'; - - for (i = 0; i < level; i++) - { - *p_new++ = '/'; - p_new = PathCpy(p_new, entry[i]); - } - *p_new = '\0'; - -#if 0 - if (strcmp(pathNormal, pathName)) - { - debug_printf(" PathNormal: [%s] -> [%s]\n", pathName, pathNormal); - } -#endif - return pathNormal; -} - - -//--------------------------------------------------------------------------- -// Get Src Path -// Normalize BASENAME -// Normalize FILENAME -// Concat both -//--------------------------------------------------------------------------- - -char *GetSrcPath(const char *baseName, const char *fileName) -{ - char *base; - char *file; - char *t; - char *path; - - base = PathNormalize(baseName, TRUE); - file = PathNormalize(fileName, TRUE); - t = Alloc(strlen(base) + strlen(file) + 2); - - // Concat base + '/' + file - sprintf(t, "%s/%s", base, file); - path = PathNormalize(t, FALSE); - - free(base); - free(file); - free(t); - - debug_printf(" GetSrcPath: [%s]\n", path); - return path; -} - - -//--------------------------------------------------------------------------- -// Get Dest Path -// Concat BASENAME + FILENAME -// Normalize it -//--------------------------------------------------------------------------- - -char *GetDestPath(const char *baseName, const char *fileName) -{ - char *t; - char *path; - - t = Alloc(strlen(baseName) + strlen(fileName) + 2); - - // Concat base + '/' + file - sprintf(t, "%s/%s", baseName, fileName); - path = PathNormalize(t, TRUE); - - free(t); - - debug_printf(" GetDestPath: [%s]\n", path); - return path; -} - - -//--------------------------------------------------------------------------- -// Remake the path into familier shape -// Delete ./ -//--------------------------------------------------------------------------- - -char *PathDenormalize(char *path) -{ - char *p; - - p = (char *)SkipDriveName(path); - if (*p == '/') - { - p++; - } - - // Cut './' - if (*p == '.' && *(p + 1) == '/') - { - while ('\0' != (*p = *(p + 2))) - { - p++; - } - - if (p == path) - { - - } - } - - - - return path; -} - - -//--------------------------------------------------------------------------- -// Get PC Path -//--------------------------------------------------------------------------- - -char *GetWin32Path(char *cygpath) -{ - static char buffer[FILENAME_MAX]; - -#ifdef __CYGWIN__ - if (*cygpath == '/') - { - cygwin_conv_to_win32_path(cygpath, buffer); - } - else -#endif - { - strcpy(buffer, cygpath); - } - - return ChangeBackSlash(buffer); -} - -char *ChangeWin32Path(char *cygpath) -{ - char *win32path = strdup(GetWin32Path(cygpath)); - - free(cygpath); - return win32path; -} - -//--------------------------------------------------------------------------- -// Change suffix -//--------------------------------------------------------------------------- -char *ChangeSuffix(const char *file, const char *suffix) -{ - int i, n; - char *path; - - n = strlen(file); - - for (i = n; file[i] != '.'; i--) - { - if (file[i] == '/' || i == 0) - { - i = n; - break; - } - } - - path = Alloc(i + strlen(suffix) + 1); - strncpy(path, file, i); - strcpy(path + i, suffix); - - return path; -} - - -//--------------------------------------------------------------------------- -// Get Current Dir -//--------------------------------------------------------------------------- - -char *GetCurrentDirectory(void) -{ - static char buffer[FILENAME_MAX]; - char *cwd; - - cwd = getcwd(buffer, FILENAME_MAX); - if (!cwd) - { - error("Can't access current directory"); - exit(10); - } - return cwd; -} - - -//--------------------------------------------------------------------------- -// Check if absolute path -// -// Return True in case of ... -// -// /dirA/dirB/fileC -// D:/dirA/dirB/fileC -// -// Return False in case of ... -// -// dirX/dirY/fileZ -// D:dirX/dirY/fileZ -//--------------------------------------------------------------------------- - -BOOL isAbsolutePath(const char *path) -{ - const char *p = path; - - while (*p != '\0') - { - if (*p == '/' || *p == '\\') - { - if (p == path || p[-1] == ':') - { - return TRUE; - } - } - p++; - } - return FALSE; -} - -//--------------------------------------------------------------------------- -// Check if drive name -// -// Return next character of ':' if drive name -// Return head of path if no drive name -//--------------------------------------------------------------------------- - -const char *SkipDriveName(const char *path) -{ - const char *p = path; - - while (*p != '\0' && *p != '/' && *p != '\\') - { - if (*p == ':') - { - return p + 1; - } - p++; - } - return path; -} - - -//--------------------------------------------------------------------------- -// App Name Utilities -//--------------------------------------------------------------------------- -static char *appName; -static char *appBaseName; -static char *appFileName; - -void InitAppName(const char *path) -{ - char *slash_path = ChangeBackSlash(strdup(path)); - - appBaseName = GetBaseName(slash_path); - appFileName = GetFileName(slash_path); - appName = ChangeSuffix(appFileName, ""); - - free(slash_path); -} - -char *GetAppName(void) -{ - return appName; -} - -char *GetAppBaseName(void) -{ - return appBaseName; -} - -char *GetAppFileName(void) -{ - return appFileName; -} - - -#ifdef TEST -int main(int argc, char *argv[]) -{ - int i; - char *s; - - for (i = 1; i < argc; i++) - { - s = PathNormalize(argv[i], TRUE); - printf("[%s] -> [%s]\n", argv[i], s); - free(s); - } - return 0; -} -#endif diff --git a/build/tools/makenorfirm/path.h b/build/tools/makenorfirm/path.h deleted file mode 100644 index e9956dc6..00000000 --- a/build/tools/makenorfirm/path.h +++ /dev/null @@ -1,93 +0,0 @@ -/*---------------------------------------------------------------------------* - Project: NitroSDK - tools - makebanner - File: path.h - - Copyright 2003-2006 Nintendo. All rights reserved. - - These coded instructions, statements, and computer programs contain - proprietary information of Nintendo of America Inc. and/or Nintendo - Company Ltd., and are protected by Federal copyright law. They may - not be disclosed to third parties or copied or duplicated in any form, - in whole or in part, without the prior written consent of Nintendo. - - $Log: path.h,v $ - Revision 1.3 2006/01/18 02:11:20 kitase_hirotake - do-indent - - Revision 1.2 2005/02/28 05:26:13 yosizaki - do-indent. - - Revision 1.1 2004/08/30 08:41:14 yasu - makebanner moves into CVS tree - - $NoKeywords: $ - *---------------------------------------------------------------------------*/ -#ifndef PATH_H_ -#define PATH_H_ - -#include // struct tat -#include "misc.h" - -#define DIRLEVEL_MAX 256 -#ifndef FILENAME_MAX -#define FILENAME_MAX 1024 -#endif - -typedef enum -{ - FILESTATUS_ERROR = -1, - FILESTATUS_FILE = 0, - FILESTATUS_DIR = 1 -} -tFileStatus; - - -// Item Reject Control - -typedef struct tWildCard -{ - struct tWildCard *next; - char *name; - -} -tWildCard; - - -// CallBacks - -typedef BOOL (*tCallBack) (char *, void *); - - -// Prototypes - -tFileStatus GetFileStatus(struct stat *s, const char *filename); -BOOL ForeachEntry(const char *pathName, tWildCard * reject, tCallBack callBack, void *param); -BOOL ForeachFile(const char *baseName, const char *fileName, tWildCard * reject, - tCallBack callBack, void *param); -BOOL ForeachPathGlobbing(const char *pathName, tCallBack callBack, void *param); -BOOL ForeachDirList(const char *dirName, tCallBack callBack, void *param); -int PathCmp(const char *path, const char *cmp); -char *PathCpy(char *dest, const char *src); -int PathLen(const char *path); -char *PathDup(const char *src); -char *PathGetDirLevelDown(const char *path); -char *GetBaseName(const char *path); -char *GetFileName(const char *path); -BOOL WildCardCmp(const char *wildcard, const char *path); -BOOL isPathWildCard(const char *path); -char *PathNormalize(const char *pathName, BOOL isTreatDotDot); -char *PathDenormalize(char *path); -char *GetSrcPath(const char *base, const char *file); -char *GetDestPath(const char *base, const char *file); -char *GetWin32Path(char *cygpath); -char *ChangeWin32Path(char *cygpath); -char *ChangeSuffix(const char *file, const char *suffix); -char *GetCurrentDirectory(void); -BOOL isAbsolutePath(const char *path); -const char *SkipDriveName(const char *path); -void InitAppName(const char *path); -char *GetAppName(void); -char *GetAppBaseName(void); -char *GetAppFileName(void); - -#endif //PATH_H_ diff --git a/build/tools/makenorfirm/test/Makefile b/build/tools/makenorfirm/test/Makefile deleted file mode 100644 index 992184a0..00000000 --- a/build/tools/makenorfirm/test/Makefile +++ /dev/null @@ -1,58 +0,0 @@ -#! make -f -#--------------------------------------------------------------------------- -# Project: TwlFirm - tools - makenorfirm -# File: Makefile -# -# Copyright 2007 Nintendo. All rights reserved. -# -# These coded instructions, statements, and computer programs contain -# proprietary information of Nintendo of America Inc. and/or Nintendo -# Company Ltd., and are protected by Federal copyright law. They may -# not be disclosed to third parties or copied or duplicated in any form, -# in whole or in part, without the prior written consent of Nintendo. -# -# $Date:: $ -# $Rev:$ -# $Author:$ -#--------------------------------------------------------------------------- - -SUBDIRS = wram_rbin \ - -include $(TWLSDK_ROOT)/build/buildtools/commondefs - -MAKENORFIRM = ../makenorfirm.exe - -MAKEFIRM_RSA_PRVKEY = ./rsa_private.der - -MAKEFIRM_ARM9 = ./twl_norfirm9_print.axf -MAKEFIRM_ARM7 = ./twl_norfirm7_print.axf -SDEPENDS_BIN += $(MAKEFIRM_ARM9) $(MAKEFIRM_ARM7) -MAKEFIRM_FLAGS += -d -MAKEFIRM_DEFS += -DFIRM_ROOT='$(FIRM_ROOT)' \ - -DMAKEFIRM_ARM9='$(basename $(MAKEFIRM_ARM9))' \ - -DMAKEFIRM_ARM7='$(basename $(MAKEFIRM_ARM7))' \ - -DMAKEFIRM_RSA_PRVKEY='$(MAKEFIRM_RSA_PRVKEY)' \ - -TARGET = test.srl - -%.srl: %.norsf $(MAKENORFIRM) $(MAKEFIRM_RSA_PRVKEY) - $(MAKENORFIRM) $(MAKEFIRM_FLAGS) $(MAKEFIRM_DEFS) $< $@ - -.PHONY: build install do-autotest clean clobber - -define ECHO_CURDIR - echo "==== $(CURDIR)"; -endef - -build: - @$(ECHO_CURDIR) - @$(MAKE) $(TARGET) - -install do-autotest: - @$(ECHO_CURDIR) - -clean clobber super-clobber: - @$(ECHO_CURDIR) - -rm -f $(TARGET) *~ - -test-utf16.bsf: icon.nbfc icon.nbfp diff --git a/build/tools/makenorfirm/test/rsa_private.der b/build/tools/makenorfirm/test/rsa_private.der deleted file mode 100644 index ccf67c186ba0783774a391fa190a1169155f281d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 608 zcmV-m0-yabf&yFu0RRGlfdI^ydqI7je1HOl+Yp(I)Tf4e@7hDDZ3|Vf5OZgl!rAb0 z*83f%7n*m8hv(?Xz=k%zT`bpHAL`&wX2*l5GxU>lo;sIsQeHis4((7+)?dUnagoFp zfy&R4POTg=aNJnsiHW0X2}6+c@s2=GxAACyF!yZ$ik#GkB}$mdW-kH*0RRC4fq+hQ zZdX^o3titC%RXCESiFGZC6%%IhdCg7s$)i{{KG5cEwT^QfEk#ZA%%I1dEh;uHZPjV z5t1~&-R{NuyD0C>s3WN#p=?Z z*(>6%jD;YYND`!^I52ZSVS9((vB6RD<0CRlzixl)1+a8Tu<UUPp7kh#$!@g$VcL08j(Mm6qlecx;X z-nFqs_-g#V-(^EJniWC02~+xnu{a#-yR)Yugs_$y8t~d@XK(+_sv%N?oT9CknwCzKqm_T diff --git a/build/tools/makenorfirm/test/test.norsf b/build/tools/makenorfirm/test/test.norsf deleted file mode 100644 index 7c3093af..00000000 --- a/build/tools/makenorfirm/test/test.norsf +++ /dev/null @@ -1,30 +0,0 @@ -#NORSF --- Norfirm Spec File - -VERSION : 0x0 # GENERATE - -BOOT_NAND : TRUE # TRUE or FALSE - -RSA_KEY : rsa_private.der -OUT_KEY : rsa_public.sbin - -WRAM_RBIN: ./wram_rbin/wram_regs.rbin - -DECOMP_PROC : ARM9 # ARM9 or ARM7 - -ARM9_COMP : TRUE # TRUE or FALSE, should be before ARM9_SBIN -ARM9_SBIN : $(MAKEFIRM_ARM9).sbin -ARM9_ELF : $(MAKEFIRM_ARM9).axf - -ARM7_COMP : FALSE # TRUE or FALSE, should be before ARM7_SBIN -ARM7_SBIN : $(MAKEFIRM_ARM7).sbin -ARM7_ELF : $(MAKEFIRM_ARM7).axf - -BAUDRATE : 8M # 4M or 8M -ARM9_X2 : TRUE # TRUE or FALSE - -ENC_KEYINFO : 0x5043414d # 'MACP' -NCD_ROMOFS : 0x07fe00 - -ERROR : ARM7_HASH # SIGN, HEADER_HASH, ARM9_HASH, ARM7_HASH, HASH_TABLE_HASH or FINAL_HASH -ERROR : HEADER_FOOTER # for debug -ERROR : WL_CHECK # for debug diff --git a/build/tools/makenorfirm/test/twl_norfirm7_print.axf b/build/tools/makenorfirm/test/twl_norfirm7_print.axf deleted file mode 100644 index b255bd21a2a20901a9313cd8ff4c795d71cefd3b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 175676 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
U4<#z|> zvnw~zljzpn6xF(4+lc|UyhR_t1C%r}%$?mkOQJ)}(yVtEx{cw5)aO79?b_+u5PLJE zegm9g*IF!+pI@x$wb%2By)x;C-d?#_i>Z$P6|8sH4qn`G!J4VMYu>#cVqUD}esRY? z>jzxBR(dgqXZ5n|B076f57F+#NVb^FjlOrW(-*%*R6e}wO9_i|#p%69hwORdo*z_( z*X(VD%kEdb>cNV=#T8-6TEX>u!(>&sl%f zhQTJ#IqP@ufAg}dwyhs*4qm(Us%_hwLsxIr-*Yx?-16$?#-R=8Y#ZD(xNd0hob5yB ztS7rd*Cb)GMN{pl%O|FH4Nr(K6-#gTbz|ThX-=D9w0OO1Zt81;UpyhN8tgmCRY&7LPt)ct}~uHoF$R& zOpcDhRS;pS#gWk67wayGb$7)UxvRy~F-mZ4@}8f%!PmExqtMdj`)@QZcwk~|zvL!j z;*B|gHIb8W5=Vgx{Q;pYwJLyXf;@~xwSQ!6CLAFo7zAJ-E=!u$)pCGAR5qj^ZURhV zHE>c+07uCiu$0L~H4~3gwafKLL4_IsdERsdNS9fGkje=<2g25wb6g-hCNnR6n3NY* z-1yX{X|9K}Hbi{~5v3-CV2i2*Om+$<5PX9XW|RB11lxVXGh_@@6YL1ryo?D4|6`!! zfsP;?9n%H6J1S7}VFz}{b^v#ESMvRv%~{2Z^)(w9lI%QBAPJTv@wzoj6zSq)mk@-{ zt=y+Z$A{&Z0bKX)4>WM?N*ldr3FcD+1kxGEd@NE`#FdsjS>*B|N}ox|oj0mvpsAh5 z%*QnI(am(4GoSBlIrv#S720xQbYVUoB~7PG9YC@!j-eu4!{AVBpLc#_RT8@)<5@M2 z4{eDK&~_LWiqZvxlunhjHd^mVPDD6RLHFeYxD(-#nS4H%qlx*z!Zhmw2VF^DJ}?t9 z;_P1S3~>FSn(Q=EJ5ZbzHg@2^8y3$aGZU@$U|AF633mI7Z%I7U%z5G3ac9m=?wIhC z&>RikF@XyY85kJPOucem`Qc5jDYD?!;IvJEJv5)?=2)@9bDE5} zdHDXB<^~6e9g}7j4iAor6EGp>d>W>3cqb`^tq2`y4MQUyOo270Y{p7B9}g7XXu^{q zKHLNtqJjKGJwVvhbyT!?4T=bVBnrTN#S(BbQ6?i&B5>hg##ZRHV6OXn)u*Vc@y)9I zq&4W|%$8l;PKCJc2^S`B%NfF#rb-_IPGoY#c##8^)v{0NwBmkg6uyKG zL|0UubRvo&?vm0Q6epR&Bj3WM3%*Q=gL((kHCm`s29~c_waRrZW@cW=rB$Y%I+JYr z8z-N>a-jbxC9;!`QaPP?{&A*yI`Mo6v8IPik3=0}hVvIOb^EHnVcA`rMq^3CFgoV; zBlIcXf*OVce7~q0vWdNONe$6m8&~hKCAGz?lYY_1(30As(;*Mr85X4$@f1jX|B7l0 z|Dw+ay@XUA&PeQZy@XZG8HfNLg8kiZVv$n~Iit>K)igLNYZ?f*YZ_2iWbYa%f~Fy4 zmoyC_oHY#~N=<`;QPTh%Gz~zmX#mKY1_Cur1L34;0FIglz?!CkaMm>BG_Gl&89~#4 z4#LFNASXo=a1b*Iy0l=Lh7>YQLkhX3Aq8F2kbb^ z04y~PqH;|G&1u&(Akr6_1_@!(gdpc+O+zXtXc`FDH4XBF*o*yEJhv5>G!2BJrU9_j zG!SgjG=RyP1_EISp!7(Z2H>D+0IF#k2-h?XgoBU>lr#+p^HIq~I`> z0_0%^!GZ@7g0Dd!saAo5)&VF;>UO6Sb0KOSlz4b%eqmNpH-Vsa018?MAlEtoxYj|K zQtLoCYaIxbS_gtb>j31+1}c6~tpoANuZ6MNrgcz1*?|vt5uq)ev<{?nD%Uzd6|@dS z1Z4qTX<7#|)N)7r(I|A%IzZ4t>tM<3YP)Yx>%e5PE6>O4(MudQ{U zHmXH8^@EeS@S5h%H%${kjZ724U)Mwc1XTl2ubPP7)DO~A#KizOsvjuF)ei;)^#kgO zpnd?G)eoRu{Qx$rA5QV%DRTq(QWHTiOzsv<1R9G&$EipY(RYxNXr7d)Qml+r=s+re zAoGDwpo{oJQ!?Oiah!X}d<^|zU-e>scTfp*av+Q%km4j)cB2W_9YQ^3x}I2?$05%u2L ztA7jgZZX*|&H-bw?j1`PGqhiBu~_}sqV;e4)4`pdmeoV==+yJg2}x~yh<)%7*Yg`i ztj~uy`}M{@)k-+nZq$t*@cqZnWp&D@)!ET{jV7{Sr_%@+tj6|lm>h=rf(I&`QRd+u z=XTqbx~MbiwnPxw(kNwz+rv?F4A0Gt&B{{&I7k}8j)}RWD3eM6QG-MftVG}D@Gkiq zP=~s(jRatbARf2qPom>SlKK>1H)UlrnAz@-w4)8LP+Y)h79j~<@xTSbNXUVd2@8es z-Qc1nuq+mI>`B1P=}OOF21Br!D@GDdb~}TEVj*(a5c|SR|42~Zqy9~RR8B z9JLM!ku(kolUjtq+%ln}l$Ol7NTW4b3o(7;bV`UX-rge^b)IJVf@VlaAu}?hkYA~of_|kU!C<&}Ih8MO$2?QL7LRkC zMYoxkC@Y}WAi~j30vOU6x@KA-F56uQxHSeK7-*C>nr#FZC$tIHPiO~3G6@k5#v-6> zLn6>_Wuh&$6WSrK@`N@hE8ZIivjuRrK3X{6d5&OPN?J5k-%Z5q{JCh3&aF@iJt8lb z>P9q2ue1l>BF|3&}`5h}(Wg|na$1xj;+8CcPGv`*<*G0&)& zza_U7N*8|Fxg}~M2148xKR;o=OU%dHFmHj&(@##d01u>}m-5f^`OYJ%>IOnr4UIQ9 z&c0#0*+^cqFt#uzy6OV{IpLWMtB(;1gqjXow=^}Y&l|qEaocOQ5AT}rl)2EqVEpUn z75wwOPKRS!Af&u5W7*n1Haj^!H9S97ebBJYtqb!*ro1Cq*8lBPqK^44SW*3am4BZ3 zcd(iLC?REzOWMeFmrc)Z7-OMc7@41*tsV(c+s5YLyhax$#@0_SOwCuXB_m5>OIU8+ z(7y5ck-gq8)$M_3{le@lYnx-Y&d*k#4iOvY9JdiZZhUxxi7;CAQ!nKlW9YC`18U>w z#F(S4rqz{g`0BcV+B8f@?H!wSavD+g%kMx`$DA2DJ%5J(4Ogxoc#hChcf;82BSht{ z7#p6kPbrF==G3jPtJK3Ub&7r90snA`SUQGa;nSPy5LQ1 zm>1Fo`uRapd#C)9-eUnX-n0|sddaA{dupV*3!Gy{wZ6^HPEA+eNvfHJ`K{ZVw&hnB z65ca5KeT<__Ubh$?$S-Kt|mPON`-Dqp-t6~C%R45FDH2J28#TXL}tPN9fQ@2sH&A) zo$k>3%^Rvq0GrLR`SU`>=jMm!tC1Gu$mHnkXmv|FcHit=b$<(*E9QqsXPbMg-*1VS z+dIB{zBya{pN{y6>Lk8$SryNy+5kFsE47=Qw~kf!=Z|)D80#7HU&FY~m{Y=Vcr_`h z0YCqn!Kk%xZiwm4qAO(?p9-f;Yo83A*RsDj3SIzDb{JR0ZW_n^_a*RM# zUBW-lZXK1-qKx14c$2Kg@s%BV!vc(yuaZh!#&udd_aH*)Cs+H3m$qUqY@-=ND$JQ9IfnGHtZBKIrXCiP|{ z-a5_qw_$#zZE?7%ZG8MoSY$@X%o5DW?Twc~48`0NqA#5opSms-v}L;bjSlDy!}G(S z%Z2^#Xt1`x_1m{?xO}{s%E(LqFR{x02oxi}ku|R$-=!>yj(rR!sE*kdI_)&jUQ?|= zGlcYEn1`FEwVj%nKi87>_n_2I9>-q|!{V2~dTyVi*4jv#uiL(HXnxHr7!>0p;UvVa zh20xRK(0adoNc1!8lRurI5Id`{eDhx9(%mYV^CNB=n+FCsz|_2Gb9 z#Ao@llua=-8a_07Umq?B2`ISB$Jl?6toOApJ^L8szmT&ozTUI{6fgF1vvJFsb2pEn zVca)1d)?fc3(zslO;3#Rk^#)xf!4vnYPe(SH6*|uFgB`$omw$i-PbW;d$FBUKOIst z(|x^W73#cFpXDRBrFj>|=1nimhxT>XW?|)M-N*to|j;uyXjWKFo)7 z{nOMsw{vEDLPEyR`Ll?bh(+T1kwf3(G4&<#Q;uYb?ADuq)rqoWcbp76Ve`4I3RilJ zO3S;|WJ0#q_HNPsCVBR=Wit$$tuo`)?g-LCAB5A+2Xq|q)sMH4 zb81aj`*bFM!pZfax{UB+(ffH%7nB{p$<{#GeO0-TOE_v%I%y`4DFGyC$MS!JoPeHI?#j`G3TJd!S9hYBwp7q^-DC5s#WH+aGH!{`36J z2TeJy`Y}|_tBs-e#%x^wvgX2F!zkmirsxiprp(-f)o-Tq>*MUHn6|9Knse1qAvt{I<9DH{Rc}C7dgDCfUgDS#!36xDVUL| zpHb0#-0AlU{yv8%1Y^%qo-=}9;qbiR5r_8+{%MEbB=|UoZxs9^4&MjdH^ux_S#Jlv z%i+C(FL!t%z&Aqk0pP}ip7x=DzXbfl0p0-oNPw>ZeoFMnhN|bqH)Z&}1-$7Ux!kRS zf5yw5xfwXrZC>z;9l!OHz-KtTserF2;0*}_X78=cl>?AU+MS<1i#hcCk4OD z;im*2>+mtRX8IEZ2l}%F|B%yMD>$Tmz2J~`zhG3^nzOeHUhDJsZs5NE;PrVx_;rqd zNbswi{!!7K?=;&rZa?e&cCFyej($@no-Am-QqVjjnozf+-UYnZ^E^Xv$bUnD9|i6k z^s@E}4&_b=4&}}W-sCi={wMNT@I0S+ANZg2{yFk4@EaX}l;GGuf-iCW_>dj)^c z+jU<-^BLgSu46w09NKjSaLn^s;XmSK-6)uRG`1fR9P03x=-=w)J|ldr^N#|Dbz?Pf z-+ywND})bu?iU=tsbHiA<$uZD8QugO)7~ijhrAB&5FEbsy@ErY4+?&}=ku`O(5^24 z_uc4qcvSG)9DZChA)l`n^lLv1KGbKE;E>O?z_C8B7yhR3-35pC-Xl2F=L>>kyLh)L z)@{4sfZq!o^Snd&hrEq<3;z+X=RJbu3&77~q6z)*L_zbUU zJOdotyOsBy8d%xY=dTwW#@K}5@O@_lk2}qMg0WYN{tJRbpL`j(?|v`q3Bez8_$k2` zdbt&^JjHU)6&%uD3>@hv3Yr@WnmY>k$%5wT0)OO3bDnzzf7HLrn}B2f4{9y_jMwd< z0)DuFA1UC^7w{Jf_|XD>tbo5gR36N3L=FZc7R+b?_Fo+#k23jTA)FZ)=gIYw~6 zpH<*5F7TTQ{I!Dr(({=q@NX*cw+sGnPIF%YKPVUnB>TPv{_z6;bb(*SZS|4<7{MXW z)q?T7P(Eu5{3QkcY2dyGy-)7v8v6)8@e{y*;rJ&72bv>)k~}}{d43Hz(mW&h=bgU# zIIvU={45h3(+d7M#~&s5vkos8{EH4BBUm1V{2VLz&m2BM@c(dlwcxKfe5&9l96m$v zlMbIH_`f@Ru3-5c@v~O&0}fv#_-7s70Nl9G=hUe1q0Wy8AJ(O>3H|}6Ir2W>H#mHj zV03-z=Zge~xp{@)ZI0h6ILx(C!6BdhfL`1b<${hhbv zUcpZ}e4k+UW&PZLBWeHHzui}W`!03-R|UV?;im=5-GrZeehT_gug`}2frlNwSny$u z>P<$~+b`wVUy`0*nafN>DPI5H$-k2BlC@R!D=Q+E(}?cf{OikTb3B{DH%B-*G>AsN zM_PIXBf>40bN4X>o(#M*XyZ8)|A_z#r=NT9V>tm;y6PgnL_g@$s$b(@$gg^m_2g@T z?^V2hM63A6!e7d@p99fpITF3fx#+V8&aVMcFLcNCNcYk}XZ53B4pcvENLDU?>}O^a zepVF;KLYjd72$6{SNDwJ%=ceo$Z15ku7z&(V555Km5T8nLHf5R{BFAO%OMV zIa6iT_Uta)<^tZLkdOr3M$Lue{9{1kS>&t?2p;iBvLKvjV$wZrAM9@GLQ=_PHJZK8 zw`UrMjaHJos=K7DC)n$H-_ew?_=yf z`Y*h^P&Vv=R}H)Hs^I(0`1q1Fj9J$2_UGx(m;<3{4V~*#nKCY1|D_gHi4p5GYe&S4t_m8-da=#{r5ua_3?2%m76tO4?iZn zH0x?KL(PQIRPLEG0<#8s>nQ?ve^QNps$PxWs;SW=bB@zqS*J#4P=AR2cup1^%5nq4 za*%<1JCs5w_+H)9ow(+WaeeIiS;M=EjCt(UfE&0r`&M%ODJ~`N`jc|hU6fAOPdb`c zuU7hoqr5t`QfpEwol>6+GLGvbfc=yCPB|Yxp6clxN-6bng0}S6QEScvQ9m+xS<$}6 z8B9)@_N8|zwK6b_{+850e{;s|Z{7(mSGj&+s^h0j*VnuU%2xpY6ZB>5`id;JBZr^D z|JuFX2@`qb;92Ed-)QVTJ(ur<>MLvPLj!nZKa7iePn*ceLLSm@G&-jZ-SMI^(+SP0 zjAw$+rp%#aEN}u_RL6bUN0C`dSH@iEDdeI-?^omFqjNmq>_@_s_3?7j?1kO~VXE{9 zeZ7HUZek4&ghlf>{hPpb5IMR2+$ueD0zMyn*MKi+dAgi1Z7Rp`ZwF&3r)*f8!juV*+LqG>yqd^c z_IY_&< z?0wNZ>L1~|X#NPej=(tkuo3Mu{l}q^z#pZoO=V?17_Ieb<5&YetZAvar5QVIl{sR^ z4_0BB|Ed9P`u*2fZ^oAI8$|EZ33Jx)RL}LBSWCiu<_!9P{ax>4lVL_ZGn`TGa3=rE z@EhIUF#0?ELKP?D!wZMDgfTzL+7s$$@9=ZpmTz z4~BE?`DH^n$f*au9|Ep`F7^b<>J1Gw5GEV9fGf|QcO*n627HMuKZ3r+y4Y8>)wA$9 zhQItJwSoMFr#9%_zoF7bhtF%{FVAaZH|MpXbzVC;p4{AG(lrE@bVp&yGD1 zYN}9<*2&&!>|MNX?Z8E{Fz1)iY1WD?)D}u1jQyHJ?NG zEOZ#zh!1|sJmhP)NNiLi@a<2*H|^U^DRtrJRpLe|LVrOt`X zpd;#EsBb*C{tLk={Yw1}YgrM<{=#$m3)Q)6quLF|s{U+j!K~p#XVF&!z&Wn3!-v4% zUWLC!YIvCh9`WtViCHRFWPQTdP3P#o3%dITjzqkOd<4g;Dvs-^g^#fXl~^GDU--W# zrAD*JEz5pId}2%AMh|1(eg-+6>aWBL3pfin@kPgg5gw35>#g9BxwUgnFh^`l%04v| z)o~1XzwiWY!6i6_SA+N}y3+`};JO5u*cRHqh(AM5VxBidYsw>6l@{3dKp!26=AA+| zF&|UatYOjFl-gWQn57_PJ&aE)l-m_+Xmf+VK!4g~?X(SZOGIC6S@hE!+FTai9rQ(L z|2|xo{gJq0S>RiI9OJ0yep1$8x&9EcZK?7s{IhFG-ITTw^j_CKYV7IQ)L*`5V zxYEj&vdTMEu6zwPM=ZHi^iP>bnzey1mWR|!zSgyA1@-8xp6d%n$HzxB>S5{>^=WF8I;6godBosW(HU8rVfB;^ zw~_P8X5@Qwpxn>wWzLh}9!XnrJ_mpPCGTs?rhB$~ZFwmFk}tHe!TleiCa%6LGQJ%8 z&EP#|z2>W;8(doD=R7*an9ePMDtf;|AjPD;ZcRFp>_xulNzesx} zZ4RdC6MV0$jy*wpi1uC9{PHCF^q>FTz){+AzQKQwe3x>BvWW5=1)Uf#YIjOK9Hvwjp5<(0^1V4k-f2xOK_}5w3tdD< zML$JP-_Ngvd8jlI{@GPy5ZEqIvE`K{k;fvyQHn>z}y z36()tO`+2fn}aK=vP`qy^dBNi)|*C-(_%SV$kB2W z`b^o6n}hk(ldCd}aMti6GOXoA_C|OSeE*Ymh^#-0tQE4>GRQ_P_QYOu$O$>7QzkKl zeM{jd4YMIEsslcDGU6~UwkG4HEAZnrFiBN7BephiuAEbZ-u2LvbJQgE2O3dKkMxwW z*e6~mFu9Mgw&lSB4ZR{x7|5A;QILIC*o5fp3u+5@CHBbf<-UAFv`0E}F_6m#1qb$I zMmm!X%-kWaqWBoomG8&2qWffqb!q8ra3yPz_1CW1$aiqp!2ba+es`iw_T@V`pH#-t zqev$4{8UvQseD5uw_14^^u_ZMxkIcY8(a^46Me+LA`fg*tw=1PZ<^IxHm&c4w#7Y_ zTBpw7lNX45fu9Gwj0ucZ9lM6HiEBAg<@NAIuK#vx`DM-ce`hU%S3zHO>iB~j1AVn7 zbpl&WC-WYDf|B1>*3F$>%;&5s-^8#H$Yz~vjm5MZtH}@W~C_$;7v<(6r8t<&aOEi-8h)KUTM_Bd69>sr*_+D}Be%6V zo~sr80bTPn^IA{Nv^IKQr=C46xc(Dd(`)#;7{26eD04->ujXtg-vd|ncnNC-{PmP0 zzTvT=Bl(2j6kMF~TN`U|O_ep4HkUaU1yih~H+`AwPt$>AJ!!EY)?}-my$RLh)~Tc5 zgC_D}9nm^}4!%s}fAivRUmnt40X{GG0iDfd8=I&zOVPXxF-Lfi*iffF>dC%k@C$X; z64pK6le>kc+&$7Kz6$?asxu3oh96Fu*>XjGH=pyx6Mdi9x$N~j`M-=Mc$Y=kHydh{oZYD6oKGHT zB)+5mj615pJk9yuA}=d)`v7Zug1dmmepuX(+axE49?ooV*jw_cvz^eI=7jCk{nlV8 zxnY~{nZV7Uh>nmOK1pu)F!f1x!S|K#7 zM7VU?mT+-tFkEbN=P31rtLR@z*{2`y=Yr!YYGwD3vw17G>X38UMNug6%6-%hMOR94 z#lL>@!!LgOs#ks^d6~z#cgA<5uOkn+quRMGp`9;;J7~+jFTNiNPT@`DE4eUi3wu5m z$`HBDq`#7X$V;4VjbMnse2>-x4?ClB&V-e7dEhtTFTQhf4jDBXT>pv-3+3_F zLix}I$N(PNC-l4Y$M;X{Jo4G~)mr>9bnwAyL~hwy0=_H8jV<@}IB z|8gaHV{phR9*x$&*Ieo!KyPIqiuO@|`s?G-o(TLpz9qLW-v)Ey9FhTDT~o%wuXZQo z%|i4(#hZn^U1-*W<&@;^&7EbTV^r-Xi5%pu;Q+Xb_CbHIJwM7-8@3Z>;Ys+Fbte67XxFK#LLrHcx_ zo^t#QeoIyJNNlVC^qhkOCQb4bZTan?mD?U-i(Zm_ zHEhl+<^gXy{#LUFh)+Aq+pa8l+stX+*2ZaGqU$T3*7^5drmH{PrO2yy_J`<0VB`lv z9sez7#*DoUUblsb+)bXcpChg>_jL7whripMr9Z3s!>qF*Y{^r@v+&#EIL*v$6}hA5 zzTp(Yhv1p>$w*6n8!#&Za&E06E78LiaHPnarhpTCF%BGFtMtVh5qturp9L!IPz2uSmUtQz|pZLxA=sa{y_Mpw&NQ~JSs;-S;i^NOj z8nkoJQ1&)YvmWOi3!KQ|tMuVN{i~QeR@K8Ua!dD9V*hR%~7q&pYV02s&Are@=o;`^#7FfN&cRkwK*YYtwHOb88>qBzOg)*0e!I} zu_w91XH;H8zL!c&xCmHF)@EX7;5X1^Sw~9sB(to=Qd{9y#yI=sD=>_+C4EWRf7vGk zn5mxYH{+MjgBLi~Ec++4Gz*#L`@*ZBDY-v+Ux@HB{$`CF#2zKjF7gmtl>EHB(Fv@` zR(!u^bC(i%;1h4EiGvn%9)F}VuRFs%#=r*2ugm?6x51=lx{1AJNfVwVmnymBSK#qb zjr|Ia9q7a^N_?gn1E<*ZV{eX+4vD_!T;fS3cFcsQ61Z4j6g$NBHeEujpik^iZ*Wda zUdG}K!`*-X4tp@%0bQ-W!heSS9H_QMUJs6qkII;Q|B&xrKvUMhmOiXf`it4)&-4B4XNFG_sRA^pGTi!F!n-SIdl~8qV4yV(Xq%Va{$$d3V zO@21L@dDnrFDUx|&bOMq75UsCaWh>v%k|&a-aHfym`^Yt)d#8wDya_Nrrd_)SG2FjRfICrxOKki5 zw6zMY^bh#9$VC!{&+#NMhihP-<2&Y8#tzAtrpmQ*V%pCzrt5F5r`L?~(oR{f899miMnADuTbg7YNf_@{vp={(9 z^47aNKrb(qxKIyXd?M$9x87hhb@){aAEM=!m+@7tUDY`BG`>*c^sX9SiM5hLA4#Z~ z$9!a;5szKlA|CgeC-FxoeeFIc;xS>J40Uxf)J*Dj2cJ%zE%@4c$IqHy=FC&E4SCzD z<(YSmh-Z9UT6isiu6)w$a;jP$b368mv^s;JoMB5XW*OcNWN5!w7(6GwrZ>u-AGwmkuiBN z_!S!R9$DXcomcPvttYvSQ}Aq8X~pY|-`pnBmiOBDzc;(^F(S9Uk1QA$-Bp^r;r%YZ zqr~i~DOIjdf{XWHtpPNj#z`?5nv<-z_}?b(Js-R z!g@t6PuI*RCN>Yyx2tBp3%px1e>?5%G6#He*J4h%iaDF;%g`rxH#uj->leNx_Rj^z zs_B0xx#+}|*j7a@?xWp_+rL?n&mq3e$M~NTwN2emeQGEF8KW%byPdL@a)|a)#>XhJ z-x2>IdMhz_MvdOa{z>GoLA&-|EC1tC`J%itVE&b}DE830kZ+AQlZE(&T=g6(KBLml zfAjKguf*tU)HcFYz6qUe{TyfLL-Wu>Y(dU%I&yh8{n$uQ{2cMNV=zp2;s?-ig7S#i z*HxTF9LMB6Me)D36Mj2wktaIcYIOF6lU>dporlqL{_jxkzrpB4#5Oc(4_f>J!&KEjQ(7zKK(;7B- z?d+9X#WfV+s>ojO$-Rg(TByUvL>#x*;K+buRTal~Cg2diEbj<2fR{CY=hvJuz$b67B}LKNG^L(W~p+Ch?_JXP@qj?oU~A0d7Nyw~cs?tQ#D=mFgmQ;FslG7PYOr z%gPSQD!;|QPHYR`u62scZV)|Q0-dsMJ?JIuCq3kLa}s)ji+$P8y*=_LmAvr)IrBXp zZPKZ5(F;1`_F z1s>oU_-_I~0Q?@{zj+=!F?~04Mk?dH({yFa+>f-$rmLY(X{&2Rd3L?K6CK@cb=_9B zlfCf3)|%C9{gG-f9C=g(D|^4o>z<%uERI2`NuDr>mIvA=WS2E=eWn@zH7+$mF_Wc&dki}T2D?K%Ck|Fq}-|MgV%T=rQ0+ge+q zHvxiAdfu{+U1i;~e)Zk!@3~x@VAQ^C-I}PSR7y?4F-}(UIFnR(etwT{Bis zUQg+xY_0aUQ_rC+q%5!Y#qj^vwfZu0;D3lLRZYL=>gj8&{OWag+#ln~wR-L9 zyYIaGR;8j3>(;yOUAxBm^ljGawRhjPdd(NCd+)hz&E-|tyKlSaw)Fyg@4C;fyX&vl V0e$D4tJkd|WOOI~ka7)h{{^{CZ=wJI diff --git a/build/tools/makenorfirm/test/twl_norfirm9_print.axf b/build/tools/makenorfirm/test/twl_norfirm9_print.axf deleted file mode 100644 index 3d064b38a5509e8ea9e4ce4cc5302e3f0684d513..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 288636 zcmeFa3w&M0b?-m>oFiEXVQ=}7xQ-LHu}vH>=J;)>lN>*>i44atY`{g5Eg373C7}nH z)Cotn0Tb**5GSFz@b@7lEv0F%AS9u_;a(YNLS4wU18oR}<~%qTBXd(HO;VDZME~z^ z_TJK#Y!aIG^Z$JA=O5Xl*=rta)~s2xX3d(}Teq#KS?M^A34dZ{hVh|Hd>)C*wW8g8y?y{ok4&)-+}!kE)*_4AM80ZK}?eeNE|1a_ZAb!*TkN2 z50@M_l{?>-yELCTzNCN@79Upn2eQT4;1!$|d~vpT32>|`TRarN9{@hU^LTSl>0+KU zv{U8wlw7Z;L}ruUgsyTHGLcn0}1a)(PnAI4S>TuM90H2mU+Sz|^mIyV!) ze_$Xs@4QUBlV@W9`nq#fwB?uwpMaJl@3ZyN#rGRidD>j^M!9j{h5fuGUAE}dT~iRf88d;tnMsc6C^=?p=^SJFoj#u1I!aZYcjm`@ z{M*G?+noik??7Rc`R?l~AJ5JYRc`{kd>27HJp`}ZG37t(A+9DqKs=UsKk+!?eZ-SY zricP5jtAZaJb}2A_+7+p#P25dz&m@)IX~P0TuIq#p06Y=IVNUfm$(wx9TWdyiZX3u z%6_<*I87`X=UEyvmPXNC)-%S;Wtt;Pu_=rbF{vZuNvu zw3Qjv@yABP`TL*WbKv(J_&o=H&w<}_;P)K({}l&*&~`(?*; z$i-K!zG}mYtCnAV`SKM@H(v2a;(0|%_Mtgdg`M+njyY99{8Po5Cr|e6&cu%sRHjgF zPCZm%PGJC{)V(1<@m$)Lm>bsxY z_JQNj{Bk@@Rqf$(n5bB=+rF zd!IacntnYDEz^=djlJFr`Cj+we1-d2+2ypkx72H1fR1dw*L&L9Z51(-nAS&m=%NljO+GhR-W!3x3j9@XgL^W#CsRINd7v=SJ6xKGy}A3t znbNP%J5X>u^SW<4elqrnYyat2*T4GnKeqb<#zy<5Dc?CzsBkAk``V((JXuk0?mroG zt8;pe&CX)$w&v%$C-T};&2_W+1hk%S+NeW+oO@nRM5io5GD_=GOE*}ApiooJSFMT&g^D=E|euzG)@0y37q^wEpWsJK^m!XgL zrw`*l_y^=H4R1`P^AYq9ef-j|2YwNzOQsrZzj8%mkdH;#yz3%=;F_*ttc1;d_0}a`+kUY@pSi-FNL(;0<9I$Jc@Z*?lI=cZ2tY=RG)svzM8Tp?YJPL8kd}l zPK8gx`?&kPLEOwC^jB`&Ta2?Y8;cJ77!?;D)BlSYamx2&JZ`=XzpjB7rg8!J#0O*U zgx?!2?^N&CDo?#1**IGS=P();SNnQBUe}v9J?QTYeS{v>?GNg{syLm^pF`g&+-&|w ztQ{uR%N#V!@lCe8&$E^u6XAYNX?U5c8u7rD!o%6!+Kd7fM%8bp#+djcsKz!UgPP^-h%s)rtX}qJQ6W(c? zhHqn%)xW0)60X{&%_`P9wdtZ`h4aI#gXlGULfQNuBR`~{)Y^$mWnd$yrFs(?!iLbJzA_V4}iP7@XyTciqw-Q-Qx!f zqW|s6<6Tk73Rwnf9K1IO4=Hjbk+!FS=yPz=??UpZ;hgUC|9Oe7ugS#Og%gN(>gYbMY zk?g@w_w?%yzNyh>OP;xYxp0nlm*hg6F}FJ>oZ`71OK>t)FPRiLbHceHA4>`62I-J5 z{&U|wdEp)12j1ML@n7Abb;sgOoCUAO{jIAnc_VpzO(E8UoVW+^BOWZdgyZJ>*bN6u z@m|fnbP=z2<#G4>`2ph;JmVD}#E-d{bXqB%UqM})vYMVueAw%aU%8eyhpzrV~&lX-gxG85_l}| z#l+ZLM>HOn@QmNDQhACiDR;uXmbz<;qnNL;^zB7_eEkmb8^jgFuM@k(CE|;yhmAHV z(R+6xk$q1|G#hhW(PTgR7-hc-&i+c)H`c8F6RGd#zPMysE}30kIG*}`UTs3(k;{m& zDP9(TX3_3A@L68eWs4U9Gd4c{x)47)tS)y3?#~N%-P_~d0WPhb&BV|g^!4X?rKi%j zkAwD@v*q?Ue1Qi)&#Rmlq-WB%$3eA$c5l(;F~^n4r`dFUTaz#ra!GvQ)FCjlPxw-at6bP=5E zZbx>qMdj&Pc?%i$7UBeBQvvTj#7@1*UNm2@u=K6^rnGX+N6LnI%)LpL=IoU@(JUIZR!T2b1~galESi7x>$j&_ zWz^4;l!@Z_Ik0G+0L`xZ0CV?&l2bLIXuKsk#$Zy4{%g)z**5Pf^?H5m0sQ{Scb+is zDKlQC%$6blsq>lZp7dG9&VvE<%j{u%({}B%Jf^)PwEGr$G5Vskn72CjkEH#p$}^TO zAz(vT%-6;ox1E-#Y?Ahg7x={&OzGRuDAOyC+luysAR1+d;P06^+>( zr(Wf#R4#uBbUEzND%5`4p+c4WU`}+XJ)M_SnN3W`YvR&xv0zLurj9L7IrzvpO(=R^ zb{uIFs5?&mG8x&F(i7<-=O>mg*q)UivHf0)ENpUC0Z;S}GPkhfa^URC=0_(-<&vC# zR3x8z{lVGN|LgOAep5Ez{mDDot7yzOIohlK1o>WMacS?HCaiTNce0V@fOq^;>^-3y8nxyyH{-%7T-dUc#zt^y{g~KyurP-HjrK<6-rt_hPl-{M{#0r# z=u^_{c`R=BWGl>b;FDdsmVW#F{1N!H#xhTRNwr zZe@-!sjM(p<`O2AW9;&#F8iqFLV5Pez6!H1XRJ<`z#7dO3ogwg&2#C3AO33Kl-gsi zzFa|iBAv-qwH+*+aJ%y2iIZAh_Lz2B=D-B(%!%@|?8s$GGvSN1_2J86yT<@G z`x4=Gpc$V>z?-$zzVBmQafj&v&z=eJrFsYLB(SY#1~#$y+XkJFlU6~V_}WH$UymKn zKa`RUo|bJh=@9GU*x=b=9`>4N@{~Kdn|hNC_3C;`=i%Gao~lgq%4{4*eno@%JiPVg zxZGs(*QpG!+Rz#4#DJ%?QK|eg=KLIuyLX7T*IB!2SUPYUC)HE!NG>lr~Svl(rB*=N&FRCtmX` z9?h__wyyY1bNC;ai!VPx-V@OMYtG>{ZypAY^`&yZzNEX5C4C>TNiNOppWR*BceI;6 zWQzyDdBEu|CA@fP-;{ewnLd0mNy){Y(jn4&2#?2(=G!Rubz+m;Q~G=MYtKTn@eY>G z@5>f9gL^Z$H>)1$i9YQK%&GCDOE*0PoeuGR#Pqok%E&zUV)V05F?RtJm;|8@P<+ec zUq}(pn3jp}za5`L=x1OoV{P~u>azJ?V@H@&HZS{ZvghlVHgA8a+3YVhxciw`*?cGQ z67sd5(>NZg+g~#2mAQnsvS8>#PkMjpzP|mX{dI>+hs=GYee@+!XG%RhGZ#x)@`UGp z;;+%S9q=R3w!gI4+mD=RKYBYn*ZR7&@W17UpuhWQb3Z}#4iJBtdMdNa>@Q^q54rmb z@)Pgo8Rc*5NZ)B42(3(ZFEXXUT70&^CStS9$+J zjGb7#-|Q2%dym7z4JXe3$7PWR;n>&q+req5; z-jr!bXG*(LnNo(Zn_vueXkT`O#wB6>LU)$(l-0c6Ni1KG_Wd*AHImwozOr>1+#XEm zwd176!nHtsydO{l(Hr_3)(eJ@$<#fiBzj^)P)>XoucaqekoF1s`77-? zfmZ^18do=0tYDqcJru{?J13sX&aQCx%wHDZ2>GHqm#GfzsQ(p=m-M;gEgMUn>I$!W z!h#WX9%pW{`z0&D4O&goY0^^_Lpdhlf*Kgqb~ z6Q^$|><5Q<-zJ`!9R0FuRUR97(*MG)+0u8ov?WQB9r~jB;PuF)dYY64X!N zJ25}_FPp}>_~d4H{mrj5rgh*DZ6=_tns%Vi%G>`$x7oRL!9LqQc|JU4-#F&-BquSx z7$Yw>WnX+Uc%++qIWuwGJ?xj*zX2O)kqn6zOh;(l{`;RX6$#r&%voCn=u8J)3c9%vkX zV*9Ewz+V)sk(#6OgiKYx)-fWD zxvRaNZAZ_a<5_Xjh&0yw;>AIlp6}*aaqWmS^ht3_kf!Huo)vE#ktSKtIwu~8Zmpy0 ztDfGufG+^@T7s(WBWJJ&|qagZ^MhswRb+>c|(kKjT3z{58AAoCj?9rKp4*=*AKc+{erV^Lh5H6!-5XT8`XayZh2_?N zdU-stwz$e1o{yfMk1n`;vCW5v%zN99pugImPV@Y;S<$b#_6p}|p}iqJA^i9MY9Mw1 z8GYp$}@OYC}_ZF^5K$GQur$7D{n^{LLir3Ug6tg|MmI`@|5 z**f=@Qp9$z$=R5fe7YDvjhMmi_7ar8>=!{;&zQWU;35^y05aNIOw;?-Ma%$}ibiu?sd^)AG-H zwZC}G?aSjsI#rd%H5=z^B`$zk2S4Q`*_a7i(RB?t(ghF>?J;Jw^iY1OJwt2 z1!ty|mwuA%C)~Z@mhN$ZT~GV4Y_S<0Dor@X(@&3Jb#aolCy5P2*|?X@?}Y{j-`JyG zhV#MoqQl-}PEv0kL40}s|7iU-r?|t=FFo4B-C)U)@+!dd{+|xn)myk5t@X8!I;ZK6 zNwH@Lc*>eJ$?>4q^LhFrb+M)M`=_#h)N^&_b;sLN@UY$SLm&C3cewOTa5$sFf#g&&&2+N?%PO%*Q6EOHyrffe z6|Mr-IWjWXZ|bzSIapdvns|)QG@m$rF!t7+PgYd&%-K}s9p`29+4FkyuSsvtK14s) z+qTLt$>uK{#~p!7v-!Em(<|_?TxG}f=D&}&dFmDqIZm#O z{YE!3mQTzU{}<0zKa6($wRv=~MvtzxaCMMAVYIREgs|Kgzr1k& z3pki7);|*Rs$XqzUrcwKB>&v;8a#XdDbJ$Awj1zPXX4TFjQ3#q@A2&TxGG=b*{jNO zHtV;i_O*uy^BH&BpTTs;6vDD0ZGT6ZSZs*4Zv$)ppgL!x?a2}4|68Q|*Lijvi>vY* zJcn%wm(GL3yk4Hw-?-=U4vNk;d_P>7=1E|mNH0y9n9XZFkPelJI>m3 zoH=y76rYA4dwh4^N%;A1iDu|EZK9d8VRVe>u7Pg(JBrXc-o?K{zqGeb)UAYWolo8w z(0z^Wxm4)Am~!*I*UL6!@}gDqLhI&uYzWn(jHO*?{$>jEIjeIId=R~~%^Jy?RcU!- zt}i-0_S|jKar1JX^KYB4F*;#>WS=F&mAy-H=R&ig`~}iA(3`3Ab!3J!pz=)i=%`Hg zgzh*xW)-%NshmMSBoCrTZL&YElwA|rE+Gv&NYgn%S&#K!^-qh`n;eW~1-{!#`X}8g zJEo#-Q?4TWsoW2sE!;<`KjY7W|6J+`|8wXzjpt+k&$0o@=bMyG26j|PO9lKNQ(+3D zD$?>t9eI{A&%#^Di2Bgy9iGrf8gbbSd@J&kJmKNLrHltGKT0pK)?(Jp{{57FI8r}D zec5{VMe6rZz9&+DKd@{>7ksjxs8gz;&Ti7GNV9fTAhV)LV>Od}FGxEZ4`PA75f7f5 zgB^n3M7(&D=gD(3@n0&9_zB`9Ax+2->IhkaN4TH-^gL`sc&GK?ui%x{$MAPXAa~Lu z!W;S%q~|nGK>Q9=^?Aw zoLVPkM}61rK_=JAmKr*X0fyc<^g8m9;$vAt)~38o`8Nj!z9_w-`)Q_6?fG}f zP9#s{9B*C0Nj~?Qc%U&--ayhRpx-LdU$4cnQCNdx;)lv|hG=~SDl31!i|uqG32#%_ zS?IA?4*Y4ItLx1D`BI#aAXKCdmN=IzO_wjTFN5Ba?RcY(psznpIyPUwAzikO;jA4U z(Qlx`u&+Cj{AIQ5u#3P69{O_+<>e#MUdUySc+l#LIJ6p5SFrNu!3)xVyNHL4PKQHOBO%e=qT4-XZQ0#AtI}5gTNZ>c1J6 zeqAT~{N({xG6kRAv-5ctI4^*9wT0ZGN1iXKKeE+E_D5wnGq!y~CUNIK|26et*HqeL z{KGy}aUQHb+>@Mc`%slWvk%(a***|I>fVb^*FA}~whzs=pTcL3?cljA7~7BXd_H5R ze8#hKI&IhRth-9|fqO@mPsfmj%J%_(99YlD2=}92!FGVh@L%_*66X0b`r}AWlot>3 zbcYK0nFM|Kk)OBYBpEp;fZ>a5XPYM(VJ))HjB!7AeeAQ95qK$`KpWMP@p@=sEjhLd zS-65{@EluW))(;MrSG8bQo=sMUcw$ins6!MO2TH!zn6aO=6M^>$ilHY;9bBCW*KMN zzAq3TqxFX^A@&H|gXwQ2Xbsv)XeNA&@KHhoK|YKXgzbbz!Zn0#gczZoKpU8_+Pl5V zySDg`(L-hMZ3}J3NK^linK&|0wuv-Dn$BdEW+=Cg`l_ome0k$W5ztlR5`+-f>Ig1$ zo5i)9dLe%N8aD0i@Zf(O#I=BW;hlw$u6I&z##v~X3a(vAbQ*FIXIwc4ENUF%$dBYg z^MDD`pKxC-p(Bw|?h4Rn2j)P|t7<1>wa)h z=XvA$UtaRl!|2Px>6$N#NR<@pWvdQ-5nWNIlcFxwcakg5A9yN`nWg0u~ zdalU4ik>=HT4f$6E$MwV&{vz{$R_(0%G^;q~;yv{AD-T?1le0Ge869N(Myb*G7JIl)6u^stE3r#W78|(duE(I| zh}zo39m<70cR|K=*uae?hrPl7mL5glGaiF{IBx!-ntMRwl8h%joIts;sX(^HFUehn zcnr_5kK+z6M7iLgok1Ki(sXa8jQ8BFAI7~ihm7Rm>r;%?)A03KJ+rnR9mQP-`uGU# z6-AR^jUDUs5#c3o5U-^vvx562jT1uoza*ejeQ>bXFGfD8Uj{wM=k-M|fHj^P*XWo= zWoaU^BtEi_vb>AcNrn`*mo{4&xt6gz$hi(OWv+|sUV&t419{_-F|BoL$YcG^uSMQ8 zcHAW@gHLZOXA_}Ec21P0P|jfBpqx#kFBdZQk~8FmwcnRB$)M&TYlW3Dbf=Xu}vu{X7&A!+|vu~_;t~rgp zn1^o1VLyoP0yVS|{d9eNxV-*jL|(T~pzPS1Kwh=J=^nnuZM+@BH2m|>5VXO(DAn zVbMm$_ImW%kgO>`HkkiF=_}adD| z$v$5?((`=&uduy$(7$Htep&Bgc>Z|fi?sfTADwGXVZTh8F%RCcPd45Q_zGT78-;Rj z70-S64_+w6NsHm{kgp>FTn3x~E(3n+iXk0b&A6_H2PtsA!hJ>QAP?DHg3q7~{H*_z z`sQ->0RFHo1D>PgsC0vyiZeusC_JltNcuhK(`G-Bx(P z`;+_$^C$VZ`McM3_ThMc_d4H3(K`=Envk^}*gQS=;QQgMrF(KFKM(nTu>YJ~Mc%{O4~Klwe*AnK8YHtwIKxrgGob)`|&_6{;@$)@7DneM`lzJrAe z(9uceR0^Gr-SEh>)vvrh%Bv`hN^UKzoyyvtUB#XHXN#k<$Iz{7^UpqbAUEK~IET}o z{<=~OU*WoO-T49b6JrRJDJI?SIlyz!kC%&vO>TD#IJVI39!reMxAuMB$z6q>zo97F z5}8$nSNU!X`T%{qF+R(udBSXX$#-h7=dUU5qA#0Ck5OJaP4!-JHUHKYFA2&s=f*OI z6Io-&vaVNae|a(WC|gDz=MPU-kZ1STyx&vwhVly0v6s%;mBAlF*iYyo93tFD$PykV ze1$N8QnbDqXrRB3Xx)}CRWhJ?Ejpz?VJ}a2b1Y$2*XdU*trxJ+J*+ zd~r6vj8MkdW0Or9-A6v>JG$o@Vy(`-5*By0}e2P7~ z*6p=L{2G+8_p~d2j1R)`_>PXofpU)}`|_c#R9{v8zd@&XAXv8YX>8@0=>Hw)e{bR8 zQayUV7QO#R=>0hB0Qx=euqMPwP|d zG4BypFkjAb(YxG@X6<8t|7z)H$cV%JEC=70?(~1%eV+ZVd=J*Q{KXS)8+=_`{8#8b zhx)<&^GfM>a8ydaT~GX9Eg!PQubb!dU(qxDm%X8R7fWJ8@GkE~ysxEu=w)U#vMnFN zHL{nFNG_N&{WITnxO4|JKjz+(k4^UX;PRtPT)?^8zhk|CFV=q}zff-e?_O85Cf^;xcqmh^J1{J!qCd!#M76?pGl{9`XcN7@5The8@;XQ+A$6p0OX9SI?Fjkq4N4Y$m$w3ZB2u^9thcA;a&7&Xqjh zLaaRW9p@GDXIL3Ob`$XPz&8T_J^D*+jlw=fm%Pj##lD;MRqj&$%zKr!E=POoSc}Y& zQNHiY+N0Dd(_YSLOT~nzu`U~5QK$E9q=WSC@}9AVk6_?CndHymJq6RYR`0tkTT29}{&x3qBEc0aE+bFbzvmhQ-^pEnduuH~^ydb3~cV~uAHOW*eYHSZvOcGh#bnxoyh zp2<(4d#}nRUB0>C?kJ6B&VF|6cXD5%%vE{byU2bD-rZ2tyDKsFviJgzIK8V%vAP|c z6|BysVw`CQ`^~fIGM{$Y<7?$Nd?aQ>bBcF&(spgN`%tq39BT_Y3sU)W;Gx6!+mwbb zf%omKGi#~0L;F;8bFg;Wz37e!(q+mE=aFy6@0id4@9es0_oO?@>cC~!!T`qK)c>>O ztLRqg<)xM;^w+Xc(8@TxJc@T+HJ*;UH1}cg_AF%`^I7_qUAAa8e5lLh;_Ro-#)osz z<4)ZbIn9}vw>M{cST|`SnPgqT?_SQ{%Sqb)9Wiymd!npo+M_Go0dGa})vtm7(YG`P z;XYpVRYv>xuztuNYb)$vzm=B1x>CH=o>Je#)4GLR`|VTDjuUq(l;@a@_Iq{6p&hdm zE_9G5STdqL6*7k(99(DNJ9vljJvM^x_`JlULUfMH4w1j_)RPWeF_O#YKEoPV$|**jSH z7I%cEXe^++o^ilXJjSF)53QBI0srk<>%WDM{jU-Ji1#wL5UwYD3;1sd&k*!}?OJHw zNV?vwZG)C|Ja_So58@c_<61n`l$EdS8-%YDzD8I@Ir+*~60aaECoCi24Cuds^c3-j z2_GW73cQ$jGqK+Hok^REfOqlCupL`RyYqktfaef<%t!enk?%=c#`^E&ZyAgKCS6^c z4i5aZ^6l9??wuF5T!7ER9b0nQD*PS>uB#^Hks!wSx5BB&pa7j0M1E?RJb46chV#e$?pWs50vh{^k88n_gG9@ zZ~nBE3)+vAy_@kbL%yoap_6~X{SuY?UzCeg9V}eT`Oc`iRPLwH^?y76rUd*ONSDR_ zJ-qw3fF}?B7T#SKl>5R6-u+p?JDn+Pi9Il(!eqv7i5P~iXQ>Wr?M(B034Mt^^`BKn>F8y9?(=!|hck8j@!S=a9MLBI z57&sZ>3gji3G=C3bj_FyAIekmUGUu&jWscAXxzh&`2%Rsw*f9D?Gkj2N6;GeeaC-K z7(QTU`rpWLyln9|wJrar!`+@~b{se8ee*|D_YYjzRlm8e>gXE;?0@sveAuej=uFYB zahyZu%YRG1)kpOYdxN_(lA{gWpD>Sj@N*)3jrL(;-Seg2)Q>1Fyw`dp!Fqe#u*QS` zoL_Tqh(3wWQ6Bf=t9YCc-uJ9vPRG(3uS2CWvo{CNseh;xPcO~rygQC>`G0bkwSs#= zj*$+!EP*8;crRWZ{yI0 zo1F_h$GCsHkhDeeC-6R?Ydm}y-jWIA6-Yn1<=RZ#c)8*U_jpb|63u1VxH0;sJ+JP1 zn4DzBeg~#PcPmEsK~M5KugOm$Uq(5+cDO^q9k>eZza95GuL-vHG;Qb^{!P*yxf34k zaL;WCK{(48TfN7NO>TWf%2&F7AH&`e!RKQ0?6-6h$iHlvSoP6jjQfAa?FNt5c+Oww zlW3NG#(7O4p?8jhvI*{9M)T!M(p=Kr^%%U3&DML_>{+~h)LD=HjT|C3dO|Wx=JajI+p>XyF_{<)Ro_H=*rsTI5ASJeF2l>04Kk#=5>-j? zF<+|qj^NwTuQJc_?r#PCGA5o&9qY|=zBwu8JYD3Dgm_R!pE=eWvLnNG53%16zc5Zt zImv83Q_Z`)_WN^j`os8E%4Y-*k_6`9g1!{Chk2xd_8KVruh1Or=LXWbb1i#+kk`T^ z+`N%8tZYL5JiDh}hb_am1%m#L2gi7Dcj^vNP*?9Z8`8cvqCLqNZM}Swa~}1{zArba z+kQJJO4s~g{|sM_>293#Nwm!@X<2Y=inMuvv;(9a8PR4)XC3)^Z|=%S9o>PeA?>e5 z)X{ujz@1`^k8^njo<6|4ilT$FIe7cvi1MMl^e!G4xb|P)dg}a^FFW#`-rr^RFMe&| zCnZPerwu>cJ3&rayBC*O67$)CyCFwZYC-Yc|i z%j$kuwepq6p73({Gad9<8Fxb+?(~8WHEi#he;1{N>X%?sKIdbGJ>t#PH6n3bYXyMNiV9J>41Yf1bOw0&srUAe!whjwYRGMg=a@vgga6+O#oXL~6DFYcSWFZa-r zY@RcTV?R!w$p6^=E@knPBP$wrY{*I{wSAZ@h?k`IJKjIO7I*Q};1@6B+i{-nSAS#_ zwj*acmn%*kKX^eR$+_ZZo}6Lae`F0_TO@4`@FLl?j;A{a0l(pO;FlnMk4>j9$n`bw zyIS>P)T>Bv|5t_S|@d{Q){&8<6IN^v{rJb6`4O!(78hyK7Nn)N@D226|Wx>fkKdZMUo$z#jd7a+dVZPMhH(}nnCoG-9 zAsVMZqt;y65jDt%=F2?RCdsnq3HXjJfR=O3Qt)rcUjlw?&3@0_SC|2x^ewD=ftjGZ zZ)y5JL-;h|AmIQ(_VcF*vY+=8?j+nnxSg<%u$Qoh@P0yuz(Uq9`VFO_^VGE&-&_Gx|*1sb@j{f}@`dt&)H%Zc` zGnSu^qG?%m_X$K-{hO{}P-5E(c&03&>YL?rEakhUw5))%Dd zUD%MmUee}Kw@IVC4;n;ku)zz)3+4=XA{YB6zJWYxP*4{jMJGcD<5+jK5WqU_Lq6l=^<~W4z17d0T<`&U-_$M>iDp zewXm0BVN`zD;~Xzc4ElMDhua|V}WHyUx=Nkwc)R5H|)z3*zYF^Za3ffAS@!J2&)Kb z!e+u2LLH%ju!GP{Xd`qIb`f?HGK77E{RG`9-mE#8VeZwT57EWii)gR^XWHMfPOaoCSB#mm)d_dohU}z)@nER(W!(Jv) zcd+y!Xqlg>$@Wf5&V4n z9it=K^JN+9-QM9+_lNg#))~*m`_j1wy;!apJ1~|!nw!bpg82FDdAzEeVK3o$_Y%i* zQyoM6VD18a4{UUX{CjhHr+UiR2XiJF!zOofQ+fX&F|~)m9MBWk=l~eIfaJ~LEv9rMEv1Y_D?;&Q|9Fw3gdowZ+@4D#m7VsBcPT%{LKlX>cdBt-mGj7(N{M>nrh3A)zyN~9WN0-YMa8jmF@Al^F z%)b1Ae#W5ulf}KXo4KerpM}=$%8b_h+?02*e}n#*Gq$Kb7~|sX;jF;%+*k-ZrU!fa z!GiWI8n@WF*cbWipPC%^*#G{O;so$^r+V^R85h6bymuM)8=h<;AHEdvyG`1gx;MWb zn6&=bx!my_#PeJ+_K_FuU2T=QnzE}YBfRLAN~aGSn*I3M@QddU!S7jD?#uJOY-Mcr z-r}rd2l9W49Y2*Z+B*Sy=;NMXj4ll5!6uj_{FegD9#Fee)mDnOW@~?H?-X1oT*Cbs z@M%oM=foL&#zr^Dxon!gEnhm5&!4t@4te^U_#H<#AjkQT-yzQ7<2H!Tj!Bv|$8kSR z`^a@LPQqi@TgIyU2Gd5u(Xp&L3l7bVm{VPR7rff#G1o6zm*bq}ND8|U-`ykKe+#Wg z4-~WT$RjO|OncnV(Au#WJt29?%+KZ*kL5jFV9(oHm>l!psd$WxFeTHeIaM+{;Y6Md&WMOo8H_#9ebFEU&2=Jk^U=`r4FHkGfZPE zA4hbrhrKRq&V#v_=HB0LDQq+5O6Egl)km41qpon#_>4(DJ9hjS3v zpM%W1@!;>S>&bU9HfPKW`U$(3cU{FD5Wi^)XJmr#_-jG+yYKE2~>u^VRR_&3kp*3(0qN+t@8<{p_pBosAap zoOd$^dH$g0CUbT#vN5PDp!qu570uY*lSI=p;16nULcjEe=BE6CmL_y&ED23sws>%0 z;L35(G;V=U)0_o+Elp!Dgr?N;-0ieC&+INv1qXKjm5#^UU>%&7I#7@+ij&pPlhiTy)9)!`?qwQSB_TfAzOb^pSc=B2Bk1V749(SkY;z{z-d2{!Zl04RpafSszBy_Pfx`c$p4((k5kOg{G1fnwF^8Fu|X(3i=_`tDa= zTyirapZe>i`-b81@0X^F_#Qu{cJuhSc<&Z6*6CaFpTZZ{AJPUtEp6BpXQPcK!}o-J z+MJ`$ok1IYh(mvrmce>D7t;RdhXF0Le>vZ|x3pj{ehS+9PjB{py_^ebZLx4XH6`~< z3frBaHPfN*r#JiSZ?=|oJ$-xbORemc>h8#u*L^OJEKG`_hgn-sIjQjlXsYhxj#*g8 z&QtC4_!~XO&0{mzJGze;uf1TB>|N9Moxjc@e^=^WQViW1PkuGWx!HAP zv?p9;*kRm>61|l=3-xV~N97y6&a{bFgkHV>h99%<064EHpp#IQvQ-|yc&Wj6O_|_ zI84|0nUvN)f9$LcKVr<{@b}A%yT<4)#>j6gTP=Jc9;c7B?r0Uf)VpYPkHNRc#B1Z$ zKZc#fIifxHMBQZP-ozeYvd2BH_IP`8u^)W~USk6#AI&+*Ww<4KbH9K7|DF$4N6((jxYUhxlEiMk-Z#i= z+&5zzoX?1 zoKt7`S+pnrg4#%*b$@1J}pOfaT>oV~tdG?&7dHnhSKhNL1 zAroH`l>a5q&+B<0ZJw>o#BZlFX5hG~sn5h8P&#y;H6?OV+Kq%}S4KOyiP8k>HI=Z6T76P_W2W&g9{$+I%?nPW3?NHxk`8a_BZxoETJP2Yy4lJ)|~Gd1gm zp3}?xXVvk%W$E?nf@1539+#zO&$p@KAEC9Qw!N{Vv2zx9yIMZh(t1max2<*O&ia-H zlj6HN?<9<;98H?(9MmmYvpc{)68^pp?SZVVLrgId9@j9#+mVEf_ayDx4GC{ zVlFka&0I6zEHsyyKQtdSA2v(OGPA;5VOE=um^J2Vv(~IP8_gzjt-0R(k(p@z08{!s zhFc$IrkQ1uW{#O>7MMlma*+D%ZY_4S)j z*-hxGZ@+c-%EqkxOMlEt{WA)I>6r8 zrqJ2Ab8BP!?yI+TDzxhPs@9to{EX#|+jbKy03FF)$uhJUA~1MVvY9_`&g|su3)Q z=Pa6=Trh9$g86e7Ex2q!h++2pIrA4S97Jd428b6fvegVIZ96^|V+1KjiMD-c;0zrJ zVr>#V974<`VF3w{NjVbE_A{$vM@MISXZ=<)tD$jg*NwIHTer41-aH7k*SFl**b#!; z+v|5Wh5&qQ4WFBvS_adbTepSDJL|VaOSN@vZ2`d`ItH)38NrzqlF)JMPLa}iOLJ{Y zYy0-5_MMm2A}TGNW>$M+bNyM;&yuuy!?HET{#vdl`)g}c3nDpd$;J&=*Id11c`b5q zwFwf}Z&P%b zTPX54lwry8%S7o~bM^9#H7jaYuC7_J-fY{^xb0)JY)SvomJ9}O+D?;Nlw5e3elJRz zY4v7WgZ<6Ji2tOI_#YNnmabjb*wNYA-ngu_rL%EY=TOO6TRSv7^_^kakyr=QN8pZt zSFdlXUEO}uvij!ct@YbJwi-EE-O|vw%UI-19jjZKI-Ba7n?ByyFm2(&`AMS+%Ud_L zAUPjfdh4dv_J$y-W+>q-bc9X%)i<=?8Yym@LadrvZmezV>a6u2;oAJm7TDjjgI-3; zY}--aZUT6FQ*(2zO*l)#gFFZyu3lf8?&@4`n^W(G_&GQPTH#t-YPWW6-`?0x_l7Eb zWX-Z+@RIhXjxz?c-g0Eaj`qg-hSd$rTDzDN>h~3mof})aIvN|oEStKnaVK-Drm5v) zE8AOluI*~KMTe z3$DMlgJp(%q|hHGD@7tH!nozkoc7jR&Bu@spT+>=Q2(u9o^=ul7jv$ol`h=c*0`*m z{tWe^wPnT5u4zo~MH+t}fzP_Z33C>~i1ySHJV;1NE0pcpMtDDH?ybVoYHn;t0t_WC zn-lONFb0EMn>E+|_SH-%>tI){*>8*2X3w*~=MVJ_D%F+cO&x8h{1v-G&7;Kijh(|2 zkm@BZ4MEwkWMnYHB#TkY){TwrA>B$#vxGIZc6D4cG*PZu(p=vjOa(E>C+C`#TG9Mc zgZN>VUmA0C(IR-j?|GK`Wp)yWiY*umHMrU;HRQ7~ocn&NO$n`QU;ioNW?E%9n!7rh zZuV!UQl!3CBRiJ5$Vl2%z*jCo=E|n+t?L@M-5gS~!LCGuU{b^AQt3%hoKPJ=+2|HilUgBAIo%vljgmW@<4tbP$8!W3?ac ztiQ2#TU%FCg9(cH86n#AhA38^hgWRfDN0E8XM$+)o39C~`E&|8qap=K-oAZn^T*oG z%w@?s zw(HFtI>$3209Nvw*fBt?O+*B2BEv8zOk?0EZWkQ3LwaV^_>yf;Fw7&TrE8~f*Rt(sY;S=>ev@6z&0&*>HVw?R)XqI)b&SfmiqR2%Lpi@Kt+Va# zxlnAIKC?XvhAU^lgCQQxww;@;&V@{Vy&;rywKOfg39_<5*g zIQh>^q5Ff0gAaZ;wy`6yda+5|4Q-lsf9^JzA#q-_dYB$rzx*S$gIl+n)$2FZuDEJB z3v%s-v^Iy^jS8$^v24TYtFNkEvTnsyOW1MMqGi`@uvvq3*RQ^A#jq5+&6>4*$%ZAh zHgEW}u7%vL?O33-4Z~|`M;56SDpOQ`duQ$T7QQqJL04b1VqMLWYipOUzGB57$xXE@ zyIQtwXl&ofjug!yYrwZ6wM{a$4YlZEXx^ZCJ6{XM%>lc4upY z)HG}M_U8JI9jYGe?^d@U!|h#dogHt7#OG4Dc2HARf=`iIzhSxP@HJgcW6O=5J4|iY z+&Q%kO*hy2Tn|}0%d%wY`t^2bq66l$_^dg$&g$i6{WZ(f&a!pO@LPx@0L!u9wpkID8jnxpEJ1o!NNQQYbP-{0_6G#Zp>2QZ;S+V}w^^%ZfAJMoo_*YzI$=Foi z)CtqtEwHhrO?!bRxF^Q6-?UtNeZS4YZOd60>&ufBKjz@p&emJDVJB^CZMj)^RyPlKLe14w+1AN+qjqO~+cLlRekF~{nbX7{ODkf2rfB2b z8sd>tcvyc|T;ICA(>Lff_Dl*1mbJ5^eTni)$^{#1o7R@vVSFCZ zv*DV-q&K7Pg6)f}dfDq&wRW!9+17dMFfx4}TM9#!qrOPtu)d)+v6;7jXMX!AW@xV>edZS%ktL$q3TLt9lnN>9UJUTv`B1h2~jU) zrruI-Jx6qL(2ume9@9|r>u>JE4b$qD^|v&2Zrc$kI-#8~)sp7sHC?b)y_C!Z`$#*1hCE`vlxRvKCX{5OE5RC4*3va>fLAu%1YdS` zG_&t%X>4cJ+$P6QEd+Mp*=7B2ZfsH1vaL;ON!5n7!CC``yGw@2#Z?>EEXCg$P4iVX zvvr6j)}YSDZ8{{{NOzznuvUz(vsexgA(n%);ITp<>Z4#X2U^NkE77I{(e`y_Lwm>B z=B>ZHGIN=otLmGF%lXhUGdLuxhbxK=oA}~6RhKv2jE9M?G98DdWXV)xku5aN~ z0VB;H5wxC+YAGo{r5TMC%m^!j!*&Ld`AT(}okRZEk;L7?-o!3A!fTCzb&WT1Kq^~c zO?`*t^-N1UqP*9vu3djieVaYeIFk~)G6$MNX2Z5t=DS@G2DRHTE0xyd9OwLC{jEE< zwo006uUUUpWDhiGb`382Rv99H))Hz6?WAB*`esQm-F>rkguWjd8diLyK*uTAvGQLJ zA8|D}Yfug$OoQ&5PZ2FJDByu`s@%G@zEu^}x$5e5wx9Oi!bl<4YO*XXCJZ~hinOp^ zPAF@Jf-gD;hZOJ1dX65pwYJ?VGn#cQ@E=hgVG!9?u`$B~ieycM3r8>nI$g2r{P0r} zJ8eO5%?S7IFvMugP?DE&V%6Ffwqu(e^zb!-r`GoghQ^faLRq`pSpsV9g$-;01gC!F zVAwemuDqd4_&Q3dNTs@|c7y3Wv>8#K2aSkeXX>j8gJzc!5b;AQauo+9+}s$hB?p>`XRF;y2GbD zOb~V9X!+*0oxQ%TEuXR-0^icxRR6KYuC~EtA9sl^@U#SKFO6=L)X;;GM+G7>Xm-dq z;2YJpiQ&UrbKS5NQ2MO1wT<;B@Hf;5-LQk($SC@ZRGr4oO-zZUsBM)8q|0`#UZ%5d zjBTB?`ufjq(UzU zJ3HKdj=-7mLmD2(0@Y*$B+L4yHK*>tfey5&RznJ~?`b-W2eGNPA-Jya=qzF)Hs7i$9x* z6WmK9vM}FDHZMi+-2l8VQokNJ+wGT+bN@}3Y;y3Q$mmX7GqLWz2^RiVV%>)e;dUN$ zM=pfBcz7`a?*i66xiFvaIT+oY3t_(XU>=IV-N1(;@IK(G2z)27?%EMqdOk($M(8`J zj0oHV$lpjFEdN>HTm=3+@bL)zC%}CX__;_n;8Iq2s*78d>maUc0a7XB4+Zv@taQvEQW%W!69 z1TF^_zA*nBVE#tmAY29f%}Dt%z>6X<-`X_CBjqOmiyp~^==}h&`Xl_3pIN}2<1=x| zq4HC}yZL*{;e1{RybCx+zW7rE+y?B|Pw*BB<25c5*WEAG-wN!3Z$kig06zz;^2)y% zSnY-ItwH$^-VH2#A$%L~fe5?@xFG`T-tFQDydStC0^be%BKI>xe4hq>I0D}ToQc4P zfOVfUEdPZ74*T;k@bdQ#<^Lt{YmxT;8hBm=eiYb5;KzXLLd1PgZ8HazXUA3DSG}8xZwisc?R$%;Hvix$-^$-?6e{N{V{NJ1m>^Rn?(`0 z8+b+p-Un91r~op_;FzIKZL&l zEPQn&i2vUK7Qdv=1nWM$+FupGzW^3}&j#=qFx?;F=UCt!5qJXdvEa{ z2>d?apG5dI1^9^wJPo)m0>2-4Q3SpS*p2Y_65zKY{7eGRi@IG4a_oATx*8)$D0h4W{A3J%HyoB<6caR^h2loTlP4~----m(6N8m33 zKOEuTmw~g9{D*m|>-hX@8Ub%_UaPp#| z{*(bvj=&YbogWy=KNq-X#t=MO^&@aK@XYrQ<&Ot85q$3k-VnjZhuO^jNd5P!egyWE z553{|Pgng2z8S#FBk;w*4H0-2@O||EeIU?!IS;re(*HE@i{w`Y`PTryLjBO5_!w}G zeA(5ie-rQ%z@fc;3-C`a9_sJMfg2+5CxFutI0G#F>W}1eFK}}Nz61E#2t5aY4@Btw zGVq(^PYvk#OJMht{Eg`VeiZnnnM3#=2R_EXqVD)Ew0RIwL^Z^>pPp1ri180D>UXB4i6rq1A@Z>v&b}}%t-nF9>BscemxDGjP&Opfad{^C13n|4ftdP z-|N8RdB;WdMPGkVU$F4~3-HWH{*Qt6PE1(-r@&jz&BP~=AbEDm(f5)31aM6R9wiuh zGPZoVc`xuQmk#0cfS-uKQ-PZ!@P)wX2)+*hznL7WKNI++Ncl^Fdn521)sMjQfmcQN zxio;)KlT3#;GabBUkPkx54E=jI1z!2G^`LH&uq zZlwODz%NGRcLDH8`XAC$11$Q4U+rHFtp0`YI^ghKCgpDgerf(t{$}7l_!pMH9$5Sg z;TwPx5x5>${0#FOR6YXV2(12v`5y%qe?oXCu=*RqZNM6@5bgjLe?$0YVExVW5WW>S z8-aHNXCm-zz;zLL53v4LdRYH9lFz;v@cs5|(+cfa8fMXv0J%AteDJ7C@suh;3n3z&DqpTInl`uZ{8m%RG^67bbt{!aqF!h`v6 z!A`(PF6Dim{EWAcAIf_Xu*Bcj@E-y5&bgug2{7-Y8~87PZ&~i(S4l_t4E^tbS$_ln z6EN#z;1C}QGf!~v1i(AI^6~!fVoyIa0pA8XrrT2fBLUw680rytHsBk*^t_yWy$9o+ zzF@-XF24nU6JGrn0iNpB_XNO0Uj0r6{GeCA4+DN_iIcY!@YP=ZY5-F|v-S5u9I&~= zPkpZe{F>K(=K!XDIS!NlF~HQ%4j2UC3jr6r@{a(X?ZFoVp5(!o0=~tAcLILYgFgkB zKgRyQ0Js|ZCXV)h17OAzAk6%~3i#SH9Q-xFF^~T{fcazOeIGDm5D>@o_XB?TOb7o2 z@RCige?0`4aR-Kwg8YvIUhdJK0Xzq=S>JsQFk|6DUDE!409-(MO#ZI{UJbgj_i^~J z8T9DW0Iva^1*CsE1Tf?2n*KKnFk|bQ^zQ`R0od5v9Kh>5`2BzxXJLu1?+Jjr0LL`E z95CZ83>kX>yxJ>I8~M}te$ezj!0SBvX26W+Yw{lk%-FuB{FgAjNB<;X#%nDBi?0WVLv^5T8y z;36;m>wtfc{EpS~_kkfzgFMcUnBNq@)DQP*XrFilUi7g`!$$$W)|2->z^s3lrk@D- zGK0{A|_ z7lBUxGc;`Y&jMWE<@i&8V}Luf{Iwc3{AUBcrPuLy1HKLLF3q3Uu;K3qd~V+HZv;FD znEGUS&IdfJ;L5i}(@pvdHQm4?fUgJt-RLh&e<|Q~{c3%J@TWB0@L#Fv2L3GITfjdR z21)*FG;HYC0lsr!aQw4c{*4+o^qT=+{ZVDVO#clH8~Po9Z}IHmmw*{F#n68Rc$Wu1 z$@CbH)`8(|koO#5em`@*PxuwUcfcN*ep)akm|UTx59R}= z?ed5G)j~J$zQG#69Pg`vqWm7fv=7BUA^2#7e{yg+;Mer`#&pd0uLpdQEzgADyMVdB z#{N7V@*V;_7wgfS@00&&z_eE*|2e?i|3S4>{Qw7puS44`@4mtG1K{t_J_??Ihmj%g zJSYDcz}ydF9a;X90Q>1z0$$?ruOYnx_JJIvzJU3?K>ZQE05IDdAo9mcm*fw)t3!Cd z;LC(<`6dPT0G7fEeRA*%z=!DX1Ey!tTdr?onk@4F0+{>R)Ccq9M4J2E2A&R>``HFQ z3NZJ(4g5a9+#g(s^la}F02e%c*8+CsIXE~I@Jsr8hUGaM@R45mHUj4UHrtEk*#dY8 z+Ust>Y_FYwU48crz6O}{@5P$`9>86*Re6~HVZfZP8+&~=l77G7Z-5yW3CTsj6Hqbw zKf`|@VDtUL@*d5KZ!`P{1jidXDoOjQ27I-(KfD-9e%oG?gMPrrp+3qUCk7Ws==%lN z3d}Uh-o6Fc$(s`VB*H&A_`T2#|AgRGzzaS5LZM`T<2bNTA2R^ce=7MCf+GOSH#q(` z4e?^$2Y6Snqc323_zS~-D*5#f`@>qm=KGZT=>yF3BF6r=MEEBMUjRIW@>M_v^>riQ zyFLBi3)t_!j{xR+VLmr31IFoRRc?X zGy$f+CKt=!%Jg1&dYIn!ul<4x0WbFSdl~70OMgA-ST8m8{~F-;d-nZ3z*oaQP5=89 zV2;08NMU(?&-CD*4Ve0Q4RFHCZyXK)o$SF=0oR9v<8RdI-vyZGA800&HxDr9*A*IG z1bDV*f31MIUTXZ!dcfDie%FAX{q20f=4TpWMO_Y<`%@y^%=P}|8vZ6=o>#e0 z!#@Pf?|0Uh_4zqq?w_0f^(VlbU+mQU`-8ym1+I5e{tUqUo``997GR$LS*hXo0Oo$R z;XehiI7iT@q5RE&&5zhCVD3K|{R{%;eDr!SF~9AA`Mq!CT?&}vH)YU1t_1AtVc*~z zfcbrI=>I{wXK%j+%=w3*zfi=#4;J!Y^ZelfT-et?)6g;B4Ve3t)E~>Y1n>mUo=ye) zXV3nVfStdX7~}xI5|2klvcQf!5ILbBrxWy0q>rsIH`Pk8bpXhb6J`x{r$edt$?||o7L&R z2l!d9eI5b)pa=h!>Gco&&1-;P@%s0HIH1Y%l^21B<$VWWp06?Gp9k3G|F)nJFwY+p zH2)f=_wvgFj(O$Z2$<(R&3L~9FwZZsSj_Kcz})Ym{Sp2SV5hHxf=2-}{ue|JnEmBN;b$7Q*8#yl0dsws{f+VtI2_~gjKT5eA_MXt0oeSo|1BcjYtIh>_U9v2 zfS;x?{IEZ*1kCdR#$K|3xu0a_0~Y}{KQbQ%%>CX3kSxz_fSo_Y_qy<7z6dAB@;w0f zC5-oj;Aedw2h8)di*@?n0p@wR4#4DpiRtb9Z(=b12#jawFUGzO0qoCb-V2!LSL(IA z69FIK*>4?Su7{cSZwAcu=K;-s24J4wxL(8EfO&p#mxeb24m^3A0Q3CQTuuKRVD3LJ z)bMS9dH&;B4gUb}i=KTx0+{DNCO|*b-){hOKM!w<3;Y+rG1$W_4Ud}@_1}{LXZ89! z^?4XzXV3cvA0X`Y&lA1?sx+t1~IdH&nz=W~Fshkm*shV63`V4e?P|Db(- z8!*pzoA%$u^d9^qVDrQN@@K%yJ^%4KVD3j$fQj-a;@}O>`>oUPA%N$2`g$*5o)@Us z^eVtS?>Ixlt$^!2`E7uY@!IQrz!T8^=W71#fU7QIp~5$X?+>O=d)u^=_BnB%x@jMtx@7$LNg)JX z5Ka#dI*^oU6RReUpLF!3Bfz~GQGPnv~XF9{D0 zDQAb22QO1W-uOwxToxV*ZoJEDbDc7A{{yGuTX!dT$nnW=oR)WaI14ibmaQIZjm1CL z0HNm76D|nH(GtyV19Eob(#ZSUgN8KjWNt|3*5@m#K2Y`E_f{atN(BPV2304nMtnp5 zCK(G6*PGMHw$%F7ZGD-pj@3FsqWS;(vW$hXngME8qn)HA{k;giv?(9R`Lwh!#3j~7_2Ge1;8sq>&hJ03$Pu6gk zrZ3TOwmq3en5~71tJ(z1tf9VlZKhpAwecnu+Ow`&W1x^) z>SHUqsA{<_p|tW4`cHsMeMU33`ENm+;JPj^oFf-Oql*Uy-I4C;?N(^?M?vR#!CDw+ z0<%AwjOh{IAg!>Rdk{-Lg+}4n^e*?okaGSh)jBM8xo!$;CWr46v-F=wu}PAebLk=v5NunG>+*19n(&uFNoVX3QD& z@3dfD%;?S6X35*In7lEcd)_M!BFJPZk<$2${(4lRiAlY^yBS%IwpC*uLaM;7mBA>eCvQZ4I7L-93X`W zc}d%1)+;dVMPN*gdl9H{qrzgC2wIUYo9m@p){_gi&zZm?z5}8qOLBfywFAXqrV29z z%y)q4#z-=tP!|IAfI+E{C6agt@U$}&xP5&B*Zc*$)5k9DEg`^Dx}CP8IeI1 zo0;8=hCwIqR~Q!Y8^DOcpayJPQv*q7q_b+n;h{&1M@lp+Kcvp zcK~C008K=TQR$R?_3u_0OcsNEi_8(NtN*DKf&VteC4ey~+ygHiA$oze$!N=_E}YOR@fS#%qYcv#&wmh>m#{9AP ze%>CEXA{ecp~Q4>Ov_P7=lLj$t8@?4Qke04GNg^Q-}^T_#c{wiH;9>4ZfL0#OOJ zEg@qKpcR(^FcXhB{w{6$vnka~3#dEpAbt|%h&HqeUU)f}w}s^3zQVN;u1LT$F8H9m z$e{;xOb8goeyZ_)8W|o31|_*5ryrE&Bq5ECK`xs@?rCse zWLH_Pc|pB!k%PMnMB+g2mtq67W^7Loflafv002;RjQJd^Xd= z$TVZ!A)X5!SM3ce=gs`ca}D@NqYvFjuYWvtI9!X?Sb!@AOaX7rL1an6T=Eo(NCoE=D$i{gZzrTg%{2qr78rCM5gzv&_ zAvt)m;FR$3fJ&l|qz9?)C6j*j;$pCF56Qy%fn_CYjw&i7PbUD`N@P~!E>^e|?Fa_Q zxjgY7h5+4XTRK#1L531UDOdu=duY|A(8GXNgjb~qr0XKYY!QgOQe`JdW<}i98t00D zoR|w&p3l=cx%x)J#SG$;b9+dplI)1Qv8cwx-CCx`=L26{Rs13 zQivC&5acK+1d(?Y)tR{a%GH_qu$w-v^Kx~LK2EX&yVl!7a_Rh5SshDKC0p8_IwtNH z3fJm%yghsZcwOlgrkPRck?_|p{{%v6iWy4x34$+TtZ{yYh2?g`xg9Vp{J^isDstyo zdzBj|yclG#cg?Yr=Lu=~v{n}%X(S|1pXT8iIEM>4)2U^Utsz<^;DX2&d>vY}StC&^C2#EC9U-rYM;w+}pkXhj1MBV6 z(|D*qIB8}O=yzb?qkfCBHN_=}TRfe^vZ;Q11O-LvbHIy&a&ml`Obu-|G@ZQ5bqI{@ z^m+C8L(6Ne;)^z0C7r4<0%#-q*B&}(qQW8~`2D4}NmXvvG2r0VR*qHQXFkZ$U*)M$2&N_XYkr-z;V1s>o zNS14uEDTy`4o+G&c9}w}+(O6A?zt4~vCS5DzF{8x<5faqt2Q#_B7Dhg4@sV(^MS9> z7?BJ+!7Y{^jXGR0tx_h=P64AHBf(BBrwe>$=8BPdm7^AMoi#{8Ir(g!ZSp!1f2N32EQnJTMOebBwA*YnEdc za1S`Hgggue+?^h-9q?+v$EkG9SsgTUBs>FHV=s8AM42f{=Mu+qsg4Xk)jZq^EQGXY zWNIA2pS~f}fx!L|Tnio&SPRr*h@}5!SDvaJ9Z>UCkz%acLYFJ5fjl}T;{`x3CL5iA z#m;xkF;nMxz}0EanN$siOH5JREQQ9!AVcS$3lgdL`jMrmv7M!qEMdi(o2u|KUrn+l zjzHP`-j$Uti>}3F3*UZ4SbXi{=tnUYVHG9#U{pfo(x&DF9uO_&ZfUHpsm0@<#dw5+ z#iO72*%VSKJc&0HtQM2iy-u&IyU>nXE67bw-mADG%5B!n9s4)HzAYr{h4{TO%C5t% z);adSf_-~v*l6!+eHK|VJ&(>k5|vSsr57%D{yUgC6Y&no^U;JQnR^Kbk#IZK*p(_G z#h@e_&q3kp;6~_9>j|M=5!+KeukjV64xYoWGdTc}ADA41YvvF%b`LhU7aNCeH%!hy z45CChv~AB8$Ob45AiUFVF)zjp%LlpFO4w`=S9W%Cgo`5a;^)$CZY7hm&xq*9U%|^* zigZ<_a<0dbsNpTD#;9sR7Wl`!rXyiu@;S=Cat@DUP$h5ZDVEn~qn*IQle_#Xg;+SVjg5vJo_B2 zNdnp)s}$EY&!t`<2B z9|8y~QC#7ss3k^}4a8o=5DX~^MUm!}l>TFtl)E*Pd(2Uq4AcGr7?t^VI%=s_rH5oT zZ&uaqCk>bL&vDx?{8q{#jWS2|DZ<@we#Xl~2nt2VJODP?rLh?>G4_>Yp+34Na4&e> zmJz>g?gvJ83D8|A$xr4l(+`EmfgAc%OYyecIcQrQ($U{X6#7XZOZI>5Hx}!`nFF@i z^=1>+U4qXbjTA&gbKLy`Fs`tez)7ks9)sxBdt9?M4vrV6NvLcjF(1Ef2l*0UZA++D z;kE)cw()N%`(2KGNLH=QK8b8o+nVzuG?Q;kr#o!d!@iYj7rGdss(fdz}-Y1H3JjF11aCrnXC ztHgy~R-JgwAh-sIOT$8M@D-JvUq&(yhw5L2XGWVsjuH&~_=oTuGxe6`ON^sM@6Y}> zBy0=G%fOK*jyosVhIYi5Ed1qOrcJ$@qc=G}t~g`L356mqrn&ynyfpuVY4ab2`C zf%=Z8 zF{_vG`xpo`6{GXI(wBE1mW;^wxE5;b`UH^AC?xBO;oxy#o>Leca75!W6GrX)Yf(mJ zAMX9|ds!#4{-HRl*MNLkA)8fJe+TBT3UiudCBaK^!T0d-(K=aoW8%tx6WQPx1K3_y z>078KHSTG`J~a0*SfO2yr5%MtQxq*B$5>$R0rKR*_k_+@HJzMN(&?T;hTB5&RKIg@ z{6kT`NXYxIV$|3kl4H8cWu;d3_V8yw9;%QnJXixhqE1vO90ORZF-sI?1-yLwdW|#R z&NBrm8!#%lAy(QuKA3qImYM%(+l566_C4D*Vd|l$a;lLu)dH^$&7NkW>o3HmqZ{LnpIkyS>Ok2 zJ1{FX#yjFL61IVGmL^0E02wkf9@F12YKBR9QU=dHzl@AW!i`|;(1k9MMoGMsG;?A^ ziII@~tKUzBkmGD6rq%eolYqHQ2UWYw^lsuJ%I8l zWHb_H!Evq;N)=3kH$f zwvdcn_&rC9*A>;Dq3+>}$G|-j7F;0`YKl1$<{d7kbl*Y26nZs&hogek2e^}qGtZEF zk&|KNjyRkzmol%%?>!)UErT;-%JFz_8;wBr_K=LNbfZW?)yM&j)uv{sM}{m(vT z!JC`gKLHYc@Y$!2V~qKC->{sf_y5J}II`!(t}F4)?$wfO_U6>``Ix$G4?hEjeK?8p z&WmghuX3OIr}d;aWa&6R=Wxxy<+E%h=CKC94}(Y-Xu62^I@5P0A2LiS$_MG0mTDS@ zE@X2UY=te33KM)B);(& zU|GH@-9txJ^6;fpi*^7n(>s1Nw}I;+iN# zQXE5Pd{L8hOJD+t2Iqr9atgdoB;MqbH}lXsXP`{WP}9GPq%VFev=8Ywh2-P4?eHdbM)!RYlNGeY?dQ;&&~Ja9!7%Tgh-=GOM3sHBjLf~d}?ia4{iF!mx_kM3S@+@ zQzc)`8SS^2{d$h`6u6)#f!(612O0BgD|5M&J{dU!Sbkjts}@j% zcc#YTTNN)~$r&KQ^J|pcI5LPACGjvJKhGK$mXvTfoPwOxXHD=+Byx*SRQqwq4vxR( zYe3_N%Hz?>F<0HN99LA|Z7vA2h08pdDnKrMDa{tl3rC}d1Z z4EnYBo_AGawRrV5bssAxRm1(Qp41+y_J(`#hW z8mn~?Y-@96gFI=A-J4PZ3KHyF9xnxCFYvN$s9edj?#3cZKeyGIDb6d!FxRGg>c$IK zyj{hmRG>9NOkOTP5wEZ2*gH3yLK*d$hBvf6 z0>*72nRu7^1~7j1csrEAfpXLok$79|+u+?ElIO-ns3To6=TY|oVP;p@Jdx!&JaIM> ze$OM|c)1}UKjtN|9L7BsTvI+jNO)E9n*km#Kcr?#MoKsxlmQk*T~EL?#+0=71eTO^ zFQr0!1=+Fa7{*a0NTVcnrmphRP>!77#d@3aUsLmOs_M>LdqmMPY8JPk>Xn zO(>!${JThw2iWu&z<%+4V5GXZKh?n;(m+^Iel9ygjt(LU{}-2|zkJB92+V`N2&ce_ z)W=hpPwPos4TbxIfnk|a#84e)8hnizvp6!f1G^3a)X;=d{RE{_7r*p18Jd*oxh!(< zG=81)rLFK@c>YnK@qpVN6(_!>#S6-F% z{NRuev44|O91r$^vsu36jH3PmwQv<-B^U(hf#;C-?~|JMlSe|brZg+x%;2zDj~2`bMwUqa+@d0qcR`XTzn^jTr~sc zi)T1o2wLf4JoV?_20McijP<*oup=A<-uBS4S7<1zJv;A%iftYEiOJh*)|jdb2K!_^ z*enuZ_>c;oLzW$Uah*P*8vsh~3a$>eQ__}@gFLL8jrs(BpN(2KhbpV<;9VakE7|y{ z#@n?~!Sl;nvE?)RYZi90@=cC2ir6s_R`ztD`((RP8;wf0ND{L1S&xCDB(PgoiCe(B zEhHO_@kd3hTCQV%3G5@`F0je$OWk)1IFEIfO;z|mGPdAK&K|7#jgKvZayLuPWt;2D z>z2UR56Jao{@KqL!#9Tp%bVK#o7jM_Fu6jr_KX4Z*_Tz(QD}U^y%nV%39H6Grp~~k zJMtY9-N*E^>59%_jNO&*rjQ=PeV$BjUw(!9=7=)!aTGGGsD-D&1I+v?Q5;{cRAOcu z4%x(0-%#fCc}8Vi^kMZ3QergH-&7pq`l_%iDOcNu!{{=pA+mIvg;WVK9ckFQV&dqW0ZLZMMD$ExdVz7%34XEB zTK)aQ3XQ`Vf=pg-(#_Vm_Eb+h787M+zdrFv z=jATBRA|8dX|4w}_I1}_b#Wu?lN>-}O|lQqx>{Jx%JqE%@=%^?2mfDOwa|vVvvdNk zt8ood2P&2~{sd1w#($i)N~};Yx2ATP zTXE*@bMfgNT6bNZepEQ&KUrix;ximP=}$cz%l2w|HnOm0cW5@_X8AeO+hZ4Le*)(1 zA(?1}oP~F!3Mu?`Gr)0FiRelG@cx0G)O`#L8)NR?hQb80YKk|>jSo98F?)V{;XUxR zeOPc&9f74LwlmewOP_E8U0DB=9>L-tT#IwdnOtFAhv_*JfL#qN4wSBMw4Ls7V7Yy5 zu=VMlwPq8W{iqu$cm^Hkf|T%Poj@ZsKkRl{O|1NvK z6zCGsm$yFwxg+66z$ar!7{u{08T3KUZtb{zU1pEVGO)DCFkObGX6!Qa&m}_!JwfVo+Ynn_S9IVBv?~TGAF9WyNLE%m^}~<2Z;KG~>rzm7rd4ttggf}@?B+Qx+!FG0Kvde`KjxQmsP=sin$$5eur*dTG ze|I@bOA_}(ESUMNOPpz<`6}r|jY=+XqKpB|_i+E^L`exnJPd`W1aXay;C`yb4265X za@U=RajMA-t=%bef>OSrBsVN6_W?2S(#uGl9S zzEYoHDCK;Dp_TdsLvcP~6f-IE`jfU;(?Ds z1Uu^)n{N#__ZSLiAZG-S(Bkz4Lu-bAjLG+CLn@~uXP7CMjIhGSkIUdR|JvdfBq|Z9 zW^25fvL&3(Bqg^kgZqGGGpMf!PDdH<{nQGS5I^{eK-iIP%)b!M3oEu`vkLE2u_gJJW71tj{U)l3%^O{?6QgX)Q}_~n3>?7^@$2frIxwzlH9sctlO4!N2(33i zrG_LEJWE!ZN5W%*{vgYb4a}JNmMKoWx37;E5dCp2^nEZ0ssW_UHif2W3z5uJIJUA* zrpv*#l*30!T~$~Oh6KIv{jMsVnX&k&E3L|Bu=&JZ%c?BLKaoDpDmyi!HAU=xB-xP+1e# zcd(cS8@{$xg9>nCwTKo{+V;HKm87>IlNM@l$4i?R59^PU&z(L?=EkS_X zY0~<yw$#@L|13jouBlofN&hh_u_2aN6}%QDH#Q}!D(mZ)R#u&wtZ7U% zuL}MS27JWR%P{cqIo{eF+loD(Dhozh`R)EykoC9wS-cN<6JWjEzPga#>C{(xb)0`sklH3 z^k11LZ|AZoI1~hkQwcX%umFrdJ$EV9k43Re5=Yd=V1J`KI_gD@y`e5CCqmd$lQ1vI z`r^=_=PjDI2p{S!Q4w;!_RfYA0*)5}<0%50Ke{^S1n;pr1uqPw6}4KLLTIt)SJ5!Y zupEC;XYD-r6#N;#PA}96--YR|wR-93-qX>ay;xH!Qp>P}ARd;;tJ^}8>EYwuIxtIL z=*=S3Qt-^_EIEm$ub@a+Lm0u;>?eaHsH{yE@Y?~WH4L7ro&vG6TuNu(!Glnpt2gV+ z_st$zW$T@0EX_U4gZ5?{*Hyj9^`VM2E2|qSmo2SNuBxw2R;{Y4ufY(_A8G$G)Ok|b z(Wvu59XD#)g`kcfmAV+z38PZ6Q^Cp3Xc;3M5-+HaM&@1}hWF9P^X4=2Nu$znB^30@ zqtZV(kJ;}xDt+FmAWs>UJfGyLqmmbry#J`=#UvjvDtX=_(hnS!j{DM;E%gcTU^2Ty zVoKZZnZy`3K~mff^L(TJ-iCd z1FrTfi76QGp_-c}f}N=oFmw+m2K{FuucQt#TeU9Lg98(JjW5RfoBRk+qI=iTLBVrR zxF5@HZ1ggTSc?;B-$4Dghvd>dy(N`v)0h=!pg0&OH+FH1Jl64eefk%ugX`1akNm*L z!zm=!4sfFb2jlk8x8Jx|+YweEL(v^G<^Y_@FYU|gjZV&gST7U;-b>g_6XFX=AxzsL zs)XINVZ*(Y#L}s`b70%-pf%oxESu{vAUNdV6oKCL<&Mv0jb-2>Hsl8(tf4NmY$a4L z3#)ldEMEcAe0sRsm-{1WWM4Eope<7q)H=+Nl2uKZq*d3&E0@;SAQ63737PQ$nwMAB z*Xlv8grPOo7bjUA(b6-n^hw*uH@+aK8)xMEI(&^9D|Xkgtc4J#@ZPw2VCs-imy=E=OYyi zf)^me)rO7a|DeGTlq3BXOt^|p`*p(LGw8`!W&83W%ZvX>svp%PMKnuhN7EvT-cj+14DGt+1Gx-N*jM1l|EGatu8+7a&d z)4*LCV&0YwJ}-aD>9cI`B>+gmEn?rj4u@YWBjg7@^Us8V30*GF`3x@$16MR0!z5J3 zW;X-CB{FGq4DWUf!G3#c?)Fsft#G((k|KvI>sPL&St*WqNfTSy>|i1MPKUko&1OG5 zExtKv{VdwLoW?Y=Ns1MK>ty;33 zYS!SLb>*iiU6D6ypa!Tbq7yJZNzU~YnvF(cLap#qG@j9R^kG@Hgy`BExwvA|kK7sR zNOTR2{yX%4a@Ip_o>hMs$7%uq>5IZf)*Rjn)z@p7S2Ex53Nvw7JMQ z49EjeDx(X%HJDMiVY|KaS9pOY|Wv!Kk>PmO&-5*A{P&Culc>QKw36TX>owu{lh-DNr zKV?@TUJ_{n)OG_@NIfOcZd~@3dB6^djbh8e#;(n!&r!J>K}Il(%$AQurovO! zC-vGYK8S_2PATGEnG$cybo6eBA!M4=->6feaiGd6;Z{_!{&cl9r?vqk1-}-k6dnbfB^cwm^wk0uaaax?s(*vakd{SJTUMM+{vN;8XVVm9(#)CB9_;ZA zu5fG$O*YYQJ+*6ddKdD25mj=fVu_aHA;otWRH=INxLG;|WkSfkp7mw}3LlKGjb9Ud z50_|omy8cb<3JZV5FM){+1bM-T5|A{jU0U1Q_(xHvxi0P9xgYL;{nLvuFu2Z=qn5oBJg#2#6XNCk{A(i zzE#P1L{s_J_u6!UuM}v?Gn&Fzs#UtB^`~mujB}Jsz95ZMkm+d4G>xy*D_Xry71tEL z%cmq7N>)?&f}o;Z?ytn)ljVo zPiX=lAxoeiR zW2z&UG;PE7B^%#e_Sy35GM$Aa!!r89_6~1 z5=M(24u1q&HIaoM!QVq+1v;5nt#U}P*dT*acXrBIVFdBjg9XQ0ZpMPZLmZhl#m}LZ z?hfcq?qVqH;U2aF``-#X3)qh;*`4x*D}Js5*lQJ5-jBl2YVz75$3pd#&kiHZuB&&0 zl4<BmRs{c1_LIp!ETB>9vHeww_wG-M*ydA7nAvnB|#U5SeutvnXUK5&mnn`0qP;>Am zOFpgF#%O&+bQ6O?@Ey4zSRqcFPFn17Q^@h;CH!^;%9~@Q;!M*w&c?nG=V8hzKZoSF zQ4QW#@tXrbYg(2co+o&Bo(mvkV;L}lU7F3!<%tWX4(9XeUQH^OBYa)35)w9rWSxZH z^Y&E0dGmtpNP#%W;GTxxp*<8434SVtBx6w_nSLgIw;R$Zg@laPrI=){!0(Pxi<#}i z7xi%k)`^UB@p~nh#l9eYMSWEgwU!Y|MU^5)48NZTmr*sjl)v8wN!vrxw1h-EE6)UL z@cU&DXv%CKorr_M-I9t#ok}12M*s{Y8pQ8Spq1p7tPlQMQj#jF!pd?x^J9{$@q4=y zX{r)S1jqGpEAkFUQz4X@;12xW?WDOx$g5qF-Rr1Kwkc$iUHJX6lV_4qZD@-TB-|E~ z=SBQJ0KSr{fa_jxZ4XI}sE$cq!|yLaC{-QO{X^1`T&z4Mo3&sN8)s#5Ox7dqqJHK{ zdPIFpv>3m?b3#p(VysX%l8uDFcT}Z7CW+zqB`41%ll-oegnx2$m5_<9!tXypFsi}A zWReekWP=x_kfi+s&JCs`5wHpCLdQB_1&G`V2@@6$j-MVnDcXMZT&aEot4lgO1tqOO zz+W!p5~YQ;v~#9+kV9Bor0f`e-{oj$qHpL@UM8|ho2+EZUgpt`SC^6!?#A!QpqRSa z{v$KGKZzvL4^)y`bt#F`rCcGUJjEeeFlMKy1E( zuqVMMQHbp!xer#koel<#(e`$RjQk_v7BC&5m`>w_c~EBoMXr(=3vlN<+)63qc@EKv z>-_$!(yx`Bi(1|cV#n;K;QdtQ=(r|=`2#l^J6Xv0xRi!daQ zLYlW&B6yT;zemN-PcCA{<#L{%TqrqX3eBmEq~k@Or5ka5+>2a5v!@2lJetbjLI?s> zP#ZHpR+=_=4QW_(^_4Dvc>hSd?#+qPz4=gAMk1$5G0(mm+1MszDWxY?c64x=%1z`x z@Nc|JhW%nJap0|Fy>odr5-$OzkSTPf-Q}|zfu^Xna)}k^aU_FVfTiVi;{oQJTb{WU zXm-6!o+f2iZN9G2-H7#s_|T4Un>70a>7b*X)30$b_O1tZEcL6Vj@9pU8N<%yv@;9a-^@{OU1ol#O z*@D1d_)!nzsq?H;6k@#Pkk(eqO02%VdcFh0qTe7?uD;fKHwcdcc421k1LoJjaQUJj zFP3c%^MJ)NGYMd%-*1&hW<1m_>^PjfGu2Qy8-EKgS-E}$DS8>1Y>%IZ%qdnhgO&^a z35?ws5iC0bn;Ht{HCMrLT0h}@&hyP7f@#3)2Mj)x70V2rtk-)Za;C<)??iq*PNN`m z*r5UlabD?mzO1ceL3v_8ZFZ0SUBDcIbh2f}mSS}y6@?0(L0!ydmfPxn6HGF=vgX>IAccuyJE1f@M>$+T=`Ab}P`~wcS^)ZNttIhSd&S0%Z$@ z>K2*d=)hx^?S)uhS6350L4;wV$mRNJnI2`@#CAVu;8>_bG@#yhmc_yyvP5mmJv11- z_XXiWh*JA^!H8qcvCNJ>AoXB*h(dd`$%AG@?4xd^8Cr*W#;ZnmO`=1mFjheyJAJCC znAOGa2K~<#s7OO&RrAuVgy276BQ%rU`Tzb*+aBf!7|(OP@558ks~h=Oy!zDDZGD-p zj@9nHXwUo0*#;GUC)SXWS5~X^=@PLIYZ>tiin~3XK|ipOKmg|gA-DBmZ_jSRvVKFU zOss!^t91D!3oQB17iz9Pou;3B(r9non_H3sNk@s6TmUy!FN7oFH+c3 z2RGxYMvsS_4dkUnVoA%fo(wF9@(f>3kcY2D!V;iWcG+~Q;M`EP#+&lBOY{awvK*u@ zLO!;?RWHZaE`l`ii5_#B2P(S&Dp*msG=q+wPfG)+XQPfao5N!A`Khuc}( zY;7W}Du0ie_ZJ2l`er~=3ffmG2hH;0eGaLQ;GUAq+p zzC=#^UK(Nr54(Ky{`ebb-wL4VF?Ki{1aOfs4u=<&O$63234u+>3hU_nj{#mhbvM?M5sE%<{R>&bhg2v>-;X6GJzbcly+UJf5x2kM*9bcYPe{)K7 zE@+pAeCts58cDE4B`_o>LPeq0S|gS!U9z{^?R-EZVEr&dQWZO6DeXEEaQ<%@Acz6E(_nm+UR%!pU#N z!viR{qU2^4&nX>iSCTdS4qb|xo1t~-F)8g~FzbEW(Y`z@)t6_v4^KlX{q8iB($7vq zF<+g*KT)vJ-CZh;xP95o9)|b5`MQIo)#}?$y?lYoMA46b^L46J%NCity?A)1&Jw^D z&+3Oq94GE$vK{Uk#*5E7kKu3;5}9736I0HmAtwr(ky?L#BSo|NVz@ZO-^u2hIL<#K zD5rn@r<9OPG`G~q47gmfWNl@AyhgMfAunx-uaa;72)3@izGhiveKJ;wOKdfGsa>ut zMOe&@qo!tT_Hs$UD^XqJipu&roY!w^XsE=!HQI5MLCfbNZc7{o-;3zAl?mjI`%I8d zeMb_Pjq+J^BIzlpGtDNr1b_7L_`LeF-}}3{W*LVzM|6mO^bNWMHN6;*zluL(PQFNI z@DeiU?>k`;GT@(DMk&mvoyb5|_3f*KE4%MUha9~JbPgoD3j_1#@1YCq#SFJ|V71I_ zFN+@Fs{459rwmWPCFjm{T|puAA{JXk5Lk?o5tr^xA-qr}J0VwpiBgBR158QBfc6>+ z1GT6V6iZFpso9&zRyW$0kc)O`%EM8lMKCjkkY){L!T9#1`2`EcQuDL@>dw66U)KCw zePqjNUN?oQViMa4qE}9FRNLqz9N7dhUnk+rMIm&O3X9N500(!VuwHZi3ZOLS;)`{2 zE?9u(jMPtr?%9g|$LazbVflW9qHj^B&{St+IW2-53PCf+XZBqDYc2GjJN^%8GE`ZD{-QJl%%2FVE95DvS)% z+pT8iYZ=xs;E$y`)-X(T5>s<)OAC!qV@r!ILd)Q1q!b-q!RjctGh$pj0g7==xXc*W zLKxQ)B(+II#=qb~{x4G@43uiw42@X>HP&Gf4=V_$6eqBHdm)z)OoafpNFvV}E)KLV1{ZNzqYV9@x|cW*G>2SH%cQfmeJ|7nqkY z3wtQ=*bU_>&T0~OyLf%`u5fpXT04Nfqrw;j;#;d{a62Rrpl#Z_KZR*1Zp84=H=1zp zat8Y1^O{(2Dq`j5V^@2J-jt(WiD}cD8#D~U2oI+$#e9S!OziOrLt~L|(6nxw{Tw3J zRq%E?$kpDJtLxUn&DrF(wKW3;$4WESc}DOsWWi%UHfhQ?!^7D!9^xU3WSft8$^gHS z4;|g0bi_Cv&{`6o#?Zy+roMK;7_2b6)?+;2#g=&3K4OX5_e>z}&}R_)aYH+4^Z zTW_I&2mb`eKF*H`{{{qA%CA{TI+t>BN>)BfPeE#2Y^;}6RI`J_&8fwgLNtEJ@Y zsmRN{#bpZK3u_zQO!C-ol_6ajV_|R2o4Lp`qnQO1dId7%^#URiYGCh&2Pt5h)&nmP!nNKIv zcV)CJYEgxyLzJi7#@eFNKt}KoN|Vp5MG&Yy^E#?=IBhuA-<0F+B5N@83H|;KG_9Y- zV@2J99_^p3>*R8h!y9kIz1F2Xbbxbvn?ow9Tp87Nv)Ygz&$6nM43d0WMYhU{ zF7>!YF75!q0xJY!%)DNTP@7}XPSP;aKu@|$pGdhMw2vT>ccbuV$XAtH`6u=Sk(_f@3 z#$i6>s<8YVC03+bEFB|9LzkE0ren1DY^KnzPtlmq2`X2Lrr0@E;YWpN28SCFdEeLq z2NFl}Cm{3=(jWzS*Hp^>c8$yTp&iUA_9KC$_x3WZ(5M_D)N?mT5<@jg(|q|V>FH%a(ZZ)1Juu8vQ(Cv#KMo(kE zigcwxIf65hqinjP0=+p0F4_hH?#CE`Q7-aoT%HT#B=+O4p^(M}Vf98a0E2m`t2Y6q z{i^1IONbf+Etn)@ArMV9Yk@=J%oU&}a#CGpK|8^%99{tsoay%Yti7B$PP3_rp>U1Y zD6iWgb5}U}Ar{`xQf75N>8+7-jT zJ0G*5EGUd21>@f6K`n2zrx~A#k|uRYE5Q9-9WyJG z@)t;^18fe3OCSg75;C~Ikru~p(z02yxwU4RVywis ziKw0EF`kA(Z!1GgvJGcbRaV>pWm$>wrx7$E;Wr~3=LAH+(%j&0KANNEX9j;^bz?lo zerAPRi+1|PwL;>&A(&GEq9Q{zri_A&jLTf4A*bsi2LZ!EVuIL{$5Avr5_1|MjM7|o znsaaj?as|`O^1_|l0lh$h<+XCNR{?XZ}3}FQ7XX7@mtJNI^}F&8Zc9Bv-65M8iVy0 zmFPGi;$Yzb%sHl+`=bw|a267Z~-&UV?uiN1i-VJV6r22AXjoqUJP+GozEEHN}L)Do2yWnrm>Np+=}wK$NP4YMyFgLfMO$ zVwEj%C4kB*5^!pr%9&k1N{ZE2u0n8OIZmNZLqLV*d<0HzFp8?8vRR{v8(I=IibbD= z@RK4&W>XbTOCY3}8NhYqU!P0oPuBY6ippjk2Dl8%vihc_nup&M(UK??CF&Y*AcUq` zOoiqZasN_cO`;`cN|=n{d00B4A^}mJ_%afH38jL zIeKM14g=|E!hRlRBBbg(#=UN{?O6rluln5P2ALyh_$eD)YnucaD3*l5)N3wsiq|uZn#K5OJjuL zh!Tc)0`080YGA`^)`*~P#e&p>zsc67=2HWH`9;gA&j?k*w%L*C!$)OUTG@CiqP6da zqqTBHO;Az7(OgprHRCB`sI#uIwkdcASl~3NHnh0*FV1aFzeTU9$ymWIeg^!ZahmjJ zhk}FWwcx?Ob8|$lD* zUP`35va|-JeIB^AUA=9ot`(_VMvj(4*VjVr(Ryr^M{Ct!!UF5hk1ry*-Ta&lw3M6l zM?vW~A_ZFkECq1HlBG&45I_vkoOoz4C5YgdJ+`QN`KF$n`L7NpOG>l4N8WD*3H1PuDm1c+FIgo0OGP?UgGl9id=Yah; zNMQusz3p>p^Q}@8d$?L(6fN108Saazb;4RM6ViIZqaswUt2)||R+}_%f0EDnyi94$ z{M=0B`C+D1N~aOKO%^P5pMYLJ3r!W3&Q5x2diph^@`p8zE0UFo1ZD`3WLzMTYWRRH zYR5@jyai)4UUjF^UGioO29+2nIiG>|qY)u@^;P~xRg>j+_h`D2C1J#pYOpuss3B_2 z`{1QUs5D=Zo+WC%`KFkpEq)71jFx&xw!ndtkJV^TV4mI=8ud|}C$-^l`U{Q5V876o z+7C4IHOCLMX1B~+w*AX|`j{#^voICLa=*I^!#WS#Zrv+uy%|?GBQ-4fk`F5O*vYsi z@D_HmI&2n3HzTQ5w`NZhB?h%;j6>bPY?8Kb5{qLCtm-%bsH&A_mm`TOTB|$s4u1ib zjm8X0SKCdy`Cq%H(Y&u+(`_SPyQa}1U%RH=xW8b z>qhu!Hvlpf-rrFO(FezM-verR6%VTj{Vfc0UgYU9-GRsy-ezTo>7e?h=&fHd;3DocJ34(L_(tSF= z3ZVW96dvZts&sRKdHr7d3DEW(TR_#%RcYNGIoN|%ln=|<{YnCT6)|S(p7rrk4TqFD z9JT{Jgcrz3#0iac*wj?%De(}LT!Mqyi3xQe5(Q(l;&NrD*@fXn_At+JIuIOGmDIRd z;G_Cv!Bk{b0HbtnE}GBLJZ=f?IFrigoN5v=knCwCnH0YwM7t<}oH&^wd)wBZ30M$u18?FcXLfF9uURU(+G0k4!w}yvL0Dlws z7eY{W%nBV|F8{D^`^c)w#wyGgtM$zp3HAJKgtDwAAq3kR zCX=REO(RQPi_S&N|CEyTEivO%Bn=& z3aky4rmL%l-Z@c@N^6Ou3e|yHv-HZw%X3(xqyLL0P}wt$TCDWa=%p!Hp+rArrRXPh zfRLiAQ}4oPz~gAHj~9UH$Y3dfQt@AMg~dd%mLpojrmYh6Er)Fh)CwWIlLO#)yAtcxftNfqOpt*x=;Dr zs3tmr6?Yp&?*uxZPOqnutY>^uONb!TKae%5j%>gb(&;2YRWE%We13WEwj_8=WiMaVQtA4`1U!Re1``q|}pzB2tYhnZqhyV6{n$=EU+{Hi@p9y{eII7bcIuZmdBb0A(##|9V zLbVCrCQ+s2e2rGe2~LuFm9ozO_HPiZVxn#i|69t3veigciq0L@On|g9R{k zfHv+z&T5i|y(sl6r5d@8(jGU(c zV$MByT%oW|T2zG>Et+ZkFX<`18@dG;sFssSs$)20xr(guoiKj{z>8WV5Kiw@6J3Qo zq2$nXz(ngNML}Kd>lk&&*swWV3tDYF6GxzF_FJ_cVZJ1&COb{7ZA?V0%Ho3EZCG8>-x!rK_w?1riA)>?XT2pIbvZ-JE@2c21s z-}4i57+&EjKztcE|BT&i;9f@+#LH<5`uLBfOR7TZKEt$DFtuVf4`?WlLnv17l33V7 zSJG#kXll~AKyV*_#^JZ+^B$JY@EHin%W+ozqcWo-jN%!GUeWlWPWi?^%gX&Mjl@^J zJR*Vkf-K-n^(45V%4aR{DC6evcg5A!r~A#NnCDQi;qVXmR|OG@o-apWMt+UpMb@Tf z|7F=?ynbC)EpRooW~#BslRZLh0w? z&obhMg)kgm3v%fe&3AxBod)c`!Rz?b*({@V-iP11K`0nM?L6s%b+Lgl@NDf_wJe6{ zF!*Ls|85JJJt^)7yHBumrui8Nott zU%Nh{ZG16qW@S2fC>)k>(oYeQBqocdMN<);eHzf0ziChcSND3)z|g3CY+a9Dr<$q> z8+CH_R5EUiBxgVMu}qEJAVcz{|c$}(t&fYIBwJ2M7%SEG%q;t}D|r08z@t_QhHWsZ`uRtG(V?qx!p ziHBud%>J3fGK!24*cQi;UH0~2**2UcTjf1S(utU9&U4Py7%PA-a}kjEm`QTJ2X)Ov zflMitV*^yr5;CrARZC~9!%#@&basX;@Xqi^O$ zkU$q*i7Ok|hEg>_R;TEOBJ8E1X_$9}#S2XXM-!zLho)gmL=qeM*hgh(8cfuqbU!o= z%`lRfs@NCEh>KNf@tv;Kcbt0|_~K$58Z9Ya*$}I*Yh0F0tcukn7cZ^Dga|(>n<#PK zd{Ui;qSScZvPPWG5eZI3WqFh!r>iKFQ1Q%qJr5<(BAm{mj5@~>ey77IKea^_V)n=Z z8ckn`3pmPG*eS=!Fd(;;$gF8nFyc;gorB$m^MTU2hC8Fre!`C~IlJi}jHCnG_hHq6 zT*N`iot=hxv2P{ynVR=WxO5%}=Rwg?4X@Rsn#U6Gd*Eb&tC7 z8-C%Gsj5YLyz`f~T4GDIzn=qV8pEo61_)xjY3w`owCiO=GsX2j!q`I|g9N!-oa@W# ziE;(d_pu26&;U(71x=dLfSmJ2aBc4t;8jZ2EW=JJt8(YvrR$KLf@WMRar(Ev~@i5G_~cPm!?ahM0^x>uo{ z=>9FX0j~%Hiwu2iqNOHIv{Sl>XsxMkR0QSSt(3&_mS#zyoVmrUe z)re=gtzOmF4e$y3=n;!ewYUdtn3X6h(}U|EuCow_Ad!5L8LBzpF;R^OQimBJwmG#y z9g3Ro-nyheL2t+>+BV`t2W^Uu(9>Ht9 zlQQA32xUWBsu)J=E(Im`#J5GbQ=Rnfy;xZxF`OPDuG6BXMX+~-5^)(l+U%q;SqdMOGF#ht5i|L`mGUdJxQbL6-E`I z9RYPw)Pj;m)eQTEo5OEDVQMB73El=5H~K^&n;U~qJqR%;tJ!~I%~f%n(^-#GNOrz@ z=C8Ra2M42ZtOzG&Zgy&VV|yx_l6&2#%RirtNW-cv#HhAHCNau$S;+UW0$E@A5T-(y z#&QqI`DlWgPlrUS%20` z>MD4bhO?av()c?=W(MBF8@62#A7!VgTzYLEdYz%6Mpx?^MXG@K$0)lx#P8Qn?F89| zphV@|^tvG{$R6V2b+B%9?Ctht4eo1DpY6Rl?i+Ab*Vgt-)Tkr!Y=f_z4ukiip?2FVlBuq>y>f`F zx982zqP-rn97Xc0R=qS?C9_m#$(R3cC<Ncmd}sW z%VKBOt3x_Wi9S0wE17!qA0W0g{c7PNlTJEG-Wm@TsxNTrP8R{($4?4P2$#m$|!5G@zLDR0*mS#o-d@0cUVG^C#F@OZHXnGm=>M2T}FpOUsIb#6uTgxsA(ivt zbgt(?l<%nN*GnDsxzN!l#eB0?JAe$;szXr*@@-tAjHdr5T6Lrzt?GtUuIlX4ABU)1 zT3tVANEg=i>iOj)Ez-~u>+lz*4jt_6L(tdm3i{^Mp_Y&!9}9VMEkc*;;t)74=y6k_ zCW%n~%bTi`jZKX;tR&Wt%8{$6vU>BFKsh?jiDG#P*KYOc)N(wy zNZ$mPicaRP zC~L8UqN}+NEUJ8w(UETE$Cl)ejuoIhXepkH!5|2GI`swZUq;i|zc$zfSRCG)&xJ0A z>>R_d1)N+g<0|SUFlbpCR8VFXXcCl?g5b8js~L_$^>n0i9dCK%u%0Oym9L4V1|LEf z*^3W2948!uaHIC~t*m-+3^9%3mTM{@*{M=9R&&?(U`DE(u@LQ)i6c&ze7WJA9X|b> zpA;7M=3*A<7&QACe-yKi${!7%lzf9z_D+HMKEx^M{2$O_++;M0Djj_^eL9XYQEJCa zWt5t9nFJ?dS!8q*Y)5Yyv-JZCE4l@?1_r@{b{Vc7pwHO7GvI@1f0Du29*Cgz{0%s_ zWz2zqGZS-eZK{UtDQr4>GT4*ebm>IENYw`k9eCrP;lQ)$c3R=O|0*q!8iJRk`Jmjz zAiyT>~sllnr2Slk*!S!*Orh4bMW&bI@*h7Hb|@!Kiu7Tcnu|F3*IJ;>r0RT%<}p9IIB6W4h-QH7^v6ORRQ|5BYX?`&#q+B;Zjteht^lU~qm zW9(ReS<91~Os3=;t5^5q9G=F{d>uY1MN_Fbfgv@`$NiGHr>HMVR+QlVRI?*g*2vt# zoKuG4r#vn~ccq*QJdd062q~WJHnCwvqw_%f?O*tzD)-Oz*ZD#%sXdj|3lfWgdByR~ z=OsOME_IPu9AL@q`=PJ`1a>8HPiDOsse;2^#X7Pd&z++h_vzuol=9eiTyEfrf+Q~E zm=i5*JQ)Is&!zSGd^X)&$P{kxmMR-)nZf%HkS2trX8%OGwSc?PN^bN z-&aC-E`3hY`BZ9~1td0?ws%RW(wTo#XxWq%^)CkY8eq-Y2PK#vjJJDOIbkFGOF+33 z6h5!)-N&p3`YEFES!LptOh9E`qL98^((b(j$4W9D9jMK(kXIXDVR9c14+e{}HQ%I;0~RJlb`#{%OfO}mVckNE88*r;+V;=E@-n_+Z=#HHDV>wzIDs$Z@U;)bMGY&IuZP0JuP?Lwi z!m&)i;K?#zQJ0_HKjf7uYDaL?BXOOX&fXIWy*f3AaDzR*(0hX7r9!yOk3rW&ls!bF z^6jafrk<{iwG31xf@gwKjd7|cPQofiqe?n5?BcDl;7j^VFTvv%MH-tU>oi5LBMcKy83f^tg1cKiz>z z*yivdSVL2CaFKlgKzcfYy zVWJ`$j-GMTaZqbZF(;|aW{l=oFHWxT<}E3zn5-0$GzhtpgQHwp3~NS`iE}K4XSImz zXzx^^Dg;YQBX)h>L(-xQYaX|(oUL&JNy-Y|DRk%xpi@)AU_;jm|8bT%K#LKi+9UY) zXnd|Sf<6xD9Hg|hWh3~xMobpdEM7R|+O1LoX5=ad+)7%P>FRJ4&O9Y=lc*sz;HZln zRnkR>iye`*cd1Tv1e^uwcLYvdb!ON|k4F-n5}{$8%1gJz(NxV=cw53t9Z|~Y)2ba! zC9K1xrks78sn(GtX_UGgR7T;2c|;Q@5cW{%HRf0%0vyLmmjw=W)neYSQl9Scoff&; zA)z0~e3rxaGZ2lu_LKJPZA}q_Gr2ZUxRr`Zw7Ym|9S+-->CO~9b)v7DHi8F&D|52e zIT8cp@C|q0mz^CYw|4t){&Yo&i2)NB2)92?eiX{10BWIM=_%{Tv?chGID$b*pUjn# zticyR+l)SfYU^Yw&AGsH908s-Yu)6alcn*_YAgWMWhRk;c~~&nGwTvv@0A<-}P?hhp%UHS2_;7y@9)j zwWxMi4I@lBF;^8cv4LV}+;!>p^^WaxjxCF#I^|s*B}n#W+2D(yT?4D2&+ov9RoS8A zYg`Y)ZJI#4V0$P-x>1W`5>lMGeAS~Ao9r#1eOt?m*ySB%5?N#ZwkFC$cZIcPxVuxM zu^+d-K8?q2RLSnrXf$LqUMx|_yEQTgOr+}fYC>B&g*gh2<7L`0%sRE*r|BEgSwuCf z({q#`Xl!;vu3@cb2loTN>_9hnNoxLGnqS64zc2h$6X23Dxk<|6jOW)L1ew#P{$wGq z=Z6pbC>PP{QH#!{yY21ZC!*rp{TFzC4cbb-ta_|`8u$$G4XO4@|91B8w5)F1Eq)Ko zN5PrJ@PJ5+((&hTvd38whuLBg7wFlZ5R+}*Ja7nM~GXLpn33OloCbu2Z0OT^G6nNKRgW^d>u3k@XPFUBnPnWna|E zb9QF-pBe*Kp6W(eFva(h#ung`^!L`EOj7!SdX7Pg_0Jlw4xs8Nw2JhKCSm^GyCK~X zp}h*)ktiJ}>hbhB=4;^9aY3*IX!g+47@p2`;8!Q&JRRozmW1KfJL&rx$iMcSPWW#sWQf+E(G#u#t`S` z4tId4Cm>y!&NN3JA!0Jk$+Dd$8&H2*m04Mspl#Pa<~|9CofseOHJ&R04B@IcXWtE3 zmcv>haKXWFTDg3`UIB(~WXx8ZkxB!Uc#PuGr?$9Q#Mz!6G%=^gQh;=lshUzijXd-L z8clOb(o-q!X+R&ZBri~y8Ne)8n1u>66PQ)NXz#7RFOLNF?Eja&cY(9~s_J~tsp>p{ z5S!}Q4c(zrBq0fTG$Dx)9-~P=(zJ9XZFfU(EIrh-`rvb|3~MDvn;! z4|m2HNAxp;ii%@Y?x3S{uilFzdKoWzaYV;ae2fP-M~-s#%FO-w6LL2aOr>8@%^Eqmp&zwxJSo5Q!3u`16(Cs8>avg8gQ0$LJb>XQ%&8}%%7q+5 zF3cc74O(uyBKnI$A6UOi#nQ0(4IB^K_rLEQ+dnniHExvGtRx%&Q0sct>enyrXE6Pq zhYEvfow4y39x#jzjf7zq@bYf=`U5}&~d6>RWVN9#$wx#bzP$$ zs#ezIaE4Ie?)L3!aBu1=N=Hw5w%*$zQMIiztS`F~b?vu%$Bx+U!EfBOR3?cz7^q%8 zsLo;&^6rY6mOiC;9#?|ud8%rwVRRyiDrv$ePV7%p8P4K{=DKRl@#lcqr?Npa61m(~ zxA!hCuI30@3KZcr$6A>gL7;slQv*XGUDDx$ZtbXlwiBP5*?jW?cO{%VofF2NrnF*D zmD}oVff={s9w+A@2NXWH6X~d@t+hb{#Jyudgow_vhk6W!*hS+Zt=u3^>_1vM$Dq>DK)xv-|SKu_7#~8w6Xsb zS*MpPuL^!A!h|TR^p(MHarNZP@`1S-0e;1S<_^4PsY#5gepY+mJ4SO^OGkHX`L4P8 zXmgZAd^TSJ#YMN8+@^z^Hj*b++M&~82d$i1k_aR)@GPP39jm8vj5$AXqCIu@srkux z0*Xt=1CgO6MY;2piB)~uFE0o6%#I^3A4@b06mzX5Ll;DU$PHroCPF;LQG?yhKWobt z8hXp^$@K6t2I^qPwWY@-jEhY7B-9ML9)Y+lgm@G1%7S~f<+F?rDye>#OMj|=i{_1t z)aCE6uSur<+OT$HVNH;0hkp7J%#=j$vMF9&wnr_R2FN4Lm&yC_I-U22I;x>Pb#>ye zz>UrCTrHTt16ON1Aaphggd@IJ{IuL5^6NEG zahl6R()1?0Y;iEIq;q|&7;qwp6QLS{a3Loh1 z!8l6@ooiALt4lONQj{)+ZkV+2JkoqKVaesk`Bn8FX@-$@M`EBgq!41LW+|8V!th*v z6p9scKfhjn$#U_2ryfb%CB*$LRv**n`Q2k2O~vg*97uV{X$a}GwOk&nG)U?$jpL!* zdEc;!Bh?g8~URmOmW*pt6Q|SE~u`?{{Y$L%{%Uk9D!G& z)=u0Hk)XW!?ua=#%&%j2M#%PNPc?k9IX({CjWifTB0m0Cptis?KlQ zKD!=0J-2UOU(mCbi+y@}?r32|DlHB9YAUV@slVb{P&QXw3Qo^)`b`&I>i+NA)!nmE zn)MAXH=|lWJ#M?3v1!29(O375F&evDA$pQ$w`W%i$5Wk!c6s#k)t(=_yt`52TuJR5 zCra7Qnk#=!(w}2E$N?Wtj4NlRT!&dvb;7Y zC8_hW@O=GlEi-;|>P)RQCoV%M^xEVR3}cyP_-{0@ zmbi$RjIdB#i(>ha{dt!7e072~bkS6izoM~R@E>hzmG-t~yXYx`XfAsQLrETPUI!!Z zW1n4je0Hlw-ZJ8{(J7_GrK3|yiSwaTN=efquFSn9iQ}WSEF9OCEUZLMxjC(|=X8rD zqqJ}oOKeDJ0%%BtYv8m6nCCUwvvYrVoblG9tKMPVZjp)W12BnMkrPVJR-q|z@7UAX z(G1*grAdoS8lPljYH;?ph-}I^3+KVoMu%#S#!*Cc)ynlEQ+B4xrY`9~U*Q-#Ewphf zTv%i)Tv}X+PDb|1VOEo%41FJ7RcKn)}?HRSdY~+h5W5*{EsU$FnAkutVJl!LrrITJp%Jl z`(~Ufm}>H{)#RQ6IS9bCs-ktND4&+F>8lKx@&c<4r(n!D=AZ@gAFL>KdOg&y&l2-d zVg_-z!|0syjdHFsmAh;dHR*>t3-SjrCKsnMrP{UZy2@JP-?G9g>e^%eygeGL#(jjh zM#-7Y1Jxfk@DlBuzM6dtcDm$9gQLXv;_zUV3b#$VgYllwFnQJsD*#Mu^X0H41=BI# zNFHV8k)wRQI6Xv#xL!YEixg{>7WT0JsUAn80tsxNm)!@H3i(pSx@sH8c(00SsQ-4V z81=XbM@I=F)3)DOtghO`6P5xTIMZ(rsCnp?Ea%2v2-V8gcs8oVCD&HnleS1QI4--P zwqL{s??f%NPd=Xnvg~+UXmN4ICRV3T9(I%Fmds1>+(U5s-o%zawnkH3V$C0FIM6MP;o=shBQ`m$=?umK|>ocy(xum}0n*xF)bC zPOYA_%X_BkkI^ilEsCN>zBNX{?>d+??gf=ucfFoJ4>rB4mD(-Xva=uQSRX#bHZ-5U zh8jC1=+MdHXVCAAtAn)Y3U;wJNRO`Yi9>m*Lq{@7-1#_d6FUmr9=z5Nj4O&oslDP1 z@Mxt@Vw?pQsr1k^(4b#KOG*N`7KUC5TF(o9y|uF>rrQR;rgGJ;DukBaO0$ZQb?NmQ zS+SQYaA536U-Kbp52!ESd?WL>M8niy>hi$MtG~KMp`|^Mc55}fLI-9Jt;SVRX?FiM z>IZK~Gs4U1H{1_5M+wPPL5s~t-VBPNebu8nT&pfseveSpUdc9ogn6~@)S6y7?|S*8 zv?|xv0^j(KIUseuY@^(bzuSXA8--7TKJ;QW^Znclg%t{(2BbY;EG)G>Gw{{=1^be~ zmTpYJzBI5oK$Oz>*1*=epxj7DV&WiU+{KlbRF@S|=(sZ0_TZHd(9ey57f+#wl(n07 z2ELT(K=h9l^}RfJu}-drwRbnHchW3z?Uh{DzDZr&*{YGx$3ZEZMr!1sHy1cuU69@- zq!*BG)V>%KA+h+y6m^Z7y`#Z2c*JIg%^Pcv5(_mQSv zl_0KDjKI)EUy$EDgxrnB$N9JJaJ}#R57(>7^WHIUE+2s^iAq(D%G3@K(ZIj)rkk7g zMPTawT*!OJyc?1;BE8cc!p>p8P}{txBaf>=xe&`B zYO5wQ(;apo;*MAy17e5Id!}}dp>>)sQDb$NB>IHlMHw5uO}X@H(_&0ja0Ys7Eum(?NlUm4(7E|>@Kx0^YKuhAR%qpkgS z9=|hu^)dS$EBth;o)bRywa1Ph7;Ejj^YG!ldgH3yH~StrdH}l$2U=#2+)~!d&Frtf za6<`_no9n$z}KY9d^eBK&~DDn<8}Nd2v56v1SB-l^(c7K9&oQDU{7tbaGPJ)>-%_& z=N&ky=U#=h&CX|haiDs*`8b_L7zAN`o+oEH_fkD(Dqfi@-xs|qFpHd0p>sM4}GJ-{Ait zVpPgqpN6U8NnN$&kLGhZ^?X)6XP(|&sT1+CC;N)Wdfr-CYz1}Fi+gy5L(V05DK|v; zN?&>_{Etwy$+nE^1@Mplf3x?0?AvqAWjgiY=6h&s>vHSedK(vg^Q5EG64_)0J?&Y?Neg-AN8Xow`PhFR>k z`Hn8re3YLJ6oy*ep_-K%Mo2Ts?u&-!OI6`&&`OTJ2X3h!Bi@0RYalNKts`+BhhsfG zy@-t?tG3wJzk+eIJfq`}y^pX#nZ4hFwq`*s?c50q*qf2?X>)DvDsaiYe;A?Tp7 z@Q&tN$SyT^T|j(#6;SMT3MlU$1r$3Ku;YoeS``B}twp{7ndTQWCC}Qf39E5nFS8!( zp3HFzXXeE@Lg-1FT656=rvFG2F#Zr5^u|)}4AXsvi+7rb0mJCf>X1*GoHX?c>5>$m zptN;!KOLFU>ZoTG)f!#ZC>Cd%*xnr))#@l;j^f9>HF{NTeL}aZP4Z!TdRl|vy;`155~kNGZq!hL`P_K!EKlzv;K@Qo%fvES#( z9WlP2=*l$zxJ*;kKiB+gSltiYpU>V`K6t+hcbL=Xnp%Q=IgN%FlnA9}P8}v-y2ZG< ztod1dtVLI`6kZr0Z(|BBw59-54Z+YL$8$iK*54L4ZiwEh6s+*-y|!wyYq;6g*E`5C zL0(T$3KIdEJ!&M+G)+qDON|lDtkTanPW7tlT2)?ZAH<}@A+RxUcW%pyo=umr+ewS8Lm!Dn5&y_12!)%j7UkW(@ohF_Ola3Z|MpVv7k?)B2X0;4T^TFXYdc-O+4F*)ED- z>X7|+)_bscx9&ClzQW3Yg@h|9DeunWzTdcfI5h3q;vU@RVQcYKKEE1#*o3_$@~$rL zH||%&mDU>G|Brd!pS-<$6mjf89Wnd-96l%*Yr-w@IpbxGl)v?6_i-DV$-n848qe=n zJDc#mG+`yVX(oIMW>~&#UTGS7z*Bk+t_;=my_0^}X4R3ycOJj%o}*)}!v}8nqLW7B z50&tPKt-gW1glUzrlXdKBFsx(nv=SfevV10ymhdy>(zHOwU?z8zk5Wec>B9Xgt*-! zLfqaXLO$z^2zjqFBIMnBM98Q2h>%bBhr0!qWoD8FRqC-q2dAbgyoR@`>cg&T{Nwh47QQ##Lv2Jz|DW zx#anGYd9HFfkvCu;;d21#jGJ%m$G@+sPP``k!zY+xx591PmY;nSg)Y(LDYCQNnlRI52R?gaXZFIMiit#DPi)^{x0NsaN7e_+q~IA2>z{os<|q9t zNROL7Q~FYrR<_xR2V`}Rr!RAubkzLZvZV^ZOPmL1mU$>(e!h^2ROAJoa+KF0s?0+N zk%;ufgXY)*J+@big9IvOhQu?6!EHT#+>{E^sDIn5*{v7nu`-OMht-qe)vm_pcj6OY zi3GO9)X3%zba`=_Z*(JD6>oi&UK>;x7yq0Zw|&1#zi#5^zs3?Pnpjns zjUB6TAqGdcg+)!qA18BfN=Bw06={)Lt1TaHjuL-tZ~Hj95SqNe0l}ad{KiMf+m1c9 zR46MAO4;hP>x$+T6+c<_RKP2|fi!)8msDgl)H#OG9PUH})yNmYWhwNV^*ux?%EcrS z=UnsS{C1!A{|;^y#NP#}wBataRzr`J6(X5$m#E>R0Zs&@+)>mTU7SD z#&l|$YT1%#y%`sn$Za7Yc}{k2CVaZ}weUBS%1O8e@X?RYC0`m~pA4JY8TDNACcHbw zqm^Vi0H(1DDJQl59Yk6x;W3M1chKbWu_6~+yrVThrKQCyJ(`Nk<0DOb5#tb#N|YM7 znkdS}bWmErVbnAz0>mQb)>9c3cyV@iCEii1jWyF&{Ci@6`QCDxk$~PqRxCCBCmB{-t*-zF7i7|4J`q8qXqYMd>YXuvc51&fivz2Iki?0VnsG zft;gYd7&g#nNLacMmvkTC_hA3K~*L81U`n{?XSj`Kjv@R)7{=hyy}}N z-oC4240v8VeV8Rgce))a%kH~+m%eyrK`ezLkowUUCz3bzYcT`u-JxanWA}JhT3t1I z{v1Xe|39YA>28;0dJ)W$r^ z@Yl!;t)f@hx$Pegp4@AQS$n<(Pt}{4E=uHh-;S5sEiOJqYrQqZ>ae)<7;H@jf1@6s za(+kP@?DvkJa{}chPK+HM-v2($*#8Htv=<=G4h<*e^k~o&#*aKqr4sw;oZlYjRzKa zy6vnVC#GsUxx6?rJ;epw%yeh1{~g|{gZBG7d3Ws*|9#*}|6=j3oX7i0{_Ao^KN0w| z2sW`DeiGilJ6?>V_rtJWOU58R0OywoqMd9>>xTNjsA^!OM&bOgTILW%(HNwSS5SS) zn_h`gW}yT#7vi1wQh2H^`m7zIwoZ-?cm*1hy+E~XleC8?v~l+l~Zex@XrQ3{&p7$r6@ zsi>To=^Tq%_8upt`I&5>fZ5XcL3om`twbgd)7Tp7W2sqFVS~rsIFFJ?j}}25vjLKf zWoThlC6j#(RmB;qC31`gXuOQnSbk^oqZAI0Gk8DT97Um$eNW>1zIzv!i>G~0yv`BI zI5_X%iwecM1|AdI8R=w%j+mZnX)?7F*!^)l{@K@(h{SNLs+VsEKY^ca%ct!6!c6&x zZu^ty<1b@lr@d%aDMWvQ)Kgs*me}l&84pqjwLg8t+3M zYN|+eDIT?ZY46Av5R8r-<<}WzLE~KWR~Y|27DB11`7-wzMkO82JoR$&x3QC1MCZ16 z?~9&8eHOSO_-R1+5)e-W!Y4EVe2k+bp;G@F`kyhmS8IiuF2ZxMipdC?wgTU*v;v$j zC+=hU%u_;bq)K7a;UwSDDtwsE<^vj6d__dvqVVG8a~hx2X?#D0iKo`qonA;izgFm# z#o5(X#G!1gF@nrTcW-<~Wd7wXTR=f2CJbe4Ueq(#%Q}NySOse@=yOllOJAP$R4%Bz zr`s#CyuNR4W@344W`1$`!6O_NY0*Y=i#6&fq(-aEc(zo80UomN2AL~(O&cLeV2 z!fI8u{RKaVes$zd)S(X-{2cm7;9B!6K2S$F-szd+y*_xUq@B^mJN$C2H{kOhseB%B z;d16|h@uO&9QjU&j_@98k(B?jNVS2GOw|FAp3FEY$W=!SPnp&QUm#0Lt z0KOBIK5xM1Z_3;_(>>Ju1s1BKi_u!6KhJd(MT)R2Fdb??Q9(g+T}k_*>MN0^5i!-< z&UmFWzArKUg)>GI!=m&+ifl%AqD9ETT6Dd!;*KF^`W#VQZ-gsR$!E5-ytc#MpBMmg_E;TCv)!$megleAui{MW7(Bo0=Gg?c3@=xvcTh`4iv9kS{FJPfIy6t9&l> zbhJy^($;Z4)wYrNCi;7LZGYm|Cv`RHk1<^0DeIGJz5r}sgzF^UX|?|-;fljHUR<)o z!!|o+6<8w|6Y3sY&91y9@CuBG(zj%-l0P)>uM-6-rh8dP?Ahf3!In zl6#~%0o7ND(g7{yt1>-rvN!~*AT|%%w~&Z|aqcvAUzMl3G0mhoZA6?a(5 z6=@r74{LS-oyO`IdGT_>5R+o$MY*N3_azc2oyaeH|2e_09<34<&QLr=SIzaqG-Qtk z@FQycRSsRaT;sVYkqnXAnouf6DJJV(2@Qf@O0SrWV9mgjpuE7U3;>_tH`6l#M1=u z?*=6Nekide?9&>tUl(fm^WZppJFZ}QLzgIcFNuh^w{ ze4VB3=ck*U{ao0#-Y^Ns@>qH$u`_stvSg3T@t7;hV<2yn_>S5>{I#v=5|;gfOR6X zULBKkt;6F9Vf<=5{&SIPkW=0O`*)QpO&M1KFUH64`7?aVn^N)A#Iu6agH8alI$C5N z=l6qu`Eujq@N~r2i+Y5Z69qEyiNcFp3;bsQdlDS-C&AkkN~8~;A6!lsfxtfnY=}7WPd_9k!SHN>-M*CcIKM~^nqRbq=7IzTMy0lYJAudAOwXF*I z_NF2}mLs~okggTd73sYUc5?3eishrG$l)P${-W4t`Sq5trg^+M`rM+W*Bd`ti{)RA zADnBAAMJ&4X!RIBk_qL#_W04>(_{RM!tNSBJ!;;dULRqc1?>4@I~Fs%kZnxZOufJS zjrBYt{le0wq+iEV6RCJLa)!=7IG5*ueJx9+Dhkpu7&nu37={|Z z2|!m#igEdH^ZhUi3lvE&KQ(|lwO>P$Pu+mn3u%T6$Zzq*b+sEp+UJb;zKFtTYiqAIa3NpgkYZ&TK@zPaCmn^6e z&#UM53il)W+FDBO>Fx+n2!9CS?HiwMfpmnDq}ST4!>^|)dzLcVCFAY0b&zo2F?IMrJEAwr9n6_M3Hk7`|`4kL4PKK$UW*5NJPP+R^JWk`bYiA4bK{(Pi zL1y5J0JRmW_2q;J+9(Fx_xKE_qBL~7yKcQ^!RF4l4gq^WtEgS${tj7nlnOluW+g7Z zo3Van2&v1iBu74pM{#A8_-Cn_Y))x~Wc7>hN#70o;blJDGM{fWJ_s+~Q{=V!ci?`6 zknyS{h+ZFs{YS8sZapw15M8{2kIqH4m*k!g(cW2mPvVYL2K+R06v-GlF&RJo)HmeK zOmdR<{ig$$p4Re^rQ-(eX`34WatggAFbSQHrx(LiK^#v%m?XkW;A=T?zOEeNf&9|o z(|wD!6`yOVFCgmV;>t|5V%f;Ni~z47Ky1NVG&KLxhUQ(2t1vRv-6~SLUOY=VoN)zg z_MDCoE}lHzyc*9mN4}FTnO~|~opc&MtFEF6(zwt%`3o?s(G{fwTYBs3rMPE=MDl?l z?i*bviMVqtNsMPR@Ipp=Hul+*#6@VZcDMTgrOk=g!$(!g`T78Hd5A#L>8v40+qX4c zf|iGh(cn`arI1q_AEE(buc%XA&deIyd+(Ta$+_mc@Qy-dhnV;icm?^=ZO6oKq-Ys& zIY6C8uXQlaHUBK7`p%|``_ASNgCiw&DUSLQIe6=K8D+A<+dLet^ehdneB7S0r4gYl zSlHuTpo$|_yyLQP8X+$r;kb2s(`$&_N{dA88XD*|1RC3`QCki3j;Ewbe;vt&bpAt? zj;V5`G28g>_e-Lo7or1jr%dW=Z_NCKVAGL++&lBJw3EN zBGpn&tw);*`w{$-+Q2CFsOGg0VQ2Vd)%Sv{tzF&e6X!$29DVI^J%L(Wa8+~EIVi>c zgU4Szv2yYy`#OyteA5HnviTqM;Heq`ZqX2uGkgbDV@J+_Pe&*^9Ov$|*3y~!4t`Ub-A$uFRnz!6-IEXiNt$=?>nq4tiSe)j z)}ftliLICNP}GwFV2a&-GKdAS-%kcCC3gJD@FAvH`jfYLnYBqMy}QG!QFWxbgPf;z zUR%1Zh^+vlFdpE1XUMj3-T>#@#5pxT|DbyQZ489Y!aG;v;n=J1Oas10Q>X&UFg%iP z=&ot)*~y*Ld02<4RoHz;_ucN-;HmWwJt(zoeMOI|J{w0J4$y_T-kG1FE_9~K z9|FDPr5&k#Pnp_3&8fwJBu8v5=s_cdlNvR0FH-7MCXNUiUf6x9-T9N-&R;N+^kxjSFH8U85d+nO=Y-)#JjO%!wqzy8?q{Vm?09kZ;%x&LpzsoD7Urb7J?6oc{zC2Rci z=5K{~aE@{>+4$vk2f)k%I$h`K`}Cw$7>;r^q62ro?&!?Q;;H4SLY48qzKI(kPz>)q z^{jfFoyi%o-|~YGjivvWNW$*vyk*ET;rO2D48i<7U--&q9p7s8qzTZt^P64gHRpa1 z&cyQagspCWR3{#zpKHnkXp>)8Ln`t(q!-O;1yKem9schB6*m7(EwA3Z!MI#KJvYw3*6HPmrIqRX^d;9YYxBTt zqcG?F$Y}cY#veDvzlAmLg2wRe&pJEox^FEEqMgz+HO{*$>~B|-`#hn-3)S+<-sx|p zglC6uZ=N0gN)l8*X;^z=jdv6C+nVw`%)bwW0F2+SKXmt@FYa zL~EP|z3o%ZS|J@+UnA@NOLefLE4rB>7v=CN{{2N!jIl%Q)@v7}j-v+|doi(bT3R$? zmX`uP=m{U0TwGmUM3w4Wn@ZwiH2u4pUKgmselA)c76?rXcFYZz+P^bFAGuIx~ws+6U(+F@N=oglt^Mzq~Y2`|3ZGxR)o^ zwGO!d730gdwkYKC;w|I$rxiY2Hokajb?KCKdh5WQdk?ja`3KF$=U3*&$BrFt9k9fW zly)sr?y=>maYm_nVS0uS1qb?68*nJl9QqU8#_m+)>q09zc%S#i?3$8ln)yjY;7Lk| zrsd)E6ct=p!ME|dNM@-ew0u%vy024 zcOD&Ud=||?GCkVjT|cCQ;3^NA(DlFFY7tnKqcxknH4l~+rGK;Bc)}Dvx%h2QX^YW^ zeB&*tYWS*u#_4eqJwRVnw1ylNOUnC!r$yxT;&EmVEJ=gk0Bb47lt4HwRuNM|;WvtB zG3mY^WWMG?`11OYJ=$d7UH08NF1r4dv-1~_8Q@~NJdjgiBZSou^+Dz(koyz~7T$7}MTkLSDWluFHbj&# zk|KH!i$$?OcUD!`6rvark*5e}Sp$Lc(Eghv^gAB{;+mK{m6}S7&}y0utwVPoX9eU{ z1`ZXt@UtA9@r0ohvrCK7#4K5yyd%CND~6Af!6=;enm-~ZZ%##XH&o0)-lt1{r5Bs* zrMFp|2NsId$>}jrBP7Kb!&;(6kdz~yNcju7r@c$#8tY*QqP=^an>y1+l(o<>XDc{jrQYU0n%uj)E{C9wCv ze%)Ir=%NoY5B%c5ojEf#v!r+D1V=dfMjGS^GjqE%(JmyS_rjlTGci227Bm}vGu+fn zYXmByndb9L#&ga0!HCe{9qa-U7w>5NA>7h>)s2+*?M+ADlwjj+Hl^Ii-($@gcEp*M zyYR#YW}8(tay0oKYfddLJxG;9C>wLb2GE6jZq^Pr&b$x7`5C! zagqhX=#{B9N2K;FUmZovAjZnc#naLdvMJ(D+eJ9DL~qSwWry#5?WNN=$n3G^DYkuW zE6NYo5;mE5m_|Z($UQOrji**tXWKJ#(~Tdutd)zqzuMfhDAI=jThx5s++k>t!imMj zX>ehDl-}foITVn-Se%uQ8kmORTZVF}X*SyVUUsf)=Q}J`v43gjJ1Sni^SvHc$IkZ+ zVihqpyQam9JKw)xsE4&q4aHEv_pEjKMW=o93rzRw{%wq-v|!_?fpWanP_>Nzsj)ui z!pRdhE#~>CDb43pCZ^^0#vLk+hLC zm@j-=7sjX!&f1CQWAFDAqfTAnfx`35GUMsAhhULvyp_~W@iJ|7O3-kMtX1**qu1%$ zPyMH>z(yBf?r9-%E@#mC+E=d4+!T)p)!w1%XFS|}KxEo`$A zU-0+C|2p_c(ky*B{Hx)wSTeIHPk{?O)ZF#$&4zXQ6E;d)_GqJ}4qj=Pb}&&IKe2@9 z!0a%-&DWvbm1lb~dkycZyh815$Y}fwJ+JbXVsVRm#A!=*czd@erdeoM|2niKa9I@w zGqe-DL})Ks0?lpINkg=%$U{xlp!Hf8o_uc#0bES0Qlv7@Rc^!2ul)Gb#Y`NR@@`&U z;Zm$`-j~{jGzmDpU{Z!MX_8b~cHLRI%_OZf0Tp#?1M&As68H`i``*r$!i?1LdwVku zmd4-W|MsRevo^uEHuuEX|NK0MS*oWWS*$|~#cgX0N&^?}zs@0v` zx#mQ#L_?NOn1;TeYr@jk_^u{!f)?$@FA}qv+EFeK$ttO)dk{v9^h8s$BzxyXv|H!d zciDF!HUqG6!f>W0osK6o-JFTL%0?NSv-H<5;54b_0?L(3Kmm8cIK9~t{#36Ls`pa~ zmCtD}qH=h`E)YV-zJ2s;LoLa58>Xg}6nMhA)|%kwNL99YIA(5;dTs!vUN^v6sqaGL z_;gNQ5z)z6VnNK$RN*x~NVxgXOPW$T@hAiV)%$P6yNq|P`42Qw;{ZX|-d~B2QKQfC z@jzqQyN5PSnh~nv+uqL7ZM7MP3ch|ui+~fgHEH>~n!{mM{Ck2*E>f}`p;~ROM{~$O zS4isyWj6GVAZC-HZ~16;3EtO2Q7=jp}eX`KuF23@OAcwy*8nOj6LcQtP{3c$g|)>gNmqg=$bW0Uw- zcm^WHFHS!iV}C}Tf&@qYY6 z+TOBvOrhdg#8@MN&<|dQl{eH8%wwc~bV+3~vOnag*04kmzK;hv9FE!maT2cwLqES1x#1vIlm-8Ipa`gHq5d)3zD ze^5(=l%8l_gFmkJd^Ago+tWP}(ERmMojDWUdZmXyQPc&(hMrU)Y zp~|al}4B__uzwS5HdX{2bR?i{0$01+!vT z>~4QSCG*t1_Pbf(B8H+a+Y1BX#a7sN6I3ZgAWSXEfLcJ`ZF#0ha)dZ>fefGhVg+92 zCWCe3COmz*#KJh}!}!q}qh%)uX}%7$1plzWB2^0**XTW_GTE`32;skHpr=06_#d2Q zwlqJp_|px`(B|NnXX%z_QKTMsp%Q>E5iVz%yT_~D9Y7M3?$}wf1wsv;;mzU z;ZL3pcR_uWbAoG4p!JtmMJcbEVtG|z1@<=EFt}Y-jBlnS^X>i!jn^>L$3a6fw=&SGd`g z{=%{P_ZRTQnf}5}E%g^J47d$jX133Kr5(^$%b>s3UqGy$pX@Ir7j4rg@dMmQ z!}niVr0dOsv1`+nJtuX#T6lm)ghb+1(?Sh{ zXa-OFiw_^DS_1xDRzRdmp3P$*1)e8SItl!MbbH(f83uwQ)5>WJjOG%D!kJ}d13lZu zq=Qi&km9r#muF7E<7gL2xNP^>Oqra*10mB&v%*FD%rp#4V;CdUp3q6m|<2m*FCZ7cO4h2lcR%jZ0Hv z#7ta5STn-2Sw<3Qy&@_^y|RH@!Y{niGkmzrarcT(z{0lGNj$OI1&Wz7Z6DGy;6fIB~KSK zv}An@FFDkM_P0H+&_=4!jL-muphvLf-nu2mxuvyeD;Qq3WV8;xo`B43k_H*m;npJt z-&>BkcMM!RHEKNWQsSQI2}Q_R-x~A2HTZ{IR544Izcx@7 zXdZR()tZAgD_;n%!5oJN<*kS(LXSt$eIWMbaWGl6VLBT-(I>r7uxD4C8Bzp%3MpP2 z+vdof`w2oxmgaL0;=82gzK${2R(24p8Yui_sL$HOAP^D{Op1?i0`a0qzzK8qdaVT9 zV#;a&A#hfX`Sx^s$&BQ?C-z93n4b^9g&{g?a>8~IC6PK2$HW{+gogk>)jk6=t>+4` zJbx!`g2xS1TDkGF9Cbl*uoihM<{Br zDxlEga5LVX(41!x3t^zh$+RV%59lIeW{g~^-C59*UOF{5ch4z}2DC}i!EO~iS{M<8OsYWc;n1m-a-PIz84P=no$=vn|A7g!c#i{%2PmVq9XE9M zl!umAh-bmn=b9O(wD8~;v`E~+t+5jeOcAFH{#Q*s9j>H(t;8uvIw;J#zZfesd{kYH zO8^yt>u@M^)n<4I;cPD{m$~gTxh}*#XkwyfLP&fnK9O*irRF5UIs~^pK}x>WCo-G& zO^CxYqu{9gS$R=|+g4k6rW#)X^tt8FnvDyFR#6-u-qsx1wtf51Fwo~g_LHH;pANv# zgzyf)P~olPHC!1FhyyS*;^ub18Xth6Yr*paFtqE&;`9Iv^=D4?92$V3>)dh;z|hYQ zYu)#`21E1XyP{Y6nDChtM)vYoZ>1I$+5LkiZu2xW@q2D7k^z!ELr9(|L{`E85=g$^}v!Abm z8scS2^B(|FhZ@75J(Ri@$R=bmDaLGs$PHl30gO35(CNIpxAHL8Dg7y64q(gyj9IF` z^;(<#DqsL(4q!}wC-RR#r?XPoEXQo8>AMo7EVL=31|a%~t}ltQWzf$Uh7}bnp@aU9 zxTZ5mjHvU0`er2IQi`ZpiI!%qSc!sWsaS~yfjM1^Bf5eTO>`zjoE}=DU3!+vQAg>h zZ%KIy%}Vq-3)eHLs+-|6z%D3l5;JiLVS1MEqWY?>0c0S3iBjM4+2;0~D}76pCtTl> zL}F`0y1pfZ=}4lz*{N^otf+74u0r1uhAF?1LO>eP__Va(bm?0@$28Znz9ssd9r~7p za1~3UXH`V>zkbgG*XvP6nhAN7lEL%4pQLG+K%*RV5h}QQy+|LEjSnB-gi01bUpVZz&?{ zTT0i{^erKRz9m%Dw}cG(mf2g`l=_zFgjV{N$sN_M5+iA6!Et@d)CaC_nUYROBYLAz z-x5#Pw?y@`(zir=(>)X->RSR)R{EAw(iFIja%Q1#Nf&2*OF3>Oi2ZeaOCzO+V?U>st~f>svBegYF#ctZxb1 z^ethA6j5ReDPA4h#`P^JNvUs%ujyN&=jr;E5T*KxTJ6C+^`$5sCMXE!YTDFaYlVh$U@%|SJJnX zPpNN-JL_BG=+?KiA#VDXv`ndQN$99=37PaQq2q9b4EmPF#EJuL1sO&JRH<)?GwNH4 zO!}5MlD;K$rEiHl>RUo)eM^d3>RUc5>RVnH`q}j@neo0tnZ9LmxxQs`y1r#{n!aUn zxxOXNpl^921uT(9F!-!*iLP&@Z;3nVTSA6-re9p?TjH1XEpfQMB}CA-R9rJaO6!W2 z`ee|z#98ZG21e4i#2xf4p|ZXuj&6NR>Qd=jhO|n3OIVh@m&B3A7n6lAF&$c#=%O0F zi1xSX#ZC#GY;5@>X``3@$!NChDjD@pngiw?>prB+2eY6tyh1O#pvT*z4Gk4y?k@(4;3q$_Y3=R zDGyXgCwhv-XY-NkZfL<__a5HcurSA%~kmNx@}tX9H8yYo8%oB)h5B} zoc2HHyi1TPyK~rIwT2h37jQ<2fb=3sjC^S0Xq*prII@t%JWfYmW_CQK5<8rUp(>$* z{VK^m&^cL^J-jJogY#M+G+{lKs^!vaa@t;&Tn8n(XP3$K$>|$ia{5M>oOWW!E)(Jl zXPK_;iOJ9RM4Z+w=?y4ne`Dy}KxFo0bGiT&T|xeovv|Ksb5*;lu!8i80idATRdL5% z6*BFr(ABPrJMXGEd{>1CyDC)LRYe!OD$aUW4UDv_;tsniRNhr_bnmLvrP@_PTIH?^ zEAFb0Nf^=)l_(z`l`zosBJx)CIP<6Xo_ne9xy$#z+U#O3V`?AZqp{^q_T1aFFTK)l z@|CpTNb2v+?G*+0C@vp*Ac`zm`DywN%ot1rkm-rDcSTTVazT zLXcF}OE-!L8@AD=8no`MFF^^R-u5dAp;HDZj@)cE@yHDscTBd8PLN8wl4IO>b{)-? zOgNe=nJMj45II~rnmad(4jo7HZeb!G&G9LY=GxxfPMOwbSMBaKmkxC6o4~A0U{F=pkUd^1Fmu}?2`GyLrj8I@>C`NWoeFmI0w_F ztiDJxB@G@&6@umWa57+% z%cQd8a;XewDTE;o6hc^Z1tAP)DPPdDS;9qVs3bCQ)+~{6^-)P=xT8b{nItmkN+QFZ zB{Cc?kwFBB3@S-vq6>)(XDyKhMv};I2Z;MJk{M$k{hTreI8YsHtx+$3EB*m{?A+kqjno;C>1Bt z4QEk(#MvP6XG*_7%<2&a{L zQF2EugTzS62yk4zNc|y&I{mF7ZcoyeQUXXPOqqIE*Cvw6L21?v#Vq$AwWMZ*QdXsA zB)d>TGEkQ)Pyo6;s~O25Z5;mA=U%j;PTcBxM;0dB;GeivdPi_dy(0yPdPmUVkStqk zN~N^(mVNCi1Me7EdPmtQDBI&ky(40FLOQ5pnck6Q@1+W<+2L66P46gYs+wA|{8iT` zy(6@^f|d~aTUrtb0Ofi|c)H#ZQL^5VPm5Ou-VuK(soQxYkn0_hzN;HaSHujy!3latC`y%jM>wLd{$Bbqq60ZJSG5uhwVNkT`-05SoQ&~d0j1|ZUy4n#tR(E?QhkvJm|DKY_(3YLLL zTnUJTu7F6~Q9}u`!X8U-jXljR!ZA;xEOKoa9F8oqO!%r{P-1d9T9}-U7AB`bfXU?$ zAWm!la1VQ3aQY~St}q{Q2F0cqQLj?5>3TJ9G$eNe?OPg>!yN%X$Pmx0-Bo}eei`t? z;ea1R0Q?j;DmIBO06&~H;1?JP@WUMdKd21&;phhZs7nR-g|te*50+)mM1>4XSBE~+ zjh0aw^;5D>+1T=bOP%R5AzXg|7H8nwFE#|weYLPTQ(Drc<;d_Uxt$cCcg0SCyWysO z;eT_2^vwAT@lNX}P=*5Xb0OhIhIdJ8%I-Za_m3&}pSK_vHivarI{YSn_82l~FEG87 zH$I1O9~lY=pGAF@Sf3%PfW|9^pR2fY{9L*^# z4r1C~nVvj>xjlqg^jPBKRq)by@__U=sTUyj_VrZ|V#L!c&_^WU>UjFJeHEm@&&VoZ ztWcdF3E@C(n47%vvF%xv3qUdDllgl9hftCYTA_St?$3jG8bQzbU%MbxwhKlGiWI&g*x3VwMWq`&C zT~6+ZB_&3JoZw`1xtJ9xY2OW~D{y8Psthz)p~}E3-Ka9~V}&XMINFdC;+H=bLKkOL zSq@>X_SZpVBLyNGp%nAA2+1Ehixa@?-tJx_K+2ckKnV6j* z@|8+F6iX3u;szoszJbUEKPJmxA3!vZOx^=+2FUknUs2&fIf#sB4-i?`1wBAy*c~7; z$YB7H0nNN^97LvoC5Vi#fymctAyach7>LZ@1R@J}vyX*Pe8-M~dpbd6aGw%H#+gB6 z92JNxjL1F~A`b(RAp(dD6+mRD3?k!*$Q)z^(SP4Xi&LA=vP?~$t1&B;A2azEh zM8-eOXy^bUiwYpJ5{Mu&bQm+lj~gyMSs}-GRmd^!u%AN()j^!PY zV@Ssgt8fW9c5Xn9SyVfaV>l&pj58v~kO@PxXCetXmQM*3i`6m_1;&fB#&`oG zVZ68l#tW4(UL4&RFLkLf-jG&_@xqE2FC?cArus|BqUYn)TP(-Ww^NN<1@-=kpxzrt z&JGWM`;a|7)$cQ3d2xcd(uLlRmh*kS759?pfN4YUEBR3sfGDrh54PKrgT0D zDYeb399uQ-56k=8K#6zm_P49Xy?7hkcXV=JCGL9wU6s;RMeu2P{Adr4x60$co5z;s z$nGn*?{tk(%jA>t{MQ#WcV4-(DA4F-aDVIqFlZs!!={vKh_yeI-G1fHT}9|sh5os< zLtj&c{xwS*1p67Z=B{f2nlET>-?>vSfrh}z!JKJs<+DAi#a`OnWzUO%ruBMg$Ig+U zJ3Bn|OzFiAH@A+!^jAf+i!m>3Zr`T=c_J4LUDe#WO>dVhiSX{ovfO5wZQHhcx1ra2 zu22+^{H=uF={&++NFHSn0o~hSsU%yHUM_9*&D26Ap{a@1Z0_1=&#gS6tp?l2+*Qe8 z)BhFxzhnFE?Yk|CT@xramjF9<>>AmsS5P~)yPwkR74lkwZM8TS?us4TiM8GG-a10I z&+uV~Cj(Gw#M>_On(tEbgrgQVI8#4w-M)QuEu?=B}N)`Jau}3!kAYfHz(IbYB5%h<|KKcW|>PbdAMq zjDZloe=Me7joZO{E&u-ehC`w5t@`rl3+;2aPw7SXIxtfqRRS|bsS>gPK041~_-5p# zOZrqYgZEkbVD8|3R;{OYVIEb;%Kk4M2s`Qb+ZkAzwux?xf2nE}M#L zi5jphDhz`AW2RDh9 zz)k1?Zi))vCS(FPp)(*JC=!k^CunyhhdK~XLRE+-?tplvg0Xu+2lP|ippIY2tDG^T zyb9SVq{8YFO%)@ErjQPdR^bvb>f8W~(#0LXsL8nbE6O+{Fsk8@Rcdi1U=+Gmsby!V zkWvCH#b0#-S{b2o;@T@xTVr9=|wCRGGVFE5le*(SgJ7{ON9*M5~{>f zaYigvWWrJvEZ^SZO2{g7g{s&n z!o>;BQYV=uCttm6rHM;y82K+_!(3EV*s$)iJhY6|CV>*V5-4$Jff9!cln?h z7CtHA?N5PGhXKSK+ZFpGV*l)xCfcvtr2pz5FQT6dlnQdmZi0N&RAa+WzSu?OhQ;Y;WJi(S8xqXzsX-bOqa8YrrFDsLUxE9>_a= zGsvg{ep12z765l^2u^xbRC>HShNTn?iRNz#fBO}L|K1C+QE;Qe-Ro%z0vx_Z@L~(b z&K<+pXKD_gQ1s`4pAIh&b_W@3;aAvZ0A8)8j$^AVjZxD6Fu^ZW?Ehjq*6)3@=xig> zC<8*bkAOMi7Ya#MsmZAEMQ%RQ>V9PaDuV?DnsoR%in*xrStJ>Vv^qN`E7;PV)+-l+ zpzho;v{jZBRL)nwfO7tyGoUwBrC zR6KKrAkgGtMj}kNI@pY$d@5uBh6Ox(8o3S!p1%Cg<0hXq)htFV2$nW6B(DbP4~(US`NF{NaB>O`@8NAdvqltTP}3Sk4u+Cr3uHKnw!OGZRLRPEeq5dp zJ-a!w9h05}O4Y2sT^@h#9@r4wRhD~Be&?P; zHaoUe9`BaNFX3UCUt>`CSwxA?^8v75mEZCt)k9p4s&3}BX~pdtgzf8~_C*hwuh$Cl z>r01yQ-|fc7rqFf@E+szd>!jLPDsVc1EDLPJRqY8$|~$SSluS5|D48j} z|Aolm(s9JO;W)x+sN*;Sr_|HH8IL27#c>2zI*vfs#}STm)p3LXCchTKD9&di4w4mRNs!n)5$<1mvCFG&B@;RSa*yg;VI3v_jO!JQ8; zIKD8^a9t&>F3*@nUg!wy^giHl^5K9JM`Qtq|FDFUcT2jGNTo}Bm+SIhGui4t1z>*J z3yJ3#xX18lo(hpIH6ZpNRS9E%gQB2bW0?g1B36hpyp?j8DE8kuh7C1__}!$W6gSC@ zHqyZpz3PcxUvfo#4X{xQ_aC~K_}F6?kJ4seWkrv_KVb>I{{8|EzAbro@AreOwf(i= z;2mGr6S33t{i^}BkpCUd@2|N@do#f|b=Di0RvVaBCf{xF@?)5jsSyiOS<^ViP6MZTFLf)N()x+mia^C$E_nCgx>k z?|Noc@jMS_z}KJ(Z5Laxr`r?yXq4V!vcfy1$l-Y&{7%IdSPABU&WbHJShlG2kP396 z&_b}mw z-Cd>#l3cFqk({pUk({Q$kzB68fphR}Nlni^^p7+^oCGw2c(G4k%t&_FV&egyls=-m zQ2A-e_Xt7!(}o*DyUMUbez+x0H|YL~Y@0t}dq7@(-M;NIzj3z9X1iG)dWLR-?TeLn zTtl)y#Lc?dSF?L}rRr(fb$dYu{SD!lerfJ%8{AW;^xmiRKAkR(Esqa~_Z>scTl|*U zc%KmOM*&3bV)$pkXongP^V0AD2N zp*_E}8r56$Mmi@J1z8BZs{*;CGZJllRUj78MATm8oT} z_3c{%gm9}=M31-7ZiU{ze}I^t)w^++RVrl}zkk3Dw<(n%vuCSR@RyWqb-^VSV z^@ko@=x<@EDrMno2?3;M9ln2nryHa~#k#Uo#Ub526aqVQX3hw#GMv`9=prGRx{>}9 zhQJC{BDy_Ws**#Ns`y)L(&(EB;rj;`Mz)lUkm)K2y6x1|YU>ttnE26j6?9O$(f1GR z%L}b+^(gzAQV!lR@G%b^oU%maaii%fVs{{C~sDoE?ZUoiITs6kYDP+&fhEO0Vig)^WWPz5$dob>36l`e#VDzGtJo!A(xgpEOGZ0u?;qhVvv z1vW-7$HpN1br=3=szZm@U82J4E+r66S3!q2UBtJcK=&{VB1uImD^`T6-gMy(*IrQJ z9T!xgMJWhAeE&e$`|{$de`-E_|3KbBI}*~hBdc&pJJPvfA7c^j(2j&tYDeOXFqszY z{8$TDg2|w5jY;1>cp*Vc+>8JjH^b45o7wO;vsN@!iJK8R;%1NuH-nBt6*Ayv#&p~a zGK?0e5;wycaWjz#H&d{Pt=K1f5{iaTg`(k(C>mr&(I|L{qH*!&C>rx5$|Bc<5#bN5 z;`nG8pq5+?s3oTZYRPGUT5>s{hSS<#>nP*y+Tiq25M5zD;tb&1b=0eT|MVg?Z?uhd zJ?&fC#=;#{2q8l}!?-IILj1A{Ar4m|gb44S6gPhVKy>l`31|KODKOIeC*0xv6I6cx zgrocY6LqQHKZUf)_fN1adm0QfEL|O#+YOeHkC&;&jSVoU-X^^q4g3|24 zi#=}%c$;1sZF8$om$IJ^HNJI#Uag}Of&|>(A*x>+KK(x7==U-H0KFPFxwU_NtPtKM z-~Kumsdp3UEA*yP|C}k4ZG5^fv49?@509~DsBF6x_ibtdYbmbV8SzRAMR|DuuRu2czm1&<2pex~71L!J( zRRid1ZgFyAPM>D@te`8$ZcFIu#%qDD{!&U>&%-9j@O|iO*$Y!Q*)H`hRKqau!mru) zF$3b^=cTTsWf0iS*OAT#K)TQ=!+W<3%&aK(vw_51>C3`Bu5dp>QkJwCB>&BZ!u{x* zJ+F(K!@q8f_Zj2YjQ%O3f5qsZd$ZX(k(q7(K z&(;xFXS0&5zKD{%(@cBgZ6(>GfXDSSJVZHOBy?AFh; zelF*SOfHs=n`LtO^8b19JUQf=(OPs&2Inv7Ukb%FnI+N;8?Wq4mn*5{@gL zcnJp?Z*`=W!p+NpGgEV?R@x8fiW%Q^OqnQ|An_=fDP7t?kl`-Sm@ZI3hPyzh@-7f(ybBbW?gAAo z-v#1IcY)B=T_Emw7YNB^e)!}Xj(jmlvt%V6lwoo(9M%`nH~fbPf4NnT$}X`rxnvR@L)?XvytVvEd@92f6b8j1OClUu%RAh%S; zK?ZV*E+>}kif=u6NPc}urJHKdTFN}Kym*3rc=WFJ+|0`O7v#4}dWeWUZW{)2OHk7t z$SnvO1G(j7BMPc~Div8eyG&oSaF(8?NtOIulL}|4NreuVIbB4LuHNR^kVvy`B)2}5 zZWW5hS+@$s;Yznks>L39@UfD)_QK5Q^vo=OR$e59X%xM(+!D@3h2%0VDdi91TfzT? zBsA1`^FT%!$SAMrc+=CbPS_WdNU?$Sp3Tc-gYT)afw1Kcpp|e}MO*yig;q*!>}q$G zMt7%9_tOx;39Aq^!&xOxH&tty1$DmSxXahOFKptbr=52~r`~e9?eZh+&1W7hOTv zlZ@8$tH~~+WK^+`P39z<{5OoY>UxPAF#9Tj*;0@>{$QsenP{*JvYkU0=qgG0%SRRa z2c$}l*;xAkgMRF@y|UIIuCCOwL0WgpVE=GT+5al#Pq5 zkfbt;DY}Q};p{I9`Fh|YqTdUu)PJRPe^$ zI0lv<29_U~7z4`>1NC`^0ag_TmLCS{^Lk)3u>3$Hfand>=LeP_7zr=xz&}4L_4%M; zSnAJjxe0*lod8$EUnUI8RNl?js^MB0%@anpbDIHU{{$OPLyh0-jbp8+G-J|me`+&* zo%%4u)8`qqujH`B)?eWUc2U=Q!``nZJ9vG6Ov4zl22hM6|cfjs=M4!YVt8d zsmW!AQj?1=ahmd(q151#p;RY>p;R2%P%8KJ$xy1%8Vyw?bzN`9^zh)mJsL{2Fu_nN zx6^JYH4zA#ZYWhmHk69X4W&W^L#a^FP%30Fl$yPjO=&0y5HsneAg$e;Mnr0ji>-JEwfeOL5T0@q6!sU#N z_N+cdfhk5U1x~r4R6N~KDp9hbROWOxkBY<0qY@&dBP*w#4wg*4SZ*Gb{7dtwvU92z zaIzWNRwF~0c~pU1(L5@FxDmsX^xZ1z3nBq0m`7zrL=hvIN5xq=D)Xp#x_MMBqw}(+ z3K7hsLIv}vP}w{xj`+?DGMGmdGnqual8P24QLj=37*w{x6ENtKK)Fd&N}f%kUTuMs zNmQIcvkIy(iAtPg5|uSAgt1p;>2pE2I_*lpO3#I$vq@A;b*3o=U6@2An43g}aFeL` zr%4SROrnYkCQ+3@G>HlwHZ9^?_tVC7eI%(!WfGN8l`0bMU=kH7m_&stUSl%)<7-UF ztR);wqRKnGvV?RM?kZe*W$E0oQ?cB3m_&tBzOuv_Us-Bt&L&ZDrB{~Fwwff9sMip* zG>J-p{GJj=_wz^_@@5j1rYfIA5;{JKgiOyMq2us`49_5q>CYe`!)SrZ3QML07N0@l zlb;hPSbheHD?NjRuAV{Sj?W+=tCx?Z5+1vkn?${m@Zrmk*M2x7$~|>48&P01_nk_48$E21EI2FAdYUuK{f0cRE!@|hU2_t(>!pJUgH8@nw zwqPn^r|YO$=yxmh`|)@dkl9tk&sUT--J!;31MI9z%I+bwTi_1B&^Et2D z&k+!l1R~lt!+qS^xagI$p;&1fg|3Bi3L3NGNN8ma59DJNd?QIN7dex&{&w9#EpN&1 zVErA>^*?N956yB^leY_JneH0jz^mm0MD%jQdRB1yh8105!;-T;KUKRHQc~WvIBZtC z7VfxfL8e^`y4tmH=Uoej?^+OH*MdsBmgr*F!ddTHfsuAC++o*(%DWbh?p=$zRJ&G4 ztK79<#a#!d-c~0Z-ISmo!wBkldRCFFw&gH z9p*Gtp3^wG=QMSx=5$D_oYS!4oQ6zuno0Z=b{Asxp6Bc!6qPk%zP&K9I-`fCQ+uX_ z?KHMr!9>4&4-@^`_&CBJPl$h`_^;&cg0b!({7_>zzda`YhQq6`o7N8H;f?2XM}!Sa z(XR!pbh)r$ib=TXQxYns=IYXl^d44-#giUt&4SNa&KI_dO_Z>yie`i@CCol zuh)+9>uX}Afzj^@Ura2Q!Xw<=;~Ix^bM!54a>4?JXU6_m?c>4^zm)B81~`?CqJRP6 zCm2v-C!@qgPUcbkYB>B(7!Xzx!l5$^Xo7w~)}ifANO_zYix(&acQ_Ej;XuMAI1oC( zfuaH&2$|qO=l}c6%QzIt-JUt;L?L0#IB;)F^Wrx zB-DF9cH@DF!oge`sU=_>Zix+2zK9K~67k*$!8qZB@FPwL8E`^lI!*`~h7(kY6XJ|G zp~z$|O~Eowh^ySMt8*TH5hsMqM?M_+$V%<<0n}vlXjKhIDbiD^EJq=;SI138X&7%% z70`@30LxGTSQf8*5sa*##Vsz?DsfA1K|S;rr@aolqoWtLSPCI!gmz}(`%TC_O=_l{xbhtM;?c|+ZcJeNqOrPYklXr4CGK{l4XmdGfPG3i& zD;%_Sm&tm%G~plCVwnyz1In*7Z7PyL*XP=~!X!k?!cR50yliZF0MYSwiH^6qNXhw8 zhD(M(INw7~gQu>`i|akP8+;~ePKaxZC2Oho>$Ob^jss=BfihnoF!kW6>$=NQeHPvD zv^G%wix2s=HQFid3;QVgluwQ}RQzmEDeWO!xY8aczDj8iA=Q=k@ECmMTwi}Kl=nD3 z70P?=8hqs(`L$Hu)5*o$D=yF`cRaBtMmpHTaY>g!H~7kVeeg-2;q{xt?9{a)E)@Tw z@*ab=6WcJIL;~VcAw8hqtkKq=5s3H=$8G_x?_J_YoLM}q#K4Jk+}eJ_jvTY&xukX8C{bVGQ9ubihf za`2V&nU+T4^^B^OxmLPJ#T_nEq4Gs4j_!-p7g^kF>o25LUZlc`7pah17P_IT8yu># zdxr9<>k(m9e~zAm8J-)q4>0Z8;Rf8^Bn3U$Y}>x8gE6vm_#$wvT|4dLNN4~O(4NIw zlrxI5gA_4Am}!dgnW>nk!_Z3{#?}+!QP#HYU%xo z^*7Dt^~IN}J}TZ{Vgygc@`Sc3wRt&JsHyltCo_~c)ZDRS$8I-ncOiLi-9CKr(3gSJ zNfYsv$lybbEBSq@cfDWOhn=VCGS}7MHqa>S`%-T+8XJW5y>i^I^CH9zu3KFQ=unn4 zff0qP3jy5mLI5(vvj+v0{sn$n{{n~WUqA%?3&oB47orRO3!Jt7MPQ_519w<9pz^YT zqkGw)E|va8NUK~nV8vwvGTrAe?(_AfZHDPJ8uxp#?YMR;uLtmP=RJDil3ad0keqfs zkX&{>kX?2?ket4CB&S~wB&S^uWS7a(g|jSzT@NHbzaEIrA{->cA>0(%y;ZMO6!Cq& zEpT=o6%sBP8e6Uh@BgctwfHoe+igLbG?@Rn{PtKr*1OO)tf0Ru?G5g|*YNKA%0!+Q z(eB+E5u>-45a6P}QUYZ37jVAM1ZP+JOK)(CFt|ln9OvcWCZ1p`bl4^Ongyrl`%j#& zVsAF>q9_}$8A-#X&#gOc#WtbWyN}boz~(}4s^EpDO<#@Pp=PyV@fE)R;tvdF_P%ng zZ$H)>j(v-7<%nG`LEmw{#BLGtzU=bqCQJxedm+n6+-tXzE?0H;fb`>c56Fns-2*b6 z-#y^*xi=UP?HtG`zRv(y z69Q1_7_9)woWNC_oC|XTVEK}u+?)UbgOVCl4|4)9w7^Mq4QEhYgDUihhqSIwwmK_T`CYUq*a25up)>E8J4b_>M#7=L^3XnPBr!j zG&7R`TV8T@c=&rSY;GR`?B~NVmk6p~1*+eU8}k76$r{~0Y}@%_K18CciGWA(%!vkzt&J6?ib%YKj-7qmN#QmXdpT#S% z4NEb2r?t2|diSBbj~}>u|2?DokBz?WmOVEM(r6vHbMK+nu~SP+i_5Fy%+m3(V~1P& z>=*CPxn;aw6J%|?Iq&X(?s21McNenWnwXSE2Di3p=kKAw;0HcC}N;5tWz@o*x0hl?de&`fiJ|4`YxC3jtw0+- z=x9T{UE<0~Myq$4kasz7;85c?I7mGuA+I07tuJ(<7Fsrv7yA!wN1O3F{D#M!eoLIx zEY~Zqm!Q4_>nnUpeZ%seZxOEF`?Afdrf$NbU;mY_TlNbZ;W8+y*Wl>9R(gQj=KGR< zwc$HLYfFQ;3IYTZ*5Fs?tu3Cm=5PcGt5XG$tGE%%XfsCmWzViYF->wT3 zMGhAziae$3ttwo)KyhxkK%p8P7btMb3lyC30tK?TK*5zRP@qlDP4{dpe_qKT;t(K; zI2?Z?N!9W@Sc2H)3er%Aq*&awaPyKdEf(6Rc-KN!5nF^z_bbrxeg!hzuNc$sS0Kav z3RHQ&f-~N)h)nk@I1(-gU5PljhB8Jjg2IZsY|OO;$- z7^c>^F0#t`D2}dhE!%OI#KfxZk}4qUOZq~kx>aMcq$^|ScrzR|wAZ|BSzKX3l2cF{zrtgwutpfv3R=XD3`H5CDz|mti~;{K2xzS7V8n7>YC(a5x0u<&nwn* z#d-%&wDfp#$WgJsmyp{t?`H9Sz))-CvBKksJpL7dgDGaq>kVT5Xphima_ISTM{uAlD5NOH&nt1<5kL3SE9>3L5m`{uOUweeU{8l{vTg-Du&hvJ8 zd@_0zg*hUR&*&2=&!)wOACUSJPm>W-zX@_=`}QJ{?^D>f^9p&TbyB&O9yMfAezvA8RCZL?S6p4#xGL(lRL zFOO{7wS6~zf8|bpoo)T|k*^^AU%p65n5NipbN9&BYeq)45|GkGl9E!|k=-PGL6i6+ zAh{O*vX>G6&n`muY0f(q z(@*gF{=T?1?D!^a;Z5}W_41JVrXKk9`+oSddiA*BcQIl1SyF)7f$e9yjn_8-u+_J)*yR4j;PvHLXL(_U}1*;P8Pvj~&=^{Mep-9GZ1dlUfI)u5U28)1h_IshH8N zy}_BJ((lM>A4;xN2$6ev9gULGE32R+t&~bvrBjh5oP?|zh3-qIT1=%gQ=OiuMtGmV zLER2y;Rtq7bv}!(pi_&}HS$d3ExBBCE;$|OPEOOvOD;RJ;_`1mf+dv7gPdja0hxgi zPtowJ12*n-_=YZU8C>~{E(c#qK0|ja)S0Q7rSNfWoZ+|+h53Iz`C?%LFknoMp3Y1l z0_=z_K$aSwII~&)ZsY>oBZDCdTWX}@?gCg6`eF&U7Y;8@>AM2BB47hqLOD1)upT%7 zNdXFSNBD$7LW@9L{1^@q0Vc>U{7K#?`8p0IfGkigTtQb;XVB9V`pUJSn^NZ!cctlx zJ7PppWs+Eoh@csYf6_rlk2b0%i*&_qsHDXV?RSk3>0w!+5=~;hMUn+UvNko2^32?+ zh3)a8nzo9}GUSy@O5Jb^&2QDk!x)y6?ZxBd_Ge*YULRA&;m`C4o-vPbLdQP>AhQ!w z3XcA420)lA2@xV(csB?Yfi1}V$Ph<(dk7WYBSQHTMF@YiC{BC2O+6l*S@!(%Q%5|@ zXOK9OI>&0nMnlPdJ+bs3sVMedO8x=8t&CJJOaTSPTW> zqn<$c?g{N?AC@Nh{8SWu(J*FU=Py#j_U}|HuoVh`BczB4{*WRR1!c8Sw-Uf!!V<&R zw}bjbHU)9xn|x(Fvh_7@@nx$Mw#DLaCyL9&DBj-Y_=-mKkeaC@XQyd7EAjGE;W=)~ zy0vHz9PnWXpPE{2-6DMioF{J8SILb~a~si~*D3~CLyF2qbyS!$t+~aCn8cYhU+}We zruY1uddpiD^QHd%by^N0_bHDu-GfKQCXA66VchU+%7Radmv}G%;%6t^+-!=GCOpOy zJ&m|7Bu21io7}4tD_Syfhi}}ISop9#A0>}pyN3+kP_wfd3=mT%XQu93Ii;49Ygw%c zf$Ucje49Dd1e%>@MgHXD>pQeo>GbJL9PGg%#OiW;L6c-u%Vk?Su_t zXiW{|;(}%H|F?HO@KGLR9-k~x(b9^PDqc}j#7b*u6G%&{xyqlUO=_T_2{o;FOUN!s zG$iR}1EIy5ehzCqsp5&1R`jUlu6UwS#S@h(Rcfi?9jAEGJ5FN{Jx)<`$|?3x?)RJL zdEc3L-_5d6&eQw!ZI^uKnP=vmnRniKXP$Z9T?wts^0^lBEOxChG@I8}Lh}8`VN8{a zK@L?_qSrAysrNRnx;51!fp3ks#VGM#0-$5zZT9W~VQz|y5YI1X=x@*9g=JgRX|{Xu z?r86!26B&meFJptS34lJ`(819ZsA_GeUNd>lN}gDyL#;J)4$RR@Kow%gGy*c+gsDg zh)AMVFW15a+b+n>8b?{)o>f}#o>j^4vQ5Vw-Nkze8j-KYcvUzbHJ8fOkGtKzI@CD_ zbJmsZcGjv-h@AH(ai;b@+;j5NIPI8&!}4^PKfYW~yVM+-L}BgX{{*pQ+4y0`e-{Q@ z8vzCUC-HYlfG)?J8{Pv!<(__U?gH@Z$x~ zny%gu8l0trJZrkjX%I0)$uyxjbC9I?|7E%wd)Fd5zWg7XxQczb3A4Ds8Y#9c+xca> zpm+`*{q`*%oXVQ3V7baQSBdEQ?%w5X-TgQ@!f|sI%v{b~1r0S?POdI?fF*q<+0VC!rgq^v{rJ55T!mGWZ?3|M+?lH|yARA&kVni_ z2#4k>uxGA9$eF7cP;(WvJaZL-YFq#X<|?3?tE^DWRlv|(1rE$rK;K-2pqi^t>eHC3 zsOy`n5RRIw&?up~%4Qszs}KszRY2cdgGbMml%1RvN4l1lDlX}h+;h}iuEHZdc9k$U8UHC zcCl_^#rme;t}d>ri*}zW-XrHs4JK!9lEGBr3|#Q2eJ1zc@9&2K3fxfP{a3u<=@~h} z6&g9DENAR@2v5H=X?EJOi?8gnU;Ur|tN*!(w0HjhvMca8&VE7sdtD0k$kR;}q{oU6 zT)upA-$=8qCY{f-AaS#iuc~3@hZ$5b;R9k00vT;$;$l+@QGdU)Y;NI#opD{yfZQ?%fncjX+`h*Q+HUD%KJE7TaUSo7lj#>Tn507hSJ@I0$AK`$ zx)g*V>uwN+!ZawK-S?LmTM|L_X+XevJHQzrTvu9F-w0Pp^a{_bLPmF-3mz%riV*^S zQBu4#2+nx}A@S(|sGA2U@cjVl3fo1qjr|`>hJ%ZQ)x9JP2mU9aAYAi95_+%rcSV?W zSPwYK*v#eHhW;`U%LH6xB!WE?-+gK=L~v?R!!x|Pks7`!w#&f_#e1O=m)QCCFu-eT z|B6$PMfJ-P*C9xJmm(_6Qu7TsFaseM-0%^zkBhZdp< zV$L3io7H)hIqMz7fd`uAh_$~O{;*D$0*V70O47H|xk4e135OmIZ2t+*j5Ed6dM%dpa0H_}zNPPoA&SemRz?BfF z{)M1$n5RPcy96^(Y43LlE@Ne^bpbVmqCP4>p~ItdgS^}-hrdgJpc1t+Y*DA z>VR;jz&8`2T<1-Q(2LX7Ne=9sK3^kcw7*LL_WVSlChnsEaVSN6ct?ZP_mrgHmCFo* z-z5NRpF#TIfs5-FaePHo#4#3OeV&8VjTYp&*TOdpPZ{fX3yittGFo2?2g;K=q8B>) zid3IQ7*uoiULf%|XAlgwZGh;Op8IjQ)592lTL|HZi*tNe$#(HHZveE6zZ-?5!9Eo* z+`a+_-4W<}W{2+D+9MF{@0KAL?4uFGSGExdx8cB2`~}!fLy-^;cJF}xCf|9%<{vwJ zFZ!^2|155D2}OUiQZ^IA$ef?09OJhp)f2xQWs;3j+4P*r#z=N|*(d51XpNr!u4EtX zK+Xmc4t7$3n$C(No3Ds-JF^JLel0+^aG5sP*d=>kdWm546$TZAo5l$1b~4EAG9wV* zhelnHncJ+^y!_WMAhM^I%3&G}xDuy;Yoz_Uh6=JBVRGEyDiOiW;dV32z*zWW+7pc# z8aM7yIJnt2izmqoq{s> zBY2w@8OSTNR@_MON&CjIEfJ&b$G+`)ArS%z=nov|Sv1Pe>;yC0JPy_7&ozhY_NNjq zaguR(qZqOB@AJu8CrzQ1vN4jAyg3~F`&^rxZy-;y?;!`L<6GSDGdw@6^GE{a`9-O| zGHmO6grcG6hzQrqa0ikL9vlzae+>=aDp`Vw{#t~Vv~(rs*)`7s*`TnRmfMy?AL!0n1()?hHte4)g=Gv6Jcc!syCGSF(2dPq$%f2rEuDCXq!tgP2h!9tSK}k) zya+e=M-fs*jv;(lG{862?6dM@!%d4@+Lm`qN>_|ltVVcTg^%QQ5bK2jgqYWLctEtI zGb=IXXVd0BD@`^HWSi~w3xa<6pDeWkulX7zM>C2D!H3b3A3}(kH)m1A>v}V_aLuLL zcyGq+)hM(WX3eRA?(~A*fu5|n1tYXgVn=vaz2?>Usku&R7qecK77S!E82Uxpl+BpW zXhcK5$QrOR>uT%9Fq1OlP%h>i#Gt{ZtEeH>oz|@DRMgmp2I)*^RQ#5hrmd502G_(F z&w4g4Z_1cl0oUL}$gADfv>Pp^3?QuPgFn_7}~f@$U; z+>y>Ux6ErXi^I72jc+h3B?g)dy(I@M)OF>{cCVaY_c&sB(lL@2SM{f6xE*B zyjp0%!df#Im`tX#v$Wv-*|w}{&k?q-Ol4B$opI^vOuyNlBgR|GZK+JM(|kK8qQA3i zMK+l+zsW1_Hm^X(^@}1InOca0W<}{TS=+F@0`8vt3>Ju+AX(6IQ|!Gqmf zupE``MW_SIXHS&-m#Psa79MOPiJVeq%v}hr=*Le#rB}4!k!{z^*q?^fn1%R==6lc* zd_q!_%PhRE)c)3FSIRu1!roQcYs?`Rm}7pa0j%GXSkEEkH_y}4tiZdPlVii<&teUh zU~O=?NVw0jYKiGA<5Vl6Qx&^S?vFhOGneP4x|a744tK5{Gjk>Pl!?SW_`izf z{3jq>I6v%}jd($>Io;8SwV2g*8UElJN&aH|k?y*;!k9nDpt5p#dyek6m<)$Yor)Ft z%Gk}cB-Vo-h~@JqvC-%$ePWg2d{VA&pid1Vgtd0>K&CxCFOz9ogRp;7ei`>cA0)iE z7*iMaa!%OP1_NEc)pR8v)gH?JCi#CJU27xL-rCa8oUObH-KeXbz82{FR-_yL#rsDm#PA^1Uz{uWOV@*C>8`n5zkJ z;?rD=!2(&Y&K-JIqmzHmW$j(Pv%eG4;lU+TS zW{))v)|s}vsVk8HORRK?3G>yW&TPw@Fn-$nsgG-F-03o2V-(6iQkP55&8gm;pnAOn zS*>6G6RpwYkrU-pH4hhiqI?gOI`ccd!~E`BhKV@4boA0h8aIDt9hwmRXLbgbk*<|# zuGe5Xd9TDohsaNh5JTkYTJy*GH1jscG%RZE{TwU84HCn%xu@02P?%fd4@gWybFcZN zDxJaY{PVm?&i-y$h*^ytWxC9Y08vBfguOBk$lK%1gE4i?$~ei$uRbE`yilj<;Zrcj zl$Q21^InrC)ja*EG#utxRNWqnsTZtU0+T$H_~zy=b8&#hHDYT_z2J#H9;o-4y@F`Z zBIjS@@OaV=9GkG^ZQc2r;0$`_{Xvq**c-XQ^PQ^B{NVHn^N$QOurI_~MTeC5u$w=1 zw#d}^3%w_A>Y|6@^RdK;7d=n%{AIsYl5;*CyPo+{nEQ~R9nS}|gV5dEVIC)795vqq zthRB#vc$*>u&`TgV=o1@s8Chrg&o&N8Rq;(!)wO>&y~;|uc5S7(O8%1ZQ2tY_uv-|XbG(6f`hE0S;} z>PVa0y@>8~Pe-;>Q#_y%(LwF(d&4QoFFOC2CR19D&5`2PJ9)IYy=3xZ0nKj95uY{>K6@`!lZ@b)>4?t4fo$yVk=`D;3 z*7t(2+j~>d%Am{p59L{vS-Y*849rk+f7ID+4VDjGWmcpQZ49!JakO&I@-}RvU}KQq zw!vv%ARyOrx_xubTt^6sf>A5`U36ZTj=4uNzT57I6ef&;CVyi zO1_vdCr+I@HAMb-iREFBH-Pc|QTEtK#zp3_nL6K)v|Grp7v4&KOn4jlyTaSaR|@YS z|5|t_d9&~?^0$O{lNSl^A@393OGbfM=6z&XbI3=)iMynr-4noH5bh(tL3rKyPCiUN zDDp!WfHm!5@^3JD;20slTXc?)Y3s*v3|#UhIdAvdAiq#_Iz3K#yv*aJ9=Cej;&GG5 zjULx~T!oZ<$zK;9MCJ7p4B^C=^1K7G87Ka%#$k{3&!Rn*aZYRK4T;CZ{fv{`WCR?#0M&lg@xzD0Nk z^;42|4;fBH%x6FOv%*Koc=}UrE=1Z^Nn1+RJg0(7J|+59o=&x=(?XrKqO+EKf$(Os z)@3_+jmYKvVr?Z7zEBbpqKIrMx zPJzzrMW=XX9V}$n2S&+mnoHb<4e<@khc7lVneV)z+PiM2Iv-DNa*Ez-(GUgRLc7ucbCtm9EF9RnwSryYt z`SYbb%g8#e_K|0Ze7mPV;nk2oF7hd4y)KR9Cq&*##!`lLTt>!9h1^Ykm++v+>pcDS zWX)%jC*MNWe72J{pPiom9#4Otr+?7XKkVrr_4G$Q{ga-4=?qt%iDa$U6tb3QI$6t8 z4o>WlwymaI>rzYBw2fp<+e+57-Q=y(K11ZEgonY2t&-T=II&-JS}5NqI<4f#g-5CL4beGC`5Gx_Rk`CPkC%De=kc(| z8$8}g-YIz=Am1W<2%Oj{=RHjRyzmGa<>5Gdgsk;FO8&Cw93%go@F;ng@Nx2^!Y9aI z5jHcyTE_}-Fh8uPoQ6Rhos{dEWi1(w&cTz=>Z-o~`7g!YOiAx#iaU`%-ooHf<#DygH6G9P zxYpx(j~hL1^0>w0R`ToQywhi)Jm<+gr`qFsGK^>Jhb`o5ggZT*K~HC$C*MG>7X7WB ze1|9BO`at>2R%MQevZgT$>W4eXFL7LWYsD2&Q!l2j32El5=Ir9~bT;R|+>(ga1KzBe>*EQpcU-7U3<|Lg(e8v-9qzbp-azgY-bh|6yosC<-b}tt zcni5tcq{oX;cet0;p!V)*>;ifz6{5Z!wbQ9Pk`LC$no|Y9Zy`0e6&p_leL^v$Xd>+ zWG!bIS<5+{tmT|R)^e7UwVV}XEoUFNWRsL_9l2Tf1o<8*=fP%hm+(olw&%npPF_t` z`4%$XNMaqw-wf{2`jWpY`R^rvNB9s~&%5o7j$3X)Io~er*-E}sco8;TDrRcQ03Gz>?4tc)t5pvKsmO7oa9&aPRU&}`RitsT{r}52BzKpEr8uH{DJ^5ab z5C0kTpO7*iCx1-1B?;Dk-bdDcUeo4uMm#>W9P+P8+G8G@b|;_g@eGe^JZ|zhpkA$@lKETd3@O8QIAVgu5430F86q@$1NUrdc2OjS?a!#{I}W;p3X^+C#0Ru6ma4Z z=_gakdxgu$j|opFe?)i&`LBe_$sZD~Ab(i6io8|0n*7(oHRK0`=aL^3t|kACa6S1U z;YRWf;U@AIgj>j;6mBJdN_Z*xOTx>@dxTTuFA8^(cMA`LOD>lFyo0Rw!U$RKk?|`W z*N|T$`Yq%qg*TFK65dAEYq5*mFY?{w<8od0lOGp8OxEjlk_^Xdjulfoz}tj(b%Hla zK8Je2bA*p)!M6!-S_SSE-a!6-iG4rSKHQ4IIfW4bCZhlgSp8EIVLxwXPfm8wJ(*j1aj;?n@91{{E*MkIM%~I$`D{YmqCG^89G%mmfn*^>V41GGj}G&%J1Kb z)Z;QIEFU;GKh~M?oH7=pHwjAAv)AsO@pcLFySzxf1-_oScFg*6dR6GWWm^8FzFvX+ z-s0;OxNZZ!UV-Z|6wxzdwlg>T@jv^iJ;u5o92%(?+#_S@od+H21xFJ)ZAeSPK|qOup5|MI#6nP!pcWqrDlv_MgBgPzgoI>> zRyUxnLeeNnoQ%F4jWd&QlXqHTGF~P;Z=ohS9ms9eNtBVvIaSt(O~#A)8j_pX@9%%A zswrDc9Opjo^W5i6la>9w_S$Q&z4qE`?^9Y&`Gw?@+lt>cFNelt3cu^`Z~lxi#~O`a zFvrJ)KQp_E{ikK~rq>S}%6TuA^U@}rkM{!R1BH0+<@VFguA=3ngV9mF^TT-WoV+3a zb>)A^FSLMHX zrhO`O&Km7JRru=g+SjLzu6_L@fa|p9RsNg){=M_TV@!K-B4Pgr+Vit1n+ZPU-TXmw zY$N#B5Kf?cLa?h?9z#QY|M~QDyKRz2e+i&==Fn{H!Tx@G>S@{7dg8{A$h8M`^ktcc zpMaLVAB@^%3TGRWI&LPtR%4vkY&RQ>nVk;$N9-?%FLv6e{*tiCn8Q})wqml?FIcTt z=S6SUG%+^QY?<4Nmbsxg#F#!SN4)K}V%_??!r`BLreL?-m3MR7^0nrWZDx*^M0`1J_8k?i&hYxzzscAwlOt}uu69lE z@^nBv-3hOp;We*!5!MrKBWxh-By1$yLfCAw1q&EKdL!v3!u5ow6Sfh)kI)5g%kUwu zFD0F#Zawh@FC-f{L|l`IPfP9{D}j9;=rFc@Fx!Z z|B3@YZM!rEm^0(i|0nqW8em8S$x&^W4kcCxoCXX7h64^z4>SOczzCoTz*=h0#-0Ea z3d~)y3ytwMnE05Q+`s;7u4c@2OXhv_+$%1-V(Ge7#?PBJa~&>XA7 z&iN0^97_`ZN?~^2(cGqNtQSz7e2qEwXwn?RC_LuYnq#%JSqyxWc>54@EJIl*a9Y9~ z`#7Q63#W1XLfpv`W{a|YMBjc>*s@*~|{#gW*Xn=Z^2-#l$w-g3>WCEM|K`}5cQ%kQr{@|(Ym&IQbk#kpzBkGAEL z&M0VKR500n$r|(EQQN5x6t`P^Y~5SKDbAr#XR0ZVAI70|v}vOa)LvhK4@}HxR7-zeryDe{=`y%=uuQ^n2nM~svXGha-!KpSnkK9+T zOZ!*i^i96b5ve*)@gl2-OO@3n|AYhcN8o18~3rIef;Jy z9qcIf-|+_h_~G!(q@(cvsAS&ToQ=(&k&PW4R$5QvQ>-~~b(=$>J;aI5x>_??WK8os zlXWy{fTI zC9X3|ES1flIKQiyaF}PeBRp|F>yb7yv-?KIq4To-{$s?CYCQzZ|2GMBj_D?hGjHl| z6!_|fm(r|>x1{Ys>DZt&eY~Z9Vo?GA4~(>+p8!n)GJo zxV?A*`lvIr3;)4CBWD?SV^Y>f(LapwkvIE)TgjJ9t%}AK6pTSWX8NJyAb;SR08Yv7 z#ptkk)X{uvtw;S(X8+k{*8Tz3_{(9|E5&EiuS2~%L<@D^M_T+$c4TA6Ii7a|apv{- zoJjA57P`)E^}|@k4@-WCOyPL@z85RBeg;~T&|J$pt#O%i&kxTAr^fVa&ehaC8qEtb zs(A?x*O&BqthGBdUFh#DV}u^H?JKuEqA=r!Ll|4q z@xwRRJ50KpHE3Al%cA~g(EsCI&qnkhCsF&KmfJr^sJWE>mRtzevnosb;frz6mnq;w zX_{aFXIH{CyAs-aq(_A-?(B%xym0(Kw9_1A8?v#s&$Aa0_PV|FySTvmvoxQ^-CsQ9 z9*^?yZ8S&v_jrHYQQ!1g$6lvC9dxX4UdTR(Uc)EkhkuFukbhKrCo&PrXEc)aXpQm< z->fgmi}u z_PpqSr+VQj>Q#8mS_{|0uSmCOe2gbg{gLIqMwa_}io8*b>0eYvXiQhpqtBUD{cmD? z8v%{e;7b#~jKLuXR`-v+jz2@~^p0~S@6K6Yq#O*}~=ru24H*7D) zy0!K)g?`JVdYzZTeq-fbYPd@CJ32XLa43|9kTP z-76cRpbO|sW|abA9{W$24T>EDDdz@0U`U!W8umIoHs3QK6RgYG<|<@bUFogs%}M312022#bX0&<-1|Io^G5 zKJK4U6wSt5TQL47_E7iR;OtAWzp-ca9ZJ6xe09#a!1L$jd($t4>J$3*UO8z8wFYm){bk{9eP`Tjz@@$O7D8w)kM%d9^3$2EjnHme zE4Ieq3q1HusCsTWKbzSa6MZ+6hkev@BO&$no&}y&#K~{mLHusoYOcihJ4kOOy___A zMXH1N+H%rme_exqyrn5n97QLl+Q)i@HQHTM@Glj=+T#@o&)qCX|$yL-(~knKzX`AS*o zE%_JBSE97^t;VLj8m&j_R?1j=%@NK1f!R})a@ki+^W$yTp@V#_(3L(|9O51wY+EX`IRX2yd64}G_HM(3! z=ULsCau1gu!QH0H>p1sT>^$Z8xy(I z9`6jI19}JOsMMFenbA2Q=NBe&t{>(x&%&Ma!!@4Hqa~k1n|pt;4H`rv_R1{LyvBL3 zX^oR@T4S~~VP}q%pJh#uElz|lk*yD3W=CfXaC0sZUJIJ>d6apxsJ`U;SX@|Ry1>)X z1Yhdc&`%uOdSclo7Ju8I^KtT$l!>ox^!Hu6H+(cL8$2W1rg<(*WRXuX#`GwY&Y;pORY;gtQ0e4sNfOt(@Jem;6+Tz0Z%&vcCEgpV?vL~SXP43~f zZoW?1&ZUDlC$;B&^0$yS-bF!YOM7w4{&vRT7q)?Oo7G;7yRqVyF*}Oc9KIM&a?w%T zNq!gbxV=AYquzH3jn`59A?LMcq1m|Gi=%UXVL7;$gL}E!ksr_LOkj?UAYZ!aQRuV? zA0TAR`HGB8g)c^bTNLsZK)@oX_yEN>AOAv{aKgB3taB?qhl-zpxwPBxGqn2Qo7fR1 z?T50@M!6*&)8=*-Z!w+4RZb`C$`98Q&Y@iAInCqF*3P2IToT0HOY(*>bY(h=59B(F zovpiyJIw>dEsQ1JYKmRNS&K!VGU0iU@H>oc4g83=brxs4oydvKqg&y*_ScK@|1LiS zi8m2P`A2P}Z@a1cBgQ0ONQD>k&Me8$Q{-2C z&l8Ys)>g?M4UcrDoey1-^SFDT>=I;sab$nWS9TY5t7mQX1>y&gP=l#$Q8UHBCB$E<_HZb(rod zE)Wgi|25%8qji)iP(KxCPM)Bx%Kj%Ic4FZ{vn9XE*@8|m$1VdncO3gRXLYB%uH+Ze z{(U?3jq?@OxyHMwpuIb?xiiRUTDBnbO`TPlY;j{cTg(ER0ApxF|FR=AFY(APbXPH? zuGaM@3FQmYxql+OMpFCGS5cc)P8TNhqDJYl%3h$cUME`8e%MQ>v8*5zy%m4M5~bmz zm)=qI&=X6`^~87aT6*GQ@;=Wvf3Gtq=}SnvnpY<%B-tnQ4#jddPmZPimZZ}$ZEhJy zg)eGzf!ffI#-C)qq|YsPZUb%VlWu#{^g(SNXKiX6@~fnY&qEibk>$8)D8${18fKEV zocjEQj^8+%JuTYjm?PQ!NuUmJfDyn*Kzhst#sSh((pMfZ6_^dEFAF;5ua+NDK3yxl z?E8CD_Hc`I{~hf|lje)~5lZ??c;tJo;PT#ri~Spa(euc; z>;?AHSFGc=g0HJMJLtlf-FuXI597zL&v$}Dyl)fFOu)FJy(+{8ZvHpyniaWS#T6c) zdB|amVE?r~dw2$LEF+ct5WsMF#xt0z8{r8&FR&aLw+exNUsxBr1| zi`LSaTcZ9cE2YP5X=E)oTk#PEn=*UMme?rpNH=$LXJR=WoR>Jikv7mG84@kXwQa|B zEvELWYE$1nIFL8w*AC!kaDU2!S zDc(+8;Z=k3Bn#T-!~@Z-eNq7Pw(_NfAEIS zdOcciQ93t}*1JLFYb^2$pH&n2PiMvAiwg72u4(A$Y3PDkv!il&$hwclQ68_(r{mnx z-K^->T6>xMw2HkUJt6!L{=VPdhK#;^4!rknx1;-}@;&PCz^~`trhaK|S8;gj#Mdly zTE4EAwaOW5v}5JpXIix1H*@YmmQCLoq?xp4_UmK1Bd*-XzRBGu@)T+h9G+os1c&gTQ=Dy<8sLg%FG+}hs^`vz#zh37! z&UOEd{8i+AgAkcuJSADj)=Zv8zYD=(F$M#_Z$S3Pk(Mk(`=QI72XWbXAE!+A=>x34 zCx8bTuVms`;x7OJ@H4=U^=s$%Xikj@4!Gjiq&e%-)Xf+)keQV^2%z9M64t zVFP*EYbJuvpH!mljyn8oaX)mE+?i5e`boB*aCd`Sy2l~yxH^aVg)-Z1n@k9P4kSaPJY zBzVsL)k(X01#hFZzvgIjobi}6XNEFQ*|VB07kb?iPhX%dwshDzmh+?H_1RY~w7?Kaqe4L^F1oFbG#p5e;S7Wua+|T6s(MY2>o+7dY6)0n6H#$ z6QsC@$?F~l*$6usv*v9+d^6Y^3&p>uIYL?{j;@Mj2_xGBo`5s_4D}~6o{7*GU)27p z?tMGQ-ruA-tsl`*Uq2$SNGB}EHl2-|i*056!YllGt70*qR((g%*|?+FXzDow`!Q^X zk}rokCoY}z8t?M+v20Km%+L8WvH*X&xf`>13&9vuQJk}1Y)F>; zf5M+=`Yxy6ZthyFy86hka0O}IBO`--rd4N~?ZwN;6OZwkhVkC*_KCapB~!$?n@Zhz znjiY7b%(D=Z?^1YoJ*p#9?6j;P!Fi({JXT|SzWZG1g{6gA6Q3+}pSwR)+WyeVc=s8HSU>nZqqcU? z?R4a=u^oBlgLexZMQdz3esJcQIOn3`?|)l5dtpnoSL{*rLils?qk8UE^iF&67o;Uq zW{!#5r}*BW%UID|Yb`SGg=f)yTBGpbm~Humnvs6t--t*0VVG0en}?P6=wbCyy1ty> zG|WWlrb@lxrTW7CKf%FTiTooKUiGOD-izsNljNT_UITaUzalO=qJGP~)tz{Cedc?h z{!fToC0wZ&iMw?^ceADb)W6OUm2&1i8qYw!W%8A}725uZI<|e1wr5D|{Gc|cqHW)x z`u|u}|GUI3E5eof2jZ2!giH6qm9lQ)8gI;X_y$FH8znznLhGb#pGYr_8R>`G52Qoo zZyqxa8FL9IU`s3HZY)N=%G>Bey27*~&*%qaY}S0%uY-R=cl@%yYv8@!5yUeW=T#@( zdZ+Fm&XGQ8!vocrdyOCzfk9zD4F{eUv=}tDHnKq(9ds%d* zN@gRPV_t93c6-@-dRarg#n?Ff*dy9QD_$x;A)2Arw25Z!hS4#idm(ho-%)_p5f1(p z#-+1$y!8_3*8SvNWxB7{JC~%si>Wa`c{Q;#8;Vw~3+7&AYH?FGP zsPbGU@!h5vpLDD2m}J|sAnD%|{1n&ODbGyBHiUQD555Jj zB7F>hCzRz*dPI0D{siectrPh%9W&`Q{E$aSIsVb^{flUW-ZwjV>*ybi zTrRX+JHLnfYsZw%2VL5OXgd)cqns|c{3 z|B2>6Y4jDo#ZsQ+tB!d~;?I>&HHkB<4f7ajsRp}MI zPcu37S9(i!$U78R?&7@V9e71N&>X3(-?Q@Qw-oy8l^8Y(d$28js4jPik*`2?<Fq`CC5z+b%gklbTe2Ou=M&z+;&9V-bh!CK z^cKuA+wwY_*vysoOgn>)Y(*c#8+1!}F6}vc_2A>!J(lLgo*1D-*Dwj64X8B5=0!aeRz-VxaJxwwE0(yaDB zi%GvOmVJJ>-;qqgXXn&>J`bE{Lc97xZqXwLiyDt?wZY?29qx>yF(H$<^ACPUW7s&B z{+R#D80xqW));npaVz+?EY_fv6mFu`~%$%)Eh zzzMRDf1kGDQiJdzQ3DV;zc^^)>vVnTa72iDl#&@^mMwJVU+3v{zf@;md2R1<+NEaiD_hvMOBY zwg}fe+Ewu5*NF1o2@n3q0bJ8*S9!Bgq3hkWn{Wym#)503hfYH-V$3V|fCbHC4Ed2< zXdSRX`r^)!B03To<*fi?MxF+EgFMF=XCpjoV(uee$X`^c3&Z$d#Mh{ffg=1ogkS4vOn?W}a=_x>^)`#lx)hE}$obh7cgL)NHtaJQq(6IY&mw|g^X=$Rh$ z!0zS5A)|-&mXgnQ6>05R@-qkra@CVeBOBd*4BvR)M)L6C_G}WQkx_b|_ z>{VaOctbg(>u$)n78`hV(c*0I@6w~_d*)++554A}>v;#%=rN!0u!(vN>9TB#Uy{3| zcnr_5k7E`eL^NqpoS74gn)l?(}PDlU&?yetmz*Il?ENJ^oa)-|lRYc22~KA+2*uGjLCKfRSkMkAk@_Ov8zv}V;# zY2kps18Ik}J^Pp`Wgcy;WX+TqUnJHBq-=VOd_azv&&m=50hYhZ*=+niJ**`!$X1 zZihuzF}K&D*G|fs%I$&jhl=0C9GNCL5rSL+0dCUc~?A$_E{23zJ9_o3pv%9t)axkj0Pg?(_Hxo>w3F z8h1YN9R7pni!t(S{2lUj#7QSe$4MthpSbj-4z6cjFM|hZaK6lYMd=_H*`0&WAOU{% z|K{8j?jFEj>C1rUl>MlWLHIlW3vES192!`k&GX(Rp6aoUcn@u^_#?b{dh&bc#kT)K z+iG6Sf0uZwc`@=mv`Haz7VB*ldSgx3_WV?AmubLsY?&FrOklRRy_iN)e=s z-uSIjzOo`sfWZd&#oG&}@5tO>TSs zOmwuzno6V7u^V)nuFG?u;HpU<26XA8A{54v?x`0T^mf_}&59!_Wa zYl}9%!o`j4VL#`I;Q)0Cp3^>=^knqoEYYycX}3w+Go1DYLR5Za--lLk1$zGaf@q6p z=jV^`yD{hk^zBu#^GY-~wZKb$rv`ie>cU3GvYdRI`qF7?_p+n)x2Q0wT%R@9z#NWb zk8NOIuh;qVT-s4LK^gZC`;wGJ=WD+2DYz%g^3`)MowYHGKL+Rox`3U)1Aq^F9rz~D zk5Y_$Gtj_zcWd94FI6(2buBujKjfo{2fg^Gus^cq4F1Vzd2l zE|6gEvB{c;IiqXeUR1!Z zL7nKGcIxN&AS{>P(a}6mZ;zJ?E4or+RsDa2PVqo#*~-VUl_#SA*P#F18M}%r(fc1q z?|%%vA7dXtzlRokg3W$Bv8?}(SJ`M9kK3*Nm^a(#fB8+5=z5boSlrWnFg%y<2$QUr zAr5+%x6$l6>`^uHv20yvNxQ+M`NmaQRV2PUqh3Ke1oHm&ku3zfdsky|)#u@pqs#+w^u?W%sRr zm;F`KIPX2Qd7-?w!qC(o;^~Vc-cF}@`U3m?d*$ha|An@Hh^G@zL92M`z03Zpd1~H6 z8?BFMJ!B=H>1drup0OWUSI-t#BM&gUXCk`nQsOTWznJhR$ne?Fc?t2)5ULD)$9;wT z8Ig?le2Vlz(tl3+hv+Z$Rf~O!E;-B@CHgk&+q|XxwR?oUE}*}~>_uj8ZOL~Q*`u^c z=qzWorETF^-Rj3KZq@fT(n0!mxue1GBN+HjnoDcABX8Ok>3f&Ci>RYME$1%AmJ#l# z-!H4r;7E9`bce5TUSBZ5+C7uH{cq>k<5|Pfw|)ON-yq$8-hp7@{`R12)RXAmD+15q zHy4~W#bK=3`x|}~JVKo-LcY83?}2yM7xe9l%~=*-;9jeHe$j4S!(G8;LE7d{yL{d} zl`bpME_-~D{D!-2Bbw8EyOW9b*618+)_`MCUUxyNKLj3H{C=DA&?WGG9sA58+O5$! z72RCkJEODcnkMNol~vYJ$&O#svRRT0#^%qR*#aM0vq6mW^r`qT1U+uGUK(i4*zV@Q zbg^&Jhv%`c;CHX#>}7e;`1YFC@^_-_XF8)R-vV#aJMtayKXyWMP&vn|z3S*3Uuj?A zPh=~s;k=cRzd9w}>P)HM!_&TnT$lQ%T{KU;sZg0^u8MxI4mphG?2rQ;lqoG4(U}UF z!w(LwQ}7+UZ{fQ=i0}Bk#G`!m8kZd+f72hcL;n1xn{KM?vG@M;^1RFV?QTDOKlWy? z`!6AUjrLagt+fVz#W%#dqZ{w=#*_Ec@)L+3I=d);Gqs} z7>YeCdi2mD`5W-xE{goO@Uia|;A4E3xdONj_yOtf15X3`zIG8bUq!yYt!;yr#l$xd z#|P2F_qY+Bdg{to_7A{!f$sqGsV86AC4?6P^MJVk&Vat_$xjnr2z&%MLV7mgazcIY zJCQzTlHN$1Y3o@`zf(!~lb%fIvL5A+M82C>G?c!}U(ta7CR1M=4-Wja^6f=sygSdY zI1`_T(@=CcE5r%q-@&KSr+1ovte(b(?mcB+=y&wwsmstSeS>L}KRGedx8^MOEuH-n zqlmBYEzv7K^C)xyIGf|?%6VkVQRD5D-wB!@D&Bkk_WUKhV=-;r;qgc==)bD&z07|C z`KmKJkA8#qC93yt)U)fh=g;MSr?xd6{0h4MPv_s5GXMHB3Hv|8yZcuCwqb?69Ul*}X5&YN$E5M6I(*0D@D>mIx@vwjm%7i?eW&Jf zsNT0RN1q?m&$j=~{d}q{GdB+EXI;6U1mi(3L}RcgYTqc0BknkSgCgC;U2fy9#2qJ~ zm%7*odndN>yBM_BxCiPp?$NAG?Vm5K+m%pV))#kL?4PYaLDggmSCO88JhM-Q>_huy zYpA?ZcS7q!B_6qv&#BN^?i1N{E}^dY*Q2+Ut$uis`e*%1p7jk$qywCK=Am@2bZ=DO z^xa(!W&3D7Z!M>_euo0aZ!cyEyZ!zAE=?(|J1gb)4Cn05y{PW2l>T%%TtBEB-5Bvg zd>P;ecc~V8?L>31h`vOhmg1_TeDrd3@AGAihdXur@w^q49MLD^uj~=0()Zdk;^v;9 zde0aIA8OL_UGTdtnrlM#(3p!I^L}X1Zv&i5-XwI53uupe$try(3?HyFOTUq0xqjgf z^)3IW#oL~7(L65I_vX9R_Wh3Rsz2OTZS)%ioPR@XK5W&ib*C8Zaoj_OHGgE>8l%RC zy}{cV$?JOqD<^Z14erGY3xhSjq?ijx1|G`_>BYT=Y6o-G!dLwtpr61n8%>jfn!QARQUTpHn zSEO>~m)>JUZ$$99L}k%$>BNzL*)n$h{({Z>KjXB6M|(W?FN{ev%Rb}2CLh-~$K|?l z-d67P!V_8+7+sNBS-rhldR_JV{T;I(tsA{7(a0|)%)}S_8@6&lxtogBKW#Q>V ze5)urxSNBw4-cwek(ch-{r%Vc;>44q*Zz$q-|2%JOy}%ZX5210$~zbYL&fpr+45&HH>~q>jQcWuM|Jf+tX}0R<4ib9{!9yf zmf&ru#hYI6p@yS(W?|HqvpKMGb6B%lXD@Tk7M_mD#vGWY{)8vN{L80noCC$5^R`XC z#LAml%USpedZdrKq4aB{6VZ**ZRpDvZaq22`a(C(VpNOV)G6%-KEH4c| z7mE+)81p=9_&Ip_u2r^ zEZznum_Ms^bH1icW5_YKs|sV0{Y227Pjq+S)&EbrP^^m`o2dvNZ!0Nvg5iibafzISfE zJNU*9`lZj5?-#y$_uWCVYaadFRE)!m2c~QZ9-ZTd+)4EO+&dKh+rnOwXK`8SZUYGq6D=NyXY6b{ii1{$^J%8powd}zH)Wp9!!Yn_0v zXF9YDH5Y+@X*db|*qVK=vn4+PKIylx?jy|t<$Fuh_eJ0fz;<98Ap7|qK=yMda2IeV zuoc(>Yz8`jvw9;E?{W|2?v}M~F z$TQ`<8C7|<70>&lw*+T#ZrqP<)V_I^Q}RpDclbm6oR%3;0B>Z=MtUq4{jMJ0cD)?# z;lEW9XFXZil=}VPJ$%c>eOsRO&UZtyN0%1#eV6c~BMxhy6^~A*9~(KDAEkpr18LdO zXJIF5Z}=AdR>txK_WM!5Y3DaSfSEuVm=9!t<-iJ{6<7tV0d4`>fc3yeU=xr9wg8=g z-V`s_8qBixTG5B-Vx2{F*8f|b@7Sl<_Zrz7W7b0HOY{h3x_7Jb{BYh1Km059dbaXr zlX*tA9rvHlU^nYL{!DQ>@}6*>DeB!^1@D)@E4xs7Bx(a6_PDemtkj9S&lFk5@H|tv z!uYYv*s~*C;1n+DZT9`tV0vzl-;%Ldj0HO{I#+2dXX`AIF6Eot7WVl~d29NejHQ5% z!Cv&RW1Mu}&ea9b0sRjKw)3^XaF&U;ZZCcWTBc=Nxnq}|4_ z`7Il@7mp@WFGZbN>P%)%>!3%!HK8$UEES9$M?ZJmF}D4?hEV>TcDdg(|tO6uTrUl{O$d@^McMXdC8kGbAmnm z=8wuXx3W)cXG@SU=xEw|_)ugcl**&uG1{v$pU+%xa(5NmFWk&sXDo>2GQq>H9o&K) zXnXsEiM%a{jpoeb)&+*Mgyr5x7z@T)hVbFwO#L3%uq@^G1^T9XOvA&0@oa2zD;Uf7 zKXx5u&i%oe;~ojd@Xo>J+a7+qAviPnNPx{B^z%)N?5nHzo5J64{TaR`#75S6tNIKT z#}-{qAI512hD0*5h_e^p&nwR~Aj6y;;6LM!A*cN2L-hSYIN=oKtii@uxtuvDRQi!U zt5c88Jh5C$V7H9D=o!l_u;EKAID}oo?{+fQVcyqxkC6$6Ir{@U^b2Epc*D{3h0w>Q z&nEb-n+5pTYt}ci-=)Sb;QQBUUkD$WwK?n>^y5RR?dHhAQ7<-?}8(!}Y6;7s3<9Qw7l&Q>xTdEs# z9t&7Uvt$ccX_H^+bcd~GOSr9%IjFh4u$g|d=X8fYw6>?R+Vg`kr*nRTe%op&=nTfZ zSRLFISgvDN(w6DMo_;v5GmGZU9*TVt`d>2v@7RC%a-j*l?dh)Y2Ii$SZoa#$j2oUT zqa3~z@Vhl{PTvz13EoE2(=Kb%Yn)lCpBx(45Clg z6n>w#U`xpNvMIY|bK$(6ZQ<9jF{c!%UVBYalk#x z-ZXY0zPsJ+--p)y+X_BBa>V=3AWVeEs&1XjYw%!1Uu`gX{rM-?-zT*GKHWG&^IP9uuzz^q z?ecQ1>TGCCs}6EvfAr}>U2aRzwHUbV&LE!tN?=<5Hos$CHj3An?qJ7l9jwDgu+_Vy z|MH3SPIPdVWgN-JUcKw#tjnJBaA0fg{cuJ8Mq?JR9#VCmV13qnTEDll;GJaRczNAP zCMxmD8my!%Ymjtl4YKY=fWN)9E8M``ylq`DPT0k|+fZ0T`R2@h;Z3AJp>>zJKl~(d z=rd|v-PW7(-s$a8 z=+v-(<`xF0qD4IC+spx;KdiOMn%#_S4Co4IzLtJPGq!iLXqrpzr*DpEYB&p;(({6?^f%RPDvSjOcK-s)Wo@tzPEBvi zOBcsn|6$V7!;iQb^ep;y%J`13ajJA-M`K;?7V7c6zM-B&z1+e_-1IGZk8g?Viu!XoBad(BXV|*9iE3x^zQe_jm$%7{@=PsZXsWLq-65l z?U5PQ#!#;>D!0)mLCfE_OzEgF5=tA_8^p4ie zNN9?kYVBOf+8KeIrdQ=XzHL_MU^m5CJNPG~`|)=pZ%$bkyqo=DFm3OJF80Cw-TDpH zcd-^Kv{mmf)waR{`0}>(kF9Vae3Y%gnvZM+<}^j#DQyLpGVR$jsM|uF|B9`!@*Ql2 zk`7%T-AxMr2k48vFzV|}`bQT=b_4eNfZb5B7Z!r^z3k=bs&!i7W3?WrW)u{ z_U~=EY-r~mR9Q@NGpL;QOQieWf~WMpG*iI$c#rxG@p19pEo3a#Z^_?-FRrgb8~luD z!>%|LZFE`rPPjyywg14|Xk!d9=&z<_pq=i8bUu2$Obh+b;&<*NTCf-IfwsQm%S*mq z?gh2CMCn+1Oz?CX+a1uJX)*TW%S-#O|8e&9%+}zMTRAJW-Wk-ieknv2nr-wjd+RYP zJt7ZH^*P>{RoX=BROdYY8$HGeu^FN_y1R|LE^j=}u9+R-CCCxJvx3!H+UJnJ1$vic zqg!L%w*&6Yu1(ONa3!$AcoQXhQ@RT+*&vU}H+rpU6R&`7egB3ZGq(+#SLe}5s7l!? zj|H`D|A1aE=|t1^lYCw7!C+|je*^cj!q4^J{iHsXtLpz9^-K1zY5Tjk)aP58-Lxs& z#}5Zq+X%i}@GagMSvt45ZCB-6YW;^fyX|({R_8rz@%mc!O>A@c+D92@M2$Imzr6P( z&q};HnWj#;p3cLSe9fOpYyT_FU1Y-#nzI=E{Tt?8b96UzRO-vG7rqJ}E5}~9zYbpN zTeQ|a@NJKHZJd>Ru(P;FjP5;AH~y4QaRwOW@{W13AC9fzEx3Epb7N=vhsN5xty6re ze@JVL-;sQ7>}3CtgZ&GhXr4OUj=+B7i|`s7$a^fXyt%j~yMsT)|G(!$q@!C#F)ytR zmPhEU)b|FV=Dnm-PR=>$mOst;|M_yNIoBKuWY>;LV|$}J^cyJg(%TT$|4v*RnMS=6 z(032tM2A^nMP1FYhF1=PpZNE#&&KAI>;I1ULB;zs=Gl*DV_O-F>F+fQS7u`mDIYqI65q;ZVPf6pmetu< zyXuS%%+GGh#=fB{^!q4uOj6u(O#E&CYOHwW-`mRGUi%`e*ZiS>%j0kV_tyH0YO4O( zi{910Y7C!>SN$`edRPA{?U^k8Qgaqxet~=2`jzX}-*%oh!zjIa?W!ncOwtTtgB)sN z@FQVrOp^beS_NJp{tEC*fZw5s@^=z{6nGqX8mQF$-xZEJFB_ZKkc~mA8GqZX@vGd- z%C$G&I7?&U_XwgtP5U|gxfgG|adq4Jn{Qp~UU}n<8`iB`y~rlER~E~PPt~`;*;^r+)`X^Tz76}$>MUgB`2eEGcD7iT=5UM^|p_%TYcN=_2+?i z!`i=Cd+TS`x;NhX$xp6ayUL{bU7dFWBdAB0W;_>lb1vVMxt#dV$Q#F6bcwG8^!F&g zrLzj?0jq#k(hm?G2UZZbj6E=awF5I+XHGN2_+0?Uj4@}Lv1XhZZ_YAjn+fJa zT$|UM2GeLpm?m?&d7nAgOfu)27Bj_6Gc(Ku=FiNB&4p%;nQJaKmzvAWN6qEtO0&o; zF;|&o<{ERI`Is4L-j6ALhT+wRnP|>4o|$Z>n(1bynPq01kC?Q%$jmdBnE7UbS!nof z$t*TY&DCbPxz?;O*P9QR51P@&rSpH>}+RtXlcmO_$%gR-ow84XXvWDZXs=D#6-PYU!E{n}Bsu z(Ix9{-UO)Dl9lTP8`hD46tiIE+D*WQmFqsc>5|nq2-Zc3%U7=31l+i0)10<-f}3w4 zP4B=0hyhmff42xeyJ^mbKNoDc4eYDi1nXCS@`lyxHeGq+dcm!VUvcZF1*L*{t8d%{ zL<#8dHhOIsRA$m;S71^T-n{lEg-R+q>54g5MEPr1Mxvr*IjU?kZR+F}uf>}=ee%@F zGp0?R+%m)Srp%Z;eX8e8oig=;8Q#ok(`K|xo_T>ceeyKwx3si)lP6E{CQl{ZGHv>_ zsovDdQ>IU8nLd4{cY!x^vNxqg6(>)bJadXSed?6y)27Uve!=t#hL&lQr_G!(fX+-Q vBc3rcYGyzg^;5!Pj8ZC5X4F44aEFcru{VhxE+M9nF`W#^q#hZk`1^kW{83d1 diff --git a/build/tools/makenorfirm/test/wram_rbin/Makefile b/build/tools/makenorfirm/test/wram_rbin/Makefile deleted file mode 100644 index 8e7621d8..00000000 --- a/build/tools/makenorfirm/test/wram_rbin/Makefile +++ /dev/null @@ -1,48 +0,0 @@ -#! make -f -#---------------------------------------------------------------------------- -# Project: TwlFirm - tools - norfirm-print -# File: Makefile -# -# Copyright 2007 Nintendo. All rights reserved. -# -# These coded instructions, statements, and computer programs contain -# proprietary information of Nintendo of America Inc. and/or Nintendo -# Company Ltd., and are protected by Federal copyright law. They may -# not be disclosed to third parties or copied or duplicated in any form, -# in whole or in part, without the prior written consent of Nintendo. -# -# $Date:: $ -# $Rev:$ -# $Author:$ -#---------------------------------------------------------------------------- - -SUBDIRS = - -LINCLUDES = ../include - -#---------------------------------------------------------------------------- - -TARGET_BIN = wram_regs.rbin - -SRCS = \ - wram_regs.c \ - -#SRCDIR = # using default -#LCFILE = # using default - - -include $(TWL_IPL_RED_ROOT)/build/buildtools/commondefs - -INSTALL_DIR = . -INSTALL_TARGETS = $(BINDIR)/$(TARGET_BIN) - - -#---------------------------------------------------------------------------- - -do-build: $(TARGETS) - - -include $(TWL_IPL_RED_ROOT)/build/buildtools/modulerules - - -#===== End of Makefile ===== diff --git a/build/tools/makenorfirm/test/wram_rbin/wram_regs.c b/build/tools/makenorfirm/test/wram_rbin/wram_regs.c deleted file mode 100644 index d2cdda90..00000000 --- a/build/tools/makenorfirm/test/wram_rbin/wram_regs.c +++ /dev/null @@ -1,89 +0,0 @@ -/*---------------------------------------------------------------------------* - Project: TwlFirm - tools - makenorfirm - File: wram_regs.c - - Copyright 2007 Nintendo. All rights reserved. - - These coded instructions, statements, and computer programs contain - proprietary information of Nintendo of America Inc. and/or Nintendo - Company Ltd., and are protected by Federal copyright law. They may - not be disclosed to third parties or copied or duplicated in any form, - in whole or in part, without the prior written consent of Nintendo. - - $Date:: 2007-09-06$ - $Rev$ - $Author$ - *---------------------------------------------------------------------------*/ -#include -#include - -MIHeader_WramRegs wram_regs = -{ - // ARM9 - { - REG_WRAM_A_BNK_PACK(0, MI_WRAM_A_ARM7, MI_WRAM_A_OFS_0KB, TRUE), - REG_WRAM_A_BNK_PACK(1, MI_WRAM_A_ARM7, MI_WRAM_A_OFS_64KB, TRUE), - REG_WRAM_A_BNK_PACK(2, MI_WRAM_A_ARM7, MI_WRAM_A_OFS_128KB, TRUE), - REG_WRAM_A_BNK_PACK(3, MI_WRAM_A_ARM7, MI_WRAM_A_OFS_192KB, TRUE), - }, - { - REG_WRAM_B_BNK_PACK(0, MI_WRAM_B_ARM7, MI_WRAM_B_OFS_0KB, TRUE), - REG_WRAM_B_BNK_PACK(1, MI_WRAM_B_ARM7, MI_WRAM_B_OFS_32KB, TRUE), - REG_WRAM_B_BNK_PACK(2, MI_WRAM_B_ARM7, MI_WRAM_B_OFS_64KB, TRUE), - REG_WRAM_B_BNK_PACK(3, MI_WRAM_B_ARM7, MI_WRAM_B_OFS_96KB, TRUE), - REG_WRAM_B_BNK_PACK(4, MI_WRAM_B_ARM7, MI_WRAM_B_OFS_128KB, TRUE), - REG_WRAM_B_BNK_PACK(5, MI_WRAM_B_ARM7, MI_WRAM_B_OFS_160KB, TRUE), - REG_WRAM_B_BNK_PACK(6, MI_WRAM_B_ARM7, MI_WRAM_B_OFS_192KB, TRUE), - REG_WRAM_B_BNK_PACK(7, MI_WRAM_B_ARM7, MI_WRAM_B_OFS_224KB, TRUE), - }, - { - REG_WRAM_C_BNK_PACK(0, MI_WRAM_C_ARM9, MI_WRAM_C_OFS_0KB, TRUE), - REG_WRAM_C_BNK_PACK(1, MI_WRAM_C_ARM9, MI_WRAM_C_OFS_32KB, TRUE), - REG_WRAM_C_BNK_PACK(2, MI_WRAM_C_ARM9, MI_WRAM_C_OFS_64KB, TRUE), - REG_WRAM_C_BNK_PACK(3, MI_WRAM_C_ARM9, MI_WRAM_C_OFS_96KB, TRUE), - REG_WRAM_C_BNK_PACK(4, MI_WRAM_C_ARM9, MI_WRAM_C_OFS_128KB, TRUE), - REG_WRAM_C_BNK_PACK(5, MI_WRAM_C_ARM9, MI_WRAM_C_OFS_160KB, TRUE), - REG_WRAM_C_BNK_PACK(6, MI_WRAM_C_ARM9, MI_WRAM_C_OFS_192KB, TRUE), - REG_WRAM_C_BNK_PACK(7, MI_WRAM_C_ARM9, MI_WRAM_C_OFS_224KB, TRUE), - }, - REG_WRAM_A_MAP_PACK(MI_WRAM_MAP_NULL, - MI_WRAM_MAP_NULL, - MI_WRAM_A_IMG_128KB - ), - REG_WRAM_B_MAP_PACK(MI_WRAM_MAP_NULL, - MI_WRAM_MAP_NULL, - MI_WRAM_B_IMG_128KB - ), - REG_WRAM_C_MAP_PACK(HW_WRAM_AREA_HALF, - HW_WRAM_AREA_HALF + 0x00020000, - MI_WRAM_C_IMG_128KB - ), - - // ARM7 - REG_WRAM_A_MAP_PACK(HW_WRAM_AREA_HALF, - HW_WRAM_AREA_HALF + 0x00020000, - MI_WRAM_A_IMG_128KB - ), - REG_WRAM_B_MAP_PACK(HW_WRAM_AREA_HALF + 0x00020000, - HW_WRAM_AREA_HALF + 0x00040000, - MI_WRAM_B_IMG_128KB - ), - REG_WRAM_C_MAP_PACK(MI_WRAM_MAP_NULL, - MI_WRAM_MAP_NULL, - MI_WRAM_C_IMG_128KB - ), - // WRAM Lock - { - 0, - 0, - 0, - }, - - // WRAM-0/1 - MI_WRAM_ARM7_ALL, - - // VRAM-C - 7, - // VRAM-D - 7, -}; diff --git a/build/tools/makenorfirm/wram_regs.c b/build/tools/makenorfirm/wram_regs.c deleted file mode 100644 index 68ed4689..00000000 --- a/build/tools/makenorfirm/wram_regs.c +++ /dev/null @@ -1,96 +0,0 @@ -/*---------------------------------------------------------------------------* - Project: TwlFirm - tools - makenorfirm - File: wram_regs.c - - Copyright 2007 Nintendo. All rights reserved. - - These coded instructions, statements, and computer programs contain - proprietary information of Nintendo of America Inc. and/or Nintendo - Company Ltd., and are protected by Federal copyright law. They may - not be disclosed to third parties or copied or duplicated in any form, - in whole or in part, without the prior written consent of Nintendo. - - $Date:: 2007-09-06$ - $Rev$ - $Author$ - *---------------------------------------------------------------------------*/ -#include "format_rom.h" -//#define SDK_ASM -#define NITRO_TYPES_H_ -#include -#include -#include - - -MIHeader_WramRegs wram_regs_init = -{ - // ARM9 - { - REG_MI_MBK_A0_FIELD( 1, MI_WRAM_A_OFFSET_0KB , MI_WRAM_ARM7 ), - REG_MI_MBK_A1_FIELD( 1, MI_WRAM_A_OFFSET_64KB , MI_WRAM_ARM7 ), - REG_MI_MBK_A2_FIELD( 1, MI_WRAM_A_OFFSET_128KB, MI_WRAM_ARM7 ), - REG_MI_MBK_A3_FIELD( 1, MI_WRAM_A_OFFSET_192KB, MI_WRAM_ARM7 ), - }, - { - REG_MI_MBK_B0_FIELD( 1, MI_WRAM_BC_OFFSET_0KB , MI_WRAM_ARM7 ), - REG_MI_MBK_B1_FIELD( 1, MI_WRAM_BC_OFFSET_32KB , MI_WRAM_ARM7 ), - REG_MI_MBK_B2_FIELD( 1, MI_WRAM_BC_OFFSET_64KB , MI_WRAM_ARM7 ), - REG_MI_MBK_B3_FIELD( 1, MI_WRAM_BC_OFFSET_96KB , MI_WRAM_ARM7 ), - REG_MI_MBK_B4_FIELD( 1, MI_WRAM_BC_OFFSET_128KB, MI_WRAM_ARM7 ), - REG_MI_MBK_B5_FIELD( 1, MI_WRAM_BC_OFFSET_160KB, MI_WRAM_ARM7 ), - REG_MI_MBK_B6_FIELD( 1, MI_WRAM_BC_OFFSET_192KB, MI_WRAM_ARM7 ), - REG_MI_MBK_B7_FIELD( 1, MI_WRAM_BC_OFFSET_224KB, MI_WRAM_ARM7 ), - }, - { - REG_MI_MBK_C0_FIELD( 1, MI_WRAM_BC_OFFSET_0KB , MI_WRAM_ARM9 ), - REG_MI_MBK_C1_FIELD( 1, MI_WRAM_BC_OFFSET_32KB , MI_WRAM_ARM9 ), - REG_MI_MBK_C2_FIELD( 1, MI_WRAM_BC_OFFSET_64KB , MI_WRAM_ARM9 ), - REG_MI_MBK_C3_FIELD( 1, MI_WRAM_BC_OFFSET_96KB , MI_WRAM_ARM9 ), - REG_MI_MBK_C4_FIELD( 1, MI_WRAM_BC_OFFSET_128KB, MI_WRAM_ARM9 ), - REG_MI_MBK_C5_FIELD( 1, MI_WRAM_BC_OFFSET_160KB, MI_WRAM_ARM9 ), - REG_MI_MBK_C6_FIELD( 1, MI_WRAM_BC_OFFSET_192KB, MI_WRAM_ARM9 ), - REG_MI_MBK_C7_FIELD( 1, MI_WRAM_BC_OFFSET_224KB, MI_WRAM_ARM9 ), - }, - REG_MI_MBK6_FIELD( REG_WRAM_MAP_CONV_ADDR( 6, A, EADDR, MI_WRAM_MAP_NULL ), - MI_WRAM_IMAGE_128KB, - REG_WRAM_MAP_CONV_ADDR( 6, A, SADDR, MI_WRAM_MAP_NULL ) - ), - REG_MI_MBK7_FIELD( REG_WRAM_MAP_CONV_ADDR( 7, B, EADDR, MI_WRAM_MAP_NULL ), - MI_WRAM_IMAGE_128KB, - REG_WRAM_MAP_CONV_ADDR( 7, B, SADDR, MI_WRAM_MAP_NULL ) - ), - REG_MI_MBK8_FIELD( REG_WRAM_MAP_CONV_ADDR( 8, C, EADDR, HW_WRAM_AREA_HALF + 0x00020000 ), - MI_WRAM_IMAGE_128KB, - REG_WRAM_MAP_CONV_ADDR( 8, C, SADDR, HW_WRAM_AREA_HALF ) - ), - - // ARM7 - REG_MI_MBK6_FIELD( REG_WRAM_MAP_CONV_ADDR( 6, A, EADDR, HW_WRAM_AREA_HALF + 0x00020000 ), - MI_WRAM_IMAGE_128KB, - REG_WRAM_MAP_CONV_ADDR( 6, A, SADDR, HW_WRAM_AREA_HALF ) - ), - REG_MI_MBK7_FIELD( REG_WRAM_MAP_CONV_ADDR( 7, B, EADDR, HW_WRAM_AREA_HALF + 0x00040000 ), - MI_WRAM_IMAGE_128KB, - REG_WRAM_MAP_CONV_ADDR( 7, B, SADDR, HW_WRAM_AREA_HALF + 0x00020000 ) - ), - REG_MI_MBK8_FIELD( REG_WRAM_MAP_CONV_ADDR( 8, C, EADDR, MI_WRAM_MAP_NULL ), - MI_WRAM_IMAGE_128KB, - REG_WRAM_MAP_CONV_ADDR( 8, C, SADDR, MI_WRAM_MAP_NULL ) - ), - - // WRAM Lock - { - 0, - 0, - 0, - }, - - // WRAM-0/1 - 3, - - // VRAM-C - 7, - // VRAM-D - 7, -}; - diff --git a/include/firm/aes.h b/include/firm/aes.h index 36462494..54e46dc5 100644 --- a/include/firm/aes.h +++ b/include/firm/aes.h @@ -25,7 +25,6 @@ #include #include #include -#include #endif // !SDK_ARM7 /* FIRM_AES_H_ */ diff --git a/include/firm/aes/ARM7/aes_ids.h b/include/firm/aes/ARM7/aes_ids.h deleted file mode 100644 index 6353fe31..00000000 --- a/include/firm/aes/ARM7/aes_ids.h +++ /dev/null @@ -1,35 +0,0 @@ -/*---------------------------------------------------------------------------* - Project: TwlFirmSDK - AES - include - File: aes_ids.h - - Copyright 2007 Nintendo. All rights reserved. - - These coded instructions, statements, and computer programs contain - proprietary information of Nintendo of America Inc. and/or Nintendo - Company Ltd., and are protected by Federal copyright law. They may - not be disclosed to third parties or copied or duplicated in any form, - in whole or in part, without the prior written consent of Nintendo. - - $Date:: 2007-09-06$ - $Rev$ - $Author$ - *---------------------------------------------------------------------------*/ - -#ifndef TWL_AES_AES_IDS_H_ -#define TWL_AES_AES_IDS_H_ - -#define AES_IDS_ID0_C(c) (((unsigned long)c[0] << 0) | ((unsigned long)c[1] << 8) | ((unsigned long)c[2] << 16) | ((unsigned long)c[3] << 24)) -#define AES_IDS_ID0_D(c) (((unsigned long)c[3] << 0) | ((unsigned long)c[2] << 8) | ((unsigned long)c[1] << 16) | ((unsigned long)c[0] << 24)) -#if 0 // not specialized for application -#define AES_IDS_ID1_A(c) (((unsigned long)c[3] << 0) | ((unsigned long)c[1] << 8) | ((unsigned long)c[2] << 16) | ((unsigned long)c[0] << 24)) -#define AES_IDS_ID1_B(c) (((unsigned long)c[0] << 0) | ((unsigned long)c[2] << 8) | ((unsigned long)c[1] << 16) | ((unsigned long)c[3] << 24)) -#endif - -// for makenorfirm/makenandfirm/makegcdfirm -#define AES_IDS_ID2_A (('N' << 0) | ('i' << 8) | ('n' << 16) | ('t' << 24)) -#define AES_IDS_ID2_B (('e' << 0) | ('n' << 8) | ('d' << 16) | ('o' << 24)) -#define AES_IDS_ID2_C ((' ' << 0) | ('D' << 8) | ('S' << 16) | ('\0' << 24)) -#define AES_IDS_ID2_D ((0x01 << 0) | (0x23 << 8) | (0x21 << 16) | (0x00 << 24)) - -/* TWL_AES_AES_IDS_H_ */ -#endif diff --git a/readme.txt b/readme.txt index ee87efab..8ed17688 100644 --- a/readme.txt +++ b/readme.txt @@ -1,16 +1,18 @@ 1.ビルドに必要なもの  NORファーム、NANDファーム - ・twl_firmware + ・(TwlIPL_private) ・TwlSDK  システムメニュー -  ・twl_firmware +  ・(TwlIPL_private)   ・TwlSDK   ・NitroSystem 070314版(本ツリーのadd-ins内のTwlSDK対応パッチを当てたもの) + TwlIPL_privateは一部の鍵を使用する場合にのみ必要 + 2.環境変数の設定 - TWLIPL_ROOT + TWL_IPL_RED_ROOT ex.) TWL_IPL_RED_ROOT=c:/TwlIPL - TWL_KEYSDIR(ブートROMから起動可能なファームを作成する場合、鍵はtwl_firmwareリポジトリ内) - ex.) TWL_KEYSDIR=c:/twl_firmware/bootrom/build/keys + TWL_IPL_RED_PRIVATE_ROOT(TwlIPL_private を利用する場合のみ) + ex.) TWL_IPL_RED_PRIVATE_ROOT=c:/TwlIPL_private diff --git a/tools/bin/makegcdfirm.exe b/tools/bin/makegcdfirm.exe new file mode 100644 index 0000000000000000000000000000000000000000..3eb156b7555244663de30273ab39fb844c315817 GIT binary patch literal 124985 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 literal 0 HcmV?d00001 diff --git a/tools/bin/makenorfirm.exe b/tools/bin/makenorfirm.exe new file mode 100644 index 0000000000000000000000000000000000000000..97f9b3483c7e58be68b2e305a681fbda10389845 GIT binary patch literal 124469 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