commit 60f18e55542f2086b3aee98fc8687367d6bd65e8 Author: yosiokat Date: Thu Sep 6 05:28:51 2007 +0000 新規追加。(まだビルドできない。) git-svn-id: file:///Users/lillianskinner/Downloads/platinum/twl/TwlIPL/trunk@1 b08762b0-b915-fc4b-9d8c-17b2551a87ff diff --git a/build/buildtools/commondefs b/build/buildtools/commondefs new file mode 100644 index 00000000..e0f0b9c9 --- /dev/null +++ b/build/buildtools/commondefs @@ -0,0 +1,249 @@ +#! make -f +#---------------------------------------------------------------------------- +# Project: TwlFirm - commondefs - common definitions for build system +# File: commondefs +# +# 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. +# +# $Log: $ +# $NoKeywords: $ +#---------------------------------------------------------------------------- +ifndef TWLFIRM_COMMONDEFS_ +TWLFIRM_COMMONDEFS_ = TRUE + +NITRO_NO_STD_PCHDR = TRUE # vRpCwb_}~ + +#TWLFIRM_ROOT ?= $(shell cygpath -am ../../) + +export TWLBROM_ROOT := $(TWLFIRM_ROOT)/bootrom + + +EMPTY ?= +SPACE ?= $(EMPTY) $(EMPTY) + +# +# CodeGen Target +# +# FIRM_PLATFORM = [BB/EVA/TS] +# FIRM_MEMSIZE = [4M/8M] +# FIRM_CODEGEN = [ARM/THUMB] +# FIRM_PROC = [ARM9/ARM7] +# +# FIRM_TARGET = [NORFIRM/NANDFIRM/GCDFIRM/APP] +# + +FIRM_PLATFORM ?= BB +FIRM_MEMSIZE ?= 8M +FIRM_CODEGEN ?= ARM +FIRM_PROC ?= ARM9 +FIRM_TARGET ?= APP + +# replace TwlSDK +TWL_PLATFORM = $(FIRM_PLATFORM) +TWL_MEMSIZE = $(FIRM_MEMSIZE) +TWL_CODEGEN = $(FIRM_CODEGEN) +TWL_PROC = $(FIRM_PROC) + +# replace NitroSDK +ifndef CODEGEN_PROC +CODEGEN_PROC := $(FIRM_PROC) +endif + +ifeq ($(FIRM_CODEGEN),ALL) +FIRM_CODEGEN_ALL ?= TRUE +override FIRM_CODEGEN = ARM +endif + +ifeq ($(FIRM_CODEGEN),ARM) +FIRM_CODEGEN_ARCH = +else # ($(FIRM_CODEGEN),THUMB) +FIRM_CODEGEN_ARCH = .thumb +endif + +# +# SDK build type +# +# one of [FIRM_DEBUG/FIRM_RELEASE/FIRM_FINALROM] +# + +ifdef FIRM_DEBUG +FIRM_BUILD_TYPE ?= DEBUG +FIRM_BUILD_DIR ?= Debug + +else +ifdef FIRM_FINALROM +FIRM_BUILD_TYPE ?= FINALROM +FIRM_BUILD_DIR ?= Rom + +else # FIRM_RELEASE (default) +FIRM_BUILD_TYPE ?= RELEASE +FIRM_BUILD_DIR ?= Release + +endif +endif + +# replace TwlSDK +TWL_BUILD_TYPE ?= $(FIRM_BUILD_TYPE) +TWL_BUILD_DIR ?= $(FIRM_BUILD_DIR) + + + +#---------------------------------------------------------------------------- +# BROM-SDK path settings +# + +BROM_ROOT := $(subst $(SPACE),\ ,$(subst \,/,$(TWLBROM_ROOT))) +BROM_KEYSDIR := $(BROM_ROOT)/build/keys + + +#---------------------------------------------------------------------------- +# TWL-FIRM path settings +# + +FIRM_ROOT := $(subst $(SPACE),\ ,$(subst \,/,$(TWLFIRM_ROOT))) +FIRM_BUILDTOOLSDIR := $(FIRM_ROOT)/build/buildtools +FIRM_BUILDSETUPDIR := $(FIRM_ROOT)/build/buildsetup +FIRM_INCDIR := $(FIRM_ROOT)/include +FIRM_TOOLSDIR := $(FIRM_ROOT)/tools +FIRM_COMPONENTSDIR := $(FIRM_ROOT)/components +FIRM_ADDINS ?= $(FIRM_ROOT)/add-ins + +FIRM_TWLSDK_ROOT ?=$(shell cygpath -w $(TWLSDK_ROOT)) +FIRM_NITROSDK_ROOT ?=$(shell cygpath -w $(NITROSDK_ROOT)) + +FIRM_BUILDARCH ?= $(CODEGEN_PROC)-$(FIRM_PLATFORM)$(FIRM_CODEGEN_ARCH) +FIRM_BUILDARCH_ARM9 := ARM9-$(FIRM_PLATFORM)$(FIRM_CODEGEN_ARCH) +FIRM_BUILDARCH_ARM7 := ARM7-$(FIRM_PLATFORM)$(FIRM_CODEGEN_ARCH) + +FIRM_BUILDTYPE ?= $(FIRM_BUILDARCH)/$(FIRM_BUILD_DIR) +FIRM_BUILDTYPE_ARM9 := $(FIRM_BUILDARCH_ARM9)/$(FIRM_BUILD_DIR) +FIRM_BUILDTYPE_ARM7 := $(FIRM_BUILDARCH_ARM7)/$(FIRM_BUILD_DIR) + +FIRM_LIBARCH := $(CODEGEN_PROC)-$(FIRM_PLATFORM) +FIRM_LIBTYPE := $(FIRM_LIBARCH)/$(FIRM_BUILD_DIR) +FIRM_LIBDIR := $(FIRM_ROOT)/lib/$(FIRM_LIBTYPE) +FIRM_LIBSYSCALLDIR := $(FIRM_ROOT)/lib/$(FIRM_LIBARCH)/etc +FIRM_LIBSUFFIX := .firm$(FIRM_CODEGEN_ARCH) + + +FIRM_SPECDIR := $(FIRM_INCDIR)/firm/specfiles +FIRM_LSFARCH := $(FIRM_LIBARCH) +ifneq ($(FIRM_TARGET),APP) +FIRM_LSFARCH := $(addsuffix -$(FIRM_TARGET),$(FIRM_LSFARCH)) +endif # FIRM_TARGET!=APP +FIRM_LCFARCH := $(FIRM_LSFARCH) +DEFAULT_FIRM_LCFILE := $(FIRM_SPECDIR)/$(FIRM_LCFARCH).lcf +DEFAULT_FIRM_LCFILE_TEMPLATE := $(FIRM_SPECDIR)/$(FIRM_LCFARCH)$(LCF_SUFFIX_).lcf.template +DEFAULT_FIRM_LCFILE_SPEC := $(FIRM_SPECDIR)/$(FIRM_LSFARCH).lsf +DEFAULT_FIRM_ROM_SPEC := $(FIRM_SPECDIR)/ROM-$(FIRM_PLATFORM).rsf + +# replace TwlSDK +TWL_BUILDARCH ?= $(FIRM_BUILDARCH) + + +### Compiler & Linker settings + +# replace NitroSDK +ifneq ($(FIRM_TARGET),APP) +LCFILE_TEMPLATE ?= $(DEFAULT_FIRM_LCFILE_TEMPLATE) +LCFILE_SPEC ?= $(DEFAULT_FIRM_LCFILE_SPEC) +endif # FIRM_TARGET!=APP + +LDEPENDS_LCF += $(FIRM_BUILDTOOLSDIR)/commondefs +LDEPENDS_RES += $(FIRM_BUILDTOOLSDIR)/commondefs + + +### SDK Library settings + +ifeq ($(CODEGEN_PROC),ARM9) + +FIRM_LIBS_BASE ?= \ + libos \ + libmi \ + libgcd \ + libacsign \ + +FIRM_TWL_LIBS_BASE ?= \ + +else # ($(CODEGEN_PROC),ARM7) + +FIRM_LIBS_BASE ?= \ + libos_sp \ + libnvram_sp \ + libgcd_sp \ + libaes_sp \ + libacsign_sp \ + libfirmsd_sp \ + +FIRM_TWL_LIBS_BASE ?= \ + +endif + +FIRM_LIBS ?= $(addsuffix $(FIRM_LIBSUFFIX).a,$(FIRM_LIBS_BASE)) +FIRM_LIBS += $(addsuffix $(TWL_LIBSUFFIX).a,$(FIRM_TWL_LIBS_BASE)) + +#---------------------------------------------------------------------------- +### TWL-commondefs +# +include $(TWLSDK_ROOT)/build/buildtools/commondefs + + +#---------------------------------------------------------------------------- +# MY BUILD TOOLS +# +MAKENORFIRM := $(FIRM_TOOLSDIR)/bin/makenorfirm.exe +MAKENANDFIRM := $(FIRM_TOOLSDIR)/bin/makenandfirm.exe +MAKEGCDFIRM := $(FIRM_TOOLSDIR)/bin/makegcdfirm.exe +OPENSSL := $(FIRM_TOOLSDIR)/openssl/openssl.exe + +MAKEFIRM_RSA_PRVKEY ?= $(FIRM_TOOLSDIR)/openssl/rsa_private.der +MAKEFIRM_RSA_PUBKEY ?= $(FIRM_TOOLSDIR)/openssl/rsa_public.der + +MAKEFIRM_FLAGS ?= + +ifneq ($(filter NORFIRM NANDFIRM GCDFIRM,$(FIRM_TARGET)),) +FIRM_STRIP_AXF := TRUE +endif + +#---------------------------------------------------------------------------- + +### Global Library resettings + +GINCLUDES := $(FIRM_INCDIR) $(GINCLUDES) +GLIBRARY_DIRS := $(FIRM_LIBDIR) $(GLIBRARY_DIRS) +GLIBRARIES := $(FIRM_LIBS) $(GLIBRARIES) + + +#---------------------------------------------------------------------------- +# TWLFIRM_INSTALL_ROOT +# + +ifdef TWLFIRM_INSTALL_ROOT +TWLFIRM_INSTALL_ROOT_ := $(TWLFIRM_INSTALL_ROOT) +else +TWLFIRM_INSTALL_ROOT_ := $(TWLFIRM_ROOT) +endif + +FIRM_INSTALL_ROOT := $(subst $(SPACE),\ ,$(subst \,/,$(TWLFIRM_INSTALL_ROOT_))) +FIRM_INSTALL_INCDIR := $(FIRM_INSTALL_ROOT)/include +FIRM_INSTALL_TOOLSDIR := $(FIRM_INSTALL_ROOT)/tools +FIRM_INSTALL_LIBDIR := $(FIRM_INSTALL_ROOT)/lib/$(FIRM_LIBTYPE) +FIRM_INSTALL_PROMDIR := $(FIRM_INSTALL_TOOLSDIR)/prom +FIRM_INSTALL_COMPONENTSDIR := $(FIRM_INSTALL_ROOT)/components +FIRM_INSTALL_ADDINS := $(FIRM_INSTALL_ROOT)/add-ins + + +#---------------------------------------------------------------------------- +# Compiler flags +# +MACRO_FLAGS += -DFIRM_TARGET_$(FIRM_TARGET) + +#---------------------------------------------------------------------------- +endif # TWLFIRM_COMMONDEFS_ +#----- End of commondefs ----- diff --git a/build/buildtools/modulerules b/build/buildtools/modulerules new file mode 100644 index 00000000..e9fb4278 --- /dev/null +++ b/build/buildtools/modulerules @@ -0,0 +1,80 @@ +#! make -f +#---------------------------------------------------------------------------- +# Project: TwlFirm - modulerules - common rules for build system +# File: modulerules +# +# 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. +# +# $Log: $ +# $NoKeywords: $ +#---------------------------------------------------------------------------- +ifndef TWLFIRM_MODULERULES_ + + +ifdef MAKEFIRM_ARM9 +MAKEROM_ARM9 = $(MAKEFIRM_ARM9) +endif +ifdef MAKEFIRM_ARM7 +MAKEROM_ARM7 = $(MAKEFIRM_ARM7) +endif + +#---------------------------------------------------------------------------- +### TWL-modulerules +# +include $(TWLSDK_ROOT)/build/buildtools/modulerules + +#---------------------------------------------------------------------------- + +# +# MAKENORFIRM / MAKENANDFIRM / MAKEGCDFIRM +# + +MAKEFIRM_ARM9 ?= $(MAKEROM_ARM9) +MAKEFIRM_ARM7 ?= $(MAKEROM_ARM7) + +MAKEFIRM_DEFS += -DFIRM_ROOT='$(FIRM_ROOT)' \ + -DMAKEFIRM_ARM9='$(basename $(MAKEFIRM_ARM9))' \ + -DMAKEFIRM_ARM7='$(basename $(MAKEFIRM_ARM7))' \ + -DMAKEFIRM_RSA_PRVKEY='$(MAKEFIRM_RSA_PRVKEY)' \ + +SDEPENDS_BIN += $(MAKEFIRM_RSA_PRVKEY) + + +.PHONY: firmtop firmlib + +firmtop: + @$(MAKE) -C $(TWLFIRM_ROOT)/build + +firmlib: + @$(MAKE) -C $(TWLFIRM_ROOT)/build/libraries + +# .nor +$(BINDIR)/%.nor: $(SDEPENDS_BIN) $(ROM_SPEC) $(LDEPENDS_BIN) $(EDEPENDS_BIN) $(MAKEFILE) $(MAKENORFIRM) $(MAKEFIRM_RSA_PRVKEY) + $(MAKENORFIRM) $(MAKEFIRM_FLAGS) $(MAKEFIRM_DEFS) $(ROM_SPEC) $@ + +# .nand +$(BINDIR)/%.nand: $(SDEPENDS_BIN) $(ROM_SPEC) $(LDEPENDS_BIN) $(EDEPENDS_BIN) $(MAKEFILE) $(MAKENANDFIRM) $(MAKEFIRM_RSA_PRVKEY) + $(MAKENANDFIRM) $(MAKEFIRM_FLAGS) $(MAKEFIRM_DEFS) $(ROM_SPEC) $@ + +# .gcd +$(BINDIR)/%.gcd: $(SDEPENDS_BIN) $(ROM_SPEC) $(LDEPENDS_BIN) $(EDEPENDS_BIN) $(MAKEFILE) $(MAKEGCDFIRM) $(MAKEFIRM_RSA_PRVKEY) + $(MAKEGCDFIRM) $(MAKEFIRM_FLAGS) $(MAKEFIRM_DEFS) $(ROM_SPEC) $@ + +# .rbin +$(BINDIR)/$(TARGET_BIN_BASENAME).rbin: $(OBJS) + objcopy -I elf32-little -O binary $< $@ + +# .axf +$(BINDIR)/$(TARGET_BIN_BASENAME).axf: $(OBJS) $(LCFILE) $(MAKEFILE) $(LDEPENDS_NEF) $(EDEPENDS_NEF) $(ALIBRARIES) $(LDRES_FILE) $(CW_LIBCXX) + $(LD) $(LDFLAGS) $(LIBRARY_DIRS) @$(call empath,$(LDRES_FILE)) $(call empath,$(LCFILE)) -o $(call empath,$@) + +#---------------------------------------------------------------------------- +TWLFIRM_MODULERULES_ = TRUE +endif # TWLFIRM_MODULERULES_ +#----- End of modulerules ----- diff --git a/build/tools/Makefile b/build/tools/Makefile new file mode 100644 index 00000000..dceeabab --- /dev/null +++ b/build/tools/Makefile @@ -0,0 +1,34 @@ +#! make -f +#---------------------------------------------------------------------------- +# Project: TwlFirm - firmware +# 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. +# +# $Log: $ +# $NoKeywords: $ +#---------------------------------------------------------------------------- + +include $(TWLSDK_ROOT)/build/buildtools/commondefs + + +#---------------------------------------------------------------------------- + +SUBDIRS = \ + makenorfirm \ + makegcdfirm \ + makenandfirm \ + + +#---------------------------------------------------------------------------- + +include $(TWLSDK_ROOT)/build/buildtools/modulerules + + +#===== End of Makefile ===== diff --git a/build/tools/acsign/Makefile b/build/tools/acsign/Makefile new file mode 100644 index 00000000..1ed36c37 --- /dev/null +++ b/build/tools/acsign/Makefile @@ -0,0 +1,61 @@ +#! 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 $(NITROSDK_ROOT)/build/libraries/mb/include + + +SRCS = acsign.c acmemory.c acsign_util.c + +TARGET_LIB = libacsign_x86.a + + +include $(TWLFIRM_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 $(TWLFIRM_ROOT)/build/buildtools/modulerules + + +#===== End of Makefile ===== diff --git a/build/tools/acsign/acsign.c b/build/tools/acsign/acsign.c new file mode 100644 index 00000000..7b63142f --- /dev/null +++ b/build/tools/acsign/acsign.c @@ -0,0 +1,334 @@ +#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, // o͗̈ + const void* buf, // f[^ւ̃|C^ + unsigned int len // f[^̒ + ) +{ + HASHContext context; + unsigned char *bufferp = buffer; + + HASHReset( &context ); + HASHUpdate( &context, buf, len ); + HASHGetDigest( &context, bufferp ); + + return TRUE; +} + +// +int ACSign_CompareUnit( + const void* decedHash, // ACSign_Decryptȍo + const void* digest // ACSign_DigestUnit̏o + ) +{ + 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; +} + +/* + CӃoCg̓̓f[^ + CӃoCg̏o̓f[^𓾂܂B + ΂Ă邩Ȃ͒llȒlɃ}bv邾łB + o̓ԂĂĂȂ +*/ +int ACSign_GetKey( + void* dest_ptr, // o̓f[^ւ̃|C^ + unsigned int dest_len, // o̓f[^̒ + const void* src_ptr, // ̓f[^ւ̃|C^ + unsigned int src_len // ̓f[^̒ + ) +{ + 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 new file mode 100644 index 00000000..e8b45670 --- /dev/null +++ b/build/tools/acsign/acsign_gcd.c @@ -0,0 +1,74 @@ +#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, // o͗̈ + GCDHeader* header // wb_ւ̃|C^ + ) +{ + 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, // wb_ւ̃|C^ + 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 new file mode 100644 index 00000000..8b0b719c --- /dev/null +++ b/build/tools/acsign/acsign_nand.c @@ -0,0 +1,75 @@ +#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, // o͗̈ + NANDHeader* header // wb_ւ̃|C^ + ) +{ + 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, // wb_ւ̃|C^ + 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 new file mode 100644 index 00000000..0bb690c9 --- /dev/null +++ b/build/tools/acsign/acsign_nor.c @@ -0,0 +1,75 @@ +#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, // o͗̈ + NORHeader* header // wb_ւ̃|C^ + ) +{ + 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, // wb_ւ̃|C^ + 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 new file mode 100644 index 00000000..a7a75d8d --- /dev/null +++ b/build/tools/acsign/aes.h @@ -0,0 +1,139 @@ +/* $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 new file mode 100644 index 00000000..778dc53a --- /dev/null +++ b/build/tools/acsign/aes2.c @@ -0,0 +1,133 @@ +#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 new file mode 100644 index 00000000..3e80799d --- /dev/null +++ b/build/tools/acsign/aes2.h @@ -0,0 +1,21 @@ +#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 new file mode 100644 index 00000000..fab235c1 --- /dev/null +++ b/build/tools/acsign/aes_e.c @@ -0,0 +1,115 @@ +/* $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 new file mode 100644 index 00000000..74f6db70 --- /dev/null +++ b/build/tools/acsign/aes_e.h @@ -0,0 +1,284 @@ +/* $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 new file mode 100644 index 00000000..55867bd9 --- /dev/null +++ b/build/tools/acsign/aes_e_ecb.c @@ -0,0 +1,48 @@ +/* $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 new file mode 100644 index 00000000..6a584f4b --- /dev/null +++ b/build/tools/acsign/aes_sbox.h @@ -0,0 +1,59 @@ +/* $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 new file mode 100644 index 00000000..682766ea --- /dev/null +++ b/build/tools/acsign/aes_skey.c @@ -0,0 +1,143 @@ +/* $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 new file mode 100644 index 00000000..75820c61 --- /dev/null +++ b/build/tools/acsign/bn_add.c @@ -0,0 +1,304 @@ +/* $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 new file mode 100644 index 00000000..59326c1f --- /dev/null +++ b/build/tools/acsign/bn_asm.c @@ -0,0 +1,509 @@ +/* $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 new file mode 100644 index 00000000..61dbc937 --- /dev/null +++ b/build/tools/acsign/bn_comba.c @@ -0,0 +1,434 @@ +/* $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 new file mode 100644 index 00000000..d2c12575 --- /dev/null +++ b/build/tools/acsign/bn_div.c @@ -0,0 +1,365 @@ +/* $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 new file mode 100644 index 00000000..dc40f5c0 --- /dev/null +++ b/build/tools/acsign/bn_ex_str.c @@ -0,0 +1,437 @@ +/* $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 new file mode 100644 index 00000000..08634e7e --- /dev/null +++ b/build/tools/acsign/bn_exp.c @@ -0,0 +1,156 @@ +/* $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 new file mode 100644 index 00000000..999ed55f --- /dev/null +++ b/build/tools/acsign/bn_fm_w.c @@ -0,0 +1,63 @@ +/* $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 new file mode 100644 index 00000000..133b33ed --- /dev/null +++ b/build/tools/acsign/bn_lsh.c @@ -0,0 +1,112 @@ +/* $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 new file mode 100644 index 00000000..8d8afe94 --- /dev/null +++ b/build/tools/acsign/bn_m_exp.c @@ -0,0 +1,283 @@ +/* $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 new file mode 100644 index 00000000..250967c9 --- /dev/null +++ b/build/tools/acsign/bn_me.c @@ -0,0 +1,251 @@ +/* $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 new file mode 100644 index 00000000..6fc5fea4 --- /dev/null +++ b/build/tools/acsign/bn_mont.c @@ -0,0 +1,231 @@ +/* $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 new file mode 100644 index 00000000..1ddd40e3 --- /dev/null +++ b/build/tools/acsign/bn_ms_w.c @@ -0,0 +1,121 @@ +/* $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 new file mode 100644 index 00000000..4dd0e235 --- /dev/null +++ b/build/tools/acsign/bn_mul.c @@ -0,0 +1,779 @@ +/* $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 new file mode 100644 index 00000000..9465e402 --- /dev/null +++ b/build/tools/acsign/bn_r_exp.c @@ -0,0 +1,134 @@ +/* $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 new file mode 100644 index 00000000..e762a819 --- /dev/null +++ b/build/tools/acsign/bn_recp.c @@ -0,0 +1,202 @@ +/* $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 new file mode 100644 index 00000000..909cd9a1 --- /dev/null +++ b/build/tools/acsign/bn_rsh.c @@ -0,0 +1,123 @@ +/* $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 new file mode 100644 index 00000000..4762cd9d --- /dev/null +++ b/build/tools/acsign/bn_sqr.c @@ -0,0 +1,273 @@ +/* $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 new file mode 100644 index 00000000..d76752a4 --- /dev/null +++ b/build/tools/acsign/bn_wdiv.c @@ -0,0 +1,100 @@ +/* $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 new file mode 100644 index 00000000..6e11663c --- /dev/null +++ b/build/tools/acsign/include/acsign.h @@ -0,0 +1,49 @@ +#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, // o͗̈ + const void* buf, // f[^ւ̃|C^ + unsigned int len // f[^̒ + ); + +// +int ACSign_CompareUnit( + const void* decedHash, // ACSign_Decryptȍo + const void* digest // ACSign_DigestUnit̏o + ); + +// +int ACSign_GetKey( + void* dest_ptr, // o̓f[^ւ̃|C^ + unsigned int dest_len, // o̓f[^̒ + const void* src_ptr, // ̓f[^ւ̃|C^ + unsigned int src_len // ̓f[^̒ + ); + +#ifdef __cplusplus +} +#endif + +#endif //_ACSIGN_H_ diff --git a/build/tools/acsign/include/acsign_gcd.h b/build/tools/acsign/include/acsign_gcd.h new file mode 100644 index 00000000..2c9853e6 --- /dev/null +++ b/build/tools/acsign/include/acsign_gcd.h @@ -0,0 +1,30 @@ +#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, // wb_ւ̃|C^ + void* buffer, // o͗̈ + const void* key + ); + +// +int ACSign_DigestHeader( + void* buffer, // o͗̈ + GCDHeader* header // f[^ւ̃|C^ + ); + +#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 new file mode 100644 index 00000000..97afa980 --- /dev/null +++ b/build/tools/acsign/include/acsign_nand.h @@ -0,0 +1,30 @@ +#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, // wb_ւ̃|C^ + void* buffer, // o͗̈ + const void* key + ); + +// +int ACSign_DigestHeader( + void* buffer, // o͗̈ + NANDHeader* header // f[^ւ̃|C^ + ); + +#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 new file mode 100644 index 00000000..eb097b50 --- /dev/null +++ b/build/tools/acsign/include/acsign_nor.h @@ -0,0 +1,30 @@ +#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, // wb_ւ̃|C^ + void* buffer, // o͗̈ + const void* key + ); + +// +int ACSign_DigestHeader( + void* buffer, // o͗̈ + NORHeader* header // f[^ւ̃|C^ + ); + +#ifdef __cplusplus +} +#endif + +#endif //_ACSIGN_NOR_H_ diff --git a/build/tools/acsign/include/bn.h b/build/tools/acsign/include/bn.h new file mode 100644 index 00000000..f68b3d22 --- /dev/null +++ b/build/tools/acsign/include/bn.h @@ -0,0 +1,1120 @@ +/* $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 new file mode 100644 index 00000000..13e157b7 --- /dev/null +++ b/build/tools/acsign/include/bn_thx.h @@ -0,0 +1,301 @@ +/* $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 new file mode 100644 index 00000000..8e269f36 --- /dev/null +++ b/build/tools/acsign/include/r_error.h @@ -0,0 +1,210 @@ +/* $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 new file mode 100644 index 00000000..566de6fa --- /dev/null +++ b/build/tools/acsign/include/r_stdiag.h @@ -0,0 +1,82 @@ +/* $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 new file mode 100644 index 00000000..d35556ad --- /dev/null +++ b/build/tools/acsign/include/r_types.h @@ -0,0 +1,241 @@ +/* $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 new file mode 100644 index 00000000..d6eeed2b --- /dev/null +++ b/build/tools/acsign/include/sha.h @@ -0,0 +1,89 @@ +/* $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 new file mode 100644 index 00000000..ed4a672e --- /dev/null +++ b/build/tools/acsign/include/sha1.h @@ -0,0 +1,73 @@ +/* + * 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 new file mode 100644 index 00000000..2361282b --- /dev/null +++ b/build/tools/acsign/include/sha_locl.h @@ -0,0 +1,274 @@ +/* $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 new file mode 100644 index 00000000..6bebd125 --- /dev/null +++ b/build/tools/acsign/sha1.c @@ -0,0 +1,453 @@ +/* + * 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 new file mode 100644 index 00000000..f9759158 --- /dev/null +++ b/build/tools/acsign/sha1dgst.c @@ -0,0 +1,770 @@ +/* $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 new file mode 100644 index 00000000..6e91da85 --- /dev/null +++ b/build/tools/makegcdfirm/Makefile @@ -0,0 +1,148 @@ +#! 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. +# +# $Log: $ +# $NoKeywords: $ +#--------------------------------------------------------------------------- + +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 $(TWLFIRM_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) +NITRO_INCDIR := $(FIRM_INCDIR) -I$(TWL_INCDIR) -I$(NITRO_INCDIR) $(addprefix -I,$(INCDIR)) + +include $(TWL_NITROSDK_ROOT)/build/buildtools/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 new file mode 100644 index 00000000..023e49f4 --- /dev/null +++ b/build/tools/makegcdfirm/compress.c @@ -0,0 +1,292 @@ +/*---------------------------------------------------------------------------* + 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. + + $Log: $ + $NoKeywords: $ + *---------------------------------------------------------------------------*/ +#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) + +//=========================================================================== +// LZ77k +//=========================================================================== +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: LZ77ksȂ֐ + + Arguments: srcp kf[^ւ̃|C^ + size kf[^TCY + dstp kf[^ւ̃|C^ + kf[^傫TCỸobt@KvłB + + Returns: k̃f[^TCYB + k̃f[^kO傫Ȃꍇɂ͈k𒆒f0Ԃ܂B + *---------------------------------------------------------------------------*/ +u32 LZCompWrite(u8 *srcp, u32 size, u8 *dstp, int boundary) +{ + u32 LZDstCount; // kf[^̃oCg + u8 LZCompFlags; // k̗LtOn + u8 *LZCompFlagsp; // LZCompFlags i[郁̈|Cg + u16 lastOffset; // vf[^܂ł̃ItZbg (̎_ł̍Œvf[^) + u8 lastLength; // vf[^ (̎_ł̍Œvf[^) + u8 i; + u32 dstMax; + +#ifdef ADD_HEADER + *(u32 *)dstp = size << 8 | LZ_CODE_HEADER; // f[^Ewb_ + dstp += 4; +#endif + LZDstCount = 4; + dstMax = size; + LZInitTable(); + + while (size > 0) + { + LZCompFlags = 0; + LZCompFlagsp = dstp++; // tOn̊i[ + LZDstCount++; + + // tOn8rbgf[^ƂĊi[邽߁A8񃋁[v + for (i = 0; i < 8; i++) + { + LZCompFlags <<= 1; // (i=0) ͓ɈӖ͂Ȃ + if (size <= 0) + { + // I[ɗꍇ̓tOŌ܂ŃVtgĂI + continue; + } + + if ((lastLength = SearchLZ(srcp, size, &lastOffset))) + { + // k”\ȏꍇ̓tO𗧂Ă + LZCompFlags |= 0x1; + + // ItZbg͏4rbgƉ8rbgɕĊi[ + *dstp++ = (u8)((lastLength - 3) << 4 | (lastOffset - 1) >> 8); + *dstp++ = (u8)((lastOffset - 1) & 0xff); + LZDstCount += 2; + LZSlide(srcp, lastLength); + srcp += lastLength; + size -= lastLength; + } + else + { + // kȂ + LZSlide(srcp, 1); + *dstp++ = *srcp++; + size--; + LZDstCount++; + } + } // 8񃋁[vI + *LZCompFlagsp = LZCompFlags; // tOni[ + } + + // 16oCgEACg + // ACgpf[^0 ̓f[^TCYɊ܂߂ + i = 0; + while (LZDstCount & (boundary - 1)) +// while ((LZDstCount + i) & 0x3) + { + *dstp++ = 0; + LZDstCount++; + i++; + } + + return LZDstCount; +} + +//-------------------------------------------------------- +// LZ77kŃXCh̒Œv܂B +// Arguments: startp f[^̊Jnʒu|C^ +// nextp Jnf[^̃|C^ +// remainSize cf[^TCY +// offset vItZbgi[̈ւ̃|C^ +// Return : v񂪌‚ꍇ 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; + } + + /* ĂǂA͂ɍ */ + if (*(searchp + 1) != *(nextp + 1) || *(searchp + 2) != *(nextp + 2)) + { + w_offset = LZOffsetTable[w_offset]; + continue; + } + + if (nextp - searchp < 2) + { + // VRAM2oCgANZXȂ̂ (VRAMf[^ǂݏoꍇ邽)A + // Ώۃf[^2oCgÕf[^ɂȂ΂ȂȂB + // + // ItZbg12rbgŊi[邽߁A4096ȉ + break; + } + tmpLength = 3; + searchHeadp = searchp + 3; + headp = nextp + 3; + + while (((u32)(headp - nextp) < remainSize) && (*headp == *searchHeadp)) + { + headp++; + searchHeadp++; + tmpLength++; + + // f[^4rbgŊi[邽߁A18ȉ (3̉ʂ͂) + if (tmpLength == (0xF + 3)) + { + break; + } + } + if (tmpLength > maxLength) + { + // ő咷ItZbgXV + maxLength = tmpLength; + maxOffset = (u16)(nextp - searchp); + if (maxLength == (0xF + 3)) + { + // vőȂ̂ŁAIB + 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 new file mode 100644 index 00000000..fcdb3ac0 --- /dev/null +++ b/build/tools/makegcdfirm/compress.h @@ -0,0 +1,37 @@ +/*---------------------------------------------------------------------------* + 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. + + $Log: $ + $NoKeywords: $ + *---------------------------------------------------------------------------*/ +#ifndef COMPRESS_H_ +#define COMPRESS_H_ + +#include "misc.h" + + +/*---------------------------------------------------------------------------* + Name: MI_CompressLZ + + Description: LZ77ksȂ֐ + + Arguments: srcp kf[^ւ̃|C^ + size kf[^TCY + dstp kf[^ւ̃|C^ + kf[^傫TCỸobt@KvłB + + Returns: k̃f[^TCYB + *---------------------------------------------------------------------------*/ +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 new file mode 100644 index 00000000..679fb0e6 --- /dev/null +++ b/build/tools/makegcdfirm/defval.c @@ -0,0 +1,315 @@ +/*---------------------------------------------------------------------------* + 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 new file mode 100644 index 00000000..71355101 --- /dev/null +++ b/build/tools/makegcdfirm/defval.h @@ -0,0 +1,38 @@ +/*---------------------------------------------------------------------------* + 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 new file mode 100644 index 00000000..c360cd33 --- /dev/null +++ b/build/tools/makegcdfirm/elf.h @@ -0,0 +1,431 @@ +/*---------------------------------------------------------------------------* + 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̃CfbNX */ +#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̌`(Ĕzu”\, s”\Ȃ) */ + Elf32_Half e_machine; /* t@CŗvA[LeN` */ + Elf32_Word e_version; /* ELFtH[}bg̃o[Wi݂1j */ + Elf32_Addr e_entry; /* vÕGg|CgBw薳Ȃ0B */ + Elf32_Off e_phoff; /* vOwb_e[ũt@C擪̃ItZbg */ + Elf32_Off e_shoff; /* ZNVwb_e[ũt@C擪̃ItZbg */ + Elf32_Word e_flags; /* vZbTŗL̃tO */ + Elf32_Half e_ehsize; /* ELFwb_̃TCY */ + Elf32_Half e_phentsize; /* 1vOwb_̃TCY */ + Elf32_Half e_phnum; /* vOwb_̐ */ + Elf32_Half e_shentsize; /* 1ZNVwb_̃TCY */ + Elf32_Half e_shnum; /* ZNVwb_̐ */ + Elf32_Half e_shstrndx; /* ZNVe[uZNVւ̃CfbNX */ +} Elf32_Ehdr; + +/* e_ident[EI_*]̒g` */ +#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 /* gȂGgŁÃo̒l̈Ӗ͖` */ +#define PT_LOAD 1 /* sɃ[hZOg */ +#define PT_DYNAMIC 2 /* I\̔zێZOg */ +#define PT_INTERP 3 /* t@C̉߂ɎgC^v^̃pXێZOg */ +#define PT_NOTE 4 /* t@C̉߂ɂ͎gȂێZOg */ +#define PT_SHLIB 5 /* \ */ +#define PT_PHDR 6 /* vOwb_e[uivÕC[Ẅꕔłꍇ̂ݑ݁j */ +//#define PT_TLS ? /* XbhǏL̈̃ev[g */ + +#define PT_LOOS 0x60000000 /* OSŗLɗ\񂳂ꂽ̈ */ +#define PT_HIOS 0x6fffffff + +#define PT_LOPROC 0x70000000 /* vZbTŗLɗ\񂳂ꂽ̈ */ +#define PT_HIPROC 0x7fffffff + +/* [p_flags]*/ +#define PF_X 1 /*s”\*/ +#define PF_W 2 /*݉”\*/ +#define PF_R 4 /*ǂݏo”\*/ +#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; /*ZNVwb_e[uZNṼCfbNX*/ + Elf32_Word sh_type; /* ^CviL`QƁj */ + Elf32_Word sh_flags; + Elf32_Addr sh_addr; /* */ + Elf32_Off sh_offset; /* t@C̐擪̃ItZbg */ + Elf32_Word sh_size; /* oCgPʂ̃TCY */ + Elf32_Word sh_link; /* sh_typeɂĒl̈Ӗς */ + Elf32_Word sh_info; /* sh_typeɂĒl̈Ӗς */ + Elf32_Word sh_addralign; /* ACg(0or1ŐȂ,44ByteAlign) */ + Elf32_Word sh_entsize; /* ŒTCỸGge[uꍇA1vf̃TCY */ +} 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 + +/*ZNVCfbNX*/ +//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 + + +//̓wb_łȂ̃f[^\ + +/*--------------------------------------------------------- + Symbol Table Entry + --------------------------------------------------------*/ +typedef struct { + Elf32_Word st_name; /* V{e[ũCfbNX */ + Elf32_Addr st_value; /* 炭֘AZNVł̃ItZbgl */ + Elf32_Word st_size; /* TCYȂAsȏꍇ 0 */ + unsigned char st_info; /* oCh ^Cv */ + unsigned char st_other; /* ݂ 0 */ + Elf32_Half st_shndx; /* ֘AZNVwb_e[ũCfbNX */ +} 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 /*f[^IuWFNg*/ +#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,c] 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,c] 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. */ + + + + + + + + + +/*--------------------------------------------------------- + ELFwb_ǂݏo + --------------------------------------------------------*/ +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 new file mode 100644 index 00000000..87db583a --- /dev/null +++ b/build/tools/makegcdfirm/format_nlist.h @@ -0,0 +1,53 @@ +/*---------------------------------------------------------------------------* + 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. + + $Log: $ + $NoKeywords: $ + *---------------------------------------------------------------------------*/ +#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 new file mode 100644 index 00000000..ca2dfd18 --- /dev/null +++ b/build/tools/makegcdfirm/format_rom.h @@ -0,0 +1,58 @@ +/*---------------------------------------------------------------------------* + 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. + + $Log: $ + $NoKeywords: $ + *---------------------------------------------------------------------------*/ +#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 new file mode 100644 index 00000000..e5cc43df --- /dev/null +++ b/build/tools/makegcdfirm/format_sign.h @@ -0,0 +1,31 @@ +/*---------------------------------------------------------------------------* + 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. + + $Log: $ + $NoKeywords: $ + *---------------------------------------------------------------------------*/ +#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 new file mode 100644 index 00000000..60ed6b7f Binary files /dev/null and b/build/tools/makegcdfirm/gcdfirm_header_twlj.template.sbin differ diff --git a/build/tools/makegcdfirm/makegcdfirm.c b/build/tools/makegcdfirm/makegcdfirm.c new file mode 100644 index 00000000..5d7c2abd --- /dev/null +++ b/build/tools/makegcdfirm/makegcdfirm.c @@ -0,0 +1,105 @@ +/*---------------------------------------------------------------------------* + 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. + + $Log: $ + $NoKeywords: $ + *---------------------------------------------------------------------------*/ +#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); + +//--------------------------------------------------------------------------- +// Main +//--------------------------------------------------------------------------- + +int main(int argc, char *argv[]) +{ + int n; + int narg; + char *gcdfirmFile; + + 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->GcdfirmFile + gcdfirmFile = + strdup(narg > + 1 ? argv[optind + 1] : ChangeSuffix(argv[optind], DEFAULT_NORFIRM_SUFFIX)); + return makegcdfirm(argv[optind], gcdfirmFile); + } + + usage: + { + char *makegcdfirm = GetAppName(); + + fprintf(stderr, + "NITRO-SDK Development Tool - %s - Make gcdfirm file \n" + "Build %lu\n\n" + "Usage: %s [-phv] [-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) +{ + 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) ? 0 : 1; +} diff --git a/build/tools/makegcdfirm/makegcdfirm.h b/build/tools/makegcdfirm/makegcdfirm.h new file mode 100644 index 00000000..6120c48f --- /dev/null +++ b/build/tools/makegcdfirm/makegcdfirm.h @@ -0,0 +1,23 @@ +/*---------------------------------------------------------------------------* + 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. + + $Log: $ + $NoKeywords: $ + *---------------------------------------------------------------------------*/ +#ifndef MAKEGCDFIRM_H_ +#define MAKEGCDFIRM_H_ + +#include "misc.h" + +BOOL OutputGcdfirmFile(const char *specFile, const char *gcdFile); + +#endif //MAKEGCDFIRM_H_ diff --git a/build/tools/makegcdfirm/misc.c b/build/tools/makegcdfirm/misc.c new file mode 100644 index 00000000..e11bd855 --- /dev/null +++ b/build/tools/makegcdfirm/misc.c @@ -0,0 +1,627 @@ +/*---------------------------------------------------------------------------* + 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. + + $Log: $ + $NoKeywords: $ + *---------------------------------------------------------------------------*/ +#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; + +#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 new file mode 100644 index 00000000..eddf95eb --- /dev/null +++ b/build/tools/makegcdfirm/out_gcdfirm.c @@ -0,0 +1,994 @@ +/*---------------------------------------------------------------------------* + 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. + + $Log: $ + $NoKeywords: $ + *---------------------------------------------------------------------------*/ +#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 +#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(void); +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) +{ + char *buffer; + BOOL state; + + if (ReadFile(specFile, &buffer, READ_ALL) <= 0) + { + return FALSE; + } + + if (!OpenFile(gcdFile)) + { + return FALSE; + } + + specFileName = specFile; + + state = InitializeGcdfirmFile() && 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] = 0xff; + 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); + + // 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); + + // 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(void) +{ + ReadRomHeaderFile( GetSrcPath(GetAppBaseName(), DEFAULT_ROMHEADER_TEMPLATE) ); + + memset(&signedContext.hash[FIRM_SIGNED_HASH_IDX_HASH_TABLE], 0xff, 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 new file mode 100644 index 00000000..eeeb9895 --- /dev/null +++ b/build/tools/makegcdfirm/path.c @@ -0,0 +1,931 @@ +/*---------------------------------------------------------------------------* + 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 new file mode 100644 index 00000000..e9956dc6 --- /dev/null +++ b/build/tools/makegcdfirm/path.h @@ -0,0 +1,93 @@ +/*---------------------------------------------------------------------------* + 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 new file mode 100644 index 00000000..154c5cb1 --- /dev/null +++ b/build/tools/makegcdfirm/test/Makefile @@ -0,0 +1,55 @@ +#! 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. +# +# $Log: $ +# $NoKeywords: $ +#--------------------------------------------------------------------------- + +SUBDIRS = wram_rbin \ + +include $(TWLFIRM_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 new file mode 100644 index 00000000..999ce185 Binary files /dev/null and b/build/tools/makegcdfirm/test/nandfirm_print.nand differ diff --git a/build/tools/makegcdfirm/test/norfirm_print.nor b/build/tools/makegcdfirm/test/norfirm_print.nor new file mode 100644 index 00000000..2a6baecd Binary files /dev/null and b/build/tools/makegcdfirm/test/norfirm_print.nor differ diff --git a/build/tools/makegcdfirm/test/rsa_private.der b/build/tools/makegcdfirm/test/rsa_private.der new file mode 100644 index 00000000..06f5f4cc Binary files /dev/null and b/build/tools/makegcdfirm/test/rsa_private.der differ diff --git a/build/tools/makegcdfirm/test/test.gcdsf b/build/tools/makegcdfirm/test/test.gcdsf new file mode 100644 index 00000000..788e8e87 --- /dev/null +++ b/build/tools/makegcdfirm/test/test.gcdsf @@ -0,0 +1,25 @@ +#GCDSF --- Gcdfirm Spec File + +VERSION : GENERATE + +RSA_KEY : rsa_private.der +OUT_KEY : rsa_public.sbin + +WRAM_RBIN: ./wram_rbin/wram_regs.rbin + +ARM9_SBIN : $(MAKEFIRM_ARM9).sbin +ARM9_ELF : $(MAKEFIRM_ARM9).axf + +ARM7_SBIN : $(MAKEFIRM_ARM7).sbin +ARM7_ELF : $(MAKEFIRM_ARM7).axf + +ARM9_X2 : TRUE # TRUE or FALSE + +NML_OFS : 0x80000 +TWL_OFS : 0x100000 + +NORFIRM : ./norfirm_print.nor +NANDFIRM : ./nandfirm_print.nand + +ERROR : ARM7_HASH # SIGN, HEADER_HASH, ARM9_HASH, ARM7_HASH, HASH_TABLE_HASH or FINAL_HASH +ERROR : HEADER_FOOTER # for debug diff --git a/build/tools/makegcdfirm/test/twl_gcdfirm7_print.axf b/build/tools/makegcdfirm/test/twl_gcdfirm7_print.axf new file mode 100644 index 00000000..b255bd21 Binary files /dev/null and b/build/tools/makegcdfirm/test/twl_gcdfirm7_print.axf differ diff --git a/build/tools/makegcdfirm/test/twl_gcdfirm7_print.sbin b/build/tools/makegcdfirm/test/twl_gcdfirm7_print.sbin new file mode 100644 index 00000000..a4eeebce Binary files /dev/null and b/build/tools/makegcdfirm/test/twl_gcdfirm7_print.sbin differ diff --git a/build/tools/makegcdfirm/test/twl_gcdfirm9_print.axf b/build/tools/makegcdfirm/test/twl_gcdfirm9_print.axf new file mode 100644 index 00000000..3d064b38 Binary files /dev/null and b/build/tools/makegcdfirm/test/twl_gcdfirm9_print.axf differ diff --git a/build/tools/makegcdfirm/test/twl_gcdfirm9_print.sbin b/build/tools/makegcdfirm/test/twl_gcdfirm9_print.sbin new file mode 100644 index 00000000..cd305be4 Binary files /dev/null and b/build/tools/makegcdfirm/test/twl_gcdfirm9_print.sbin differ diff --git a/build/tools/makegcdfirm/test/wram_rbin/Makefile b/build/tools/makegcdfirm/test/wram_rbin/Makefile new file mode 100644 index 00000000..310ef0c2 --- /dev/null +++ b/build/tools/makegcdfirm/test/wram_rbin/Makefile @@ -0,0 +1,47 @@ +#! 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. +# +# $Log: $ +# $NoKeywords: $ +#---------------------------------------------------------------------------- + +SUBDIRS = + +LINCLUDES = ../include + +#---------------------------------------------------------------------------- + +TARGET_BIN = wram_regs.rbin + +SRCS = \ + wram_regs.c \ + +#SRCDIR = # using default +#LCFILE = # using default + + +include $(TWLFIRM_ROOT)/build/buildtools/commondefs + +INSTALL_DIR = . +INSTALL_TARGETS = $(BINDIR)/$(TARGET_BIN) + + +#---------------------------------------------------------------------------- + +do-build: $(TARGETS) + + +include $(TWLFIRM_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 new file mode 100644 index 00000000..ade0c709 --- /dev/null +++ b/build/tools/makegcdfirm/test/wram_rbin/wram_regs.c @@ -0,0 +1,88 @@ +/*---------------------------------------------------------------------------* + 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. + + $Log: $ + $NoKeywords: $ + *---------------------------------------------------------------------------*/ +#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 new file mode 100644 index 00000000..9472c5e8 --- /dev/null +++ b/build/tools/makegcdfirm/wram_regs.c @@ -0,0 +1,91 @@ +/*---------------------------------------------------------------------------* + 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. + + $Log: $ + $NoKeywords: $ + *---------------------------------------------------------------------------*/ +#include "format_rom.h" +#define SDK_ASM +#include +#include + +MIHeader_WramRegs wram_regs_init = +{ + // 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 + 3, + + // VRAM-C + 7, + // VRAM-D + 7, +}; + diff --git a/build/tools/makenandfirm/Makefile b/build/tools/makenandfirm/Makefile new file mode 100644 index 00000000..2e8c7b9c --- /dev/null +++ b/build/tools/makenandfirm/Makefile @@ -0,0 +1,148 @@ +#! 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. +# +# $Log: $ +# $NoKeywords: $ +#--------------------------------------------------------------------------- + +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 $(TWLFIRM_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) +NITRO_INCDIR := $(FIRM_INCDIR) -I$(TWL_INCDIR) -I$(NITRO_INCDIR) $(addprefix -I,$(INCDIR)) + +include $(TWL_NITROSDK_ROOT)/build/buildtools/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 new file mode 100644 index 00000000..acc7fdd2 --- /dev/null +++ b/build/tools/makenandfirm/compress.c @@ -0,0 +1,292 @@ +/*---------------------------------------------------------------------------* + 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. + + $Log: $ + $NoKeywords: $ + *---------------------------------------------------------------------------*/ +#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) + +//=========================================================================== +// LZ77k +//=========================================================================== +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: LZ77ksȂ֐ + + Arguments: srcp kf[^ւ̃|C^ + size kf[^TCY + dstp kf[^ւ̃|C^ + kf[^傫TCỸobt@KvłB + + Returns: k̃f[^TCYB + k̃f[^kO傫Ȃꍇɂ͈k𒆒f0Ԃ܂B + *---------------------------------------------------------------------------*/ +u32 LZCompWrite(u8 *srcp, u32 size, u8 *dstp, int boundary) +{ + u32 LZDstCount; // kf[^̃oCg + u8 LZCompFlags; // k̗LtOn + u8 *LZCompFlagsp; // LZCompFlags i[郁̈|Cg + u16 lastOffset; // vf[^܂ł̃ItZbg (̎_ł̍Œvf[^) + u8 lastLength; // vf[^ (̎_ł̍Œvf[^) + u8 i; + u32 dstMax; + +#ifdef ADD_HEADER + *(u32 *)dstp = size << 8 | LZ_CODE_HEADER; // f[^Ewb_ + dstp += 4; +#endif + LZDstCount = 4; + dstMax = size; + LZInitTable(); + + while (size > 0) + { + LZCompFlags = 0; + LZCompFlagsp = dstp++; // tOn̊i[ + LZDstCount++; + + // tOn8rbgf[^ƂĊi[邽߁A8񃋁[v + for (i = 0; i < 8; i++) + { + LZCompFlags <<= 1; // (i=0) ͓ɈӖ͂Ȃ + if (size <= 0) + { + // I[ɗꍇ̓tOŌ܂ŃVtgĂI + continue; + } + + if ((lastLength = SearchLZ(srcp, size, &lastOffset))) + { + // k”\ȏꍇ̓tO𗧂Ă + LZCompFlags |= 0x1; + + // ItZbg͏4rbgƉ8rbgɕĊi[ + *dstp++ = (u8)((lastLength - 3) << 4 | (lastOffset - 1) >> 8); + *dstp++ = (u8)((lastOffset - 1) & 0xff); + LZDstCount += 2; + LZSlide(srcp, lastLength); + srcp += lastLength; + size -= lastLength; + } + else + { + // kȂ + LZSlide(srcp, 1); + *dstp++ = *srcp++; + size--; + LZDstCount++; + } + } // 8񃋁[vI + *LZCompFlagsp = LZCompFlags; // tOni[ + } + + // 16oCgEACg + // ACgpf[^0 ̓f[^TCYɊ܂߂ + i = 0; + while (LZDstCount & (boundary - 1)) +// while ((LZDstCount + i) & 0x3) + { + *dstp++ = 0; + LZDstCount++; + i++; + } + + return LZDstCount; +} + +//-------------------------------------------------------- +// LZ77kŃXCh̒Œv܂B +// Arguments: startp f[^̊Jnʒu|C^ +// nextp Jnf[^̃|C^ +// remainSize cf[^TCY +// offset vItZbgi[̈ւ̃|C^ +// Return : v񂪌‚ꍇ 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; + } + + /* ĂǂA͂ɍ */ + if (*(searchp + 1) != *(nextp + 1) || *(searchp + 2) != *(nextp + 2)) + { + w_offset = LZOffsetTable[w_offset]; + continue; + } + + if (nextp - searchp < 2) + { + // VRAM2oCgANZXȂ̂ (VRAMf[^ǂݏoꍇ邽)A + // Ώۃf[^2oCgÕf[^ɂȂ΂ȂȂB + // + // ItZbg12rbgŊi[邽߁A4096ȉ + break; + } + tmpLength = 3; + searchHeadp = searchp + 3; + headp = nextp + 3; + + while (((u32)(headp - nextp) < remainSize) && (*headp == *searchHeadp)) + { + headp++; + searchHeadp++; + tmpLength++; + + // f[^4rbgŊi[邽߁A18ȉ (3̉ʂ͂) + if (tmpLength == (0xF + 3)) + { + break; + } + } + if (tmpLength > maxLength) + { + // ő咷ItZbgXV + maxLength = tmpLength; + maxOffset = (u16)(nextp - searchp); + if (maxLength == (0xF + 3)) + { + // vőȂ̂ŁAIB + 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 new file mode 100644 index 00000000..d8aa290a --- /dev/null +++ b/build/tools/makenandfirm/compress.h @@ -0,0 +1,37 @@ +/*---------------------------------------------------------------------------* + 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. + + $Log: $ + $NoKeywords: $ + *---------------------------------------------------------------------------*/ +#ifndef COMPRESS_H_ +#define COMPRESS_H_ + +#include "misc.h" + + +/*---------------------------------------------------------------------------* + Name: MI_CompressLZ + + Description: LZ77ksȂ֐ + + Arguments: srcp kf[^ւ̃|C^ + size kf[^TCY + dstp kf[^ւ̃|C^ + kf[^傫TCỸobt@KvłB + + Returns: k̃f[^TCYB + *---------------------------------------------------------------------------*/ +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 new file mode 100644 index 00000000..679fb0e6 --- /dev/null +++ b/build/tools/makenandfirm/defval.c @@ -0,0 +1,315 @@ +/*---------------------------------------------------------------------------* + 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 new file mode 100644 index 00000000..71355101 --- /dev/null +++ b/build/tools/makenandfirm/defval.h @@ -0,0 +1,38 @@ +/*---------------------------------------------------------------------------* + 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 new file mode 100644 index 00000000..c360cd33 --- /dev/null +++ b/build/tools/makenandfirm/elf.h @@ -0,0 +1,431 @@ +/*---------------------------------------------------------------------------* + 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̃CfbNX */ +#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̌`(Ĕzu”\, s”\Ȃ) */ + Elf32_Half e_machine; /* t@CŗvA[LeN` */ + Elf32_Word e_version; /* ELFtH[}bg̃o[Wi݂1j */ + Elf32_Addr e_entry; /* vÕGg|CgBw薳Ȃ0B */ + Elf32_Off e_phoff; /* vOwb_e[ũt@C擪̃ItZbg */ + Elf32_Off e_shoff; /* ZNVwb_e[ũt@C擪̃ItZbg */ + Elf32_Word e_flags; /* vZbTŗL̃tO */ + Elf32_Half e_ehsize; /* ELFwb_̃TCY */ + Elf32_Half e_phentsize; /* 1vOwb_̃TCY */ + Elf32_Half e_phnum; /* vOwb_̐ */ + Elf32_Half e_shentsize; /* 1ZNVwb_̃TCY */ + Elf32_Half e_shnum; /* ZNVwb_̐ */ + Elf32_Half e_shstrndx; /* ZNVe[uZNVւ̃CfbNX */ +} Elf32_Ehdr; + +/* e_ident[EI_*]̒g` */ +#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 /* gȂGgŁÃo̒l̈Ӗ͖` */ +#define PT_LOAD 1 /* sɃ[hZOg */ +#define PT_DYNAMIC 2 /* I\̔zێZOg */ +#define PT_INTERP 3 /* t@C̉߂ɎgC^v^̃pXێZOg */ +#define PT_NOTE 4 /* t@C̉߂ɂ͎gȂێZOg */ +#define PT_SHLIB 5 /* \ */ +#define PT_PHDR 6 /* vOwb_e[uivÕC[Ẅꕔłꍇ̂ݑ݁j */ +//#define PT_TLS ? /* XbhǏL̈̃ev[g */ + +#define PT_LOOS 0x60000000 /* OSŗLɗ\񂳂ꂽ̈ */ +#define PT_HIOS 0x6fffffff + +#define PT_LOPROC 0x70000000 /* vZbTŗLɗ\񂳂ꂽ̈ */ +#define PT_HIPROC 0x7fffffff + +/* [p_flags]*/ +#define PF_X 1 /*s”\*/ +#define PF_W 2 /*݉”\*/ +#define PF_R 4 /*ǂݏo”\*/ +#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; /*ZNVwb_e[uZNṼCfbNX*/ + Elf32_Word sh_type; /* ^CviL`QƁj */ + Elf32_Word sh_flags; + Elf32_Addr sh_addr; /* */ + Elf32_Off sh_offset; /* t@C̐擪̃ItZbg */ + Elf32_Word sh_size; /* oCgPʂ̃TCY */ + Elf32_Word sh_link; /* sh_typeɂĒl̈Ӗς */ + Elf32_Word sh_info; /* sh_typeɂĒl̈Ӗς */ + Elf32_Word sh_addralign; /* ACg(0or1ŐȂ,44ByteAlign) */ + Elf32_Word sh_entsize; /* ŒTCỸGge[uꍇA1vf̃TCY */ +} 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 + +/*ZNVCfbNX*/ +//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 + + +//̓wb_łȂ̃f[^\ + +/*--------------------------------------------------------- + Symbol Table Entry + --------------------------------------------------------*/ +typedef struct { + Elf32_Word st_name; /* V{e[ũCfbNX */ + Elf32_Addr st_value; /* 炭֘AZNVł̃ItZbgl */ + Elf32_Word st_size; /* TCYȂAsȏꍇ 0 */ + unsigned char st_info; /* oCh ^Cv */ + unsigned char st_other; /* ݂ 0 */ + Elf32_Half st_shndx; /* ֘AZNVwb_e[ũCfbNX */ +} 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 /*f[^IuWFNg*/ +#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,c] 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,c] 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. */ + + + + + + + + + +/*--------------------------------------------------------- + ELFwb_ǂݏo + --------------------------------------------------------*/ +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 new file mode 100644 index 00000000..e832edc0 --- /dev/null +++ b/build/tools/makenandfirm/format_nlist.h @@ -0,0 +1,53 @@ +/*---------------------------------------------------------------------------* + 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. + + $Log: $ + $NoKeywords: $ + *---------------------------------------------------------------------------*/ +#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 new file mode 100644 index 00000000..43decb01 --- /dev/null +++ b/build/tools/makenandfirm/format_rom.h @@ -0,0 +1,50 @@ +/*---------------------------------------------------------------------------* + 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. + + $Log: $ + $NoKeywords: $ + *---------------------------------------------------------------------------*/ +#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 new file mode 100644 index 00000000..a965863b --- /dev/null +++ b/build/tools/makenandfirm/format_sign.h @@ -0,0 +1,31 @@ +/*---------------------------------------------------------------------------* + 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. + + $Log: $ + $NoKeywords: $ + *---------------------------------------------------------------------------*/ +#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 new file mode 100644 index 00000000..48d08797 --- /dev/null +++ b/build/tools/makenandfirm/makenandfirm.c @@ -0,0 +1,105 @@ +/*---------------------------------------------------------------------------* + 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. + + $Log: $ + $NoKeywords: $ + *---------------------------------------------------------------------------*/ +#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 new file mode 100644 index 00000000..69abe085 --- /dev/null +++ b/build/tools/makenandfirm/makenandfirm.h @@ -0,0 +1,23 @@ +/*---------------------------------------------------------------------------* + 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. + + $Log: $ + $NoKeywords: $ + *---------------------------------------------------------------------------*/ +#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 new file mode 100644 index 00000000..56f06bf6 --- /dev/null +++ b/build/tools/makenandfirm/misc.c @@ -0,0 +1,627 @@ +/*---------------------------------------------------------------------------* + 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. + + $Log: $ + $NoKeywords: $ + *---------------------------------------------------------------------------*/ +#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; + +#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 new file mode 100644 index 00000000..0cdfa4da --- /dev/null +++ b/build/tools/makenandfirm/out_nandfirm.c @@ -0,0 +1,979 @@ +/*---------------------------------------------------------------------------* + 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. + + $Log: $ + $NoKeywords: $ + *---------------------------------------------------------------------------*/ +#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 +#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] = 0xff; + ver8[6] = 0xff; + ver8[7] = 0xff; + } + + 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], 0xff, 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 new file mode 100644 index 00000000..eeeb9895 --- /dev/null +++ b/build/tools/makenandfirm/path.c @@ -0,0 +1,931 @@ +/*---------------------------------------------------------------------------* + 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 new file mode 100644 index 00000000..e9956dc6 --- /dev/null +++ b/build/tools/makenandfirm/path.h @@ -0,0 +1,93 @@ +/*---------------------------------------------------------------------------* + 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 new file mode 100644 index 00000000..6882b9ee --- /dev/null +++ b/build/tools/makenandfirm/test/Makefile @@ -0,0 +1,55 @@ +#! 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. +# +# $Log: $ +# $NoKeywords: $ +#--------------------------------------------------------------------------- + +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 new file mode 100644 index 00000000..06f5f4cc Binary files /dev/null and b/build/tools/makenandfirm/test/rsa_private.der differ diff --git a/build/tools/makenandfirm/test/test.nandsf b/build/tools/makenandfirm/test/test.nandsf new file mode 100644 index 00000000..545d66cd --- /dev/null +++ b/build/tools/makenandfirm/test/test.nandsf @@ -0,0 +1,28 @@ +#NANDSF --- Nandfirm Spec File + +VERSION : 0x0 # GENERATE + +RSA_KEY : rsa_private.der +OUT_KEY : rsa_public.sbin + +WRAM_RBIN: ./wram_rbin/wram_regs.rbin + +DECOMP_PROC : ARM9 # ARM9 or ARM7 + +MIRROR_OFS : 0xc000 # 0x8000 is too small + +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 + +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 diff --git a/build/tools/makenandfirm/test/twl_nandfirm7_print.axf b/build/tools/makenandfirm/test/twl_nandfirm7_print.axf new file mode 100644 index 00000000..b255bd21 Binary files /dev/null and b/build/tools/makenandfirm/test/twl_nandfirm7_print.axf differ diff --git a/build/tools/makenandfirm/test/twl_nandfirm7_print.sbin b/build/tools/makenandfirm/test/twl_nandfirm7_print.sbin new file mode 100644 index 00000000..a4eeebce Binary files /dev/null and b/build/tools/makenandfirm/test/twl_nandfirm7_print.sbin differ diff --git a/build/tools/makenandfirm/test/twl_nandfirm9_print.axf b/build/tools/makenandfirm/test/twl_nandfirm9_print.axf new file mode 100644 index 00000000..3d064b38 Binary files /dev/null and b/build/tools/makenandfirm/test/twl_nandfirm9_print.axf differ diff --git a/build/tools/makenandfirm/test/twl_nandfirm9_print.sbin b/build/tools/makenandfirm/test/twl_nandfirm9_print.sbin new file mode 100644 index 00000000..cd305be4 Binary files /dev/null and b/build/tools/makenandfirm/test/twl_nandfirm9_print.sbin differ diff --git a/build/tools/makenandfirm/test/wram_rbin/Makefile b/build/tools/makenandfirm/test/wram_rbin/Makefile new file mode 100644 index 00000000..562d9811 --- /dev/null +++ b/build/tools/makenandfirm/test/wram_rbin/Makefile @@ -0,0 +1,47 @@ +#! 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. +# +# $Log: $ +# $NoKeywords: $ +#---------------------------------------------------------------------------- + +SUBDIRS = + +LINCLUDES = ../include + +#---------------------------------------------------------------------------- + +TARGET_BIN = wram_regs.rbin + +SRCS = \ + wram_regs.c \ + +#SRCDIR = # using default +#LCFILE = # using default + + +include $(TWLFIRM_ROOT)/build/buildtools/commondefs + +INSTALL_DIR = . +INSTALL_TARGETS = $(BINDIR)/$(TARGET_BIN) + + +#---------------------------------------------------------------------------- + +do-build: $(TARGETS) + + +include $(TWLFIRM_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 new file mode 100644 index 00000000..5d0c9b18 --- /dev/null +++ b/build/tools/makenandfirm/test/wram_rbin/wram_regs.c @@ -0,0 +1,88 @@ +/*---------------------------------------------------------------------------* + 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. + + $Log: $ + $NoKeywords: $ + *---------------------------------------------------------------------------*/ +#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 new file mode 100644 index 00000000..1350f138 --- /dev/null +++ b/build/tools/makenandfirm/wram_regs.c @@ -0,0 +1,91 @@ +/*---------------------------------------------------------------------------* + 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. + + $Log: $ + $NoKeywords: $ + *---------------------------------------------------------------------------*/ +#include "format_rom.h" +#define SDK_ASM +#include +#include + +MIHeader_WramRegs wram_regs_init = +{ + // 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 + 3, + + // VRAM-C + 7, + // VRAM-D + 7, +}; + diff --git a/build/tools/makenorfirm/Makefile b/build/tools/makenorfirm/Makefile new file mode 100644 index 00000000..990fb2ac --- /dev/null +++ b/build/tools/makenorfirm/Makefile @@ -0,0 +1,148 @@ +#! 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. +# +# $Log: $ +# $NoKeywords: $ +#--------------------------------------------------------------------------- + +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 $(TWLFIRM_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) +NITRO_INCDIR := $(FIRM_INCDIR) -I$(TWL_INCDIR) -I$(NITRO_INCDIR) $(addprefix -I,$(INCDIR)) + +include $(TWL_NITROSDK_ROOT)/build/buildtools/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 new file mode 100644 index 00000000..903adf77 --- /dev/null +++ b/build/tools/makenorfirm/compress.c @@ -0,0 +1,292 @@ +/*---------------------------------------------------------------------------* + 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. + + $Log: $ + $NoKeywords: $ + *---------------------------------------------------------------------------*/ +#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) + +//=========================================================================== +// LZ77k +//=========================================================================== +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: LZ77ksȂ֐ + + Arguments: srcp kf[^ւ̃|C^ + size kf[^TCY + dstp kf[^ւ̃|C^ + kf[^傫TCỸobt@KvłB + + Returns: k̃f[^TCYB + k̃f[^kO傫Ȃꍇɂ͈k𒆒f0Ԃ܂B + *---------------------------------------------------------------------------*/ +u32 LZCompWrite(u8 *srcp, u32 size, u8 *dstp, int boundary) +{ + u32 LZDstCount; // kf[^̃oCg + u8 LZCompFlags; // k̗LtOn + u8 *LZCompFlagsp; // LZCompFlags i[郁̈|Cg + u16 lastOffset; // vf[^܂ł̃ItZbg (̎_ł̍Œvf[^) + u8 lastLength; // vf[^ (̎_ł̍Œvf[^) + u8 i; + u32 dstMax; + +#ifdef ADD_HEADER + *(u32 *)dstp = size << 8 | LZ_CODE_HEADER; // f[^Ewb_ + dstp += 4; +#endif + LZDstCount = 4; + dstMax = size; + LZInitTable(); + + while (size > 0) + { + LZCompFlags = 0; + LZCompFlagsp = dstp++; // tOn̊i[ + LZDstCount++; + + // tOn8rbgf[^ƂĊi[邽߁A8񃋁[v + for (i = 0; i < 8; i++) + { + LZCompFlags <<= 1; // (i=0) ͓ɈӖ͂Ȃ + if (size <= 0) + { + // I[ɗꍇ̓tOŌ܂ŃVtgĂI + continue; + } + + if ((lastLength = SearchLZ(srcp, size, &lastOffset))) + { + // k”\ȏꍇ̓tO𗧂Ă + LZCompFlags |= 0x1; + + // ItZbg͏4rbgƉ8rbgɕĊi[ + *dstp++ = (u8)((lastLength - 3) << 4 | (lastOffset - 1) >> 8); + *dstp++ = (u8)((lastOffset - 1) & 0xff); + LZDstCount += 2; + LZSlide(srcp, lastLength); + srcp += lastLength; + size -= lastLength; + } + else + { + // kȂ + LZSlide(srcp, 1); + *dstp++ = *srcp++; + size--; + LZDstCount++; + } + } // 8񃋁[vI + *LZCompFlagsp = LZCompFlags; // tOni[ + } + + // 16oCgEACg + // ACgpf[^0 ̓f[^TCYɊ܂߂ + i = 0; + while (LZDstCount & (boundary - 1)) +// while ((LZDstCount + i) & 0x3) + { + *dstp++ = 0; + LZDstCount++; + i++; + } + + return LZDstCount; +} + +//-------------------------------------------------------- +// LZ77kŃXCh̒Œv܂B +// Arguments: startp f[^̊Jnʒu|C^ +// nextp Jnf[^̃|C^ +// remainSize cf[^TCY +// offset vItZbgi[̈ւ̃|C^ +// Return : v񂪌‚ꍇ 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; + } + + /* ĂǂA͂ɍ */ + if (*(searchp + 1) != *(nextp + 1) || *(searchp + 2) != *(nextp + 2)) + { + w_offset = LZOffsetTable[w_offset]; + continue; + } + + if (nextp - searchp < 2) + { + // VRAM2oCgANZXȂ̂ (VRAMf[^ǂݏoꍇ邽)A + // Ώۃf[^2oCgÕf[^ɂȂ΂ȂȂB + // + // ItZbg12rbgŊi[邽߁A4096ȉ + break; + } + tmpLength = 3; + searchHeadp = searchp + 3; + headp = nextp + 3; + + while (((u32)(headp - nextp) < remainSize) && (*headp == *searchHeadp)) + { + headp++; + searchHeadp++; + tmpLength++; + + // f[^4rbgŊi[邽߁A18ȉ (3̉ʂ͂) + if (tmpLength == (0xF + 3)) + { + break; + } + } + if (tmpLength > maxLength) + { + // ő咷ItZbgXV + maxLength = tmpLength; + maxOffset = (u16)(nextp - searchp); + if (maxLength == (0xF + 3)) + { + // vőȂ̂ŁAIB + 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 new file mode 100644 index 00000000..fcdb3ac0 --- /dev/null +++ b/build/tools/makenorfirm/compress.h @@ -0,0 +1,37 @@ +/*---------------------------------------------------------------------------* + 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. + + $Log: $ + $NoKeywords: $ + *---------------------------------------------------------------------------*/ +#ifndef COMPRESS_H_ +#define COMPRESS_H_ + +#include "misc.h" + + +/*---------------------------------------------------------------------------* + Name: MI_CompressLZ + + Description: LZ77ksȂ֐ + + Arguments: srcp kf[^ւ̃|C^ + size kf[^TCY + dstp kf[^ւ̃|C^ + kf[^傫TCỸobt@KvłB + + Returns: k̃f[^TCYB + *---------------------------------------------------------------------------*/ +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 new file mode 100644 index 00000000..679fb0e6 --- /dev/null +++ b/build/tools/makenorfirm/defval.c @@ -0,0 +1,315 @@ +/*---------------------------------------------------------------------------* + 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 new file mode 100644 index 00000000..71355101 --- /dev/null +++ b/build/tools/makenorfirm/defval.h @@ -0,0 +1,38 @@ +/*---------------------------------------------------------------------------* + 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 new file mode 100644 index 00000000..c360cd33 --- /dev/null +++ b/build/tools/makenorfirm/elf.h @@ -0,0 +1,431 @@ +/*---------------------------------------------------------------------------* + 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̃CfbNX */ +#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̌`(Ĕzu”\, s”\Ȃ) */ + Elf32_Half e_machine; /* t@CŗvA[LeN` */ + Elf32_Word e_version; /* ELFtH[}bg̃o[Wi݂1j */ + Elf32_Addr e_entry; /* vÕGg|CgBw薳Ȃ0B */ + Elf32_Off e_phoff; /* vOwb_e[ũt@C擪̃ItZbg */ + Elf32_Off e_shoff; /* ZNVwb_e[ũt@C擪̃ItZbg */ + Elf32_Word e_flags; /* vZbTŗL̃tO */ + Elf32_Half e_ehsize; /* ELFwb_̃TCY */ + Elf32_Half e_phentsize; /* 1vOwb_̃TCY */ + Elf32_Half e_phnum; /* vOwb_̐ */ + Elf32_Half e_shentsize; /* 1ZNVwb_̃TCY */ + Elf32_Half e_shnum; /* ZNVwb_̐ */ + Elf32_Half e_shstrndx; /* ZNVe[uZNVւ̃CfbNX */ +} Elf32_Ehdr; + +/* e_ident[EI_*]̒g` */ +#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 /* gȂGgŁÃo̒l̈Ӗ͖` */ +#define PT_LOAD 1 /* sɃ[hZOg */ +#define PT_DYNAMIC 2 /* I\̔zێZOg */ +#define PT_INTERP 3 /* t@C̉߂ɎgC^v^̃pXێZOg */ +#define PT_NOTE 4 /* t@C̉߂ɂ͎gȂێZOg */ +#define PT_SHLIB 5 /* \ */ +#define PT_PHDR 6 /* vOwb_e[uivÕC[Ẅꕔłꍇ̂ݑ݁j */ +//#define PT_TLS ? /* XbhǏL̈̃ev[g */ + +#define PT_LOOS 0x60000000 /* OSŗLɗ\񂳂ꂽ̈ */ +#define PT_HIOS 0x6fffffff + +#define PT_LOPROC 0x70000000 /* vZbTŗLɗ\񂳂ꂽ̈ */ +#define PT_HIPROC 0x7fffffff + +/* [p_flags]*/ +#define PF_X 1 /*s”\*/ +#define PF_W 2 /*݉”\*/ +#define PF_R 4 /*ǂݏo”\*/ +#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; /*ZNVwb_e[uZNṼCfbNX*/ + Elf32_Word sh_type; /* ^CviL`QƁj */ + Elf32_Word sh_flags; + Elf32_Addr sh_addr; /* */ + Elf32_Off sh_offset; /* t@C̐擪̃ItZbg */ + Elf32_Word sh_size; /* oCgPʂ̃TCY */ + Elf32_Word sh_link; /* sh_typeɂĒl̈Ӗς */ + Elf32_Word sh_info; /* sh_typeɂĒl̈Ӗς */ + Elf32_Word sh_addralign; /* ACg(0or1ŐȂ,44ByteAlign) */ + Elf32_Word sh_entsize; /* ŒTCỸGge[uꍇA1vf̃TCY */ +} 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 + +/*ZNVCfbNX*/ +//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 + + +//̓wb_łȂ̃f[^\ + +/*--------------------------------------------------------- + Symbol Table Entry + --------------------------------------------------------*/ +typedef struct { + Elf32_Word st_name; /* V{e[ũCfbNX */ + Elf32_Addr st_value; /* 炭֘AZNVł̃ItZbgl */ + Elf32_Word st_size; /* TCYȂAsȏꍇ 0 */ + unsigned char st_info; /* oCh ^Cv */ + unsigned char st_other; /* ݂ 0 */ + Elf32_Half st_shndx; /* ֘AZNVwb_e[ũCfbNX */ +} 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 /*f[^IuWFNg*/ +#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,c] 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,c] 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. */ + + + + + + + + + +/*--------------------------------------------------------- + ELFwb_ǂݏo + --------------------------------------------------------*/ +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 new file mode 100644 index 00000000..06c99d0e --- /dev/null +++ b/build/tools/makenorfirm/format_nlist.h @@ -0,0 +1,53 @@ +/*---------------------------------------------------------------------------* + 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. + + $Log: $ + $NoKeywords: $ + *---------------------------------------------------------------------------*/ +#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 new file mode 100644 index 00000000..13cea6b1 --- /dev/null +++ b/build/tools/makenorfirm/format_rom.h @@ -0,0 +1,50 @@ +/*---------------------------------------------------------------------------* + 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. + + $Log: $ + $NoKeywords: $ + *---------------------------------------------------------------------------*/ +#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 new file mode 100644 index 00000000..e5cc43df --- /dev/null +++ b/build/tools/makenorfirm/format_sign.h @@ -0,0 +1,31 @@ +/*---------------------------------------------------------------------------* + 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. + + $Log: $ + $NoKeywords: $ + *---------------------------------------------------------------------------*/ +#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 new file mode 100644 index 00000000..19a8cde0 --- /dev/null +++ b/build/tools/makenorfirm/makenorfirm.c @@ -0,0 +1,105 @@ +/*---------------------------------------------------------------------------* + 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. + + $Log: $ + $NoKeywords: $ + *---------------------------------------------------------------------------*/ +#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 new file mode 100644 index 00000000..79dc4fb7 --- /dev/null +++ b/build/tools/makenorfirm/makenorfirm.h @@ -0,0 +1,23 @@ +/*---------------------------------------------------------------------------* + 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. + + $Log: $ + $NoKeywords: $ + *---------------------------------------------------------------------------*/ +#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 new file mode 100644 index 00000000..e11bd855 --- /dev/null +++ b/build/tools/makenorfirm/misc.c @@ -0,0 +1,627 @@ +/*---------------------------------------------------------------------------* + 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. + + $Log: $ + $NoKeywords: $ + *---------------------------------------------------------------------------*/ +#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; + +#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 new file mode 100644 index 00000000..42a287fa --- /dev/null +++ b/build/tools/makenorfirm/out_norfirm.c @@ -0,0 +1,984 @@ +/*---------------------------------------------------------------------------* + 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. + + $Log: $ + $NoKeywords: $ + *---------------------------------------------------------------------------*/ +#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 +#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] = 0xff; + 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], 0xff, 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 new file mode 100644 index 00000000..eeeb9895 --- /dev/null +++ b/build/tools/makenorfirm/path.c @@ -0,0 +1,931 @@ +/*---------------------------------------------------------------------------* + 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 new file mode 100644 index 00000000..e9956dc6 --- /dev/null +++ b/build/tools/makenorfirm/path.h @@ -0,0 +1,93 @@ +/*---------------------------------------------------------------------------* + 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 new file mode 100644 index 00000000..b2673ecf --- /dev/null +++ b/build/tools/makenorfirm/test/Makefile @@ -0,0 +1,57 @@ +#! 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. +# +# $Log: $ +# $NoKeywords: $ +#--------------------------------------------------------------------------- + +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 new file mode 100644 index 00000000..ccf67c18 Binary files /dev/null and b/build/tools/makenorfirm/test/rsa_private.der differ diff --git a/build/tools/makenorfirm/test/test.norsf b/build/tools/makenorfirm/test/test.norsf new file mode 100644 index 00000000..7c3093af --- /dev/null +++ b/build/tools/makenorfirm/test/test.norsf @@ -0,0 +1,30 @@ +#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 new file mode 100644 index 00000000..b255bd21 Binary files /dev/null and b/build/tools/makenorfirm/test/twl_norfirm7_print.axf differ diff --git a/build/tools/makenorfirm/test/twl_norfirm7_print.sbin b/build/tools/makenorfirm/test/twl_norfirm7_print.sbin new file mode 100644 index 00000000..a4eeebce Binary files /dev/null and b/build/tools/makenorfirm/test/twl_norfirm7_print.sbin differ diff --git a/build/tools/makenorfirm/test/twl_norfirm9_print.axf b/build/tools/makenorfirm/test/twl_norfirm9_print.axf new file mode 100644 index 00000000..3d064b38 Binary files /dev/null and b/build/tools/makenorfirm/test/twl_norfirm9_print.axf differ diff --git a/build/tools/makenorfirm/test/twl_norfirm9_print.sbin b/build/tools/makenorfirm/test/twl_norfirm9_print.sbin new file mode 100644 index 00000000..cd305be4 Binary files /dev/null and b/build/tools/makenorfirm/test/twl_norfirm9_print.sbin differ diff --git a/build/tools/makenorfirm/test/wram_rbin/Makefile b/build/tools/makenorfirm/test/wram_rbin/Makefile new file mode 100644 index 00000000..2d5f2eac --- /dev/null +++ b/build/tools/makenorfirm/test/wram_rbin/Makefile @@ -0,0 +1,47 @@ +#! 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. +# +# $Log: $ +# $NoKeywords: $ +#---------------------------------------------------------------------------- + +SUBDIRS = + +LINCLUDES = ../include + +#---------------------------------------------------------------------------- + +TARGET_BIN = wram_regs.rbin + +SRCS = \ + wram_regs.c \ + +#SRCDIR = # using default +#LCFILE = # using default + + +include $(TWLFIRM_ROOT)/build/buildtools/commondefs + +INSTALL_DIR = . +INSTALL_TARGETS = $(BINDIR)/$(TARGET_BIN) + + +#---------------------------------------------------------------------------- + +do-build: $(TARGETS) + + +include $(TWLFIRM_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 new file mode 100644 index 00000000..b87e8ba5 --- /dev/null +++ b/build/tools/makenorfirm/test/wram_rbin/wram_regs.c @@ -0,0 +1,88 @@ +/*---------------------------------------------------------------------------* + 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. + + $Log: $ + $NoKeywords: $ + *---------------------------------------------------------------------------*/ +#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 new file mode 100644 index 00000000..b303c52e --- /dev/null +++ b/build/tools/makenorfirm/wram_regs.c @@ -0,0 +1,91 @@ +/*---------------------------------------------------------------------------* + 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. + + $Log: $ + $NoKeywords: $ + *---------------------------------------------------------------------------*/ +#include "format_rom.h" +#define SDK_ASM +#include +#include + +MIHeader_WramRegs wram_regs_init = +{ + // 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 + 3, + + // VRAM-C + 7, + // VRAM-D + 7, +}; + diff --git a/include/firm.h b/include/firm.h new file mode 100644 index 00000000..a44dcc38 --- /dev/null +++ b/include/firm.h @@ -0,0 +1,29 @@ +/*---------------------------------------------------------------------------* + Project: TwlFirm + File: firm.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. + + $Log: $ + $NoKeywords: $ + *---------------------------------------------------------------------------*/ +#ifndef FIRM_H_ +#define FIRM_H_ + +#include + +#include +#include +#include +#include +#include +#include + +/* FIRM_H_ */ +#endif diff --git a/include/firm/acsign.h b/include/firm/acsign.h new file mode 100644 index 00000000..2ccfcced --- /dev/null +++ b/include/firm/acsign.h @@ -0,0 +1,32 @@ +/*---------------------------------------------------------------------------* + Project: TwlFirm - ACSIGN + File: acsign.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. + + $Log: $ + $NoKeywords: $ + *---------------------------------------------------------------------------*/ + +#ifndef FIRM_ACSIGN_H_ +#define FIRM_ACSIGN_H_ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +/* FIRM_ACSIGN_H_ */ +#endif diff --git a/include/firm/aes.h b/include/firm/aes.h new file mode 100644 index 00000000..403eec4a --- /dev/null +++ b/include/firm/aes.h @@ -0,0 +1,27 @@ +/*---------------------------------------------------------------------------* + Project: TwlFirm - include - AES + File: aes.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. + + $Log: $ + $NoKeywords: $ + *---------------------------------------------------------------------------*/ +#ifndef FIRM_AES_H_ +#define FIRM_AES_H_ + +#ifdef SDK_ARM7 +#include +#include +#include +#include +#endif // SDK_ARM7 + +/* FIRM_AES_H_ */ +#endif diff --git a/include/firm/aes/ARM7/aes_ids.h b/include/firm/aes/ARM7/aes_ids.h new file mode 100644 index 00000000..53b19963 --- /dev/null +++ b/include/firm/aes/ARM7/aes_ids.h @@ -0,0 +1,41 @@ +/*---------------------------------------------------------------------------* + 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. + + $Log: $ + $NoKeywords: $ + *---------------------------------------------------------------------------*/ + +#ifndef TWL_AES_AES_IDS_H_ +#define TWL_AES_AES_IDS_H_ + +#define AES_IDS_ID0_A (('N' << 0) | ('i' << 8) | ('n' << 16) | ('t' << 24)) +#define AES_IDS_ID0_B (('e' << 0) | ('n' << 8) | ('d' << 16) | ('o' << 24)) +#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)) + +#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)) +#define AES_IDS_ID1_C (*(unsigned long*)0x04004d04) +#define AES_IDS_ID1_D (*(unsigned long*)0x04004d00) + +#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)) + +#define AES_IDS_ID3_A (*(unsigned long*)0x04004d00) +#define AES_IDS_ID3_B (('N' << 0) | ('I' << 8) | ('N' << 16) | ('T' << 24)) +#define AES_IDS_ID3_C (('E' << 0) | ('N' << 8) | ('D' << 16) | ('O' << 24)) +#define AES_IDS_ID3_D (*(unsigned long*)0x04004d04) + +/* TWL_AES_AES_IDS_H_ */ +#endif diff --git a/include/firm/aes/ARM7/aes_init.h b/include/firm/aes/ARM7/aes_init.h new file mode 100644 index 00000000..cc787258 --- /dev/null +++ b/include/firm/aes/ARM7/aes_init.h @@ -0,0 +1,34 @@ +/*---------------------------------------------------------------------------* + Project: TwlFirm - AES - include + File: aes_init.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. + + $Log: $ + $NoKeywords: $ + *---------------------------------------------------------------------------*/ + +#ifndef TWL_AES_AES_INIT_H_ +#define TWL_AES_AES_INIT_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +/*---------------------------------------------------------------------------* + ֐` + *---------------------------------------------------------------------------*/ +void AESi_InitGameKeys( u8 game_code[4] ); + +/* TWL_AES_AES_INIT_H_ */ +#endif diff --git a/include/firm/devices/firm_sdmc/ARM7/sdmc.h b/include/firm/devices/firm_sdmc/ARM7/sdmc.h new file mode 100644 index 00000000..7ddbb092 --- /dev/null +++ b/include/firm/devices/firm_sdmc/ARM7/sdmc.h @@ -0,0 +1,170 @@ + +#ifndef __SDMC_H__ +#define __SDMC_H__ + +//#include +//#include + + +#ifdef __cplusplus +extern "C" { +#endif + + + +/********************************************* + |[gԍ +*********************************************/ +typedef enum { + SDMC_PORT_CARD = 0x400, + SDMC_PORT_NAND = 0x401 +}SDMC_PORT_NO; + + +/********************************************* + DMAԍ +*********************************************/ +typedef enum { + SDMC_USE_DMA_0 = 0, + SDMC_USE_DMA_1 = 1, + SDMC_USE_DMA_2 = 2, + SDMC_USE_DMA_3 = 3, + SDMC_NOUSE_DMA = 0xFF +}SDMC_DMA_NO; + + +/********************************************* + J[hG[R[hiJ[hG[Xe[^XݒljAvP[VŗLSDCARD_ErrStatusɑ΂ +*********************************************/ +typedef enum { + SDMC_NORMAL = 0, /* I */ + SDMC_ERR_COMMAND = 0x0001, /* CMDG[ */ + SDMC_ERR_CRC = 0x0002, /* CRCG[ */ + SDMC_ERR_END = 0x0004, /* sG[ */ + SDMC_ERR_TIMEOUT = 0x0008, /* R}h^CAEg */ + SDMC_ERR_FIFO_OVF = 0x0010, /* FIFO I[o[t[G[(INFO2Illegal write access to buffer) */ + SDMC_ERR_FIFO_UDF = 0x0020, /* FIFO A_[t[G[(INFO2Illegal read access to buffer) */ + SDMC_ERR_WP = 0x0040, /* WriteProtectɂ鏑݃G[ */ + SDMC_ERR_FPGA_TIMEOUT = 0x0100, /* FPGA ANZX^CAEg */ + SDMC_ERR_PARAM = 0x0200, /* R}hp[^G[ */ + SDMC_ERR_R1_STATUS = 0x0800, /* Normal response command J[hXe[^X G[ */ + SDMC_ERR_NUM_WR_SECTORS = 0x1000, /* ݊ZN^ G[ */ + SDMC_ERR_RESET = 0x2000, /* J[hZbgR}h1.5b^CAEgG[ */ + SDMC_ERR_ILA = 0x4000, /* C[KANZXG[ */ + SDMC_ERR_INFO_DETECT = 0x8000 /* J[hroʃG[rbg(IO3) */ +}SDMC_ERR_CODE; + + +/********************************************* + SDhCoʒʒm\ +*********************************************/ +typedef struct { + u16 b_flags; /* e */ + u16 result; /* s */ + u32 resid; /* ǂ()TCY */ +} SdmcResultInfo; + + + + + +/********************************************* + SD|[gԕۑp\ +*********************************************/ +typedef struct +{ + u16 SD_CID[8]; /* CIDۑp (Card IDentification register) : ID*/ + u16 SD_CSD[8]; /* CSDۑp (Card Specific Data register) : spec*/ + u16 SD_OCR[2]; /* OCRۑp (Operation Condition Register) : voltage and status*/ + u16 SD_SCR[4]; /* SCRۑp (Sd card Configulation Register) : bus-width, card-ver, etc*/ + u16 SD_RCA; /* RCAۑp (Relative Card Address register) : address*/ + s16 MMCFlag; + s16 SDHCFlag; + s16 SDFlag; + SDMC_ERR_CODE ErrStatus; /* SDCARD_ErrStatus */ + u32 Status; /* SDCARD_Status */ + u16 SD_CLK_CTRL_VALUE; + u16 SD_OPTION_VALUE; + + s16 OutFlag; + u16 port_no; +} +SDPortContext; + + + + + +/********************************************* + SDXybN\ +*********************************************/ +typedef struct { + u32 csd_ver2_flag; //CSDtH[}bgo[W(SDHĈƂ1) + u32 memory_capacity; //data areãTCY(512ByteP) + u32 protected_capacity; //protected areãTCY(512ByteP) + u32 card_capacity; //J[hŜ̃TCY(512ByteP) + + u32 adjusted_memory_capacity; //memory_capacityV_(heads*secptrack)̔{ɒTCY(cylinders*heads*secptrackɂȂ) + + u16 heads; + u16 secptrack; + u16 cylinders; + u16 SC; //sectors per cluster + u16 BU; + u16 RDE; //number of root dir entries(512 fix) + u32 SS; //sector size(512 fix) + u32 RSC; //reserved sector count(1 fix) +// u32 TS; //total sectors + u16 FATBITS; //16 or 32 + u16 SF; //sectors per FAT + u32 SSA; //sectors in system area + u32 NOM; //sectors in master boot record +} SdmcSpec; + + +/********************************************* + RTFSphCoC^tF[X +*********************************************/ +#if 0 +BOOL sdmcRtfsIo( int driveno, dword block, void* buffer, word count, BOOLEAN reading); +int sdmcRtfsCtrl( int driveno, int opcode, void* pargs); +BOOL sdmcRtfsAttach( int driveno); +#endif + +BOOL sdmcCheckMedia( void); + + + +/********************************************* + {API +*********************************************/ +void sdmcClearPortContext( SDPortContext* buf_adr); +SDMC_ERR_CODE sdmcCheckPortContext( SDPortContext* buf_adr); + + +SDMC_ERR_CODE sdmcInit( SDMC_DMA_NO dma_no, void (*func1)(void),void (*func2)(void)); /* J[hhCo */ +SDMC_ERR_CODE sdmcReset( void); /* J[hZbg */ + +SDMC_ERR_CODE sdmcGetStatus(u16 *status); /* J[hhCǒ݂̏Ԃ擾 */ +u32 sdmcGetCardSize(void); /* J[hSTCY̎擾 */ + +/*SD I/FFIFOgă[hij*/ +SDMC_ERR_CODE sdmcReadFifo(void* buf,u32 bufsize,u32 offset,void(*func)(void),SdmcResultInfo *info);/* eXgpJ[h[h */ +/*[h*/ +SDMC_ERR_CODE sdmcRead(void* buf,u32 bufsize,u32 offset,void(*func)(void),SdmcResultInfo *info); /* eXgpJ[h[h */ + +/*SD I/FFIFOgăCgij*/ +SDMC_ERR_CODE sdmcWriteFifo(void* buf,u32 bufsize,u32 offset,void(*func)(void),SdmcResultInfo *info);/* eXgpJ[hCg */ +/*Cg*/ +SDMC_ERR_CODE sdmcWrite(void* buf,u32 bufsize,u32 offset,void(*func)(void),SdmcResultInfo *info); /* eXgpJ[hCg */ + +u16 sdmcSelectedNo(void); +SDMC_ERR_CODE sdmcSelect( u16 select); + + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif /*__SDMC_H__*/ diff --git a/include/firm/format/firm_common.h b/include/firm/format/firm_common.h new file mode 100644 index 00000000..21816c18 --- /dev/null +++ b/include/firm/format/firm_common.h @@ -0,0 +1,66 @@ +/*---------------------------------------------------------------------------* + Project: TwlFirm - format - firm + File: firm_common.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. + + $Log: $ + $NoKeywords: $ + *---------------------------------------------------------------------------*/ +#ifndef FIRM_FORMAT_FIRM_COMMON_H_ +#define FIRM_FORMAT_FIRM_COMMON_H_ + +#include +#include + + +#ifdef __cplusplus +extern "C" { +#endif + + +// 풓W[ +typedef struct +{ + u32 rom_offset; /* ] ROM ItZbg */ + u32 decomp_size; /* WJTCY */ + void *ram_address; /* ] RAM ItZbg */ + u32 size; /* ]TCY */ +} +FIRMHeader_ModuleInfo; + +// DS-IPL2wb_ +typedef struct +{ + u16 reserved_0h[4]; + u32 ds_key; + u16 ds_arm9_romAdr; + u16 ds_arm9_ramAdr; + u16 ds_arm7_romAdr; + u16 ds_arm7_ramAdr; + u16 ds_arm9_romOffsetUnit:3; + u16 ds_arm9_ramOffsetUnit:3; + u16 ds_arm7_romOffsetUnit:3; + u16 ds_arm7_ramOffsetUnit:3; + u16 :2; + u16 ds_header_ver:2; + u16 ds_data_romAdr; + u64 card_key; + u16 ncd_romAdr; + u16 reserved_24h[2]; + u16 ds_data_crc16; +} +NORHeaderDS; + + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif // FIRM_FORMAT_FIRM_COMMON_H_ diff --git a/include/firm/format/from_brom.h b/include/firm/format/from_brom.h new file mode 100644 index 00000000..de165174 --- /dev/null +++ b/include/firm/format/from_brom.h @@ -0,0 +1,92 @@ +/*---------------------------------------------------------------------------* + Project: TwlFirm - format - from_brom + File: from_brom.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. + + $Log: $ + $NoKeywords: $ + *---------------------------------------------------------------------------*/ +#ifndef FIRM_FORMAT_FROM_BROM_H_ +#define FIRM_FORMAT_FROM_BROM_H_ + +#include +#include +#include +#include +#include + + + + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef SDK_ARM9 +#define RSA_PUBKEY_NUM_FROM_BROM 8 +#define AESKEY_NUM_FROM_BROM 8 +#else // SDK_ARM7 +#define RSA_PUBKEY_NUM_FROM_BROM 4 +#define AESKEY_NUM_FROM_BROM 4 +#endif // SDK_ARM7 + +typedef struct +{ + union + { + NANDHeader nand; + NORHeader nor; + GCDHeader gcd; + u8 max[0x400]; + } + header; // 1KB + + u8 rsa_pubkey[RSA_PUBKEY_NUM_FROM_BROM][ACS_PUBKEY_LEN]; // 1KB + u8 aes_key[AESKEY_NUM_FROM_BROM][ACS_AES_LEN]; // 128B + u8 hash_table_hash[ACS_HASH_LEN]; // 20B + + BLOWFISH_CTX ds_blowfish; // 4KB + + BLOWFISH_CTX twl_blowfish; // 4KB + +} +OSFromBrom9Buf; + +typedef struct +{ + union + { + NANDHeader nand; + NORHeader nor; + GCDHeader gcd; + u8 max[0x400]; + } + header; // 1KB + + u8 rsa_pubkey[RSA_PUBKEY_NUM_FROM_BROM][ACS_PUBKEY_LEN]; // 512B + u8 aes_key[AESKEY_NUM_FROM_BROM][ACS_AES_LEN]; // 64B + u8 hash_table_hash[ACS_HASH_LEN]; // 20B + + BLOWFISH_CTX twl_blowfish[2]; // (4KB + ) * 2 + + SDPortContext SDNandContext; +} +OSFromBrom7Buf; + +#ifdef SDK_ARM9 +typedef OSFromBrom9Buf OSFromBromBuf; +#else // SDK_ARM7 +typedef OSFromBrom7Buf OSFromBromBuf; +#endif // SDK_ARM7 + + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif // FIRM_FORMAT_FROM_BROM_H_ diff --git a/include/firm/format/gcdfirm.h b/include/firm/format/gcdfirm.h new file mode 100644 index 00000000..1c8b771b --- /dev/null +++ b/include/firm/format/gcdfirm.h @@ -0,0 +1,113 @@ +/*---------------------------------------------------------------------------* + Project: TwlFirm - format - gcdfirm + File: gcdfirm.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. + + $Log: $ + $NoKeywords: $ + *---------------------------------------------------------------------------*/ +#ifndef FIRM_FORMAT_GCDFIRM_H_ +#define FIRM_FORMAT_GCDFIRM_H_ + +#include +#include +#include + + +#ifdef __cplusplus +extern "C" { +#endif + + +/*===========================================================================* + * NOR FORMAT + *===========================================================================*/ + +//--------------------------------------------------------------------------- +// Section A NOR HEADER +//--------------------------------------------------------------------------- + +// 풓W[ +typedef FIRMHeader_ModuleInfo GCDHeader_ModuleInfo; + +// TWL-GCDt@[wb_ +typedef struct +{ + /* 0x000-0x020 [VXe\̈] */ + u8 reserved_0h[0x14]; + u8 rom_size; // Rom size (2rom_size Mbit: ex. 128Mbit̂Ƃrom_size = 7) + u8 reserved_16h[0xb]; + + /* 0x020-0x040 [풓W[pp[^] */ + u32 main_rom_offset; /* ARM9 ] ROM ItZbg */ + u32 main_decomp_size; /* ARM9 WJTCY */ + void *main_ram_address; /* ARM9 ] RAM ItZbg */ + u32 main_size; /* ARM9 ]TCY */ + u32 sub_rom_offset; /* ARM7 ] ROM ItZbg */ + u32 sub_decomp_size; /* ARM9 WJTCY */ + void *sub_ram_address; /* ARM7 ] RAM ItZbg */ + u32 sub_size; /* ARM7 ]TCY */ + + /* 0x040-0x080 [VXe\̈] */ + u8 reserved_40h[0x40]; + + /* 0x080-0x090 [t@[oCi] */ + u32 nandfirm_offset; // address of rom_valid_size + u32 nandfirm_size; // address of rom_header_size + u32 norfirm_offset; // address of main_module_param + u32 norfirm_size; // address of sub_module_param + + /* 0x090-0x094 [TWL-ROMRg[] */ + u16 normal_area_offset; + u16 twl_area_offset; + + /* 0x094-0x0c0 [VXe\̈] */ + u8 reserved_98h[0x2c]; + + /* 0x0c0-0x100 [DSJ[hNINTENDOSd̈] */ + u8 reserved_C0h[0x3f]; + + u8 comp_arm9_boot_area:1; // Compress arm9 boot area + u8 comp_arm7_boot_area:1; // Compress arm7 boot area + u8 arm9_x2:1; + u8 :0; +} +GCDHeaderLow; + +typedef struct +{ + /* 0x180-0x1b0 [WRAMWX^p[^] */ + MIHeader_WramRegs w; + + /* 0x1b0-0x200 [VXe\̈] */ + u8 reserved_footer[0x50]; +} +GCDHeaderHigh; + +// GCDwb_ +typedef struct +{ + /* 0x000-0x100 */ + GCDHeaderLow l; + + /* 0x100-0x180 */ + FIRMPaddedSign sign; + + /* 0x180-0x200 */ + GCDHeaderHigh h; +} +GCDHeader; + + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif //FIRM_FORMAT_GCDFIRM_H_ diff --git a/include/firm/format/nandfirm.h b/include/firm/format/nandfirm.h new file mode 100644 index 00000000..1ec292c0 --- /dev/null +++ b/include/firm/format/nandfirm.h @@ -0,0 +1,130 @@ +/*---------------------------------------------------------------------------* + Project: TwlFirm - format - nandfirm + File: nandfirm.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. + + $Log: $ + $NoKeywords: $ + *---------------------------------------------------------------------------*/ +#ifndef FIRM_FORMAT_NAND_H_ +#define FIRM_FORMAT_NAND_H_ + +#include +#include +#include + + +#ifdef __cplusplus +extern "C" { +#endif + + +/*===========================================================================* + * NAND FORMAT + *===========================================================================*/ + +//--------------------------------------------------------------------------- +// Section A NAND HEADER +//--------------------------------------------------------------------------- + +// 풓W[ +typedef FIRMHeader_ModuleInfo NANDHeader_ModuleInfo; + +// TWL-NANDt@[wb_ +typedef struct +{ + /* 0x000-0x020 [VXe\̈] */ + u8 reserved_0h[0x20]; /* VXe\ A */ + + /* 0x020-0x040 [풓W[pp[^] */ + u32 main_rom_offset; /* ARM9 ] ROM ItZbg */ + u32 main_decomp_size; /* ARM9 WJTCY */ + void *main_ram_address; /* ARM9 ] RAM ItZbg */ + u32 main_size; /* ARM9 ]TCY */ + u32 sub_rom_offset; /* ARM7 ] ROM ItZbg */ + u32 sub_decomp_size; /* ARM9 WJTCY */ + void *sub_ram_address; /* ARM7 ] RAM ItZbg */ + u32 sub_size; /* ARM7 ]TCY */ + + /* 0x040-0x0c0 [VXe\̈] */ + u8 reserved_40h[0x80]; + + /* 0x0c0-0x100 [DSJ[hNINTENDOSd̈] */ + u8 reserved_C0h[0x3f]; + + u8 comp_arm9_boot_area:1; // Compress arm9 boot area + u8 comp_arm7_boot_area:1; // Compress arm7 boot area + u8 arm9_x2:1; + u8 arm9_decomp:1; + u8 :0; +} +NANDHeaderLow; + +typedef struct +{ + /* 0x180-0x1b0 [WRAMWX^p[^] */ + MIHeader_WramRegs w; + + /* 0x1b0-0x200 [VXe\̈] */ + u8 reserved_footer[0x50]; +} +NANDHeaderHigh; + +// NANDwb_ +typedef struct +{ + /* 0x000-0x028 [DS-NORwb_] */ + NORHeaderDS d; + + /* 0x028-0x200 [VXe\̈(O)] */ + u8 reserved_mbr[512 - sizeof(NORHeaderDS)]; + + /* 0x200-0x300 */ + NANDHeaderLow l; + + /* 0x300-0x380 */ + FIRMPaddedSign sign; + + /* 0x380-0x400 */ + NANDHeaderHigh h; +} +NANDHeader; + +// 璷wb_ (璷) +typedef struct +{ + /* 0x400-0x500 *//* 0x600-0x700 */ + NANDHeaderLow l; + + /* 0x500-0x580 *//* 0x700-0x780 */ + FIRMPaddedSign sign; + + /* 0x580-0x600 *//* 0x780-0x800 */ + NANDHeaderHigh h; +} +NANDHeaderCore; + +// 璷wb_ (S) +typedef struct +{ + /* 0x000-0x400 [ۂɎgpwb_] */ + NANDHeader g; + /* 0x400-0x600 [ftHgʒuC[Wɑ΂wb_] */ + NANDHeaderCore o; + /* 0x600-0x800 [ꎞҔʒuC[Wɑ΂wb_] */ + NANDHeaderCore m; +} +NANDHeaderEx; + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif //FIRM_FORMAT_NAND_H_ diff --git a/include/firm/format/norfirm.h b/include/firm/format/norfirm.h new file mode 100644 index 00000000..6eafc329 --- /dev/null +++ b/include/firm/format/norfirm.h @@ -0,0 +1,107 @@ +/*---------------------------------------------------------------------------* + Project: TwlFirm - format - norfirm + File: norfirm.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. + + $Log: $ + $NoKeywords: $ + *---------------------------------------------------------------------------*/ +#ifndef FIRM_FORMAT_NOR_H_ +#define FIRM_FORMAT_NOR_H_ + +#include +#include +#include + + +#ifdef __cplusplus +extern "C" { +#endif + + +/*===========================================================================* + * NOR FORMAT + *===========================================================================*/ + +//--------------------------------------------------------------------------- +// Section A NOR HEADER +//--------------------------------------------------------------------------- + +// 풓W[ +typedef FIRMHeader_ModuleInfo NORHeader_ModuleInfo; + +// TWL-NORt@[wb_ +typedef struct +{ + /* 0x000-0x020 [VXe\̈] */ + u8 reserved_0h[0x20]; /* VXe\ A */ + + /* 0x020-0x040 [풓W[pp[^] */ + u32 main_rom_offset; /* ARM9 ] ROM ItZbg */ + u32 main_decomp_size; /* ARM9 WJTCY */ + void *main_ram_address; /* ARM9 ] RAM ItZbg */ + u32 main_size; /* ARM9 ]TCY */ + u32 sub_rom_offset; /* ARM7 ] ROM ItZbg */ + u32 sub_decomp_size; /* ARM9 WJTCY */ + void *sub_ram_address; /* ARM7 ] RAM ItZbg */ + u32 sub_size; /* ARM7 ]TCY */ + + /* 0x040-0x0c0 [VXe\̈] */ + u8 reserved_40h[0x80]; + + /* 0x0c0-0x100 [DSJ[hNINTENDOSd̈] */ + u8 reserved_C0h[0x3f]; + + u8 comp_arm9_boot_area:1; // Compress arm9 boot area + u8 comp_arm7_boot_area:1; // Compress arm7 boot area + u8 arm9_x2:1; + u8 arm9_decomp:1; + u8 :2; + u8 baudrate:1; + u8 boot_nandfirm:1; +} +NORHeaderLow; + +typedef struct +{ + /* 0x180-0x1b0 [WRAMWX^p[^] */ + MIHeader_WramRegs w; + + /* 0x1b0-0x200 [VXe\̈] */ + u8 reserved_footer[0x50]; +} +NORHeaderHigh; + +// NORwb_ +typedef struct +{ + /* 0x000-0x028 */ + NORHeaderDS d; + + /* 0x028-0x200 */ + u8 wl_params[472]; + + /* 0x200-0x300 */ + NORHeaderLow l; + + /* 0x300-0x380 */ + FIRMPaddedSign sign; + + /* 0x380-0x400 */ + NORHeaderHigh h; +} +NORHeader; + + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif //FIRM_FORMAT_NOR_H_ diff --git a/include/firm/format/sign.h b/include/firm/format/sign.h new file mode 100644 index 00000000..7dc5d7e9 --- /dev/null +++ b/include/firm/format/sign.h @@ -0,0 +1,94 @@ +/*---------------------------------------------------------------------------* + Project: TwlFirm - format - sign + File: sign.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. + + $Log: $ + $NoKeywords: $ + *---------------------------------------------------------------------------*/ +#ifndef FORMAT_SIGN_H_ +#define FORMAT_SIGN_H_ + + +#ifdef __cplusplus +extern "C" { +#endif + +// signed hash index +typedef enum +{ + FIRM_SIGNED_HASH_IDX_HEADER = 0, + FIRM_SIGNED_HASH_IDX_ARM9 = 1, + FIRM_SIGNED_HASH_IDX_ARM7 = 2, + FIRM_SIGNED_HASH_IDX_HASH_TABLE = 3, + FIRM_SIGNED_HASH_IDX_FINAL = 4, + + FIRM_SIGNED_HASH_NUM = 5 +} +FIRMSignedHashIndex; + + +#define ACS_BASE_BLOCK_SIZE 4096 // should be the multiple of 16 +#define ACS_META_BLOCK_SIZE 5120 // should be the multiple of 16 and the multiple of 20 + // would be the multiple of 512, then the mutilple of 2560 + +#define ACS_PUBKEY_LEN 128 +#define ACS_HASH_LEN 20 +#define ACS_AES_LEN 16 + +#define ACS_ENCRYPTED_HASH_LEN ACS_PUBKEY_LEN +#define ACS_DECRYPTED_HASH_LEN ACS_HASH_LEN + +#define ACS_RSA_EXP 0x00010001 +#define ACS_RSA_EXP_LEN 3 + +// DER format of RSA keys + +#define ACS_RSA_PRVMOD_OFFSET 0x0B +#define ACS_RSA_PRVEXP_OFFSET 0x93 +#define ACS_RSA_PRVMOD_LEN 128 +#define ACS_RSA_PRVEXP_LEN 128 + +#define ACS_RSA_PUBMOD_OFFSET 0x1D +#define ACS_RSA_PUBEXP_OFFSET 0x93 +#define ACS_RSA_PUBMOD_LEN 128 +#define ACS_RSA_PUBEXP_LEN ACS_RSA_EXP_LEN + +#define FIRM_HEADER_2ND_HASH_AREA_LEN (sizeof(FIRMSignedContext) - ACS_HASH_LEN) + + +// ReLXg +typedef struct +{ + unsigned char aes_key[ACS_AES_LEN]; + unsigned char hash[FIRM_SIGNED_HASH_NUM][ACS_HASH_LEN]; +} +FIRMSignedContext; + +// +typedef union +{ + struct + { + unsigned char prePad[(ACS_ENCRYPTED_HASH_LEN - sizeof(FIRMSignedContext))-1]; + FIRMSignedContext c; + unsigned char postPad[1]; + } + e; + unsigned int raw[ACS_ENCRYPTED_HASH_LEN/4]; +} +FIRMPaddedSign; + + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif //FORMAT_SIGN_H_ diff --git a/include/firm/format/wram_regs.h b/include/firm/format/wram_regs.h new file mode 100644 index 00000000..10e8347c --- /dev/null +++ b/include/firm/format/wram_regs.h @@ -0,0 +1,52 @@ +/*---------------------------------------------------------------------------* + Project: TwlFirm - MI - include + File: wram_regs.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. + + $Log: $ + $NoKeywords: $ + *---------------------------------------------------------------------------*/ +#ifndef FIRM_FORMAT_WRAM_REGS_H_ +#define FIRM_FORMAT_WRAM_REGS_H_ + + +#ifdef __cplusplus +extern "C" { +#endif + +// WRAM}bsOWX^ +typedef struct +{ + u8 main_wrambnk_a[4]; // ARM9 SCFG_MBK1 + u8 main_wrambnk_b[8]; // ARM9 SCFG_MBK2-3 + u8 main_wrambnk_c[8]; // ARM9 SCFG_MBK4-5 + + u32 main_wrammap_a; // ARM9 SCFG_MBK6 + u32 main_wrammap_b; // ARM9 SCFG_MBK7 + u32 main_wrammap_c; // ARM9 SCFG_MBK8 + + u32 sub_wrammap_a; // ARM7 SCFG_MBK6 + u32 sub_wrammap_b; // ARM7 SCFG_MBK7 + u32 sub_wrammap_c; // ARM7 SCFG_MBK8 + + u8 sub_wramlock[3]; // ARM7 SCFG_MBK9 + + u8 main_wrambnk_01:2; // ARM9 RBKCNT1_H + u8 main_vrambnk_c:3; // ARM9 RBKCNT0_H + u8 main_vrambnk_d:3; // ARM9 RBKCNT0_H +} +MIHeader_WramRegs; + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +/* FIRM_FORMAT_WRAM_REGS_H_ */ +#endif diff --git a/include/firm/gcd.h b/include/firm/gcd.h new file mode 100644 index 00000000..8f2404c6 --- /dev/null +++ b/include/firm/gcd.h @@ -0,0 +1,25 @@ +/*---------------------------------------------------------------------------* + Project: TwlFirm - GCD + File: gcd.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. + + $Log: $ + $NoKeywords: $ + *---------------------------------------------------------------------------*/ + +#ifndef FIRM_GCD_H_ +#define FIRM_GCD_H_ + +//#include +#include +#include + +/* FIRM_GCD_H_ */ +#endif diff --git a/include/firm/gcd/blowfish.h b/include/firm/gcd/blowfish.h new file mode 100644 index 00000000..6d33d599 --- /dev/null +++ b/include/firm/gcd/blowfish.h @@ -0,0 +1,41 @@ +/*---------------------------------------------------------------------------* + Project: TwlFirm - GCD - include + File: blowfish.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. + + $Log: $ + $NoKeywords: $ + *---------------------------------------------------------------------------*/ +#ifndef FIRM_GCD_BLOWFISH_H +#define FIRM_GCD_BLOWFISH_H + +#include + + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct { + u32 P[16 + 2]; + u32 S[4][256]; +} BLOWFISH_CTX; + + +void InitBlowfish(BLOWFISH_CTX *ctx, const unsigned char *key, int keyLen); +void EncryptByBlowfish(const BLOWFISH_CTX *ctx, u32 *xl, u32 *xr); +void DecryptByBlowfish(const BLOWFISH_CTX *ctx, u32 *xl, u32 *xr); + + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif // FIRM_GCD_BLOWFISH_H diff --git a/include/firm/gcd/gcd.h b/include/firm/gcd/gcd.h new file mode 100644 index 00000000..347d84c3 --- /dev/null +++ b/include/firm/gcd/gcd.h @@ -0,0 +1,773 @@ +/*---------------------------------------------------------------------------* + Project: TwlFirm - GCD - include + File: gcd.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. + + $Log: $ + $NoKeywords: $ + *---------------------------------------------------------------------------*/ + +#ifndef FIRM_GCD_GCD_H_ +#define FIRM_GCD_GCD_H_ + +#include +#include +#include +#include +#include +#include + + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum +{ + GCD_PRIMARY_SLOT = 0, + GCD_SECONDARY_SLOT = 1, + + GCD_NO_SLOT = -1 +} +GCDSlot; + + +/*****************/ + +/* ROMwb_Eu[gp[^\ */ +typedef struct { + u8 *romAddr; // ROMAhX + u8 *entryAddr; // GgAhX + u8 *ramAddr; // RAMAhX + s32 romSize; // ROMTCY +} GCDBootUsrParam; + +// J[hANZXERg[WX^\ +typedef struct { + u16 latency1:13; // CeVP̃TCN + u16 dataScramble_on:1; // f[^XNu nm + u16 scrambleUnit_on:1; // XNuH nm + u16 initScramblePN:1; // XNuomf[^ + u16 latency2:6; // CeVQ̃TCN + u16 cmdScramble_on:1; // R}hXNu nm + u16 dataReady:1; // f[^ fB + u16 pages:3; // y[W + u16 clockType:1; // NbN^CviPTO^QSOj + u16 clockInLatency:1; // CeVԂɃNbN + u16 reset:1; // ZbgM + u16 accessMode:1; // ANZX[h + u16 start:1; // X^[g +} GCDCardCnt; + +// J[hRg[Ep[^\ +typedef struct { + // u32 dmaNo; // DMAԍ + u32 cardCnt; // J[hRg[ + u32 op[2]; // R}h +} GCDCardCtrlParam; + + +/* ROMwb_\ */ +typedef struct { + s8 titleName[12]; // \tg^Cg + u32 initialCode; // CjVR[h + + u16 makerCode; // [J[R[h + u8 machineCode; // {̃R[h + u8 deviceType; // foCX^Cv + + u8 nonVerReserved[4]; // \i4oCgj + u8 verDepReserved[4]; // \io[WˑA4oCgj + u16 wirelessSerialNo; + u16 softVersion:8; // \tgo[W + u16 compArm9BootArea:1; // ARM9u[gGAktO + u16 compArm7BootArea:1; // ARM7u[gGAktO + u16 :0; + + GCDBootUsrParam arm9; // ARM9u[g̈p[^ + GCDBootUsrParam arm7; // ARM7u[g̈p[^ + + u32 fileSysReserved[8]; // t@CVXe\i32oCgj + + GCDCardCnt romCtrl4Game; // ROMRg[iNORMAL & GAME[hj + GCDCardCnt romCtrl4Secure; // iSECURE[hj + u8 romCtrlReserved_l[4]; // \ + u16 secureCRC16; // ZLÄCRC16bit + u16 romTimerLatency; // ^C}[CeVi(TCN/256) - 2A3Dpj + u8 romReserved_h[8]; // \ + u32 romNormalModeKey[2]; // NORMAL[hL[ + + u8 reserved_80h[0x10]; // \̈i16oCgj + + u16 normalAreaOffset; // NORMAL̈ + u16 twlAreaOffset; // TWLp̈ + + u8 reserved_94h[0x2c]; // \̈i44oCgj + + u16 nintendoLogo[0x9c/2]; // NINTENDOSi156oCgj + u16 ninLogoCRC16; // NINTENDOSCRC16 + u16 headerCRC16; // wb_CRC16 + + u8 *dbgRomAddr; // fobKj^ROMAhX + s32 dbgRomSize; // fobKj^ROMTCY + u8 *dbgArm9RamAddr; // fobKj^ARM9-RAMAhX + u8 *dbgArm7RamAddr; // fobKj^ARM7-RAMAhX + + u8 reserved_170h[0x10]; // \̈i16oCgj +} +GCDRomHeaderDS; + +typedef struct { + // DS݊ + GCDRomHeaderDS l; + + // TWLg + MIHeader_WramRegs w; + + u8 reserved_1b0h[0x10]; // \̈i16oCgj + + GCDBootUsrParam arm9ex; // ARM9gu[g̈p[^ + GCDBootUsrParam arm7ex; // ARM7gu[g̈p[^ + + u8 reserved_1e0h[0x1000 - 0x1e0 - 0x200]; // \̈ + + u8 acsign_contents[0x180]; // Recؖ + + u8 acsign_header[0x80]; // ROMwb_dq +} +GCDRomHeader; + + +/* ZLA[N\ */ +typedef struct { + u8 recvRtcBuf[8]; // RTCf[^Mobt@iv4oCgEj +#if 0 + u16 flashCrc16; // tbVCRC16 + u16 flashCount; // tbV 8oCgJEg + u32 flashBuf[2]; // tbVMobt@iv4oCgEj + u32 flashKeyBuf[3]; // tbVL[Ee|obt@ +#endif + u32 unScrambleKey[2]; // XNuL[i8oCgAMakeBlowfishTable() ŎZoj + s16 isGenUnScrambleKey; // XNuL[iMakeBlowfishTable() Őݒj + + u32 va; // 24biti24bitMj + u32 vb; // 20biti+`4bitAVBI: 32bitMj + u32 vc_dummy; // 16biti16bitMj + u32 vd; // 24biti24bitMj + + GCDCardCnt cardCntBak4Secure; // SECURER}hp[^EobNAbv + s16 enableReadSecure; // SECURË惊[hECl[uiLoadSecure4Card() Őݒj + u32 cardNormalModeKey[2]; // NORMAL[hL[iMakeBlowfishTable() ŎZoj + u32 cardKeyBuf[3]; // J[hL[Ee|obt@ + s32 secureSize; // SECURËTCY + s16 sequenceNo4Secure; // V[PXԍiSECUREpj + s16 segmentTblShift; // ZOgԍe[uVtgliSECUREpj + u8 *segmentTblp; // ZOge[u|C^iSECUREpj + s16 numSecureSegment; // SECUREZOgiSECUREpj + s16 segmentOffset; // ZOgItZbgiSECUREpj + s16 blockOffset; // ubNItZbgiSECUREpj + + // CardCtrlParam paramBak; // J[hp[^ ÍOobNAbviSECUREpj + + BLOWFISH_CTX blowfishCardTable; // J[hpBlowfishe[u + BLOWFISH_CTX blowfishFlashTable; + + u8 bufEnd[4]; // ZLA[NŏIf[^ +} GCDSecureWork; + + +/* L[N\ */ +typedef struct { + u32 nCardID; // NORMALJ[hIDiLoadCardHeader() Ŏ擾j + u32 sCardID; // SECUREJ[hIDiCardTimerIntr4Secure() Ŏ擾j + u16 cardHeaderCrc16; // J[hwb_CRC16iLoadCardHeader() ŎZoj + u16 cardSecureCrc16; // J[hSECURËCRC16iLoadSecure4Card() ŎZoj + s16 cardHeaderError; // J[hwb_G[iCheckCardHeader() Őݒj + s16 disableEncryptedCardData;// J[hSECURËÍf[^iDecryptObjectFile() Őݒj + s16 cardSequenceNo; // J[hǂݍ݃V[PXԍ + s16 enableCardNormalOnly; // J[hNORMAL[ĥݗLiLoadFlashDemo() Őݒj + + // s16 isOnDebugger; // fobKœ쒆 + // s16 rtcError; // RTCG[ + + u32 recvRtc[2]; // RTCXe[^X1^C}[f[^iv4oCgEj + +} GCDSharedWork; + + +typedef union +{ + u64 dw; + u8 b[8]; +} +GCDCmd64; + +typedef struct +{ + u32 ctrl; + s32 cmdcount; + u32 latency; + u32 scramble; + u8 master; + u8 spi; + GCDSlot slot; +} +GCDCtrlRegs; + +typedef struct +{ + GCDCmd64 gcdOp; + u32 dmaNo; + u32 lastDmaNo; + BOOL ltckReq; + GCDCtrlRegs *gcdRegs; + GCDCtrlRegs nLoadTableRegs; + GCDCtrlRegs nSendOnlyOpRegs; + GCDCtrlRegs sSendOnlyOpRegs; + GCDCtrlRegs nIDRegs; + GCDCtrlRegs sIDRegs; + GCDCtrlRegs gIDRegs; + GCDCtrlRegs nReadShortHeaderRegs; + GCDCtrlRegs nReadRomRegs; + GCDCtrlRegs sReadRomRegs; + GCDCtrlRegs gReadRomRegs; + GCDCtrlRegs gWriteRomRegs; +} +GCDRomCtrls; + +typedef void (* GCDRomFuncp)( u32 romp, void *ramp, s32 size ); +typedef void (* GCDAsyncCoreFuncp)( GCDSlot slot, u32 romp, void *ramp, s32 size, GCDRomCtrls *ctrls ); + + +typedef struct +{ + u32 romp; // ROM offset + u8 *ramp; // RAM address + s32 restSize; // rest size + s32 oneShotSize; // one shot size + vs8 intrDone; + s8 isAsync; + volatile BOOL isPxiDone; + GCDRomCtrls ctrls; + GCDAsyncCoreFuncp funcp; +} +GCDWork; + + +#define GCD_DEFAULT_DMA_A_NO 7 +#define GCD_DEFAULT_DMA_B_NO 6 + +#define GCD_CHATTERING_CYCLES 0x200U + +#define GCD_ROM_PAGE_SIZE 0x200 // 512B +#define GCD_SECURE_SEGMENT_SIZE 0x1000 // 4KB +#define GCD_LOAD_TABLE_SIZE 0x2000 // 8KB + +#define GCD_NML_AREA_ALIGN 0x80000 // 512KB +#define GCD_TWL_AREA_ALIGN 0x80000 // 512KB +#define GCD_SECURE2_AREA_SIZE 0x4000 // 16KB +#define GCD_SECURE2_AREA_OFFSET 0x3000 // 12KB +#define GCD_GAME2_AREA_OFFSET 0x7000 // 28KB + + +// ROM area + +#define GCD_LOAD_TABLE_SIZE 0x2000 // 8KB +#define GCD_DS_ROM_HEADER_SIZE 0x200 // 512B +#define GCD_ROM_HEADER_SIZE 0x1000 // 4KB +#define GCD_SECURE_AREA_SIZE 0x4000 // 16KB + +#define GCD_SECURE_AREA_OFFSET 0x4000 +#define GCD_GAME_AREA_OFFSET 0x8000 + + +// ROM command + +#define GCDOP_BIT_NUM 64 + +// NORMAL mode + +#define GCDOP_N_OP_MASK 0xff00000000000000ULL +#define GCDOP_N_OP_SIZE 8 + +#define GCDOP_N_OP_RD_ROM_ID 0x9000000000000000ULL +#define GCDOP_N_OP_RD_PAGE 0x0000000000000000ULL +#define GCDOP_N_OP_WR_PAGE 0x8000000000000000ULL +#define GCDOP_N_OP_LD_TABLE 0x9f00000000000000ULL +#define GCDOP_N_OP_CHG_MODE 0x3c00000000000000ULL +#define GCDOP_N_OP_CHG2_MODE 0x3d00000000000000ULL + +#define GCDOP_N_RD_ROM_ID_PAD 0x00ffffffffffffffULL +#define GCDOP_N_RD_PAGE_PAD 0x00fffffeff00ffffULL +#define GCDOP_N_CHG_MODE_PAD 0x00000000f00000ffULL +#define GCDOP_N_CHG2_MODE_PAD GCDOP_N_CHG_MODE_PAD + +#define GCDOP_N_RD_PAGE_ADDR_SHIFT 33 +#define GCDOP_N_RD_PAGE_ADDR_SIZE 23 +#define GCDOP_N_RD_PAGE_ADDR_MASK 0x00fffffe00000000ULL + +#define GCDOP_N_VAE_SHIFT 32 +#define GCDOP_N_VAE_SIZE 24 +#define GCDOP_N_VAE_MASK 0x00ffffff00000000ULL + +#define GCDOP_N_VBI_SHIFT 8 +#define GCDOP_N_VBI_SIZE 20 +#define GCDOP_N_VBI_MASK 0x000000000fffff00ULL + + +// SECURE mode + +#define GCDOP_S_OP_MASK 0xf000000000000000ULL +#define GCDOP_S_OP_SIZE 4 + +#define GCDOP_S_OP_RD_ROM_ID 0x1000000000000000ULL +#define GCDOP_S_OP_RD_SEGMENT 0x2000000000000000ULL +#define GCDOP_S_OP_PNG_ON 0x4000000000000000ULL +#define GCDOP_S_OP_PNG_OFF 0x6000000000000000ULL +#define GCDOP_S_OP_CHG_MODE 0xa000000000000000ULL + +#define GCDOP_S_VA_SHIFT GCDOP_S_VB_SIZE +#define GCDOP_S_VA_SIZE 24 +#define GCDOP_S_VA_MASK 0x00000ffffff00000ULL + +#define GCDOP_S_VB_SHIFT 0 +#define GCDOP_S_VB_SIZE 20 +#define GCDOP_S_VB_MASK 0x00000000000fffffULL + +#define GCDOP_S_VC_SHIFT (GCDOP_S_VA_SIZE + GCDOP_S_VB_SIZE) +#define GCDOP_S_VC_SIZE 16 +#define GCDOP_S_VC_MASK 0x0ffff00000000000ULL + +#define GCDOP_S_VD_SHIFT GCDOP_S_VA_SHIFT +#define GCDOP_S_VD_SIZE GCDOP_S_VA_SIZE +#define GCDOP_S_VD_MASK GCDOP_S_VA_MASK + + +// GAME mode + +#define GCDOP_G_OP_MASK 0xff00000000000000ULL +#define GCDOP_G_OP_SIZE 8 + +#define GCDOP_G_OP_RD_ROM_ID 0xb800000000000000ULL +#define GCDOP_G_OP_RD_ROM_UID 0xb900000000000000ULL +#define GCDOP_G_OP_RD_PAGE 0xb700000000000000ULL +#define GCDOP_G_OP_RD_CACHE_START 0x5800000000000000ULL +#define GCDOP_G_OP_RD_CACHE 0x6000000000000000ULL +#define GCDOP_G_OP_RD_CACHE_LAST 0x6800000000000000ULL +#define GCDOP_G_OP_WR_PAGE 0x8000000000000000ULL + +#define GCDOP_G_RD_ROM_ID_PAD 0x00ffffffffffffffULL +#define GCDOP_G_RD_ROM_UID_PAD 0x00ffffffffffffffULL +#define GCDOP_G_RD_PAGE_PAD 0x00f0000000ffffffULL + +#define GCDOP_G_RD_PAGE_ADDR_SHIFT 33 +#define GCDOP_G_RD_PAGE_ADDR_SIZE 23 +#define GCDOP_G_RD_PAGE_ADDR_MASK 0x000ffffe00000000ULL + + +// ROM ID + +#define GCD_ROMID_1TROM_MASK 0x80000000UL +#define GCD_ROMID_TWLROM_MASK 0x40000000UL +#define GCD_ROMID_BADBLK_MASK 0x20000000UL +#define GCD_ROMID_SIZE_MASK 0x0000ff00UL + + + +/*---------------------------------------------------------------------------* + Name: GCDi_ReadRomID + + Description: read rom ID + sync version + + Arguments: None + + Returns: rom ID + *---------------------------------------------------------------------------*/ +u32 GCDi_ReadRomID( GCDSlot slot ); + +/*---------------------------------------------------------------------------* + Name: GCDi_ReadRom + + Description: read rom data + sync version + + Arguments: romp : rom offset + ramp : ram destination address + size : size (byte) + + Returns: None + *---------------------------------------------------------------------------*/ +void GCDi_ReadRom( GCDSlot slot, u32 romp, void *ramp, s32 size ); + +/*---------------------------------------------------------------------------* + Name: GCDi_ReadRomAsync + + Description: read rom data + async version + + Arguments: romp : rom offset + ramp : ram destination address + size : size (byte) + + Returns: None + *---------------------------------------------------------------------------*/ +void GCDi_ReadRomAsync( GCDSlot slot, u32 romp, void *ramp, s32 size ); + +/*---------------------------------------------------------------------------* + Name: GCDi_ReadNormalModeRom + + Description: read rom data on normal mode + sync version + + Arguments: romp : rom offset + ramp : ram destination address + size : size (byte) + + Returns: None + *---------------------------------------------------------------------------*/ +void GCDi_ReadNormalModeRom( GCDSlot slot, u32 romp, void *ramp, s32 size ); + +/*---------------------------------------------------------------------------* + Name: GCD_ReadNormalModeRomAsync + + Description: read rom data on normal mode + async version + + Arguments: romp : rom offset + ramp : ram destination address + size : size (byte) + + Returns: None + *---------------------------------------------------------------------------*/ +void GCD_ReadNormalModeRomAsync( GCDSlot slot, u32 romp, void *ramp, s32 size ); + +/*---------------------------------------------------------------------------* + Name: GCDi_ReadGameModeRom + + Description: read rom data on game mode + sync version + + Arguments: romp : rom offset + ramp : ram destination address + size : size (byte) + + Returns: None + *---------------------------------------------------------------------------*/ +void GCDi_ReadGameModeRom( GCDSlot slot, u32 romp, void *ramp, s32 size ); + +/*---------------------------------------------------------------------------* + Name: GCDi_ReadGameModeRomAsync + + Description: read rom data on game mode + async version + + Arguments: romp : rom offset + ramp : ram destination address + size : size (byte) + + Returns: None + *---------------------------------------------------------------------------*/ +void GCDi_ReadGameModeRomAsync( GCDSlot slot, u32 romp, void *ramp, s32 size ); + +/*---------------------------------------------------------------------------* + Name: GCDi_WriteGameModeRom + + Description: write rom data on game mode + sync version + + Arguments: romp : rom offset + ramp : ram destination address + size : size (byte) + + Returns: None + *---------------------------------------------------------------------------*/ +void GCDi_WriteGameModeRom( GCDSlot slot, u32 romp, void *ramp, s32 size ); + +/*---------------------------------------------------------------------------* + Name: GCDi_WriteGameModeRomAsync + + Description: write rom data on game mode + async version + + Arguments: romp : rom offset + ramp : ram destination address + size : size (byte) + + Returns: None + *---------------------------------------------------------------------------*/ +void GCDi_WriteGameModeRomAsync( GCDSlot slot, u32 romp, void *ramp, s32 size ); + +/*---------------------------------------------------------------------------* + Name: GCDi_Enable + + Description: Enable game card master control + + Arguments: None + + Returns: None + *---------------------------------------------------------------------------*/ +void GCDi_Enable( GCDSlot slot ); + +/*---------------------------------------------------------------------------* + Name: GCDi_Disable + + Description: disable game card master control + + Arguments: None + + Returns: None + *---------------------------------------------------------------------------*/ +void GCDi_Disable( GCDSlot slot ); + +/*---------------------------------------------------------------------------* + Name: GCD_SetPrimarySlot + + Description: set primary game card slot + + Arguments: primary slot + + Returns: None + *---------------------------------------------------------------------------*/ +void GCD_SetPrimarySlot( u8 slot ); + +/*---------------------------------------------------------------------------* + Name: GCD_GetPrimarySlot + + Description: get primary game card slot + + Arguments: None + + Returns: primary slot + *---------------------------------------------------------------------------*/ +u8 GCD_GetPrimarySlot(void ); + +/*---------------------------------------------------------------------------* + Name: GCD_Reset + + Description: reset game card + + Arguments: None + + Returns: None + *---------------------------------------------------------------------------*/ +void GCD_Reset( GCDSlot slot, u32 chat_cycles ); + +/*---------------------------------------------------------------------------* + Name: GCD_Reset + + Description: reset game card + + Arguments: None + + Returns: None + *---------------------------------------------------------------------------*/ +void GCD_ResetAll( u32 chat_cycles ); + +/*---------------------------------------------------------------------------* + Name: GCDi_SelectRom + + Description: select game card spi + + Arguments: None + + Returns: None + *---------------------------------------------------------------------------*/ +void GCDi_SelectRom( GCDSlot slot ); + +/*---------------------------------------------------------------------------* + Name: GCDi_SelectSpi + + Description: select game card spi + + Arguments: None + + Returns: None + *---------------------------------------------------------------------------*/ +void GCDi_SelectSpi( GCDSlot slot ); + +/*---------------------------------------------------------------------------* + Name: GCDi_SetDmaNo + + Description: set card dma number + + Arguments: dmaNo : dma channel number + + Returns: None + *---------------------------------------------------------------------------*/ +void GCDi_SetDmaNo( GCDSlot slot, u32 dmaNo ); + +/*---------------------------------------------------------------------------* + Name: GCDi_GetDmaNo + + Description: get card dma number + + Arguments: None + + Returns: dmaNo : dma channel number + *---------------------------------------------------------------------------*/ +u32 GCDi_GetDmaNo( GCDSlot slot ); + +/*---------------------------------------------------------------------------* + Name: GCDi_InterruptHandler + + Description: interrupt handler + + Arguments: None + + Returns: None + *---------------------------------------------------------------------------*/ +void GCDi_InterruptHandlerPRIME( void ); +void GCDi_InterruptHandlerSECOND( void ); +void GCDi_InterruptHandlerCommon( GCDSlot slot ); + +//================================================================================ +// WAIT/STOP +//================================================================================ +/*---------------------------------------------------------------------------* + Name: GCDi_IsBusy + + Description: check whether game card is busy or not + + Arguments: None + + Returns: TRUE if game card is busy, FALSE if not + *---------------------------------------------------------------------------*/ +BOOL GCDi_IsBusy( GCDSlot slot ); + +/*---------------------------------------------------------------------------* + Name: GCDi_IsDataReady + + Description: check whether data is ready or not + + Arguments: None + + Returns: TRUE if game card is busy, FALSE if not + *---------------------------------------------------------------------------*/ +BOOL GCDi_IsDataReady( GCDSlot slot ); + +/*---------------------------------------------------------------------------* + Name: GCDi_Stop + + Description: stop game card access + + Arguments: None + + Returns: None + *---------------------------------------------------------------------------*/ +void GCDi_Stop( GCDSlot slot ); + +/*---------------------------------------------------------------------------* + Name: GCDi_WaitCtrl + + Description: wait while game card is busy + + Arguments: None + + Returns: None + *---------------------------------------------------------------------------*/ +void GCDi_WaitCtrl( GCDSlot slot ); + +/*---------------------------------------------------------------------------* + Name: GCDi_WaitData + + Description: wait until data is ready + + Arguments: None + + Returns: None + *---------------------------------------------------------------------------*/ +void GCDi_WaitData( GCDSlot slot ); + +/*---------------------------------------------------------------------------* + Name: GCDi_WaitDma + + Description: wait for stopping game card DMA + + Arguments: dmaNo : DMA channel No. + + Returns: None + *---------------------------------------------------------------------------*/ +void GCDi_WaitDma( GCDSlot slot, u32 dmaNo ); + +/*---------------------------------------------------------------------------* + Name: GCDi_WaitInterrupt + + Description: wait for game card interrupt + + Arguments: None + + Returns: None + *---------------------------------------------------------------------------*/ +void GCDi_WaitInterrupt( GCDSlot slot ); + + +// internal + +BOOL GCDi_IsSecureInitialized( GCDSlot slot ); +BOOL GCDi_IsCtrApp( GCDSlot slot ); +BOOL GCDi_IsDsApp( GCDSlot slot ); + +u32 GCDi_ReadNormalModeID( GCDSlot slot ); +u32 GCDi_ReadSecureModeID( GCDSlot slot ); +u32 GCDi_ReadGameModeID( GCDSlot slot ); + +u32 GCDi_ReadRomIDCore( GCDSlot slot, GCDRomCtrls *ctrls ); +void GCDi_ReadRomCore( GCDSlot slot, void *ramp, s32 size, GCDRomCtrls *ctrls ); +BOOL GCDi_ReadRomCommonPreCore( GCDSlot slot, u32 romp, void *ram, s32 size ); +void GCDi_WriteRomCore( GCDSlot slot, void *ramp, s32 size, GCDRomCtrls *ctrls ); + +void GCDi_ReadNormalModeRomCore( GCDSlot slot, u32 romp, void *ramp, s32 size, GCDRomCtrls *ctrls ); + +void GCDi_InitSecureParam( GCDSlot slot, BOOL twl_ex ); +void GCDi_InitPngIntf( GCDSlot slot ); +void GCDi_SetInitCardOpBlowfish( void (*p)( void ) ); +void GCDi_SetDecryptObjectFilep( void (*p)( void ) ); +void GCDi_SetSetPngIntf( void (*p)( u32 pnA_l, u8 pnA_h, u32 pnB_l, u8 pnB_h ) ); +void GCDi_SetReadSecureModeIDCorep( u32 (p)( GCDRomCtrls *ctrls ) ); +void GCDi_SetReadSecureModeRomCorep( void (p)( u32 romp, void *ramp, s32 size, GCDRomCtrls *ctrls ) ); +void GCDi_SetGetOneShotSizeFromCtrlp( s32 (p)( u32 ctrl ) ); + +void GCDi_SetSendOnlyCardOpCorep( void (*p)( GCDRomCtrls *ctrls ) ); +void GCDi_ChangeIntoSecureMode( GCDSlot slot ); +void GCDi_ChangeIntoSecure2Mode( GCDSlot slot ); +void GCDi_SendPngON( GCDSlot slot ); +void GCDi_SendPngOFF( GCDSlot slot ); +void GCDi_ChangeIntoGameMode( GCDSlot slot ); +void GCDi_ReadCardSegmentAsync4Secure( GCDSlot slot, BOOL twl_ex ); + +void GCDi_InitCardOpBlowfish( GCDSlot slot ); +void GCDi_InitCardOpBlowfishDS( GCDSlot slot ); +void GCDi_DecryptObjectFile( GCDSlot slot ); +void GCDi_DecryptObjectFileDS( GCDSlot slot ); + +void GCD_SetInterrupt( GCDSlot slot, u32 romp, void *ramp, s32 size, GCDWork *wp ); + +void* GCDi_GetRomHeaderAddr( GCDSlot slot ); + + +extern u32 GCDi_HeaderBuf[2][ GCD_ROM_HEADER_SIZE/sizeof(u32) ]; +extern u32 GCDi_SecureAreaBuf[2][ GCD_SECURE_AREA_SIZE/sizeof(u32) ]; +extern u32 GCDi_Secure2AreaBuf[2][ GCD_SECURE_AREA_SIZE/sizeof(u32) ]; + +extern GCDSharedWork GCDi_SharedWork[2]; +extern GCDWork GCDi_Work[2]; + +// e[u +extern const BLOWFISH_CTX GCDi_BlowfishInitTableDS; +extern const BLOWFISH_CTX GCDi_BlowfishInitTableGCDFIRM; + +#ifdef __cplusplus +} /* extern "C" */ + +#endif + +/* FIRM_GCD_GCD_H_ */ +#endif diff --git a/include/firm/gcd/gcd_misc.h b/include/firm/gcd/gcd_misc.h new file mode 100644 index 00000000..cf136ea3 --- /dev/null +++ b/include/firm/gcd/gcd_misc.h @@ -0,0 +1,468 @@ +/*---------------------------------------------------------------------------* + Project: TwlFirm - GCD - include + File: ngcd.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. + + $Log: $ + $NoKeywords: $ + *---------------------------------------------------------------------------*/ + +#ifndef FIRM_GCD_GCD_MISC_H_ +#define FIRM_GCD_GCD_MISC_H_ + +#include +#include "./gcd.h" + + +#ifdef __cplusplus +extern "C" { +#endif + + +typedef enum +{ + GCD_PAGE_0 = 0x0UL << REG_MI_MCCNT1_PC_SHIFT, + GCD_PAGE_1 = 0x1UL << REG_MI_MCCNT1_PC_SHIFT, + GCD_PAGE_2 = 0x2UL << REG_MI_MCCNT1_PC_SHIFT, + GCD_PAGE_4 = 0x3UL << REG_MI_MCCNT1_PC_SHIFT, + GCD_PAGE_8 = 0x4UL << REG_MI_MCCNT1_PC_SHIFT, + GCD_PAGE_16 = 0x5UL << REG_MI_MCCNT1_PC_SHIFT, + GCD_PAGE_32 = 0x6UL << REG_MI_MCCNT1_PC_SHIFT, + GCD_PAGE_STAT = 0x7UL << REG_MI_MCCNT1_PC_SHIFT +} +GCDPageCount; + +typedef enum +{ + GCD_CKT_150NS = 0x0UL << REG_MI_MCCNT1_CT_SHIFT, + GCD_CKT_240NS = 0x1UL << REG_MI_MCCNT1_CT_SHIFT +} +GCDClockType; + +typedef enum +{ + GCD_RW_READ = 0x0UL << REG_MI_MCCNT1_WR_SHIFT, + GCD_RW_WRITE = 0x1UL << REG_MI_MCCNT1_WR_SHIFT +} +GCDRw; + +typedef enum +{ + GCD_RESET_LO = 0x0UL << REG_MI_MCCNT1_RESB_SHIFT, + GCD_RESET_HI = 0x1UL << REG_MI_MCCNT1_RESB_SHIFT +} +GCDReset; + +typedef enum +{ + GCD_LTCK_DISABLE = 0x0UL << REG_MI_MCCNT1_TRM_SHIFT, + GCD_LTCK_ENABLE = 0x1UL << REG_MI_MCCNT1_TRM_SHIFT +} +GCDLtClkEnable; + +typedef struct +{ + u32 ctrl; + u8 master; + u8 spi; +} +NGCDCtrlRegs; + + +// PXIł̒ʐMvgR֘A` +#define GCD_PXI_COMMAND_MASK 0x0000003f // Jn[h̃R}h +#define GCD_PXI_COMMAND_SHIFT 0 +#define GCD_PXI_COMMAND_SIZE 6 +#define GCD_PXI_COMMAND_PARAM_MASK 0x03ffffc0 // Jn[h̃p[^ +#define GCD_PXI_COMMAND_PARAM_SHIFT 6 +#define GCD_PXI_COMMAND_PARAM_SIZE 20 + +typedef union +{ + struct + { + u32 cmd:GCD_PXI_COMMAND_SIZE; + u32 param:GCD_PXI_COMMAND_PARAM_SIZE-1; + u32 slot:1; + } + e; + u32 raw; +} +GCDPxiCmd; + +// PXIoRŔs閽 +#define GCD_PXI_COMMAND_RESET 0x01 +#define GCD_PXI_COMMAND_LOADED 0x02 + + +/*---------------------------------------------------------------------------* + Name: GCD_Init + + Description: initialize for game card access + + Arguments: None + + Returns: None + *---------------------------------------------------------------------------*/ +void GCD_Init( void ); + +/*---------------------------------------------------------------------------* + Name: GCDi_Init + + Description: initialize for game card access + + Arguments: None + + Returns: None + *---------------------------------------------------------------------------*/ +void GCDi_Init( BOOL reset ); + +/*---------------------------------------------------------------------------* + Name: GCD_ReadRomID + + Description: read rom ID + sync version + + Arguments: None + + Returns: rom ID + *---------------------------------------------------------------------------*/ +u32 GCD_ReadRomID( GCDSlot slot ); + +/*---------------------------------------------------------------------------* + Name: GCD_ReadRom + + Description: read rom data + sync version + + Arguments: romp : rom offset + ramp : ram destination address + size : size (byte) + + Returns: None + *---------------------------------------------------------------------------*/ +void GCD_ReadRom( GCDSlot slot, u32 romp, void *ramp, s32 size ); + +/*---------------------------------------------------------------------------* + Name: GCD_ReadRomAsync + + Description: read rom data + async version + + Arguments: romp : rom offset + ramp : ram destination address + size : size (byte) + + Returns: None + *---------------------------------------------------------------------------*/ +void GCD_ReadRomAsync( GCDSlot slot, u32 romp, void *ramp, s32 size ); + +/*---------------------------------------------------------------------------* + Name: GCD_ReadNormalModeRom + + Description: read rom data on normal mode + sync version + + Arguments: romp : rom offset + ramp : ram destination address + size : size (byte) + + Returns: None + *---------------------------------------------------------------------------*/ +void GCD_ReadNormalModeRom( GCDSlot slot, u32 romp, void *ramp, s32 size ); + +/*---------------------------------------------------------------------------* + Name: GCD_ReadGameModeRom + + Description: read rom data on game mode + sync version + + Arguments: romp : rom offset + ramp : ram destination address + size : size (byte) + + Returns: None + *---------------------------------------------------------------------------*/ +void GCD_ReadGameModeRom( GCDSlot slot, u32 romp, void *ramp, s32 size ); + +/*---------------------------------------------------------------------------* + Name: GCD_ReadRomPreCore + + Description: read rom data + sync version + + Arguments: romp : rom offset + ramp : ram destination address + size : size (byte) + + Returns: None + *---------------------------------------------------------------------------*/ +BOOL GCD_ReadRomPreCore( GCDSlot slot, u32 romp, void *ramp, s32 size ); + +/*---------------------------------------------------------------------------* + Name: GCD_ReadGameModeRomAsync + + Description: read rom data on game mode + async version + + Arguments: romp : rom offset + ramp : ram destination address + size : size (byte) + + Returns: None + *---------------------------------------------------------------------------*/ +void GCD_ReadGameModeRomAsync( GCDSlot slot, u32 romp, void *ramp, s32 size ); + +/*---------------------------------------------------------------------------* + Name: GCD_WriteGameModeRom + + Description: write rom data on game mode + sync version + + Arguments: romp : rom offset + ramp : ram destination address + size : size (byte) + + Returns: None + *---------------------------------------------------------------------------*/ +void GCD_WriteGameModeRom( GCDSlot slot, u32 romp, void *ramp, s32 size ); + +/*---------------------------------------------------------------------------* + Name: GCD_WriteGameModeRomAsync + + Description: write rom data on game mode + async version + + Arguments: romp : rom offset + ramp : ram destination address + size : size (byte) + + Returns: None + *---------------------------------------------------------------------------*/ +void GCD_WriteGameModeRomAsync( GCDSlot slot, u32 romp, void *ramp, s32 size ); + +/*---------------------------------------------------------------------------* + Name: GCDi_Enable + + Description: Enable game card master control + + Arguments: None + + Returns: None + *---------------------------------------------------------------------------*/ +void GCDi_Enable( GCDSlot slot ); + +/*---------------------------------------------------------------------------* + Name: GCDi_Disable + + Description: disable game card master control + + Arguments: None + + Returns: None + *---------------------------------------------------------------------------*/ +void GCDi_Disable( GCDSlot slot ); + +//================================================================================ +// WAIT/STOP +//================================================================================ +/*---------------------------------------------------------------------------* + Name: GCD_IsExisting + + Description: get whether cartridge exists + + Arguments: None + + Returns: TRUE if game card is busy, FALSE if not + *---------------------------------------------------------------------------*/ +static inline BOOL GCD_IsExisting( GCDSlot slot ) +{ + s32 ofs = (GCD_GetPrimarySlot() ^ slot) * 4; + s32 r = ~reg_MI_MC_DET & (REG_MI_MC_DET_DET1_MASK << ofs); + return r >> (REG_MI_MC_DET_DET1_SHIFT + ofs); +} + +/*---------------------------------------------------------------------------* + Name: GCD_SetDetectMode + + Description: + + Arguments: None + + Returns: None + *---------------------------------------------------------------------------*/ +static inline void GCD_SetDetectMode( GCDSlot slot, u32 mode ) +{ + s32 ofs = (GCD_GetPrimarySlot() ^ slot) * 4; + s32 others = reg_MI_MC_DET & ~(REG_MI_MC_DET_MODE1_MASK << ofs); + reg_MI_MC_DET = (u8)((mode << (REG_MI_MC_DET_MODE1_SHIFT + ofs)) | others); +} + +/*---------------------------------------------------------------------------* + Name: GCD_GetDetectMode + + Description: + + Arguments: None + + Returns: None + *---------------------------------------------------------------------------*/ +static inline u8 GCD_GetDetectMode( GCDSlot slot ) +{ + s32 ofs = (GCD_GetPrimarySlot() ^ slot) * 4; + return (u8)((reg_MI_MC_DET & (REG_MI_MC_DET_MODE1_MASK << ofs)) + >> (REG_MI_MC_DET_MODE1_SHIFT + ofs)); +} + +/*---------------------------------------------------------------------------* + Name: GCD_SetChatCounter + + Description: + + Arguments: None + + Returns: None + *---------------------------------------------------------------------------*/ +static inline void GCD_SetChatCounter( u16 value ) +{ + reg_MI_MC_CHT = value; +} + +/*---------------------------------------------------------------------------* + Name: GCD_IsBusy + + Description: check whether game card is busy or not + + Arguments: None + + Returns: TRUE if game card is busy, FALSE if not + *---------------------------------------------------------------------------*/ +BOOL GCD_IsBusy( GCDSlot slot ); + +/*---------------------------------------------------------------------------* + Name: GCD_IsDataReady + + Description: check whether data is ready or not + + Arguments: None + + Returns: TRUE if game card is busy, FALSE if not + *---------------------------------------------------------------------------*/ +BOOL GCD_IsDataReady( GCDSlot slot ); + +/*---------------------------------------------------------------------------* + Name: GCD_Stop + + Description: stop game card access + + Arguments: None + + Returns: None + *---------------------------------------------------------------------------*/ +void GCD_Stop( GCDSlot slot ); + +/*---------------------------------------------------------------------------* + Name: GCD_WaitRomAsync + + Description: wait for game card async access + + Arguments: None + + Returns: None + *---------------------------------------------------------------------------*/ +void GCD_WaitRomAsync( GCDSlot slot ); + +/*---------------------------------------------------------------------------* + Name: GCDi_SelectRegAddr + + Description: + + Arguments: None + + Returns: None + *---------------------------------------------------------------------------*/ +static inline void* GCDi_SelectRegAddr( GCDSlot slot, u32 base ) +{ + u32 addr = base; + + if ( slot == GCD_SECONDARY_SLOT ) + { + addr += REG_MCCNT0_B_ADDR - REG_MCCNT0_ADDR; + } + + return (void*)addr; +} + +/*---------------------------------------------------------------------------* + Name: GCDi_SelectIrqMask + + Description: + + Arguments: None + + Returns: None + *---------------------------------------------------------------------------*/ +static inline u32 GCDi_SelectIrqMask( GCDSlot slot, u32 base_mask ) +{ + u32 mask = base_mask; + + if ( slot == GCD_SECONDARY_SLOT ) + { + switch ( mask ) + { + case OS_IE_CARD_DATA: + mask = OS_IE_CARD_B_DATA; + break; + case OS_IE_CARD_IREQ: + mask = OS_IE_CARD_B_IREQ; + break; + case OS_IE_CARD_DET: + mask = OS_IE_CARD_B_DET; + break; + } + } + + return mask; +} + + +// internal + +u32 GCD_ReadNormalModeID( GCDSlot slot ); +u32 GCD_ReadSecureModeID( GCDSlot slot ); +u32 GCD_ReadGameModeID( GCDSlot slot ); + +void GCDi_SetOp( GCDSlot slot, GCDCmd64* op ); +void GCDi_SetCtrl( GCDSlot slot, GCDCtrlRegs* regs ); +void GCDi_GenCtrl( GCDCtrlRegs* regs, + GCDRw rw, + GCDPageCount pcount, + GCDClockType ckt, u32 lt1, u32 lt2, + BOOL cpn, BOOL dpn, BOOL csc, BOOL dsc ); +s32 GCDi_GetOneShotSizeFromCtrl( u32 ctrl ); +void GCD_SendOnlyCardOpCore( GCDSlot slot, GCDRomCtrls *ctrls ); +u32 GCDi_ReadRomIDCore( GCDSlot slot, GCDRomCtrls *ctrls ); +void GCD_ReadRomCore( GCDSlot slot, u32 romp, void *ramp, s32 size, GCDRomCtrls *ctrls ); +void GCD_WaitRomAsyncCore( GCDSlot slot ); + +void GCDi_WaitCtrl( GCDSlot slot ); +void GCDi_WaitData( GCDSlot slot ); +void GCDi_WaitDma( GCDSlot slot, u32 dmaNo ); +void GCDi_WaitInterrupt( GCDSlot slot ); + +void GCDi_SendtoPxi(u32 data); + +#ifdef __cplusplus +} /* extern "C" */ + +#endif + +/* FIRM_GCD_GCD_MISC_H_ */ +#endif diff --git a/include/firm/hw/ARM7/mmap_firm.h b/include/firm/hw/ARM7/mmap_firm.h new file mode 100644 index 00000000..dfec8855 --- /dev/null +++ b/include/firm/hw/ARM7/mmap_firm.h @@ -0,0 +1,44 @@ +/*---------------------------------------------------------------------------* + Project: TwlFirm - HW - include + File: mmap_firm.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. + + $Log: $ + $NoKeywords: $ + *---------------------------------------------------------------------------*/ +#ifndef FIRM_HW_MMAP_FIRM_H_ +#define FIRM_HW_MMAP_FIRM_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +//------------------------------------- NORFIRM +#define HW_NORFIRM HW_WRAM +#define HW_NORFIRM_END (HW_NORFIRM + HW_NORFIRM_SIZE) +#define HW_NORFIRM_SIZE (HW_WRAM_0_SIZE + HW_WRAM_1_SIZE + HW_WRAM_A_SIZE_MAX + HW_WRAM_B_SIZE_MAX) + +//------------------------------------- NORFIRM_WRAM_ABC +#define HW_NORFIRM_WRAM_A_MAP_END (HW_WRAM_AREA_END - HW_PRV_WRAM_SIZE) +#define HW_NORFIRM_WRAM_B_MAP_END HW_NORFIRM_WRAM_A_MAP_END +#define HW_NORFIRM_WRAM_C_MAP_END HW_NORFIRM_WRAM_A_MAP_END + +//------------------------------------- HW_NORFIRM_FROM_BROM_BUF +#define HW_NORFIRM_FROM_BROM_BUF (HW_NORFIRM_FROM_BROM_BUF_END - HW_NORFIRM_FROM_BROM_BUF_SIZE) +#define HW_NORFIRM_FROM_BROM_BUF_END (HW_WRAM_AREA_END - 0x1000) // END - 4KB +#define HW_NORFIRM_FROM_BROM_BUF_SIZE 0x3000 // 12KB + + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +/* FIRM_HW_MMAP_FIRM_H_ */ +#endif diff --git a/include/firm/hw/ARM9/mmap_firm.h b/include/firm/hw/ARM9/mmap_firm.h new file mode 100644 index 00000000..cecda941 --- /dev/null +++ b/include/firm/hw/ARM9/mmap_firm.h @@ -0,0 +1,44 @@ +/*---------------------------------------------------------------------------* + Project: TwlFirm - HW - include + File: mmap_firm.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. + + $Log: $ + $NoKeywords: $ + *---------------------------------------------------------------------------*/ +#ifndef FIRM_HW_MMAP_FIRM_H_ +#define FIRM_HW_MMAP_FIRM_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +//------------------------------------- NORFIRM +#define HW_NORFIRM HW_WRAM_EX +#define HW_NORFIRM_END (HW_NORFIRM + HW_NORFIRM_SIZE) +#define HW_NORFIRM_SIZE HW_WRAM_C_SIZE_MAX + +//------------------------------------- NORFIRM_WRAM_ABC +#define HW_NORFIRM_WRAM_A_MAP_END HW_WRAM_AREA_END +#define HW_NORFIRM_WRAM_B_MAP_END HW_NORFIRM_WRAM_A_MAP_END +#define HW_NORFIRM_WRAM_C_MAP_END HW_NORFIRM_WRAM_A_MAP_END + +//------------------------------------- HW_NORFIRM_FROM_BROM_BUF +#define HW_NORFIRM_FROM_BROM_BUF (HW_NORFIRM_FROM_BROM_BUF_END - HW_NORFIRM_FROM_BROM_BUF_SIZE) +#define HW_NORFIRM_FROM_BROM_BUF_END (HW_ITCM_END - 0x1000) // END - 4KB +#define HW_NORFIRM_FROM_BROM_BUF_SIZE 0x3000 // 12KB + + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +/* FIRM_HW_MMAP_FIRM_H_ */ +#endif diff --git a/include/firm/memorymap.h b/include/firm/memorymap.h new file mode 100644 index 00000000..a6150eeb --- /dev/null +++ b/include/firm/memorymap.h @@ -0,0 +1,28 @@ +/*---------------------------------------------------------------------------* + Project: TwlFirm - include - HW + File: memorymap.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. + + $Log: $ + $NoKeywords: $ + *---------------------------------------------------------------------------*/ +#ifndef FIRM_MEMORYMAP_H_ +#define FIRM_MEMORYMAP_H_ + +#include + +#ifdef SDK_ARM9 +#include +#else //SDK_ARM7 +#include +#endif + +/* FIRM_MEMORYMAP_H_ */ +#endif diff --git a/include/firm/mi.h b/include/firm/mi.h new file mode 100644 index 00000000..e644867d --- /dev/null +++ b/include/firm/mi.h @@ -0,0 +1,25 @@ +/*---------------------------------------------------------------------------* + Project: TwlFirm - include - MI + File: mi.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. + + $Log: $ + $NoKeywords: $ + *---------------------------------------------------------------------------*/ + +#ifndef FIRM_MI_H_ +#define FIRM_MI_H_ + +#include + +#include + +/* FIRM_MI_H_ */ +#endif diff --git a/include/firm/mi/mainMemory.h b/include/firm/mi/mainMemory.h new file mode 100644 index 00000000..29b47e62 --- /dev/null +++ b/include/firm/mi/mainMemory.h @@ -0,0 +1,79 @@ +/*---------------------------------------------------------------------------* + Project: TwlFirm - include - MI + File: mainMemory.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. + + $Log: $ + $NoKeywords: $ + *---------------------------------------------------------------------------*/ + +#ifndef FIRM_MI_MAINMEMORY_H_ +#define FIRM_MI_MAINMEMORY_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +//---------------------------------------------------------------------- +// C CRR}h +//---------------------------------------------------------------------- + +// for DS-PSRAM + +// CR0 +#define MMEM_DCR0_PARTIAL_REFRESH_NONE 0x0003 // p[VtbV +#define MMEM_DCR0_BURST_CONTINUOUS 0x001c // Ao[XgiQQSoCgj +#define MMEM_DCR0_BURST_MODE 0x0000 // o[Xg[h +#define MMEM_DCR0_PAGE_MODE 0x0020 // y[W[h +#define MMEM_DCR0_SB1 0xffc0 // PŒ + +// CR1 +#define MMEM_DCR1_1ST_R4_W3 0x0002 // Pq^v S^R +#define MMEM_DCR1_BURST_WRITE 0x0000 // o[XgCg +#define MMEM_DCR1_CLOCK_TRIGGER_UP 0x0100 // NbN +#define MMEM_DCR1_BURST_LINER 0x0200 // o[XgjAEV[PX +#define MMEM_DCR1_SB1 0xe430 // PŒ + +// CR2 +#define MMEM_DCR2_SB1 0x004003fe // PŒ +#define MMEM_DCR2_CLOCK_TRIGGER_UP 0x00000400 // NbN +#define MMEM_DCR2_BURST_WRITE 0x00000000 // o[XgCg +#define MMEM_DCR2_BURST_LINER 0x00001000 // o[XgjAEV[PX +#define MMEM_DCR2_1ST_R4_W3 0x00004000 // Pq^v S^R +#define MMEM_DCR2_BURST_MODE 0x00000000 // o[Xg[h +#define MMEM_DCR2_PAGE_MODE 0x00010000 // y[W[h +#define MMEM_DCR2_BURST_CONTINUOUS 0x000e0000 // Ao[XgiQQSoCgj +#define MMEM_DCR2_PARTIAL_REFRESH_NONE 0x00300000 // p[VtbV + +// for TWL-PSRAM + +#define MMEM_TCR0 0xFFFF +#define MMEM_TCR1 0xFFDF +#define MMEM_TCR2 0xFFEA + + +/*---------------------------------------------------------------------------* + Name: MIi_InitMainMemCR + + Description: change main memory into the burst mode + + Arguments: None + + Returns: None + *---------------------------------------------------------------------------*/ +void MIi_InitMainMemCR( void ); + + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +/* FIRM_MI_MAINMEMORY_H_ */ +#endif diff --git a/include/firm/misc.h b/include/firm/misc.h new file mode 100644 index 00000000..21ff27e0 --- /dev/null +++ b/include/firm/misc.h @@ -0,0 +1,32 @@ +/*---------------------------------------------------------------------------* + Project: TwlFirm - include - + File: misc.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. + + $Log: $ + $NoKeywords: $ + *---------------------------------------------------------------------------*/ +#ifndef FIRM_MISC_H_ +#define FIRM_MISC_H_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define offsetof(t, memb) ((size_t)(&(((t *)0)->memb))) + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +/* FIRM_MISC_H_ */ +#endif diff --git a/include/firm/nvram.h b/include/firm/nvram.h new file mode 100644 index 00000000..c9b8ffd4 --- /dev/null +++ b/include/firm/nvram.h @@ -0,0 +1,42 @@ +/*---------------------------------------------------------------------------* + Project: TwlFirm - NVRAM + File: nvram.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. + + $Log: $ + $NoKeywords: $ + *---------------------------------------------------------------------------*/ + +#ifndef FIRM_NVRAM_H_ +#define FIRM_NVRAM_H_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef SDK_ARM9 +#else // SDK_ARM7 + +/*---------------------------------------------------------------------------* + ֐` + *---------------------------------------------------------------------------*/ +void NVRAMi_Read(u32 address, void *buf, u32 size); +void NVRAMi_Write(u32 address, void *buf, u32 size); + +#endif + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +/* FIRM_NVRAM_H_ */ +#endif diff --git a/include/firm/os.h b/include/firm/os.h new file mode 100644 index 00000000..3d1afa41 --- /dev/null +++ b/include/firm/os.h @@ -0,0 +1,37 @@ +/*---------------------------------------------------------------------------* + Project: TwlFirm - OS + File: os.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. + + $Log: $ + $NoKeywords: $ + *---------------------------------------------------------------------------*/ + +#ifndef FIRM_OS_H_ +#define FIRM_OS_H_ + +#include + +#include +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +/* FIRM_OS_H_ */ +#endif diff --git a/include/firm/os/common/boot.h b/include/firm/os/common/boot.h new file mode 100644 index 00000000..6f8c59f6 --- /dev/null +++ b/include/firm/os/common/boot.h @@ -0,0 +1,74 @@ +/*---------------------------------------------------------------------------* + Project: TwlFirm - OS - include + File: boot.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. + + $Log: $ + $NoKeywords: $ + *---------------------------------------------------------------------------*/ +#ifndef FIRM_OS_BOOT_H_ +#define FIRM_OS_BOOT_H_ + +#include +#include +#include +#include //from_brom.hp +#include + +#include + +#ifdef __cplusplus +extern "C" { +#endif + + +/*---------------------------------------------------------------------------* + Name: OSi_Boot + + Description: boot firm + + Arguments: entry : entry point + + Returns: None + *---------------------------------------------------------------------------*/ +void OSi_Boot( void* entry, MIHeader_WramRegs* w, BOOL to_firm ); + +/*---------------------------------------------------------------------------* + Name: OSi_Finalize + + Description: finalize + + Arguments: None + + Returns: None + *---------------------------------------------------------------------------*/ +void OSi_Finalize(void); + +/*---------------------------------------------------------------------------* + Name: OSi_GetFromBromAddr + + Description: data address from bootrom to norfirm + + Arguments: None + + Returns: address + *---------------------------------------------------------------------------*/ +static inline OSFromBromBuf* OSi_GetFromBromAddr( void ) +{ + return (OSFromBromBuf*)HW_NORFIRM_FROM_BROM_BUF; +} + + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +/* FIRM_OS_BOOT_H_ */ +#endif diff --git a/include/firm/os/common/init.h b/include/firm/os/common/init.h new file mode 100644 index 00000000..b6bf0f87 --- /dev/null +++ b/include/firm/os/common/init.h @@ -0,0 +1,42 @@ +/*---------------------------------------------------------------------------* + Project: TwlFirm - OS - include + File: init.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. + + $Log: $ + $NoKeywords: $ + *---------------------------------------------------------------------------*/ +#ifndef FIRM_OS_INIT_H_ +#define FIRM_OS_INIT_H_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/*---------------------------------------------------------------------------* + Name: OS_InitNOR + + Description: initialize sdk os for norfirm + + Arguments: None + + Returns: None + *---------------------------------------------------------------------------*/ +void OS_InitNOR(void); + + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +/* FIRM_OS_INIT_H_ */ +#endif diff --git a/include/firm/os/common/systemCall.h b/include/firm/os/common/systemCall.h new file mode 100644 index 00000000..b81d50bd --- /dev/null +++ b/include/firm/os/common/systemCall.h @@ -0,0 +1,94 @@ +/*---------------------------------------------------------------------------* + Project: TwlFirm - OS - include + File: systemCall.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. + + $Log: $ + $NoKeywords: $ + *---------------------------------------------------------------------------*/ + +#ifndef FIRM_OS_SYSTEMCALL_H_ +#define FIRM_OS_SYSTEMCALL_H_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + + +#define SVC_ID_PREMASK 0x3f +#define SVC_ID_SHIFT 1 + +#define SVC_ID_SEMIHOST_ARM 0x12 +#define SVC_ID_SEMIHOST_THUMB 0xab + + +typedef enum +{ + // TWL + SVC_ID_INIT_SIGN_HEAP = 32, + SVC_ID_DEC_RSA = 33, + SVC_ID_DEC_SIGN = 34, + SVC_ID_DEC_SIGN_DER = 35, + SVC_ID_SHA1_INIT = 36, + SVC_ID_SHA1_UPDATE = 37, + SVC_ID_SHA1_FINAL = 38, + SVC_ID_CALC_SHA1 = 39, + SVC_ID_CMP_SHA1 = 40, + SVC_ID_RAND_SHA1 = 41, + SVC_ID_LZ8_DEV = 1, + SVC_ID_LZ16_DEV_IMG = 2, + + // reserve 0x2b for semihosting (0xab & 0x3f == 0x2b) + + // DS compatible + SVC_ID_SOFT_RESET = 0, + + SVC_ID_WAIT_BY_LOOP = 3, + SVC_ID_WAIT_INTR = 4, + SVC_ID_WAIT_VB_INTR = 5, + SVC_ID_HALT = 6, + SVC_ID_SLEEP = 7, + SVC_ID_SND_BIAS = 8, + SVC_ID_DIV = 9, + + SVC_ID_CPU_SET = 11, + SVC_ID_CPU_SET_FAST = 12, + SVC_ID_SQRT = 13, + SVC_ID_CRC16 = 14, + SVC_ID_IS_MEMEX = 15, + SVC_ID_UNPACKBITS_DEV = 16, + SVC_ID_LZ8 = 17, + // overlap semihosting ((0x123456>>16) & 0x3f == 0x12) + SVC_ID_LZ16_DEV = 18, + SVC_ID_HUFF_DEV = 19, + SVC_ID_RL8 = 20, + SVC_ID_RL16_DEV = 21, + SVC_ID_DF8 = 22, + + SVC_ID_DF16 = 24, + + SVC_ID_SND_SIN = 26, + SVC_ID_SND_PITCH = 27, + SVC_ID_SND_VOL = 28, + SVC_ID_DS_IPL2 = 29, + + SVC_ID_PAUSE_HI = 31 +} +OSSvcID; + + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +/* FIRM_OS_SYSTEMCALL_H_ */ +#endif diff --git a/include/firm/os/common/tick_brom.h b/include/firm/os/common/tick_brom.h new file mode 100644 index 00000000..c9b57557 --- /dev/null +++ b/include/firm/os/common/tick_brom.h @@ -0,0 +1,50 @@ +/*---------------------------------------------------------------------------* + Project: TwlBromSDK - OS - include + File: tick_addin.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. + + $Log: $ + $NoKeywords: $ + *---------------------------------------------------------------------------*/ + +#ifndef FRIM_OS_TICK_BROM_H_ +#define FRIM_OS_TICK_BROM_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +//---- sec to tick +#define OS_MicroSecondsToTicksBROM( usec ) ((OSTick)( ((OS_SYSTEM_CLOCK/1000) * (u64)(usec)) / 1024 / 1000 )) +#define OS_MicroSecondsToTicksBROM32( usec ) ((OSTick)( ((OS_SYSTEM_CLOCK/1000) * (u32)(usec)) / 1024 / 1000 )) + +#define OS_MilliSecondsToTicksBROM( msec ) ((OSTick)( ((OS_SYSTEM_CLOCK/1000) * (u64)(msec)) / 1024 )) +#define OS_MilliSecondsToTicksBROM32( msec ) ((OSTick)( ((OS_SYSTEM_CLOCK/1000) * (u32)(msec)) / 1024 )) + +#define OS_SecondsToTicksBROM( sec ) ((OSTick)( (OS_SYSTEM_CLOCK * (u64)(sec)) / 1024 )) +#define OS_SecondsToTicksBROM32( sec ) ((OSTick)( (OS_SYSTEM_CLOCK * (u32)(sec)) / 1024 )) + +//---- tick to sec +#define OS_TicksToMicroSecondsBROM( tick ) ( ((u64)(tick) * 1024 * 1000) / (OS_SYSTEM_CLOCK/1000) ) +#define OS_TicksToMicroSecondsBROM32( tick ) ( ((u32)(tick) * 1024 * 1000) / (OS_SYSTEM_CLOCK/1000) ) + +#define OS_TicksToMilliSecondsBROM( tick ) ( ((u64)(tick) * 1024) / (OS_SYSTEM_CLOCK/1000) ) +#define OS_TicksToMilliSecondsBROM32( tick ) ( ((u32)(tick) * 1024) / (OS_SYSTEM_CLOCK/1000) ) + +#define OS_TicksToSecondsBROM( tick ) ( ((u64)(tick) * 1024) / OS_SYSTEM_CLOCK ) +#define OS_TicksToSecondsBROM32( tick ) ( ((u32)(tick) * 1024) / OS_SYSTEM_CLOCK ) + + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +/* FRIM_OS_TICK_BROM_H_ */ +#endif diff --git a/include/firm/pm.h b/include/firm/pm.h new file mode 100644 index 00000000..b471de66 --- /dev/null +++ b/include/firm/pm.h @@ -0,0 +1,29 @@ +/*---------------------------------------------------------------------------* + Project: TwlFirm - include - PM + File: pm.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. + + $Log: $ + $NoKeywords: $ + *---------------------------------------------------------------------------*/ + +#ifndef FIRM_PM_H_ +#define FIRM_PM_H_ + +#include + +#ifdef SDK_ARM7 +#include <../build/libraries/spi/ARM7/pm/include/pm_pmic.h> +#include <../build/libraries/spi/ARM7/pm/include/pm_pmic_ex.h> +#endif // SDK_ARM7 + + +/* FIRM_PM_H_ */ +#endif diff --git a/include/firm/specfiles/ARM7-BB-GCDFIRM.lcf.template b/include/firm/specfiles/ARM7-BB-GCDFIRM.lcf.template new file mode 100644 index 00000000..2b60c555 --- /dev/null +++ b/include/firm/specfiles/ARM7-BB-GCDFIRM.lcf.template @@ -0,0 +1,494 @@ +#--------------------------------------------------------------------------- +# Project: TwlFirm - tools - makelcf +# File: ARM7-BB-NORFIRM.lcf.template +# +# 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. +# +# $Log: $ +# $NoKeywords: $ +#--------------------------------------------------------------------------- +MEMORY +{ + (RWX) : ORIGIN = , LENGTH = 0x0 # > + + (RWX) : ORIGIN = , LENGTH = 0x0 > + +# binary.AUTOLOAD_INFO (RWX) : ORIGIN = 0, LENGTH = 0x0 > + + (RW) : ORIGIN = AFTER(), LENGTH = 0x0 > + (RW) : ORIGIN = AFTER(), LENGTH = 0x0 > + + (RWXO): ORIGIN = , LENGTH = 0x0 > + + arena.MAIN (RW) : ORIGIN = AFTER(,), LENGTH = 0x0 + check.WORKRAM (RWX) : ORIGIN = , LENGTH = 0x48000 > workram.check +} + +KEEP_SECTION +{ + .ctor +} + +SECTIONS +{ + ############################ STATIC ################################# + .: + { + ALIGNALL(4); . = ALIGN(4); # Fit to cache line + + + + # + # TEXT BLOCK: READ ONLY + # + SDK_STATIC_START =.; + SDK_STATIC_TEXT_START =.; + #:::::::::: text/rodata + OBJECT(_start,*) + crt0.o (.text) + + + + + + + . = ALIGN(4); + * (.exception) + . = ALIGN(4); + SDK_STATIC_ETABLE_START =.; + EXCEPTION + SDK_STATIC_ETABLE_END =.; + . = ALIGN(4); + + + + + + + . = ALIGN(4); + + + + + + + . = ALIGN(4); + + SDK_STATIC_SINIT_START =.; + #:::::::::: ctor + + + + + + + WRITEW 0; + #:::::::::: ctor + SDK_STATIC_SINIT_END =.; + + #:::::::::: text/rodata + . = ALIGN(4); + SDK_STATIC_TEXT_END =.; + + # + # DATA BLOCK: READ WRITE + # + SDK_STATIC_DATA_START =.; + #:::::::::: data + + + + + + + . = ALIGN(4); + + + + + + + . = ALIGN(4); + + + + + + + . = ALIGN(4); + #:::::::::: data + . = ALIGN(4); + SDK_STATIC_DATA_END =.; + SDK_STATIC_END =.; + + SDK_STATIC_TEXT_SIZE = SDK_STATIC_TEXT_END - SDK_STATIC_TEXT_START; + SDK_STATIC_DATA_SIZE = SDK_STATIC_DATA_END - SDK_STATIC_DATA_START; + SDK_STATIC_SIZE = SDK_STATIC_END - SDK_STATIC_START; + __sinit__ = SDK_STATIC_SINIT_START; # for static initializer + __exception_table_start__ = SDK_STATIC_ETABLE_START; # for exception table + __exception_table_end__ = SDK_STATIC_ETABLE_END; # for exception table + } > + + ..bss: + { + ALIGNALL(4); . = ALIGN(4); + + + + # + # BSS BLOCK + # + SDK_STATIC_BSS_START =.; + #:::::::::: bss + + + + + + + . = ALIGN(4); + + + + + + + . = ALIGN(4); + #:::::::::: bss + . = ALIGN(4); + SDK_STATIC_BSS_END = .; + SDK_STATIC_BSS_SIZE = SDK_STATIC_BSS_END - SDK_STATIC_BSS_START; + + } >> + + + ############################ AUTOLOADS ############################## + SDK_AUTOLOAD.MAIN.START = 0x02380000; + SDK_AUTOLOAD.MAIN.END = SDK_AUTOLOAD.MAIN.START; + SDK_AUTOLOAD.MAIN.BSS_END = SDK_AUTOLOAD.MAIN.START; + SDK_AUTOLOAD.MAIN.SIZE = 0; + SDK_AUTOLOAD.MAIN.BSS_SIZE = 0; + SDK_AUTOLOAD.WRAM.START = 0x037f8000; + SDK_AUTOLOAD.WRAM.END = SDK_AUTOLOAD.WRAM.START; + SDK_AUTOLOAD.WRAM.BSS_END = SDK_AUTOLOAD.WRAM.START; + SDK_AUTOLOAD.WRAM.SIZE = 0; + SDK_AUTOLOAD.WRAM.BSS_SIZE = 0; + SDK_AUTOLOAD_START = SDK_STATIC_END; + SDK_AUTOLOAD_SIZE = 0; + SDK_AUTOLOAD_NUMBER = ; + + + .: + { + ALIGNALL(4); . = ALIGN(4); + + + + # + # TEXT BLOCK: READ ONLY + # + SDK_AUTOLOAD__ID =; + SDK_AUTOLOAD..ID =; + SDK_AUTOLOAD..START =.; + SDK_AUTOLOAD..TEXT_START =.; + #:::::::::: text/rodata + + + + + + + . = ALIGN(4); + + + + + + + . = ALIGN(4); + #:::::::::: text/rodata + SDK_AUTOLOAD..TEXT_END =.; + + # + # DATA BLOCK: READ WRITE BLOCK + # + SDK_AUTOLOAD..DATA_START =.; + #:::::::::: data + + + + + + + . = ALIGN(4); + + + + + + + . = ALIGN(4); + + + + + + + . = ALIGN(4); + #:::::::::: data + SDK_AUTOLOAD..DATA_END =.; + SDK_AUTOLOAD..END =.; + + SDK_AUTOLOAD..TEXT_SIZE = SDK_AUTOLOAD..TEXT_END - SDK_AUTOLOAD..TEXT_START; + SDK_AUTOLOAD..DATA_SIZE = SDK_AUTOLOAD..DATA_END - SDK_AUTOLOAD..DATA_START; + SDK_AUTOLOAD..SIZE = SDK_AUTOLOAD..END - SDK_AUTOLOAD..START; + SDK_AUTOLOAD_SIZE = SDK_AUTOLOAD_SIZE + SDK_AUTOLOAD..SIZE; + + } > + + ..bss: + { + ALIGNALL(4); . = ALIGN(4); + + + + # + # BSS BLOCK + # + SDK_AUTOLOAD..BSS_START = .; + #:::::::::: bss + + + + + + + . = ALIGN(4); + + + + + + + . = ALIGN(4); + #:::::::::: bss + . = ALIGN(4); + SDK_AUTOLOAD..BSS_END = .; + + SDK_AUTOLOAD..BSS_SIZE = SDK_AUTOLOAD..BSS_END - SDK_AUTOLOAD..BSS_START; + + } >> + + + + SDK_AUTOLOAD_MAIN_START = SDK_AUTOLOAD.MAIN.START; + SDK_AUTOLOAD_MAIN_END = SDK_AUTOLOAD.MAIN.END; + SDK_AUTOLOAD_MAIN_BSS_END = SDK_AUTOLOAD.MAIN.BSS_END; + SDK_AUTOLOAD_MAIN_SIZE = SDK_AUTOLOAD.MAIN.SIZE; + SDK_AUTOLOAD_MAIN_BSS_SIZE = SDK_AUTOLOAD.MAIN.BSS_SIZE; + SDK_AUTOLOAD_WRAM_START = SDK_AUTOLOAD.WRAM.START; + SDK_AUTOLOAD_WRAM_END = SDK_AUTOLOAD.WRAM.END; + SDK_AUTOLOAD_WRAM_BSS_END = SDK_AUTOLOAD.WRAM.BSS_END; + SDK_AUTOLOAD_WRAM_SIZE = SDK_AUTOLOAD.WRAM.SIZE; + SDK_AUTOLOAD_WRAM_BSS_SIZE = SDK_AUTOLOAD.WRAM.BSS_SIZE; + + ############################ AUTOLOAD_INFO ########################## + .binary.AUTOLOAD_INFO: + { + SDK_AUTOLOAD_LIST = .; + + WRITEW ADDR(.); + WRITEW SDK_AUTOLOAD..SIZE; + WRITEW SDK_AUTOLOAD..BSS_SIZE; + + SDK_AUTOLOAD_LIST_END = .; + } >> # > binary.AUTOLOAD_INFO + +# SDK_AUTOLOAD_LIST = SDK_AUTOLOAD_START + SDK_AUTOLOAD_SIZE; +# SDK_AUTOLOAD_LIST_END = SDK_AUTOLOAD_START + SDK_AUTOLOAD_SIZE + SIZEOF(.binary.AUTOLOAD_INFO); + SDK_AUTOLOAD_SIZE = SDK_AUTOLOAD_SIZE + SIZEOF(.binary.AUTOLOAD_INFO); + + ############################ OVERLAYS ############################### + SDK_OVERLAY_NUMBER = ; + + + .: + { + ALIGNALL(4); . = ALIGN(4); + + + + # + # TEXT BLOCK: READ ONLY + # + SDK_OVERLAY__ID =; ### SEGMENT OVERLAY ID + SDK_OVERLAY..ID =; + SDK_OVERLAY..START =.; + SDK_OVERLAY..TEXT_START =.; + #:::::::::: text/rodata + + + + + + + . = ALIGN(4); + + + + + + + . = ALIGN(4); + + + + + + + . = ALIGN(4); + SDK_OVERLAY..SINIT_START =.; + #:::::::::: ctor + + + + + + + WRITEW 0; + #:::::::::: ctor + SDK_OVERLAY..SINIT_END =.; + + #:::::::::: text/rodata + . = ALIGN(4); + SDK_OVERLAY..TEXT_END =.; + + # + # DATA BLOCK: READ WRITE + # + SDK_OVERLAY..DATA_START =.; + #:::::::::: data + + + + + + + . = ALIGN(4); + + + + + + + . = ALIGN(4); + #:::::::::: data + . = ALIGN(4); + SDK_OVERLAY..DATA_END =.; + SDK_OVERLAY..END =.; + + SDK_OVERLAY..TEXT_SIZE = SDK_OVERLAY..TEXT_END - SDK_OVERLAY..TEXT_START; + SDK_OVERLAY..DATA_SIZE = SDK_OVERLAY..DATA_END - SDK_OVERLAY..DATA_START; + SDK_OVERLAY..SIZE = SDK_OVERLAY..END - SDK_OVERLAY..START; + + } > + + ..bss: + { + ALIGNALL(4); . = ALIGN(4); + + + + # + # BSS BLOCK + # + SDK_OVERLAY..BSS_START = .; + #:::::::::: bss + + + + + + + . = ALIGN(4); + + + + + + + . = ALIGN(4); + #:::::::::: bss + . = ALIGN(4); + SDK_OVERLAY..BSS_END = .; + + SDK_OVERLAY..BSS_SIZE = SDK_OVERLAY..BSS_END - SDK_OVERLAY..BSS_START; + + } >> + + + + + ############################ ARENA ################################## + .arena.MAIN: + { + . = ALIGN(4); + SDK_SECTION_ARENA_START =.; + } > arena.MAIN + + + ############################ OVERLAYDEFS ############################ + .: + { + ### module information + WRITEW ADDR(.); # load address + WRITEW _start; # entry address + WRITEW SDK_STATIC_SIZE + SDK_AUTOLOAD_SIZE; # size of module + WRITEW _start_AutoloadDoneCallback; # callback autoload done + + ### overlay filename + + WRITES (""); # Overlay + + + } > + + + ############################ OVERLAYTABLE ########################### + .: + { + + # Overlay + WRITEW ; # overlay ID + WRITEW ADDR(.); # load address + WRITEW SDK_OVERLAY..SIZE; # size of module + WRITEW SDK_OVERLAY..BSS_SIZE; # size of bss + WRITEW SDK_OVERLAY..SINIT_START; # start address of static init + WRITEW SDK_OVERLAY..SINIT_END; # end address of static init + WRITEW ; # ROM file ID + WRITEW 0; # Reserved + + + + } > + + + ############################ OTHERS ################################# + SDK_SUBPRIV_ARENA_LO = SDK_AUTOLOAD.MAIN.BSS_END; + SDK_WRAM_ARENA_LO = SDK_SECTION_ARENA_START; + SDK_IRQ_STACKSIZE = ; # allocated in WRAM + SDK_SYS_STACKSIZE = ; # allocated in WRAM + + # work ram size checker + SDK_SYS_STACKSIZE_SIGN = (SDK_SYS_STACKSIZE < 0x80000000) * 2 - 1; + .check.WORKRAM: + { + . = . + SDK_SECTION_ARENA_START - + SDK_IRQ_STACKSIZE + SDK_SYS_STACKSIZE * SDK_SYS_STACKSIZE_SIGN; + } > check.WORKRAM +} diff --git a/include/firm/specfiles/ARM7-BB-GCDFIRM.lsf b/include/firm/specfiles/ARM7-BB-GCDFIRM.lsf new file mode 100644 index 00000000..6c472e66 --- /dev/null +++ b/include/firm/specfiles/ARM7-BB-GCDFIRM.lsf @@ -0,0 +1,27 @@ +#---------------------------------------------------------------------------- +# Project: TwlFirm - include +# File: ARM7-BB-NORFIRM.lsf +# +# Copyright 2007 Nintendo. All rights reserved. +# +# These coded insructions, 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: $ +# $NoKeywords: $ +#---------------------------------------------------------------------------- +# +# TwlFirm LCF SPEC FILE +# + +Static $(TARGET_NAME) +{ + Address 0x037f8000 + Object $(OBJS_STATIC) + Library $(LLIBS) $(GLIBS) $(CW_LIBS) + Object * (.wram) + StackSize 1024 512 +} diff --git a/include/firm/specfiles/ARM7-BB-NORFIRM.lcf.template b/include/firm/specfiles/ARM7-BB-NORFIRM.lcf.template new file mode 100644 index 00000000..2b60c555 --- /dev/null +++ b/include/firm/specfiles/ARM7-BB-NORFIRM.lcf.template @@ -0,0 +1,494 @@ +#--------------------------------------------------------------------------- +# Project: TwlFirm - tools - makelcf +# File: ARM7-BB-NORFIRM.lcf.template +# +# 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. +# +# $Log: $ +# $NoKeywords: $ +#--------------------------------------------------------------------------- +MEMORY +{ + (RWX) : ORIGIN = , LENGTH = 0x0 # > + + (RWX) : ORIGIN = , LENGTH = 0x0 > + +# binary.AUTOLOAD_INFO (RWX) : ORIGIN = 0, LENGTH = 0x0 > + + (RW) : ORIGIN = AFTER(), LENGTH = 0x0 > + (RW) : ORIGIN = AFTER(), LENGTH = 0x0 > + + (RWXO): ORIGIN = , LENGTH = 0x0 > + + arena.MAIN (RW) : ORIGIN = AFTER(,), LENGTH = 0x0 + check.WORKRAM (RWX) : ORIGIN = , LENGTH = 0x48000 > workram.check +} + +KEEP_SECTION +{ + .ctor +} + +SECTIONS +{ + ############################ STATIC ################################# + .: + { + ALIGNALL(4); . = ALIGN(4); # Fit to cache line + + + + # + # TEXT BLOCK: READ ONLY + # + SDK_STATIC_START =.; + SDK_STATIC_TEXT_START =.; + #:::::::::: text/rodata + OBJECT(_start,*) + crt0.o (.text) + + + + + + + . = ALIGN(4); + * (.exception) + . = ALIGN(4); + SDK_STATIC_ETABLE_START =.; + EXCEPTION + SDK_STATIC_ETABLE_END =.; + . = ALIGN(4); + + + + + + + . = ALIGN(4); + + + + + + + . = ALIGN(4); + + SDK_STATIC_SINIT_START =.; + #:::::::::: ctor + + + + + + + WRITEW 0; + #:::::::::: ctor + SDK_STATIC_SINIT_END =.; + + #:::::::::: text/rodata + . = ALIGN(4); + SDK_STATIC_TEXT_END =.; + + # + # DATA BLOCK: READ WRITE + # + SDK_STATIC_DATA_START =.; + #:::::::::: data + + + + + + + . = ALIGN(4); + + + + + + + . = ALIGN(4); + + + + + + + . = ALIGN(4); + #:::::::::: data + . = ALIGN(4); + SDK_STATIC_DATA_END =.; + SDK_STATIC_END =.; + + SDK_STATIC_TEXT_SIZE = SDK_STATIC_TEXT_END - SDK_STATIC_TEXT_START; + SDK_STATIC_DATA_SIZE = SDK_STATIC_DATA_END - SDK_STATIC_DATA_START; + SDK_STATIC_SIZE = SDK_STATIC_END - SDK_STATIC_START; + __sinit__ = SDK_STATIC_SINIT_START; # for static initializer + __exception_table_start__ = SDK_STATIC_ETABLE_START; # for exception table + __exception_table_end__ = SDK_STATIC_ETABLE_END; # for exception table + } > + + ..bss: + { + ALIGNALL(4); . = ALIGN(4); + + + + # + # BSS BLOCK + # + SDK_STATIC_BSS_START =.; + #:::::::::: bss + + + + + + + . = ALIGN(4); + + + + + + + . = ALIGN(4); + #:::::::::: bss + . = ALIGN(4); + SDK_STATIC_BSS_END = .; + SDK_STATIC_BSS_SIZE = SDK_STATIC_BSS_END - SDK_STATIC_BSS_START; + + } >> + + + ############################ AUTOLOADS ############################## + SDK_AUTOLOAD.MAIN.START = 0x02380000; + SDK_AUTOLOAD.MAIN.END = SDK_AUTOLOAD.MAIN.START; + SDK_AUTOLOAD.MAIN.BSS_END = SDK_AUTOLOAD.MAIN.START; + SDK_AUTOLOAD.MAIN.SIZE = 0; + SDK_AUTOLOAD.MAIN.BSS_SIZE = 0; + SDK_AUTOLOAD.WRAM.START = 0x037f8000; + SDK_AUTOLOAD.WRAM.END = SDK_AUTOLOAD.WRAM.START; + SDK_AUTOLOAD.WRAM.BSS_END = SDK_AUTOLOAD.WRAM.START; + SDK_AUTOLOAD.WRAM.SIZE = 0; + SDK_AUTOLOAD.WRAM.BSS_SIZE = 0; + SDK_AUTOLOAD_START = SDK_STATIC_END; + SDK_AUTOLOAD_SIZE = 0; + SDK_AUTOLOAD_NUMBER = ; + + + .: + { + ALIGNALL(4); . = ALIGN(4); + + + + # + # TEXT BLOCK: READ ONLY + # + SDK_AUTOLOAD__ID =; + SDK_AUTOLOAD..ID =; + SDK_AUTOLOAD..START =.; + SDK_AUTOLOAD..TEXT_START =.; + #:::::::::: text/rodata + + + + + + + . = ALIGN(4); + + + + + + + . = ALIGN(4); + #:::::::::: text/rodata + SDK_AUTOLOAD..TEXT_END =.; + + # + # DATA BLOCK: READ WRITE BLOCK + # + SDK_AUTOLOAD..DATA_START =.; + #:::::::::: data + + + + + + + . = ALIGN(4); + + + + + + + . = ALIGN(4); + + + + + + + . = ALIGN(4); + #:::::::::: data + SDK_AUTOLOAD..DATA_END =.; + SDK_AUTOLOAD..END =.; + + SDK_AUTOLOAD..TEXT_SIZE = SDK_AUTOLOAD..TEXT_END - SDK_AUTOLOAD..TEXT_START; + SDK_AUTOLOAD..DATA_SIZE = SDK_AUTOLOAD..DATA_END - SDK_AUTOLOAD..DATA_START; + SDK_AUTOLOAD..SIZE = SDK_AUTOLOAD..END - SDK_AUTOLOAD..START; + SDK_AUTOLOAD_SIZE = SDK_AUTOLOAD_SIZE + SDK_AUTOLOAD..SIZE; + + } > + + ..bss: + { + ALIGNALL(4); . = ALIGN(4); + + + + # + # BSS BLOCK + # + SDK_AUTOLOAD..BSS_START = .; + #:::::::::: bss + + + + + + + . = ALIGN(4); + + + + + + + . = ALIGN(4); + #:::::::::: bss + . = ALIGN(4); + SDK_AUTOLOAD..BSS_END = .; + + SDK_AUTOLOAD..BSS_SIZE = SDK_AUTOLOAD..BSS_END - SDK_AUTOLOAD..BSS_START; + + } >> + + + + SDK_AUTOLOAD_MAIN_START = SDK_AUTOLOAD.MAIN.START; + SDK_AUTOLOAD_MAIN_END = SDK_AUTOLOAD.MAIN.END; + SDK_AUTOLOAD_MAIN_BSS_END = SDK_AUTOLOAD.MAIN.BSS_END; + SDK_AUTOLOAD_MAIN_SIZE = SDK_AUTOLOAD.MAIN.SIZE; + SDK_AUTOLOAD_MAIN_BSS_SIZE = SDK_AUTOLOAD.MAIN.BSS_SIZE; + SDK_AUTOLOAD_WRAM_START = SDK_AUTOLOAD.WRAM.START; + SDK_AUTOLOAD_WRAM_END = SDK_AUTOLOAD.WRAM.END; + SDK_AUTOLOAD_WRAM_BSS_END = SDK_AUTOLOAD.WRAM.BSS_END; + SDK_AUTOLOAD_WRAM_SIZE = SDK_AUTOLOAD.WRAM.SIZE; + SDK_AUTOLOAD_WRAM_BSS_SIZE = SDK_AUTOLOAD.WRAM.BSS_SIZE; + + ############################ AUTOLOAD_INFO ########################## + .binary.AUTOLOAD_INFO: + { + SDK_AUTOLOAD_LIST = .; + + WRITEW ADDR(.); + WRITEW SDK_AUTOLOAD..SIZE; + WRITEW SDK_AUTOLOAD..BSS_SIZE; + + SDK_AUTOLOAD_LIST_END = .; + } >> # > binary.AUTOLOAD_INFO + +# SDK_AUTOLOAD_LIST = SDK_AUTOLOAD_START + SDK_AUTOLOAD_SIZE; +# SDK_AUTOLOAD_LIST_END = SDK_AUTOLOAD_START + SDK_AUTOLOAD_SIZE + SIZEOF(.binary.AUTOLOAD_INFO); + SDK_AUTOLOAD_SIZE = SDK_AUTOLOAD_SIZE + SIZEOF(.binary.AUTOLOAD_INFO); + + ############################ OVERLAYS ############################### + SDK_OVERLAY_NUMBER = ; + + + .: + { + ALIGNALL(4); . = ALIGN(4); + + + + # + # TEXT BLOCK: READ ONLY + # + SDK_OVERLAY__ID =; ### SEGMENT OVERLAY ID + SDK_OVERLAY..ID =; + SDK_OVERLAY..START =.; + SDK_OVERLAY..TEXT_START =.; + #:::::::::: text/rodata + + + + + + + . = ALIGN(4); + + + + + + + . = ALIGN(4); + + + + + + + . = ALIGN(4); + SDK_OVERLAY..SINIT_START =.; + #:::::::::: ctor + + + + + + + WRITEW 0; + #:::::::::: ctor + SDK_OVERLAY..SINIT_END =.; + + #:::::::::: text/rodata + . = ALIGN(4); + SDK_OVERLAY..TEXT_END =.; + + # + # DATA BLOCK: READ WRITE + # + SDK_OVERLAY..DATA_START =.; + #:::::::::: data + + + + + + + . = ALIGN(4); + + + + + + + . = ALIGN(4); + #:::::::::: data + . = ALIGN(4); + SDK_OVERLAY..DATA_END =.; + SDK_OVERLAY..END =.; + + SDK_OVERLAY..TEXT_SIZE = SDK_OVERLAY..TEXT_END - SDK_OVERLAY..TEXT_START; + SDK_OVERLAY..DATA_SIZE = SDK_OVERLAY..DATA_END - SDK_OVERLAY..DATA_START; + SDK_OVERLAY..SIZE = SDK_OVERLAY..END - SDK_OVERLAY..START; + + } > + + ..bss: + { + ALIGNALL(4); . = ALIGN(4); + + + + # + # BSS BLOCK + # + SDK_OVERLAY..BSS_START = .; + #:::::::::: bss + + + + + + + . = ALIGN(4); + + + + + + + . = ALIGN(4); + #:::::::::: bss + . = ALIGN(4); + SDK_OVERLAY..BSS_END = .; + + SDK_OVERLAY..BSS_SIZE = SDK_OVERLAY..BSS_END - SDK_OVERLAY..BSS_START; + + } >> + + + + + ############################ ARENA ################################## + .arena.MAIN: + { + . = ALIGN(4); + SDK_SECTION_ARENA_START =.; + } > arena.MAIN + + + ############################ OVERLAYDEFS ############################ + .: + { + ### module information + WRITEW ADDR(.); # load address + WRITEW _start; # entry address + WRITEW SDK_STATIC_SIZE + SDK_AUTOLOAD_SIZE; # size of module + WRITEW _start_AutoloadDoneCallback; # callback autoload done + + ### overlay filename + + WRITES (""); # Overlay + + + } > + + + ############################ OVERLAYTABLE ########################### + .: + { + + # Overlay + WRITEW ; # overlay ID + WRITEW ADDR(.); # load address + WRITEW SDK_OVERLAY..SIZE; # size of module + WRITEW SDK_OVERLAY..BSS_SIZE; # size of bss + WRITEW SDK_OVERLAY..SINIT_START; # start address of static init + WRITEW SDK_OVERLAY..SINIT_END; # end address of static init + WRITEW ; # ROM file ID + WRITEW 0; # Reserved + + + + } > + + + ############################ OTHERS ################################# + SDK_SUBPRIV_ARENA_LO = SDK_AUTOLOAD.MAIN.BSS_END; + SDK_WRAM_ARENA_LO = SDK_SECTION_ARENA_START; + SDK_IRQ_STACKSIZE = ; # allocated in WRAM + SDK_SYS_STACKSIZE = ; # allocated in WRAM + + # work ram size checker + SDK_SYS_STACKSIZE_SIGN = (SDK_SYS_STACKSIZE < 0x80000000) * 2 - 1; + .check.WORKRAM: + { + . = . + SDK_SECTION_ARENA_START - + SDK_IRQ_STACKSIZE + SDK_SYS_STACKSIZE * SDK_SYS_STACKSIZE_SIGN; + } > check.WORKRAM +} diff --git a/include/firm/specfiles/ARM7-BB-NORFIRM.lsf b/include/firm/specfiles/ARM7-BB-NORFIRM.lsf new file mode 100644 index 00000000..6c472e66 --- /dev/null +++ b/include/firm/specfiles/ARM7-BB-NORFIRM.lsf @@ -0,0 +1,27 @@ +#---------------------------------------------------------------------------- +# Project: TwlFirm - include +# File: ARM7-BB-NORFIRM.lsf +# +# Copyright 2007 Nintendo. All rights reserved. +# +# These coded insructions, 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: $ +# $NoKeywords: $ +#---------------------------------------------------------------------------- +# +# TwlFirm LCF SPEC FILE +# + +Static $(TARGET_NAME) +{ + Address 0x037f8000 + Object $(OBJS_STATIC) + Library $(LLIBS) $(GLIBS) $(CW_LIBS) + Object * (.wram) + StackSize 1024 512 +} diff --git a/include/firm/specfiles/ARM7-TS-GCDFIRM.lcf.template b/include/firm/specfiles/ARM7-TS-GCDFIRM.lcf.template new file mode 100644 index 00000000..83064d35 --- /dev/null +++ b/include/firm/specfiles/ARM7-TS-GCDFIRM.lcf.template @@ -0,0 +1,494 @@ +#--------------------------------------------------------------------------- +# Project: TwlFirm - tools - makelcf +# File: ARM7-TS-NORFIRM.lcf.template +# +# 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. +# +# $Log: $ +# $NoKeywords: $ +#--------------------------------------------------------------------------- +MEMORY +{ + (RWX) : ORIGIN = , LENGTH = 0x0 # > + + (RWX) : ORIGIN = , LENGTH = 0x0 > + +# binary.AUTOLOAD_INFO (RWX) : ORIGIN = 0, LENGTH = 0x0 > + + (RW) : ORIGIN = AFTER(), LENGTH = 0x0 > + (RW) : ORIGIN = AFTER(), LENGTH = 0x0 > + + (RWXO): ORIGIN = , LENGTH = 0x0 > + + arena.MAIN (RW) : ORIGIN = AFTER(,), LENGTH = 0x0 + check.WORKRAM (RWX) : ORIGIN = , LENGTH = 0x48000 > workram.check +} + +KEEP_SECTION +{ + .ctor +} + +SECTIONS +{ + ############################ STATIC ################################# + .: + { + ALIGNALL(4); . = ALIGN(4); # Fit to cache line + + + + # + # TEXT BLOCK: READ ONLY + # + SDK_STATIC_START =.; + SDK_STATIC_TEXT_START =.; + #:::::::::: text/rodata + OBJECT(_start,*) + crt0.o (.text) + + + + + + + . = ALIGN(4); + * (.exception) + . = ALIGN(4); + SDK_STATIC_ETABLE_START =.; + EXCEPTION + SDK_STATIC_ETABLE_END =.; + . = ALIGN(4); + + + + + + + . = ALIGN(4); + + + + + + + . = ALIGN(4); + + SDK_STATIC_SINIT_START =.; + #:::::::::: ctor + + + + + + + WRITEW 0; + #:::::::::: ctor + SDK_STATIC_SINIT_END =.; + + #:::::::::: text/rodata + . = ALIGN(4); + SDK_STATIC_TEXT_END =.; + + # + # DATA BLOCK: READ WRITE + # + SDK_STATIC_DATA_START =.; + #:::::::::: data + + + + + + + . = ALIGN(4); + + + + + + + . = ALIGN(4); + + + + + + + . = ALIGN(4); + #:::::::::: data + . = ALIGN(4); + SDK_STATIC_DATA_END =.; + SDK_STATIC_END =.; + + SDK_STATIC_TEXT_SIZE = SDK_STATIC_TEXT_END - SDK_STATIC_TEXT_START; + SDK_STATIC_DATA_SIZE = SDK_STATIC_DATA_END - SDK_STATIC_DATA_START; + SDK_STATIC_SIZE = SDK_STATIC_END - SDK_STATIC_START; + __sinit__ = SDK_STATIC_SINIT_START; # for static initializer + __exception_table_start__ = SDK_STATIC_ETABLE_START; # for exception table + __exception_table_end__ = SDK_STATIC_ETABLE_END; # for exception table + } > + + ..bss: + { + ALIGNALL(4); . = ALIGN(4); + + + + # + # BSS BLOCK + # + SDK_STATIC_BSS_START =.; + #:::::::::: bss + + + + + + + . = ALIGN(4); + + + + + + + . = ALIGN(4); + #:::::::::: bss + . = ALIGN(4); + SDK_STATIC_BSS_END = .; + SDK_STATIC_BSS_SIZE = SDK_STATIC_BSS_END - SDK_STATIC_BSS_START; + + } >> + + + ############################ AUTOLOADS ############################## + SDK_AUTOLOAD.MAIN.START = 0x02380000; + SDK_AUTOLOAD.MAIN.END = SDK_AUTOLOAD.MAIN.START; + SDK_AUTOLOAD.MAIN.BSS_END = SDK_AUTOLOAD.MAIN.START; + SDK_AUTOLOAD.MAIN.SIZE = 0; + SDK_AUTOLOAD.MAIN.BSS_SIZE = 0; + SDK_AUTOLOAD.WRAM.START = 0x037f8000; + SDK_AUTOLOAD.WRAM.END = SDK_AUTOLOAD.WRAM.START; + SDK_AUTOLOAD.WRAM.BSS_END = SDK_AUTOLOAD.WRAM.START; + SDK_AUTOLOAD.WRAM.SIZE = 0; + SDK_AUTOLOAD.WRAM.BSS_SIZE = 0; + SDK_AUTOLOAD_START = SDK_STATIC_END; + SDK_AUTOLOAD_SIZE = 0; + SDK_AUTOLOAD_NUMBER = ; + + + .: + { + ALIGNALL(4); . = ALIGN(4); + + + + # + # TEXT BLOCK: READ ONLY + # + SDK_AUTOLOAD__ID =; + SDK_AUTOLOAD..ID =; + SDK_AUTOLOAD..START =.; + SDK_AUTOLOAD..TEXT_START =.; + #:::::::::: text/rodata + + + + + + + . = ALIGN(4); + + + + + + + . = ALIGN(4); + #:::::::::: text/rodata + SDK_AUTOLOAD..TEXT_END =.; + + # + # DATA BLOCK: READ WRITE BLOCK + # + SDK_AUTOLOAD..DATA_START =.; + #:::::::::: data + + + + + + + . = ALIGN(4); + + + + + + + . = ALIGN(4); + + + + + + + . = ALIGN(4); + #:::::::::: data + SDK_AUTOLOAD..DATA_END =.; + SDK_AUTOLOAD..END =.; + + SDK_AUTOLOAD..TEXT_SIZE = SDK_AUTOLOAD..TEXT_END - SDK_AUTOLOAD..TEXT_START; + SDK_AUTOLOAD..DATA_SIZE = SDK_AUTOLOAD..DATA_END - SDK_AUTOLOAD..DATA_START; + SDK_AUTOLOAD..SIZE = SDK_AUTOLOAD..END - SDK_AUTOLOAD..START; + SDK_AUTOLOAD_SIZE = SDK_AUTOLOAD_SIZE + SDK_AUTOLOAD..SIZE; + + } > + + ..bss: + { + ALIGNALL(4); . = ALIGN(4); + + + + # + # BSS BLOCK + # + SDK_AUTOLOAD..BSS_START = .; + #:::::::::: bss + + + + + + + . = ALIGN(4); + + + + + + + . = ALIGN(4); + #:::::::::: bss + . = ALIGN(4); + SDK_AUTOLOAD..BSS_END = .; + + SDK_AUTOLOAD..BSS_SIZE = SDK_AUTOLOAD..BSS_END - SDK_AUTOLOAD..BSS_START; + + } >> + + + + SDK_AUTOLOAD_MAIN_START = SDK_AUTOLOAD.MAIN.START; + SDK_AUTOLOAD_MAIN_END = SDK_AUTOLOAD.MAIN.END; + SDK_AUTOLOAD_MAIN_BSS_END = SDK_AUTOLOAD.MAIN.BSS_END; + SDK_AUTOLOAD_MAIN_SIZE = SDK_AUTOLOAD.MAIN.SIZE; + SDK_AUTOLOAD_MAIN_BSS_SIZE = SDK_AUTOLOAD.MAIN.BSS_SIZE; + SDK_AUTOLOAD_WRAM_START = SDK_AUTOLOAD.WRAM.START; + SDK_AUTOLOAD_WRAM_END = SDK_AUTOLOAD.WRAM.END; + SDK_AUTOLOAD_WRAM_BSS_END = SDK_AUTOLOAD.WRAM.BSS_END; + SDK_AUTOLOAD_WRAM_SIZE = SDK_AUTOLOAD.WRAM.SIZE; + SDK_AUTOLOAD_WRAM_BSS_SIZE = SDK_AUTOLOAD.WRAM.BSS_SIZE; + + ############################ AUTOLOAD_INFO ########################## + .binary.AUTOLOAD_INFO: + { + SDK_AUTOLOAD_LIST = .; + + WRITEW ADDR(.); + WRITEW SDK_AUTOLOAD..SIZE; + WRITEW SDK_AUTOLOAD..BSS_SIZE; + + SDK_AUTOLOAD_LIST_END = .; + } >> # > binary.AUTOLOAD_INFO + +# SDK_AUTOLOAD_LIST = SDK_AUTOLOAD_START + SDK_AUTOLOAD_SIZE; +# SDK_AUTOLOAD_LIST_END = SDK_AUTOLOAD_START + SDK_AUTOLOAD_SIZE + SIZEOF(.binary.AUTOLOAD_INFO); + SDK_AUTOLOAD_SIZE = SDK_AUTOLOAD_SIZE + SIZEOF(.binary.AUTOLOAD_INFO); + + ############################ OVERLAYS ############################### + SDK_OVERLAY_NUMBER = ; + + + .: + { + ALIGNALL(4); . = ALIGN(4); + + + + # + # TEXT BLOCK: READ ONLY + # + SDK_OVERLAY__ID =; ### SEGMENT OVERLAY ID + SDK_OVERLAY..ID =; + SDK_OVERLAY..START =.; + SDK_OVERLAY..TEXT_START =.; + #:::::::::: text/rodata + + + + + + + . = ALIGN(4); + + + + + + + . = ALIGN(4); + + + + + + + . = ALIGN(4); + SDK_OVERLAY..SINIT_START =.; + #:::::::::: ctor + + + + + + + WRITEW 0; + #:::::::::: ctor + SDK_OVERLAY..SINIT_END =.; + + #:::::::::: text/rodata + . = ALIGN(4); + SDK_OVERLAY..TEXT_END =.; + + # + # DATA BLOCK: READ WRITE + # + SDK_OVERLAY..DATA_START =.; + #:::::::::: data + + + + + + + . = ALIGN(4); + + + + + + + . = ALIGN(4); + #:::::::::: data + . = ALIGN(4); + SDK_OVERLAY..DATA_END =.; + SDK_OVERLAY..END =.; + + SDK_OVERLAY..TEXT_SIZE = SDK_OVERLAY..TEXT_END - SDK_OVERLAY..TEXT_START; + SDK_OVERLAY..DATA_SIZE = SDK_OVERLAY..DATA_END - SDK_OVERLAY..DATA_START; + SDK_OVERLAY..SIZE = SDK_OVERLAY..END - SDK_OVERLAY..START; + + } > + + ..bss: + { + ALIGNALL(4); . = ALIGN(4); + + + + # + # BSS BLOCK + # + SDK_OVERLAY..BSS_START = .; + #:::::::::: bss + + + + + + + . = ALIGN(4); + + + + + + + . = ALIGN(4); + #:::::::::: bss + . = ALIGN(4); + SDK_OVERLAY..BSS_END = .; + + SDK_OVERLAY..BSS_SIZE = SDK_OVERLAY..BSS_END - SDK_OVERLAY..BSS_START; + + } >> + + + + + ############################ ARENA ################################## + .arena.MAIN: + { + . = ALIGN(4); + SDK_SECTION_ARENA_START =.; + } > arena.MAIN + + + ############################ OVERLAYDEFS ############################ + .: + { + ### module information + WRITEW ADDR(.); # load address + WRITEW _start; # entry address + WRITEW SDK_STATIC_SIZE + SDK_AUTOLOAD_SIZE; # size of module + WRITEW _start_AutoloadDoneCallback; # callback autoload done + + ### overlay filename + + WRITES (""); # Overlay + + + } > + + + ############################ OVERLAYTABLE ########################### + .: + { + + # Overlay + WRITEW ; # overlay ID + WRITEW ADDR(.); # load address + WRITEW SDK_OVERLAY..SIZE; # size of module + WRITEW SDK_OVERLAY..BSS_SIZE; # size of bss + WRITEW SDK_OVERLAY..SINIT_START; # start address of static init + WRITEW SDK_OVERLAY..SINIT_END; # end address of static init + WRITEW ; # ROM file ID + WRITEW 0; # Reserved + + + + } > + + + ############################ OTHERS ################################# + SDK_SUBPRIV_ARENA_LO = SDK_AUTOLOAD.MAIN.BSS_END; + SDK_WRAM_ARENA_LO = SDK_SECTION_ARENA_START; + SDK_IRQ_STACKSIZE = ; # allocated in WRAM + SDK_SYS_STACKSIZE = ; # allocated in WRAM + + # work ram size checker + SDK_SYS_STACKSIZE_SIGN = (SDK_SYS_STACKSIZE < 0x80000000) * 2 - 1; + .check.WORKRAM: + { + . = . + SDK_SECTION_ARENA_START - + SDK_IRQ_STACKSIZE + SDK_SYS_STACKSIZE * SDK_SYS_STACKSIZE_SIGN; + } > check.WORKRAM +} diff --git a/include/firm/specfiles/ARM7-TS-GCDFIRM.lsf b/include/firm/specfiles/ARM7-TS-GCDFIRM.lsf new file mode 100644 index 00000000..ef7f7d42 --- /dev/null +++ b/include/firm/specfiles/ARM7-TS-GCDFIRM.lsf @@ -0,0 +1,27 @@ +#---------------------------------------------------------------------------- +# Project: TwlFirm - include +# File: ARM7-TS-NORFIRM.lsf +# +# Copyright 2007 Nintendo. All rights reserved. +# +# These coded insructions, 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: $ +# $NoKeywords: $ +#---------------------------------------------------------------------------- +# +# TwlFirm LCF SPEC FILE +# + +Static $(TARGET_NAME) +{ + Address 0x037f8000 + Object $(OBJS_STATIC) + Library $(LLIBS) $(GLIBS) $(CW_LIBS) + Object * (.wram) + StackSize 1024 512 +} diff --git a/include/firm/specfiles/ARM7-TS-NORFIRM.lcf.template b/include/firm/specfiles/ARM7-TS-NORFIRM.lcf.template new file mode 100644 index 00000000..83064d35 --- /dev/null +++ b/include/firm/specfiles/ARM7-TS-NORFIRM.lcf.template @@ -0,0 +1,494 @@ +#--------------------------------------------------------------------------- +# Project: TwlFirm - tools - makelcf +# File: ARM7-TS-NORFIRM.lcf.template +# +# 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. +# +# $Log: $ +# $NoKeywords: $ +#--------------------------------------------------------------------------- +MEMORY +{ + (RWX) : ORIGIN = , LENGTH = 0x0 # > + + (RWX) : ORIGIN = , LENGTH = 0x0 > + +# binary.AUTOLOAD_INFO (RWX) : ORIGIN = 0, LENGTH = 0x0 > + + (RW) : ORIGIN = AFTER(), LENGTH = 0x0 > + (RW) : ORIGIN = AFTER(), LENGTH = 0x0 > + + (RWXO): ORIGIN = , LENGTH = 0x0 > + + arena.MAIN (RW) : ORIGIN = AFTER(,), LENGTH = 0x0 + check.WORKRAM (RWX) : ORIGIN = , LENGTH = 0x48000 > workram.check +} + +KEEP_SECTION +{ + .ctor +} + +SECTIONS +{ + ############################ STATIC ################################# + .: + { + ALIGNALL(4); . = ALIGN(4); # Fit to cache line + + + + # + # TEXT BLOCK: READ ONLY + # + SDK_STATIC_START =.; + SDK_STATIC_TEXT_START =.; + #:::::::::: text/rodata + OBJECT(_start,*) + crt0.o (.text) + + + + + + + . = ALIGN(4); + * (.exception) + . = ALIGN(4); + SDK_STATIC_ETABLE_START =.; + EXCEPTION + SDK_STATIC_ETABLE_END =.; + . = ALIGN(4); + + + + + + + . = ALIGN(4); + + + + + + + . = ALIGN(4); + + SDK_STATIC_SINIT_START =.; + #:::::::::: ctor + + + + + + + WRITEW 0; + #:::::::::: ctor + SDK_STATIC_SINIT_END =.; + + #:::::::::: text/rodata + . = ALIGN(4); + SDK_STATIC_TEXT_END =.; + + # + # DATA BLOCK: READ WRITE + # + SDK_STATIC_DATA_START =.; + #:::::::::: data + + + + + + + . = ALIGN(4); + + + + + + + . = ALIGN(4); + + + + + + + . = ALIGN(4); + #:::::::::: data + . = ALIGN(4); + SDK_STATIC_DATA_END =.; + SDK_STATIC_END =.; + + SDK_STATIC_TEXT_SIZE = SDK_STATIC_TEXT_END - SDK_STATIC_TEXT_START; + SDK_STATIC_DATA_SIZE = SDK_STATIC_DATA_END - SDK_STATIC_DATA_START; + SDK_STATIC_SIZE = SDK_STATIC_END - SDK_STATIC_START; + __sinit__ = SDK_STATIC_SINIT_START; # for static initializer + __exception_table_start__ = SDK_STATIC_ETABLE_START; # for exception table + __exception_table_end__ = SDK_STATIC_ETABLE_END; # for exception table + } > + + ..bss: + { + ALIGNALL(4); . = ALIGN(4); + + + + # + # BSS BLOCK + # + SDK_STATIC_BSS_START =.; + #:::::::::: bss + + + + + + + . = ALIGN(4); + + + + + + + . = ALIGN(4); + #:::::::::: bss + . = ALIGN(4); + SDK_STATIC_BSS_END = .; + SDK_STATIC_BSS_SIZE = SDK_STATIC_BSS_END - SDK_STATIC_BSS_START; + + } >> + + + ############################ AUTOLOADS ############################## + SDK_AUTOLOAD.MAIN.START = 0x02380000; + SDK_AUTOLOAD.MAIN.END = SDK_AUTOLOAD.MAIN.START; + SDK_AUTOLOAD.MAIN.BSS_END = SDK_AUTOLOAD.MAIN.START; + SDK_AUTOLOAD.MAIN.SIZE = 0; + SDK_AUTOLOAD.MAIN.BSS_SIZE = 0; + SDK_AUTOLOAD.WRAM.START = 0x037f8000; + SDK_AUTOLOAD.WRAM.END = SDK_AUTOLOAD.WRAM.START; + SDK_AUTOLOAD.WRAM.BSS_END = SDK_AUTOLOAD.WRAM.START; + SDK_AUTOLOAD.WRAM.SIZE = 0; + SDK_AUTOLOAD.WRAM.BSS_SIZE = 0; + SDK_AUTOLOAD_START = SDK_STATIC_END; + SDK_AUTOLOAD_SIZE = 0; + SDK_AUTOLOAD_NUMBER = ; + + + .: + { + ALIGNALL(4); . = ALIGN(4); + + + + # + # TEXT BLOCK: READ ONLY + # + SDK_AUTOLOAD__ID =; + SDK_AUTOLOAD..ID =; + SDK_AUTOLOAD..START =.; + SDK_AUTOLOAD..TEXT_START =.; + #:::::::::: text/rodata + + + + + + + . = ALIGN(4); + + + + + + + . = ALIGN(4); + #:::::::::: text/rodata + SDK_AUTOLOAD..TEXT_END =.; + + # + # DATA BLOCK: READ WRITE BLOCK + # + SDK_AUTOLOAD..DATA_START =.; + #:::::::::: data + + + + + + + . = ALIGN(4); + + + + + + + . = ALIGN(4); + + + + + + + . = ALIGN(4); + #:::::::::: data + SDK_AUTOLOAD..DATA_END =.; + SDK_AUTOLOAD..END =.; + + SDK_AUTOLOAD..TEXT_SIZE = SDK_AUTOLOAD..TEXT_END - SDK_AUTOLOAD..TEXT_START; + SDK_AUTOLOAD..DATA_SIZE = SDK_AUTOLOAD..DATA_END - SDK_AUTOLOAD..DATA_START; + SDK_AUTOLOAD..SIZE = SDK_AUTOLOAD..END - SDK_AUTOLOAD..START; + SDK_AUTOLOAD_SIZE = SDK_AUTOLOAD_SIZE + SDK_AUTOLOAD..SIZE; + + } > + + ..bss: + { + ALIGNALL(4); . = ALIGN(4); + + + + # + # BSS BLOCK + # + SDK_AUTOLOAD..BSS_START = .; + #:::::::::: bss + + + + + + + . = ALIGN(4); + + + + + + + . = ALIGN(4); + #:::::::::: bss + . = ALIGN(4); + SDK_AUTOLOAD..BSS_END = .; + + SDK_AUTOLOAD..BSS_SIZE = SDK_AUTOLOAD..BSS_END - SDK_AUTOLOAD..BSS_START; + + } >> + + + + SDK_AUTOLOAD_MAIN_START = SDK_AUTOLOAD.MAIN.START; + SDK_AUTOLOAD_MAIN_END = SDK_AUTOLOAD.MAIN.END; + SDK_AUTOLOAD_MAIN_BSS_END = SDK_AUTOLOAD.MAIN.BSS_END; + SDK_AUTOLOAD_MAIN_SIZE = SDK_AUTOLOAD.MAIN.SIZE; + SDK_AUTOLOAD_MAIN_BSS_SIZE = SDK_AUTOLOAD.MAIN.BSS_SIZE; + SDK_AUTOLOAD_WRAM_START = SDK_AUTOLOAD.WRAM.START; + SDK_AUTOLOAD_WRAM_END = SDK_AUTOLOAD.WRAM.END; + SDK_AUTOLOAD_WRAM_BSS_END = SDK_AUTOLOAD.WRAM.BSS_END; + SDK_AUTOLOAD_WRAM_SIZE = SDK_AUTOLOAD.WRAM.SIZE; + SDK_AUTOLOAD_WRAM_BSS_SIZE = SDK_AUTOLOAD.WRAM.BSS_SIZE; + + ############################ AUTOLOAD_INFO ########################## + .binary.AUTOLOAD_INFO: + { + SDK_AUTOLOAD_LIST = .; + + WRITEW ADDR(.); + WRITEW SDK_AUTOLOAD..SIZE; + WRITEW SDK_AUTOLOAD..BSS_SIZE; + + SDK_AUTOLOAD_LIST_END = .; + } >> # > binary.AUTOLOAD_INFO + +# SDK_AUTOLOAD_LIST = SDK_AUTOLOAD_START + SDK_AUTOLOAD_SIZE; +# SDK_AUTOLOAD_LIST_END = SDK_AUTOLOAD_START + SDK_AUTOLOAD_SIZE + SIZEOF(.binary.AUTOLOAD_INFO); + SDK_AUTOLOAD_SIZE = SDK_AUTOLOAD_SIZE + SIZEOF(.binary.AUTOLOAD_INFO); + + ############################ OVERLAYS ############################### + SDK_OVERLAY_NUMBER = ; + + + .: + { + ALIGNALL(4); . = ALIGN(4); + + + + # + # TEXT BLOCK: READ ONLY + # + SDK_OVERLAY__ID =; ### SEGMENT OVERLAY ID + SDK_OVERLAY..ID =; + SDK_OVERLAY..START =.; + SDK_OVERLAY..TEXT_START =.; + #:::::::::: text/rodata + + + + + + + . = ALIGN(4); + + + + + + + . = ALIGN(4); + + + + + + + . = ALIGN(4); + SDK_OVERLAY..SINIT_START =.; + #:::::::::: ctor + + + + + + + WRITEW 0; + #:::::::::: ctor + SDK_OVERLAY..SINIT_END =.; + + #:::::::::: text/rodata + . = ALIGN(4); + SDK_OVERLAY..TEXT_END =.; + + # + # DATA BLOCK: READ WRITE + # + SDK_OVERLAY..DATA_START =.; + #:::::::::: data + + + + + + + . = ALIGN(4); + + + + + + + . = ALIGN(4); + #:::::::::: data + . = ALIGN(4); + SDK_OVERLAY..DATA_END =.; + SDK_OVERLAY..END =.; + + SDK_OVERLAY..TEXT_SIZE = SDK_OVERLAY..TEXT_END - SDK_OVERLAY..TEXT_START; + SDK_OVERLAY..DATA_SIZE = SDK_OVERLAY..DATA_END - SDK_OVERLAY..DATA_START; + SDK_OVERLAY..SIZE = SDK_OVERLAY..END - SDK_OVERLAY..START; + + } > + + ..bss: + { + ALIGNALL(4); . = ALIGN(4); + + + + # + # BSS BLOCK + # + SDK_OVERLAY..BSS_START = .; + #:::::::::: bss + + + + + + + . = ALIGN(4); + + + + + + + . = ALIGN(4); + #:::::::::: bss + . = ALIGN(4); + SDK_OVERLAY..BSS_END = .; + + SDK_OVERLAY..BSS_SIZE = SDK_OVERLAY..BSS_END - SDK_OVERLAY..BSS_START; + + } >> + + + + + ############################ ARENA ################################## + .arena.MAIN: + { + . = ALIGN(4); + SDK_SECTION_ARENA_START =.; + } > arena.MAIN + + + ############################ OVERLAYDEFS ############################ + .: + { + ### module information + WRITEW ADDR(.); # load address + WRITEW _start; # entry address + WRITEW SDK_STATIC_SIZE + SDK_AUTOLOAD_SIZE; # size of module + WRITEW _start_AutoloadDoneCallback; # callback autoload done + + ### overlay filename + + WRITES (""); # Overlay + + + } > + + + ############################ OVERLAYTABLE ########################### + .: + { + + # Overlay + WRITEW ; # overlay ID + WRITEW ADDR(.); # load address + WRITEW SDK_OVERLAY..SIZE; # size of module + WRITEW SDK_OVERLAY..BSS_SIZE; # size of bss + WRITEW SDK_OVERLAY..SINIT_START; # start address of static init + WRITEW SDK_OVERLAY..SINIT_END; # end address of static init + WRITEW ; # ROM file ID + WRITEW 0; # Reserved + + + + } > + + + ############################ OTHERS ################################# + SDK_SUBPRIV_ARENA_LO = SDK_AUTOLOAD.MAIN.BSS_END; + SDK_WRAM_ARENA_LO = SDK_SECTION_ARENA_START; + SDK_IRQ_STACKSIZE = ; # allocated in WRAM + SDK_SYS_STACKSIZE = ; # allocated in WRAM + + # work ram size checker + SDK_SYS_STACKSIZE_SIGN = (SDK_SYS_STACKSIZE < 0x80000000) * 2 - 1; + .check.WORKRAM: + { + . = . + SDK_SECTION_ARENA_START - + SDK_IRQ_STACKSIZE + SDK_SYS_STACKSIZE * SDK_SYS_STACKSIZE_SIGN; + } > check.WORKRAM +} diff --git a/include/firm/specfiles/ARM7-TS-NORFIRM.lsf b/include/firm/specfiles/ARM7-TS-NORFIRM.lsf new file mode 100644 index 00000000..ef7f7d42 --- /dev/null +++ b/include/firm/specfiles/ARM7-TS-NORFIRM.lsf @@ -0,0 +1,27 @@ +#---------------------------------------------------------------------------- +# Project: TwlFirm - include +# File: ARM7-TS-NORFIRM.lsf +# +# Copyright 2007 Nintendo. All rights reserved. +# +# These coded insructions, 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: $ +# $NoKeywords: $ +#---------------------------------------------------------------------------- +# +# TwlFirm LCF SPEC FILE +# + +Static $(TARGET_NAME) +{ + Address 0x037f8000 + Object $(OBJS_STATIC) + Library $(LLIBS) $(GLIBS) $(CW_LIBS) + Object * (.wram) + StackSize 1024 512 +} diff --git a/include/firm/specfiles/ARM9-BB-GCDFIRM.lcf.template b/include/firm/specfiles/ARM9-BB-GCDFIRM.lcf.template new file mode 100644 index 00000000..fcc55e5a --- /dev/null +++ b/include/firm/specfiles/ARM9-BB-GCDFIRM.lcf.template @@ -0,0 +1,589 @@ +#--------------------------------------------------------------------------- +# Project: TwlFirm - tools - makelcf +# File: ARM9-BB-NORFIRM.lcf.template +# +# 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. +# +# $Log: $ +# $NoKeywords: $ +#--------------------------------------------------------------------------- +MEMORY +{ + (RWX) : ORIGIN = , LENGTH = 0x0 # > + + (RWX) : ORIGIN = , LENGTH = 0x0 # > + +# binary.AUTOLOAD_INFO (RWX) : ORIGIN = 0, LENGTH = 0x0 > +# binary.STATIC_FOOTER (RWX) : ORIGIN = 0, LENGTH = 0x0 >> + + (RW) : ORIGIN = AFTER(), LENGTH = 0x0 > + (RW) : ORIGIN = AFTER(), LENGTH = 0x0 > + + (RWXO): ORIGIN = , LENGTH = 0x0 > + + dummy.MAIN_EX (RW) : ORIGIN = 0x023e0000, LENGTH = 0x0 + arena.MAIN (RW) : ORIGIN = AFTER(,), LENGTH = 0x0 + arena.MAIN_EX (RW) : ORIGIN = AFTER(dummy.MAIN_EX,), LENGTH = 0x0 + arena.ITCM (RW) : ORIGIN = AFTER(ITCM,), LENGTH = 0x0 + arena.DTCM (RW) : ORIGIN = AFTER(DTCM,), LENGTH = 0x0 + binary.MODULE_FILES (RW) : ORIGIN = 0x0, LENGTH = 0x0 > component.files + check.ITCM (RWX) : ORIGIN = 0x0, LENGTH = 0x08000 > itcm.check + check.DTCM (RW) : ORIGIN = 0x0, LENGTH = 0x04000 > dtcm.check +} + +FORCE_ACTIVE +{ + SVC_SoftReset +} + +KEEP_SECTION +{ + .sinit +} + +SECTIONS +{ + ############################ STATIC ################################# + .: + { + ALIGNALL(4); . = ALIGN(32); # Fit to cache line + + + + # + # TEXT BLOCK: READ ONLY + # + SDK_STATIC_START =.; + SDK_STATIC_TEXT_START =.; + #:::::::::: text/rodata + crt0.o (.text) + libsyscall.a (.text) + crt0.o (.rodata) + # + # .version ZNVljĂ܂B + # ̃ZNVɊ܂܂̓bg`FbN̍ۂ + # KvƂȂ܂̂ŁAK̈ʒuɎc悤ɂĉB + # + * (.version) + OBJECT(TwlMain,*) + + + + + + + . = ALIGN(4); + * (.exception) + . = ALIGN(4); + SDK_STATIC_ETABLE_START =.; + EXCEPTION + SDK_STATIC_ETABLE_END =.; + . = ALIGN(4); + + + + + + + . = ALIGN(4); + + + + + + + . = ALIGN(4); + + SDK_STATIC_SINIT_START =.; + #:::::::::: ctor + + + + + + + + + + + + + WRITEW 0; + #:::::::::: ctor + SDK_STATIC_SINIT_END =.; + + #:::::::::: text/rodata + . = ALIGN(32); + SDK_STATIC_TEXT_END =.; + + # + # DATA BLOCK: READ WRITE + # + SDK_STATIC_DATA_START =.; + #:::::::::: data + + + + + + + . = ALIGN(4); + + + + + + + . = ALIGN(4); + SDK_OVERLAY_DIGEST =.; + # NO DIGEST + SDK_OVERLAY_DIGEST_END =.; + #:::::::::: data + . = ALIGN(32); + SDK_STATIC_DATA_END =.; + SDK_STATIC_END =.; + + SDK_STATIC_TEXT_SIZE = SDK_STATIC_TEXT_END - SDK_STATIC_TEXT_START; + SDK_STATIC_DATA_SIZE = SDK_STATIC_DATA_END - SDK_STATIC_DATA_START; + SDK_STATIC_SIZE = SDK_STATIC_END - SDK_STATIC_START; + __sinit__ = SDK_STATIC_SINIT_START; # for static initializer + __exception_table_start__ = SDK_STATIC_ETABLE_START; # for exception table + __exception_table_end__ = SDK_STATIC_ETABLE_END; # for exception table + } > + + ..bss: + { + ALIGNALL(4); . = ALIGN(32); + + + + # + # BSS BLOCK + # + SDK_STATIC_BSS_START =.; + #:::::::::: bss + + + + + + + . = ALIGN(4); + + + + + + + . = ALIGN(4); + #:::::::::: bss + . = ALIGN(32); + SDK_STATIC_BSS_END = .; + SDK_STATIC_BSS_SIZE = SDK_STATIC_BSS_END - SDK_STATIC_BSS_START; + + } >> + + + ############################ AUTOLOADS ############################## + SDK_AUTOLOAD.ITCM.START = 0x01ff8000; + SDK_AUTOLOAD.ITCM.END = SDK_AUTOLOAD.ITCM.START; + SDK_AUTOLOAD.ITCM.BSS_END = SDK_AUTOLOAD.ITCM.START; + SDK_AUTOLOAD.ITCM.SIZE = 0; + SDK_AUTOLOAD.ITCM.BSS_SIZE = 0; + SDK_AUTOLOAD.DTCM.START = 0x027e0000; + SDK_AUTOLOAD.DTCM.END = SDK_AUTOLOAD.DTCM.START; + SDK_AUTOLOAD.DTCM.BSS_END = SDK_AUTOLOAD.DTCM.START; + SDK_AUTOLOAD.DTCM.SIZE = 0; + SDK_AUTOLOAD.DTCM.BSS_SIZE = 0; + SDK_AUTOLOAD_START = SDK_STATIC_END; + SDK_AUTOLOAD_SIZE = 0; + SDK_AUTOLOAD_NUMBER = ; + + + .: + { + ALIGNALL(4); . = ALIGN(32); + + + + # + # TEXT BLOCK: READ ONLY + # + SDK_AUTOLOAD__ID =; + SDK_AUTOLOAD..ID =; + SDK_AUTOLOAD..START =.; + SDK_AUTOLOAD..TEXT_START =.; + #:::::::::: text/rodata + + + + + + + . = ALIGN(4); + + + + + + + . = ALIGN(4); + + + + + + + . = ALIGN(4); + #:::::::::: text/rodata + SDK_AUTOLOAD..TEXT_END =.; + + # + # DATA BLOCK: READ WRITE BLOCK + # + SDK_AUTOLOAD..DATA_START =.; + #:::::::::: data + + + + + + + . = ALIGN(4); + + + + + + + . = ALIGN(4); + + + + + + + . = ALIGN(4); + #:::::::::: data + . = ALIGN(32); + SDK_AUTOLOAD..DATA_END =.; + SDK_AUTOLOAD..END =.; + + SDK_AUTOLOAD..TEXT_SIZE = SDK_AUTOLOAD..TEXT_END - SDK_AUTOLOAD..TEXT_START; + SDK_AUTOLOAD..DATA_SIZE = SDK_AUTOLOAD..DATA_END - SDK_AUTOLOAD..DATA_START; + SDK_AUTOLOAD..SIZE = SDK_AUTOLOAD..END - SDK_AUTOLOAD..START; + SDK_AUTOLOAD_SIZE = SDK_AUTOLOAD_SIZE + SDK_AUTOLOAD..SIZE; + + } > + + ..bss: + { + ALIGNALL(4); . = ALIGN(32); + + + + # + # BSS BLOCK + # + SDK_AUTOLOAD..BSS_START = .; + #:::::::::: bss + + + + + + + . = ALIGN(4); + + + + + + + . = ALIGN(4); + + + + + + + . = ALIGN(4); + + + + + + + . = ALIGN(4); + #:::::::::: bss + . = ALIGN(32); + SDK_AUTOLOAD..BSS_END = .; + + SDK_AUTOLOAD..BSS_SIZE = SDK_AUTOLOAD..BSS_END - SDK_AUTOLOAD..BSS_START; + + } >> + + + + SDK_AUTOLOAD_ITCM_START = SDK_AUTOLOAD.ITCM.START; + SDK_AUTOLOAD_ITCM_END = SDK_AUTOLOAD.ITCM.END; + SDK_AUTOLOAD_ITCM_BSS_END = SDK_AUTOLOAD.ITCM.BSS_END; + SDK_AUTOLOAD_ITCM_SIZE = SDK_AUTOLOAD.ITCM.SIZE; + SDK_AUTOLOAD_ITCM_BSS_SIZE = SDK_AUTOLOAD.ITCM.BSS_SIZE; + SDK_AUTOLOAD_DTCM_START = SDK_AUTOLOAD.DTCM.START; + SDK_AUTOLOAD_DTCM_END = SDK_AUTOLOAD.DTCM.END; + SDK_AUTOLOAD_DTCM_BSS_END = SDK_AUTOLOAD.DTCM.BSS_END; + SDK_AUTOLOAD_DTCM_SIZE = SDK_AUTOLOAD.DTCM.SIZE; + SDK_AUTOLOAD_DTCM_BSS_SIZE = SDK_AUTOLOAD.DTCM.BSS_SIZE; + + ############################ AUTOLOAD_INFO ########################## + .binary.AUTOLOAD_INFO: + { + SDK_AUTOLOAD_LIST = .; + + WRITEW ADDR(.); + WRITEW SDK_AUTOLOAD..SIZE; + WRITEW SDK_AUTOLOAD..BSS_SIZE; + + SDK_AUTOLOAD_LIST_END = .; + } >> # > binary.AUTOLOAD_INFO + +# SDK_AUTOLOAD_LIST = SDK_AUTOLOAD_START + SDK_AUTOLOAD_SIZE; +# SDK_AUTOLOAD_LIST_END = SDK_AUTOLOAD_START + SDK_AUTOLOAD_SIZE + SIZEOF(.binary.AUTOLOAD_INFO); + SDK_AUTOLOAD_SIZE = SDK_AUTOLOAD_SIZE + SIZEOF(.binary.AUTOLOAD_INFO); + + ############################ STATIC_FOOTER ########################## + .binary.STATIC_FOOTER: + { + WRITEW 0xdec00621; # LE(0x2106C0DE) = NITRO CODE + WRITEW _start_ModuleParams - ADDR(.); + WRITEW 0; # NO DIGEST + } >> # > binary.STATIC_FOOTER + + ############################ OVERLAYS ############################### + SDK_OVERLAY_NUMBER = ; + + + .: + { + ALIGNALL(4); . = ALIGN(32); + + + + # + # TEXT BLOCK: READ ONLY + # + SDK_OVERLAY__ID =; ### SEGMENT OVERLAY ID + SDK_OVERLAY..ID =; + SDK_OVERLAY..START =.; + SDK_OVERLAY..TEXT_START =.; + #:::::::::: text/rodata + + + + + + + . = ALIGN(4); + + + + + + + . = ALIGN(4); + + + + + + + . = ALIGN(4); + SDK_OVERLAY..SINIT_START =.; + #:::::::::: ctor + + + + + + + + + + + + + WRITEW 0; + #:::::::::: ctor + SDK_OVERLAY..SINIT_END =.; + + #:::::::::: text/rodata + . = ALIGN(32); + SDK_OVERLAY..TEXT_END =.; + + # + # DATA BLOCK: READ WRITE + # + SDK_OVERLAY..DATA_START =.; + #:::::::::: data + + + + + + + . = ALIGN(4); + + + + + + + . = ALIGN(4); + #:::::::::: data + . = ALIGN(32); + SDK_OVERLAY..DATA_END =.; + SDK_OVERLAY..END =.; + + SDK_OVERLAY..TEXT_SIZE = SDK_OVERLAY..TEXT_END - SDK_OVERLAY..TEXT_START; + SDK_OVERLAY..DATA_SIZE = SDK_OVERLAY..DATA_END - SDK_OVERLAY..DATA_START; + SDK_OVERLAY..SIZE = SDK_OVERLAY..END - SDK_OVERLAY..START; + + } > + + ..bss: + { + ALIGNALL(4); . = ALIGN(32); + + + + # + # BSS BLOCK + # + SDK_OVERLAY..BSS_START = .; + #:::::::::: bss + + + + + + + . = ALIGN(4); + + + + + + + . = ALIGN(4); + #:::::::::: bss + . = ALIGN(32); + SDK_OVERLAY..BSS_END = .; + + SDK_OVERLAY..BSS_SIZE = SDK_OVERLAY..BSS_END - SDK_OVERLAY..BSS_START; + + } >> + + + + ############################ MAIN EX ################################## + # MAIN EX Area + .dummy.MAIN_EX: + { + . = ALIGN(32); + } > dummy.MAIN_EX + + ############################ ARENA ################################## + .arena.MAIN: + { + . = ALIGN(32); + SDK_SECTION_ARENA_START =.; + } > arena.MAIN + + .arena.MAIN_EX: + { + . = ALIGN(32); + SDK_SECTION_ARENA_EX_START =.; + } > arena.MAIN_EX + + .arena.ITCM: + { + . = ALIGN(32); + SDK_SECTION_ARENA_ITCM_START =.; + } > arena.ITCM + + .arena.DTCM: + { + . = ALIGN(32); + SDK_SECTION_ARENA_DTCM_START =.; + } > arena.DTCM + + ############################ OVERLAYDEFS ############################ + .: + { + ### module information + WRITEW ADDR(.); # load address + WRITEW _start; # entry address + WRITEW SDK_STATIC_SIZE + SDK_AUTOLOAD_SIZE; # size of module + WRITEW _start_AutoloadDoneCallback; # callback autoload done + + ### overlay filename + + WRITES (""); # Overlay + + + } > + + + ############################ OVERLAYTABLE ########################### + .: + { + + # Overlay + WRITEW ; # overlay ID + WRITEW ADDR(.); # load address + WRITEW SDK_OVERLAY..SIZE; # size of module + WRITEW SDK_OVERLAY..BSS_SIZE; # size of bss + WRITEW SDK_OVERLAY..SINIT_START; # start address of static init + WRITEW SDK_OVERLAY..SINIT_END; # end address of static init + WRITEW ; # ROM file ID + WRITEW 0; # Reserved + + + + } > + + + ############################ OTHERS ################################# + SDK_MAIN_ARENA_LO = SDK_SECTION_ARENA_START; + SDK_IRQ_STACKSIZE = ; # allocated in DTCM + SDK_SYS_STACKSIZE = ; # when 0 means all remains of DTCM + + # Module filelist + .binary.MODULE_FILES: + { + WRITES (""); + WRITES (""); + WRITES (""); + } > binary.MODULE_FILES + + # ITCM/DTCM size checker => check AUTOLOAD_ITCM/DTCM + .check.ITCM: + { + . = . + SDK_AUTOLOAD_ITCM_SIZE + SDK_AUTOLOAD_ITCM_BSS_SIZE; + } > check.ITCM + + SDK_SYS_STACKSIZE_SIGN = (SDK_SYS_STACKSIZE < 0x80000000) * 2 - 1; + .check.DTCM: + { + . = . + SDK_AUTOLOAD_DTCM_SIZE + SDK_AUTOLOAD_DTCM_BSS_SIZE; + . = . + SDK_IRQ_STACKSIZE + SDK_SYS_STACKSIZE * SDK_SYS_STACKSIZE_SIGN; + } > check.DTCM + +} diff --git a/include/firm/specfiles/ARM9-BB-GCDFIRM.lsf b/include/firm/specfiles/ARM9-BB-GCDFIRM.lsf new file mode 100644 index 00000000..e6488a8b --- /dev/null +++ b/include/firm/specfiles/ARM9-BB-GCDFIRM.lsf @@ -0,0 +1,41 @@ +#---------------------------------------------------------------------------- +# Project: TwlFirm - include +# File: ARM9-BB-NORFIRM.lsf +# +# Copyright 2007 Nintendo. All rights reserved. +# +# These coded insructions, 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: $ +# $NoKeywords: $ +#---------------------------------------------------------------------------- +# +# TwlFirm LCF SPEC FILE +# + +Static $(TARGET_NAME) +{ + Address 0x03800000 + Object $(OBJS_STATIC) + Library $(LLIBS) $(GLIBS) $(CW_LIBS) +} + +Autoload ITCM +{ + Address 0x01ff8000 + Object * (.itcm) + Object $(OBJS_AUTOLOAD) (.text) +} + +Autoload DTCM +{ + Address 0x027e0000 + Object * (.dtcm) + Object $(OBJS_AUTOLOAD) (.data) + Object $(OBJS_AUTOLOAD) (.bss) +} + diff --git a/include/firm/specfiles/ARM9-BB-NORFIRM.lcf.template b/include/firm/specfiles/ARM9-BB-NORFIRM.lcf.template new file mode 100644 index 00000000..fcc55e5a --- /dev/null +++ b/include/firm/specfiles/ARM9-BB-NORFIRM.lcf.template @@ -0,0 +1,589 @@ +#--------------------------------------------------------------------------- +# Project: TwlFirm - tools - makelcf +# File: ARM9-BB-NORFIRM.lcf.template +# +# 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. +# +# $Log: $ +# $NoKeywords: $ +#--------------------------------------------------------------------------- +MEMORY +{ + (RWX) : ORIGIN = , LENGTH = 0x0 # > + + (RWX) : ORIGIN = , LENGTH = 0x0 # > + +# binary.AUTOLOAD_INFO (RWX) : ORIGIN = 0, LENGTH = 0x0 > +# binary.STATIC_FOOTER (RWX) : ORIGIN = 0, LENGTH = 0x0 >> + + (RW) : ORIGIN = AFTER(), LENGTH = 0x0 > + (RW) : ORIGIN = AFTER(), LENGTH = 0x0 > + + (RWXO): ORIGIN = , LENGTH = 0x0 > + + dummy.MAIN_EX (RW) : ORIGIN = 0x023e0000, LENGTH = 0x0 + arena.MAIN (RW) : ORIGIN = AFTER(,), LENGTH = 0x0 + arena.MAIN_EX (RW) : ORIGIN = AFTER(dummy.MAIN_EX,), LENGTH = 0x0 + arena.ITCM (RW) : ORIGIN = AFTER(ITCM,), LENGTH = 0x0 + arena.DTCM (RW) : ORIGIN = AFTER(DTCM,), LENGTH = 0x0 + binary.MODULE_FILES (RW) : ORIGIN = 0x0, LENGTH = 0x0 > component.files + check.ITCM (RWX) : ORIGIN = 0x0, LENGTH = 0x08000 > itcm.check + check.DTCM (RW) : ORIGIN = 0x0, LENGTH = 0x04000 > dtcm.check +} + +FORCE_ACTIVE +{ + SVC_SoftReset +} + +KEEP_SECTION +{ + .sinit +} + +SECTIONS +{ + ############################ STATIC ################################# + .: + { + ALIGNALL(4); . = ALIGN(32); # Fit to cache line + + + + # + # TEXT BLOCK: READ ONLY + # + SDK_STATIC_START =.; + SDK_STATIC_TEXT_START =.; + #:::::::::: text/rodata + crt0.o (.text) + libsyscall.a (.text) + crt0.o (.rodata) + # + # .version ZNVljĂ܂B + # ̃ZNVɊ܂܂̓bg`FbN̍ۂ + # KvƂȂ܂̂ŁAK̈ʒuɎc悤ɂĉB + # + * (.version) + OBJECT(TwlMain,*) + + + + + + + . = ALIGN(4); + * (.exception) + . = ALIGN(4); + SDK_STATIC_ETABLE_START =.; + EXCEPTION + SDK_STATIC_ETABLE_END =.; + . = ALIGN(4); + + + + + + + . = ALIGN(4); + + + + + + + . = ALIGN(4); + + SDK_STATIC_SINIT_START =.; + #:::::::::: ctor + + + + + + + + + + + + + WRITEW 0; + #:::::::::: ctor + SDK_STATIC_SINIT_END =.; + + #:::::::::: text/rodata + . = ALIGN(32); + SDK_STATIC_TEXT_END =.; + + # + # DATA BLOCK: READ WRITE + # + SDK_STATIC_DATA_START =.; + #:::::::::: data + + + + + + + . = ALIGN(4); + + + + + + + . = ALIGN(4); + SDK_OVERLAY_DIGEST =.; + # NO DIGEST + SDK_OVERLAY_DIGEST_END =.; + #:::::::::: data + . = ALIGN(32); + SDK_STATIC_DATA_END =.; + SDK_STATIC_END =.; + + SDK_STATIC_TEXT_SIZE = SDK_STATIC_TEXT_END - SDK_STATIC_TEXT_START; + SDK_STATIC_DATA_SIZE = SDK_STATIC_DATA_END - SDK_STATIC_DATA_START; + SDK_STATIC_SIZE = SDK_STATIC_END - SDK_STATIC_START; + __sinit__ = SDK_STATIC_SINIT_START; # for static initializer + __exception_table_start__ = SDK_STATIC_ETABLE_START; # for exception table + __exception_table_end__ = SDK_STATIC_ETABLE_END; # for exception table + } > + + ..bss: + { + ALIGNALL(4); . = ALIGN(32); + + + + # + # BSS BLOCK + # + SDK_STATIC_BSS_START =.; + #:::::::::: bss + + + + + + + . = ALIGN(4); + + + + + + + . = ALIGN(4); + #:::::::::: bss + . = ALIGN(32); + SDK_STATIC_BSS_END = .; + SDK_STATIC_BSS_SIZE = SDK_STATIC_BSS_END - SDK_STATIC_BSS_START; + + } >> + + + ############################ AUTOLOADS ############################## + SDK_AUTOLOAD.ITCM.START = 0x01ff8000; + SDK_AUTOLOAD.ITCM.END = SDK_AUTOLOAD.ITCM.START; + SDK_AUTOLOAD.ITCM.BSS_END = SDK_AUTOLOAD.ITCM.START; + SDK_AUTOLOAD.ITCM.SIZE = 0; + SDK_AUTOLOAD.ITCM.BSS_SIZE = 0; + SDK_AUTOLOAD.DTCM.START = 0x027e0000; + SDK_AUTOLOAD.DTCM.END = SDK_AUTOLOAD.DTCM.START; + SDK_AUTOLOAD.DTCM.BSS_END = SDK_AUTOLOAD.DTCM.START; + SDK_AUTOLOAD.DTCM.SIZE = 0; + SDK_AUTOLOAD.DTCM.BSS_SIZE = 0; + SDK_AUTOLOAD_START = SDK_STATIC_END; + SDK_AUTOLOAD_SIZE = 0; + SDK_AUTOLOAD_NUMBER = ; + + + .: + { + ALIGNALL(4); . = ALIGN(32); + + + + # + # TEXT BLOCK: READ ONLY + # + SDK_AUTOLOAD__ID =; + SDK_AUTOLOAD..ID =; + SDK_AUTOLOAD..START =.; + SDK_AUTOLOAD..TEXT_START =.; + #:::::::::: text/rodata + + + + + + + . = ALIGN(4); + + + + + + + . = ALIGN(4); + + + + + + + . = ALIGN(4); + #:::::::::: text/rodata + SDK_AUTOLOAD..TEXT_END =.; + + # + # DATA BLOCK: READ WRITE BLOCK + # + SDK_AUTOLOAD..DATA_START =.; + #:::::::::: data + + + + + + + . = ALIGN(4); + + + + + + + . = ALIGN(4); + + + + + + + . = ALIGN(4); + #:::::::::: data + . = ALIGN(32); + SDK_AUTOLOAD..DATA_END =.; + SDK_AUTOLOAD..END =.; + + SDK_AUTOLOAD..TEXT_SIZE = SDK_AUTOLOAD..TEXT_END - SDK_AUTOLOAD..TEXT_START; + SDK_AUTOLOAD..DATA_SIZE = SDK_AUTOLOAD..DATA_END - SDK_AUTOLOAD..DATA_START; + SDK_AUTOLOAD..SIZE = SDK_AUTOLOAD..END - SDK_AUTOLOAD..START; + SDK_AUTOLOAD_SIZE = SDK_AUTOLOAD_SIZE + SDK_AUTOLOAD..SIZE; + + } > + + ..bss: + { + ALIGNALL(4); . = ALIGN(32); + + + + # + # BSS BLOCK + # + SDK_AUTOLOAD..BSS_START = .; + #:::::::::: bss + + + + + + + . = ALIGN(4); + + + + + + + . = ALIGN(4); + + + + + + + . = ALIGN(4); + + + + + + + . = ALIGN(4); + #:::::::::: bss + . = ALIGN(32); + SDK_AUTOLOAD..BSS_END = .; + + SDK_AUTOLOAD..BSS_SIZE = SDK_AUTOLOAD..BSS_END - SDK_AUTOLOAD..BSS_START; + + } >> + + + + SDK_AUTOLOAD_ITCM_START = SDK_AUTOLOAD.ITCM.START; + SDK_AUTOLOAD_ITCM_END = SDK_AUTOLOAD.ITCM.END; + SDK_AUTOLOAD_ITCM_BSS_END = SDK_AUTOLOAD.ITCM.BSS_END; + SDK_AUTOLOAD_ITCM_SIZE = SDK_AUTOLOAD.ITCM.SIZE; + SDK_AUTOLOAD_ITCM_BSS_SIZE = SDK_AUTOLOAD.ITCM.BSS_SIZE; + SDK_AUTOLOAD_DTCM_START = SDK_AUTOLOAD.DTCM.START; + SDK_AUTOLOAD_DTCM_END = SDK_AUTOLOAD.DTCM.END; + SDK_AUTOLOAD_DTCM_BSS_END = SDK_AUTOLOAD.DTCM.BSS_END; + SDK_AUTOLOAD_DTCM_SIZE = SDK_AUTOLOAD.DTCM.SIZE; + SDK_AUTOLOAD_DTCM_BSS_SIZE = SDK_AUTOLOAD.DTCM.BSS_SIZE; + + ############################ AUTOLOAD_INFO ########################## + .binary.AUTOLOAD_INFO: + { + SDK_AUTOLOAD_LIST = .; + + WRITEW ADDR(.); + WRITEW SDK_AUTOLOAD..SIZE; + WRITEW SDK_AUTOLOAD..BSS_SIZE; + + SDK_AUTOLOAD_LIST_END = .; + } >> # > binary.AUTOLOAD_INFO + +# SDK_AUTOLOAD_LIST = SDK_AUTOLOAD_START + SDK_AUTOLOAD_SIZE; +# SDK_AUTOLOAD_LIST_END = SDK_AUTOLOAD_START + SDK_AUTOLOAD_SIZE + SIZEOF(.binary.AUTOLOAD_INFO); + SDK_AUTOLOAD_SIZE = SDK_AUTOLOAD_SIZE + SIZEOF(.binary.AUTOLOAD_INFO); + + ############################ STATIC_FOOTER ########################## + .binary.STATIC_FOOTER: + { + WRITEW 0xdec00621; # LE(0x2106C0DE) = NITRO CODE + WRITEW _start_ModuleParams - ADDR(.); + WRITEW 0; # NO DIGEST + } >> # > binary.STATIC_FOOTER + + ############################ OVERLAYS ############################### + SDK_OVERLAY_NUMBER = ; + + + .: + { + ALIGNALL(4); . = ALIGN(32); + + + + # + # TEXT BLOCK: READ ONLY + # + SDK_OVERLAY__ID =; ### SEGMENT OVERLAY ID + SDK_OVERLAY..ID =; + SDK_OVERLAY..START =.; + SDK_OVERLAY..TEXT_START =.; + #:::::::::: text/rodata + + + + + + + . = ALIGN(4); + + + + + + + . = ALIGN(4); + + + + + + + . = ALIGN(4); + SDK_OVERLAY..SINIT_START =.; + #:::::::::: ctor + + + + + + + + + + + + + WRITEW 0; + #:::::::::: ctor + SDK_OVERLAY..SINIT_END =.; + + #:::::::::: text/rodata + . = ALIGN(32); + SDK_OVERLAY..TEXT_END =.; + + # + # DATA BLOCK: READ WRITE + # + SDK_OVERLAY..DATA_START =.; + #:::::::::: data + + + + + + + . = ALIGN(4); + + + + + + + . = ALIGN(4); + #:::::::::: data + . = ALIGN(32); + SDK_OVERLAY..DATA_END =.; + SDK_OVERLAY..END =.; + + SDK_OVERLAY..TEXT_SIZE = SDK_OVERLAY..TEXT_END - SDK_OVERLAY..TEXT_START; + SDK_OVERLAY..DATA_SIZE = SDK_OVERLAY..DATA_END - SDK_OVERLAY..DATA_START; + SDK_OVERLAY..SIZE = SDK_OVERLAY..END - SDK_OVERLAY..START; + + } > + + ..bss: + { + ALIGNALL(4); . = ALIGN(32); + + + + # + # BSS BLOCK + # + SDK_OVERLAY..BSS_START = .; + #:::::::::: bss + + + + + + + . = ALIGN(4); + + + + + + + . = ALIGN(4); + #:::::::::: bss + . = ALIGN(32); + SDK_OVERLAY..BSS_END = .; + + SDK_OVERLAY..BSS_SIZE = SDK_OVERLAY..BSS_END - SDK_OVERLAY..BSS_START; + + } >> + + + + ############################ MAIN EX ################################## + # MAIN EX Area + .dummy.MAIN_EX: + { + . = ALIGN(32); + } > dummy.MAIN_EX + + ############################ ARENA ################################## + .arena.MAIN: + { + . = ALIGN(32); + SDK_SECTION_ARENA_START =.; + } > arena.MAIN + + .arena.MAIN_EX: + { + . = ALIGN(32); + SDK_SECTION_ARENA_EX_START =.; + } > arena.MAIN_EX + + .arena.ITCM: + { + . = ALIGN(32); + SDK_SECTION_ARENA_ITCM_START =.; + } > arena.ITCM + + .arena.DTCM: + { + . = ALIGN(32); + SDK_SECTION_ARENA_DTCM_START =.; + } > arena.DTCM + + ############################ OVERLAYDEFS ############################ + .: + { + ### module information + WRITEW ADDR(.); # load address + WRITEW _start; # entry address + WRITEW SDK_STATIC_SIZE + SDK_AUTOLOAD_SIZE; # size of module + WRITEW _start_AutoloadDoneCallback; # callback autoload done + + ### overlay filename + + WRITES (""); # Overlay + + + } > + + + ############################ OVERLAYTABLE ########################### + .: + { + + # Overlay + WRITEW ; # overlay ID + WRITEW ADDR(.); # load address + WRITEW SDK_OVERLAY..SIZE; # size of module + WRITEW SDK_OVERLAY..BSS_SIZE; # size of bss + WRITEW SDK_OVERLAY..SINIT_START; # start address of static init + WRITEW SDK_OVERLAY..SINIT_END; # end address of static init + WRITEW ; # ROM file ID + WRITEW 0; # Reserved + + + + } > + + + ############################ OTHERS ################################# + SDK_MAIN_ARENA_LO = SDK_SECTION_ARENA_START; + SDK_IRQ_STACKSIZE = ; # allocated in DTCM + SDK_SYS_STACKSIZE = ; # when 0 means all remains of DTCM + + # Module filelist + .binary.MODULE_FILES: + { + WRITES (""); + WRITES (""); + WRITES (""); + } > binary.MODULE_FILES + + # ITCM/DTCM size checker => check AUTOLOAD_ITCM/DTCM + .check.ITCM: + { + . = . + SDK_AUTOLOAD_ITCM_SIZE + SDK_AUTOLOAD_ITCM_BSS_SIZE; + } > check.ITCM + + SDK_SYS_STACKSIZE_SIGN = (SDK_SYS_STACKSIZE < 0x80000000) * 2 - 1; + .check.DTCM: + { + . = . + SDK_AUTOLOAD_DTCM_SIZE + SDK_AUTOLOAD_DTCM_BSS_SIZE; + . = . + SDK_IRQ_STACKSIZE + SDK_SYS_STACKSIZE * SDK_SYS_STACKSIZE_SIGN; + } > check.DTCM + +} diff --git a/include/firm/specfiles/ARM9-BB-NORFIRM.lsf b/include/firm/specfiles/ARM9-BB-NORFIRM.lsf new file mode 100644 index 00000000..e6488a8b --- /dev/null +++ b/include/firm/specfiles/ARM9-BB-NORFIRM.lsf @@ -0,0 +1,41 @@ +#---------------------------------------------------------------------------- +# Project: TwlFirm - include +# File: ARM9-BB-NORFIRM.lsf +# +# Copyright 2007 Nintendo. All rights reserved. +# +# These coded insructions, 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: $ +# $NoKeywords: $ +#---------------------------------------------------------------------------- +# +# TwlFirm LCF SPEC FILE +# + +Static $(TARGET_NAME) +{ + Address 0x03800000 + Object $(OBJS_STATIC) + Library $(LLIBS) $(GLIBS) $(CW_LIBS) +} + +Autoload ITCM +{ + Address 0x01ff8000 + Object * (.itcm) + Object $(OBJS_AUTOLOAD) (.text) +} + +Autoload DTCM +{ + Address 0x027e0000 + Object * (.dtcm) + Object $(OBJS_AUTOLOAD) (.data) + Object $(OBJS_AUTOLOAD) (.bss) +} + diff --git a/include/firm/specfiles/ARM9-TS-GCDFIRM.lcf.template b/include/firm/specfiles/ARM9-TS-GCDFIRM.lcf.template new file mode 100644 index 00000000..fab99dba --- /dev/null +++ b/include/firm/specfiles/ARM9-TS-GCDFIRM.lcf.template @@ -0,0 +1,589 @@ +#--------------------------------------------------------------------------- +# Project: TwlFirm - tools - makelcf +# File: ARM9-TS-NORFIRM.lcf.template +# +# 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. +# +# $Log: $ +# $NoKeywords: $ +#--------------------------------------------------------------------------- +MEMORY +{ + (RWX) : ORIGIN = , LENGTH = 0x0 # > + + (RWX) : ORIGIN = , LENGTH = 0x0 # > + +# binary.AUTOLOAD_INFO (RWX) : ORIGIN = 0, LENGTH = 0x0 > +# binary.STATIC_FOOTER (RWX) : ORIGIN = 0, LENGTH = 0x0 >> + + (RW) : ORIGIN = AFTER(), LENGTH = 0x0 > + (RW) : ORIGIN = AFTER(), LENGTH = 0x0 > + + (RWXO): ORIGIN = , LENGTH = 0x0 > + + dummy.MAIN_EX (RW) : ORIGIN = 0x023e0000, LENGTH = 0x0 + arena.MAIN (RW) : ORIGIN = AFTER(,), LENGTH = 0x0 + arena.MAIN_EX (RW) : ORIGIN = AFTER(dummy.MAIN_EX,), LENGTH = 0x0 + arena.ITCM (RW) : ORIGIN = AFTER(ITCM,), LENGTH = 0x0 + arena.DTCM (RW) : ORIGIN = AFTER(DTCM,), LENGTH = 0x0 + binary.MODULE_FILES (RW) : ORIGIN = 0x0, LENGTH = 0x0 > component.files + check.ITCM (RWX) : ORIGIN = 0x0, LENGTH = 0x08000 > itcm.check + check.DTCM (RW) : ORIGIN = 0x0, LENGTH = 0x04000 > dtcm.check +} + +FORCE_ACTIVE +{ + SVC_SoftReset +} + +KEEP_SECTION +{ + .sinit +} + +SECTIONS +{ + ############################ STATIC ################################# + .: + { + ALIGNALL(4); . = ALIGN(32); # Fit to cache line + + + + # + # TEXT BLOCK: READ ONLY + # + SDK_STATIC_START =.; + SDK_STATIC_TEXT_START =.; + #:::::::::: text/rodata + crt0.o (.text) + libsyscall.a (.text) + crt0.o (.rodata) + # + # .version ZNVljĂ܂B + # ̃ZNVɊ܂܂̓bg`FbN̍ۂ + # KvƂȂ܂̂ŁAK̈ʒuɎc悤ɂĉB + # + * (.version) + OBJECT(TwlMain,*) + + + + + + + . = ALIGN(4); + * (.exception) + . = ALIGN(4); + SDK_STATIC_ETABLE_START =.; + EXCEPTION + SDK_STATIC_ETABLE_END =.; + . = ALIGN(4); + + + + + + + . = ALIGN(4); + + + + + + + . = ALIGN(4); + + SDK_STATIC_SINIT_START =.; + #:::::::::: ctor + + + + + + + + + + + + + WRITEW 0; + #:::::::::: ctor + SDK_STATIC_SINIT_END =.; + + #:::::::::: text/rodata + . = ALIGN(32); + SDK_STATIC_TEXT_END =.; + + # + # DATA BLOCK: READ WRITE + # + SDK_STATIC_DATA_START =.; + #:::::::::: data + + + + + + + . = ALIGN(4); + + + + + + + . = ALIGN(4); + SDK_OVERLAY_DIGEST =.; + # NO DIGEST + SDK_OVERLAY_DIGEST_END =.; + #:::::::::: data + . = ALIGN(32); + SDK_STATIC_DATA_END =.; + SDK_STATIC_END =.; + + SDK_STATIC_TEXT_SIZE = SDK_STATIC_TEXT_END - SDK_STATIC_TEXT_START; + SDK_STATIC_DATA_SIZE = SDK_STATIC_DATA_END - SDK_STATIC_DATA_START; + SDK_STATIC_SIZE = SDK_STATIC_END - SDK_STATIC_START; + __sinit__ = SDK_STATIC_SINIT_START; # for static initializer + __exception_table_start__ = SDK_STATIC_ETABLE_START; # for exception table + __exception_table_end__ = SDK_STATIC_ETABLE_END; # for exception table + } > + + ..bss: + { + ALIGNALL(4); . = ALIGN(32); + + + + # + # BSS BLOCK + # + SDK_STATIC_BSS_START =.; + #:::::::::: bss + + + + + + + . = ALIGN(4); + + + + + + + . = ALIGN(4); + #:::::::::: bss + . = ALIGN(32); + SDK_STATIC_BSS_END = .; + SDK_STATIC_BSS_SIZE = SDK_STATIC_BSS_END - SDK_STATIC_BSS_START; + + } >> + + + ############################ AUTOLOADS ############################## + SDK_AUTOLOAD.ITCM.START = 0x01ff8000; + SDK_AUTOLOAD.ITCM.END = SDK_AUTOLOAD.ITCM.START; + SDK_AUTOLOAD.ITCM.BSS_END = SDK_AUTOLOAD.ITCM.START; + SDK_AUTOLOAD.ITCM.SIZE = 0; + SDK_AUTOLOAD.ITCM.BSS_SIZE = 0; + SDK_AUTOLOAD.DTCM.START = 0x027e0000; + SDK_AUTOLOAD.DTCM.END = SDK_AUTOLOAD.DTCM.START; + SDK_AUTOLOAD.DTCM.BSS_END = SDK_AUTOLOAD.DTCM.START; + SDK_AUTOLOAD.DTCM.SIZE = 0; + SDK_AUTOLOAD.DTCM.BSS_SIZE = 0; + SDK_AUTOLOAD_START = SDK_STATIC_END; + SDK_AUTOLOAD_SIZE = 0; + SDK_AUTOLOAD_NUMBER = ; + + + .: + { + ALIGNALL(4); . = ALIGN(32); + + + + # + # TEXT BLOCK: READ ONLY + # + SDK_AUTOLOAD__ID =; + SDK_AUTOLOAD..ID =; + SDK_AUTOLOAD..START =.; + SDK_AUTOLOAD..TEXT_START =.; + #:::::::::: text/rodata + + + + + + + . = ALIGN(4); + + + + + + + . = ALIGN(4); + + + + + + + . = ALIGN(4); + #:::::::::: text/rodata + SDK_AUTOLOAD..TEXT_END =.; + + # + # DATA BLOCK: READ WRITE BLOCK + # + SDK_AUTOLOAD..DATA_START =.; + #:::::::::: data + + + + + + + . = ALIGN(4); + + + + + + + . = ALIGN(4); + + + + + + + . = ALIGN(4); + #:::::::::: data + . = ALIGN(32); + SDK_AUTOLOAD..DATA_END =.; + SDK_AUTOLOAD..END =.; + + SDK_AUTOLOAD..TEXT_SIZE = SDK_AUTOLOAD..TEXT_END - SDK_AUTOLOAD..TEXT_START; + SDK_AUTOLOAD..DATA_SIZE = SDK_AUTOLOAD..DATA_END - SDK_AUTOLOAD..DATA_START; + SDK_AUTOLOAD..SIZE = SDK_AUTOLOAD..END - SDK_AUTOLOAD..START; + SDK_AUTOLOAD_SIZE = SDK_AUTOLOAD_SIZE + SDK_AUTOLOAD..SIZE; + + } > + + ..bss: + { + ALIGNALL(4); . = ALIGN(32); + + + + # + # BSS BLOCK + # + SDK_AUTOLOAD..BSS_START = .; + #:::::::::: bss + + + + + + + . = ALIGN(4); + + + + + + + . = ALIGN(4); + + + + + + + . = ALIGN(4); + + + + + + + . = ALIGN(4); + #:::::::::: bss + . = ALIGN(32); + SDK_AUTOLOAD..BSS_END = .; + + SDK_AUTOLOAD..BSS_SIZE = SDK_AUTOLOAD..BSS_END - SDK_AUTOLOAD..BSS_START; + + } >> + + + + SDK_AUTOLOAD_ITCM_START = SDK_AUTOLOAD.ITCM.START; + SDK_AUTOLOAD_ITCM_END = SDK_AUTOLOAD.ITCM.END; + SDK_AUTOLOAD_ITCM_BSS_END = SDK_AUTOLOAD.ITCM.BSS_END; + SDK_AUTOLOAD_ITCM_SIZE = SDK_AUTOLOAD.ITCM.SIZE; + SDK_AUTOLOAD_ITCM_BSS_SIZE = SDK_AUTOLOAD.ITCM.BSS_SIZE; + SDK_AUTOLOAD_DTCM_START = SDK_AUTOLOAD.DTCM.START; + SDK_AUTOLOAD_DTCM_END = SDK_AUTOLOAD.DTCM.END; + SDK_AUTOLOAD_DTCM_BSS_END = SDK_AUTOLOAD.DTCM.BSS_END; + SDK_AUTOLOAD_DTCM_SIZE = SDK_AUTOLOAD.DTCM.SIZE; + SDK_AUTOLOAD_DTCM_BSS_SIZE = SDK_AUTOLOAD.DTCM.BSS_SIZE; + + ############################ AUTOLOAD_INFO ########################## + .binary.AUTOLOAD_INFO: + { + SDK_AUTOLOAD_LIST = .; + + WRITEW ADDR(.); + WRITEW SDK_AUTOLOAD..SIZE; + WRITEW SDK_AUTOLOAD..BSS_SIZE; + + SDK_AUTOLOAD_LIST_END = .; + } >> # > binary.AUTOLOAD_INFO + +# SDK_AUTOLOAD_LIST = SDK_AUTOLOAD_START + SDK_AUTOLOAD_SIZE; +# SDK_AUTOLOAD_LIST_END = SDK_AUTOLOAD_START + SDK_AUTOLOAD_SIZE + SIZEOF(.binary.AUTOLOAD_INFO); + SDK_AUTOLOAD_SIZE = SDK_AUTOLOAD_SIZE + SIZEOF(.binary.AUTOLOAD_INFO); + + ############################ STATIC_FOOTER ########################## + .binary.STATIC_FOOTER: + { + WRITEW 0xdec00621; # LE(0x2106C0DE) = NITRO CODE + WRITEW _start_ModuleParams - ADDR(.); + WRITEW 0; # NO DIGEST + } >> # > binary.STATIC_FOOTER + + ############################ OVERLAYS ############################### + SDK_OVERLAY_NUMBER = ; + + + .: + { + ALIGNALL(4); . = ALIGN(32); + + + + # + # TEXT BLOCK: READ ONLY + # + SDK_OVERLAY__ID =; ### SEGMENT OVERLAY ID + SDK_OVERLAY..ID =; + SDK_OVERLAY..START =.; + SDK_OVERLAY..TEXT_START =.; + #:::::::::: text/rodata + + + + + + + . = ALIGN(4); + + + + + + + . = ALIGN(4); + + + + + + + . = ALIGN(4); + SDK_OVERLAY..SINIT_START =.; + #:::::::::: ctor + + + + + + + + + + + + + WRITEW 0; + #:::::::::: ctor + SDK_OVERLAY..SINIT_END =.; + + #:::::::::: text/rodata + . = ALIGN(32); + SDK_OVERLAY..TEXT_END =.; + + # + # DATA BLOCK: READ WRITE + # + SDK_OVERLAY..DATA_START =.; + #:::::::::: data + + + + + + + . = ALIGN(4); + + + + + + + . = ALIGN(4); + #:::::::::: data + . = ALIGN(32); + SDK_OVERLAY..DATA_END =.; + SDK_OVERLAY..END =.; + + SDK_OVERLAY..TEXT_SIZE = SDK_OVERLAY..TEXT_END - SDK_OVERLAY..TEXT_START; + SDK_OVERLAY..DATA_SIZE = SDK_OVERLAY..DATA_END - SDK_OVERLAY..DATA_START; + SDK_OVERLAY..SIZE = SDK_OVERLAY..END - SDK_OVERLAY..START; + + } > + + ..bss: + { + ALIGNALL(4); . = ALIGN(32); + + + + # + # BSS BLOCK + # + SDK_OVERLAY..BSS_START = .; + #:::::::::: bss + + + + + + + . = ALIGN(4); + + + + + + + . = ALIGN(4); + #:::::::::: bss + . = ALIGN(32); + SDK_OVERLAY..BSS_END = .; + + SDK_OVERLAY..BSS_SIZE = SDK_OVERLAY..BSS_END - SDK_OVERLAY..BSS_START; + + } >> + + + + ############################ MAIN EX ################################## + # MAIN EX Area + .dummy.MAIN_EX: + { + . = ALIGN(32); + } > dummy.MAIN_EX + + ############################ ARENA ################################## + .arena.MAIN: + { + . = ALIGN(32); + SDK_SECTION_ARENA_START =.; + } > arena.MAIN + + .arena.MAIN_EX: + { + . = ALIGN(32); + SDK_SECTION_ARENA_EX_START =.; + } > arena.MAIN_EX + + .arena.ITCM: + { + . = ALIGN(32); + SDK_SECTION_ARENA_ITCM_START =.; + } > arena.ITCM + + .arena.DTCM: + { + . = ALIGN(32); + SDK_SECTION_ARENA_DTCM_START =.; + } > arena.DTCM + + ############################ OVERLAYDEFS ############################ + .: + { + ### module information + WRITEW ADDR(.); # load address + WRITEW _start; # entry address + WRITEW SDK_STATIC_SIZE + SDK_AUTOLOAD_SIZE; # size of module + WRITEW _start_AutoloadDoneCallback; # callback autoload done + + ### overlay filename + + WRITES (""); # Overlay + + + } > + + + ############################ OVERLAYTABLE ########################### + .: + { + + # Overlay + WRITEW ; # overlay ID + WRITEW ADDR(.); # load address + WRITEW SDK_OVERLAY..SIZE; # size of module + WRITEW SDK_OVERLAY..BSS_SIZE; # size of bss + WRITEW SDK_OVERLAY..SINIT_START; # start address of static init + WRITEW SDK_OVERLAY..SINIT_END; # end address of static init + WRITEW ; # ROM file ID + WRITEW 0; # Reserved + + + + } > + + + ############################ OTHERS ################################# + SDK_MAIN_ARENA_LO = SDK_SECTION_ARENA_START; + SDK_IRQ_STACKSIZE = ; # allocated in DTCM + SDK_SYS_STACKSIZE = ; # when 0 means all remains of DTCM + + # Module filelist + .binary.MODULE_FILES: + { + WRITES (""); + WRITES (""); + WRITES (""); + } > binary.MODULE_FILES + + # ITCM/DTCM size checker => check AUTOLOAD_ITCM/DTCM + .check.ITCM: + { + . = . + SDK_AUTOLOAD_ITCM_SIZE + SDK_AUTOLOAD_ITCM_BSS_SIZE; + } > check.ITCM + + SDK_SYS_STACKSIZE_SIGN = (SDK_SYS_STACKSIZE < 0x80000000) * 2 - 1; + .check.DTCM: + { + . = . + SDK_AUTOLOAD_DTCM_SIZE + SDK_AUTOLOAD_DTCM_BSS_SIZE; + . = . + SDK_IRQ_STACKSIZE + SDK_SYS_STACKSIZE * SDK_SYS_STACKSIZE_SIGN; + } > check.DTCM + +} diff --git a/include/firm/specfiles/ARM9-TS-GCDFIRM.lsf b/include/firm/specfiles/ARM9-TS-GCDFIRM.lsf new file mode 100644 index 00000000..05d913a8 --- /dev/null +++ b/include/firm/specfiles/ARM9-TS-GCDFIRM.lsf @@ -0,0 +1,41 @@ +#---------------------------------------------------------------------------- +# Project: TwlFirm - include +# File: ARM9-TS-NORFIRM.lsf +# +# Copyright 2007 Nintendo. All rights reserved. +# +# These coded insructions, 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: $ +# $NoKeywords: $ +#---------------------------------------------------------------------------- +# +# TwlFirm LCF SPEC FILE +# + +Static $(TARGET_NAME) +{ + Address 0x03800000 + Object $(OBJS_STATIC) + Library $(LLIBS) $(GLIBS) $(CW_LIBS) +} + +Autoload ITCM +{ + Address 0x01ff8000 + Object * (.itcm) + Object $(OBJS_AUTOLOAD) (.text) +} + +Autoload DTCM +{ + Address 0x027e0000 + Object * (.dtcm) + Object $(OBJS_AUTOLOAD) (.data) + Object $(OBJS_AUTOLOAD) (.bss) +} + diff --git a/include/firm/specfiles/ARM9-TS-NORFIRM.lcf.template b/include/firm/specfiles/ARM9-TS-NORFIRM.lcf.template new file mode 100644 index 00000000..fab99dba --- /dev/null +++ b/include/firm/specfiles/ARM9-TS-NORFIRM.lcf.template @@ -0,0 +1,589 @@ +#--------------------------------------------------------------------------- +# Project: TwlFirm - tools - makelcf +# File: ARM9-TS-NORFIRM.lcf.template +# +# 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. +# +# $Log: $ +# $NoKeywords: $ +#--------------------------------------------------------------------------- +MEMORY +{ + (RWX) : ORIGIN = , LENGTH = 0x0 # > + + (RWX) : ORIGIN = , LENGTH = 0x0 # > + +# binary.AUTOLOAD_INFO (RWX) : ORIGIN = 0, LENGTH = 0x0 > +# binary.STATIC_FOOTER (RWX) : ORIGIN = 0, LENGTH = 0x0 >> + + (RW) : ORIGIN = AFTER(), LENGTH = 0x0 > + (RW) : ORIGIN = AFTER(), LENGTH = 0x0 > + + (RWXO): ORIGIN = , LENGTH = 0x0 > + + dummy.MAIN_EX (RW) : ORIGIN = 0x023e0000, LENGTH = 0x0 + arena.MAIN (RW) : ORIGIN = AFTER(,), LENGTH = 0x0 + arena.MAIN_EX (RW) : ORIGIN = AFTER(dummy.MAIN_EX,), LENGTH = 0x0 + arena.ITCM (RW) : ORIGIN = AFTER(ITCM,), LENGTH = 0x0 + arena.DTCM (RW) : ORIGIN = AFTER(DTCM,), LENGTH = 0x0 + binary.MODULE_FILES (RW) : ORIGIN = 0x0, LENGTH = 0x0 > component.files + check.ITCM (RWX) : ORIGIN = 0x0, LENGTH = 0x08000 > itcm.check + check.DTCM (RW) : ORIGIN = 0x0, LENGTH = 0x04000 > dtcm.check +} + +FORCE_ACTIVE +{ + SVC_SoftReset +} + +KEEP_SECTION +{ + .sinit +} + +SECTIONS +{ + ############################ STATIC ################################# + .: + { + ALIGNALL(4); . = ALIGN(32); # Fit to cache line + + + + # + # TEXT BLOCK: READ ONLY + # + SDK_STATIC_START =.; + SDK_STATIC_TEXT_START =.; + #:::::::::: text/rodata + crt0.o (.text) + libsyscall.a (.text) + crt0.o (.rodata) + # + # .version ZNVljĂ܂B + # ̃ZNVɊ܂܂̓bg`FbN̍ۂ + # KvƂȂ܂̂ŁAK̈ʒuɎc悤ɂĉB + # + * (.version) + OBJECT(TwlMain,*) + + + + + + + . = ALIGN(4); + * (.exception) + . = ALIGN(4); + SDK_STATIC_ETABLE_START =.; + EXCEPTION + SDK_STATIC_ETABLE_END =.; + . = ALIGN(4); + + + + + + + . = ALIGN(4); + + + + + + + . = ALIGN(4); + + SDK_STATIC_SINIT_START =.; + #:::::::::: ctor + + + + + + + + + + + + + WRITEW 0; + #:::::::::: ctor + SDK_STATIC_SINIT_END =.; + + #:::::::::: text/rodata + . = ALIGN(32); + SDK_STATIC_TEXT_END =.; + + # + # DATA BLOCK: READ WRITE + # + SDK_STATIC_DATA_START =.; + #:::::::::: data + + + + + + + . = ALIGN(4); + + + + + + + . = ALIGN(4); + SDK_OVERLAY_DIGEST =.; + # NO DIGEST + SDK_OVERLAY_DIGEST_END =.; + #:::::::::: data + . = ALIGN(32); + SDK_STATIC_DATA_END =.; + SDK_STATIC_END =.; + + SDK_STATIC_TEXT_SIZE = SDK_STATIC_TEXT_END - SDK_STATIC_TEXT_START; + SDK_STATIC_DATA_SIZE = SDK_STATIC_DATA_END - SDK_STATIC_DATA_START; + SDK_STATIC_SIZE = SDK_STATIC_END - SDK_STATIC_START; + __sinit__ = SDK_STATIC_SINIT_START; # for static initializer + __exception_table_start__ = SDK_STATIC_ETABLE_START; # for exception table + __exception_table_end__ = SDK_STATIC_ETABLE_END; # for exception table + } > + + ..bss: + { + ALIGNALL(4); . = ALIGN(32); + + + + # + # BSS BLOCK + # + SDK_STATIC_BSS_START =.; + #:::::::::: bss + + + + + + + . = ALIGN(4); + + + + + + + . = ALIGN(4); + #:::::::::: bss + . = ALIGN(32); + SDK_STATIC_BSS_END = .; + SDK_STATIC_BSS_SIZE = SDK_STATIC_BSS_END - SDK_STATIC_BSS_START; + + } >> + + + ############################ AUTOLOADS ############################## + SDK_AUTOLOAD.ITCM.START = 0x01ff8000; + SDK_AUTOLOAD.ITCM.END = SDK_AUTOLOAD.ITCM.START; + SDK_AUTOLOAD.ITCM.BSS_END = SDK_AUTOLOAD.ITCM.START; + SDK_AUTOLOAD.ITCM.SIZE = 0; + SDK_AUTOLOAD.ITCM.BSS_SIZE = 0; + SDK_AUTOLOAD.DTCM.START = 0x027e0000; + SDK_AUTOLOAD.DTCM.END = SDK_AUTOLOAD.DTCM.START; + SDK_AUTOLOAD.DTCM.BSS_END = SDK_AUTOLOAD.DTCM.START; + SDK_AUTOLOAD.DTCM.SIZE = 0; + SDK_AUTOLOAD.DTCM.BSS_SIZE = 0; + SDK_AUTOLOAD_START = SDK_STATIC_END; + SDK_AUTOLOAD_SIZE = 0; + SDK_AUTOLOAD_NUMBER = ; + + + .: + { + ALIGNALL(4); . = ALIGN(32); + + + + # + # TEXT BLOCK: READ ONLY + # + SDK_AUTOLOAD__ID =; + SDK_AUTOLOAD..ID =; + SDK_AUTOLOAD..START =.; + SDK_AUTOLOAD..TEXT_START =.; + #:::::::::: text/rodata + + + + + + + . = ALIGN(4); + + + + + + + . = ALIGN(4); + + + + + + + . = ALIGN(4); + #:::::::::: text/rodata + SDK_AUTOLOAD..TEXT_END =.; + + # + # DATA BLOCK: READ WRITE BLOCK + # + SDK_AUTOLOAD..DATA_START =.; + #:::::::::: data + + + + + + + . = ALIGN(4); + + + + + + + . = ALIGN(4); + + + + + + + . = ALIGN(4); + #:::::::::: data + . = ALIGN(32); + SDK_AUTOLOAD..DATA_END =.; + SDK_AUTOLOAD..END =.; + + SDK_AUTOLOAD..TEXT_SIZE = SDK_AUTOLOAD..TEXT_END - SDK_AUTOLOAD..TEXT_START; + SDK_AUTOLOAD..DATA_SIZE = SDK_AUTOLOAD..DATA_END - SDK_AUTOLOAD..DATA_START; + SDK_AUTOLOAD..SIZE = SDK_AUTOLOAD..END - SDK_AUTOLOAD..START; + SDK_AUTOLOAD_SIZE = SDK_AUTOLOAD_SIZE + SDK_AUTOLOAD..SIZE; + + } > + + ..bss: + { + ALIGNALL(4); . = ALIGN(32); + + + + # + # BSS BLOCK + # + SDK_AUTOLOAD..BSS_START = .; + #:::::::::: bss + + + + + + + . = ALIGN(4); + + + + + + + . = ALIGN(4); + + + + + + + . = ALIGN(4); + + + + + + + . = ALIGN(4); + #:::::::::: bss + . = ALIGN(32); + SDK_AUTOLOAD..BSS_END = .; + + SDK_AUTOLOAD..BSS_SIZE = SDK_AUTOLOAD..BSS_END - SDK_AUTOLOAD..BSS_START; + + } >> + + + + SDK_AUTOLOAD_ITCM_START = SDK_AUTOLOAD.ITCM.START; + SDK_AUTOLOAD_ITCM_END = SDK_AUTOLOAD.ITCM.END; + SDK_AUTOLOAD_ITCM_BSS_END = SDK_AUTOLOAD.ITCM.BSS_END; + SDK_AUTOLOAD_ITCM_SIZE = SDK_AUTOLOAD.ITCM.SIZE; + SDK_AUTOLOAD_ITCM_BSS_SIZE = SDK_AUTOLOAD.ITCM.BSS_SIZE; + SDK_AUTOLOAD_DTCM_START = SDK_AUTOLOAD.DTCM.START; + SDK_AUTOLOAD_DTCM_END = SDK_AUTOLOAD.DTCM.END; + SDK_AUTOLOAD_DTCM_BSS_END = SDK_AUTOLOAD.DTCM.BSS_END; + SDK_AUTOLOAD_DTCM_SIZE = SDK_AUTOLOAD.DTCM.SIZE; + SDK_AUTOLOAD_DTCM_BSS_SIZE = SDK_AUTOLOAD.DTCM.BSS_SIZE; + + ############################ AUTOLOAD_INFO ########################## + .binary.AUTOLOAD_INFO: + { + SDK_AUTOLOAD_LIST = .; + + WRITEW ADDR(.); + WRITEW SDK_AUTOLOAD..SIZE; + WRITEW SDK_AUTOLOAD..BSS_SIZE; + + SDK_AUTOLOAD_LIST_END = .; + } >> # > binary.AUTOLOAD_INFO + +# SDK_AUTOLOAD_LIST = SDK_AUTOLOAD_START + SDK_AUTOLOAD_SIZE; +# SDK_AUTOLOAD_LIST_END = SDK_AUTOLOAD_START + SDK_AUTOLOAD_SIZE + SIZEOF(.binary.AUTOLOAD_INFO); + SDK_AUTOLOAD_SIZE = SDK_AUTOLOAD_SIZE + SIZEOF(.binary.AUTOLOAD_INFO); + + ############################ STATIC_FOOTER ########################## + .binary.STATIC_FOOTER: + { + WRITEW 0xdec00621; # LE(0x2106C0DE) = NITRO CODE + WRITEW _start_ModuleParams - ADDR(.); + WRITEW 0; # NO DIGEST + } >> # > binary.STATIC_FOOTER + + ############################ OVERLAYS ############################### + SDK_OVERLAY_NUMBER = ; + + + .: + { + ALIGNALL(4); . = ALIGN(32); + + + + # + # TEXT BLOCK: READ ONLY + # + SDK_OVERLAY__ID =; ### SEGMENT OVERLAY ID + SDK_OVERLAY..ID =; + SDK_OVERLAY..START =.; + SDK_OVERLAY..TEXT_START =.; + #:::::::::: text/rodata + + + + + + + . = ALIGN(4); + + + + + + + . = ALIGN(4); + + + + + + + . = ALIGN(4); + SDK_OVERLAY..SINIT_START =.; + #:::::::::: ctor + + + + + + + + + + + + + WRITEW 0; + #:::::::::: ctor + SDK_OVERLAY..SINIT_END =.; + + #:::::::::: text/rodata + . = ALIGN(32); + SDK_OVERLAY..TEXT_END =.; + + # + # DATA BLOCK: READ WRITE + # + SDK_OVERLAY..DATA_START =.; + #:::::::::: data + + + + + + + . = ALIGN(4); + + + + + + + . = ALIGN(4); + #:::::::::: data + . = ALIGN(32); + SDK_OVERLAY..DATA_END =.; + SDK_OVERLAY..END =.; + + SDK_OVERLAY..TEXT_SIZE = SDK_OVERLAY..TEXT_END - SDK_OVERLAY..TEXT_START; + SDK_OVERLAY..DATA_SIZE = SDK_OVERLAY..DATA_END - SDK_OVERLAY..DATA_START; + SDK_OVERLAY..SIZE = SDK_OVERLAY..END - SDK_OVERLAY..START; + + } > + + ..bss: + { + ALIGNALL(4); . = ALIGN(32); + + + + # + # BSS BLOCK + # + SDK_OVERLAY..BSS_START = .; + #:::::::::: bss + + + + + + + . = ALIGN(4); + + + + + + + . = ALIGN(4); + #:::::::::: bss + . = ALIGN(32); + SDK_OVERLAY..BSS_END = .; + + SDK_OVERLAY..BSS_SIZE = SDK_OVERLAY..BSS_END - SDK_OVERLAY..BSS_START; + + } >> + + + + ############################ MAIN EX ################################## + # MAIN EX Area + .dummy.MAIN_EX: + { + . = ALIGN(32); + } > dummy.MAIN_EX + + ############################ ARENA ################################## + .arena.MAIN: + { + . = ALIGN(32); + SDK_SECTION_ARENA_START =.; + } > arena.MAIN + + .arena.MAIN_EX: + { + . = ALIGN(32); + SDK_SECTION_ARENA_EX_START =.; + } > arena.MAIN_EX + + .arena.ITCM: + { + . = ALIGN(32); + SDK_SECTION_ARENA_ITCM_START =.; + } > arena.ITCM + + .arena.DTCM: + { + . = ALIGN(32); + SDK_SECTION_ARENA_DTCM_START =.; + } > arena.DTCM + + ############################ OVERLAYDEFS ############################ + .: + { + ### module information + WRITEW ADDR(.); # load address + WRITEW _start; # entry address + WRITEW SDK_STATIC_SIZE + SDK_AUTOLOAD_SIZE; # size of module + WRITEW _start_AutoloadDoneCallback; # callback autoload done + + ### overlay filename + + WRITES (""); # Overlay + + + } > + + + ############################ OVERLAYTABLE ########################### + .: + { + + # Overlay + WRITEW ; # overlay ID + WRITEW ADDR(.); # load address + WRITEW SDK_OVERLAY..SIZE; # size of module + WRITEW SDK_OVERLAY..BSS_SIZE; # size of bss + WRITEW SDK_OVERLAY..SINIT_START; # start address of static init + WRITEW SDK_OVERLAY..SINIT_END; # end address of static init + WRITEW ; # ROM file ID + WRITEW 0; # Reserved + + + + } > + + + ############################ OTHERS ################################# + SDK_MAIN_ARENA_LO = SDK_SECTION_ARENA_START; + SDK_IRQ_STACKSIZE = ; # allocated in DTCM + SDK_SYS_STACKSIZE = ; # when 0 means all remains of DTCM + + # Module filelist + .binary.MODULE_FILES: + { + WRITES (""); + WRITES (""); + WRITES (""); + } > binary.MODULE_FILES + + # ITCM/DTCM size checker => check AUTOLOAD_ITCM/DTCM + .check.ITCM: + { + . = . + SDK_AUTOLOAD_ITCM_SIZE + SDK_AUTOLOAD_ITCM_BSS_SIZE; + } > check.ITCM + + SDK_SYS_STACKSIZE_SIGN = (SDK_SYS_STACKSIZE < 0x80000000) * 2 - 1; + .check.DTCM: + { + . = . + SDK_AUTOLOAD_DTCM_SIZE + SDK_AUTOLOAD_DTCM_BSS_SIZE; + . = . + SDK_IRQ_STACKSIZE + SDK_SYS_STACKSIZE * SDK_SYS_STACKSIZE_SIGN; + } > check.DTCM + +} diff --git a/include/firm/specfiles/ARM9-TS-NORFIRM.lsf b/include/firm/specfiles/ARM9-TS-NORFIRM.lsf new file mode 100644 index 00000000..05d913a8 --- /dev/null +++ b/include/firm/specfiles/ARM9-TS-NORFIRM.lsf @@ -0,0 +1,41 @@ +#---------------------------------------------------------------------------- +# Project: TwlFirm - include +# File: ARM9-TS-NORFIRM.lsf +# +# Copyright 2007 Nintendo. All rights reserved. +# +# These coded insructions, 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: $ +# $NoKeywords: $ +#---------------------------------------------------------------------------- +# +# TwlFirm LCF SPEC FILE +# + +Static $(TARGET_NAME) +{ + Address 0x03800000 + Object $(OBJS_STATIC) + Library $(LLIBS) $(GLIBS) $(CW_LIBS) +} + +Autoload ITCM +{ + Address 0x01ff8000 + Object * (.itcm) + Object $(OBJS_AUTOLOAD) (.text) +} + +Autoload DTCM +{ + Address 0x027e0000 + Object * (.dtcm) + Object $(OBJS_AUTOLOAD) (.data) + Object $(OBJS_AUTOLOAD) (.bss) +} + diff --git a/include/twl/os/common/systemCall.h b/include/twl/os/common/systemCall.h new file mode 100644 index 00000000..ed83d483 --- /dev/null +++ b/include/twl/os/common/systemCall.h @@ -0,0 +1,92 @@ +/*---------------------------------------------------------------------------* + Project: TwlSDK - OS - include + File: systemCall.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. + + $Log: $ + $NoKeywords: $ + *---------------------------------------------------------------------------*/ + +#ifndef TWL_OS_SYSTEMCALL_H_ +#define TWL_OS_SYSTEMCALL_H_ + + +#ifdef __cplusplus +extern "C" { +#endif + +int SVC_InitSignHeap( + int acmemory_pool[3], + void* heap, + unsigned int length + ); + +int SVC_DecryptoRSA( + const void* acmemory_pool, + const void* pData, + unsigned int* len // o̓TCY + ); + +int SVC_DecryptoSign( + const void* acmemory_pool, + void* buffer, // o͗̈ + const void* sgn_ptr, // f[^ւ̃|C^ + const void* key_ptr // L[ւ̃|C^ + ); + +int SVC_DecryptoSignDER( + const void* acmemory_pool, + void* buffer, // o͗̈ + const void* sgn_ptr, // f[^ւ̃|C^ + const void* key_ptr // L[ւ̃|C^ + ); + +void SVC_SHA1Init( void *c ); +void SVC_SHA1Update( void *c, const unsigned char *data, unsigned long len ); +void SVC_SHA1GetHash( unsigned char *md, void *c ); + +int SVC_CalcSHA1( + void* buffer, // o͗̈ + const void* buf, // f[^ւ̃|C^ + unsigned int len // f[^̒ + ); + +int SVC_CompareSHA1( + const void* decedHash, // SVC_Decrypto*̏o + const void* digest // SVC_GetDigest̏o + ); + +int SVC_RandomSHA1( + void* dest_ptr, // o̓f[^ւ̃|C^ + unsigned int dest_len, // o̓f[^̒ + const void* src_ptr, // ̓f[^ւ̃|C^ + unsigned int src_len // ̓f[^̒ + ); + +int SVC_UncompressLZ8FromDevice( const void* srcp, + void* destp, + const void* paramp, + const MIReadStreamCallbacks *callbacks + ); + +int SVC_UncompressLZ16FromDeviceIMG( const void* srcp, + void* destp, + const void* paramp, + const MIReadStreamCallbacks *callbacks + ); + + + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +/* TWL_OS_SYSTEMCALL_H_ */ +#endif diff --git a/tools/bin/makenorfirm.exe b/tools/bin/makenorfirm.exe new file mode 100644 index 00000000..743abd88 Binary files /dev/null and b/tools/bin/makenorfirm.exe differ diff --git a/tools/openssl/openssl.exe b/tools/openssl/openssl.exe new file mode 100644 index 00000000..8967c316 Binary files /dev/null and b/tools/openssl/openssl.exe differ