Add unedited TwlIPL commit #99.

This commit is contained in:
rmc 2023-12-16 15:41:34 -05:00
parent 4659c7136d
commit 0ca1d3e0ee
No known key found for this signature in database
GPG Key ID: 5633EC10309D77D1
452 changed files with 79054 additions and 0 deletions

BIN
.DS_Store vendored Normal file

Binary file not shown.

31
Makefile Normal file
View File

@ -0,0 +1,31 @@
#! make -f
#----------------------------------------------------------------------------
# Project: TwlFirm - build
# File: Makefile
#
# Copyright 2007 Nintendo. All rights reserved.
#
# These coded instructions, statements, and computer programs contain
# proprietary information of Nintendo of America Inc. and/or Nintendo
# Company Ltd., and are protected by Federal copyright law. They may
# not be disclosed to third parties or copied or duplicated in any form,
# in whole or in part, without the prior written consent of Nintendo.
#
# $Date:: $
# $Rev:$
# $Author:$
#----------------------------------------------------------------------------
include $(TWLIPL_ROOT)/build/buildtools/commondefs
#----------------------------------------------------------------------------
SUBDIRS = build
#----------------------------------------------------------------------------
include $(TWLIPL_ROOT)/build/buildtools/modulerules
#===== End of Makefile =====

Binary file not shown.

View File

@ -0,0 +1,25 @@
---------------
このパッチは暫定的ながら NitroSystem を
TWL-SDK 上でビルド/使用できるようにするものです。
添付の zip ファイルを展開し既存の NitroSystem に上書きしてください。
注意
・TWLSYSTEM_ROOT 環境変数に NITROSYSTEM_ROOT 環境変数と
 同じ値を設定する必要があります。
・NitroSystem はビルドしなおす必要があります。
・snd, mcs ライブラリは使用できません。
・demo はそのままではビルドできません。
 TWL-SDK では nef が tef へ変更されたため
 TARGET_NEF が設定されているものは削除する必要があります。
----
demoのビルドを通す方法
LLIBRARY_DIRS = $(G2D_DEMOLIB)/lib/$(NITRO_BUILDTYPE)
LLIBRARY_DIRS = $(G2D_DEMOLIB)/$(LIBDIR)
TARGET_NEF = main.nef を削除。

BIN
build/.DS_Store vendored Normal file

Binary file not shown.

37
build/Makefile Normal file
View File

@ -0,0 +1,37 @@
#! make -f
#----------------------------------------------------------------------------
# Project: TwlFirm - build
# File: Makefile
#
# Copyright 2007 Nintendo. All rights reserved.
#
# These coded instructions, statements, and computer programs contain
# proprietary information of Nintendo of America Inc. and/or Nintendo
# Company Ltd., and are protected by Federal copyright law. They may
# not be disclosed to third parties or copied or duplicated in any form,
# in whole or in part, without the prior written consent of Nintendo.
#
# $Date:: $
# $Rev:$
# $Author:$
#----------------------------------------------------------------------------
include $(TWLIPL_ROOT)/build/buildtools/commondefs
#----------------------------------------------------------------------------
SUBDIRS = \
tools \
libraries \
nandfirm \
nand_formatter \
libraries_sysmenu\
systemmenu_RED
#----------------------------------------------------------------------------
include $(TWLIPL_ROOT)/build/buildtools/modulerules
#===== End of Makefile =====

View File

@ -0,0 +1,30 @@
#! make -f
#----------------------------------------------------------------------------
# Project: TwlIPL - 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.
#
# $Date:: 2007-09-06$
# $Rev$
# $Author$
#----------------------------------------------------------------------------
ifndef TWL_IPL_COMMONDEFS_
TWL_IPL_COMMONDEFS_ = TRUE
ifeq ($(TARGET_FIRM),SYSTEMMENU)
include $(TWLIPL_ROOT)/build/buildtools/commondefs.sysmenu
else
include $(TWLIPL_ROOT)/build/buildtools/commondefs.firm
endif
#----------------------------------------------------------------------------
endif # TWL_IPL_COMMONDEFS_
#----- End of commondefs -----

View File

@ -0,0 +1,260 @@
#! 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.
#
# $Date:: 2007-09-06$
# $Rev$
# $Author$
#----------------------------------------------------------------------------
ifndef TWLFIRM_COMMONDEFS_
TWLFIRM_COMMONDEFS_ = TRUE
NITRO_NO_STD_PCHDR = TRUE # プリコンパイルヘッダ抑止
ifndef TWL_KEYSDIR
DUMMY_KEYS_SUFFIX = .dummykey
endif
TWL_KEYSDIR ?= $(FIRM_ROOT)/keys/dummy
ifneq ($(filter FIRM GCDFIRM,$(FIRM_TARGET)),)
TARGET_BIN ?= $(subst .,$(DUMMY_KEYS_SUFFIX).,$(TARGET_FIRM_BIN))
endif
EMPTY ?=
SPACE ?= $(EMPTY) $(EMPTY)
#
# CodeGen Target
#
# FIRM_PLATFORM = [BB/EVA/TS]
# FIRM_MEMSIZE = [16M/32M]
# FIRM_CODEGEN = [ARM/THUMB]
# FIRM_PROC = [ARM9/ARM7]
#
# FIRM_TARGET = [FIRM/GCDFIRM/APP]
#
FIRM_PLATFORM ?= TS
FIRM_MEMSIZE ?= 16M
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)
#----------------------------------------------------------------------------
# TWL-FIRM path settings
#
FIRM_ROOT := $(subst $(SPACE),\ ,$(subst \,/,$(TWLIPL_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)
ROM_SPEC ?= $(DEFAULT_FIRM_ROM_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 \
libpxi \
# libgcd \
# libacsign \
FIRM_TWL_LIBS_BASE ?= \
else # ($(CODEGEN_PROC),ARM7)
FIRM_LIBS_BASE ?= \
libos_sp \
libfatfs_sp \
libpxi_sp \
libaes_sp \
libpm_sp \
# libnvram_sp \
# libgcd_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 FIRM 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_ := $(TWLIPL_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)
#----------------------------------------------------------------------------
# Makelcf change for build firmware
#
ifneq ($(filter FIRM GCDFIRM,$(FIRM_TARGET)),)
MAKELCF := $(TWLSDK_ROOT)/tools/bin/makelcf.exe
endif
#----------------------------------------------------------------------------
endif # TWLFIRM_COMMONDEFS_
#----- End of commondefs -----

View File

@ -0,0 +1,97 @@
#! make -f
#----------------------------------------------------------------------------
# Project: TwlIPL - 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.
#
# $Date:: 2007-09-06$
# $Rev$
# $Author$
#----------------------------------------------------------------------------
ifndef TWL_SYSMENU_COMMONDEFS_
TWL_SYSMENU_COMMONDEFS_ = TRUE
NITRO_NO_STD_PCHDR = TRUE # プリコンパイルヘッダ抑止
EMPTY ?=
SPACE ?= $(EMPTY) $(EMPTY)
#----------------------------------------------------------------------------
# TWL-SYSTEM-MENU path settings
#
SYSMENU_ROOT := $(subst $(SPACE),\ ,$(subst \,/,$(TWLIPL_ROOT)))
SYSMENU_BUILDTOOLSDIR := $(SYSMENU_ROOT)/build/buildtools
SYSMENU_INCDIR := $(SYSMENU_ROOT)/include \
$(TWLSDK_ROOT)/build/libraries/spi/arm9/include \
$(TWLSDK_ROOT)/build/libraries/mb/common/include
SYSMENU_TOOLSDIR := $(SYSMENU_ROOT)/tools
SYSMENU_COMPONENTSDIR := $(SYSMENU_ROOT)/components
LDEPENDS_LCF += $(SYSMENU_BUILDTOOLSDIR)/commondefs.sysmenu
LDEPENDS_RES += $(SYSMENU_BUILDTOOLSDIR)/commondefs.sysmenu
#----------------------------------------------------------------------------
### TWL-commondefs
#
#include $(TWLSDK_ROOT)/build/buildtools/commondefs
include $(NITROSYSTEM_ROOT)/build/buildtools/commondefs
#----------------------------------------------------------------------------
### SYSTEM_MENU Library settings
SYSMENU_LIBDIR := $(SYSMENU_ROOT)/lib/$(TWL_LIBTYPE)
ifeq ($(CODEGEN_PROC),ARM9)
SYSMENU_LIBS ?= \
libsysmenu$(TWL_LIBSUFFIX).a \
libmbloader$(TWL_LIBSUFFIX).a \
libacsign$(TWL_LIBSUFFIX).a
else # ($(CODEGEN_PROC),ARM7)
SYSMENU_LIBS ?= \
libmbloader_sp$(TWL_LIBSUFFIX).a
endif
#----------------------------------------------------------------------------
# MY BUILD TOOLS
#
OPENSSL := $(SYSMENU_TOOLSDIR)/openssl/openssl.exe
MAKESYSMENU_RSA_PRVKEY ?= $(SYSMENU_TOOLSDIR)/openssl/rsa_private.der
MAKESYSMENU_RSA_PUBKEY ?= $(SYSMENU_TOOLSDIR)/openssl/rsa_public.der
#----------------------------------------------------------------------------
### Global Library resettings
GINCLUDES := $(SYSMENU_INCDIR) $(GINCLUDES)
GLIBRARY_DIRS := $(SYSMENU_LIBDIR) $(GLIBRARY_DIRS)
GLIBRARIES := $(SYSMENU_LIBS) $(GLIBRARIES)
#----------------------------------------------------------------------------
# TWLSYSMENU_INSTALL_ROOT
#
SYSMENU_INSTALL_ROOT := $(SYSMENU_ROOT)
SYSMENU_INSTALL_INCDIR := $(SYSMENU_INSTALL_ROOT)/include
SYSMENU_INSTALL_TOOLSDIR := $(SYSMENU_INSTALL_ROOT)/tools
SYSMENU_INSTALL_LIBDIR := $(SYSMENU_INSTALL_ROOT)/lib/$(TWL_LIBTYPE)
SYSMENU_INSTALL_COMPONENTSDIR := $(SYSMENU_INSTALL_ROOT)/components
#----------------------------------------------------------------------------
endif # TWL_SYSMENU_COMMONDEFS_
#----- End of commondefs -----

View File

@ -0,0 +1,34 @@
#! make -f
#----------------------------------------------------------------------------
# Project: TwlIPL - 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.
#
# $Date:: 2007-09-06$
# $Rev$
# $Author$
#----------------------------------------------------------------------------
ifndef TWL_IPL_MODULERULES_
#----------------------------------------------------------------------------
### TWL-modulerules
#
ifeq ($(TARGET_FIRM),SYSTEMMENU)
include $(TWLIPL_ROOT)/build/buildtools/modulerules.sysmenu
else
include $(TWLIPL_ROOT)/build/buildtools/modulerules.firm
endif
#----------------------------------------------------------------------------
TWL_IPL_MODULERULES_ = TRUE
endif # TWL_IPL_MODULERULES_
#----- End of modulerules -----

View File

@ -0,0 +1,92 @@
#! 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.
#
# $Date:: 2007-09-06$
# $Rev$
# $Author$
#----------------------------------------------------------------------------
ifndef TWLFIRM_MODULERULES_
ifneq ($(MAKEFIRM_ARM9),)
MAKEROM_ARM9 = $(MAKEFIRM_ARM9)
endif
ifneq ($(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 $(TWLIPL_ROOT)/build
firmlib:
@$(MAKE) -C $(TWLIPL_ROOT)/build/libraries
# .nor
$(BINDIR)/%.nor: $(SDEPENDS_BIN) $(FIRM_SPEC) $(LDEPENDS_BIN) $(EDEPENDS_BIN) $(MAKEFILE) $(MAKENORFIRM)
$(MAKENORFIRM) $(MAKEFIRM_FLAGS) $(MAKEFIRM_DEFS) $(FIRM_SPEC) $@
# .nand
$(BINDIR)/%.nand: $(SDEPENDS_BIN) $(FIRM_SPEC) $(LDEPENDS_BIN) $(EDEPENDS_BIN) $(MAKEFILE) $(MAKENANDFIRM)
$(MAKENANDFIRM) $(MAKEFIRM_FLAGS) $(MAKEFIRM_DEFS) $(FIRM_SPEC) $@
# .gcd
$(BINDIR)/%.gcd: $(SDEPENDS_BIN) $(FIRM_SPEC) $(LDEPENDS_BIN) $(EDEPENDS_BIN) $(MAKEFILE) $(MAKEGCDFIRM)
$(MAKEGCDFIRM) $(MAKEFIRM_FLAGS) $(MAKEFIRM_DEFS) $(FIRM_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)
#ifeq ($(NITRO_CCTYPE),RVCT)
# $(LD) $(LDFLAGS) $(LIBRARY_DIRS) -o $@ $(GLIBRARIES) $(OBJS)
#else
# $(LD) $(LDFLAGS) $(LIBRARY_DIRS) @$(LDRES_FILE) $(LCFILE) -o $@
#ifeq ($(TWL_PLATFORM),TS)
# cp $(BINDIR)/$(TARGET_BIN_BASENAME).axf $(BINDIR)/$(TARGET_BIN_BASENAME).tef
#else # ($(TWL_PLATFORM),BB)
#ifdef FIRM_STRIP_AXF
# $(OBJCOPY) $@ $(BINDIR)/$(TARGET_BIN_BASENAME).sbin
#endif
#endif
#endif
#----------------------------------------------------------------------------
TWLFIRM_MODULERULES_ = TRUE
endif # TWLFIRM_MODULERULES_
#----- End of modulerules -----

View File

@ -0,0 +1,30 @@
#! make -f
#----------------------------------------------------------------------------
# Project: TwlIPL - 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.
#
# $Date:: 2007-09-06$
# $Rev$
# $Author$
#----------------------------------------------------------------------------
ifndef TWL_SYSMENU_MODULERULES_
#----------------------------------------------------------------------------
### TWL-modulerules
#
#include $(TWLSDK_ROOT)/build/buildtools/modulerules
include $(NITROSYSTEM_ROOT)/build/buildtools/modulerules
#----------------------------------------------------------------------------
TWL_SYSMENU_MODULERULES_ = TRUE
endif # TWL_SYSMENU_MODULERULES_
#----- End of modulerules -----

BIN
build/libraries/.DS_Store vendored Normal file

Binary file not shown.

44
build/libraries/Makefile Normal file
View File

@ -0,0 +1,44 @@
#! make -f
#----------------------------------------------------------------------------
# Project: TwlFirm - libraries
# File: Makefile
#
# Copyright 2007 Nintendo. All rights reserved.
#
# These coded instructions, statements, and computer programs contain
# proprietary information of Nintendo of America Inc. and/or Nintendo
# Company Ltd., and are protected by Federal copyright law. They may
# not be disclosed to third parties or copied or duplicated in any form,
# in whole or in part, without the prior written consent of Nintendo.
#
# $Date:: $
# $Rev:$
# $Author:$
#----------------------------------------------------------------------------
include $(TWLIPL_ROOT)/build/buildtools/commondefs
#----------------------------------------------------------------------------
SUBDIRS = \
os \
gcd \
mi \
init \
pxi \
fatfs \
aes \
pm \
# syscall \
# nvram \
# acsign \
# acsign_ecc \
# devices \
#----------------------------------------------------------------------------
include $(TWLIPL_ROOT)/build/buildtools/modulerules
#===== End of Makefile =====

View File

@ -0,0 +1,60 @@
#! make -f
#----------------------------------------------------------------------------
# Project: TwlFirm - libraries - aes
# File: Makefile
#
# Copyright 2007 Nintendo. All rights reserved.
#
# These coded instructions, statements, and computer programs contain
# proprietary information of Nintendo of America Inc. and/or Nintendo
# Company Ltd., and are protected by Federal copyright law. They may
# not be disclosed to third parties or copied or duplicated in any form,
# in whole or in part, without the prior written consent of Nintendo.
#
# $Date:: $
# $Rev:$
# $Author:$
#----------------------------------------------------------------------------
SUBDIRS =
SUBMAKES =
#----------------------------------------------------------------------------
# build ARM & THUMB libraries
FIRM_CODEGEN_ALL ?= TRUE
# Codegen for sub processer
FIRM_PROC = ARM7
SRCDIR = .
SRCS = \
aes_init.c \
aes_util.c \
TARGET_LIB = libaes_sp$(FIRM_LIBSUFFIX).a
#----------------------------------------------------------------------------
# DEBUG版ビルドの場合、RELEASE版でビルドして
# DEBUG版のライブラリを装います。
ifdef NITRO_DEBUG
NITRO_BUILD_TYPE = RELEASE
endif
include $(TWLIPL_ROOT)/build/buildtools/commondefs
INSTALL_TARGETS = $(TARGETS)
INSTALL_DIR = $(FIRM_INSTALL_LIBDIR)
#----------------------------------------------------------------------------
do-build: $(TARGETS)
include $(TWLIPL_ROOT)/build/buildtools/modulerules
#===== End of Makefile =====

View File

@ -0,0 +1,72 @@
/*---------------------------------------------------------------------------*
Project: TwlIPL - libraries - aes
File: aes_init.c
Copyright 2007 Nintendo. All rights reserved.
These coded instructions, statements, and computer programs contain
proprietary information of Nintendo of America Inc. and/or Nintendo
Company Ltd., and are protected by Federal copyright law. They may
not be disclosed to third parties or copied or duplicated in any form,
in whole or in part, without the prior written consent of Nintendo.
$Date:: $
$Rev$
$Author$
*---------------------------------------------------------------------------*/
#include <firm/aes.h>
/*---------------------------------------------------------------------------*
Name: AESi_InitGameKeys
Description: set IDs depending on the application.
you SHOULD NOT touch any ID registers after this call.
Arguments: u8[4] game code
Returns: None
*---------------------------------------------------------------------------*/
void AESi_InitGameKeys( u8 game_code[4] )
{
while (reg_AES_AES_CNT & REG_AES_AES_CNT_E_MASK)
{
}
reg_AES_AES_ID_B2 = AES_IDS_ID0_C(game_code);
reg_AES_AES_ID_B3 = AES_IDS_ID0_D(game_code);
reg_AES_AES_ID_C0 = AES_IDS_ID1_A(game_code);
reg_AES_AES_ID_C1 = AES_IDS_ID1_B(game_code);
// set dummy without seed[3]
reg_AES_AES_SEED_A0 = 1;
reg_AES_AES_SEED_A1 = 2;
reg_AES_AES_SEED_A2 = 3;
reg_AES_AES_SEED_B0 = 4;
reg_AES_AES_SEED_B1 = 5;
reg_AES_AES_SEED_B2 = 6;
reg_AES_AES_SEED_C0 = 7;
reg_AES_AES_SEED_C1 = 8;
reg_AES_AES_SEED_C2 = 9;
reg_AES_AES_SEED_D0 = 10;
reg_AES_AES_SEED_D1 = 11;
reg_AES_AES_SEED_D2 = 12;
reg_AES_AES_KEY_A0 = 1;
reg_AES_AES_KEY_A1 = 2;
reg_AES_AES_KEY_A2 = 3;
reg_AES_AES_KEY_A3 = 3;
reg_AES_AES_KEY_B0 = 4;
reg_AES_AES_KEY_B1 = 5;
reg_AES_AES_KEY_B2 = 6;
reg_AES_AES_KEY_B3 = 6;
reg_AES_AES_KEY_C0 = 7;
reg_AES_AES_KEY_C1 = 8;
reg_AES_AES_KEY_C2 = 9;
reg_AES_AES_KEY_C3 = 9;
reg_AES_AES_KEY_D0 = 10;
reg_AES_AES_KEY_D1 = 11;
reg_AES_AES_KEY_D2 = 12;
reg_AES_AES_KEY_D3 = 12;
}

View File

@ -0,0 +1,46 @@
/*---------------------------------------------------------------------------*
Project: TwlIPL - libraries - aes
File: aes_util.c
Copyright 2007 Nintendo. All rights reserved.
These coded instructions, statements, and computer programs contain
proprietary information of Nintendo of America Inc. and/or Nintendo
Company Ltd., and are protected by Federal copyright law. They may
not be disclosed to third parties or copied or duplicated in any form,
in whole or in part, without the prior written consent of Nintendo.
$Date:: $
$Rev$
$Author$
*---------------------------------------------------------------------------*/
#include <firm/aes.h>
/*---------------------------------------------------------------------------*
Name: AESi_AddCounter
Description: calculate updated counter
Arguments: pCounter pointer to the counter at offset 0
nums offset in blocks (AES_BLOCK_SIZE)
Returns: None
*---------------------------------------------------------------------------*/
void AESi_AddCounter(AESCounter* pCounter, u32 nums)
{
u32 data = 0;
int i;
for (i = 0; i < 16; i++)
{
data += pCounter->bytes[i] + (nums & 0xFF);
pCounter->bytes[i] = (u8)(data & 0xFF);
data >>= 8;
nums >>= 8;
if ( !data && !nums )
{
break;
}
}
}

View File

@ -0,0 +1,31 @@
#! make -f
#----------------------------------------------------------------------------
# Project: TwlIPL - libraries - aes
# File: Makefile
#
# Copyright 2007 Nintendo. All rights reserved.
#
# These coded instructions, statements, and computer programs contain
# proprietary information of Nintendo of America Inc. and/or Nintendo
# Company Ltd., and are protected by Federal copyright law. They may
# not be disclosed to third parties or copied or duplicated in any form,
# in whole or in part, without the prior written consent of Nintendo.
#
# $Date:: $
# $Rev:$
# $Author:$
#----------------------------------------------------------------------------
include $(TWLIPL_ROOT)/build/buildtools/commondefs
#----------------------------------------------------------------------------
SUBDIRS = ARM7
#----------------------------------------------------------------------------
include $(TWLIPL_ROOT)/build/buildtools/modulerules
#===== End of Makefile =====

View File

@ -0,0 +1,65 @@
#! make -f
#----------------------------------------------------------------------------
# Project: TwlFirm - libraries - fatfs
# File: Makefile
#
# Copyright 2007 Nintendo. All rights reserved.
#
# These coded instructions, statements, and computer programs contain
# proprietary information of Nintendo of America Inc. and/or Nintendo
# Company Ltd., and are protected by Federal copyright law. They may
# not be disclosed to third parties or copied or duplicated in any form,
# in whole or in part, without the prior written consent of Nintendo.
#
# $Date:: $
# $Rev:$
# $Author:$
#----------------------------------------------------------------------------
SUBDIRS =
SUBMAKES =
#----------------------------------------------------------------------------
# build ARM & THUMB libraries
FIRM_CODEGEN_ALL ?= TRUE
# Codegen for sub processer
FIRM_PROC = ARM7
INCDIR = \
$(TWLSDK_ROOT)/build/libraries/fatfs/ARM7.TWL/include \
$(TWLSDK_ROOT)/build/libraries/fatfs/ARM7.TWL/include/twl/fatfs/ARM7
SRCDIR = src
SRCS = \
fatfs_loader.c \
fatfs_firm.c \
TARGET_LIB = libfatfs_sp$(FIRM_LIBSUFFIX).a
#----------------------------------------------------------------------------
# DEBUG版ビルドの場合、RELEASE版でビルドして
# DEBUG版のライブラリを装います。
ifdef NITRO_DEBUG
NITRO_BUILD_TYPE = RELEASE
endif
include $(TWLIPL_ROOT)/build/buildtools/commondefs
INSTALL_TARGETS = $(TARGETS)
INSTALL_DIR = $(FIRM_INSTALL_LIBDIR)
#----------------------------------------------------------------------------
do-build: $(TARGETS)
include $(TWLIPL_ROOT)/build/buildtools/modulerules
#===== End of Makefile =====

View File

@ -0,0 +1,506 @@
/*---------------------------------------------------------------------------*
Project: TwlIPL - libraries - fatfs
File: fatfs_firm.c
Copyright 2007 Nintendo. All rights reserved.
These coded instructions, statements, and computer programs contain
proprietary information of Nintendo of America Inc. and/or Nintendo
Company Ltd., and are protected by Federal copyright law. They may
not be disclosed to third parties or copied or duplicated in any form,
in whole or in part, without the prior written consent of Nintendo.
$Date:: $
$Rev$
$Author$
*---------------------------------------------------------------------------*/
#include <symbols.h>
#include <firm.h>
#include <rtfs.h>
#include <devices/sdif_reg.h>
#include <devices/sdif_ip.h>
#include <devices/sdmc_config.h>
#include <twl/devices/sdmc/ARM7/sdmc.h>
extern u32 NAND_FAT_PARTITION_COUNT;
#define DMA_PIPE 2
#define DMA_RECV 3
/*
SD関数
*/
extern volatile SDMC_ERR_CODE SDCARD_ErrStatus;
extern s16 SDCARD_SDHCFlag; /* SDHCカードフラグ */
extern SDPortContext* SDNandContext; /* NAND初期化パラメータ */
/*---------------------------------------------------------------------------*
Name: WaitFifoFull
Description: waiting to fill the SD FIFO
SDカードからの読み込みデータがFIFOから読み込める状態になるまで
Arguments: None
Returns: None
*---------------------------------------------------------------------------*/
static inline void WaitFifoFull( void )
{
while( (*SDIF_CNT & SDIF_CNT_FULL) == 0 )
{
if ( SDCARD_ErrStatus != SDMC_NORMAL ) // an error was occurred
{
break;
}
}
}
/*---------------------------------------------------------------------------*
Name: StartToRead
Description: start to read from SD I/F
SDカードからの読み込みの開始処理を行います
Arguments: block begining sector to transfer
count number of setctors to transfer
Returns: None
*---------------------------------------------------------------------------*/
static void StartToRead(u32 block, u32 count)
{
*SDIF_FSC = count;
*SDIF_FDS = SECTOR_SIZE;
*SDIF_CNT = (*SDIF_CNT & ~(SDIF_CNT_FEIE | SDIF_CNT_FFIE)) | SDIF_CNT_FCLR | SDIF_CNT_USEFIFO;
CC_EXT_MODE = CC_EXT_MODE_DMA;
SDCARD_ErrStatus = SDMC_NORMAL;
SD_EnableClock();
SD_EnableSeccnt(count);
if ( SDCARD_SDHCFlag )
{
SD_MultiReadBlock( block );
}
else
{
SD_MultiReadBlock( block * SECTOR_SIZE );
}
}
/*---------------------------------------------------------------------------*
Name: StopToRead
Description: stop to read from SD I/F
SDカードからの読み込みの完了処理を行います
Arguments: None
Returns: None
*---------------------------------------------------------------------------*/
static void StopToRead( void )
{
if( !SD_CheckFPGAReg( SD_STOP,SD_STOP_SEC_ENABLE ) ){
SD_StopTransmission(); /* カード転送終了をFPGAに通知CMD12発行 */
}
SD_TransEndFPGA(); /* 転送終了処理(割り込みマスクを禁止に戻す) */
SD_DisableClock(); /* クロック供給停止 */
*SDIF_CNT = (*SDIF_CNT & ~SDIF_CNT_USEFIFO) | SDIF_CNT_FCLR; /* FIFO使用フラグOFF */
CC_EXT_MODE = CC_EXT_MODE_PIO; /* PIOモード(DMAモードOFF) */
}
/*
FATFS-SDMCの間にAESを組み込む
FATFSを迂回して設定することになる
*/
#define AES_GET_CNT_BITS(regValue, name) \
((regValue) & (REG_AES_AES_CNT_##name##_MASK))
static BOOL useAES = FALSE;
static AESCounter aesCounter;
/*---------------------------------------------------------------------------*
Name: FATFS_EnableAES
Description: enable AES data path
AES暗号化されていることを
IO関数に通知するためのAPIです
APIを呼び出した直後に読み込むデータのAESの初期値を指定
APIを呼び出す
Arguments: counter initial counter value
Returns: None
*---------------------------------------------------------------------------*/
void FATFS_EnableAES( const AESCounter* pCounter )
{
useAES = TRUE;
aesCounter = *pCounter;
}
/*---------------------------------------------------------------------------*
Name: FATFS_DisableAES
Description: bypass AES
AES暗号化されていないことを
IO関数に通知するためのAPIです
Arguments: None
Returns: None
*---------------------------------------------------------------------------*/
void FATFS_DisableAES( void )
{
useAES = FALSE;
}
/*---------------------------------------------------------------------------*
Name: ReadNormal
Description: normal read
NAND/SDカードを読み込みます
Arguments: block: source sector number in NAND
dest: dest address (4 bytes alignment)
count: sectors to transfer
Returns: 0 if success
*---------------------------------------------------------------------------*/
static u16 ReadNormal(u32 block, void *dest, u16 count)
{
MINDmaConfig config =
{
MI_NDMA_NO_INTERVAL,
MI_NDMA_INTERVAL_PS_1,
MI_NDMA_BWORD_128,
SECTOR_SIZE/4
};
// OS_TPrintf("ReadNormal(0x%X, 0x%08X, 0x%X) is calling.\n", block, dest, count);
MI_NDmaRecvExAsync_Dev( DMA_PIPE, SDIF_FI, dest, (u32)(count * SECTOR_SIZE), NULL, NULL, &config, MI_NDMA_TIMING_SD_1 );
StartToRead( block, count );
MI_WaitNDma( DMA_PIPE );
StopToRead();
return SDCARD_ErrStatus;
}
/*---------------------------------------------------------------------------*
Name: ReadAES
Description: AES read
AESをかけながらNAND/SDカードを読み込みます
AESの鍵の設定はあらかじめ行っておく必要があります
AESの初期値の設定はFATFS_EnableAESの引数から計算されます
Arguments: block: source sector number in NAND
dest: dest address (4 bytes alignment)
count: sectors to transfer
Returns: 0 if success
*---------------------------------------------------------------------------*/
#define PIPE_SIZE 64
static u16 ReadAES(u32 block, void *dest, u16 count)
{
u32 offset = 0; // in bytes
// OS_TPrintf("ReadAES(0x%X, 0x%08X, 0x%X) is calling.\n", block, dest, count);
MI_NDmaPipeAsync_SetUp( DMA_PIPE, (void*)SDIF_FI, (void*)REG_AES_IFIFO_ADDR, PIPE_SIZE, NULL, NULL );
/*
AESのセットアップDMA設定
*/
AESi_Reset();
AESi_Reset();
AESi_DmaRecv( DMA_RECV, dest, (u32)(count * SECTOR_SIZE), NULL, NULL );
AESi_SetCounter( &aesCounter );
AESi_Run( AES_MODE_CTR, 0, (u32)(count * SECTOR_SIZE / AES_BLOCK_SIZE), NULL, NULL );
// update for next read
AESi_AddCounter( &aesCounter, (u32)(count * SECTOR_SIZE / AES_BLOCK_SIZE) );
StartToRead( block, count );
if ( SDCARD_ErrStatus != SDMC_NORMAL )
{
goto err;
}
while ( count * SECTOR_SIZE > offset )
{
while ( AES_GET_CNT_BITS( reg_AES_AES_CNT, IFIFO_CNT ) )
{
}
if ( (offset & (SECTOR_SIZE-1)) == 0 )
{
WaitFifoFull();
if ( SDCARD_ErrStatus != SDMC_NORMAL )
{
goto err;
}
}
MI_NDmaRestart( DMA_PIPE );
offset += PIPE_SIZE;
}
MI_WaitNDma( DMA_PIPE );
StopToRead();
MI_WaitNDma( DMA_RECV );
return SDCARD_ErrStatus;
err:
MI_StopNDma( DMA_RECV );
MI_StopNDma( DMA_PIPE );
StopToRead();
AESi_Reset();
return SDCARD_ErrStatus;
}
/*---------------------------------------------------------------------------*
Name: nandRtfsIoFirm
Description:
Readに対してのみ使IO関数です
AESの有無の判定は断片化時に未検証です
()
Arguments: driveno :
block :
buffer :
count :
reading : TRUE
Returns: TRUE/FALSE
*---------------------------------------------------------------------------*/
static BOOL nandRtfsIoFirm( int driveno, u32 block, void* buffer, u16 count, BOOL reading )
{
u16 result;
#pragma unused( driveno)
sdmcSelect( (u16)SDMC_PORT_NAND);
if( reading )
{
result = useAES ?
ReadAES( block, buffer, count ) :
ReadNormal( block, buffer, count );
}
else
{
SdmcResultInfo SdResult;
result = sdmcWriteFifo( buffer, count, block, NULL, &SdResult );
}
return result ? FALSE : TRUE;
}
/*---------------------------------------------------------------------------*
Name: sdmcRtfsIoFirm
Description:
Readに対してのみ使IO関数です
Arguments: driveno :
block :
buffer :
count :
reading : TRUE
Returns: TRUE/FALSE
*---------------------------------------------------------------------------*/
static BOOL sdmcRtfsIoFirm( int driveno, u32 block, void* buffer, u16 count, BOOL reading )
{
u16 result;
#pragma unused( driveno)
sdmcSelect( (u16)SDMC_PORT_CARD );
if( reading )
{
result = useAES ?
ReadAES( block, buffer, count ) :
ReadNormal( block, buffer, count );
}
else
{
SdmcResultInfo SdResult;
result = sdmcWriteFifo( buffer, count, block, NULL, &SdResult );
}
return result ? FALSE : TRUE;
}
/*---------------------------------------------------------------------------*
Name: nandRtfsAttachFirm
Description: sdmcドライバをドライブに割り当てる
IO関数を使用するように初期化します
Arguments: driveno :
Returns:
*---------------------------------------------------------------------------*/
#define nandRtfsCtrl FATFSi_nandRtfsCtrl
extern int nandRtfsCtrl( int driveno, int opcode, void* pargs);
static BOOL nandRtfsAttachFirm( int driveno, int partition_no)
{
BOOLEAN result;
DDRIVE pdr;
pdr.dev_table_drive_io = nandRtfsIoFirm;
pdr.dev_table_perform_device_ioctl = nandRtfsCtrl;
pdr.register_file_address = (dword) 0; /* Not used */
pdr.interrupt_number = 0; /* Not used */
pdr.drive_flags = (DRIVE_FLAGS_VALID | DRIVE_FLAGS_PARTITIONED);//DRIVE_FLAGS_FAILSAFE;
pdr.partition_number = partition_no; /* Not used */
pdr.pcmcia_slot_number = 0; /* Not used */
pdr.controller_number = 0;
pdr.logical_unit_number = 0;
switch( partition_no )
{
case 0:
result = rtfs_attach( driveno, &pdr, "SD1p0" ); //構造体がFSライブラリ側にコピーされる
break;
case 1:
result = rtfs_attach( driveno, &pdr, "SD1p1" ); //構造体がFSライブラリ側にコピーされる
break;
case 2:
result = rtfs_attach( driveno, &pdr, "SD1p2" ); //構造体がFSライブラリ側にコピーされる
break;
case 3:
result = rtfs_attach( driveno, &pdr, "SD1p3" ); //構造体がFSライブラリ側にコピーされる
break;
default:
result = FALSE;
break;
}
return result;
}
/*---------------------------------------------------------------------------*
Name: sdmcRtfsAttachFirm
Description: sdmcドライバをドライブに割り当てる
IO関数を使用するように初期化します
Arguments: driveno :
Returns:
*---------------------------------------------------------------------------*/
#define sdmcRtfsCtrl FATFSi_sdmcRtfsCtrl
extern int sdmcRtfsCtrl( int driveno, int opcode, void* pargs);
static BOOL sdmcRtfsAttachFirm( int driveno)
{
BOOLEAN result;
DDRIVE pdr;
pdr.dev_table_drive_io = sdmcRtfsIoFirm;
pdr.dev_table_perform_device_ioctl = sdmcRtfsCtrl;
pdr.register_file_address = (dword) 0; /* Not used */
pdr.interrupt_number = 0; /* Not used */
pdr.drive_flags = 0;//DRIVE_FLAGS_FAILSAFE;
pdr.partition_number = 0; /* Not used */
pdr.pcmcia_slot_number = 0; /* Not used */
pdr.controller_number = 0;
pdr.logical_unit_number = 0;
result = rtfs_attach( driveno, &pdr, "SD0" ); //構造体がFSライブラリ側にコピーされる
return result;
}
/*---------------------------------------------------------------------------*
Name: FATFS_InitFIRM
Description: init file system
FATFSを初期化します
FATFS_Initの使用しない部分を省略しているだけです
NANDコンテキストが残っているなら
FATFS用のメモリヒープ(OS_ARENA_MAIN_SUBPRIVの関連とヒープ)
Arguments: nandContext context of nand driver's previous life
Returns: None
*---------------------------------------------------------------------------*/
BOOL FATFS_InitFIRM( void* nandContext )
{
/* RTFSライブラリを初期化 */
if( !FATFSi_rtfs_init() )
{
return FALSE;
}
/* NAND初期化パラメータの設定 */
SDNandContext = (SDPortContext*)nandContext;
/* SDドライバ初期化 */
if ( FATFSi_sdmcInit( SDMC_NOUSE_DMA ) != SDMC_NORMAL )
{
return FALSE;
}
return TRUE;
}
/*---------------------------------------------------------------------------*
Name: FATFS_MountDriveFIRM
Description: mount specified partition
NANDまたはSDカードのみ対応しています
APIでマウントした場合IO関数を使用するようになります
Arguments: driveno drive number "A:" is 0
media media type
partition_no pertition number
Returns: None
*---------------------------------------------------------------------------*/
BOOL FATFS_MountDriveFIRM( int driveno, FATFSMediaType media, int partition_no )
{
if ( media == FATFS_MEDIA_TYPE_NAND )
{
// CAUTION!: 同じ関数を2回呼び出す理由について要確認。
if ( !nandRtfsAttachFirm( driveno, partition_no ) || nandRtfsAttachFirm( driveno, partition_no ) )
{
return FALSE;
}
}
else
{
if ( partition_no ) // support only 0
{
return FALSE;
}
// CAUTION!: 同じ関数を2回呼び出す理由について要確認。
if ( !sdmcRtfsAttachFirm( driveno ) || sdmcRtfsAttachFirm( driveno ) )
{
return FALSE;
}
}
return TRUE;
}

View File

@ -0,0 +1,491 @@
/*---------------------------------------------------------------------------*
Project: TwlIPL - libraries - fatfs
File: fatfs_loader.c
Copyright 2007 Nintendo. All rights reserved.
These coded instructions, statements, and computer programs contain
proprietary information of Nintendo of America Inc. and/or Nintendo
Company Ltd., and are protected by Federal copyright law. They may
not be disclosed to third parties or copied or duplicated in any form,
in whole or in part, without the prior written consent of Nintendo.
$Date:: $
$Rev$
$Author$
*---------------------------------------------------------------------------*/
#include <symbols.h>
#include <firm.h>
#include <firm/format/format_rom.h>
#include <rtfs.h>
#include <devices/sdif_reg.h>
/*
PROFILE_ENABLE
main.cかどこかにu32 profile[256]; u32 pf_cnt;
*/
//#define PROFILE_ENABLE
#define MODULE_ALIGNMENT 0x10 // 16バイト単位で読み込む
//#define MODULE_ALIGNMENT 0x200 // 512バイト単位で読み込む
#define RoundUpModuleSize(value) (((value) + MODULE_ALIGNMENT - 1) & -MODULE_ALIGNMENT)
#ifdef SDK_FINALROM // FINALROMで無効化
#undef PROFILE_ENABLE
#endif
#ifdef PROFILE_ENABLE
#define PROFILE_PXI_SEND 0x10000000
#define PROFILE_PXI_RECV 0x20000000
extern u32 profile[];
extern u32 pf_cnt;
#endif
#define PXI_FIFO_TAG_DATA PXI_FIFO_TAG_USER_0
static ROM_Header* const rh= (ROM_Header*)HW_TWL_ROM_HEADER_BUF;
static int menu_fd = -1;
/*---------------------------------------------------------------------------*
Name: FATFS_OpenRecentMenu
Description: open recent menu file
IDを
menu_fdにセットします
eTicketの処理
Arguments: driveno drive number ('A' is 0)
Returns: None
*---------------------------------------------------------------------------*/
BOOL FATFS_OpenRecentMenu( int driveno )
{
char *menufile = (char*)L"A:\\ipl\\menu.srl";
if (driveno < 0 || driveno >= 26)
{
return FALSE;
}
menufile[0] += (char)driveno;
menu_fd = po_open((u8*)menufile, PO_BINARY, 0);
if (menu_fd < 0)
{
return FALSE;
}
return TRUE;
}
/*---------------------------------------------------------------------------*
Name: FATFS_OpenSpecifiedSrl
Description: open specified menu file
IDをmenu_fdにセットします
Arguments: menufile target filename
Returns: None
*---------------------------------------------------------------------------*/
BOOL FATFS_OpenSpecifiedSrl( const char* menufile )
{
menu_fd = po_open((u8*)menufile, PO_BINARY, 0);
if (menu_fd < 0)
{
return FALSE;
}
return TRUE;
}
#define HEADER_SIZE 0x1000
#define AUTH_SIZE ROM_HEADER_SIGN_TARGET_SIZE
/*---------------------------------------------------------------------------*
Name: FATFS_LoadBuffer
Description: load data and pass to ARM9 via WRAM[B]
LoadBufferメカニズムでFAT中のファイルの内容をARM9に転送します
[LoadBufferメカニズム]
WRAM[B]ARM7,ARM9間のデータ転送を行います
WRAM[B]
1ARM9へ
FIRM_PXI_ID_LOAD_PIRIODを送信します
2使
使ARM9側に割り当てられているときはARM7側に
[使]
WRAM[B]ARM7側に倒しておくこと
[]
offsetとsizeはARM9に通知されません
SRLファイルを読み込む場合はROMヘッダを参照できれば十分です
(ROMヘッダ部分は元から知っているはず)
:
ARM7/ARM9側で歩調を合わせられることを
()
PXIコールバック
APIがデータをWRAMに格納した後
destとsizeを通知するという形でOKではないか
()
Arguments: offset offset of the file to load (512 bytes alignment)
size size to load
Returns: None
*---------------------------------------------------------------------------*/
static BOOL FATFS_LoadBuffer(u32 offset, u32 size)
{
u8* base = (u8*)HW_FIRM_LOAD_BUFFER_BASE;
static int count = 0;
// seek first
// OS_TPrintf("po_lseek(offset=%X);\n", offset);
if (po_lseek(menu_fd, (s32)offset, PSEEK_SET) < 0)
{
return FALSE;
}
#ifdef PROFILE_ENABLE
// x2: after Seek
profile[pf_cnt++] = (u32)OS_TicksToMicroSeconds(OS_GetTick());
#endif
// loading loop
while (size > 0)
{
u8* dest = base + count * HW_FIRM_LOAD_BUFFER_UNIT_SIZE; // target buffer address
u32 unit = size < HW_FIRM_LOAD_BUFFER_UNIT_SIZE ? size : HW_FIRM_LOAD_BUFFER_UNIT_SIZE; // size
while (MI_GetWramBankMaster_B(count) != MI_WRAM_ARM7) // waiting to be master
{
}
#ifdef PROFILE_ENABLE
// x3...: after to wait ARM9
profile[pf_cnt++] = (u32)OS_TicksToMicroSeconds(OS_GetTick());
#endif
// OS_TPrintf("po_read(dest=%X, unit=%X);\n", dest, unit);
if (po_read(menu_fd, (u8*)dest, (int)unit) < 0) // reading
{
return FALSE;
}
#ifdef PROFILE_ENABLE
// x4...: before PXI
profile[pf_cnt++] = (u32)OS_TicksToMicroSeconds(OS_GetTick());
profile[pf_cnt++] = (u32)PROFILE_PXI_SEND | FIRM_PXI_ID_LOAD_PIRIOD; // checkpoint
#endif
PXI_NotifyID( FIRM_PXI_ID_LOAD_PIRIOD );
count = (count + 1) % HW_FIRM_LOAD_BUFFER_UNIT_NUMS;
size -= unit;
}
return TRUE;
}
/*---------------------------------------------------------------------------*
Name: FATFS_LoadHeader
Description: load header
SRLのROMヘッダ部分を読み込みARM9に渡します
ARM9へ FIRM_PXI_ID_LOAD_HEADER
ARM9から FIRM_PXI_ID_AUTH_HEADER
ROMヘッダが格納されたと
seedデータを16バイト受信します
seedはSeedAとKeyCに設定されます
makerom.TWLまたはIPLの仕様に依存します
Arguments: None
Returns: TRUE if success
*---------------------------------------------------------------------------*/
BOOL FATFS_LoadHeader( void )
{
// open the file in FATFS_InitFIRM()
if (menu_fd < 0)
{
return FALSE;
}
#ifdef PROFILE_ENABLE
// 10: before PXI
pf_cnt = 0x10;
profile[pf_cnt++] = (u32)OS_TicksToMicroSeconds(OS_GetTick());
profile[pf_cnt++] = (u32)PROFILE_PXI_SEND | FIRM_PXI_ID_LOAD_HEADER; // checkpoint
#endif
// load header without AES
PXI_NotifyID( FIRM_PXI_ID_LOAD_HEADER );
FATFS_DisableAES();
if (!FATFS_LoadBuffer(0, AUTH_SIZE) ||
#ifdef PROFILE_ENABLE
// 12: after to load half
((profile[pf_cnt++] = (u32)OS_TicksToMicroSeconds(OS_GetTick())), FALSE) ||
#endif
!FATFS_LoadBuffer(AUTH_SIZE, HEADER_SIZE - AUTH_SIZE) ||
#ifdef PROFILE_ENABLE
// 1x: after to load remain
((profile[pf_cnt++] = (u32)OS_TicksToMicroSeconds(OS_GetTick())), FALSE) ||
#endif
PXI_RecvID() != FIRM_PXI_ID_AUTH_HEADER )
{
return FALSE;
}
#ifdef PROFILE_ENABLE
// 1x: after PXI
profile[pf_cnt++] = (u32)PROFILE_PXI_RECV | FIRM_PXI_ID_AUTH_HEADER; // checkpoint
profile[pf_cnt++] = (u32)OS_TicksToMicroSeconds(OS_GetTick());
#endif
// set id depends on game_code and seed to use (or all?)
{
AESKeySeed seed;
AESi_InitGameKeys((u8*)rh->s.game_code);
PXI_RecvDataByFifo( PXI_FIFO_TAG_DATA, &seed, AES_BLOCK_SIZE );
AESi_WaitKey();
AESi_SetKeySeedA(&seed); // APP
//AESi_WaitKey();
//AESi_SetKeySeedB(&seed); // APP & HARD
//AESi_WaitKey();
//AESi_SetKeySeedC(&seed); //
//AESi_WaitKey();
//AESi_SetKeySeedD(&seed); // HARD
AESi_WaitKey();
AESi_SetKeyC(&seed); // Direct
}
return TRUE;
}
/*---------------------------------------------------------------------------*
Name: FATFSi_GetCounter
Description: get counter
offsetに対応したAESのカウンタ値を計算します
makerom.TWL内のコードに依存します
Arguments: offset offset from head of ROM_Header
Returns: counter
*---------------------------------------------------------------------------*/
static AESCounter* FATFSi_GetCounter( u32 offset )
{
static AESCounter counter;
MI_CpuCopy8( rh->s.main_static_digest, &counter, 16 );
AESi_AddCounter( &counter, offset - rh->s.aes_target_rom_offset );
return &counter;
}
/*---------------------------------------------------------------------------*
Name: FATFSi_SetupAES
Description: setup whiere to use AES
AES暗号化されたデータを読み込むためのセットアップを行います
fatfs_sdmc.cのドライバを使用していることが条件となります
(TwlSDK標準で行う場合は)
APIを呼び出す前にROMヘッダが
AES領域をまたぐ場合は (
)
makerom.TWLまたはIPLの使用に依存します
Arguments: offset offset of region from head of ROM_Header
size size of region
Returns: size to transfer once
*---------------------------------------------------------------------------*/
static u32 FATFSi_SetupAES( u32 offset, u32 size )
{
u32 aes_offset = rh->s.aes_target_rom_offset;
u32 aes_end = aes_offset + RoundUpModuleSize(rh->s.aes_target_size);
u32 end = offset + RoundUpModuleSize(size);
if ( rh->s.enable_aes )
{
if ( offset >= aes_offset && offset < aes_end )
{
if ( end > aes_end )
{
size = aes_end - offset;
}
AESi_WaitKey();
if (rh->s.developer_encrypt)
{
AESi_LoadKey( AES_KEY_SLOT_C );
}
else
{
AESi_LoadKey( AES_KEY_SLOT_A );
}
FATFS_EnableAES( FATFSi_GetCounter( offset ) );
}
else
{
if ( offset < aes_offset && offset + size > aes_offset )
{
size = aes_offset - offset;
}
FATFS_DisableAES();
}
}
else
{
FATFS_DisableAES();
}
return size;
}
/*---------------------------------------------------------------------------*
Name: FATFSi_LoadModule
Description: transfer module to ARM9 via WRAM[B]
FATFSi_LoadBufferの上位APIです
AES境界をまたぐときに2回に分けるだけです
Arguments: offset offset from head of ROM_Header
size size to load
Returns: TRUE if success
*---------------------------------------------------------------------------*/
static /*inline*/ BOOL FATFSi_LoadModule(u32 offset, u32 size)
{
size = RoundUpModuleSize( size ); // アラインメント調整
while ( size > 0 )
{
u32 unit = FATFSi_SetupAES( offset, size ); // 一度の転送サイズ
if ( !FATFS_LoadBuffer( offset, unit ) )
{
return FALSE;
}
offset += unit;
size -= unit;
}
return TRUE;
}
/*---------------------------------------------------------------------------*
Name: FATFS_LoadStatic
Description: load static binary
ARM9/ARM7のStaticおよびLTD Staticを読み込みます
ARM9へFIRM_PXI_ID_LOAD_*_STATICを送信します
ARM9からFIRM_PXI_ID_AUTH_*_STATICを受信します
0PXI通信すら行いません
APIを呼び出す前にROMヘッダが
ARM9側と異なり
()
Arguments: None
Returns: TRUE if success
*---------------------------------------------------------------------------*/
BOOL FATFS_LoadStatic( void )
{
#ifdef PROFILE_ENABLE
// 30: LoadStatic
pf_cnt = 0x30;
profile[pf_cnt++] = (u32)OS_TicksToMicroSeconds(OS_GetTick());
profile[pf_cnt++] = (u32)PROFILE_PXI_SEND | FIRM_PXI_ID_LOAD_STATIC; // checkpoint
#endif
PXI_NotifyID( FIRM_PXI_ID_LOAD_STATIC );
// load ARM9 static region without AES
if ( rh->s.main_size > 0 )
{
#ifdef PROFILE_ENABLE
// 31: before PXI
profile[pf_cnt++] = (u32)OS_TicksToMicroSeconds(OS_GetTick());
#endif
if ( !FATFSi_LoadModule( rh->s.main_rom_offset, rh->s.main_size ) )
{
return FALSE;
}
}
// load ARM7 static region without AES
if ( rh->s.sub_size > 0 )
{
#ifdef PROFILE_ENABLE
// 50: before PXI
pf_cnt = 0x50;
profile[pf_cnt++] = (u32)OS_TicksToMicroSeconds(OS_GetTick());
#endif
if ( !FATFSi_LoadModule( rh->s.sub_rom_offset, rh->s.sub_size ) )
{
return FALSE;
}
}
// load ARM9 extended static region with AES
if ( rh->s.main_ltd_size > 0 )
{
#ifdef PROFILE_ENABLE
// 70: before PXI
pf_cnt = 0x70;
profile[pf_cnt++] = (u32)OS_TicksToMicroSeconds(OS_GetTick());
#endif
if ( !FATFSi_LoadModule( rh->s.main_ltd_rom_offset, rh->s.main_ltd_size ) )
{
return FALSE;
}
}
// load ARM7 extended static region with AES
if ( rh->s.sub_ltd_size > 0 )
{
#ifdef PROFILE_ENABLE
// 90: before PXI
pf_cnt = 0x90;
profile[pf_cnt++] = (u32)OS_TicksToMicroSeconds(OS_GetTick());
#endif
if ( !FATFSi_LoadModule( rh->s.sub_ltd_rom_offset, rh->s.sub_ltd_size ) )
{
return FALSE;
}
}
// waiting result
if ( PXI_RecvID() != FIRM_PXI_ID_AUTH_STATIC )
{
return FALSE;
}
#ifdef PROFILE_ENABLE
// 9x: after PXI
profile[pf_cnt++] = (u32)PROFILE_PXI_RECV | FIRM_PXI_ID_AUTH_STATIC; // checkpoint
profile[pf_cnt++] = (u32)OS_TicksToMicroSeconds(OS_GetTick());
#endif
return TRUE;
}
/*---------------------------------------------------------------------------*
Name: FATFS_Boot
Description: boot
ROMヘッダの情報を引数にOSi_Bootを呼び出すだけです
APIを呼び出す前にROMヘッダが
Arguments: None
Returns: None
*---------------------------------------------------------------------------*/
void FATFS_Boot( void )
{
OSi_Boot( rh->s.sub_entry_address, (MIHeader_WramRegs*)rh->s.main_wram_config_data );
}

View File

@ -0,0 +1,31 @@
#! make -f
#----------------------------------------------------------------------------
# Project: TwlIPL - libraries - fatfs
# File: Makefile
#
# Copyright 2007 Nintendo. All rights reserved.
#
# These coded instructions, statements, and computer programs contain
# proprietary information of Nintendo of America Inc. and/or Nintendo
# Company Ltd., and are protected by Federal copyright law. They may
# not be disclosed to third parties or copied or duplicated in any form,
# in whole or in part, without the prior written consent of Nintendo.
#
# $Date:: $
# $Rev:$
# $Author:$
#----------------------------------------------------------------------------
include $(TWLIPL_ROOT)/build/buildtools/commondefs
#----------------------------------------------------------------------------
SUBDIRS = ARM7
#----------------------------------------------------------------------------
include $(TWLIPL_ROOT)/build/buildtools/modulerules
#===== End of Makefile =====

View File

@ -0,0 +1,60 @@
#! make -f
#----------------------------------------------------------------------------
# Project: TwlIPL
# File: Makefile
#
# Copyright 2007 Nintendo. All rights reserved.
#
# These coded instructions, statements, and computer programs contain
# proprietary information of Nintendo of America Inc. and/or Nintendo
# Company Ltd., and are protected by Federal copyright law. They may
# not be disclosed to third parties or copied or duplicated in any form,
# in whole or in part, without the prior written consent of Nintendo.
#
# $Date:: 2007-10-03#$
# $Rev: 1319 $
# $Author: kitase_hirotake $
#----------------------------------------------------------------------------
SUBDIRS =
#----------------------------------------------------------------------------
# build ARM & THUMB libraries
FIRM_CODEGEN_ALL ?= True
FIRM_PROC = ARM7
SRCDIR = . ../common
SRCS = \
gcd.c \
gcd_init.c \
blowfish.c \
ds_blowfish.c \
ds_blowfish_table.c \
gcdfirm_blowfish_table.c \
TARGET_LIB = libgcd_sp$(FIRM_LIBSUFFIX).a
INCDIR = ../include
#----------------------------------------------------------------------------
# DEBUG版ビルドの場合、RELEASE版でビルドして
# DEBUG版のライブラリを装います。
ifdef NITRO_DEBUG
NITRO_BUILD_TYPE = RELEASE
endif
include $(TWLIPL_ROOT)/build/buildtools/commondefs
INSTALL_TARGETS = $(TARGETS)
INSTALL_DIR = $(FIRM_INSTALL_LIBDIR)
#----------------------------------------------------------------------------
do-build: $(TARGETS)
include $(TWLIPL_ROOT)/build/buildtools/modulerules
#===== End of Makefile =====

View File

@ -0,0 +1,65 @@
#! make -f
#----------------------------------------------------------------------------
# Project: TwlIPL
# File: Makefile
#
# Copyright 2007 Nintendo. All rights reserved.
#
# These coded instructions, statements, and computer programs contain
# proprietary information of Nintendo of America Inc. and/or Nintendo
# Company Ltd., and are protected by Federal copyright law. They may
# not be disclosed to third parties or copied or duplicated in any form,
# in whole or in part, without the prior written consent of Nintendo.
#
# $Date:: 2007-10-03#$
# $Rev: 1319 $
# $Author: kitase_hirotake $
#----------------------------------------------------------------------------
SUBDIRS =
#----------------------------------------------------------------------------
# build ARM & THUMB libraries
FIRM_CODEGEN_ALL ?= True
SRCDIR = . ../common
SRCS = \
gcd.c \
gcd_init.c \
blowfish.c \
ds_blowfish.c \
ds_blowfish_table.c \
gcdfirm_blowfish_table.c \
TARGET_LIB = libgcd$(FIRM_LIBSUFFIX).a
INCDIR = ../include
#----------------------------------------------------------------------------
# DEBUG版ビルドの場合、RELEASE版でビルドして
# DEBUG版のライブラリを装います。
ifdef NITRO_DEBUG
NITRO_BUILD_TYPE = RELEASE
endif
include $(TWLIPL_ROOT)/build/buildtools/commondefs
INSTALL_TARGETS = $(TARGETS)
INSTALL_DIR = $(FIRM_INSTALL_LIBDIR)
#----------------------------------------------------------------------------
do-build: $(TARGETS)
include $(TWLIPL_ROOT)/build/buildtools/modulerules
LDEPENDS_OBJ := $(MAKEFIRM_RSA_PUBKEY) \
gcd_acsign.c : $(LDEPENDS_OBJ)
touch gcd_acsign.c
#===== End of Makefile =====

View File

@ -0,0 +1,34 @@
#! make -f
#----------------------------------------------------------------------------
# Project: TwlFirm - libraries - init
# 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 $(TWLIPL_ROOT)/build/buildtools/commondefs
#----------------------------------------------------------------------------
SUBDIRS = ARM9
#ifdef TWL_WITH_ARM7
SUBDIRS += ARM7
#endif
#----------------------------------------------------------------------------
include $(TWLIPL_ROOT)/build/buildtools/modulerules
#===== End of Makefile =====

View File

@ -0,0 +1,149 @@
/*---------------------------------------------------------------------------*
Project: TwlBrom - libraries - GCD
File: blowfish.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 <firm/gcd/blowfish.h>
#define MAXKEYBYTES 56 /* 448 bits */
#define N 16
static u32 F(const BLOWFISH_CTX *ctx, u32 x);
void InitBlowfish(BLOWFISH_CTX *ctx, const unsigned char *key, int keyLen)
{
int i, j, k;
u32 data, datal, datar;
j = 0;
for (i = 0; i < N + 2; ++i) {
data = 0x00000000;
for (k = 0; k < 4; ++k) {
data = (data << 8) | key[j];
j = j + 1;
if (j >= keyLen)
j = 0;
}
ctx->P[i] = ctx->P[i] ^ data;
}
datal = 0x00000000;
datar = 0x00000000;
for (i = 0; i < N + 2; i += 2) {
EncryptByBlowfish(ctx, &datal, &datar);
ctx->P[i] = datal;
ctx->P[i + 1] = datar;
}
for (i = 0; i < 4; ++i) {
for (j = 0; j < 256; j += 2) {
EncryptByBlowfish(ctx, &datal, &datar);
ctx->S[i][j] = datal;
ctx->S[i][j + 1] = datar;
}
}
}
void EncryptByBlowfish(const BLOWFISH_CTX *ctx, u32 *xl, u32 *xr)
{
u32 Xl;
u32 Xr;
u32 temp;
int i;
Xl = *xl;
Xr = *xr;
for (i = 0; i < N; ++i) {
Xl = Xl ^ ctx->P[i];
Xr = F(ctx, Xl) ^ Xr;
temp = Xl;
Xl = Xr;
Xr = temp;
}
temp = Xl;
Xl = Xr;
Xr = temp;
Xr = Xr ^ ctx->P[N];
Xl = Xl ^ ctx->P[N + 1];
*xl = Xl;
*xr = Xr;
}
void DecryptByBlowfish(const BLOWFISH_CTX *ctx, u32 *xl, u32 *xr)
{
u32 Xl;
u32 Xr;
u32 temp;
int i;
Xl = *xl;
Xr = *xr;
for (i = N + 1; i > 1; --i) {
Xl = Xl ^ ctx->P[i];
Xr = F(ctx, Xl) ^ Xr;
/* Exchange Xl and Xr */
temp = Xl;
Xl = Xr;
Xr = temp;
}
/* Exchange Xl and Xr */
temp = Xl;
Xl = Xr;
Xr = temp;
Xr = Xr ^ ctx->P[1];
Xl = Xl ^ ctx->P[0];
*xl = Xl;
*xr = Xr;
}
static u32 F(const BLOWFISH_CTX *ctx, u32 x) {
u32 a, b, c, d;
u32 y;
d = x & 0x00FF;
x >>= 8;
c = x & 0x00FF;
x >>= 8;
b = x & 0x00FF;
x >>= 8;
a = x & 0x00FF;
y = ctx->S[0][a] + ctx->S[1][b];
y = y ^ ctx->S[2][c];
y = y + ctx->S[3][d];
return y;
}

View File

@ -0,0 +1,186 @@
/*---------------------------------------------------------------------------*
Project: TwlBrom - libraries - GCD
File: ds_blowfish.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 <firm/gcd.h>
#include <firm/gcd/blowfish.h>
#ifdef PRINT_DEBUG
#define DBG_PRINTF vlink_dos_printf
#define DBG_CHAR vlink_dos_put_console
#else
#define DBG_PRINTF( ... ) ((void)0)
#define DBG_CHAR( c ) ((void)0)
#endif
static void my_memcopy(void *src, void *dst, int size);
// DS
static char *normal_mode_key ATTRIBUTE_ALIGN(4) = "NmMdOnly";
static char *png_off_key ATTRIBUTE_ALIGN(4) = "enPngOFF";
static char *encrypt_object_key ATTRIBUTE_ALIGN(4) = "encryObj";
extern GCDSharedWork GCDi_SharedWork[2];
extern GCDSecureWork GCDi_SecureWork[2];
static void GCDi_InitBlowfishKeyAndTableDS(BLOWFISH_CTX *ctx, u32 *keyBufp, s32 keyLen)
{
EncryptByBlowfish(ctx, &(keyBufp)[2], &(keyBufp)[1]);
EncryptByBlowfish(ctx, &(keyBufp)[1], &(keyBufp)[0]);
InitBlowfish(ctx, (u8 *)keyBufp, keyLen);
}
static void GCDi_MakeBlowfishTableDS(GCDSlot slot, BLOWFISH_CTX *tableBufp, const u32 *keyp, u32 *keyBufp, s32 keyLen)
{
const BLOWFISH_CTX *blowfishInitTablep = &GCDi_BlowfishInitTableDS;
GCDRomHeader *rh = GCDi_GetRomHeaderAddr( slot );
GCDSecureWork* sec = &GCDi_SecureWork[slot];
u32 *blowfishedKeyp;
MI_CpuCopy32((void *)blowfishInitTablep, (void *)tableBufp, sizeof(BLOWFISH_CTX));
keyBufp[0] = *keyp;
keyBufp[1] = (*keyp >> 1);
keyBufp[2] = (*keyp << 1);
GCDi_InitBlowfishKeyAndTableDS(tableBufp, keyBufp, keyLen);
*(u64 *)sec->cardNormalModeKey = *(u64 *)rh->l.romNormalModeKey;
blowfishedKeyp = sec->cardNormalModeKey;
DecryptByBlowfish(tableBufp, &(blowfishedKeyp)[1], &(blowfishedKeyp)[0]);
if (keyLen > 8) {
sec->isGenUnScrambleKey = 1;
}
GCDi_InitBlowfishKeyAndTableDS(tableBufp, keyBufp, keyLen);
}
void GCDi_InitCardOpBlowfishDS( GCDSlot slot )
{
GCDRomHeader *rh = GCDi_GetRomHeaderAddr( slot );
GCDSecureWork* sec = &GCDi_SecureWork[slot];
GCDi_MakeBlowfishTableDS(slot, &sec->blowfishCardTable, &rh->l.initialCode, sec->cardKeyBuf, 8);
}
static void GCDi_ChangeObjectTableDS(GCDSlot slot, s32 keyLen)
{
GCDSecureWork* sec = &GCDi_SecureWork[slot];
BLOWFISH_CTX *tableBufp = &sec->blowfishCardTable;
u32 *keyBufp = sec->cardKeyBuf;
keyBufp[1] = (keyBufp[1] << 1);
keyBufp[2] = (keyBufp[2] >> 1);
GCDi_InitBlowfishKeyAndTableDS(tableBufp, keyBufp, keyLen);
}
#define UNDEF_CODE 0xe7ffdeff
#define ENCRYPT_DEF_SIZE 0x800
/* あとで名前変える */
#define ENC_DESTINATION_BUF_SIZE 0x4000
static u32 encDestBuf[ENC_DESTINATION_BUF_SIZE/sizeof(u32)];
void GCDi_DecryptObjectFileDS( GCDSlot slot )
{
GCDRomHeader *rh = GCDi_GetRomHeaderAddr( slot );
GCDSecureWork* sec = &GCDi_SecureWork[slot];
GCDSharedWork* sh = &GCDi_SharedWork[slot];
BLOWFISH_CTX *tableBufp = &sec->blowfishCardTable;
u32 *encBufp = (u32 *)&sec->blowfishFlashTable;
u32 *encDestp = (u32 *)rh->l.arm9.ramAddr;
s32 size = sec->secureSize;
s32 restSize;
BOOL exist = TRUE;
int i;
sec->enableReadSecure = 1; // SECURE領域リード・イネーブル
encDestp = GCDi_SecureAreaBuf[slot];
encBufp = encDestBuf;
if (size > ENCRYPT_DEF_SIZE) {
size = ENCRYPT_DEF_SIZE;
}
restSize = size;
if (sec->enableReadSecure) {
MI_CpuCopy32(encDestp, encBufp, (u32)size);
DBG_PRINTF("%s %d\n",__FUNCTION__,__LINE__);
DecryptByBlowfish(tableBufp, &(encBufp)[1], &(encBufp)[0]);
}
GCDi_ChangeObjectTableDS( slot, 8 );
if (sec->enableReadSecure) {
DecryptByBlowfish(tableBufp, &(encBufp)[1], &(encBufp)[0]);
DBG_PRINTF("%s %d\n",__FUNCTION__,__LINE__);
#if 1
for ( i=0; i<8; i++ )
{
if ( encrypt_object_key[i] != ((char*)encBufp)[i] )
{
exist = FALSE;
break;
}
}
// 暗号化オブジェクト有効時
if ( exist )
{
#else
if ((encBufp[0] == encrypt_object_key[0]) // 暗号化オブジェクト有効時
&& (encBufp[1] == encrypt_object_key[1])) {
#endif
u32 *bufp = encBufp;
bufp[0] = UNDEF_CODE;
bufp[1] = UNDEF_CODE;
while ((restSize -= 8) > 0) {
bufp += 2; // 復号処理
DecryptByBlowfish(tableBufp, &(bufp)[1], &(bufp)[0]);
}
DBG_PRINTF("SUCCESS %s %d\n",__FUNCTION__,__LINE__);
}
else {
DBG_PRINTF("ERROR %s %d\n",__FUNCTION__,__LINE__);
// CpuClearFast32(UNDEF_CODE, encBufp, size); // 未定義コードでクリア
sh->disableEncryptedCardData = 1; // 暗号化オブジェクト無効 通知
}
MI_CpuCopy32(encBufp, encDestp, (u32)size);
DBG_PRINTF("%s %d\n",__FUNCTION__,__LINE__);
}
}
/***************************************************
utility functions
***************************************************/
static void my_memcopy(void *src, void *dst, int size)
{
u8 *s,*d;
int i;
s = (u8 *)src;
d = (u8 *)dst;
for( i = 0 ; i < size ; i++ ) {
*d++ = *s++;
}
}

View File

@ -0,0 +1,286 @@
/*---------------------------------------------------------------------------*
Project: TwlBrom - libraries - GCD
File: ds_blowfish_table.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 <firm/gcd/blowfish.h>
const BLOWFISH_CTX GCDi_BlowfishInitTableDS = {
0x5f20d599, 0xb9f54457, 0xd9a4196e, 0x945a6a9e,
0xebf1aed8, 0x3ae27541, 0x32d08293, 0xd531ee33,
0x9a6157cc, 0x1ba20637, 0xf5723979, 0xbef6ae55,
0xfb691b5f, 0xe9f19de5, 0xa1d92cce, 0xe605325e,
0xcffed3fe, 0x0d0462d4 ,
0xb7ecf58b, 0xbb79602b, 0x0d319512, 0x2bda3f6e,
0xf1f08488, 0x257e123d, 0xbbf12245, 0x061a0624,
0x28dfad11, 0x3481648b, 0x2933eb2b, 0xbdf2aa99,
0x9d95149c, 0x8cf5f79f, 0x29a19772, 0xcf5fd19d,
0x1a074d66, 0x4b4ad3de, 0xa3a7c985, 0x3a059517,
0xbf0a493d, 0xa28b890a, 0xdd49824a, 0x0bf19027,
0x6a1cebe9, 0x05457683, 0x617081ba, 0xde4b3f17,
0x39abcfae, 0x563af257, 0x8aad1148, 0x3f45e140,
0x54029bfa, 0xfb93a6ca, 0x6ffe4def, 0x9c87d8a3,
0x48d5ba08, 0xfd2d8d6a, 0x74f8156e, 0x8b52bebd,
0x9e8a2218, 0x073774fb, 0x4a6c361b, 0x6242ba19,
0x109179b9, 0x9665677b, 0xe82302fe, 0x778c99ee,
0x64865c3e, 0x86786d4d, 0xe2654fa5, 0x5adfb21e,
0x087ed00a, 0xac71b014, 0x1c83dbbd, 0x62a1d7b9,
0x7c63c6cd, 0xe6c36952, 0x12ce75bf, 0x04215d44,
0x3cd3fbfa, 0xd4631138, 0x49418595, 0x08f20946,
0x1fdc1143, 0x6d15c076, 0x70633c1f, 0x6c8087ea,
0x8b63bdc3, 0x372137c2, 0x2309eedc, 0x4d6a372e,
0x50f79073, 0x921cac30, 0x91231004, 0xaa07d24f,
0x9a4f3e68, 0x6a6064c9, 0xf32114c8, 0x124122d6,
0xe6cf2444, 0x0ddd568a, 0x85e14d53, 0x5a528c1e,
0xc284199c, 0x6ff15703, 0x58be00e3, 0xd5ed4cf6,
0x1f9c6421, 0x3c0355be, 0xaaffdc4a, 0x5de0dac9,
0xdee6bf5e, 0xf8b1d8f5, 0xb9b336ff, 0xdb956762,
0xed375f31, 0x9967704c, 0x3118b590, 0x99993d6c,
0xd3da42e4, 0xa0134225, 0x6c70d7ae, 0xc7cf55b1,
0x43d546d7, 0x443d1761, 0x8533e928, 0x93a2d0d5,
0x1f1225aa, 0x460bc5fb, 0x567697f5, 0x87bea645,
0xe86b94b1, 0x9933feb1, 0x6c3e1fae, 0x091d7139,
0xe4379000, 0x74753e10, 0x3b838cff, 0xf9b0f1b0,
0x42470501, 0xacd6f195, 0x9ee6387e, 0x3f267495,
0x185068b4, 0xb43043d0, 0x68e34b4c, 0xb64de5bf,
0xa00a8b95, 0x77322574, 0x2cf7a1cf, 0x5a1371d8,
0x51c9eaab, 0xefee0de8, 0x197e93e9, 0x38431ea7,
0xa12c1681, 0xcc73e348, 0xd36c2129, 0xd9a0ce5d,
0xa0437161, 0x64b51315, 0x192acf92, 0xa5b7addc,
0xf865869f, 0xfbe79f1a, 0x13b8fdf7, 0x6fdb276c,
0xf71c35df, 0x9b5b2c8d, 0x6438ab12, 0x31decc06,
0x11754ee8, 0xeafae364, 0xc25434eb, 0xeb343fad,
0x267d2c93, 0xf3569d36, 0xb3f6e15a, 0x9e4a6398,
0x9ae48332, 0x907d6084, 0xee0e132e, 0xa2364b93,
0x3816ec85, 0x020688e8, 0x3aa0f0bf, 0x9a6ad7ed,
0xcf57e173, 0xdcb844f8, 0xd159232e, 0x715295df,
0x4ba06199, 0x786e7fd5, 0x30c5a9ba, 0x328640d3,
0x9c0c329d, 0x2f02b737, 0xa99854ba, 0xc90413c4,
0xe7c8be8d, 0x2e50975d, 0x5922d693, 0x22bc270c,
0x20a7e092, 0x7f6f930f, 0xb5d39f4c, 0x740b2aa6,
0x107d4967, 0xc5d1cb26, 0x8ce77186, 0x5be99ca0,
0x01f61ab2, 0x5e9e8cee, 0xdb1af283, 0x84eae5e6,
0x7cd27659, 0x49a58df6, 0x16c24836, 0xa383bb52,
0x0c07b974, 0x2861ff3b, 0xe4e961e1, 0xaa156eef,
0x5de8ba4e, 0x32bb9605, 0x72fbb056, 0xc80e0f52,
0x76652542, 0xdef2af89, 0x01f02710, 0x97a7744b,
0x5426d507, 0x821f0954, 0x307d860a, 0x26b30e39,
0xbb570b9b, 0xaf310636, 0xd9fc79fd, 0x0c2b1030,
0xd79be1b3, 0xef5fdc7b, 0x4513f8d2, 0xbd75474d,
0x7e3c9646, 0xb53ef375, 0x3b9ac567, 0x6b295bb0,
0xc85b80de, 0x31b10515, 0xdd49ceb6, 0xaeb584ad,
0x3167dc60, 0x4efe3034, 0xa62f80bd, 0x213963bf,
0x7f35d986, 0x05226816, 0x2690e954, 0x516c078c,
0xd75531a4, 0x3ea80709, 0xc166532e, 0xc47bf2f8,
0xf1cf58f2, 0xe7a2c587, 0x87308f27, 0x6264a058,
0x88b91823, 0xc4cefa7c, 0x17adae98, 0xf35b4acc,
0x56d548e9, 0xc8f20dd3, 0xdb8c7392, 0xac562fd7,
0x6992f981, 0xf632c64d, 0x218dc0e6, 0x618076e2,
0x6cdcbc11, 0x6919af93, 0xb9bfd09b, 0x67029f31,
0x83ee51a3, 0x0c7b2206, 0x404249ab, 0x7d01d5b8,
0x55f75ece, 0x99c53953, 0x9f87d846, 0xb464f7ba,
0xa1fa9ae3, 0x1068906d, 0x548aca30, 0xc3609fa7,
0x0d6bf519, 0xe698517a, 0xb4514398, 0x4fe935d6,
0x7b0fdfc3, 0xbd5c2fd6, 0x1961153a, 0xaacb4bf1,
0xc9646ddc, 0x561ec6d3, 0x504c38ef, 0xcc758671,
0xe94e0d0d, 0x5d06f628, 0xd3aa1b70, 0x39a8cf45,
0x2ea695ac, 0xd422e4b4, 0x5f37a874, 0xcc047a48,
0xd8404ca5, 0x0828b428, 0x52721c0d, 0x477df041,
0x4e533a19, 0x6b628458, 0x818ab593, 0xdc0d4e21,
0xc6a23fb4, 0x402bc9fc, 0xe90438da, 0x6b865a5e,
0x8525220c, 0x7c8d1168, 0x55951d92, 0xbb8eab4d,
0xb7e6a6da, 0x5a32b651, 0x05dd4105, 0x50560a2a,
0xcc471791, 0xb57ee6c9, 0x73db4a61, 0x33c85167,
0x746edaf5, 0x37c3542e, 0x08af6d0d, 0x5f8a15e8,
0xcd2159e2, 0x060cdea8, 0x5f6b775a, 0x3e6518db,
0x78de50c8, 0xb382b8e0, 0x32724e5d, 0x34c14f07,
0xb796ba23, 0x28a44e67, 0xeb62341e, 0xe9706a2d,
0x70c4422f, 0x9c315a4e, 0x28475bf9, 0x6f71daaa,
0x78b31f38, 0x1c6b92c4, 0x9a35f69e, 0xbf0e4db7,
0x412918cc, 0x5d354803, 0xc62bd055, 0x605caf29,
0x5e8e6974, 0xbdd47c9b, 0x7d64447b, 0x695d923f,
0x4b001fb6, 0xcf3583d4, 0x174e647e, 0x2ed58dae,
0x4e12289a, 0x08492b2e, 0x46c6ae5c, 0x6141ae85,
0xd2826f1e, 0x1f163751, 0xa459f60b, 0xaf5aca9a,
0x8b33d40d, 0x84f16320, 0xcfcb5c80, 0xd3b9b408,
0x62bd0516, 0x569b3183, 0xba9f9851, 0xb2aa5bb2,
0xb52c6b22, 0x63fa48d4, 0xfa585f2b, 0x0964fa61,
0xb8e038bb, 0xa860929d, 0x0e6f670d, 0x010df537,
0xd477c29f, 0x73f1ecfe, 0x7de03930, 0xe49861f5,
0x0455282c, 0x2fdb5556, 0x58e5ec6b, 0x8064b606,
0x4e1a2a6a, 0xc4d80f5b, 0x19522e0a, 0x30f562d9,
0x7b8cbe48, 0xa29b384f, 0xd3c9afc3, 0x4162c1c7,
0x2161b986, 0x4f996f57, 0x7bcebac1, 0x5e4d3bb5,
0x57448b8a, 0x705f135f, 0x47295b6d, 0xece238dc,
0x12655504, 0x4317e82a, 0x2add8ee1, 0xf794e2b3,
0xe65c6e09, 0x6df88aeb, 0x48544989, 0xbfad2ff5,
0xca4b94ea, 0x828739fc, 0xf2018a5f, 0x71e6f275,
0xde42d8d6, 0x281d2df1, 0xa37e88a6, 0x301d47a0,
0xdf71a3d9, 0x01cb1c49, 0xf2b136f8, 0x5d5822f0,
0xa0bd6b45, 0x4288b2bb, 0xce288cc7, 0x6390e893,
0x897c9008, 0xb77df53c, 0x554f2d04, 0x7efd1651,
0xc1bee879, 0xf8d412f2, 0x230584b4, 0x2bd2cca0,
0xadabe1fd, 0x6c55d10d, 0x4d944123, 0x054f3777,
0x17bf0c28, 0x6c6712b3, 0xf75ac38c, 0x6d2a8441,
0x271294d0, 0x9cedb42c, 0x8247ec4d, 0xb967d597,
0x55c09d1b, 0x8ee57e07, 0x3ee7a8e2, 0x3a0ee412,
0x3455452a, 0x5a2df9a2, 0x7c52ab1b, 0x555f1083,
0x435af1d2, 0xa4a7c62b, 0xe8951589, 0xf89d4bb4,
0x609fe375, 0xe6d65b78, 0x21e6440d, 0x2247bd06,
0xad00a453, 0x8513438d, 0xfcaaf739, 0xed7baf38,
0x542be4fc, 0xfc4c9850, 0xdff78085, 0xe122803c,
0x24deda94, 0x397ab0c6, 0xa10fdc38, 0x6ff9f4a7,
0x8b571863, 0x2e2a4184, 0xd9f253d4, 0xddd00f00,
0xa6196e99, 0x5becd00a, 0xc0ab2458, 0xec6506cb,
0x9438131a, 0x2f03670a, 0x77e3f73f, 0xc6337744,
0xe3d03914, 0x7908a2c0, 0x579940bb, 0x90010b41,
0x48cce1cd, 0xafb3db67, 0x4cf37488, 0xb1728f82,
0xc42923b5, 0xfc196c12, 0x9ca4468e, 0x876525c4,
0x8abe6dd3, 0x38031193, 0xf32b83ed, 0xea93a446,
0x1d85533b, 0x08f1d4ce, 0xfced2783, 0xbc181a9b,
0xdcae8bf9, 0x3850ab24, 0x104b72e9, 0x467b1722,
0x6459ab5d, 0xf8ae40f3, 0xf9c8e5bb, 0x554e0326,
0xfeebeb7d, 0xe0e639f7, 0x2ebe110a, 0xed98ff28,
0x5642c9c0, 0x00fdc342, 0xa287aff6, 0x323f015b,
0x9a954792, 0x3d32a572, 0x9bd06bae, 0x9249d207,
0xfa4a78e3, 0xf27d06a1, 0x7477cf41, 0x0cb21404,
0x16648486, 0xa151bbd5, 0xd1f16fe5, 0x5ff7e2f2,
0xb84d2058, 0xddcfc757, 0x76bed8c5, 0x7e5ff63d,
0x888b2ae7, 0x3f381b24, 0x7723410e, 0xd44bf0f5,
0xa4fa1f0c, 0xcf5f800b, 0xdae0f645, 0x5359342f,
0x523c20fb, 0xb5355e62, 0x608bfe62, 0x5a86e363,
0xd16e1a15, 0x32bc4547, 0x3867ebb4, 0x336ee4ab,
0xa3edb53a, 0x4ee067ad, 0x62ee9541, 0x1d267162,
0x3062ef31, 0xac82d7af, 0x0405dcc2, 0xbf0797f5,
0x07235911, 0xe80264c0, 0xaf3ee597, 0xa659ac18,
0x90334a8b, 0x9c7c6e1c, 0x3c4c7e20, 0xbb64613e,
0x7e7c6bc5, 0x4cc59f3e, 0xf573ea9f, 0x4cc089d7,
0x2df4fbf4, 0x511b14ec, 0xc812c1d5, 0x4a0bdf10,
0x93bc9c8b, 0x3e3e6a45, 0xbaa9c17d, 0x07b4c1cd,
0x8668e1e4, 0x386db243, 0x5c0cfbf3, 0xde713766,
0xa06eef56, 0xa7654010, 0xbed0f798, 0x3637c80e,
0x7cca10ec, 0x1e84ab9c, 0x02761705, 0xaa524f1c,
0xa0c6c15f, 0x04d8b956, 0xa74d4484, 0x60ded859,
0x050e38e6, 0x3be1038f, 0x3304816d, 0xce0b306f,
0x33210569, 0x89bb26fb, 0x87aeb67d, 0xe007517e,
0x0a96f7ac, 0x5cc4f96b, 0x4744e41d, 0xe3fa5eb8,
0x42558478, 0xf75e484b, 0x8635477d, 0x05432b1d,
0xb88aec03, 0x763c061e, 0x431a480c, 0xed8ab7a7,
0x43c6131e, 0xdbef10ee, 0x833cfbec, 0xef4495b2,
0x4e5154d8, 0x1d44112d, 0x1e5936fb, 0xc3c1347a,
0x610057ca, 0x16a567ea, 0x55d0559b, 0x36d97fe1,
0xae7640d2, 0xb0ce01dc, 0xcbd5837a, 0x6bec9820,
0x349272c1, 0x375782f3, 0x36328a62, 0xae43900c,
0x789b5cae, 0x0265138e, 0xc17168fd, 0xa031b0fe,
0xc3b08224, 0xa76979b1, 0xd0ebd2f5, 0xdc32c082,
0x3c26c79e, 0xc1988d6d, 0xd0d422bb, 0x3eec330f,
0xdce1ccb9, 0x36774c6a, 0xbff91c14, 0x5f289f81,
0x29328571, 0xc4487590, 0xd8ce4ab3, 0x2f148f44,
0xef5740fd, 0xd97508aa, 0x6ed6d146, 0xc31f5532,
0x1f84fe18, 0xffd584fc, 0x481b5e71, 0x0e9586c3,
0xd3270828, 0x7b718338, 0x5463804c, 0xacb0569a,
0x31ca80cf, 0xf3feef09, 0x7e24afbe, 0x3f53fea6,
0x334a8dc2, 0xa622d168, 0xea7bad66, 0xb043b6de,
0x009525a1, 0x46753fa3, 0xec441114, 0x92bc95d7,
0x16a94ff0, 0x60976253, 0xf1410f2a, 0xeebe2471,
0xcd087f94, 0x85b39360, 0x3f00075b, 0x83280fd8,
0x9f69d19a, 0xc32edad1, 0xb9a20190, 0x662a4e6b,
0xa6aeda9d, 0x68d32aea, 0x9c0c0c2f, 0xed4a8cd2,
0x65579ee2, 0xa387099d, 0x5d32c4b4, 0x2b32d4c9,
0x1e71e0b1, 0x90e64d64, 0x401ee371, 0x84f37ded,
0x78c8ed0e, 0x71c0ae76, 0x05bb7227, 0xfb6402ea,
0xb56b48f3, 0xed3f9342, 0xd253139f, 0xec2afef7,
0xdb25471d, 0xc686913c, 0xfd11f08e, 0xf7367423,
0x7a9ef5a4, 0x4450537e, 0xd3ca47d4, 0xe66d38eb,
0x7f9471d9, 0x4b69c64a, 0xea52f411, 0xb08afe22,
0x598b6736, 0x2a80e6e8, 0x130465eb, 0x9edcecee,
0x05ecb15f, 0x9fe6596a, 0x896b595e, 0xca1af7bf,
0x6a5bf944, 0xe4038571, 0x70e06229, 0xcfc4416f,
0xe3ccb1b2, 0xa807a67e, 0x847fe787, 0x4b52db93,
0xdd7eec6c, 0x104824d4, 0x60049f69, 0x1848e674,
0xb92ce4f3, 0x7a502e4f, 0x6954d4df, 0xf3a78b2b,
0xf31fffce, 0x3901263e, 0x89849517, 0x4b4cf0b0,
0xc49f9182, 0xa59dac4b, 0x2517af74, 0xd332cac9,
0x848a89bc, 0xae0dcc89, 0x9cdba27c, 0xee91786a,
0x4e5d76ea, 0x69f56087, 0x02d46715, 0x3648afcf,
0x6fbfea07, 0x8f062d66, 0xf9fe9ac4, 0x758790f6,
0x0fadf7b8, 0x3d5a1076, 0xb32eb059, 0xcc2c35c7,
0xcb2b5670, 0xc59637e3, 0x8a1b462f, 0x88c74622,
0x983226a7, 0x2286df61, 0x2f1cf48a, 0xaa09a187,
0xd3aea9cc, 0x1c4500bd, 0x8687549a, 0xffef8752,
0x8fa18f1e, 0x355c89c1, 0x3a2dda1b, 0xc2b2162c,
0x78e256f1, 0x97636bc1, 0xc98f56c5, 0xaa2c7f32,
0xaca8a6af, 0x88229120, 0x8b60e4de, 0x25424bf9,
0x9c7fe31a, 0x3a89192c, 0x36d4057e, 0xc25869cc,
0x2f8b32c1, 0x7aeb8590, 0xa1a55039, 0x66c59227,
0x584f20b0, 0x4383557e, 0x9ce2452b, 0x9012d8e4,
0x5683162c, 0xb3037916, 0x18612dad, 0x371f131a,
0x739ce1e2, 0xfdd5807b, 0xfc87512d, 0x1fd7aa7b,
0xaf8e7a2c, 0xcdbb8df4, 0x727c1195, 0xe26fee0b,
0x37deafb9, 0x8d8cde83, 0xb7670562, 0x568dc696,
0x62d70db6, 0x3646d6ba, 0xe6c88ebd, 0x106c2aea,
0x5b6bff14, 0x463c82fa, 0x464330b1, 0x9b7d8a51,
0x79833e92, 0xb25d555b, 0x90ce5e6c, 0x98538e62,
0xe56d0dc9, 0xc5cd572d, 0xe1ba5781, 0x728fb8e8,
0xdc134fe5, 0x15719dea, 0x8811b210, 0x7fd409d5,
0x2c7f655b, 0x114c383b, 0xfb8d5068, 0xbf59b09e,
0x4a898094, 0x12181ac5, 0x4ad15389, 0x8ce82910,
0xeab6ec1c, 0x8b17c746, 0xa8311525, 0xb1436ba2,
0x0bdbe29d, 0x11b09b87, 0xd2710e04, 0x82897729,
0x7f41660a, 0xff480b1d, 0xfd24bb72, 0x9ba148c2,
0xce7f7bfe, 0xd986db88, 0xb01c3b85, 0x0733a8dc,
0xe32e51bf, 0x97009a0e, 0x97c0061e, 0xb6d89d43,
0x6786c445, 0x88f8005f, 0x9e52a49a, 0x838aaac7,
0x18c5ec75, 0x2fc3ceae, 0x18f92b1a, 0xf51aaeff,
0x33b50b53, 0xe8fda751, 0x64a2e1a8, 0x431722b6,
0xd80acc80, 0x40ba3bae, 0x4a92d9d7, 0x1004df89,
0x2b189bee, 0x8a69776a, 0xb9f9f468, 0x6e1521a2,
0x033b1ee6, 0x609b3062, 0x9b257e41, 0x52c58f9e,
0xc2f80810, 0x1121a169, 0x795e3788, 0x10ff6635,
0xed6e1842, 0x1c6bb697, 0x6de5364e, 0xbfe4b47d,
0x05e0b920, 0xb8d5693a, 0xe0dcd5e3, 0x3e53acb9,
0xad57a407, 0x1848ff77, 0x49ac2a76, 0x75478e2a,
0x63679f6d, 0x398c3530, 0x6fd53905, 0xad5b3a64,
0x82bb0bca, 0xb1459952, 0x99363693, 0x442013af,
0x4402d836, 0x85923909, 0x974a4aff, 0xd763a687,
0x24b5b5c7, 0x6fb40fed, 0x1452580c, 0xd37ba6d9,
0x5838bc79, 0x843bbda1, 0x061ad806, 0xeaa86bfd,
0x0428694b, 0x9982ad37, 0x851b0efb, 0x735da8bd,
0x7558dccd, 0x6c63be0a, 0xe44ce748, 0x60042b30,
0xdad815b9, 0x8f758186, 0x1c8dd496, 0x7c85705d,
0xd57b671c, 0xcea66708, 0x70660a4b, 0xd463e5b7,
0xea828a5b, 0xe2ca6710, 0x8517eff4, 0x8a5f2a2f,
0x6af88297, 0xea1034d6, 0x3c5cc9eb, 0x46f849e1,
0xf6bddeeb, 0xaaf192a9, 0xb018a0a6, 0x1f0fd33a,
0x31ff6ff3, 0xd3444345, 0x88f79a50, 0xcec19609,
0x2cf2cc76, 0x82adba2c, 0x84188f77, 0x9c07d2c0,
0x4e839036, 0x434fa50b, 0x78ab043e, 0x09fbd64f,
0xda902401, 0x613a3c6f, 0x4a697f0d, 0x02302beb,
0x84e0dbb4, 0x35d7eca9, 0x857d37bf, 0x4ea9ce58,
0xa8c780e4, 0x486730d3, 0x2faf29eb, 0xa7b46a74,
0x923f0f3f, 0xaccaf3af, 0x94d94baf, 0x81ca43c0,
0xa1482f0d, 0xd2d527b0, 0x85054bef, 0x934ddea3,
0xbbf03c30, 0x27308f4a, 0x3ee3eb4c, 0x2f9aed64,
0xf082f13b, 0x7fcff4ba, 0xe1b0cb40, 0x57aabc7f,
0xf274c9d3, 0x220d43fa, 0x4e77f4d0, 0x7085d793,
0xb6bf991f, 0x30f135de, 0xf0715ea7, 0x7b2d016b,
0x5333f064, 0xf388390a, 0x6ba63a6b, 0x432fd235,
0xb5fd02cd, 0xaa5bbce9, 0x7e19a4d8, 0x81945d0e,
0xad776f9e, 0x93740ed6, 0x18c4e796, 0x19f5ad5f
};

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,288 @@
/*---------------------------------------------------------------------------*
Project: TwlBrom - libraries - GCD
File: gcdfirm_blowfish_table.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 <firm/gcd/blowfish.h>
const BLOWFISH_CTX GCDi_BlowfishInitTableGCDFIRM = {
0x7595a8ee, 0x84fff32d, 0x58f8aec6, 0x6f6444c2,
0x10a6cfbc, 0xbee1b813, 0x88efabc3, 0xc72026cd,
0xc00b913a, 0x9fb074c0, 0x56d4830f, 0x69abdee5,
0xcf6e5ff2, 0xd7febe2f, 0x84f5d5e2, 0x73a1ccda,
0x44205999, 0x74278f63,
0xf0907253, 0x1c95d48f, 0x7cdbce99, 0xa8b9508a,
0x79379f9e, 0x129144fe, 0xd2b3554d, 0x72d702c6,
0xce058143, 0x72b411b8, 0x9acf2ae7, 0x62c0d195,
0x7d0861e5, 0x333ac8f6, 0xafc17b59, 0x7fabab12,
0x5a20b8df, 0x43c908e1, 0xdf057b54, 0x65237d17,
0x8988581c, 0x1d02cad9, 0xdde63c8a, 0x302fee12,
0x0abedd9d, 0x586fb574, 0x10130aad, 0x0a1ead35,
0xfe6f0870, 0x8cac4f02, 0x9c56ef2c, 0xc0ab9bcd,
0x7faf9a52, 0xef822dcd, 0x2bc0fdc2, 0xde22a557,
0xccf82867, 0x582a9d19, 0xd2790715, 0xdc8df689,
0x250ca6e2, 0xfe35236d, 0x8648e2d6, 0xaa0bf6e7,
0xd1240620, 0x413a5ea7, 0x4cf59143, 0x4f4f5472,
0xa5f29a08, 0x1fff4e8f, 0x14f0ec2d, 0x47d6f42a,
0x85b021f0, 0x7836f20a, 0xd908d0d7, 0xbdcc9dd5,
0xa6ac0bfb, 0x96fb7daf, 0xb65476ff, 0xbde99b51,
0xe8c84b8e, 0x72c88630, 0x3f8d0979, 0x5c1e45dc,
0x7555b1db, 0x3edb5a90, 0xb07fac66, 0xf7316aba,
0x84a088bd, 0xf0b2fb9d, 0x014b48e1, 0x6d0967e3,
0xa38d60e4, 0x148eedf2, 0x81898864, 0xfe0d73aa,
0x58c37bd5, 0x8ce2c345, 0x82951de7, 0x17be1aa6,
0xbfe8ad1b, 0x4d6b4176, 0x3a0da43d, 0x50a4dcac,
0x69f1282e, 0x16b49576, 0x6b521ffe, 0x67588174,
0xb3de1d28, 0x06198cbd, 0xeea240ea, 0xd13e358e,
0x3664b06c, 0x59f4e227, 0xb54122d3, 0x94bb71e3,
0x0315fb94, 0x647301d6, 0x943f1f0d, 0x7a2aaec4,
0x51bf88f7, 0x712c091a, 0x6d3b6e3e, 0x6eb24d52,
0x9fc82ca4, 0x8ffc188e, 0xbe31140a, 0x1d3e5756,
0xc574e16e, 0xb105a793, 0x94f658ec, 0x6ed4864c,
0xb2bae3cf, 0xe342cf15, 0xf2bc4d27, 0x090334b1,
0xc2632a42, 0x884f0092, 0xa59abd51, 0xe9d203f9,
0x7d122257, 0x02a709aa, 0xac9fc39b, 0x4840beed,
0x74be37a4, 0x24b9a4d3, 0x8178bca7, 0x606b85e5,
0x1dcb46b2, 0xe6112060, 0xbd44008a, 0xd1be2964,
0xcfcc5032, 0x74e10e43, 0x53fac5ab, 0x84a6e0a4,
0x9080997a, 0xa31a0100, 0xcee21c1c, 0xebcee973,
0x77e9a4c7, 0x3a261b9b, 0xce49ca16, 0xec3a432d,
0x1410c1bf, 0x8d22c824, 0xb0018266, 0x7964e2e2,
0xfcc6eb14, 0x12e6e035, 0xca689d0a, 0x5f9f39fc,
0xbf14f7e9, 0x5d7813f2, 0x87347401, 0x1a107660,
0xfeaa1bb7, 0x53ebb1a2, 0xfc47a457, 0xf71cde17,
0x25379a36, 0xb2ed205d, 0x1225bf36, 0x14536bd4,
0x31138cdf, 0xeeecb7f4, 0xbb6e5b19, 0x39877d0f,
0x4366ac24, 0xfb13893c, 0x3a7039b2, 0x3a1b8037,
0xfc668634, 0x0a3fb783, 0x50380526, 0x9c0e4b1a,
0x462b9398, 0x0e6c7d2d, 0x689a929e, 0x715701e6,
0x2e61d17d, 0x09da9145, 0xfb143ba1, 0x5b199259,
0xc4e3a5ee, 0x0b4bda9a, 0xe18c526c, 0x73171c1a,
0x1572a94b, 0x6d15b729, 0x71509e91, 0x571bc76e,
0x8c721018, 0x1fcc1742, 0xa6602c75, 0x787f88a9,
0x0598f9c4, 0x5addc61b, 0x8e9b7b41, 0x2f4daf72,
0xd9f09e2a, 0xe76054ca, 0x28bc0b4e, 0x4a320c32,
0xdf2b687e, 0x2cdffbcc, 0x77f16b69, 0x5d425665,
0xcf207fd9, 0x2e4d166d, 0x46e57957, 0x37f50f39,
0x6742b74a, 0xbb21df47, 0xe2df0964, 0x0dd6d989,
0x6f635a6e, 0x8f05a457, 0x6e5dc010, 0xeae76f43,
0x135c206a, 0x876bd938, 0x1ccbc607, 0xaf600e28,
0x0daa4fe0, 0x95e0fe33, 0x093e44b1, 0x1d16b2ad,
0x8d710ba2, 0x3ca3c1d9, 0x8f54a8e1, 0x7eb11ec8,
0xcdb82a0e, 0xde1aff6d, 0x68ae2ce2, 0x80e1ca3e,
0x67d60c2c, 0xac6ad1da, 0x5330c802, 0x5f67a04d,
0x5d6f3c9d, 0x1f4725b0, 0x094a4c69, 0x4c1dea21,
0xfd09ced5, 0x270fc341, 0xf16081f5, 0x54dcbdb4,
0x72a36bf5, 0xbeabc16a, 0xdd82bb02, 0xf0e75d20,
0xea6a64b0, 0x85cb5c2c, 0xd53a5aaa, 0x400f91d1,
0xc020695e, 0xa3d05c76, 0x8ac00446, 0xe0ebe1ce,
0x7ed2ca13, 0x7f41bbca, 0x09daffc0, 0x16d39c09,
0xd417fe9e, 0x11fc4b36, 0x87b92111, 0x581cea89,
0x6a51516d, 0xa691f994, 0x06e5c6ab, 0x81200780,
0xe6ea60b7, 0x8d0967af, 0x32f81d79, 0x1bf63b78,
0xeefe70bb, 0x74123b42, 0xf7345b16, 0x7aaa1388,
0x0152a394, 0xb5463ea1, 0xe7968633, 0xf6b00f17,
0xfee65926, 0xfac95f88, 0xf7788838, 0x404d27c8,
0x0a40725a, 0xac948618, 0xb2fb966f, 0x730b40c3,
0x3fa5b3a0, 0x2a4a7b57, 0xe2ee0994, 0xe2662b03,
0xa517c253, 0x5fcd9ac2, 0x7cf1861a, 0xfb9c6d92,
0x726cfcf6, 0x6bc20855, 0xe03c7757, 0x15f7aefc,
0x0490f4b2, 0xc5c49d9e, 0xd91bc403, 0x84799016,
0x5e8b5d2f, 0xdd8aef68, 0x4225b87a, 0xd3912770,
0x56f84df2, 0xe191d469, 0xb6306514, 0xf66b7461,
0xaa528b42, 0xd7d8d211, 0x0409e809, 0x3e995489,
0x984e2cd0, 0x21da8726, 0xa901dcce, 0xc59ed627,
0xa508a395, 0xe67e1c10, 0x7786c594, 0x7db49c12,
0xf3a048fa, 0x6c03c939, 0x5fe538b2, 0xe68d94f1,
0x74116818, 0xbc041b38, 0x37e9f59f, 0xd5f0d6b4,
0x3abedc09, 0xf2277fcf, 0xb1c090ca, 0x179fbeaf,
0x6799f269, 0x4ef2e1ba, 0x9a8530fe, 0xe629bad3,
0xef2d1806, 0xefe0d41a, 0x8fbd8038, 0xae93b3b8,
0xb96af69a, 0xe976f30a, 0x3735edf2, 0xa10aab80,
0x572bc346, 0xd9d352e5, 0xa88382fb, 0xc36d9a6a,
0x622169f5, 0x2b668147, 0xc68d8e94, 0xd83725df,
0x75ca8dc0, 0xe0fef07d, 0x3020348f, 0xd7e941c5,
0x0f18da00, 0x9909caca, 0x1b5f4c03, 0x611ba66e,
0xe3c25c8d, 0x87fe1654, 0x20ed099e, 0x2eef6251,
0xf8b62747, 0xa8863716, 0x2e654e0a, 0x17985515,
0xd121a7f0, 0xf0545a5b, 0xed9f9da3, 0xfe607b10,
0x3afc599b, 0xa3c13305, 0x9667a20a, 0xbd639f0c,
0xe647e3a0, 0x0e1304b2, 0x26a31cec, 0xd1435273,
0x33845341, 0xbe3383f5, 0x22e5e07f, 0xb516aed2,
0xe7dad3c1, 0x7e0b2eec, 0x7709d235, 0x48923397,
0x086b62a6, 0x05270843, 0x48073d32, 0x3e22db8e,
0x7b0fd2eb, 0x9199531d, 0xa47e9efc, 0x76b1bf31,
0xee7b6f31, 0xdc6de2c0, 0x120d4d2c, 0x1c7d1a8b,
0xd9192142, 0x5251ce66, 0x26dd0acf, 0x18073f04,
0x5901f0a3, 0xfc24fea0, 0xe9d4474b, 0xbbda7bdd,
0x66cb45f6, 0x66137a90, 0xa010a036, 0xa3fff96c,
0x61c8194f, 0x553e0b2b, 0x72b54de2, 0x59aeefe9,
0xda01dab4, 0xdac48b91, 0xbba66e7a, 0xa3819de2,
0x1f950fce, 0xa3c4d697, 0xc4e28dce, 0x530179ee,
0xaa7cc068, 0x1b44146a, 0xb267d209, 0x984ff1be,
0x90fd796b, 0xe0e42a5f, 0x36d033fb, 0x13c2f482,
0x3b19a86d, 0xff0ad256, 0xf06acb47, 0x0d4fbfa0,
0x53246fd3, 0xf9296dd5, 0x42bb5d4a, 0xd4d86e75,
0x96442650, 0x0bdebc51, 0xb3cee98d, 0x188c83e2,
0xbe632850, 0x9a0ce659, 0xc51250cd, 0x141b9f77,
0x292844d4, 0xa8ce50d4, 0xe6f471a3, 0xe51b7ef9,
0xece33b79, 0x1ec17a6a, 0x01a0125e, 0x09071e04,
0xbfe72df4, 0x170ed1cf, 0x2fa259ac, 0x4821704f,
0x95b82704, 0xcd1e0c6a, 0xb57a33ce, 0x057204fe,
0x7617de6b, 0xaa72f1d5, 0x4b46d61a, 0xac797378,
0x4984d9cf, 0x40726022, 0x2b425b5c, 0x4ca25dab,
0xa0e23aa3, 0x4fe1527a, 0x6fd3b7ac, 0xeb47ba60,
0xcde7c8b7, 0x9aef5d0f, 0x821674cd, 0xc258ea7d,
0xa6a813a5, 0x93e88a84, 0x8f32d2e3, 0x58ae440d,
0xc5799715, 0x425284d0, 0x1b696e64, 0x7d3ce93a,
0xdad0f25c, 0xc4b0dd14, 0x7079e2e5, 0xa9e8e61d,
0xfaf686b7, 0x1cf1b87b, 0x31ab43c7, 0xdc45d1bb,
0x386cb6ec, 0xcad283f2, 0x4dccbfaf, 0x4934f28b,
0x2fbc3dd4, 0x789b64f7, 0xb2e8918f, 0x506acbf7,
0x50a13360, 0xd128d4d3, 0xba687526, 0xc5474940,
0x6bb5dfc7, 0xef9bdf1f, 0x92cc643b, 0xfb2ad4f0,
0x4ff9410b, 0xb013c81e, 0x9fe69574, 0x5fed0d88,
0xcfe87720, 0x09cddf06, 0x9e57696f, 0xc429dfb9,
0x460c5dd2, 0x9b9e505b, 0xc012bcf6, 0xd955bdda,
0x7310ed31, 0xcdaaebe2, 0xc9761ff6, 0x5de00f45,
0x66a5e949, 0x45c5df1d, 0x96a38fab, 0x18939d5b,
0x94015083, 0xd27b1379, 0xe10107e7, 0xdaef6ef8,
0xaf8f83b3, 0xafd37029, 0x7d6803e0, 0x3a545055,
0xfd419925, 0xb49fa25f, 0x533ad3f4, 0xc49f3fe4,
0x9b9eb196, 0x2015408e, 0xd6f46485, 0xa8e66479,
0x5b8866e1, 0xc97d478d, 0xb7fcb30a, 0xddefdff0,
0x34afb94c, 0xa155d92f, 0xf53979b1, 0xf0cdd075,
0xf25accae, 0xe4208afd, 0x5b11bb77, 0x37b337e4,
0xa69da8be, 0x28a9ee86, 0xb284b30e, 0xc3527598,
0xf423936e, 0x7e2e1d51, 0xcaf2613d, 0x7505391e,
0x252d3dd5, 0x00d18203, 0x7ef4577e, 0x244e98a9,
0xb73b5840, 0xb0f9c9ed, 0xa8d4bc23, 0xb7228243,
0x241418d3, 0x39fd4429, 0xe8ab9b37, 0x3a74ecdf,
0xbf99499c, 0x70c3eb26, 0xc6ac5d10, 0x7085410a,
0x9bc5ca24, 0x37cf4d32, 0x5a407af1, 0x7f38c2af,
0x6cf95726, 0x2934cce9, 0x478e4a5e, 0x86bccd71,
0x46673804, 0x5cd7e9da, 0x601c0e47, 0x32f3c95c,
0x98f3b207, 0x2a9f09f2, 0xa68e3b9b, 0xe0a67f44,
0x8d4801eb, 0x0d650900, 0x2dbd9d8f, 0x9113fe47,
0x5a317b0e, 0x3d5a8d71, 0xfbd60e45, 0x86f6eedc,
0x3f77fec6, 0xe56a0bb2, 0x32ab5ef7, 0x2262c429,
0x7ed387c6, 0x0087c87e, 0x6570e4b7, 0x648d80e1,
0xc3bd761a, 0x5c3c0c47, 0x9ac5b07c, 0x6ecb158f,
0x73e2d323, 0x5095435e, 0x21a97ee4, 0x0c599519,
0x1f6c6441, 0xee52efd7, 0xbd886ee2, 0x66ec3c66,
0x0e42820c, 0xb4f244cb, 0xa56f2efc, 0xc0302f16,
0xf9b795aa, 0x60a00f3f, 0xa83fb0a9, 0xe9b2f724,
0xa3c3b44f, 0x8151cc80, 0x2ae0e99c, 0x0cb0ff00,
0x2e9a646d, 0x991d2cd6, 0xef2bf16b, 0x0a610ad2,
0x1674ea07, 0x567fcfe7, 0xf05ef5af, 0xdfdf47cb,
0x6c3ebb59, 0x2f052cad, 0x4701ca04, 0x0c65164a,
0xa285ecb3, 0x348fd20a, 0x7915f8ff, 0xdc269d33,
0x74578f72, 0x763ced80, 0x53275951, 0x8c51eebd,
0x6d8b4452, 0x5267c34e, 0xe9b7197b, 0x912800ab,
0x10d207a4, 0x4238eaf7, 0x2171bd12, 0x9c7eff0b,
0x251b79ff, 0x41bb7753, 0xecea6583, 0x031393e5,
0x49a58fe9, 0x83bb7587, 0x4a2a3156, 0xa3ab8da7,
0x38f774aa, 0xd3844d4e, 0x7cc81418, 0x894ca09d,
0x341ade56, 0x9574d6a5, 0xd2299751, 0xdbd43293,
0x253d53e8, 0x64005cc4, 0x813de56f, 0x631c3cda,
0x931681bd, 0x77dd0ab8, 0x15d6b56f, 0x2a3106b1,
0x603102bf, 0xfef29a3d, 0x648baa38, 0x470ae791,
0x02e625ab, 0x04904d5d, 0x3b31cea4, 0xa9a2126d,
0x76814575, 0x4c6a5511, 0xe2d7c619, 0x840d8ca5,
0x4d15e8f8, 0x59256a95, 0xf1ed6a56, 0xb996efab,
0x5da9c913, 0x7652bed8, 0xedbda0be, 0x59f81908,
0xd1d45ed7, 0x00b5f876, 0x986b97e4, 0x0bf99862,
0xf3a448c6, 0x05f92573, 0x9ab2c7c4, 0xbf92bbf2,
0xa8e5e036, 0x3030a02b, 0xab1e833b, 0x5190d039,
0x3d31eec2, 0x4eadf427, 0xea65d217, 0xafac4dd3,
0xdf5ef6fe, 0xe88cdd6c, 0xab55d1df, 0x77689e8b,
0x3ba6b081, 0x9ed37908, 0x42383678, 0xf9f221a6,
0xb6cf355d, 0x1c10aa09, 0x38645486, 0xab46320e,
0x6c01bdce, 0xaa9b77bf, 0xdc8a7085, 0x843c40c0,
0x35218b12, 0x57c15a35, 0x37a879d4, 0x41fa8671,
0xe9bae4f3, 0x9521c923, 0x2a32bab3, 0x5415b46b,
0xcb7245dd, 0x6e6407bd, 0x88477782, 0x18424ea6,
0x48214427, 0xd266b8b8, 0x70b796d4, 0xe4e48223,
0xf6a5bf45, 0xa34cc400, 0x0b62f21c, 0xf0eb6ca7,
0x4f8566a3, 0xd23e5904, 0x86eac0fd, 0x95080a7d,
0xe2926a24, 0x9983c4a1, 0x7e398b84, 0x9fccb2f1,
0xff70696b, 0xccb47af7, 0x61d3bf96, 0xf4170385,
0x0bc86fef, 0x06fb5c90, 0xce92d9fe, 0x120ca3cf,
0xdcde2f59, 0xd6fd2b38, 0x4258d974, 0x4b2c0a3c,
0x1f0967ec, 0x25987e51, 0x4e7acfc7, 0x1f7f9694,
0x18de3230, 0x85d9095d, 0x54737616, 0x6ec26956,
0x9eb3637b, 0x908a5192, 0x839fb43e, 0xefe70f2a,
0x42e168a5, 0x776e5c22, 0x736be3a9, 0xb72d66ed,
0xa4f94794, 0xb414bd55, 0x5de623d3, 0x9cd1e1a9,
0x42957f7e, 0x381cf593, 0x678a7d07, 0x158bb604,
0xe64926bd, 0x5a047438, 0x360d68cb, 0xab487a8e,
0x0d769a0b, 0xde3fc939, 0xf33ea9c0, 0x28b87455,
0xd5f6c00c, 0x853f8ffe, 0xc8d238c3, 0x3bb5473e,
0xc9779097, 0xc4af3a0c, 0x899098c0, 0x3c51c0e4,
0x7e02214e, 0xe65f85a4, 0xe7c4a857, 0x6096179e,
0x9c9eb559, 0x709a5f7d, 0x548f6fd5, 0xf1ad58cb,
0xe4bce783, 0x43ca2b6c, 0x6f43de8f, 0xa60a02f9,
0xbcdd0f35, 0x58f582b3, 0x30633b0d, 0xf17c7d49,
0x35f809f7, 0x9ee90417, 0x6360674f, 0x44375b7b,
0x72949c97, 0xff78dcd2, 0x08bff59a, 0x00b14d4e,
0xf37ef8c1, 0x6760a010, 0x87dd4dee, 0x31f5208a,
0x721c3add, 0x6eb9ab46, 0x29250341, 0x2fdcc721,
0x9d812ebb, 0x60a078a0, 0x20fcdc2d, 0xe8c594f9,
0x4956e488, 0x81873803, 0xf51a953d, 0x9b43c7e1,
0xdfd95440, 0x8dbdb07e, 0x1ecaf22f, 0xb14dceca,
0xc4c8003d, 0xdc26051b, 0x8bdc1011, 0x6df204db,
0xc72491cf, 0x9fd74623, 0xa663c57f, 0xd0f6f96d,
0x60f5d249, 0x10b66b81, 0xeeb26437, 0xe739332c,
0xeb94bdfd, 0xbfc4e0e3, 0x5d8ee7a8, 0xf676c5c3,
0x38357061, 0x8d3e4d68, 0xd560280b, 0x7a85b438,
0x00e7da19, 0x44e3021b, 0xb22bee73, 0x7af11114,
0x9a4aacd3, 0xbb5ea97a, 0x7993ac0b, 0x3dc12ed7,
0x7ac7eda8, 0x26528e57, 0xb15b78c9, 0xeae2b177,
0xa9bd7a3c, 0x03812180, 0x0ed1451f, 0x9ab1c57d,
0xa0acc3c5, 0xbf0b533d, 0x017f8413, 0x3228452a,
0x86eb48e1, 0x379cbcff, 0x3b200f75, 0x0cbbb62b,
0x7467627f, 0xc782b5e3, 0xd402c537, 0x026be842,
0x41a32d7a, 0x5910b6ff, 0x909926b4, 0x05bd811e,
0x92fd98c8, 0xcf66e980, 0x1f5eb79c, 0x4e2c31e4,
0x5f9b7f0c, 0x91972e91, 0xf70f2e5a, 0xd5b6b627,
0x3b1f243a, 0xf404cb7b, 0xe6232ec3, 0x22da8906,
0x0cb348ff, 0x0da6349d, 0x7c858b98, 0xd9b258f1,
0x623c9dd4, 0x8493c626, 0x91551f3b, 0x6ed97a53,
0xb5a10c32, 0x23d39f3e, 0x57e7da04, 0x8f0b2689,
0xebb54529, 0x0f015572, 0x2f4db833, 0x407e1d2b,
0xfd815f1a, 0xdeacbb64, 0xe8c38859, 0xde04110b,
0xb6c901ab, 0x153aee1a, 0x6b5af720, 0xc3bfe796,
0x8b412bc7, 0xe8cbe167, 0x60d83df2, 0x35506981,
0x2b8f1fc7, 0x311029cf, 0xf46fad6e, 0x7440056b,
0x61df9779, 0x693d02da, 0xe7d93ccc, 0x861bd3d3,
0xad0b85a0, 0x8bcd277a, 0xb72fceb7, 0x8ca5d84f,
0xc0847150, 0x1bd88428, 0x4673ca0d, 0xb030dbe5,
0xb51c06c1, 0x642baffb, 0xccb5043b, 0xb84aebcb,
0xbcd80352, 0x385520d6, 0x3b4518aa, 0xfed91bbe,
0x95f68932, 0x3a10ae0e, 0xd733aeaf, 0xf9f85ba7,
0x978ac3d1, 0x6a64540c, 0xc5a1575c, 0xc2adcd2b,
0xc3d45465, 0x47671f05, 0x8542fff3, 0x0f528f92,
0x3da8b9cd, 0x13e96928, 0x0ae5cb86, 0x55602423,
0x1acfb022, 0x68c9f16b, 0xbebc28a5, 0xb1d1d15e,
0xa9f54130, 0x0ebb0b93, 0xaf3ffdb9, 0x52078aad,
0xb3bf2160, 0xfb4d9d05, 0xe32785a3, 0xd05a87e5,
0x688e68a5, 0x38840376, 0x9b46ac8d, 0x23f286fd,
};

View File

@ -0,0 +1,58 @@
#! make -f
#----------------------------------------------------------------------------
# Project: TwlIPL - libraries - init
# File: Makefile
#
# Copyright 2007 Nintendo. All rights reserved.
#
# These coded instructions, statements, and computer programs contain
# proprietary information of Nintendo of America Inc. and/or Nintendo
# Company Ltd., and are protected by Federal copyright law. They may
# not be disclosed to third parties or copied or duplicated in any form,
# in whole or in part, without the prior written consent of Nintendo.
#
# $Date:: $
# $Rev:$
# $Author:$
#----------------------------------------------------------------------------
SUBDIRS =
#SUBMAKES = Makefile.CALLTRACE \
# Makefile.FUNCTIONCOST
#----------------------------------------------------------------------------
# build ARM & THUMB libraries
FIRM_CODEGEN_ALL ?= TRUE
# Codegen for sub processer
FIRM_PROC = ARM7
SRCS = crt0_firm.c \
TARGET_OBJ = crt0_firm.o
#----------------------------------------------------------------------------
# DEBUG版ビルドの場合、RELEASE版でビルドして
# DEBUG版のライブラリを装います。
ifdef NITRO_DEBUG
NITRO_BUILD_TYPE = RELEASE
endif
include $(TWLIPL_ROOT)/build/buildtools/commondefs
INSTALL_TARGETS = $(TARGETS)
INSTALL_DIR = $(FIRM_INSTALL_LIBDIR)
#----------------------------------------------------------------------------
do-build: $(TARGETS)
include $(TWLIPL_ROOT)/build/buildtools/modulerules
#===== End of Makefile =====

View File

@ -0,0 +1,447 @@
/*---------------------------------------------------------------------------*
Project: TwlIPL - libraries - init
File: crt0.c
Copyright 2007 Nintendo. All rights reserved.
These coded instructions, statements, and computer programs contain
proprietary information of Nintendo of America Inc. and/or Nintendo
Company Ltd., and are protected by Federal copyright law. They may
not be disclosed to third parties or copied or duplicated in any form,
in whole or in part, without the prior written consent of Nintendo.
$Date:: $
$Rev$
$Author$
*---------------------------------------------------------------------------*/
#include <nitro/code32.h>
#include <firm.h>
#define FIRM_ENABLE_JTAG
void _start(void);
void _start_AutoloadDoneCallback(void *argv[]);
#define SDK_NITROCODE_LE 0x2106c0de
#define SDK_NITROCODE_BE 0xdec00621
#define SDK_TWLCODE_LE 0x6314c0de
#define SDK_TWLCODE_BE 0xdec01463
// volatile parameters in IPL's work memory
#define IPL_PARAM_CARD_ROM_HEADER 0x023FE940
#define IPL_PARAM_DOWNLOAD_PARAMETER 0x023FE904
extern void OS_IrqHandler(void);
extern void _fp_init(void);
extern void __call_static_initializers(void);
extern void TwlMain(void);
static void INITi_DoAutoload(void);
static void INITi_ShelterLtdBinary(void);
static void detect_main_memory_size(void);
// from LCF
extern unsigned long SDK_IRQ_STACKSIZE[];
extern void SDK_STATIC_BSS_START(void); // static bss start address
extern void SDK_STATIC_BSS_END(void); // static bss start address
extern void SDK_AUTOLOAD_LIST(void); // start pointer to autoload information
extern void SDK_AUTOLOAD_LIST_END(void); // end pointer to autoload information
extern void SDK_AUTOLOAD_START(void); // autoload data will start from here
extern void SDK_LTDAUTOLOAD_LIST(void); // start pointer to autoload information
extern void SDK_LTDAUTOLOAD_LIST_END(void); // end pointer to autoload information
extern void SDK_LTDAUTOLOAD_START(void); // autoload data will start from here
//---- IRQ+SVC stack size in boot (this area is not cleared)
#define INITi_Initial_Stack 0x100
void *const _start_ModuleParams[] =
{
(void *)SDK_AUTOLOAD_LIST,
(void *)SDK_AUTOLOAD_LIST_END,
(void *)SDK_AUTOLOAD_START,
(void *)SDK_STATIC_BSS_START,
(void *)SDK_STATIC_BSS_END,
(void*)0, // CompressedStaticEnd. This fixed number will be updated by compstatic tool.
(void*)0, // SDK_VERSION_ID // SDK version info /* [TODO] ビルドを通すため */
(void*)SDK_NITROCODE_BE,
(void*)SDK_NITROCODE_LE,
};
void* const _start_LtdModuleParams[] =
{
(void*)SDK_LTDAUTOLOAD_LIST,
(void*)SDK_LTDAUTOLOAD_LIST_END,
(void*)SDK_LTDAUTOLOAD_START,
(void*)0, // CompressedLtdautoloadEnd. This fixed number will be updated by compstatic tool.
(void*)SDK_TWLCODE_BE,
(void*)SDK_TWLCODE_LE,
};
/*---------------------------------------------------------------------------*
Name: _start
Description: Start up
Arguments: None
Returns: None.
*---------------------------------------------------------------------------*/
SDK_WEAK_SYMBOL asm void _start( void )
{
#ifdef FIRM_ENABLE_JTAG
ldr r1, =REG_JTAG_ADDR
ldrh r2, [r1]
orr r2, r2, #REG_SCFG_JTAG_CPUJE_MASK | REG_SCFG_JTAG_ARM7SEL_MASK
strh r2, [r1]
#endif
//---- set IME = 0
// ( use that LSB of HW_REG_BASE equal to 0 )
mov r12, #HW_REG_BASE
str r12, [r12, #REG_IME_OFFSET]
//---- initialize stack pointer
// SVC mode
mov r0, #HW_PSR_SVC_MODE
msr cpsr_c, r0
ldr sp, =HW_PRV_WRAM_SVC_STACK_END
// IRQ mode
mov r0, #HW_PSR_IRQ_MODE
msr cpsr_c, r0
ldr r0, =HW_PRV_WRAM_IRQ_STACK_END
mov sp, r0
// System mode
ldr r1, =SDK_IRQ_STACKSIZE
sub r1, r0, r1
mov r0, #HW_PSR_SYS_MODE
msr cpsr_csfx, r0
sub sp, r1, #4 // 4byte for stack check code
//---- read reset flag from pmic
#ifdef TWL_PLATFORM_TS
#if 0
mov r0, #REG_PMIC_SW_FLAGS_ADDR
bl PMi_GetRegister
ands r0, r0, #PMIC_SW_FLAGS_WARMBOOT
#else
mov r0, #I2C_SLAVE_MICRO_CONTROLLER
mov r1, #MCU_REG_TEMP_ADDR
bl I2Ci_ReadRegister
ands r0, r0, #0x01 // under construction
#endif
movne r0, #FIRM_PXI_ID_WARMBOOT
moveq r0, #FIRM_PXI_ID_COLDBOOT
bl PXI_SendByIntf
mov r0, #FIRM_PXI_ID_INIT_MMEM
bl PXI_WaitByIntf
#endif // TWL_PLATFORM_TS
//---- wait for main memory mode into burst mode
ldr r3, =REG_EXMEMCNT_L_ADDR
mov r1, #REG_MI_EXMEMCNT_L_ECE2_MASK
@1:
ldrh r2, [r3]
tst r2, r1
beq @1
#if 0
// move parameters from IPL's work memory to shared area
ldr r0, =IPL_PARAM_CARD_ROM_HEADER
ldr r1, =HW_CARD_ROM_HEADER
add r2, r1, #HW_CARD_ROM_HEADER_SIZE
@1_1:
ldr r3, [r0], #4
str r3, [r1], #4
cmp r1, r2
bmi @1_1
ldr r0, =IPL_PARAM_DOWNLOAD_PARAMETER
add r2, r1, #HW_DOWNLOAD_PARAMETER_SIZE
@1_2:
ldr r3, [r0], #4
str r3, [r1], #4
cmp r1, r2
bmi @1_2
#endif
//---- load autoload block and initialize bss
//bl INITi_DoAutoload
#ifndef SDK_FINALROM // for IS-TWL-DEBUGGER
bl _start_AutoloadDoneCallback
#endif
//---- fill static static bss with 0
ldr r0, =_start_ModuleParams
ldr r1, [r0, #12] // BSS segment start
ldr r2, [r0, #16] // BSS segment end
mov r0, #0
@2: cmp r1, r2
strcc r0, [r1], #4
bcc @2
//---- detect main memory size
//bl detect_main_memory_size
//---- set interrupt vector
ldr r1, =HW_INTR_VECTOR_BUF
ldr r0, =OS_IrqHandler
str r0, [r1, #0]
#ifndef SDK_NOINIT
//---- for C++
bl _fp_init
bl TwlSpStartUp
bl __call_static_initializers
#endif
//---- start (to 16bit code)
ldr r1, =TwlSpMain
ldr lr, =HW_RESET_VECTOR
bx r1
}
/*---------------------------------------------------------------------------*
Name: INITi_DoAutoload
Description: 沿
0
Arguments:
Returns:
*---------------------------------------------------------------------------*/
/*
* < >
* 0x02f88000 crt0
* NITRO WRAM 0x037c0000
* TWL WRAM
* 0x02e80000
* 0x04000 ROM 0x02f84000 - 0x02f88000 退
* NITRO MAIN 0x02f88000 + sizeof(crt0)
* TWL MAIN
*/
static asm void
INITi_DoAutoload(void)
{
@000:
stmdb sp!, {lr}
/* WRAM 用ブロックをオートロード */
ldr r1, =_start_ModuleParams
ldr r12, [r1] // r12 = SDK_AUTOLOAD_LIST
ldr r0, [r1, #4] // r0 = SDK_AUTOLOAD_LIST_END
ldr r1, [r1, #8] // r1 = SDK_AUTOLOAD_START
@001: cmp r12, r0
bge @010
/* 固定セクションをロード */
stmdb sp!, {r0}
ldr r2, [r12], #4 // r2 = start address of destination range
ldr r3, [r12], #4 // r3 = size of fixed section
add r3, r3, r2 // r3 = end address of destination range of fixed section
@002: cmp r2, r3
ldrlt r0, [r1], #4
strlt r0, [r2], #4
blt @002
/* .bss セクションを 0 クリア */
mov r0, #0
ldr r3, [r12], #4 // r3 = size of .bss section
add r3, r3, r2 // r3 = end address of destination range of .bss section
@003: cmp r2, r3
strlt r0, [r2], #4
blt @003
@004: ldmia sp!, {r0}
b @001
@010: /* メインメモリ用ブロックの存在を確認 */
ldr r1, =HW_TWL_ROM_HEADER_BUF + 0x1dc /* ARM7 用拡張常駐モジュール ROM サイズ */
ldr r0, [r1]
cmp r0, #0
beq @020
/* 再読み出し不可部分を退避 */
bl INITi_ShelterLtdBinary
/* メインメモリ用ブロックをオートロード */
ldr r1, =_start_LtdModuleParams
ldr r12, [r1] // r12 = SDK_LTDAUTOLOAD_LIST
ldr r0, [r1, #4] // r0 = SDK_LTDAUTOLOAD_LIST_END
ldr r1, [r1, #8] // r1 = SDK_LTDAUTOLOAD_START
@011: cmp r12, r0
bge @020
/* 固定セクションをロード */
stmdb sp!, {r0}
ldr r2, [r12], #4 // r2 = start address of destination range
ldr r3, [r12], #4 // r3 = size of fixed section
add r3, r3, r2 // r3 = end address of destination range of fixed section
@012: cmp r2, r3
ldrlt r0, [r1], #4
strlt r0, [r2], #4
blt @012
/* .bss セクションを 0 クリア */
mov r0, #0
ldr r3, [r12], #4 // r3 = size of .bss section
add r3, r3, r2 // r3 = end address of destination range of .bss section
@013: cmp r2, r3
strlt r0, [r2], #4
blt @013
@014: ldmia sp!, {r0}
b @011
@020: /* オートロード完了コールバック関数呼び出し */
ldr r0, =_start_ModuleParams
ldr r1, =_start_LtdModuleParams
ldmia sp!, {lr}
b _start_AutoloadDoneCallback
}
/*---------------------------------------------------------------------------*
Name: INITi_ShelterLtdBinary
Description: TWL ROM
退退
ARM7 ARM9
0x4000 退
Arguments:
Returns:
*---------------------------------------------------------------------------*/
static asm void
INITi_ShelterLtdBinary(void)
{
/* 退避元・先アドレスを調査 */
ldr r1, =HW_TWL_ROM_HEADER_BUF + 0x1d8 /* ARM7 用拡張常駐モジュール RAM アドレス */
ldr r1, [r1]
ldr r3, =HW_TWL_ROM_HEADER_BUF + 0x038 /* ARM7 用常駐モジュール RAM アドレス */
ldr r3, [r3]
sub r2, r3, #0x4000 /* 再読み出し不可領域サイズ */ /* ARM7 用退避エリア */
/* コピー */
@loop: ldr r0, [r1], #4
str r0, [r2], #4
cmp r2, r3
blt @loop
bx lr
}
/*---------------------------------------------------------------------------*
Name: _start_AutoloadDoneCallback
Description:
Arguments: argv -
argv[0] = SDK_AUTOLOAD_LIST
argv[1] = SDK_AUTOLOAD_LIST_END
argv[2] = SDK_AUTOLOAD_START
argv[3] = SDK_STATIC_BSS_START
argv[4] = SDK_STATIC_BSS_END
Returns:
*---------------------------------------------------------------------------*/
SDK_WEAK_SYMBOL asm void
_start_AutoloadDoneCallback(void* argv[])
{
bx lr
}
/*---------------------------------------------------------------------------*
Name: detect_main_memory_size
Description: detect main memory size.
result is written into (u32*)HW_MMEMCHECKER_SUB.
value is [OS_CONSOLE_SIZE_4MB|OS_CONSOLE_SIZE_8MB|
OS_CONSOLE_SIZE_16MB|OS_CONSOLE_SIZE_32MB]
Arguments: None.
Returns: None.
*---------------------------------------------------------------------------*/
#define OSi_IMAGE_DIFFERENCE 0x400000
#define OSi_IMAGE_DIFFERENCE2 0xb00000
static asm void detect_main_memory_size( void )
{
#if 0 // NITRO hardware is not supported
mov r0, #OS_CONSOLE_SIZE_4MB
mov r1, #0
ldr r2, =HW_MMEMCHECKER_SUB
sub r3, r2, #OSi_IMAGE_DIFFERENCE
@1:
strh r1, [r2]
ldrh r12, [r3]
cmp r1, r12
bne @2
add r1, r1, #1
cmp r1, #2 // check 2 loop
bne @1
//---- 4MB
b @4
//---- 8MB or 16MB or 32MB
@2:
// check if running on twl/nitro
ldr r1, =REG_CLK_ADDR
ldrh r12, [r1]
tst r12, #REG_SCFG_CLK_WRAMHCLK_MASK
moveq r0, #OS_CONSOLE_SIZE_8MB
beq @4
#else
ldr r2, =HW_MMEMCHECKER_SUB
#endif
//---- 16MB or 32MB
mov r1, #0
add r3, r2, #OSi_IMAGE_DIFFERENCE2
@3:
strh r1, [r2]
ldrh r12, [r3]
cmp r1, r12
movne r0, #OS_CONSOLE_SIZE_32MB
bne @4
add r1, r1, #1
cmp r1, #2 // check 2 loop
bne @3
mov r0, #OS_CONSOLE_SIZE_16MB
@4:
strh r0, [r2]
//---- detect chiptype
ldr r2, =REG_OP_ADDR
ldrh r0, [r2]
and r0, r0, #REG_SCFG_OP_OPT_MASK
// check SMX_CNT
ldr r2, =REG_SMX_CNT_ADDR
ldrh r1, [r2]
tst r1, #0
orrne r0, r0, #OS_CHIPTYPE_SMX_MASK
//---- detect jtag
ldr r2, =REG_JTAG_ADDR
ldrh r1, [r2]
and r1, r1, #REG_SCFG_JTAG_CPUJE_MASK
orr r0, r0, r1, LSL #1
ldr r2, =HW_CHIPTYPE_FLAG
strb r0, [r2]
bx lr
}
/*---------------------------------------------------------------------------*
Name: TwlSpStartUp
Description: hook for user start up
Arguments: None
Returns: None.
*---------------------------------------------------------------------------*/
SDK_WEAK_SYMBOL void TwlSpStartUp(void)
{
}

View File

@ -0,0 +1,54 @@
#! make -f
#----------------------------------------------------------------------------
# Project: TwlIPL - libraries - init
# File: Makefile
#
# Copyright 2007 Nintendo. All rights reserved.
#
# These coded instructions, statements, and computer programs contain
# proprietary information of Nintendo of America Inc. and/or Nintendo
# Company Ltd., and are protected by Federal copyright law. They may
# not be disclosed to third parties or copied or duplicated in any form,
# in whole or in part, without the prior written consent of Nintendo.
#
# $Date:: $
# $Rev:$
# $Author:$
#----------------------------------------------------------------------------
SUBDIRS =
#SUBMAKES = Makefile.CALLTRACE \
# Makefile.FUNCTIONCOST
#----------------------------------------------------------------------------
# build ARM & THUMB libraries
FIRM_CODEGEN_ALL ?= TRUE
SRCS = crt0_firm.c \
TARGET_OBJ = crt0_firm.o
#----------------------------------------------------------------------------
# DEBUG版ビルドの場合、RELEASE版でビルドして
# DEBUG版のライブラリを装います。
ifdef NITRO_DEBUG
NITRO_BUILD_TYPE = RELEASE
endif
include $(TWLIPL_ROOT)/build/buildtools/commondefs
INSTALL_TARGETS = $(TARGETS)
INSTALL_DIR = $(FIRM_INSTALL_LIBDIR)
#----------------------------------------------------------------------------
do-build: $(TARGETS)
include $(TWLIPL_ROOT)/build/buildtools/modulerules
#===== End of Makefile =====

View File

@ -0,0 +1,817 @@
/*---------------------------------------------------------------------------*
Project: TwlIPL - libraries - init
File: crt0.c
Copyright 2007 Nintendo. All rights reserved.
These coded instructions, statements, and computer programs contain
proprietary information of Nintendo of America Inc. and/or Nintendo
Company Ltd., and are protected by Federal copyright law. They may
not be disclosed to third parties or copied or duplicated in any form,
in whole or in part, without the prior written consent of Nintendo.
$Date:: $
$Rev$
$Author$
*---------------------------------------------------------------------------*/
#include <nitro/code32.h>
#include <firm.h>
void _start(void);
void _start_AutoloadDoneCallback(void *argv[]);
#define SDK_NITROCODE_LE 0x2106c0de
#define SDK_NITROCODE_BE 0xdec00621
#define SDK_TWLCODE_LE 0x6314c0de
#define SDK_TWLCODE_BE 0xdec01463
extern void OS_IrqHandler(void);
extern void _fp_init(void);
extern void __call_static_initializers(void);
extern void TwlMain(void);
static void INITi_CpuClear32(register u32 data, register void *destp, register u32 size);
static void INITi_InitCoprocessor(void);
static void INITi_InitRegion(void);
static void INITi_DoAutoload(void);
static void INITi_ShelterLtdBinary(void);
// from LCF
extern unsigned long SDK_IRQ_STACKSIZE[];
extern void SDK_AUTOLOAD_LIST(void); // start pointer to autoload information
extern void SDK_AUTOLOAD_LIST_END(void); // end pointer to autoload information
extern void SDK_AUTOLOAD_START(void); // autoload data will start from here
extern void SDK_STATIC_BSS_START(void); // static bss start address
extern void SDK_STATIC_BSS_END(void); // static bss end address
extern void SDK_LTDAUTOLOAD_LIST(void); // start pointer to autoload information
extern void SDK_LTDAUTOLOAD_LIST_END(void); // end pointer to autoload information
extern void SDK_LTDAUTOLOAD_START(void); // autoload data will start from here
/*---------------------------------------------------------------------------*
Name: _start_ModuleParams
Description: autoload/compress/arguments data block
Arguments: None.
Returns: None.
*---------------------------------------------------------------------------*/
//#include <nitro/version.h>
#define SDK_VERSION_ID ((u32)SDK_VERSION_MAJOR<<24|\
(u32)SDK_VERSION_MINOR<<16|\
(u32)SDK_VERSION_RELSTEP)
void *const _start_ModuleParams[] =
{
(void *)SDK_AUTOLOAD_LIST,
(void *)SDK_AUTOLOAD_LIST_END,
(void *)SDK_AUTOLOAD_START,
(void *)SDK_STATIC_BSS_START,
(void *)SDK_STATIC_BSS_END,
(void *)0, // CompressedStaticEnd
(void *)SDK_VERSION_ID, // SDK version info
(void *)SDK_NITROCODE_BE, // Checker 1
(void *)SDK_NITROCODE_LE, // Checker 2
};
void* const _start_LtdModuleParams[] =
{
(void*)SDK_LTDAUTOLOAD_LIST,
(void*)SDK_LTDAUTOLOAD_LIST_END,
(void*)SDK_LTDAUTOLOAD_START,
(void*)0, // CompressedLtdautoloadEnd. This fixed number will be updated by compstatic tool.
(void*)SDK_TWLCODE_BE,
(void*)SDK_TWLCODE_LE,
};
/*---------------------------------------------------------------------------*
Name: _start
Description: Start up
Arguments: None
Returns: None.
*---------------------------------------------------------------------------*/
#define INITi_HW_DTCM SDK_AUTOLOAD_DTCM_START
SDK_WEAK_SYMBOL asm void _start( void )
{
//---- set IME = 0
// ( use that LSB of HW_REG_BASE equal to 0 )
mov r12, #HW_REG_BASE
str r12, [r12, #REG_IME_OFFSET]
//---- initialize stack pointer
// SVC mode
mov r0, #HW_PSR_SVC_MODE
msr cpsr_c, r0
ldr r0, =INITi_HW_DTCM
add r0, r0, #0x3fc0
mov sp, r0
// IRQ mode
mov r0, #HW_PSR_IRQ_MODE
msr cpsr_c, r0
ldr r0, =INITi_HW_DTCM
add r0, r0, #0x3fc0
sub r0, r0, #HW_SVC_STACK_SIZE
sub sp, r0, #4 // 4byte for stack check code
tst sp, #4
subeq sp, sp, #4 // for 8byte-alignment
// System mode
ldr r1, =SDK_IRQ_STACKSIZE
sub r1, r0, r1
mov r0, #HW_PSR_SYS_MODE
msr cpsr_csfx, r0
sub sp, r1, #4 // 4byte for stack check code
//---- read reset flag from pmic
#ifdef TWL_PLATFORM_TS
@0: bl PXI_RecvByIntf
cmp r0, #FIRM_PXI_ID_COLDBOOT
cmpne r0, #FIRM_PXI_ID_WARMBOOT
bne @0
//---- initialize Main Memory
cmp r0, #FIRM_PXI_ID_COLDBOOT
moveq r0, #TRUE
movne r0, #FALSE
bl MIi_InitMainMemCR
mov r0, #FIRM_PXI_ID_INIT_MMEM
bl PXI_SendByIntf
#else // TWL_PLATFORM_BB
//---- initialize Main Memory
bl MIi_InitMainMemCR
#endif // TWL_PLATFORM_BB
/* システム制御コプロセッサ初期化 */
bl INITi_InitCoprocessor
/* リージョン初期設定 */
bl INITi_InitRegion
//---- clear memory
// DTCM (16KB)
mov r0, #0
ldr r1, =INITi_HW_DTCM
mov r2, #HW_DTCM_SIZE
bl INITi_CpuClear32
// BG/OBJ palette (1KB)
mov r0, #0
ldr r1, =HW_PLTT
mov r2, #HW_PLTT_SIZE
bl INITi_CpuClear32
// OAM (1KB)
mov r0, #0x0200
ldr r1, =HW_OAM
mov r2, #HW_OAM_SIZE
bl INITi_CpuClear32
//---- load autoload block and initialize bss
// bl INITi_DoAutoload
#ifndef SDK_FINALROM // for IS-TWL-DEBUGGER
bl _start_AutoloadDoneCallback
#endif
//---- fill static static bss with 0
mov r0, #0
ldr r3, =_start_ModuleParams
ldr r1, [r3, #12] // SDK_STATIC_BSS_START
ldr r2, [r3, #16] // SDK_STATIC_BSS_END
sub r2, r2, r1
bl INITi_CpuClear32
//---- flush static bss region
// (r0 == #0, r3 == _start_ModuleParams::BSS_segment_start)
bic r1, r3, #HW_CACHE_LINE_SIZE - 1
@cacheflush:
mcr p15, 0, r0, c7, c10, 4 // wait writebuffer empty
mcr p15, 0, r1, c7, c5, 1 // ICache
mcr p15, 0, r1, c7, c14, 1 // DCache
add r1, r1, #HW_CACHE_LINE_SIZE
cmp r1, r2
blt @cacheflush
// print buffer (used for ARM7's printing)
ldr r1, =HW_COMPONENT_PARAM
str r0, [r1, #0]
//---- set interrupt vector
ldr r1, =INITi_HW_DTCM
add r1, r1, #0x3fc0
add r1, r1, #HW_DTCM_SYSRV_OFS_INTR_VECTOR
ldr r0, =OS_IrqHandler
str r0, [r1, #0]
#ifndef SDK_NOINIT
//---- for C++
bl _fp_init
bl TwlStartUp
bl __call_static_initializers
#endif
//---- start (to 16bit code)
ldr r1, =TwlMain
ldr lr, =HW_RESET_VECTOR
tst sp, #4
subne sp, sp, #4 // for 8byte-alignment
bx r1
}
/*---------------------------------------------------------------------------*
Name: INITi_CpuClear32
Description: fill memory with specified data.
32bit version
Arguments: data : fill data
destp : destination address
size : size (byte)
Returns: None
*---------------------------------------------------------------------------*/
static asm void INITi_CpuClear32( register u32 data, register void *destp, register u32 size )
{
add r12, r1, r2 // r12: destEndp = destp + size
@20:
cmp r1, r12 // while (destp < destEndp)
stmltia r1!, {r0} // *((vu32 *)(destp++)) = data
blt @20
bx lr
}
/*---------------------------------------------------------------------------*
Name: INITi_DoAutoload
Description: 沿
0 4M bytes PSRAM
TWL
Arguments:
Returns:
*---------------------------------------------------------------------------*/
/*
* < >
* 0x02000000 Static ()
* 0x02000000
* NITRO ITCM 0x01ff8000
* NITRO DTCM 0x02fe0000
* 0x02400000 ()
* 0x04000 ROM 0x02f80000 - 0x02f84000 退
* 0x02400000
* TWL WRAM
* TWL
* NITRO 0x02400000
* 0x02400000
* .bss
*
*/
static asm void
INITi_DoAutoload(void)
{
@000:
stmdb sp!, {lr}
/* NITRO 共用ブロックの解凍 */
ldr r1, =_start_ModuleParams
ldr r0, [r1, #20] // r0 = bottom of compressed data
bl MIi_UncompressBackward
@010:
/* NITRO 共用ブロックをオートロード */
ldr r1, =_start_ModuleParams
ldr r12, [r1] // r12 = SDK_AUTOLOAD_LIST
ldr r0, [r1, #4] // r0 = SDK_AUTOLOAD_LIST_END
ldr r1, [r1, #8] // r1 = SDK_AUTOLOAD_START
@011: cmp r12, r0
bge @020
/* 固定セクションをロード */
stmdb sp!, {r0}
ldr r2, [r12], #4 // r2 = start address of destination range
stmdb sp!, {r2}
ldr r3, [r12], #4 // r3 = size of fixed section
add r3, r3, r2 // r3 = end address of destination range of fixed section
@012: cmp r2, r3
ldrlt r0, [r1], #4
strlt r0, [r2], #4
blt @012
/* .bss セクションを 0 クリア */
mov r0, #0 // r0 = number to fill .bss section
ldr r3, [r12], #4 // r3 = size of .bss section
add r3, r3, r2 // r3 = end address of destination range of .bss section
@013: cmp r2, r3
strlt r0, [r2], #4
blt @013
/* キャッシュを調整 */
ldmia sp!, {r2} // r2 = start address of destination range
mov r0, #HW_ITCM_IMAGE
cmp r2, r0
addge r0, r0, #HW_ITCM_SIZE
cmpge r0, r2
bgt @015 // If I-TCM autoload block, skip cache control logic.
ldr r0, =SDK_AUTOLOAD_DTCM_START
cmp r2, r0
addge r0, r0, #HW_DTCM_SIZE
cmpge r0, r2
bgt @015 // If D-TCM autoload block, skip cache control logic.
bic r2, r2, #HW_CACHE_LINE_SIZE - 1 // RoundDown32
@014: cmp r2, r3
bge @015
mcr p15, 0, r2, c7, c14, 1 // Store and Invalidate D-Cache
mcr p15, 0, r2, c7, c5, 1 // Invalidate I-Cache
add r2, r2, #HW_CACHE_LINE_SIZE
b @014
@015: ldmia sp!, {r0}
b @011
@020:
/* TWL ハードウェア上で動作しているかどうかを調査 */
ldr r1, =REG_CLK_ADDR
ldrh r0, [r1]
tst r0, #REG_SCFG_CLK_WRAMHCLK_MASK
beq @030
/* TWL 専用ブロックの存在を確認 */
ldr r1, =HW_TWL_ROM_HEADER_BUF + 0x1cc /* ARM9 用拡張常駐モジュール ROM サイズ */
ldr r0, [r1]
cmp r0, #0
beq @030
/* 再読み出し不可部分を退避 */
bl INITi_ShelterLtdBinary
/* TWL 専用ブロックの解凍 */
ldr r1, =_start_LtdModuleParams
ldr r0, [r1, #12]
bl MIi_UncompressBackward
/* TWL 専用ブロックをオートロード */
ldr r1, =_start_LtdModuleParams
ldr r12, [r1] // r12 = SDK_LTDAUTOLOAD_LIST
ldr r0, [r1, #4] // r0 = SDK_LTDAUTOLOAD_LIST_END
ldr r1, [r1, #8] // r1 = SDK_LTDAUTOLOAD_START
@021: cmp r12, r0
bge @030
/* 固定セクションをロード */
stmdb sp!, {r0}
ldr r2, [r12], #4 // r2 = start address of destination range
stmdb sp!, {r2}
ldr r3, [r12], #4 // r3 = size of fixed section
add r3, r3, r2 // r3 = end address of destination range of fixed section
@022: cmp r2, r3
ldrlt r0, [r1], #4
strlt r0, [r2], #4
blt @022
/* .bss セクションを 0 クリア */
mov r0, #0 // r0 = number to fill .bss section
ldr r3, [r12], #4 // r3 = size of .bss section
add r3, r3, r2 // r3 = end address of destination range of .bss section
@023: cmp r2, r3
strlt r0, [r2], #4
blt @023
/* キャッシュを調整 */
ldmia sp!, {r2} // r2 = start address of destination range
mov r0, #HW_ITCM_IMAGE
cmp r2, r0
addge r0, r0, #HW_ITCM_SIZE
cmpge r0, r2
bgt @025 // If I-TCM autoload block, skip cache control logic.
ldr r0, =SDK_AUTOLOAD_DTCM_START
cmp r2, r0
addge r0, r0, #HW_DTCM_SIZE
cmpge r0, r2
bgt @025 // If D-TCM autoload block, skip cache control logic.
bic r2, r2, #HW_CACHE_LINE_SIZE - 1 // RoundDown32
@024: cmp r2, r3
bge @025
mcr p15, 0, r2, c7, c14, 1 // Store and Invalidate D-Cache
mcr p15, 0, r2, c7, c5, 1 // Invalidate I-Cache
add r2, r2, #HW_CACHE_LINE_SIZE
b @024
@025: ldmia sp!, {r0}
b @021
@030: /* ライトバッファが空になるのを待つ */
mov r0, #0
mcr p15, 0, r0, c7, c10, 4
/* オートロード完了コールバック関数呼び出し */
ldr r0, =_start_ModuleParams
ldr r1, =_start_LtdModuleParams
ldmia sp!, {lr}
b _start_AutoloadDoneCallback
}
/*---------------------------------------------------------------------------*
Name: INITi_ShelterLtdBinary
Description: TWL ROM
退退
ARM7 ARM9
0x4000 退
Arguments:
Returns:
*---------------------------------------------------------------------------*/
static asm void
INITi_ShelterLtdBinary(void)
{
/* ARM7 専用メインメモリ空間保護リージョンを一旦アクセス可能に変更 */
mrc p15, 0, r0, c5, c0, 3
mrc p15, 0, r1, c5, c0, 2
stmdb sp!, {r0, r1}
bic r0, r0, #(0xf << 8)
orr r0, r0, #(0x1 << 8)
bic r1, r1, #(0xf << 8)
orr r1, r1, #(0x1 << 8)
mcr p15, 0, r0, c5, c0, 3
mcr p15, 0, r1, c5, c0, 2
/* 退避元・先アドレスを調査 */
ldr r1, =HW_TWL_ROM_HEADER_BUF + 0x1c8 /* ARM9 用拡張常駐モジュール RAM アドレス */
ldr r1, [r1]
ldr r3, =HW_TWL_ROM_HEADER_BUF + 0x038 /* ARM7 用常駐モジュール RAM アドレス */
ldr r3, [r3]
sub r3, r3, #0x4000 /* 再読み出し不可領域サイズ */ /* ARM7 用退避エリア */
sub r2, r3, #0x4000 /* 再読み出し不可領域サイズ */ /* ARM9 用退避エリア */
/* コピー */
@loop: ldr r0, [r1], #4
str r0, [r2], #4
cmp r2, r3
blt @loop
/* ARM7 専用メインメモリ空間保護リージョン設定を元に戻す */
ldmia sp!, {r0, r1}
mcr p15, 0, r0, c5, c0, 3
mcr p15, 0, r1, c5, c0, 2
bx lr
}
/*---------------------------------------------------------------------------*
Name: MIi_UncompressBackward
Description: Uncompress special archive for module compression.
Arguments: bottom = Bottom adrs of packed archive + 1
bottom[-8..-6] = offset for top of compressed data
inp_top = bottom - bottom[-8..-6]
bottom[-5] = offset for bottom of compressed data
inp = bottom - bottom[-5]
bottom[-4..-1] = offset for bottom of original data
outp = bottom + bottom[-4..-1]
typedef struct
{
u32 bufferTop:24;
u32 compressBottom:8;
u32 originalBottom;
} CompFooter;
Returns: None.
*---------------------------------------------------------------------------*/
asm void
MIi_UncompressBackward(register void* bottom)
{
#define data r0
#define inp_top r1
#define outp r2
#define inp r3
#define outp_save r4
#define flag r5
#define count8 r6
#define index r7
#define len r12
cmp bottom, #0
beq @exit
stmfd sp!, {r4-r7}
ldmdb bottom, {r1-r2}
add outp, bottom, outp
sub inp, bottom, inp_top, LSR #24
bic inp_top, inp_top, #0xff000000
sub inp_top, bottom, inp_top
mov outp_save, outp
@loop:
cmp inp, inp_top // exit if inp==inp_top
ble @end_loop
ldrb flag, [inp, #-1]! // r4 = compress_flag = *--inp
mov count8, #8
@loop8:
subs count8, count8, #1
blt @loop
tst flag, #0x80
bne @blockcopy
@bytecopy:
ldrb data, [inp, #-1]!
strb data, [outp, #-1]! // Copy 1 byte
b @joinhere
@blockcopy:
ldrb len, [inp, #-1]!
ldrb index, [inp, #-1]!
orr index, index, len, LSL #8
bic index, index, #0xf000
add index, index, #0x0002
add len, len, #0x0020
@patterncopy:
ldrb data, [outp, index]
strb data, [outp, #-1]!
subs len, len, #0x0010
bge @patterncopy
@joinhere:
cmp inp, inp_top
mov flag, flag, LSL #1
bgt @loop8
@end_loop:
// DC_FlushRange & IC_InvalidateRange
mov r0, #0
bic inp, inp_top, #HW_CACHE_LINE_SIZE - 1
@cacheflush:
mcr p15, 0, r0, c7, c10, 4 // wait writebuffer empty
mcr p15, 0, inp, c7, c5, 1 // ICache
mcr p15, 0, inp, c7, c14, 1 // DCache
add inp, inp, #HW_CACHE_LINE_SIZE
cmp inp, outp_save
blt @cacheflush
ldmfd sp!, {r4-r7}
@exit bx lr
}
/*---------------------------------------------------------------------------*
Name: _start_AutoloadDoneCallback
Description:
Arguments: argv -
argv[0] = SDK_AUTOLOAD_LIST
argv[1] = SDK_AUTOLOAD_LIST_END
argv[2] = SDK_AUTOLOAD_START
argv[3] = SDK_STATIC_BSS_START
argv[4] = SDK_STATIC_BSS_END
Returns:
*---------------------------------------------------------------------------*/
SDK_WEAK_SYMBOL asm void
_start_AutoloadDoneCallback(void* argv[])
{
bx lr
}
/*---------------------------------------------------------------------------*
Name: INITi_InitCoprocessor
Description:
I-TCM D-TCM 使
Arguments:
Returns:
*---------------------------------------------------------------------------*/
static asm void
INITi_InitCoprocessor(void)
{
/* コプロセッサの状態取得 */
mrc p15, 0, r0, c1, c0, 0
tst r0, #HW_C1_PROTECT_UNIT_ENABLE
beq @010
tst r0, #HW_C1_DCACHE_ENABLE
beq @003
/* D-Cache 内容をメモリにライトバック */
mov r1, #0
@001: mov r2, #0
@002: orr r3, r1, r2
mcr p15, 0, r3, c7, c10, 2
add r2, r2, #HW_CACHE_LINE_SIZE
cmp r2, #HW_DCACHE_SIZE / 4
blt @002
adds r1, r1, #1 << HW_C7_CACHE_SET_NO_SHIFT
bne @001
@003: /* ライトバッファが空になるのを待つ */
mov r1, #0
mcr p15, 0, r1, c7, c10, 4
@010: /* コプロセッサの状態を初期化 */
ldr r1, = HW_C1_ITCM_LOAD_MODE \
| HW_C1_DTCM_LOAD_MODE \
| HW_C1_ITCM_ENABLE \
| HW_C1_DTCM_ENABLE \
| HW_C1_LD_INTERWORK_DISABLE \
| HW_C1_ICACHE_ENABLE \
| HW_C1_DCACHE_ENABLE \
| HW_C1_PROTECT_UNIT_ENABLE
bic r0, r0, r1
ldr r1, = HW_C1_SB1_BITSET \
| HW_C1_EXCEPT_VEC_UPPER
orr r0, r0, r1
mcr p15, 0, r0, c1, c0, 0
/* I-TCM のサイズを設定 */
mov r1, #HW_C9_TCMR_32MB
mcr p15, 0, r1, c9, c1, 1
/* D-TCM のサイズ及び領域ベースアドレスを設定 */
ldr r1, =SDK_AUTOLOAD_DTCM_START
orr r1, r1, #HW_C9_TCMR_16KB
mcr p15, 0, r1, c9, c1, 0
/* I-TCM / D-TCM 使用許可設定 */
mov r1, #HW_C1_ITCM_ENABLE | HW_C1_DTCM_ENABLE
orr r0, r0, r1
mcr p15, 0, r0, c1, c0, 0
bx lr
}
/*---------------------------------------------------------------------------*
Name: INITi_InitRegion
Description:
Arguments:
Returns:
*---------------------------------------------------------------------------*/
/* When hardware is TWL
; Region G: BACK_GROUND: Base = 0x0, Size = 4GB, I:NC NB / D:NC NB, I:NA / D:NA
; Region 0: IO_VRAM: Base = 0x04000000, Size = 64MB, I:NC NB / D:NC NB, I:RW / D:RW
; Region 1: MAINMEM_WRAM: Base = 0x02000000, Size = 32MB, I:Cach Buf / D:Cach Buf, I:RW / D:RW
; Region 2: ARM7_RESERVE: Base = 0x02f80000, Size = 512KB, I:NC NB / D:NC NB, I:NA / D:NA
; Region 3: EX_MAINMEM: Base = 0x0d000000, Size = 16MB, I:Cach Buf / D:Cach Buf, I:RW / D:RW
; Region 4: DTCM: Base = 0x02fe0000, Size = 16KB, I:NC NB / D:NC NB, I:NA / D:RW
; Region 5: ITCM: Base = 0x01000000, Size = 16MB, I:NC NB / D:NC NB, I:RW / D:RW
; Region 6: BIOS: Base = 0xffff0000, Size = 32KB, I:Cach NB / D:Cach NB, I:RO / D:RO
; Region 7: SHARED_WORK: Base = 0x02ffc000, Size = 16KB, I:NC NB / D:NC NB, I:NA / D:RW
*/
/* When hardware is NITRO
; Region G: BACK_GROUND: Base = 0x0, Size = 4GB, I:NC NB / D:NC NB, I:NA / D:NA
; Region 0: IO_VRAM: Base = 0x04000000, Size = 64MB, I:NC NB / D:NC NB, I:RW / D:RW
; Region 1: MAIN_MEM: Base = 0x02000000, Size = 8MB*, I:Cach Buf / D:Cach Buf, I:RW / D:RW
; (* When hardware is not debugger, size will be reduced to 4MB in OS_InitArena() )
; Region 2: ARM7_RESERVE: Base = 0x027e0000, Size = 128KB, I:NC NB / D:NC NB, I:NA / D:NA
; (* When hardware is not debugger, base will be moved to 0x023e0000 in OS_InitArena() )
; Region 3: CARTRIDGE: Base = 0x08000000, Size = 128MB, I:NC NB / D:NC NB, I:NA / D:RW
; Region 4: DTCM: Base = 0x02fe0000, Size = 16KB, I:NC NB / D:NC NB, I:NA / D:RW
; Region 5: ITCM: Base = 0x01000000, Size = 16MB, I:NC NB / D:NC NB, I:RW / D:RW
; Region 6: BIOS: Base = 0xffff0000, Size = 32KB, I:Cach NB / D:Cach NB, I:RO / D:RO
; Region 7: SHARED_WORK: Base = 0x02fff000, Size = 4KB, I:NC NB / D:NC NB, I:NA / D:RW
*/
static asm void
INITi_InitRegion(void)
{
#define SET_PROTECTION_A(id, adr, siz) ldr r0, =(adr|HW_C6_PR_##siz|HW_C6_PR_ENABLE)
#define SET_PROTECTION_B(id, adr, siz) mcr p15, 0, r0, c6, id, 0
#define REGION_BIT(a, b, c, d, e, f, g, h) (((a) << 0) | ((b) << 1) | ((c) << 2) | ((d) << 3) | ((e) << 4) | ((f) << 5) | ((g) << 6) | ((h) << 7))
#define REGION_ACC(a, b, c, d, e, f, g, h) (((a) << 0) | ((b) << 4) | ((c) << 8) | ((d) << 12) | ((e) << 16) | ((f) << 20) | ((g) << 24) | ((h) << 28))
#define NA 0
#define RW 1
#define RO 5
/* (0) I/O レジスタ及び VRAM 等 */
SET_PROTECTION_A(c0, HW_IOREG, 64MB)
SET_PROTECTION_B(c0, HW_IOREG, 64MB)
/* (4) D-TCM */
ldr r0, =SDK_AUTOLOAD_DTCM_START
orr r0, r0, #HW_C6_PR_16KB | HW_C6_PR_ENABLE
SET_PROTECTION_B(c4, SDK_AUTOLOAD_DTCM_START, 16KB)
/* (5) I-TCM */
SET_PROTECTION_A(c5, HW_ITCM_IMAGE, 16MB)
SET_PROTECTION_B(c5, HW_ITCM_IMAGE, 16MB)
/* (6) システムコール ROM */
SET_PROTECTION_A(c6, HW_BIOS, 32KB)
SET_PROTECTION_B(c6, HW_BIOS, 32KB)
/* TWL ハードウェア上で動作しているかどうかを調査 */
ldr r1, =REG_CLK_ADDR
ldrh r0, [r1]
tst r0, #REG_SCFG_CLK_WRAMHCLK_MASK
beq @002
@001: /* ハードウェアが TWL の場合 */
/* (1) メインメモリ及び WRAM */
SET_PROTECTION_A(c1, HW_TWL_MAIN_MEM_MAIN, 32MB)
SET_PROTECTION_B(c1, HW_TWL_MAIN_MEM_MAIN, 32MB)
/* (2) ARM7 専用メインメモリ空間 */
SET_PROTECTION_A(c2, HW_TWL_MAIN_MEM_SUB, 512KB)
SET_PROTECTION_B(c2, HW_TWL_MAIN_MEM_SUB, 512KB)
/* (3) 拡張メインメモリ */
SET_PROTECTION_A(c3, HW_TWL_MAIN_MEM_EX, 16MB)
SET_PROTECTION_B(c3, HW_TWL_MAIN_MEM_EX, 16MB)
/* (7) ARM9/ARM7 共有メインメモリ空間 */
SET_PROTECTION_A(c7, HW_TWL_MAIN_MEM_SHARED, 16KB)
SET_PROTECTION_B(c7, HW_TWL_MAIN_MEM_SHARED, 16KB)
/* 命令キャッシュ許可 */
mov r0, #REGION_BIT(0, 1, 0, 1, 0, 0, 1, 0)
mcr p15, 0, r0, c2, c0, 1
/* データキャッシュ許可 */
// mov r0, #REGION_BIT(0, 1, 0, 1, 0, 0, 1, 0)
mov r0, #REGION_BIT(0, 1, 1, 1, 0, 0, 1, 0)
mcr p15, 0, r0, c2, c0, 0
/* ライトバッファ許可 */
// mov r0, #REGION_BIT(0, 1, 0, 1, 0, 0, 0, 0)
mov r0, #REGION_BIT(0, 1, 1, 1, 0, 0, 0, 0)
mcr p15, 0, r0, c3, c0, 0
/* 命令アクセス許可 */
ldr r0, =REGION_ACC(RW, RW, NA, RW, NA, RW, RO, NA)
mcr p15, 0, r0, c5, c0, 3
/* データアクセス許可 */
// ldr r0, =REGION_ACC(RW, RW, NA, RW, RW, RW, RO, RW)
ldr r0, =REGION_ACC(RW, RW, RW, RW, RW, RW, RO, RW)
mcr p15, 0, r0, c5, c0, 2
// b @003
@002: /* ハードウェアが NITRO の場合 */
#if 0
/* (1) メインメモリ */
SET_PROTECTION_A(c1, HW_MAIN_MEM_MAIN, 8MB)
SET_PROTECTION_B(c1, HW_MAIN_MEM_MAIN, 8MB)
/* Size will be arranged in OS_InitArena(). */
/* (2) ARM7 専用メインメモリ空間 */
SET_PROTECTION_A(c2, (HW_MAIN_MEM_EX_END - HW_MAIN_MEM_SHARED_SIZE - HW_MAIN_MEM_SUB_SIZE), 128KB)
SET_PROTECTION_B(c2, (HW_MAIN_MEM_EX_END - HW_MAIN_MEM_SHARED_SIZE - HW_MAIN_MEM_SUB_SIZE), 128KB)
/* Base address will be moved in OS_InitArena(). */
/* (3) カートリッジ */
SET_PROTECTION_A(c3, HW_CTRDG_ROM, 128MB)
SET_PROTECTION_B(c3, HW_CTRDG_ROM, 128MB)
/* (7) ARM9/ARM7 共有メインメモリ空間 */
SET_PROTECTION_A(c7, HW_MAIN_MEM_SHARED, 4KB)
SET_PROTECTION_B(c7, HW_MAIN_MEM_SHARED, 4KB)
/* 命令キャッシュ許可 */
mov r0, #REGION_BIT(0, 1, 0, 0, 0, 0, 1, 0)
mcr p15, 0, r0, c2, c0, 1
/* データキャッシュ許可 */
mov r0, #REGION_BIT(0, 1, 0, 0, 0, 0, 1, 0)
mcr p15, 0, r0, c2, c0, 0
/* ライトバッファ許可 */
mov r0, #REGION_BIT(0, 1, 0, 0, 0, 0, 0, 0)
mcr p15, 0, r0, c3, c0, 0
/* 命令アクセス許可 */
ldr r0, =REGION_ACC(RW, RW, NA, NA, NA, RW, RO, NA)
mcr p15, 0, r0, c5, c0, 3
/* データアクセス許可 */
ldr r0, =REGION_ACC(RW, RW, NA, RW, RW, RW, RO, RW)
mcr p15, 0, r0, c5, c0, 2
#endif
@003: /* プロテクションユニット及びキャッシュ使用許可設定 */
mrc p15, 0, r0, c1, c0, 0
ldr r1, = HW_C1_ICACHE_ENABLE \
| HW_C1_DCACHE_ENABLE \
| HW_C1_CACHE_ROUND_ROBIN \
| HW_C1_PROTECT_UNIT_ENABLE
orr r0, r0, r1
mcr p15, 0, r0, c1, c0, 0
/* キャッシュの内容を破棄 */
mov r1, #0
mcr p15, 0, r1, c7, c6, 0
mcr p15, 0, r1, c7, c5, 0
bx lr
}
/*---------------------------------------------------------------------------*
Name: TwlStartUp
Description: hook for user start up
Arguments: None
Returns: None.
*---------------------------------------------------------------------------*/
SDK_WEAK_SYMBOL void TwlStartUp(void)
{
}
/*---------------------------------------------------------------------------*
Name: OSi_ReferSymbol
Description: used by SDK_REFER_SYMBOL macro to avoid dead-strip.
Arguments: symbol unused
Returns: None.
*---------------------------------------------------------------------------*/
void OSi_ReferSymbol(void *symbol)
{
#pragma unused(symbol)
}

View File

@ -0,0 +1,32 @@
#! make -f
#----------------------------------------------------------------------------
# Project: TwlIPL - libraries - init
# File: Makefile
#
# Copyright 2007 Nintendo. All rights reserved.
#
# These coded instructions, statements, and computer programs contain
# proprietary information of Nintendo of America Inc. and/or Nintendo
# Company Ltd., and are protected by Federal copyright law. They may
# not be disclosed to third parties or copied or duplicated in any form,
# in whole or in part, without the prior written consent of Nintendo.
#
# $Date:: $
# $Rev:$
# $Author:$
#----------------------------------------------------------------------------
include $(TWLIPL_ROOT)/build/buildtools/commondefs
#----------------------------------------------------------------------------
SUBDIRS = ARM9 \
ARM7 \
#----------------------------------------------------------------------------
include $(TWLIPL_ROOT)/build/buildtools/modulerules
#===== End of Makefile =====

View File

@ -0,0 +1,60 @@
#! make -f
#----------------------------------------------------------------------------
# Project: TwlFirm - libraries - mi
# File: Makefile
#
# Copyright 2007 Nintendo. All rights reserved.
#
# These coded instructions, statements, and computer programs contain
# proprietary information of Nintendo of America Inc. and/or Nintendo
# Company Ltd., and are protected by Federal copyright law. They may
# not be disclosed to third parties or copied or duplicated in any form,
# in whole or in part, without the prior written consent of Nintendo.
#
# $Date:: $
# $Rev:$
# $Author:$
#----------------------------------------------------------------------------
SUBDIRS =
SUBMAKES =
#----------------------------------------------------------------------------
# build ARM & THUMB libraries
FIRM_CODEGEN_ALL ?= TRUE
SRCDIR = . ../common
SRCS = \
mi_init_mainMemory.c \
mi_loader.c \
mi_exDma.c \
TARGET_LIB = libmi$(FIRM_LIBSUFFIX).a
include $(TWLIPL_ROOT)/build/buildtools/commondefs
INSTALL_TARGETS = $(TARGETS)
INSTALL_DIR = $(FIRM_INSTALL_LIBDIR)
ifdef NITRO_CALLTRACE
CCFLAGS += -DOS_PROFILE_AVAILABLE -DOS_PROFILE_CALL_TRACE
endif
ifdef NITRO_FUNCTIONCOST
CCFLAGS += -DOS_PROFILE_AVAILABLE -DOS_PROFILE_FUNCTION_COST
endif
ifdef NITRO_TCM_APPLY
CCFLAGS += -DSDK_TCM_APPLY
endif
#----------------------------------------------------------------------------
do-build: $(TARGETS)
include $(TWLIPL_ROOT)/build/buildtools/modulerules
#===== End of Makefile =====

View File

@ -0,0 +1,160 @@
/*---------------------------------------------------------------------------*
Project: TwlIPL - libraries - mi
File: mi_init_mainMemory.c
Copyright 2007 Nintendo. All rights reserved.
These coded instructions, statements, and computer programs contain
proprietary information of Nintendo of America Inc. and/or Nintendo
Company Ltd., and are protected by Federal copyright law. They may
not be disclosed to third parties or copied or duplicated in any form,
in whole or in part, without the prior written consent of Nintendo.
$Date:: $
$Rev$
$Author$
*---------------------------------------------------------------------------*/
#include <firm/mi.h>
void MIi_InitMainMemCRCore( void );
/*---------------------------------------------------------------------------*
Name: MIi_IsMainMemoryInitialized
Description:
Arguments: None
Returns: None
*---------------------------------------------------------------------------*/
BOOL MIi_IsMainMemoryInitialized( void )
{
return (BOOL)((reg_MI_EXMEMCNT & REG_MI_EXMEMCNT_CE2_MASK) >> REG_MI_EXMEMCNT_CE2_SHIFT);
}
/*---------------------------------------------------------------------------*
Name: MIi_WaitMainMemoryInitialize
Description:
Arguments: None
Returns: None
*---------------------------------------------------------------------------*/
void MIi_WaitMainMemoryInitialize( void )
{
while( MIi_IsMainMemoryInitialized() == FALSE )
{
}
}
/*---------------------------------------------------------------------------*
Name: MIi_InitMainMemCR
Description: change mainmem into the burst mode
Arguments: None
Returns: None
*---------------------------------------------------------------------------*/
#include <nitro/code32.h>
asm void MIi_InitMainMemCR( BOOL setCR )
{
mov r12, lr
mov r2, r0
mov r0, #0x8000 // low period 0.97ms
bl OS_SpinWaitCpuCycles
ldr r3, =REG_EXMEMCNT_ADDR
mov r1, #REG_MI_EXMEMCNT_CE2_MASK
ldrh r0, [r3]
tst r0, r1
bxne r12
strh r1, [r3]
mov r0, #0x8000 // high period 0.97ms
bl OS_SpinWaitCpuCycles
cmp r2, #FALSE
beq @10
// メインメモリが同期モード時(ハードリセット時)に
// 非同期モードCLK固定でコマンド発行しても大丈夫
ldr r3, =HW_WRAM_AREA - 2
bl MIi_InitMainMemCRCore
#ifdef TWL_PLATFORM_TS
ldr r3, =HW_MAIN_MEM_HI_EX_END - 2
bl MIi_InitMainMemCRCore
#endif // TWL_PLATFORM_TS
@10:
ldr r3, =REG_EXMEMCNT_ADDR
mov r1, #REG_MI_EXMEMCNT_IFM_MASK | REG_MI_EXMEMCNT_CE2_MASK
strh r1, [r3]
bx r12
}
asm void MIi_InitMainMemCRCore( void )
{
// stmfd sp!, { lr }
#ifdef TWL_PLATFORM_BB
mov r2, lr
ldr r0, =MMEM_DCR0_BURST_MODE | MMEM_DCR0_BURST_CONTINUOUS \
| MMEM_DCR0_PARTIAL_REFRESH_NONE | MMEM_DCR0_SB1
ldr r1, =MMEM_DCR1_1ST_R4_W3 | MMEM_DCR1_BURST_WRITE | MMEM_DCR1_BURST_LINER \
| MMEM_DCR1_CLOCK_TRIGGER_UP | MMEM_DCR1_SB1
ldrh lr, [r3]
strh lr, [r3]
strh lr, [r3]
mov lr, r2
ldr r2, =HW_MAIN_MEM | MMEM_DCR2_CLOCK_TRIGGER_UP \
| MMEM_DCR2_BURST_MODE | MMEM_DCR2_BURST_CONTINUOUS \
| MMEM_DCR2_1ST_R4_W3 | MMEM_DCR2_BURST_WRITE | MMEM_DCR2_BURST_LINER \
| MMEM_DCR2_PARTIAL_REFRESH_NONE | MMEM_DCR2_SB1
strh r0, [r3]
strh r1, [r3]
ldrh r3, [r2]
#else // TWL_PLATFORM_TS
mov r2, lr
ldr r0, =MMEM_TCR0
ldr r1, =MMEM_TCR1
ldrh lr, [r3]
strh lr, [r3]
strh lr, [r3]
mov lr, r2
ldr r2, =MMEM_TCR2
strh r0, [r3]
strh r1, [r3]
strh r2, [r3]
#endif // TWL_PLATFORM_TS
// ldmfd sp!, { lr }
bx lr
}
asm void MIi_GetMainMemCR( MIMmemCR* dest )
{
#ifdef TWL_PLATFORM_TS
ldr r3, =HW_WRAM_AREA - 2
ldr r1, =MMEM_TCR0_R
ldrh r2, [r3]
strh r2, [r3]
strh r2, [r3]
strh r1, [r3]
ldrh r1, [r3]
ldrh r2, [r3]
strh r2, [r0, #4]
strh r1, [r0, #2]
ldr r1, =MMEM_TCR0_R
strh r1, [r0, #0]
#endif // TWL_PLATFORM_TS
bx lr
}

View File

@ -0,0 +1,509 @@
/*---------------------------------------------------------------------------*
Project: TwlIPL - libraries - mi
File: mi_loader.c
Copyright 2007 Nintendo. All rights reserved.
These coded instructions, statements, and computer programs contain
proprietary information of Nintendo of America Inc. and/or Nintendo
Company Ltd., and are protected by Federal copyright law. They may
not be disclosed to third parties or copied or duplicated in any form,
in whole or in part, without the prior written consent of Nintendo.
$Date:: $
$Rev$
$Author$
*---------------------------------------------------------------------------*/
#include <twl.h>
#include <firm.h>
#include <firm/format/format_rom.h>
/*
PROFILE_ENABLE
main.cかどこかにu32 profile[256]; u32 pf_cnt;
*/
//#define PROFILE_ENABLE
#ifdef SDK_FINALROM // FINALROMで無効化
#undef PROFILE_ENABLE
#endif
#ifdef PROFILE_ENABLE
#define PROFILE_PXI_SEND 0x10000000
#define PROFILE_PXI_RECV 0x20000000
#define PROFILE_SHA1 0xa0000000
#define PROFILE_RSA 0xb0000000
extern u32 profile[];
extern u32 pf_cnt;
#endif
#define PXI_FIFO_TAG_DATA PXI_FIFO_TAG_USER_0
static ROM_Header* const rh = (ROM_Header*)HW_TWL_ROM_HEADER_BUF;
#define HEADER_SIZE 0x1000
#define AUTH_SIZE 0xe00
#define RSA_BLOCK_SIZE 128
#define HASH_UNIT 0x1000 // TODO: optimizing to maximize cache efficiency
static const u8 s_digestDefaultKey[ SVC_SHA1_BLOCK_SIZE ] = {
0x21, 0x06, 0xc0, 0xde,
0xba, 0x98, 0xce, 0x3f,
0xa6, 0x92, 0xe3, 0x9d,
0x46, 0xf2, 0xed, 0x01,
0x76, 0xe3, 0xcc, 0x08,
0x56, 0x23, 0x63, 0xfa,
0xca, 0xd4, 0xec, 0xdf,
0x9a, 0x62, 0x78, 0x34,
0x8f, 0x6d, 0x63, 0x3c,
0xfe, 0x22, 0xca, 0x92,
0x20, 0x88, 0x97, 0x23,
0xd2, 0xcf, 0xae, 0xc2,
0x32, 0x67, 0x8d, 0xfe,
0xca, 0x83, 0x64, 0x98,
0xac, 0xfd, 0x3e, 0x37,
0x87, 0x46, 0x58, 0x24,
};
/*---------------------------------------------------------------------------*
Name: CheckRomCertificate
Description: check the certification in the ROM
ROMヘッダに付加された証明書のチェックを行います
makerom.TWL内のコードに依存します
Arguments: pool pointer to the SVCSignHeapContext
pCert pointer to the certification
pCAPubKey pointer to the public key for the certification
gameCode initial code
Returns: TRUE if success
*---------------------------------------------------------------------------*/
static BOOL CheckRomCertificate( SVCSignHeapContext* pool, const RomCertificate *pCert, const void* pCAPubKey, u32 gameCode )
{
u8 digest[DIGEST_SIZE_SHA1];
u8 md[DIGEST_SIZE_SHA1];
int i;
BOOL result = TRUE;
// 証明書ヘッダのマジックナンバーチェック
if( pCert->header.magicNumber != TWL_ROM_CERT_MAGIC_NUMBER ||
// 証明書ヘッダとROMヘッダのゲームコード一致チェック
pCert->header.gameCode != gameCode )
{
result = FALSE;
}
// 証明書署名チェック
SVC_DecryptSign( pool, &digest, pCert->sign, pCAPubKey );
// ダイジェストの計算
SVC_CalcSHA1( md, pCert, ROM_CERT_SIGN_OFFSET );
// 比較
for (i = 0; i < DIGEST_SIZE_SHA1; i++)
{
if ( md[i] != digest[i] )
{
result = FALSE;
}
}
return result;
}
/*---------------------------------------------------------------------------*
Name: MIi_LoadBuffer
Description: receive data from ARM7 and store(move) via WRAM[B]
LoadBufferメカニズムでARM7から受け取ります
SVCSHA1Contextを指定していた場合SHA1の
[LoadBufferメカニズム]
WRAM[B]ARM7,ARM9間のデータ転送を行います
WRAM[B]
1ARM7から
FIRM_PXI_ID_LOAD_PIRIODを受信します
ARM9は受信後にそのスロットの使用権をARM9に変更してデータを
()使
ARM7に戻します
[使]
WRAM[B]ARM7側に倒しておくこと
[]
offsetとsizeはARM7から通知されません
SRLファイルを読み込む場合はROMヘッダを参照できれば十分です
(ROMヘッダ部分は元から知っているはず)
:
ARM7/ARM9側で歩調を合わせられることを
()
PXIコールバック
APIがデータをWRAMに格納した後
destとsizeを通知するという形でOKではないか
()
Arguments: dest destination address for received data
size size to load
ctx context for SHA1 if execute SVC_SHA1Update
Returns: TRUE if success
*---------------------------------------------------------------------------*/
static BOOL MIi_LoadBuffer(u8* dest, u32 size, SVCSHA1Context *ctx)
{
u8* base = (u8*)HW_FIRM_LOAD_BUFFER_BASE;
static int count = 0;
while (size > 0)
{
u8* src = base + count * HW_FIRM_LOAD_BUFFER_UNIT_SIZE;
u32 unit = size < HW_FIRM_LOAD_BUFFER_UNIT_SIZE ? size : HW_FIRM_LOAD_BUFFER_UNIT_SIZE;
//OS_TPrintf("%s: src=%X, unit=%X\n", __func__, src, unit);
if ( PXI_RecvID() != FIRM_PXI_ID_LOAD_PIRIOD )
{
return FALSE;
}
#ifdef PROFILE_ENABLE
// x2...: after PXI
profile[pf_cnt++] = PROFILE_PXI_RECV | FIRM_PXI_ID_LOAD_PIRIOD;
profile[pf_cnt++] = (u32)OS_TicksToMicroSeconds(OS_GetTick());
#endif
MIi_SetWramBankMaster_B(count, MI_WRAM_ARM9);
if (ctx)
{
int done;
for (done = 0; done < unit; done += HASH_UNIT)
{
u8* s = src + done;
u8* d = dest + done;
u32 u = unit < done + HASH_UNIT ? unit - done : HASH_UNIT;
MI_CpuCopyFast( s, d, u );
SVC_SHA1Update( ctx, s, u );
}
}
else
{
MI_CpuCopyFast( src, dest, unit );
}
MI_CpuClearFast( src, unit );
DC_FlushRange( src, unit );
#ifdef PROFILE_ENABLE
// x2...: after copy & clear
profile[pf_cnt++] = (u32)OS_TicksToMicroSeconds(OS_GetTick());
#endif
MIi_SetWramBankMaster_B(count, MI_WRAM_ARM7);
count = (count + 1) % HW_FIRM_LOAD_BUFFER_UNIT_NUMS;
size -= unit;
dest += unit;
}
return TRUE;
}
/*---------------------------------------------------------------------------*
Name: MI_LoadHeader
Description: load header
SRLのROMヘッダ部分をARM7から受け取り
ARM7から FIRM_PXI_ID_LOAD_HEADER
ARM7へ FIRM_PXI_ID_AUTH_HEADER
ROMヘッダが格納
seedデータを16バイト送信します
makerom.TWLまたはIPLの仕様に依存します
Arguments: pool pointer to the pool info for SVCSignHeapContext
rsa_key key address
Returns: TRUE if success
*---------------------------------------------------------------------------*/
BOOL MI_LoadHeader( SVCSignHeapContext* pool, const void* rsa_key )
{
SVCSHA1Context ctx;
u8 md[DIGEST_SIZE_SHA1];
SignatureData sd;
int i;
BOOL result = TRUE;
SVC_SHA1Init(&ctx);
#ifdef PROFILE_ENABLE
pf_cnt = 0x10;
#endif
// load header (hash target)
if ( PXI_RecvID() != FIRM_PXI_ID_LOAD_HEADER ||
#ifdef PROFILE_ENABLE
// 10: after PXI
((profile[pf_cnt++] = PROFILE_PXI_RECV | FIRM_PXI_ID_LOAD_HEADER), FALSE) ||
((profile[pf_cnt++] = (u32)OS_TicksToMicroSeconds(OS_GetTick())), FALSE) ||
#endif
!MIi_LoadBuffer( (u8*)rh, AUTH_SIZE, &ctx ) )
{
return FALSE;
}
SVC_SHA1GetHash(&ctx, md);
#ifdef PROFILE_ENABLE
// 1x: after HMAC
profile[pf_cnt++] = PROFILE_SHA1; // checkpoint
profile[pf_cnt++] = (u32)OS_TicksToMicroSeconds(OS_GetTick());
#endif
// load header (remain)
if ( !MIi_LoadBuffer( (u8*)rh + AUTH_SIZE, HEADER_SIZE - AUTH_SIZE, NULL ) )
{
return FALSE;
}
// コンテンツ証明書
if ( CheckRomCertificate( pool, &rh->certificate, rsa_key, *(u32*)rh->s.game_code ) )
{
rsa_key = rh->certificate.pubKeyMod; // ヘッダ用の鍵の取り出し
}
else
{
// とりあえずコンテンツ証明書用の鍵がそのまま使えると仮定
}
// ヘッダ署名チェック
SVC_DecryptSign( pool, &sd, rh->signature, rsa_key );
for (i = 0; i < DIGEST_SIZE_SHA1; i++)
{
if ( md[i] != sd.digest[i] )
{
result = FALSE;
}
}
#ifdef PROFILE_ENABLE
// 1x: after RSA, before PXI
profile[pf_cnt++] = PROFILE_RSA; // checkpoint
profile[pf_cnt++] = (u32)OS_TicksToMicroSeconds(OS_GetTick());
profile[pf_cnt++] = (u32)PROFILE_PXI_SEND | FIRM_PXI_ID_AUTH_HEADER; // checkpoint
#endif
if ( result )
{
PXI_NotifyID( FIRM_PXI_ID_AUTH_HEADER );
PXI_SendDataByFifo( PXI_FIFO_TAG_DATA, sd.aes_key_seed, AES_BLOCK_SIZE );
// DS互換ヘッダコピー
MI_CpuCopyFast( rh, (void*)HW_ROM_HEADER_BUF, HW_ROM_HEADER_BUF_END-HW_ROM_HEADER_BUF );
}
MI_CpuClear8(&sd, sizeof(sd));
MI_CpuClear8(&md, sizeof(md));
return result;
}
/*---------------------------------------------------------------------------*
Name: MIi_GetTransferSize
Description: get size to transfer once
AES領域をまたぐ場合は (
)
makerom.TWLまたはIPLの使用に依存します
Arguments: offset offset of region from head of ROM_Header
size size of region
Returns: size to transfer once
*---------------------------------------------------------------------------*/
static u32 MIi_GetTransferSize( u32 offset, u32 size )
{
u32 aes_offset = rh->s.aes_target_rom_offset;
u32 aes_end = aes_offset + rh->s.aes_target_size;
u32 end = offset + size;
if ( rh->s.enable_aes )
{
if ( offset >= aes_offset && offset < aes_end )
{
if ( end > aes_end )
{
size = aes_end - offset;
}
}
else
{
if ( offset < aes_offset && offset + size > aes_offset )
{
size = aes_offset - offset;
}
}
}
return size;
}
/*---------------------------------------------------------------------------*
Name: MIi_LoadModule
Description: receive module from ARM7 and store(move) via WRAM[B]
MIi_LoadBufferの上位APIです
AES境界をまたぐ場合は2LoadBufferに分割します
SHA1の計算範囲全体を
便
Arguments: dest destination address for received data
offset offset from head of ROM_Header
size size to load
digest digest to compare
Returns: TRUE if success
*---------------------------------------------------------------------------*/
static /*inline*/ BOOL MIi_LoadModule(void* dest, u32 offset, u32 size, const u8 digest[DIGEST_SIZE_SHA1])
{
SVCHMACSHA1Context ctx;
u8 md[DIGEST_SIZE_SHA1];
int i;
BOOL result = TRUE;
SVC_HMACSHA1Init(&ctx, s_digestDefaultKey, SVC_SHA1_BLOCK_SIZE );
while ( size > 0 )
{
u32 unit = MIi_GetTransferSize( offset, size );
if ( !MIi_LoadBuffer( dest, unit, &ctx.sha1_ctx ) ) // UpdateはSHA1と同じ処理
{
return FALSE;
}
dest = (u8*)dest + unit;
offset += unit;
size -= unit;
}
SVC_HMACSHA1GetHash(&ctx, md);
#ifdef PROFILE_ENABLE
// 3x: after SHA1
profile[pf_cnt++] = PROFILE_SHA1; // checkpoint
profile[pf_cnt++] = (u32)OS_TicksToMicroSeconds(OS_GetTick());
#endif
for (i = 0; i < DIGEST_SIZE_SHA1; i++)
{
if (md[i] != digest[i])
{
result = FALSE;
}
}
MI_CpuClear8(md, DIGEST_SIZE_SHA1);
return result;
}
/*---------------------------------------------------------------------------*
Name: MI_LoadStatic
Description: load static binary
ARM9/ARM7のStaticおよびLTD Staticを受信します
ARM7からFIRM_PXI_ID_LOAD_*_STATICを受信します
ARM7へFIRM_PXI_ID_AUTH_*_STATICを送信
0PXI通信すら行いません
APIを呼び出す前にROMヘッダが
Arguments: None
Returns: TRUE if success
*---------------------------------------------------------------------------*/
BOOL MI_LoadStatic( void )
{
// load static
if ( PXI_RecvID() != FIRM_PXI_ID_LOAD_STATIC )
{
return FALSE;
}
#ifdef PROFILE_ENABLE
// 30: after PXI
pf_cnt = 0x30;
profile[pf_cnt++] = PROFILE_PXI_RECV | FIRM_PXI_ID_LOAD_STATIC;
profile[pf_cnt++] = (u32)OS_TicksToMicroSeconds(OS_GetTick());
#endif
// load ARM9 static region
if ( rh->s.main_size > 0 )
{
#ifdef PROFILE_ENABLE
// 31: before PXI
profile[pf_cnt++] = (u32)OS_TicksToMicroSeconds(OS_GetTick());
#endif
if ( !MIi_LoadModule(rh->s.main_ram_address, rh->s.main_rom_offset, rh->s.main_size, rh->s.main_static_digest) )
{
return FALSE;
}
}
// load ARM7 static region
if ( rh->s.sub_size > 0 )
{
#ifdef PROFILE_ENABLE
// 50: before PXI
pf_cnt = 0x50;
profile[pf_cnt++] = (u32)OS_TicksToMicroSeconds(OS_GetTick());
#endif
if ( !MIi_LoadModule( rh->s.sub_ram_address, rh->s.sub_rom_offset, rh->s.sub_size, rh->s.sub_static_digest ) )
{
return FALSE;
}
}
// load ARM9 extended static region
if ( rh->s.main_ltd_size > 0 )
{
#ifdef PROFILE_ENABLE
// 70: before PXI
pf_cnt = 0x70;
profile[pf_cnt++] = (u32)OS_TicksToMicroSeconds(OS_GetTick());
#endif
if ( !MIi_LoadModule( rh->s.main_ltd_ram_address, rh->s.main_ltd_rom_offset, rh->s.main_ltd_size, rh->s.main_ltd_static_digest ) )
{
return FALSE;
}
}
// load ARM7 extended static region
if ( rh->s.sub_ltd_size > 0 )
{
#ifdef PROFILE_ENABLE
// 90: before PXI
pf_cnt = 0x90;
profile[pf_cnt++] = (u32)OS_TicksToMicroSeconds(OS_GetTick());
#endif
if ( !MIi_LoadModule( rh->s.sub_ltd_ram_address, rh->s.sub_ltd_rom_offset, rh->s.sub_ltd_size, rh->s.sub_ltd_static_digest ) )
{
return FALSE;
}
}
#ifdef PROFILE_ENABLE
// 9x: before PXI
profile[pf_cnt++] = (u32)OS_TicksToMicroSeconds(OS_GetTick());
profile[pf_cnt++] = (u32)PROFILE_PXI_SEND | FIRM_PXI_ID_AUTH_STATIC; // checkpoint
#endif
PXI_NotifyID( FIRM_PXI_ID_AUTH_STATIC );
return TRUE;
}
/*---------------------------------------------------------------------------*
Name: MI_Boot
Description: boot
ROMヘッダの情報を引数にOSi_Bootを呼び出すだけです
APIを呼び出す前にROMヘッダが
Arguments: None
Returns: None
*---------------------------------------------------------------------------*/
void MI_Boot( void )
{
OSi_Boot( rh->s.main_entry_address, (MIHeader_WramRegs*)rh->s.main_wram_config_data );
}

View File

@ -0,0 +1,31 @@
#! make -f
#----------------------------------------------------------------------------
# Project: TwlIPL - libraries - mi
# File: Makefile
#
# Copyright 2007 Nintendo. All rights reserved.
#
# These coded instructions, statements, and computer programs contain
# proprietary information of Nintendo of America Inc. and/or Nintendo
# Company Ltd., and are protected by Federal copyright law. They may
# not be disclosed to third parties or copied or duplicated in any form,
# in whole or in part, without the prior written consent of Nintendo.
#
# $Date:: $
# $Rev:$
# $Author:$
#----------------------------------------------------------------------------
include $(TWLIPL_ROOT)/build/buildtools/commondefs
#----------------------------------------------------------------------------
SUBDIRS = ARM9
#----------------------------------------------------------------------------
include $(TWLIPL_ROOT)/build/buildtools/modulerules
#===== End of Makefile =====

View File

@ -0,0 +1,286 @@
/*---------------------------------------------------------------------------*
Project: TwlIPL - libraries - mi
File: mi_init_mainMemory.c
Copyright 2007 Nintendo. All rights reserved.
These coded instructions, statements, and computer programs contain
proprietary information of Nintendo of America Inc. and/or Nintendo
Company Ltd., and are protected by Federal copyright law. They may
not be disclosed to third parties or copied or duplicated in any form,
in whole or in part, without the prior written consent of Nintendo.
$Date:: $
$Rev$
$Author$
*---------------------------------------------------------------------------*/
#include <firm/mi.h>
static u16 intervalTable[] =
{
1, 1, 1, 1,
};
static u32 prescaleTable[] =
{
MI_NDMA_INTERVAL_PS_1,
MI_NDMA_INTERVAL_PS_1,
MI_NDMA_INTERVAL_PS_1,
MI_NDMA_INTERVAL_PS_1,
};
//================================================================================
// memory oparation using DMA (sync)
//================================================================================
/*---------------------------------------------------------------------------*
Name: MIi_ExDmaSendAsync
Description: send data with DMA
async version
Arguments: dmaNo : DMA channel No.
dest : destination address
src : source address
size : size (byte)
Returns: None
*---------------------------------------------------------------------------*/
void MIi_ExDmaSendAsync( u32 dmaNo, const void *src, void *dest, u32 size )
{
u32 idx = dmaNo - MI_EXDMA_CH_MIN;
{
u32 blockSize = MI_NDMA_BWORD_8;
u32 interval = intervalTable[idx];
u32 prescale = prescaleTable[idx];
MIi_ExDmaSendAsyncCore( dmaNo, src, dest, size, size,
blockSize, interval, prescale,
MI_NDMA_CONTINUOUS_OFF, MI_NDMA_SRC_RELOAD_DISABLE, MI_NDMA_DEST_RELOAD_DISABLE,
MI_NDMA_IMM_MODE_ON );
}
}
/*---------------------------------------------------------------------------*
Name: MIi_ExDmaRecvAsync
Description: receive data with DMA
async version
Arguments: dmaNo : DMA channel No.
dest : destination address
src : source address
size : size (byte)
Returns: None
*---------------------------------------------------------------------------*/
void MIi_ExDmaRecvAsync( u32 dmaNo, const void *src, void *dest, u32 size )
{
u32 idx = dmaNo - MI_EXDMA_CH_MIN;
{
u32 blockSize = MI_NDMA_BWORD_8;
u32 interval = intervalTable[idx];
u32 prescale = prescaleTable[idx];
MIi_ExDmaRecvAsyncCore( dmaNo, src, dest, size, size,
blockSize, interval, prescale,
MI_NDMA_CONTINUOUS_OFF, MI_NDMA_SRC_RELOAD_DISABLE, MI_NDMA_DEST_RELOAD_DISABLE,
MI_NDMA_IMM_MODE_ON );
}
}
//----------------- internel functions -------------------
/*---------------------------------------------------------------------------*
Name: MIi_ExDmaSendAsyncCore
Description: send data with DMA
async version
Arguments: dmaNo : DMA channel No.
dest : destination address
src : source address
size : size (byte)
blockSize : block size
Returns: None
*---------------------------------------------------------------------------*/
void MIi_ExDmaSendAsyncCore( u32 dmaNo, const void *src, void *dest, u32 size, u32 oneShotSize,
u32 blockSize, u32 interval, u32 prescale,
u32 continuous, u32 srcRld, u32 destRld,
u32 timing )
{
MIi_WaitExDma( dmaNo );
MIi_SetExDmaParams( dmaNo, src, dest, size, oneShotSize,
blockSize, interval, prescale,
continuous, srcRld, destRld,
timing,
0, MI_NDMA_SRC_INC, MI_NDMA_DEST_FIX );
}
/*---------------------------------------------------------------------------*
Name: MIi_ExDmaRecvAsyncCore
Description: receive data with DMA
async version
Arguments: dmaNo : DMA channel No.
dest : destination address
src : source address
size : size (byte)
blockSize : block size
Returns: None
*---------------------------------------------------------------------------*/
void MIi_ExDmaRecvAsyncCore( u32 dmaNo, const void *src, void *dest, u32 size, u32 oneShotSize,
u32 blockSize, u32 interval, u32 prescale,
u32 continuous, u32 srcRld, u32 destRld,
u32 timing )
{
MIi_WaitExDma( dmaNo );
MIi_SetExDmaParams( dmaNo, src, dest, size, oneShotSize,
blockSize, interval, prescale,
continuous, srcRld, destRld,
timing,
0, MI_NDMA_SRC_FIX, MI_NDMA_DEST_INC );
}
/*---------------------------------------------------------------------------*
Name: MIi_SetExDmaParams
Description: set DMA
Arguments: dmaNo : DMA channel No.
dest : destination address
src : source address
size : size (byte)
blockSize : block size
Returns: None
*---------------------------------------------------------------------------*/
void MIi_SetExDmaParams( u32 dmaNo, const void *src, void *dest, u32 size, u32 oneShotSize,
u32 blockSize, u32 interval, u32 prescale,
u32 continuous, u32 srcRld, u32 destRld,
u32 timing,
u32 fillData, u32 srcDir, u32 destDir )
{
u32 idx = dmaNo - MI_EXDMA_CH_MIN;
if ( idx < MI_EXDMA_CH_NUM )
{
OSIntrMode enabled = OS_DisableInterrupts();
MIExDmaChanRegs *reg = &((MIExDmaChanRegs*)REG_NDMA0SAD_ADDR)[idx];
reg->src = src;
reg->dest = dest;
reg->fillData = fillData;
reg->totalCount = size / 4;
reg->wordCount = oneShotSize / 4;
reg->blockInterval = (interval << REG_MI_NDMA0BCNT_ICNT_SHIFT) | prescale;
reg->ctrl = blockSize
| srcDir | destDir
| srcRld | destRld
| continuous
| timing
| MI_NDMA_ENABLE | MI_NDMA_IF_ENABLE;
(void)OS_RestoreInterrupts(enabled);
}
}
//================================================================================
// DMA WAIT/STOP
//================================================================================
/*---------------------------------------------------------------------------*
Name: MIi_IsExDmaBusy
Description: check whether extended DMA is busy or not
Arguments: dmaNo : DMA channel No.
Returns: TRUE if extended DMA is busy, FALSE if not
*---------------------------------------------------------------------------*/
BOOL MIi_IsExDmaBusy( u32 dmaNo )
{
u32 idx = dmaNo - MI_EXDMA_CH_MIN;
if ( idx < MI_EXDMA_CH_NUM )
{
MIExDmaChanRegs *reg = &((MIExDmaChanRegs*)REG_NDMA0SAD_ADDR)[idx];
return (BOOL)((reg->ctrl & REG_MI_NDMA0CNT_E_MASK) >> REG_MI_NDMA0CNT_E_SHIFT);
}
return FALSE;
}
/*---------------------------------------------------------------------------*
Name: MIi_WaitExDma
Description: wait while extended DMA is busy
Arguments: dmaNo : DMA channel No.
Returns: None
*---------------------------------------------------------------------------*/
void MIi_WaitExDma( u32 dmaNo )
{
u32 idx = dmaNo - MI_EXDMA_CH_MIN;
if ( idx < MI_EXDMA_CH_NUM )
{
MIExDmaChanRegs *reg = &((MIExDmaChanRegs*)REG_NDMA0SAD_ADDR)[idx];
while (reg->ctrl & REG_MI_NDMA0CNT_E_MASK)
{
}
}
}
/*---------------------------------------------------------------------------*
Name: MIi_StopDma
Description: stop extended DMA
Arguments: dmaNo : DMA channel No.
Returns: None
*---------------------------------------------------------------------------*/
void MIi_StopExDma( u32 dmaNo )
{
MIi_StopExDmaAsync( dmaNo );
MIi_WaitExDma( dmaNo );
}
/*---------------------------------------------------------------------------*
Name: MIi_StopDmaAsync
Description: stop extended DMA
async version
Arguments: dmaNo : DMA channel No.
Returns: None
*---------------------------------------------------------------------------*/
void MIi_StopExDmaAsync( u32 dmaNo )
{
OSIntrMode enabled = OS_DisableInterrupts();
u32 idx = dmaNo - MI_EXDMA_CH_MIN;
if ( idx < MI_EXDMA_CH_NUM )
{
MIExDmaChanRegs *reg = &((MIExDmaChanRegs*)REG_NDMA0SAD_ADDR)[idx];
reg->ctrl &= ~MI_NDMA_ENABLE;
}
(void)OS_RestoreInterrupts(enabled);
}

View File

@ -0,0 +1,62 @@
#! make -f
#----------------------------------------------------------------------------
# Project: TwlFirm - libraries_sp - os
# File: Makefile
#
# Copyright 2007 Nintendo. All rights reserved.
#
# These coded instructions, statements, and computer programs contain
# proprietary information of Nintendo of America Inc. and/or Nintendo
# Company Ltd., and are protected by Federal copyright law. They may
# not be disclosed to third parties or copied or duplicated in any form,
# in whole or in part, without the prior written consent of Nintendo.
#
# $Date:: $
# $Rev:$
# $Author:$
#----------------------------------------------------------------------------
SUBDIRS =
#SUBMAKES = Makefile.CALLTRACE \
# Makefile.FUNCTIONCOST
#----------------------------------------------------------------------------
# build ARM & THUMB libraries
FIRM_CODEGEN_ALL ?= TRUE
# Codegen for sub processer
FIRM_PROC = ARM7
SRCDIR = ../common .
SRCS = \
os_init_firm.c \
os_boot.c \
TARGET_LIB = libos_sp$(FIRM_LIBSUFFIX).a
#----------------------------------------------------------------------------
# DEBUG版ビルドの場合、RELEASE版でビルドして
# DEBUG版のライブラリを装います。
ifdef NITRO_DEBUG
NITRO_BUILD_TYPE = RELEASE
endif
include $(TWLIPL_ROOT)/build/buildtools/commondefs
INSTALL_TARGETS = $(TARGETS)
INSTALL_DIR = $(FIRM_INSTALL_LIBDIR)
#----------------------------------------------------------------------------
do-build: $(TARGETS)
include $(TWLIPL_ROOT)/build/buildtools/modulerules
#===== End of Makefile =====

View File

@ -0,0 +1,60 @@
#! make -f
#----------------------------------------------------------------------------
# Project: TwlFirm - libraries - os
# File: Makefile
#
# Copyright 2007 Nintendo. All rights reserved.
#
# These coded instructions, statements, and computer programs contain
# proprietary information of Nintendo of America Inc. and/or Nintendo
# Company Ltd., and are protected by Federal copyright law. They may
# not be disclosed to third parties or copied or duplicated in any form,
# in whole or in part, without the prior written consent of Nintendo.
#
# $Date:: $
# $Rev:$
# $Author:$
#----------------------------------------------------------------------------
SUBDIRS =
SUBMAKES =
#----------------------------------------------------------------------------
# build ARM & THUMB libraries
FIRM_CODEGEN_ALL ?= TRUE
SRCDIR = ../common .
SRCS = \
os_init_firm.c \
os_boot.c \
os_cache_tag.c \
TARGET_LIB = libos$(FIRM_LIBSUFFIX).a
include $(TWLIPL_ROOT)/build/buildtools/commondefs
INSTALL_TARGETS = $(TARGETS)
INSTALL_DIR = $(FIRM_INSTALL_LIBDIR)
ifdef NITRO_CALLTRACE
CCFLAGS += -DOS_PROFILE_AVAILABLE -DOS_PROFILE_CALL_TRACE
endif
ifdef NITRO_FUNCTIONCOST
CCFLAGS += -DOS_PROFILE_AVAILABLE -DOS_PROFILE_FUNCTION_COST
endif
ifdef NITRO_TCM_APPLY
CCFLAGS += -DSDK_TCM_APPLY
endif
#----------------------------------------------------------------------------
do-build: $(TARGETS)
include $(TWLIPL_ROOT)/build/buildtools/modulerules
#===== End of Makefile =====

View File

@ -0,0 +1,269 @@
/*---------------------------------------------------------------------------*
Project: TwlFirm - OS
File: os_cache_tag.c
Copyright 2007 Nintendo. All rights reserved.
These coded instructions, statements, and computer programs contain
proprietary information of Nintendo of America Inc. and/or Nintendo
Company Ltd., and are protected by Federal copyright law. They may
not be disclosed to third parties or copied or duplicated in any form,
in whole or in part, without the prior written consent of Nintendo.
$Date:: $
$Rev$
$Author$
*---------------------------------------------------------------------------*/
#include <firm/os/ARM9/os_cache_tag.h>
#include <nitro/code32.h>
//===========================================================================
// DATA CACHE (for specified range)
//===========================================================================
/*---------------------------------------------------------------------------*
Name: DC_ClearTagAll
Description: clear tag in data cache
Arguments: None
Returns: None.
*---------------------------------------------------------------------------*/
void DC_ClearTagAll( void )
{
DC_FillTagAll( 0 );
}
/*---------------------------------------------------------------------------*
Name: DC_FillTagAll
Description: clear tag in data cache
Arguments: data : fill data
Returns: None.
*---------------------------------------------------------------------------*/
asm void DC_FillTagAll( u32 data )
{
mov r12, #0
@1:
mov r2, #0
@2:
orr r3, r2, r12
mcr p15, 3, r3, c15, c0, 0 // set index
mcr p15, 3, r0, c15, c2, 0 // clear tag
add r2, r2, #HW_CACHE_LINE_SIZE
cmp r2, #HW_DCACHE_SIZE/4
blt @2
add r12, r12, #1<<HW_C7_CACHE_SET_NO_SHIFT
cmp r12, #0
bne @1
bx lr
}
/*---------------------------------------------------------------------------*
Name: DC_ClearDataAll
Description: clear data in data cache
Arguments: None
Returns: None.
*---------------------------------------------------------------------------*/
void DC_ClearDataAll( void )
{
DC_FillDataAll( 0 );
}
/*---------------------------------------------------------------------------*
Name: DC_FillDataAll
Description: fill data in data cache
Arguments: data : fill data
Returns: None.
*---------------------------------------------------------------------------*/
asm void DC_FillDataAll( u32 data )
{
mov r12, #0
@1:
mov r2, #0
@2:
orr r3, r2, r12
mcr p15, 3, r3, c15, c0, 0 // set index
mcr p15, 3, r0, c15, c4, 0 // clear data
add r2, r2, #4
cmp r2, #HW_DCACHE_SIZE/4
blt @2
add r12, r12, #1<<HW_C7_CACHE_SET_NO_SHIFT
cmp r12, #0
bne @1
bx lr
}
/*---------------------------------------------------------------------------*
Name: DC_GetTagAndDataAll
Description: get tag and data in data cache
Arguments: tag tag address
data data address
Returns: None.
*---------------------------------------------------------------------------*/
asm void DC_GetTagAndDataAll( void* tag, void* data )
{
mov r12, #0
@1:
mov r2, #0
@2:
orr r3, r2, r12
mcr p15, 3, r3, c15, c0, 0 // set index
tst r2, #HW_CACHE_LINE_SIZE - 1
mrceq p15, 3, r3, c15, c2, 0 // get tag
streq r3, [r0], #4
mrc p15, 3, r3, c15, c4, 0 // get data
str r3, [r1], #4
add r2, r2, #4
cmp r2, #HW_DCACHE_SIZE/4
blt @2
add r12, r12, #1<<HW_C7_CACHE_SET_NO_SHIFT
cmp r12, #0
bne @1
bx lr
}
//===========================================================================
// INSTRUCTION CACHE
//===========================================================================
/*---------------------------------------------------------------------------*
Name: IC_ClearTagAll
Description: clear tag in instruction cache
Arguments: None
Returns: None.
*---------------------------------------------------------------------------*/
void IC_ClearTagAll( void )
{
IC_FillTagAll( 0 );
}
/*---------------------------------------------------------------------------*
Name: IC_FillTagAll
Description: fill tag in instruction cache
Arguments: None
Returns: None.
*---------------------------------------------------------------------------*/
asm void IC_FillTagAll( u32 data )
{
mov r12, #0
@1:
mov r2, #0
@2:
orr r3, r2, r12
mcr p15, 3, r3, c15, c0, 0 // set index
mcr p15, 3, r0, c15, c1, 0 // clear tag
add r2, r2, #HW_CACHE_LINE_SIZE
cmp r2, #HW_ICACHE_SIZE/4
blt @2
add r12, r12, #1<<HW_C7_CACHE_SET_NO_SHIFT
cmp r12, #0
bne @1
bx lr
}
/*---------------------------------------------------------------------------*
Name: IC_ClearInstructionAll
Description: clear instruction in instruction cache
Arguments: None
Returns: None.
*---------------------------------------------------------------------------*/
void IC_ClearInstructionAll( void )
{
IC_FillInstructionAll( 0 );
}
/*---------------------------------------------------------------------------*
Name: IC_FillInstructionAll
Description: fill instruction in instruction cache
Arguments: data : fill data
Returns: None.
*---------------------------------------------------------------------------*/
asm void IC_FillInstructionAll( u32 data )
{
mov r12, #0
@1:
mov r2, #0
@2:
orr r3, r2, r12
mcr p15, 3, r3, c15, c0, 0 // set index
mcr p15, 3, r0, c15, c3, 0 // clear data
add r2, r2, #4
cmp r2, #HW_ICACHE_SIZE/4
blt @2
add r12, r12, #1<<HW_C7_CACHE_SET_NO_SHIFT
cmp r12, #0
bne @1
bx lr
}
/*---------------------------------------------------------------------------*
Name: IC_GetTagAndInstructionAll
Description: get tag and instruction in instruction cache
Arguments: tag tag address
inst instruction address
Returns: None.
*---------------------------------------------------------------------------*/
asm void IC_GetTagAndInstructionAll( void* tag, void* inst )
{
mov r12, #0
@1:
mov r2, #0
@2:
orr r3, r2, r12
mcr p15, 3, r3, c15, c0, 0 // set index
tst r2, #HW_CACHE_LINE_SIZE - 1
mrceq p15, 3, r3, c15, c1, 0 // get tag
streq r3, [r0], #4
mrc p15, 3, r3, c15, c3, 0 // get data
str r3, [r1], #4
add r2, r2, #4
cmp r2, #HW_ICACHE_SIZE/4
blt @2
add r12, r12, #1<<HW_C7_CACHE_SET_NO_SHIFT
cmp r12, #0
bne @1
bx lr
}
#include <nitro/codereset.h>

View File

@ -0,0 +1,32 @@
#! make -f
#----------------------------------------------------------------------------
# Project: TwlFirm - libraries - os
# File: Makefile
#
# Copyright 2007 Nintendo. All rights reserved.
#
# These coded instructions, statements, and computer programs contain
# proprietary information of Nintendo of America Inc. and/or Nintendo
# Company Ltd., and are protected by Federal copyright law. They may
# not be disclosed to third parties or copied or duplicated in any form,
# in whole or in part, without the prior written consent of Nintendo.
#
# $Date:: $
# $Rev:$
# $Author:$
#----------------------------------------------------------------------------
include $(TWLIPL_ROOT)/build/buildtools/commondefs
#----------------------------------------------------------------------------
SUBDIRS = ARM9 \
ARM7 \
#----------------------------------------------------------------------------
include $(TWLIPL_ROOT)/build/buildtools/modulerules
#===== End of Makefile =====

View File

@ -0,0 +1,219 @@
/*---------------------------------------------------------------------------*
Project: TwlFirm - OS
File: os_boot.c
Copyright 2007 Nintendo. All rights reserved.
These coded instructions, statements, and computer programs contain
proprietary information of Nintendo of America Inc. and/or Nintendo
Company Ltd., and are protected by Federal copyright law. They may
not be disclosed to third parties or copied or duplicated in any form,
in whole or in part, without the prior written consent of Nintendo.
$Date:: $
$Rev$
$Author$
*---------------------------------------------------------------------------*/
#include <firm/os.h>
#include <firm/mi.h>
#include <firm/pxi.h>
#ifdef SDK_ARM9
#include <firm/os/ARM9/os_cache_tag.h>
#else
#include <twl/aes/ARM7/lo.h>
#endif
#if 0
:
OSi_BootCoreのコピー先決定
(ITCM,DTCM,STACK,TEXT,RODATA,DATAなど (OSi_BootCoreは残す))
OSi_BootCoreは次のプログラムですぐに壊されそうなところを使う
#endif
void OSi_BootCore( OSEntryPoint p, MIHeader_WramRegs* w );
/*---------------------------------------------------------------------------*
Name: OSi_Boot
Description: boot firm
Arguments: entry : entry point
w : wram settings
Returns: None
*---------------------------------------------------------------------------*/
void OSi_Boot( void* entry, MIHeader_WramRegs* w )
{
OSEntryPoint p = (OSEntryPoint)entry;
void (*OSBootCore)( OSEntryPoint p, MIHeader_WramRegs* w );
(void)OS_DisableInterrupts();
OSi_Finalize();
#ifdef SDK_ARM9
OSBootCore = (void*)HW_ITCM;
#else // SDK_ARM7
OSBootCore = (void*)(HW_PRV_WRAM_SVC_STACK - 0x200);
#endif // SDK_ARM7
MI_CpuCopyFast( OSi_BootCore, OSBootCore, 0x200 );
OSBootCore(p, w);
}
/*---------------------------------------------------------------------------*
Name: OSi_Finalize
Description: finalize
Arguments: None
Returns: None
*---------------------------------------------------------------------------*/
void OSi_Finalize(void)
{
(void)OS_DisableInterrupts();
(void)OS_DisableIrq();
reg_OS_IE = 0;
reg_OS_IF = 0xffffffff;
#ifdef SDK_ARM7
reg_OS_IE2 = 0;
reg_OS_IF2 = 0xffff;
// set init check flag by bootrom
SVC_CpuClear( REG_OS_PAUSE_CHK_MASK, (void*)REG_PAUSE_ADDR, sizeof(u16), 16 );
#else // SDK_ARM9
// set init check flag
reg_OS_PAUSE = REG_OS_PAUSE_CHK_MASK;
*(u64*)HW_INIT_LOCK_BUF = 0;
DC_Disable();
DC_FlushAll();
DC_WaitWriteBufferEmpty();
IC_Disable();
IC_InvalidateAll();
// clear cache
IC_ClearTagAll();
IC_ClearInstructionAll();
DC_ClearTagAll();
DC_ClearDataAll();
OS_DisableProtectionUnit();
#endif // SDK_ARM9
}
extern void SDK_STATIC_DATA_START(void); // static data start address
extern void SDK_STATIC_BSS_END(void); // static bss end address
/*---------------------------------------------------------------------------*
Name: OSi_ClearWorkArea
Description: clear work area
Arguments: None
Returns: None
*---------------------------------------------------------------------------*/
#include <nitro/code32.h>
asm void OSi_ClearWorkArea( void )
{
mov r11, lr
// clear stack with r4-r9
mov r0, #0
ldr r1, =SDK_STATIC_DATA_START
ldr r2, =SDK_STATIC_BSS_END
sub r2, r2, r1
bl MIi_CpuClearFast
bx r11
}
asm void OSi_BootCore( OSEntryPoint p, MIHeader_WramRegs* w )
{
mov r11, r0
mov r10, r1
#ifdef SDK_ARM9
// wait for request of wram map
ldr r3, =REG_SUBPINTF_ADDR
mov r2, #REG_PXI_SUBPINTF_A7STATUS_MASK
@0:
ldr r0, [r3]
and r0, r0, r2
cmp r0, r2
bne @0
// r10- => r9-r2
ldr r9, =REG_MBK1_ADDR
add r2, r9, #32
@1:
ldr r3, [r10], #4
str r3, [r9], #4
cmp r9, r2
blt @1
// notify wram map
ldr r3, =REG_SUBPINTF_ADDR
mov r0, #REG_PXI_SUBPINTF_A9STATUS_MASK
str r0, [r3]
// wait for finalizing pxi
ldr r3, =REG_SUBPINTF_ADDR
@2:
ldr r0, [r3]
and r0, r0, #REG_PXI_SUBPINTF_A7STATUS_MASK
cmp r0, #0
bne @2
// finalize pxi
mov r0, #0
str r0, [r3]
#else // ARM7
// request wram map
ldr r3, =REG_MAINPINTF_ADDR
mov r0, #REG_PXI_MAINPINTF_A7STATUS_MASK
str r0, [r3]
// wait for wram map
mov r2, #REG_PXI_MAINPINTF_A9STATUS_MASK
@0:
ldr r0, [r3]
and r0, r0, r2
cmp r0, r2
bne @0
// finalize pxi
mov r0, #0
str r0, [r3]
// r10- => r9-r2
add r10, r10, #32
ldr r9, =REG_MBK6_ADDR
add r2, r9, #15
@1:
ldr r3, [r10], #4
str r3, [r9], #4
cmp r9, r2
blt @1
#endif
// clear stack with r4-r9
mov r0, #0
#if 0
ldr r1, =HW_FIRM_STACK
ldr r2, =HW_FIRM_STACK_SIZE
bl MIi_CpuClearFast
#endif
mov lr, r11
// clear registers
#if 0
ldr sp, =HW_FIRM_STACK
ldmia sp, {r0-r12,sp}
#endif
bx lr
}

View File

@ -0,0 +1,148 @@
/*---------------------------------------------------------------------------*
Project: TwlFirm - OS
File: os_init_firm.c
Copyright 2007 Nintendo. All rights reserved.
These coded instructions, statements, and computer programs contain
proprietary information of Nintendo of America Inc. and/or Nintendo
Company Ltd., and are protected by Federal copyright law. They may
not be disclosed to third parties or copied or duplicated in any form,
in whole or in part, without the prior written consent of Nintendo.
$Date:: $
$Rev$
$Author$
*---------------------------------------------------------------------------*/
#include <firm.h>
/*---------------------------------------------------------------------------*
Name: OS_InitNOR
Description: initialize sdk os for firm
Arguments: None
Returns: None
*---------------------------------------------------------------------------*/
#pragma profile off
void OS_InitFIRM(void)
{
#ifdef SDK_ARM9
//---- system shared area check
// SDK_ASSERT((u32)&(OS_GetSystemWork()->command_area) == HW_CMD_AREA);
//----------------------------------------------------------------
// for ARM9
#ifdef SDK_ENABLE_ARM7_PRINT
// Init PrintServer for ARM7 (if specified)
// OS_InitPrintServer();
#endif
//---- Init interProcessor I/F
// Sync with ARM7 to enable OS_GetConsoleType()
// PXI_Init() must be called before OS_InitArenaEx()
//PXI_Init();
PXI_InitFifoFIRM();
//---- Init Arena (arenas except SUBPRIV-WRAM)
OS_InitArena();
//---- Init Spinlock
OS_InitLock();
//---- Init Arena (extended main)
OS_InitArenaEx();
//---- Init IRQ Table
OS_InitIrqTable();
//---- Init IRQ Stack checker
OS_SetIrqStackChecker();
//---- Init Exception System
// OS_InitException();
//---- Init MI (Wram bank and DMA0 arranged)
MI_Init();
//---- Init VCountAlarm
OS_InitVAlarm();
//---- Init VRAM exclusive System
OSi_InitVramExclusive();
//---- Init Thread System
#ifndef SDK_NO_THREAD
OS_InitThread();
#endif
//---- Init Reset System
#ifndef SDK_SMALL_BUILD
// OS_InitReset();
#endif
//---- Init Cartridge
#ifndef SDK_TEG
// CTRDG_Init();
#endif
//---- Init Card
#ifndef SDK_SMALL_BUILD
// CARD_Init();
#endif
//---- Init Power Manager
#ifndef SDK_TEG
// PM_Init();
#endif
//---- adjust VCOUNT
// OSi_WaitVCount0();
#else // SDK_ARM9
//----------------------------------------------------------------
// for ARM7
//---- Init interProcessor I/F
//PXI_Init();
PXI_InitFifoFIRM();
//---- Init Arena (SUBPRIV-WRAM arena)
OS_InitArena();
//---- Init Spinlock
OS_InitLock();
//---- Init IRQ Table
OS_InitIrqTable();
#define SDK_EXCEPTION_BUG
#ifndef SDK_EXCEPTION_BUG
//---- Init Exception System
OS_InitException();
#endif
//---- Init Tick
OS_InitTick();
//---- Init Alarm System
OS_InitAlarm();
//---- Init Thread System
OS_InitThread();
//---- Init Reset System
#ifndef SDK_SMALL_BUILD
// OS_InitReset();
#endif
//---- Init Cartridge
#ifndef SDK_TEG
// CTRDG_Init();
#endif
#endif // SDK_ARM9
}
#pragma profile reset

View File

@ -0,0 +1,62 @@
#! make -f
#----------------------------------------------------------------------------
# Project: TwlFirm - libraries - pm
# File: Makefile
#
# Copyright 2007 Nintendo. All rights reserved.
#
# These coded instructions, statements, and computer programs contain
# proprietary information of Nintendo of America Inc. and/or Nintendo
# Company Ltd., and are protected by Federal copyright law. They may
# not be disclosed to third parties or copied or duplicated in any form,
# in whole or in part, without the prior written consent of Nintendo.
#
# $Date:: $
# $Rev:$
# $Author:$
#----------------------------------------------------------------------------
SUBDIRS =
SUBMAKES =
#----------------------------------------------------------------------------
# build ARM & THUMB libraries
FIRM_CODEGEN_ALL ?= TRUE
# Codegen for sub processer
FIRM_PROC = ARM7
INCDIR = $(TWLSDK_ROOT)/build/libraries/spi/ARM7/pm/include \
SRCDIR = .
SRCS = \
pm_init.c \
pm_pmic_ex.c \
TARGET_LIB = libpm_sp$(FIRM_LIBSUFFIX).a
#----------------------------------------------------------------------------
# DEBUG版ビルドの場合、RELEASE版でビルドして
# DEBUG版のライブラリを装います。
ifdef NITRO_DEBUG
NITRO_BUILD_TYPE = RELEASE
endif
include $(TWLIPL_ROOT)/build/buildtools/commondefs
INSTALL_TARGETS = $(TARGETS)
INSTALL_DIR = $(FIRM_INSTALL_LIBDIR)
#----------------------------------------------------------------------------
do-build: $(TARGETS)
include $(TWLIPL_ROOT)/build/buildtools/modulerules
#===== End of Makefile =====

View File

@ -0,0 +1,88 @@
/*---------------------------------------------------------------------------*
Project: TwlIPL - libraries - pm
File: pm_init.c
Copyright 2007 Nintendo. All rights reserved.
These coded instructions, statements, and computer programs contain
proprietary information of Nintendo of America Inc. and/or Nintendo
Company Ltd., and are protected by Federal copyright law. They may
not be disclosed to third parties or copied or duplicated in any form,
in whole or in part, without the prior written consent of Nintendo.
$Date:: $
$Rev$
$Author$
*---------------------------------------------------------------------------*/
#include <firm/pm.h>
#include <twl/spi/common/pm_common.h>
static BOOL doneBackLight = FALSE;
/*---------------------------------------------------------------------------*
Name: PM_InitFIRM
Description: set default parameters
Arguments: None
Returns: None
*---------------------------------------------------------------------------*/
void PM_InitFIRM( void )
{
// LED
PMi_ResetFlags( REG_PMIC_LED_CTL_ADDR, PMIC_LED_CTL_AUTO_BLINK | PMIC_LED_CTL_BLINK_BY_SLEEP );
PMi_SetParams( REG_PMIC_LVL4_BRT_ADDR,
PMIC_LED_1_BRT_LEVEL_4_OFF | PMIC_LED_2_BRT_LEVEL_4_OFF,
PMIC_LVL4_BRT_LED_1_MASK | PMIC_LVL4_BRT_LED_2_MASK
);
PMi_SetParams( REG_PMIC_LVL3_BRT_ADDR,
PMIC_LED_1_BRT_LEVEL_3_100 | PMIC_LED_2_BRT_LEVEL_3_OFF,
PMIC_LVL3_BRT_LED_1_MASK | PMIC_LVL3_BRT_LED_2_MASK
);
PMi_SetParams( REG_PMIC_LVL2_BRT_ADDR,
PMIC_LED_1_BRT_LEVEL_2_OFF | PMIC_LED_1_BRT_LEVEL_2_100,
PMIC_LVL2_BRT_LED_1_MASK | PMIC_LVL2_BRT_LED_2_MASK
);
PMi_SetParams( REG_PMIC_LVL1_BRT_ADDR,
PMIC_LED_1_BRT_LEVEL_1_100 | PMIC_LED_2_BRT_LEVEL_1_100,
PMIC_LVL1_BRT_LED_1_MASK | PMIC_LVL1_BRT_LED_2_MASK
);
// LCD ON
PMi_SetFlags( REG_PMIC_CTL2_ADDR, PMIC_CTL2_VDD50 );
// back light
PMi_SetParams( REG_PMIC_BL_BRT_A_ADDR, PMIC_BACKLIGHT_BRIGHT_MAX, PMIC_BL_BRT_A_MASK ); // TODO: less brightness
PMi_SetParams( REG_PMIC_BL_BRT_B_ADDR, PMIC_BACKLIGHT_BRIGHT_MAX, PMIC_BL_BRT_B_MASK ); // TODO: less brightness
}
/*---------------------------------------------------------------------------*
Name: PM_BackLightOn
Description: power B/L on if not set yet
Arguments: force TRUE: wait until valid condition
FALSE not set unless valid condition
Returns: None
*---------------------------------------------------------------------------*/
void PM_BackLightOn( BOOL force )
{
if ( doneBackLight )
{
return; // have already set
}
if ( force )
{
while ( (reg_GX_DISPSTAT & REG_GX_DISPSTAT_INI_MASK) == FALSE )
{
}
}
if ( reg_GX_DISPSTAT & REG_GX_DISPSTAT_INI_MASK )
{
PMi_SetFlags( REG_PMIC_CTL2_ADDR, PMIC_CTL2_BACK_LIGHT_1 | PMIC_CTL2_BACK_LIGHT_2 );
doneBackLight = TRUE;
}
}

View File

@ -0,0 +1,72 @@
/*---------------------------------------------------------------------------*
Project: TwlIPL - libraries - pm
File: pm_pmic_ex.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 <firm/pm.h>
#include <pm_pmic.h>
//================================================================================
// PMIC BIT CONTROL
//================================================================================
/*---------------------------------------------------------------------------*
Name: PMi_SetParams
Description: set control bit to device register
Arguments: reg : device register
setBits : bits to set
maskBits : bits to mask
Returns: None
*---------------------------------------------------------------------------*/
void PMi_SetParams( u8 reg, u8 setBits, u8 maskBits )
{
u8 tmp;
tmp = PMi_GetRegister( reg );
tmp &= ~maskBits;
setBits &= maskBits;
tmp |= setBits;
PMi_SetRegister( reg, tmp );
}
/*---------------------------------------------------------------------------*
Name: PMi_SetFlags
Description: set control bit to device register
Arguments: reg : device register
setBits : bits to set
Returns: None
*---------------------------------------------------------------------------*/
void PMi_SetFlags( u8 reg, u8 setBits )
{
PMi_SetParams( reg, setBits, setBits );
}
/*---------------------------------------------------------------------------*
Name: PMi_ResetFlags
Description: clear control bit to device register
Arguments: reg : device register
clrBits : bits to set
Returns: None
*---------------------------------------------------------------------------*/
void PMi_ResetFlags( u8 reg, u8 clrBits )
{
PMi_SetParams( reg, 0, clrBits );
}

View File

@ -0,0 +1,31 @@
#! make -f
#----------------------------------------------------------------------------
# Project: TwlIPL - libraries - pm
# File: Makefile
#
# Copyright 2007 Nintendo. All rights reserved.
#
# These coded instructions, statements, and computer programs contain
# proprietary information of Nintendo of America Inc. and/or Nintendo
# Company Ltd., and are protected by Federal copyright law. They may
# not be disclosed to third parties or copied or duplicated in any form,
# in whole or in part, without the prior written consent of Nintendo.
#
# $Date:: $
# $Rev:$
# $Author:$
#----------------------------------------------------------------------------
include $(TWLIPL_ROOT)/build/buildtools/commondefs
#----------------------------------------------------------------------------
SUBDIRS = ARM7
#----------------------------------------------------------------------------
include $(TWLIPL_ROOT)/build/buildtools/modulerules
#===== End of Makefile =====

View File

@ -0,0 +1,61 @@
#! make -f
#----------------------------------------------------------------------------
# Project: TwlFirm - libraries_sp - pxi
# File: Makefile
#
# Copyright 2007 Nintendo. All rights reserved.
#
# These coded instructions, statements, and computer programs contain
# proprietary information of Nintendo of America Inc. and/or Nintendo
# Company Ltd., and are protected by Federal copyright law. They may
# not be disclosed to third parties or copied or duplicated in any form,
# in whole or in part, without the prior written consent of Nintendo.
#
# $Date:: $
# $Rev:$
# $Author:$
#----------------------------------------------------------------------------
SUBDIRS =
#SUBMAKES = Makefile.CALLTRACE \
# Makefile.FUNCTIONCOST
#----------------------------------------------------------------------------
# build ARM & THUMB libraries
FIRM_CODEGEN_ALL ?= TRUE
# Codegen for sub processer
FIRM_PROC = ARM7
SRCDIR = ../common .
SRCS = \
pxi_misc.c \
TARGET_LIB = libpxi_sp$(FIRM_LIBSUFFIX).a
#----------------------------------------------------------------------------
# DEBUG版ビルドの場合、RELEASE版でビルドして
# DEBUG版のライブラリを装います。
ifdef NITRO_DEBUG
NITRO_BUILD_TYPE = RELEASE
endif
include $(TWLIPL_ROOT)/build/buildtools/commondefs
INSTALL_TARGETS = $(TARGETS)
INSTALL_DIR = $(FIRM_INSTALL_LIBDIR)
#----------------------------------------------------------------------------
do-build: $(TARGETS)
include $(TWLIPL_ROOT)/build/buildtools/modulerules
#===== End of Makefile =====

View File

@ -0,0 +1,58 @@
#! make -f
#----------------------------------------------------------------------------
# Project: TwlFirm - libraries - pxi
# File: Makefile
#
# Copyright 2007 Nintendo. All rights reserved.
#
# These coded instructions, statements, and computer programs contain
# proprietary information of Nintendo of America Inc. and/or Nintendo
# Company Ltd., and are protected by Federal copyright law. They may
# not be disclosed to third parties or copied or duplicated in any form,
# in whole or in part, without the prior written consent of Nintendo.
#
# $Date:: $
# $Rev:$
# $Author:$
#----------------------------------------------------------------------------
SUBDIRS =
SUBMAKES =
#----------------------------------------------------------------------------
# build ARM & THUMB libraries
FIRM_CODEGEN_ALL ?= TRUE
SRCDIR = ../common .
SRCS = \
pxi_misc.c \
TARGET_LIB = libpxi$(FIRM_LIBSUFFIX).a
include $(TWLIPL_ROOT)/build/buildtools/commondefs
INSTALL_TARGETS = $(TARGETS)
INSTALL_DIR = $(FIRM_INSTALL_LIBDIR)
ifdef NITRO_CALLTRACE
CCFLAGS += -DOS_PROFILE_AVAILABLE -DOS_PROFILE_CALL_TRACE
endif
ifdef NITRO_FUNCTIONCOST
CCFLAGS += -DOS_PROFILE_AVAILABLE -DOS_PROFILE_FUNCTION_COST
endif
ifdef NITRO_TCM_APPLY
CCFLAGS += -DSDK_TCM_APPLY
endif
#----------------------------------------------------------------------------
do-build: $(TARGETS)
include $(TWLIPL_ROOT)/build/buildtools/modulerules
#===== End of Makefile =====

View File

@ -0,0 +1,32 @@
#! make -f
#----------------------------------------------------------------------------
# Project: TwlFirm - libraries - pxi
# File: Makefile
#
# Copyright 2007 Nintendo. All rights reserved.
#
# These coded instructions, statements, and computer programs contain
# proprietary information of Nintendo of America Inc. and/or Nintendo
# Company Ltd., and are protected by Federal copyright law. They may
# not be disclosed to third parties or copied or duplicated in any form,
# in whole or in part, without the prior written consent of Nintendo.
#
# $Date:: $
# $Rev:$
# $Author:$
#----------------------------------------------------------------------------
include $(TWLIPL_ROOT)/build/buildtools/commondefs
#----------------------------------------------------------------------------
SUBDIRS = ARM9 \
ARM7 \
#----------------------------------------------------------------------------
include $(TWLIPL_ROOT)/build/buildtools/modulerules
#===== End of Makefile =====

View File

@ -0,0 +1,352 @@
/*---------------------------------------------------------------------------*
Project: TwlFirm - library - pxi
File: pxi_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 <firm/os.h>
#include <twl/memorymap.h>
#include <firm/pxi.h>
static u16 FifoCtrlInit = 0;
/*********** function prototypes ******************/
static inline PXIFifoStatus PXIi_GetFromFifo(u32 *data_buf);
static inline PXIFifoStatus PXIi_SetToFifo(u32 data);
/*---------------------------------------------------------------------------*
Name: PXI_InitFifoFIRM
Description: initialize FIFO system for firm
Arguments: None.
Returns: None.
*---------------------------------------------------------------------------*/
void PXI_InitFifoFIRM(void)
{
OSIntrMode enabled;
enabled = OS_DisableInterrupts();
if (!FifoCtrlInit)
{
FifoCtrlInit = TRUE;
reg_PXI_FIFO_CNT =
(REG_PXI_FIFO_CNT_SEND_CL_MASK |
REG_PXI_FIFO_CNT_E_MASK | REG_PXI_FIFO_CNT_ERR_MASK);
#ifdef SDK_ARM9
PXI_SendIDByIntf( FIRM_PXI_ID_INIT_ARM9 );
PXI_WaitIDByIntf( FIRM_PXI_ID_INIT_ARM7 );
#else // SDK_ARM7
PXI_SendIDByIntf( FIRM_PXI_ID_INIT_ARM7 );
PXI_WaitIDByIntf( FIRM_PXI_ID_INIT_ARM9 );
#endif // SDK_ARM7
}
(void)OS_RestoreInterrupts(enabled);
}
/*---------------------------------------------------------------------------*
Name: PXI_NotifyID
Description: Send 4bit id to other processor
Arguments: id notifying id
Returns: None
*---------------------------------------------------------------------------*/
void PXI_NotifyID( u32 id )
{
PXI_SendIDByFifo( PXI_FIFO_TAG_SYSTEM, id );
}
/*---------------------------------------------------------------------------*
Name: PXI_WaitID
Description: Wait 4bit id from the other processor
Arguments: id waiting id
Returns: None
*---------------------------------------------------------------------------*/
void PXI_WaitID( u32 id )
{
PXI_WaitIDByFifo( PXI_FIFO_TAG_SYSTEM, id );
}
/*---------------------------------------------------------------------------*
Name: PXI_RecvID
Description: Receive 4bit id from the other processor
Arguments: None
Returns: id
*---------------------------------------------------------------------------*/
u8 PXI_RecvID( void )
{
u8 id;
while (PXI_RecvIDByFifo(PXI_FIFO_TAG_SYSTEM, &id) != PXI_FIFO_SUCCESS)
{
}
return id;
}
/*---------------------------------------------------------------------------*
Name: PXI_SendIDByIntf
Description: Send 4bit id to the other processor
Arguments: id sending id
Returns: None
*---------------------------------------------------------------------------*/
void PXI_SendIDByIntf( u32 id )
{
reg_PXI_INTF = (u16)(id << REG_PXI_INTF_SEND_SHIFT);
}
/*---------------------------------------------------------------------------*
Name: PXI_RecvIDByIntf
Description: Receive 4bit id from the other processor
Arguments: None
Returns: received id
*---------------------------------------------------------------------------*/
u32 PXI_RecvIDByIntf( void )
{
return (u32)((reg_PXI_INTF & REG_PXI_INTF_RECV_MASK) >> REG_PXI_INTF_RECV_SHIFT);
}
/*---------------------------------------------------------------------------*
Name: PXI_WaitIDByIntf
Description: Wait 4bit id from the other processor
Arguments: id waiting id
Returns: None
*---------------------------------------------------------------------------*/
void PXI_WaitIDByIntf( u32 id )
{
while (PXI_RecvIDByIntf() != id)
{
}
}
/*---------------------------------------------------------------------------*
Name: PXI_SendIDByFifo
Description: Send 32bit-word to another CPU via FIFO
Arguments:
Returns: None
*---------------------------------------------------------------------------*/
void PXI_SendIDByFifo(PXIFifoTag tag, u32 id)
{
static PXIFifoMessage fifomsg;
fifomsg.e.tag = tag;
fifomsg.e.data = id;
while ( PXIi_SetToFifo(fifomsg.raw) != PXI_FIFO_SUCCESS )
{
}
}
/*---------------------------------------------------------------------------*
Name: PXI_RecvIDByFifo
Description: Recv 32bit-word from another CPU via FIFO
Arguments:
Returns: if error occured, returns minus value
*---------------------------------------------------------------------------*/
PXIFifoStatus PXI_RecvIDByFifo(PXIFifoTag tag, void* buf)
{
static PXIFifoMessage fifomsg;
u8* p = buf;
while ( PXIi_GetFromFifo(&fifomsg.raw) != PXI_FIFO_SUCCESS )
{
}
if (fifomsg.e.tag != tag)
{
return PXI_FIFO_FAIL_RECV_ERR;
}
*p = (u8)fifomsg.e.data;
return PXI_FIFO_SUCCESS;
}
/*---------------------------------------------------------------------------*
Name: PXI_WaitIDByFifo
Description: Wait 32bit-word from another CPU via FIFO
Arguments: id waiting id
Returns: None
*---------------------------------------------------------------------------*/
void PXI_WaitIDByFifo(PXIFifoTag tag, u32 id)
{
u8 buf = (u8)id;
do
{
while (PXI_RecvIDByFifo(tag, &buf) != PXI_FIFO_SUCCESS)
{
}
}
while ( buf != id );
}
/*---------------------------------------------------------------------------*
Name: PXI_SendDataByFifo
Description: Send data to another CPU via FIFO
Arguments:
Returns: None
*---------------------------------------------------------------------------*/
void PXI_SendDataByFifo(PXIFifoTag tag, void* buf, int size)
{
static PXIFifoMessage fifomsg;
u32* p = buf;
int len = size/4;
int i;
fifomsg.e.tag = tag;
fifomsg.e.data = len;
while ( PXIi_SetToFifo(fifomsg.raw) != PXI_FIFO_SUCCESS )
{
}
for ( i=0; i<len; i++ )
{
while ( PXIi_SetToFifo(p[i]) != PXI_FIFO_SUCCESS )
{
}
}
}
/*---------------------------------------------------------------------------*
Name: PXI_RecvDataByFifo
Description: Recv data to another CPU via FIFO
Arguments:
Returns: if error occured, returns minus value
*---------------------------------------------------------------------------*/
PXIFifoStatus PXI_RecvDataByFifo(PXIFifoTag tag, void* buf, int max_size )
{
static PXIFifoMessage fifomsg;
u32* p = buf;
u32 len;
int i;
while ( PXIi_GetFromFifo(&fifomsg.raw) != PXI_FIFO_SUCCESS )
{
}
if (fifomsg.e.tag != tag)
{
return PXI_FIFO_FAIL_SEND_ERR;
}
len = fifomsg.e.data;
if (len > max_size/4)
{
return PXI_FIFO_FAIL_SEND_ERR;
}
for ( i=0; i<len; i++ )
{
while ( PXIi_GetFromFifo(&p[i]) != PXI_FIFO_SUCCESS )
{
}
}
return PXI_FIFO_SUCCESS;
}
//======================================================================
// Write Send-FIFO reg.
//======================================================================
static inline PXIFifoStatus PXIi_SetToFifo(u32 data)
{
OSIntrMode enabled;
if (reg_PXI_FIFO_CNT & REG_PXI_FIFO_CNT_ERR_MASK)
{
reg_PXI_FIFO_CNT |= (REG_PXI_FIFO_CNT_E_MASK | REG_PXI_FIFO_CNT_ERR_MASK);
return PXI_FIFO_FAIL_SEND_ERR;
}
enabled = OS_DisableInterrupts();
if (reg_PXI_FIFO_CNT & REG_PXI_FIFO_CNT_SEND_FULL_MASK)
{
(void)OS_RestoreInterrupts(enabled);
return PXI_FIFO_FAIL_SEND_FULL;
}
reg_PXI_SEND_FIFO = data;
(void)OS_RestoreInterrupts(enabled);
return PXI_FIFO_SUCCESS;
}
//======================================================================
// Read Send-FIFO reg.
//======================================================================
static inline PXIFifoStatus PXIi_GetFromFifo(u32 *data_buf)
{
OSIntrMode enabled;
if (reg_PXI_FIFO_CNT & REG_PXI_FIFO_CNT_ERR_MASK)
{
reg_PXI_FIFO_CNT |= (REG_PXI_FIFO_CNT_E_MASK | REG_PXI_FIFO_CNT_ERR_MASK);
return PXI_FIFO_FAIL_RECV_ERR;
}
enabled = OS_DisableInterrupts();
if (reg_PXI_FIFO_CNT & REG_PXI_FIFO_CNT_RECV_EMP_MASK)
{
(void)OS_RestoreInterrupts(enabled);
return PXI_FIFO_FAIL_RECV_EMPTY;
}
*data_buf = reg_PXI_RECV_FIFO;
(void)OS_RestoreInterrupts(enabled);
return PXI_FIFO_SUCCESS;
}

BIN
build/libraries_sysmenu/.DS_Store vendored Normal file

Binary file not shown.

View File

@ -0,0 +1,32 @@
#! make -f
#----------------------------------------------------------------------------
# Project: TwlIPL
# File: Makefile
#
# Copyright 2007 Nintendo. All rights reserved.
#
# These coded instructions, statements, and computer programs contain
# proprietary information of Nintendo of America Inc. and/or Nintendo
# Company Ltd., and are protected by Federal copyright law. They may
# not be disclosed to third parties or copied or duplicated in any form,
# in whole or in part, without the prior written consent of Nintendo.
#
# $Date:: 2007-10-03#$
# $Rev: 1319 $
# $Author: kitase_hirotake $
#----------------------------------------------------------------------------
TARGET_FIRM = SYSTEMMENU
include $(TWLIPL_ROOT)/build/buildtools/commondefs
#----------------------------------------------------------------------------
SUBDIRS = sysmenu mb_loader acsign
#----------------------------------------------------------------------------
include $(TWLIPL_ROOT)/build/buildtools/modulerules
#===== End of Makefile =====

View File

@ -0,0 +1,57 @@
#! make -f
#----------------------------------------------------------------------------
# Project: TwlIPL
# File: Makefile
#
# Copyright 2007 Nintendo. All rights reserved.
#
# These coded instructions, statements, and computer programs contain
# proprietary information of Nintendo of America Inc. and/or Nintendo
# Company Ltd., and are protected by Federal copyright law. They may
# not be disclosed to third parties or copied or duplicated in any form,
# in whole or in part, without the prior written consent of Nintendo.
#
# $Date:: 2007-10-03#$
# $Rev: 1319 $
# $Author: kitase_hirotake $
#----------------------------------------------------------------------------
#----------------------------------------------------------------------------
SUBDIRS =
#----------------------------------------------------------------------------
TARGET_FIRM = SYSTEMMENU
TARGET_PLATFORM = TWL
TWL_ARCHGEN = LIMITED
TWL_PROC = ARM9
INCDIR = include \
$(TWLSDK_ROOT)/build/libraries/mb/common/include
SRCS = acsign.c acmemory.c acsign_util.c
TARGET_LIB = libacsign$(TWL_LIBSUFFIX).a
include $(TWLIPL_ROOT)/build/buildtools/commondefs
INSTALL_TARGETS = $(TARGETS)
INSTALL_DIR = $(SYSMENU_INSTALL_LIBDIR)
CCFLAGS += -DSMALL_CODE_SIZE \
-DSTANDALONE \
-DOPT_32_BIT \
-DNO_SPLIT \
-DNO_FP_API \
-DNO_R_DIAG \
-DNO_STDIO_H \
-DNO_STDLIB_H
do-build: $(TARGETS)
include $(TWLIPL_ROOT)/build/buildtools/modulerules
#===== End of Makefile =====

View File

@ -0,0 +1,36 @@
/*---------------------------------------------------------------------------*
Project: TwlIPL
File: acmemory.h
Copyright 2007 Nintendo. All rights reserved.
These coded instructions, statements, and computer programs contain
proprietary information of Nintendo of America Inc. and/or Nintendo
Company Ltd., and are protected by Federal copyright law. They may
not be disclosed to third parties or copied or duplicated in any form,
in whole or in part, without the prior written consent of Nintendo.
$Date:: $
$Rev$
$Author$
*---------------------------------------------------------------------------*/
#ifndef _ACMEMORY_H_
#define _ACMEMORY_H_
#ifdef __cplusplus
extern "C" {
#endif
//
void ACMemory_Clear( );
void* ACMemory_Alloc( u32 size );
void ACMemory_Free( void* adrs );
void* ACMemory_Memset( void* adrs, u32 val, u32 cnt );
void* ACMemory_Memcpy( void* dst, void* src, u32 cnt );
#ifdef __cplusplus
}
#endif
#endif //_ACMEMORY_H_

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,356 @@
/*---------------------------------------------------------------------------*
Project: TwlIPL
File:
Copyright 2007 Nintendo. All rights reserved.
These coded instructions, statements, and computer programs contain
proprietary information of Nintendo of America Inc. and/or Nintendo
Company Ltd., and are protected by Federal copyright law. They may
not be disclosed to third parties or copied or duplicated in any form,
in whole or in part, without the prior written consent of Nintendo.
$Date:: $
$Rev$
$Author$
*---------------------------------------------------------------------------*/
/*
* 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_LCL_H
#define HEADER_COMMON_BN_LCL_H
#ifdef __cplusplus
extern "C" {
#endif
#if 0 //RSA
#include <stdio.h>
#include <stdlib.h>
#include "r_error.h"
#include "err.h"
#include <string.h>
#else //NITRO
#include "r_error.h"
#ifndef NULL
#define NULL 0
#endif
#endif
#ifndef STANDALONE
#include "r_com.h"
#else
#if 0 //RSA
#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)
#else // Nitro
#define NO_STDLIB_MAPPING
#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
/* 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; iii<n; iii++) \
{ \
a[iii]= (-a[iii])&BN_MASK2; \
} \
for (;;) \
if ((++a[iii])&BN_MASK2) break; \
}
/* This macro is to add extra stuff for development checking */
#ifdef BN_DEBUG
#define bn_set_max(r) ((r)->max=(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)
#define mul64(l,h,bl,bh) \
{ \
BN_ULONG m,m1,lt,ht; \
\
lt=l; \
ht=h; \
m =(bh)*(lt); \
lt=(bl)*(lt); \
m1=(bl)*(ht); \
ht =(bh)*(ht); \
m=(m+m1)&BN_MASK2; if (m < m1) ht+=L2HBITS(1L); \
ht+=HBITS(m); \
m1=L2HBITS(m); \
lt=(lt+m1)&BN_MASK2; if (lt < m1) ht++; \
(l)=lt; \
(h)=ht; \
}
#define sqr64(lo,ho,in) \
{ \
BN_ULONG l,h,m; \
\
h=(in); \
l=LBITS(h); \
h=HBITS(h); \
m =(l)*(h); \
l*=l; \
h*=h; \
h+=(m&BN_MASK2h1)>>(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); \
c+=(mt>>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);

View File

@ -0,0 +1,317 @@
/*---------------------------------------------------------------------------*
Project: TwlIPL
File:
Copyright 2007 Nintendo. All rights reserved.
These coded instructions, statements, and computer programs contain
proprietary information of Nintendo of America Inc. and/or Nintendo
Company Ltd., and are protected by Federal copyright law. They may
not be disclosed to third parties or copied or duplicated in any form,
in whole or in part, without the prior written consent of Nintendo.
$Date:: $
$Rev$
$Author$
*---------------------------------------------------------------------------*/
/*
* 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 <stdio.h>
#endif
#ifndef NO_STDLIB_H
#include <stdlib.h>
#endif
#ifndef NO_STRING_H
#include <string.h>
#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 */

View File

@ -0,0 +1,73 @@
/*---------------------------------------------------------------------------*
Project: TwlIPL
File:
Copyright 2007 Nintendo. All rights reserved.
These coded instructions, statements, and computer programs contain
proprietary information of Nintendo of America Inc. and/or Nintendo
Company Ltd., and are protected by Federal copyright law. They may
not be disclosed to third parties or copied or duplicated in any form,
in whole or in part, without the prior written consent of Nintendo.
$Date:: $
$Rev$
$Author$
*---------------------------------------------------------------------------*/
#ifndef _MD5_H_
#define _MD5_H_
#ifdef __cplusplus
extern "C" {
#endif
/* MD5.H - header file for MD5C.C
*/
/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
rights reserved.
License to copy and use this software is granted provided that it
is identified as the "RSA Data Security, Inc. MD5 Message-Digest
Algorithm" in all material mentioning or referencing this software
or this function.
License is also granted to make and use derivative works provided
that such works are identified as "derived from the RSA Data
Security, Inc. MD5 Message-Digest Algorithm" in all material
mentioning or referencing the derived work.
RSA Data Security, Inc. makes no representations concerning either
the merchantability of this software or the suitability of this
software for any particular purpose. It is provided "as is"
without express or implied warranty of any kind.
These notices must be retained in any copies of any part of this
documentation and/or software.
*/
typedef struct MD5_CTX MD5_CTX;
typedef struct MD5_CTX MD5Context;
/* MD5 context. */
struct MD5_CTX{
unsigned long state[4]; /* state (ABCD) */
unsigned long count[2]; /* number of bits, modulo 2^64 (lsb first) */
unsigned char buffer[64]; /* input buffer */
} ;
void MD5Init(MD5_CTX *);
void MD5Update(MD5_CTX *, unsigned char *, unsigned int);
void MD5Final(unsigned char digest[16], MD5_CTX *);
#if defined( MD5_TEST )
int MD5Test( );
#endif // MD5_TEST
#ifdef __cplusplus
}
#endif
#endif // _MD5_H_

View File

@ -0,0 +1,226 @@
/*---------------------------------------------------------------------------*
Project: TwlIPL
File:
Copyright 2007 Nintendo. All rights reserved.
These coded instructions, statements, and computer programs contain
proprietary information of Nintendo of America Inc. and/or Nintendo
Company Ltd., and are protected by Federal copyright law. They may
not be disclosed to third parties or copied or duplicated in any form,
in whole or in part, without the prior written consent of Nintendo.
$Date:: $
$Rev$
$Author$
*---------------------------------------------------------------------------*/
/*
* 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
* <a href="pdf/dev_guide.pdf">Developer's Guide</a>.
*
* @{
*/
/**
* Indicates that a fatal error has occurred in the operation performed.
* This flag is set with the following error codes:<br>
* <ul>
* <li>#R_ERROR_INVALID_STATE.</li>
* <li>#R_ERROR_INIT_NOT_CALLED.</li>
* <li>#R_ERROR_SHOULD_NOT_HAVE_BEEN_CALLED.</li>
* </ul>
*/
#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:<br>
* <ul>
* <li>#R_ERROR_NULL_ARG.</li>
* <li>#R_ERROR_BUFFER_TOO_SMALL.</li>
* <li>#R_ERROR_BAD_VALUE.</li>
* <li>#R_ERROR_BAD_RANGE.</li>
* <li>#R_ERROR_BAD_FORMAT.</li>
* <li>#R_ERROR_BAD_TYPE.</li>
* <li>#R_ERROR_BAD_DATA.</li>
* <li>#R_ERROR_BAD_LENGTH.</li>
* </ul>
*/
#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 <tt>NULL</tt>.
*/
#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 */

View File

@ -0,0 +1,98 @@
/*---------------------------------------------------------------------------*
Project: TwlIPL
File:
Copyright 2007 Nintendo. All rights reserved.
These coded instructions, statements, and computer programs contain
proprietary information of Nintendo of America Inc. and/or Nintendo
Company Ltd., and are protected by Federal copyright law. They may
not be disclosed to third parties or copied or duplicated in any form,
in whole or in part, without the prior written consent of Nintendo.
$Date:: $
$Rev$
$Author$
*---------------------------------------------------------------------------*/
/*
* 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 */

View File

@ -0,0 +1,257 @@
/*---------------------------------------------------------------------------*
Project: TwlIPL
File:
Copyright 2007 Nintendo. All rights reserved.
These coded instructions, statements, and computer programs contain
proprietary information of Nintendo of America Inc. and/or Nintendo
Company Ltd., and are protected by Federal copyright law. They may
not be disclosed to third parties or copied or duplicated in any form,
in whole or in part, without the prior written consent of Nintendo.
$Date:: $
$Rev$
$Author$
*---------------------------------------------------------------------------*/
/*
* 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

View File

@ -0,0 +1,105 @@
/*---------------------------------------------------------------------------*
Project: TwlIPL
File:
Copyright 2007 Nintendo. All rights reserved.
These coded instructions, statements, and computer programs contain
proprietary information of Nintendo of America Inc. and/or Nintendo
Company Ltd., and are protected by Federal copyright law. They may
not be disclosed to third parties or copied or duplicated in any form,
in whole or in part, without the prior written consent of Nintendo.
$Date:: $
$Rev$
$Author$
*---------------------------------------------------------------------------*/
/*
* 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 */

View File

@ -0,0 +1,90 @@
/*---------------------------------------------------------------------------*
Project: TwlIPL
File:
Copyright 2007 Nintendo. All rights reserved.
These coded instructions, statements, and computer programs contain
proprietary information of Nintendo of America Inc. and/or Nintendo
Company Ltd., and are protected by Federal copyright law. They may
not be disclosed to third parties or copied or duplicated in any form,
in whole or in part, without the prior written consent of Nintendo.
$Date:: $
$Rev$
$Author$
*---------------------------------------------------------------------------*/
/*
* 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_

View File

@ -0,0 +1,290 @@
/*---------------------------------------------------------------------------*
Project: TwlIPL
File:
Copyright 2007 Nintendo. All rights reserved.
These coded instructions, statements, and computer programs contain
proprietary information of Nintendo of America Inc. and/or Nintendo
Company Ltd., and are protected by Federal copyright law. They may
not be disclosed to third parties or copied or duplicated in any form,
in whole or in part, without the prior written consent of Nintendo.
$Date:: $
$Rev$
$Author$
*---------------------------------------------------------------------------*/
/*
* 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 0 //RSA
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#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 */

View File

@ -0,0 +1,306 @@
/*---------------------------------------------------------------------------*
Project: TwlIPL
File:
Copyright 2007 Nintendo. All rights reserved.
These coded instructions, statements, and computer programs contain
proprietary information of Nintendo of America Inc. and/or Nintendo
Company Ltd., and are protected by Federal copyright law. They may
not be disclosed to third parties or copied or duplicated in any form,
in whole or in part, without the prior written consent of Nintendo.
$Date:: $
$Rev$
$Author$
*---------------------------------------------------------------------------*/
//
// BN系関数用のメモリ関連処理を置き換え
//
#include <nitro.h>
#include "acmemory.h"
/*
head tail
| | | |
+--------+---------+----....----+---------+--------+
|block |check |buffer |check |block |
+--------+---------+----....----+---------+--------+
|4byte |4byte |Upper4(size)|4byte |4byte |
<------------------ 4 * n ------------------->
block = n = (4 * 4 + Upper4(size)) / 4
check = 0x0F5555F0使0x0FAAAAF0使
*/
unsigned long aACMemoryPoolA[ 16 ];
unsigned long aACMemoryPool[ 1024 * 32 / sizeof (unsigned long) ]; // 32K
unsigned long aACMemoryPoolB[ 16 ];
#define ACMEMORYPOOL_HEAD (aACMemoryPool)
#define ACMEMORYPOOL_TAIL (aACMemoryPool + sizeof aACMemoryPool / sizeof (unsigned long))
#define ACMEMORYPOOL_SIZE ((unsigned long)ACMEMORYPOOL_TAIL - (unsigned long)ACMEMORYPOOL_HEAD)
#define ACMEMORY_CHECK_BASE 0xF000000F
#define ACMEMORY_CHECK_FREE (0x00555500 | ACMEMORY_CHECK_BASE)
#define ACMEMORY_CHECK_USED (0x00AAAA00 | ACMEMORY_CHECK_BASE)
#define ACMemory_Lower4( _size ) (((_size) ) & 0xFFFFFFFC)
#define ACMemory_Upper4( _size ) (((_size) + 3) & 0xFFFFFFFC)
#define pACMemory_FromHeadToBody( _head ) ((unsigned long*)(((volatile unsigned long*)(_head)) + 2))
#define pACMemory_FromBodyToHead( _body ) ((unsigned long*)(((volatile unsigned long*)(_body)) - 2))
#define pACMemory_FromHeadToTail( _head ) ((unsigned long*)(((volatile unsigned long*)(_head)) + nACMemory_HeadBlock( _head )))
#define pACMemory_FromTailToHead( _tail ) ((unsigned long*)(((volatile unsigned long*)(_tail)) - nACMemory_TailBlock( _tail )))
#define nACMemory_HeadBlock( _head ) (((volatile unsigned long*)(_head))[+0])
#define nACMemory_HeadCheck( _head ) (((volatile unsigned long*)(_head))[+1])
#define nACMemory_TailBlock( _tail ) (((volatile unsigned long*)(_tail))[-1])
#define nACMemory_TailCheck( _tail ) (((volatile unsigned long*)(_tail))[-2])
//#define USE_OSALLOC
//#define USE_ACMEMORY_DEBUGDUMP
//#define USE_ACMEMORY_DEBUGFILL
//
#if defined( USE_ACMEMORY_DEBUGDUMP )
static
void acMemory_DebugDump( )
{
unsigned long* ptr = ACMEMORYPOOL_HEAD;
//
OS_Printf( "----ACMemory_Dump [0x%.8x - 0x%.8x : 0x%.8x ]----\n", ACMEMORYPOOL_HEAD, ACMEMORYPOOL_TAIL, ACMEMORYPOOL_SIZE );
for ( ; (unsigned long)ptr < (unsigned long)ACMEMORYPOOL_TAIL; )
{
OS_Printf( " [0x%.8x - 0x%.8x] (0x%.8x) <%c> ",
ptr,
pACMemory_FromHeadToTail( ptr ),
nACMemory_HeadBlock( ptr ),
nACMemory_HeadCheck( ptr ) == ACMEMORY_CHECK_USED ? '*' : '-' );
//OS_Printf( "0x%.8x 0x%.8x", nACMemory_HeadBlock( ptr ), nACMemory_HeadCheck( ptr ) );
//OS_Printf( " .... " );
ptr += nACMemory_HeadBlock( ptr );
//OS_Printf( "0x%.8x 0x%.8x", nACMemory_TailCheck( ptr ), nACMemory_TailBlock( ptr ) );
OS_Printf( "\n" );
OS_PrintServer();
}
ptr = 0;
}
#define ACMemory_DebugDump( ) acMemory_DebugDump( )
#else
#define ACMemory_DebugDump( )
#endif //USE_ACMEMORY_DEBUGDUMP
//
#if defined( USE_ACMEMORY_DEBUGFILL )
static
void acMemory_DebugFill( void* ptr, int cnt, int val )
{
(void)ACMemory_Memset( ptr, val, cnt );
}
#define ACMemory_DebugFill( _ptr, _cnt, _val ) acMemory_DebugFill( _ptr, _cnt, _val )
#else
#define ACMemory_DebugFill( _ptr, _cnt, _val )
#endif //USE_ACMEMORY_DEBUGFILL
//
void ACMemory_Clear( )
{
unsigned long* head = ACMEMORYPOOL_HEAD;
unsigned long* tail = ACMEMORYPOOL_TAIL;
unsigned long block;
unsigned long check;
block = ACMEMORYPOOL_SIZE / 4;
check = ACMEMORY_CHECK_FREE;
nACMemory_HeadBlock( head ) = block;
nACMemory_HeadCheck( head ) = check;
nACMemory_TailBlock( tail ) = block;
nACMemory_TailCheck( tail ) = check;
ACMemory_DebugFill( pACMemory_FromHeadToBody( head ), (block - 4) * 4, 0xFF );
ACMemory_DebugDump( );
}
//
void* ACMemory_Alloc( u32 size )
{
#if defined( USE_OSALLOC )
OSIntrMode nOSIntrMode;
void* alloc = NULL;
nOSIntrMode = OS_DisableInterrupts( );
alloc = OS_Alloc( size );
(void)OS_RestoreInterrupts( nOSIntrMode );
return alloc;
#else
unsigned long* head = ACMEMORYPOOL_HEAD;
unsigned long* tail = ACMEMORYPOOL_TAIL;
unsigned long block, oldblock, newblock;
unsigned long check, oldcheck, newcheck;
if ( !size ) return 0;
//
if ( size < 16 ) size = 16;
block = 4 + ACMemory_Upper4( size ) / 4;
check = ACMEMORY_CHECK_USED;
//
for ( ; ; )
{
if ( (unsigned long)head >= (unsigned long)tail )
{
head = 0;
break;
}
newblock = nACMemory_HeadBlock( head );
newcheck = nACMemory_HeadCheck( head );
if ( newcheck == check )
{
head += newblock;
continue ;
}
if ( newblock < block + 4 + 4 )
{
head += newblock;
continue ;
}
break;
}
if ( !head ) return 0;
//
oldblock = nACMemory_HeadBlock( head );
oldcheck = nACMemory_HeadCheck( head );
nACMemory_HeadBlock( head ) = block;
nACMemory_HeadCheck( head ) = check;
tail = pACMemory_FromHeadToTail( head );
nACMemory_TailBlock( tail ) = block;
nACMemory_TailCheck( tail ) = check;
if ( (unsigned long)tail < (unsigned long)ACMEMORYPOOL_TAIL )
{
nACMemory_HeadBlock( tail ) = oldblock - block;
nACMemory_HeadCheck( tail ) = oldcheck;
tail = pACMemory_FromHeadToTail( tail );
nACMemory_TailBlock( tail ) = oldblock - block;
nACMemory_TailCheck( tail ) = oldcheck;
}
//
(void)ACMemory_Memset( pACMemory_FromHeadToBody( head ), 0x00, (block - 4) * 4 );
ACMemory_DebugFill( pACMemory_FromHeadToBody( head ), (block - 4) * 4, 0x00 );
ACMemory_DebugDump( );
return (void*)pACMemory_FromHeadToBody( head );
#endif
}
//
void ACMemory_Free( void* adrs )
{
#if defined( USE_OSALLOC )
OSIntrMode nOSIntrMode;
nOSIntrMode = OS_DisableInterrupts( );
OS_Free( adrs );
(void)OS_RestoreInterrupts( nOSIntrMode );
#else
unsigned long* work;
unsigned long* head;
unsigned long* tail;
unsigned long block;
unsigned long check;
if ( !adrs ) return ;
//
head = pACMemory_FromBodyToHead( adrs );
tail = pACMemory_FromHeadToTail( head );
block = nACMemory_HeadBlock( head );
check = ACMEMORY_CHECK_FREE;
//
if ( nACMemory_HeadBlock( head ) != nACMemory_TailBlock( tail ) )
return ;
if ( nACMemory_HeadCheck( head ) != nACMemory_TailCheck( tail ) )
return ;
//
if ( (unsigned long)head != (unsigned long)ACMEMORYPOOL_HEAD )
{
work = pACMemory_FromTailToHead( head );
if ( nACMemory_HeadCheck( work ) == check )
{
block += nACMemory_HeadBlock( work );
head = work;
}
}
//
if ( (unsigned long)tail != (unsigned long)ACMEMORYPOOL_TAIL )
{
work = pACMemory_FromHeadToTail( tail );
if ( nACMemory_TailCheck( work ) == check )
{
block += nACMemory_TailBlock( work );
tail = work;
}
}
//
nACMemory_HeadBlock( head ) = nACMemory_TailBlock( tail ) = block;
nACMemory_HeadCheck( head ) = nACMemory_TailCheck( tail ) = check;
ACMemory_DebugFill( pACMemory_FromHeadToBody( head ), (block - 4) * 4, 0xFF );
ACMemory_DebugDump( );
#endif
}
//
void* ACMemory_Memset( void* adrs, u32 val, u32 cnt )
{
if ( !adrs ) return 0;
MI_CpuFill8( (void*)adrs, (u8)val, (u32)cnt );
return adrs;
}
//
void* ACMemory_Memcpy( void* dst, void* src, u32 cnt )
{
if ( !dst || !src ) return 0;
MI_CpuCopy8( (const void*)src, (void*)dst, (u32)cnt );
return dst;
}

View File

@ -0,0 +1,453 @@
/*---------------------------------------------------------------------------*
Project: TwlIPL
File:
Copyright 2007 Nintendo. All rights reserved.
These coded instructions, statements, and computer programs contain
proprietary information of Nintendo of America Inc. and/or Nintendo
Company Ltd., and are protected by Federal copyright law. They may
not be disclosed to third parties or copied or duplicated in any form,
in whole or in part, without the prior written consent of Nintendo.
$Date:: $
$Rev$
$Author$
*---------------------------------------------------------------------------*/
#include <sysmenu/acsign.h>
#include "acmemory.h"
// SHA1
#include "sha.h"
#include "sha1dgst.c"
#define _DLENGTH_ (160/8)
#define _BLENGTH_ (512/8)
#define HASHContext SHA_CTX
#define HASHReset( _context ) (void)SHA1_Init( _context )
#define HASHSetSource( _context, _ptr, _len ) (void)SHA1_Update( _context, _ptr, _len )
#define HASHGetDigest( _context, _ptr ) (void)SHA1_Final( _ptr, _context )
// 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"
#if !defined( RSA_ENC_DEC )
#define BER_NULL 5
#define BER_OBJECT 6
#define BER_SEQUENCE 16
#define BER_OCTET_STRING 4
#define BER_CONSTRUCTED 0x20
//
// rsa_padding_check_pkcs1_type_1関数相当
//
static
int decode_padding( unsigned char* pdst_adrs, unsigned int* pdst_size,
unsigned char* psrc_adrs, unsigned int nsrc_size,
int length )
{
unsigned char* p;
unsigned char* q;
unsigned char* pe;
int i;
if (nsrc_size >= length )
return 0;
/* The leading 0 was removed by the bignum->bin conversion */
if (nsrc_size < 10)
return 0;
p = psrc_adrs;
pe = &(psrc_adrs[nsrc_size]);
/* if (p[0] != 0) goto err; */
if ( p[0] != 1 )
return 0;
p++;
for ( i = 0; i < 8; i++ )
{
if ( *(p++) != 0xFF )
return 0;
}
for ( ; p != pe; p++ )
{
if ( *p != 0xFF )
break;
}
if ( p == pe )
return 0;
if ( *(p++) != 0 )
return 0;
*pdst_size = (unsigned int)((int)pe - (int)p);
q = pdst_adrs;
while ( p != pe )
*(q++)= *(p++);
return 1;
}
//
//
//
static
int pk_skip( unsigned char **datap, unsigned int *dlenp,
unsigned char type, unsigned int *lenp)
{
unsigned char *data = *datap;
unsigned int dlen = *dlenp;
unsigned int len = 0;
unsigned char l;
if (*(data++) != type)
return 0;
if (dlen < 1)
return 0;
dlen--;
if ( (*data & 0x80) != 0 )
{
l = (unsigned char)( *data & 0x7F );
if (dlen < (unsigned int)l + 1)
return 0;
dlen -= l;
if (lenp != NULL)
{
data++;
do
{
len <<= 7;
len += (*data & 0x7f);
l--;
}
while (l > 0);
}
else
{
data += l;
}
}
else
{
len = *data;
data++;
if (dlen < 1)
return 0;
dlen--;
}
*datap = data;
*dlenp = dlen;
if (lenp != NULL)
{
*lenp = len;
}
return 1;
}
//
// PK_decode_sighash関数相当
//
static
int decode_sighash( unsigned char* data, unsigned int dlen,
unsigned char** ppdgst_adrs, unsigned int* pdgst_size,
unsigned char** pphash_adrs, unsigned int* phash_size )
{
#if 0
/* 01 */ OB_cmpu(BER_SEQUENCE, 0, 0),
/* 02 */ OB_down(0, 1),
/* 03 */ OB_cmpu(BER_SEQUENCE, 0, 0),
/* 04 */ OB_down(0, 1),
/* 05 */ OB_cmpu(BER_OBJECT, 0, 0),
/* 06 */ OB_call(OB_F_SET, PK_TYPE_SIG, PK_SIG_DIGEST_OID),
/* go up a level - we got all we need out of the
* sequence that contains the parameters
* - we could OB_next(0,1) and check that we have BER_NULL
* as then next item but there is no real need to do that
*/
/* 07 */ OB_up(0, 1),
/* 08 */ OB_next(0, 1),
/* 09 */ OB_cmpu(BER_OCTET_STRING, 0, 0),
/* 10 */ OB_call(OB_F_SET, PK_TYPE_SIG, PK_SIG_HASH),
/* 11 */ OB_exit(0),
/* 12 */ OB_FINISH,
#endif
unsigned int len;
if ( !pk_skip(&data, &dlen, (BER_SEQUENCE|BER_CONSTRUCTED), NULL) )
return 0;
if ( !pk_skip(&data, &dlen, (BER_SEQUENCE|BER_CONSTRUCTED), NULL) )
return 0;
if ( !pk_skip(&data, &dlen, (BER_OBJECT), &len) )
return 0;
/*
if (digest != NULL)
{
digest->adrs = data;
digest->size = len;
}
*/
if ( ppdgst_adrs ) *ppdgst_adrs = data;
if ( pdgst_size ) *pdgst_size = len;
data += len;
if (dlen < len)
return 0;
dlen -= len;
if ( !pk_skip(&data, &dlen, BER_NULL, &len) )
return 0;
data += len;
if (dlen < len)
return 0;
dlen -= len;
if ( !pk_skip(&data, &dlen, (BER_OCTET_STRING), &len) )
return 0;
/*
if (hash != NULL)
{
hash->adrs = data;
hash->size = len;
}
*/
if ( pphash_adrs ) *pphash_adrs = data;
if ( phash_size ) *phash_size = len;
return 1;
}
#endif
//
#define SGN_LEN 128
#define MOD_LEN 128
#define EXP_LEN 3
int ACSign_Decrypto(
void* buffer, // 出力領域
void* sgn_ptr, // データへのポインタ
void* key_ptr // キーへのポインタ
)
{
BN_CTX* ctx;
BIGNUM src, dst, exp, mod;
void* exp_ptr;
void* mod_ptr;
int nTmp, nWrk;
unsigned char* pAdrs = 0;
unsigned int nSize = 0;
unsigned long nDummyExp = 0x00010001; // 65537固定
unsigned long aBufferA[ 256 / sizeof (unsigned long) ];
unsigned long aBufferB[ 256 / sizeof (unsigned long) ];
if ( !buffer ) return 0;
if ( !sgn_ptr ) return 0;
if ( !key_ptr ) return 0;
//
ACMemory_Clear( );
//
exp_ptr = &nDummyExp;
mod_ptr = key_ptr;
(void)ACMemory_Memset( aBufferA, 0, sizeof aBufferA );
(void)ACMemory_Memset( aBufferB, 0, sizeof aBufferB );
ctx=BN_CTX_new();
BN_init( &src );
BN_init( &dst );
BN_init( &exp );
BN_init( &mod );
(void)BN_bin2bn( sgn_ptr, SGN_LEN, &src );
(void)BN_bin2bn( exp_ptr, EXP_LEN, &exp );
(void)BN_bin2bn( mod_ptr, MOD_LEN, &mod );
nTmp = BN_mod_exp( &dst, &src, &exp, &mod, ctx );
nTmp = BN_bn2bin( &dst, (unsigned char*)aBufferA );
BN_free( &src );
BN_free( &dst );
BN_free( &exp );
BN_free( &mod );
if (ctx != NULL)
BN_CTX_free(ctx);
#if defined( RSA_ENC_DEC )
pAdrs = (unsigned char*)aBufferA + 4; //ダミー部4バイトは読み飛ばし
nSize = nTmp;
(void)ACMemory_Memcpy( buffer, pAdrs, _DLENGTH_ * 4 );
#else
if ( !decode_padding( (unsigned char*)aBufferB, (unsigned int*)&nWrk, (unsigned char*)aBufferA, (unsigned int )nTmp, SGN_LEN ) )
return 0;
if ( !decode_sighash( (unsigned char*)aBufferB, (unsigned int)nWrk, NULL, NULL, (unsigned char**)&pAdrs, (unsigned int*)&nSize ) )
return 0;
if ( nSize != _DLENGTH_ )
return 0;
(void)ACMemory_Memcpy( buffer, pAdrs, _DLENGTH_ * 1 );
#endif
return 1;
}
//
#define ROMH_SIZE 0x0160
int ACSign_Digest(
void* buffer, // 出力領域
void* romh_ptr, // データへのポインタ
void* mbin_ptr, // データへのポインタ
int mbin_len, // データの長さ
void* sbin_ptr, // データへのポインタ
int sbin_len, // データの長さ
u32 serial_num // シリアルナンバー
)
{
#if defined( RSA_ENC_DEC )
HASHContext context;
if ( !buffer ) return 0;
if ( !romh_ptr ) return 0;
if ( !mbin_ptr || !mbin_len ) return 0;
if ( !sbin_ptr || !sbin_len ) return 0;
HASHReset( &context );
HASHSetSource( &context, romh_ptr, ROMH_SIZE );
HASHGetDigest( &context, (unsigned char*)buffer + _DLENGTH_ * 0 );
HASHReset( &context );
HASHSetSource( &context, mbin_ptr, mbin_len );
HASHGetDigest( &context, (unsigned char*)buffer + _DLENGTH_ * 1 );
HASHReset( &context );
HASHSetSource( &context, sbin_ptr, sbin_len );
HASHGetDigest( &context, (unsigned char*)buffer + _DLENGTH_ * 2 );
HASHReset( &context );
HASHSetSource( &context, buffer, _DLENGTH_ * 3 );
HASHGetDigest( &context, (unsigned char*)buffer + _DLENGTH_ * 3 );
#else
HASHContext context;
unsigned char aBuffer[ (_DLENGTH_ * 3 + sizeof (unsigned long)) ];
if ( !buffer ) return 0;
if ( !romh_ptr ) return 0;
if ( !mbin_ptr || !mbin_len ) return 0;
if ( !sbin_ptr || !sbin_len ) return 0;
HASHReset( &context );
HASHSetSource( &context, romh_ptr, ROMH_SIZE );
HASHGetDigest( &context, (unsigned char*)aBuffer + _DLENGTH_ * 0 );
HASHReset( &context );
HASHSetSource( &context, mbin_ptr, mbin_len );
HASHGetDigest( &context, (unsigned char*)aBuffer + _DLENGTH_ * 1 );
HASHReset( &context );
HASHSetSource( &context, sbin_ptr, sbin_len );
HASHGetDigest( &context, (unsigned char*)aBuffer + _DLENGTH_ * 2 );
// シリアル番号分 今は0固定
aBuffer[ (_DLENGTH_ * 3) + 0 ] = (unsigned char)((serial_num >> 0) & 0xFF);
aBuffer[ (_DLENGTH_ * 3) + 1 ] = (unsigned char)((serial_num >> 8) & 0xFF);
aBuffer[ (_DLENGTH_ * 3) + 2 ] = (unsigned char)((serial_num >> 16) & 0xFF);
aBuffer[ (_DLENGTH_ * 3) + 3 ] = (unsigned char)((serial_num >> 24) & 0xFF);
HASHReset( &context );
HASHSetSource( &context, (unsigned char*)aBuffer, _DLENGTH_ * 3 + sizeof (unsigned long) );
HASHGetDigest( &context, (unsigned char*)buffer );
#endif
return 1;
}
//
int ACSign_Compare(
void* decrypto, // ACSign_Decryptoの出力
void* digest // ACSign_Digestの出力
)
{
unsigned char* ptrA = (unsigned char*)decrypto;
unsigned char* ptrB = (unsigned char*)digest;
int loop;
int test = 1;
if ( !decrypto ) return 0;
if ( !digest ) return 0;
#if defined( RSA_ENC_DEC )
for ( loop = 0; loop < _DLENGTH_ * 4; loop++ )
#else
for ( loop = 0; loop < _DLENGTH_ * 1; loop++ )
#endif
{
if ( *ptrA++ != *ptrB++ )
{
test = 0;
break;
}
}
return test;
}

View File

@ -0,0 +1,111 @@
/*---------------------------------------------------------------------------*
Project: TwlIPL
File:
Copyright 2007 Nintendo. All rights reserved.
These coded instructions, statements, and computer programs contain
proprietary information of Nintendo of America Inc. and/or Nintendo
Company Ltd., and are protected by Federal copyright law. They may
not be disclosed to third parties or copied or duplicated in any form,
in whole or in part, without the prior written consent of Nintendo.
$Date:: $
$Rev$
$Author$
*---------------------------------------------------------------------------*/
#include <nitro.h>
#include <sysmenu/acsign.h>
#include <string.h>
#define AUTH_KEY_BUFFER_LEN 128
#define MB_AUTH_SIGN_SIZE (128) /* digital sign size */
typedef struct MbAuthCode
{
char magic_code[2]; // マジックナンバー
u16 version; // バージョン
u8 sign[MB_AUTH_SIGN_SIZE]; // 署名
u32 serial_number; // シリアル番号
} MbAuthCode; // 16byte
static u8 key_buffer[AUTH_KEY_BUFFER_LEN] = {
0x9E,0xC1,0xCC,0xC0,0x4A,0x6B,0xD0,0xA0,0x6D,0x62,0xED,0x5F,0x15,0x67,0x87,0x12,
0xE6,0xF4,0x77,0x1F,0xD8,0x5C,0x81,0xCE,0x0C,0xD0,0x22,0x31,0xF5,0x89,0x08,0xF5,
0xBE,0x04,0xCB,0xC1,0x4F,0x63,0xD9,0x5A,0x98,0xFF,0xEB,0x36,0x0F,0x9C,0x5D,0xAD,
0x15,0xB9,0x99,0xFB,0xC6,0x86,0x2C,0x0A,0x0C,0xFC,0xE6,0x86,0x03,0x60,0xD4,0x87,
0x28,0xD5,0x66,0x42,0x9C,0xF7,0x04,0x14,0x4E,0x6F,0x73,0x20,0xC3,0x3E,0x3F,0xF5,
0x82,0x2E,0x78,0x18,0xD6,0xCD,0xD5,0xC2,0xDC,0xAA,0x1D,0x34,0x91,0xEC,0x99,0xC9,
0xF7,0xBF,0xBF,0xA0,0x0E,0x1E,0xF0,0x25,0xF8,0x66,0x17,0x54,0x34,0x28,0x2D,0x28,
0xA3,0xAE,0xF0,0xA9,0xFA,0x3A,0x70,0x56,0xD2,0x34,0xA9,0xC5,0x9E,0x5D,0xF5,0xE1
};
int ACSignDecrpto(void *output_buffer, MBDownloadFileInfo *download_file_info_buf)
{
return ACSign_Decrypto(output_buffer,
((MbAuthCode *)(download_file_info_buf->auth_code))->sign,
key_buffer);
}
int ACSignDigest(void *input_buffer, MBDownloadFileInfo *download_file_info_buf)
{
int ret_code;
u8 digest_output_buffer[AUTH_BUFFER_LEN];
ret_code = ACSign_Digest((void *)digest_output_buffer, // 出力領域 20 Bytes
(void *)(download_file_info_buf->seg[0].recv_addr),
(void *)(download_file_info_buf->seg[1].recv_addr),
(int)(download_file_info_buf->seg[1].size),
(void *)(download_file_info_buf->seg[2].recv_addr),
(int)(download_file_info_buf->seg[2].size),
((MbAuthCode *)(download_file_info_buf)->auth_code)->serial_number // serial_number
);
if( ret_code == 0 )
{
return ret_code; // failure
}
return ACSign_Compare(
input_buffer, // ACSign_Decryptoの出力
(void*)digest_output_buffer // ACSign_Digestの出力
);
}
#if 0
void* doAlloc( int size )
{
OSIntrMode nOSIntrMode;
void* alloc = NULL;
nOSIntrMode = OS_DisableInterrupts( );
alloc = OS_Alloc( size );
(void)OS_RestoreInterrupts( nOSIntrMode );
return alloc;
}
void doFree( void* adrs )
{
OSIntrMode nOSIntrMode;
nOSIntrMode = OS_DisableInterrupts( );
OS_Free( adrs );
(void)OS_RestoreInterrupts( nOSIntrMode );
}
void* doMemset( void* adrs, int val, int cnt )
{
return memset( adrs, val, cnt );
}
void* doMemcpy( void* dst, void* src, int cnt )
{
return memcpy( dst, src, cnt );
}
#endif

View File

@ -0,0 +1,320 @@
/*---------------------------------------------------------------------------*
Project: TwlIPL
File:
Copyright 2007 Nintendo. All rights reserved.
These coded instructions, statements, and computer programs contain
proprietary information of Nintendo of America Inc. and/or Nintendo
Company Ltd., and are protected by Federal copyright law. They may
not be disclosed to third parties or copied or duplicated in any form,
in whole or in part, without the prior written consent of Nintendo.
$Date:: $
$Rev$
$Author$
*---------------------------------------------------------------------------*/
/*
* 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 (; i<max; i++)
*(rp++)= *(ap++);
}
/* Memcpy(rp,ap,sizeof(*ap)*(max-i));*/
return(1);
}
#endif
/**
* perform unsigned subtraction of <tt>b</tt> from <tt>a</tt>
* @param r result of subtraction
* @param a pointer to a BIGNUM
* @param b pointer to a BIGNUM
* @pre <tt>a</tt> must be larger than <tt>b</tt>
* @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<min; i++)
{
t1= *(ap++);
t2= *(bp++);
if (carry)
{
carry=(t1 <= t2);
t1=(t1-t2-1)&BN_MASK2;
}
else
{
carry=(t1 < t2);
t1=(t1-t2)&BN_MASK2;
}
#if defined(IRIX_CC_BUG) && !defined(LINT)
dummy=t1;
#endif
*(rp++)=t1&BN_MASK2;
}
if (carry) /* subtracted */
{
while (i < max)
{
i++;
t1= *(ap++);
t2=(t1-1)&BN_MASK2;
*(rp++)=t2;
if (t1 > 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

View File

@ -0,0 +1,525 @@
/*---------------------------------------------------------------------------*
Project: TwlIPL
File:
Copyright 2007 Nintendo. All rights reserved.
These coded instructions, statements, and computer programs contain
proprietary information of Nintendo of America Inc. and/or Nintendo
Company Ltd., and are protected by Federal copyright law. They may
not be disclosed to third parties or copied or duplicated in any form,
in whole or in part, without the prior written consent of Nintendo.
$Date:: $
$Rev$
$Author$
*---------------------------------------------------------------------------*/
/*
* 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<num;i++)
* rp[i]+=ap[i]*w (with carry propagation)
*
*/
#ifdef BN_MUL_ADD_WORDS
#if 0
BN_ULONG bn_mul_add_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);
for (;;)
{
mul_add(rp[0],ap[0],w,c1);
if (--num == 0) break;
ap++;
rp++;
}
return(c1);
}
#endif
BN_ULONG bn_mul_add_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);
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

View File

@ -0,0 +1,450 @@
/*---------------------------------------------------------------------------*
Project: TwlIPL
File:
Copyright 2007 Nintendo. All rights reserved.
These coded instructions, statements, and computer programs contain
proprietary information of Nintendo of America Inc. and/or Nintendo
Company Ltd., and are protected by Federal copyright law. They may
not be disclosed to third parties or copied or duplicated in any form,
in whole or in part, without the prior written consent of Nintendo.
$Date:: $
$Rev$
$Author$
*---------------------------------------------------------------------------*/
/*
* 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

View File

@ -0,0 +1,381 @@
/*---------------------------------------------------------------------------*
Project: TwlIPL
File:
Copyright 2007 Nintendo. All rights reserved.
These coded instructions, statements, and computer programs contain
proprietary information of Nintendo of America Inc. and/or Nintendo
Company Ltd., and are protected by Federal copyright law. They may
not be disclosed to third parties or copied or duplicated in any form,
in whole or in part, without the prior written consent of Nintendo.
$Date:: $
$Rev$
$Author$
*---------------------------------------------------------------------------*/
/*
* 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<loop-1; i++)
{
BN_ULONG q,n0,n1;
BN_ULONG l0;
wnum.d--; wnum.top++;
n0=wnump[0];
n1=wnump[-1];
if (n0 == d0)
q=BN_MASK2;
else
q=bn_div_words(n0,n1,d0);
{
#ifdef BN_LLONG
BN_ULLONG t1,t2,rem;
t1=((((BN_ULLONG)n0)<<BN_BITS2)|n1)&BN_MASK;
for (;;)
{
t2=((BN_ULLONG)d1*q)&BN_MASK;
rem=(t1-(BN_ULLONG)q*d0)&BN_MASK;
if ((rem>>BN_BITS2) ||
(t2 <= ((BN_ULLONG)(rem<<BN_BITS2)+wnump[-2])))
break;
q--;
}
#else
BN_ULONG t1l,t1h,t2l,t2h,t3l,t3h,ql,qh,t3t;
t1h=n0;
t1l=n1;
for (;;)
{
t2l=LBITS(d1); t2h=HBITS(d1);
ql =LBITS(q); qh =HBITS(q);
mul64(t2l,t2h,ql,qh); /* t2=(BN_ULLONG)d1*q; */
t3t=LBITS(d0); t3h=HBITS(d0);
mul64(t3t,t3h,ql,qh); /* t3=t1-(BN_ULLONG)q*d0; */
t3l=(t1l-t3t)&BN_MASK2;
if (t3l > t1l) t3h++;
t3h=(t1h-t3h)&BN_MASK2;
/*if ((t3>>BN_BITS2) ||
(t2 <= ((t3<<BN_BITS2)+wnump[-2])))
break; */
if (t3h) break;
if (t2h < t3l) break;
if ((t2h == t3l) && (t2l <= wnump[-2])) break;
q--;
}
#endif
}
l0=bn_mul_words(tmp->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

View File

@ -0,0 +1,453 @@
/*---------------------------------------------------------------------------*
Project: TwlIPL
File:
Copyright 2007 Nintendo. All rights reserved.
These coded instructions, statements, and computer programs contain
proprietary information of Nintendo of America Inc. and/or Nintendo
Company Ltd., and are protected by Federal copyright law. They may
not be disclosed to third parties or copied or duplicated in any form,
in whole or in part, without the prior written consent of Nintendo.
$Date:: $
$Rev$
$Author$
*---------------------------------------------------------------------------*/
/*
* 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=(unsigned int)( (1<<bits)-1 );
ss=0;
sp= &(str[((p->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=(unsigned int)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( (int)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

View File

@ -0,0 +1,172 @@
/*---------------------------------------------------------------------------*
Project: TwlIPL
File:
Copyright 2007 Nintendo. All rights reserved.
These coded instructions, statements, and computer programs contain
proprietary information of Nintendo of America Inc. and/or Nintendo
Company Ltd., and are protected by Federal copyright law. They may
not be disclosed to third parties or copied or duplicated in any form,
in whole or in part, without the prior written consent of Nintendo.
$Date:: $
$Rev$
$Author$
*---------------------------------------------------------------------------*/
/*
* 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; i<bits; i++)
{
if (!BN_sqr(tmp,v,ctx)) goto err;
if (!BN_mod(v,tmp,m,ctx)) goto err;
if (BN_is_bit_set(p,i))
{
if (!BN_mul(tmp,r,v,ctx)) goto err;
if (!BN_mod(r,tmp,m,ctx)) goto err;
}
}
ret=1;
err:
ctx->tos-=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; i<bits; i++)
{
if (!BN_sqr(v,v,ctx)) goto err;
if (BN_is_bit_set(p,i))
{
if (!BN_mul(rr,rr,v,ctx)) goto err;
}
}
ret=1;
err:
ctx->tos=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

View File

@ -0,0 +1,79 @@
/*---------------------------------------------------------------------------*
Project: TwlIPL
File:
Copyright 2007 Nintendo. All rights reserved.
These coded instructions, statements, and computer programs contain
proprietary information of Nintendo of America Inc. and/or Nintendo
Company Ltd., and are protected by Federal copyright law. They may
not be disclosed to third parties or copied or duplicated in any form,
in whole or in part, without the prior written consent of Nintendo.
$Date:: $
$Rev$
$Author$
*---------------------------------------------------------------------------*/
/*
* 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; i<w; i++)
{
v0=bn_mul_add_words(ap,np,w,((*ap)*n0)&BN_MASK2);
v0=(v1+v0)&BN_MASK2;
v1= (BN_ULONG)( (v0 < v1)?1:0 );
if (((*wap= *wap+v0)&BN_MASK2) < v0) v1++;
ap++; wap++;
}
/* ap is now wap (&a[w]) */
i=w-1;
if (v1 == 0)
{
if (ap[i] == np[i]) /* GTCHECK */
{
/* i=w-1 */
for (; i>0; 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; i<w; i++)
ret[i]=ap[i];
#endif
}
}

View File

@ -0,0 +1,245 @@
/*---------------------------------------------------------------------------*
Project: TwlIPL
File:
Copyright 2007 Nintendo. All rights reserved.
These coded instructions, statements, and computer programs contain
proprietary information of Nintendo of America Inc. and/or Nintendo
Company Ltd., and are protected by Federal copyright law. They may
not be disclosed to third parties or copied or duplicated in any form,
in whole or in part, without the prior written consent of Nintendo.
$Date:: $
$Rev$
$Author$
*---------------------------------------------------------------------------*/
/*
* 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 NOPROTO
BIGNUM *bn_euclid(BIGNUM *a, BIGNUM *b);
#else
BIGNUM *bn_euclid();
#endif
#if !(defined(NO_SPLIT) && defined(SPLIT_FILE))
#ifdef NO_SPLIT
#define SPLIT_BN_GCD
#define SPLIT_BN_MOD_INVERSE
#define SPLIT_BN_MOD_INVERSE_WORD
#endif /* NO_SPLIT */
#ifdef SPLIT_BN_GCD
int BN_gcd(r,in_a,in_b,ctx)
BIGNUM *r,*in_a,*in_b;
BN_CTX *ctx;
{
BIGNUM *a,*b,*t;
int ret=0;
bn_check_top(in_a);
bn_check_top(in_b);
a= &(ctx->bn[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<<BN_BITS2)) mod n */
BN_ULONG BN_mod_inverse_word(n)
BN_ULONG n;
{
BN_ULONG A,B,X,Y,M,D,R;
BN_ULONG T;
int sign;
X=0;
Y=1;
A=0; /* 1 00000000 */
B=n;
sign=1;
T=((BN_ULONG)0-B)&BN_MASK2;
D=T/B+1;
M=T%B;
T=A; A=B; B=M;
/* T=D*X; X == 0; so leave out */
T=Y;
M=Y; Y=X; X=T;
sign= -sign;
while (B != 0)
{
D=A/B;
M=A%B;
T=D*X+Y;
Y=X; X=T;
A=B; B=M;
sign= -sign;
}
if (sign < 0)
Y=(n-Y)&BN_MASK2;
if (A == 1)
R=Y%n;
else
R=0;
return(R);
}
#endif
#endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,128 @@
/*---------------------------------------------------------------------------*
Project: TwlIPL
File:
Copyright 2007 Nintendo. All rights reserved.
These coded instructions, statements, and computer programs contain
proprietary information of Nintendo of America Inc. and/or Nintendo
Company Ltd., and are protected by Federal copyright law. They may
not be disclosed to third parties or copied or duplicated in any form,
in whole or in part, without the prior written consent of Nintendo.
$Date:: $
$Rev$
$Author$
*---------------------------------------------------------------------------*/
/*
* 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; i<a->top; 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<<lb)&BN_MASK2;
}
(void)Memset(t,0,nw*sizeof(t[0]));
/* for (i=0; i<nw; i++)
t[i]=0;*/
r->top=a->top+nw+1;
bn_fix_top(r);
return(1);
}
#endif
#endif

View File

@ -0,0 +1,299 @@
/*---------------------------------------------------------------------------*
Project: TwlIPL
File:
Copyright 2007 Nintendo. All rights reserved.
These coded instructions, statements, and computer programs contain
proprietary information of Nintendo of America Inc. and/or Nintendo
Company Ltd., and are protected by Federal copyright law. They may
not be disclosed to third parties or copied or duplicated in any form,
in whole or in part, without the prior written consent of Nintendo.
$Date:: $
$Rev$
$Author$
*---------------------------------------------------------------------------*/
/*
* 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 <stdio.h>
#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; j<a_in->top; 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<num; i++)
{
vall[i]= &(vall[i-1][top]);
bn_mul_normal(tmp,vall[i-1],top,dp,top);
bn_from_montgomery_words(vall[i],tmp,np,top,n0);
}
}
mul= *(str++);
sqr= *(str++);
/* add all of the 255s together plus next less than 255
* 255 is a special case and should be treated as 256
* which is too big to fit in an unsigned char
*/
if(sqr == 255 && mul == 0)
{
mul = *(str++); /* grab next mul in case it is last */
while(*str == 255 && mul == 0)
{
sqr += 256;
str++;
mul = *(str++); /* increment the str pointer */
}
sqr+= *(str++) + 1; /* add last sqr value < 255 + 1 for 1st 255 */
}
/* Get the first element */
(void)Memcpy(rp,vall[mul>>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<sqr; i++)
{
bn_sqr_normal(tmp,rp,top,dp);
bn_from_montgomery_words(rp,tmp,np,top,n0);
}
mul= *(str++);
sqr= *(str++);
/* add all of the 255s together plus next less than 255 */
if(sqr == 255 && mul == 0)
{
mul = *(str++); /* grab next mul */
while(str[0] == 255 && mul == 0)
{
sqr += 256;
str++;
mul = *(str++); /* increment the str pointer */
}
sqr+= *(str++) + 1; /* add last sqr value < 255 + 1 */
}
if ((mul == 0) && (sqr == 0)) break;
if ((sqr != 0) || (mul != 1))
{
bn_mul_normal(tmp,rp,top,vall[mul>>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; i<top+top; i++)
rp[i]=0;
bn_from_montgomery_words(rr_in->d,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 */

View File

@ -0,0 +1,267 @@
/*---------------------------------------------------------------------------*
Project: TwlIPL
File:
Copyright 2007 Nintendo. All rights reserved.
These coded instructions, statements, and computer programs contain
proprietary information of Nintendo of America Inc. and/or Nintendo
Company Ltd., and are protected by Federal copyright law. They may
not be disclosed to third parties or copied or duplicated in any form,
in whole or in part, without the prior written consent of Nintendo.
$Date:: $
$Rev$
$Author$
*---------------------------------------------------------------------------*/
/*
* 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 <i>bnme[]</i> and counter <i>me_num</i>
*
* @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 <i>a</i> 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

View File

@ -0,0 +1,247 @@
/*---------------------------------------------------------------------------*
Project: TwlIPL
File:
Copyright 2007 Nintendo. All rights reserved.
These coded instructions, statements, and computer programs contain
proprietary information of Nintendo of America Inc. and/or Nintendo
Company Ltd., and are protected by Federal copyright law. They may
not be disclosed to third parties or copied or duplicated in any form,
in whole or in part, without the prior written consent of Nintendo.
$Date:: $
$Rev$
$Author$
*---------------------------------------------------------------------------*/
/*
* 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; i<max; i++) /* Memset? XXX */
r->d[i]=0;
r->top=max;
n0=mont->n0;
v1=0;
for (i=0; i<nl; i++)
{
v0=bn_mul_add_words(rp,np,nl,(rp[0]*n0)&BN_MASK2);
v0=(v1+v0)&BN_MASK2;
v1=(BN_ULONG)( (v0 < v1)?1:0 );
if ((nrp[0]=(nrp[0]+v0)&BN_MASK2) < v0)
v1++;
nrp++;
rp++;
}
nrp[0]=v1;
bn_fix_top(r);
/* mont->riw 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

View File

@ -0,0 +1,137 @@
/*---------------------------------------------------------------------------*
Project: TwlIPL
File:
Copyright 2007 Nintendo. All rights reserved.
These coded instructions, statements, and computer programs contain
proprietary information of Nintendo of America Inc. and/or Nintendo
Company Ltd., and are protected by Federal copyright law. They may
not be disclosed to third parties or copied or duplicated in any form,
in whole or in part, without the prior written consent of Nintendo.
$Date:: $
$Rev$
$Author$
*---------------------------------------------------------------------------*/
/*
* 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);
}

View File

@ -0,0 +1,795 @@
/*---------------------------------------------------------------------------*
Project: TwlIPL
File:
Copyright 2007 Nintendo. All rights reserved.
These coded instructions, statements, and computer programs contain
proprietary information of Nintendo of America Inc. and/or Nintendo
Company Ltd., and are protected by Federal copyright law. They may
not be disclosed to third parties or copied or duplicated in any form,
in whole or in part, without the prior written consent of Nintendo.
$Date:: $
$Rev$
$Author$
*---------------------------------------------------------------------------*/
/*
* 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<n; i++)
lp[i]=((~mp[i])+1)&BN_MASK2;
}
/* s[0] = low(al*bl)
* t[3] = high(al*bl)
* t[10] = (a[0]-a[1])*(b[1]-b[0]) neg is the sign
* r[10] = (a[1]*b[1])
*/
/* R[10] = al*bl
* R[21] = al*bl + ah*bh + (a[0]-a[1])*(b[1]-b[0])
* R[32] = ah*bh
*/
/* R[1]=t[3]+l[0]+r[0](+-)t[0] (have carry/borrow)
* R[2]=r[0]+t[3]+r[1](+-)t[1] (have carry/borrow)
* R[3]=r[1]+(carry/borrow)
*/
if (l != NULL)
{
lp= &(t[n2]);
c1= (int)bn_add_words(lp,&(t[n2+n]),&(l[0]),n);
}
else
{
lp= &(t[n2+n]);
c1=0;
}
c1+=(int)bn_add_words(&(t[n2]),lp, &(r[0]),n);
if (oneg)
c1-=(int)bn_sub_words(&(t[n2]),&(t[n2]),&(t[0]),n);
else
c1+=(int)bn_add_words(&(t[n2]),&(t[n2]),&(t[0]),n);
c2 =(int)bn_add_words(&(r[0]),&(r[0]),&(t[n2+n]),n);
c2+=(int)bn_add_words(&(r[0]),&(r[0]),&(r[n]),n);
if (oneg)
c2-=(int)bn_sub_words(&(r[0]),&(r[0]),&(t[n]),n);
else
c2+=(int)bn_add_words(&(r[0]),&(r[0]),&(t[n]),n);
if (c1 != 0) /* Add starting at r[0], could be +ve or -ve */
{
i=0;
if (c1 > 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

View File

@ -0,0 +1,150 @@
/*---------------------------------------------------------------------------*
Project: TwlIPL
File:
Copyright 2007 Nintendo. All rights reserved.
These coded instructions, statements, and computer programs contain
proprietary information of Nintendo of America Inc. and/or Nintendo
Company Ltd., and are protected by Federal copyright law. They may
not be disclosed to third parties or copied or duplicated in any form,
in whole or in part, without the prior written consent of Nintendo.
$Date:: $
$Rev$
$Author$
*---------------------------------------------------------------------------*/
/*
* 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<j; i++)
{
BN_init(&val[i]);
if (!BN_mod_mul_reciprocal(&(val[i]),&(val[i-1]),aa,&recp,ctx))
goto err;
}
ts=i;
start=1; /* This is used to avoid multiplication etc
* when there is only the value '1' in the
* buffer. */
wvalue=0; /* The 'value' of the window */
wstart=bits-1; /* The top bit of the window */
wend=0; /* The bottom bit of the window */
if (!BN_one(r)) goto err;
for (;;)
{
if (BN_is_bit_set(p,wstart) == 0)
{
if (!start)
if (!BN_mod_mul_reciprocal(r,r,r,&recp,ctx))
goto err;
if (wstart == 0) break;
wstart--;
continue;
}
/* We now have wstart on a 'set' bit, we now need to work out
* how bit a window to do. To do this we need to scan
* forward until the last set bit before the end of the
* window */
j=wstart;
wvalue=1;
wend=0;
for (i=1; i<window; i++)
{
if (wstart-i < 0) break;
if (BN_is_bit_set(p,wstart-i))
{
wvalue<<=(i-wend);
wvalue|=1;
wend=i;
}
}
/* wend is the size of the current window */
j=wend+1;
/* add the 'bytes above' */
if (!start)
for (i=0; i<j; i++)
{
if (!BN_mod_mul_reciprocal(r,r,r,&recp,ctx))
goto err;
}
/* wvalue will be an odd number < 2^window */
if (!BN_mod_mul_reciprocal(r,r,&(val[wvalue>>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; i<ts; i++)
BN_clear_free(&(val[i]));
BN_RECP_CTX_free(&recp);
return(ret);
}
/* #endif */

View File

@ -0,0 +1,249 @@
/*---------------------------------------------------------------------------*
Project: TwlIPL
File:
Copyright 2007 Nintendo. All rights reserved.
These coded instructions, statements, and computer programs contain
proprietary information of Nintendo of America Inc. and/or Nintendo
Company Ltd., and are protected by Federal copyright law. They may
not be disclosed to third parties or copied or duplicated in any form,
in whole or in part, without the prior written consent of Nintendo.
$Date:: $
$Rev$
$Author$
*---------------------------------------------------------------------------*/
/*
* 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_2s_COMP
#define SPLIT_BN_MUL_REC_WORDS
#define SPLIT_BN_SQR_REC_WORDS
#endif /* NO_SPLIT */
#ifdef SPLIT_BN_2s_COMP
void bn_2s_comp(r,a,n)
BN_ULONG *r,*a;
int n;
{
BN_ULONG l;
int i;
for (i=0; i<n; i++)
{
l=a[i];
l= ~l+1;
r[i]=l;
if (l != 0) break;
}
#if 1
for (i++; i<n; i++)
{
r[i]= ~a[i];
}
#else
for (i+=4; i<n; i+=4)
{
r[i-3]= ~a[i-3];
r[i-2]= ~a[i-2];
r[i-1]= ~a[i-1];
r[i ]= ~a[i ];
}
for (i-=3; i<n; i++)
{
r[i]= ~a[i];
}
#endif
}
#endif
#ifdef SPLIT_BN_MUL_REC_WORDS
/* t needs to be 2*n words */
void bn_mul_rec_words(r,a,b,tt,rec)
BN_ULONG *r,*a,*b,*tt;
BN_REC *rec;
{
int n=rec->n;
int n2=n/2;
int neg=0;
BN_ULONG 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 *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;
BN_ULONG 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 */

View File

@ -0,0 +1,218 @@
/*---------------------------------------------------------------------------*
Project: TwlIPL
File:
Copyright 2007 Nintendo. All rights reserved.
These coded instructions, statements, and computer programs contain
proprietary information of Nintendo of America Inc. and/or Nintendo
Company Ltd., and are protected by Federal copyright law. They may
not be disclosed to third parties or copied or duplicated in any form,
in whole or in part, without the prior written consent of Nintendo.
$Date:: $
$Rev$
$Author$
*---------------------------------------------------------------------------*/
/*
* 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);
}

View File

@ -0,0 +1,139 @@
/*---------------------------------------------------------------------------*
Project: TwlIPL
File:
Copyright 2007 Nintendo. All rights reserved.
These coded instructions, statements, and computer programs contain
proprietary information of Nintendo of America Inc. and/or Nintendo
Company Ltd., and are protected by Federal copyright law. They may
not be disclosed to third parties or copied or duplicated in any form,
in whole or in part, without the prior written consent of Nintendo.
$Date:: $
$Rev$
$Author$
*---------------------------------------------------------------------------*/
/*
* 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<j; i++)
{
tmp =(l>>rb)&BN_MASK2;
l= *(f++);
*(t++) =(tmp|(l<<lb))&BN_MASK2;
}
*(t++) =(l>>rb)&BN_MASK2;
*t=0;
}
bn_fix_top(r);
return(1);
}
#endif
#endif

View File

@ -0,0 +1,289 @@
/*---------------------------------------------------------------------------*
Project: TwlIPL
File:
Copyright 2007 Nintendo. All rights reserved.
These coded instructions, statements, and computer programs contain
proprietary information of Nintendo of America Inc. and/or Nintendo
Company Ltd., and are protected by Federal copyright law. They may
not be disclosed to third parties or copied or duplicated in any form,
in whole or in part, without the prior written consent of Nintendo.
$Date:: $
$Rev$
$Author$
*---------------------------------------------------------------------------*/
/*
* 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

View File

@ -0,0 +1,116 @@
/*---------------------------------------------------------------------------*
Project: TwlIPL
File:
Copyright 2007 Nintendo. All rights reserved.
These coded instructions, statements, and computer programs contain
proprietary information of Nintendo of America Inc. and/or Nintendo
Company Ltd., and are protected by Federal copyright law. They may
not be disclosed to third parties or copied or duplicated in any form,
in whole or in part, without the prior written consent of Nintendo.
$Date:: $
$Rev$
$Author$
*---------------------------------------------------------------------------*/
/*
* 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_BITS2)|l)/(BN_ULLONG)d));
}
#else
/* Divide h-l by d and return the result. */
/* I need to test this some more */
BN_ULONG bn_div_words(h,l,d)
BN_ULONG h,l,d;
{
BN_ULONG dh,dl,q,ret=0,th,tl,t;
int i,count=2;
if (d == 0) return(BN_MASK2);
i=BN_num_bits_word(d);
if ((i != BN_BITS2) && (h > ((BN_ULONG)1)<<i))
{
return(0);
}
i=BN_BITS2-i;
if (h >= d) h-=d;
if (i)
{
d=(d<<i)&BN_MASK2;
h=((h<<i)|(l>>(BN_BITS2-i)))&BN_MASK2;
l=(l<<i)&BN_MASK2;
}
dh=(d>>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)+
((l>>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;
th=(th+t)&BN_MASK2;
if (l < tl) th++;
l=(l-tl)&BN_MASK2;
if (h < th)
{
h=(h+d)&BN_MASK2;
q--;
}
h=(h-th)&BN_MASK2;
if (--count == 0) break;
ret=(q&BN_MASK2lh)<<BN_BITS4;
h=((h<<BN_BITS4)|(l>>BN_BITS4))&BN_MASK2;
l=(l&BN_MASK2l)<<BN_BITS4;
}
ret|=q;
return(ret);
}
#endif
#endif /* BN_DIV_WORDS */

View File

@ -0,0 +1,238 @@
/*---------------------------------------------------------------------------*
Project: TwlIPL
File:
Copyright 2007 Nintendo. All rights reserved.
These coded instructions, statements, and computer programs contain
proprietary information of Nintendo of America Inc. and/or Nintendo
Company Ltd., and are protected by Federal copyright law. They may
not be disclosed to third parties or copied or duplicated in any form,
in whole or in part, without the prior written consent of Nintendo.
$Date:: $
$Rev$
$Author$
*---------------------------------------------------------------------------*/
/*
* 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_WORD
#define SPLIT_BN_DIV_WORD
#define SPLIT_BN_ADD_WORD
#define SPLIT_BN_SUB_WORD
#define SPLIT_BN_MUL_WORD
#endif /* NO_SPLIT */
#ifdef SPLIT_BN_MOD_WORD
BN_ULONG BN_mod_word(a, w)
BIGNUM *a;
BN_ULONG w;
{
#ifndef BN_LLONG
BN_ULONG ret=0;
#else
BN_ULLONG ret=0;
#endif
int i;
w=w&BN_MASK2;//w&=BN_MASK2;
for (i=a->top-1; i>=0; i--)
{
#ifndef BN_LLONG
ret=((ret<<BN_BITS4)|((a->d[i]>>BN_BITS4)&BN_MASK2l))%w;
ret=((ret<<BN_BITS4)|(a->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

View File

@ -0,0 +1,320 @@
/*---------------------------------------------------------------------------*
Project: TwlIPL
File:
Copyright 2007 Nintendo. All rights reserved.
These coded instructions, statements, and computer programs contain
proprietary information of Nintendo of America Inc. and/or Nintendo
Company Ltd., and are protected by Federal copyright law. They may
not be disclosed to third parties or copied or duplicated in any form,
in whole or in part, without the prior written consent of Nintendo.
$Date:: $
$Rev$
$Author$
*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
#include <nitro.h>
#include <nitro/fs.h>
#include "acsign.h"
#include "acmemory.h"
/*---------------------------------------------------------------------------*/
unsigned long binarray[ 1024 * 1024 * 2 / sizeof (unsigned long) ];
unsigned long keyarray[ 1024 / sizeof (unsigned long) ];
unsigned long sgnarray[ 1024 / sizeof (unsigned long) ];
unsigned long bufferA[ ACSIGN_BUFFER / sizeof (unsigned long) ];
unsigned long bufferB[ ACSIGN_BUFFER / sizeof (unsigned long) ];
/*--------------------------------------------------------------------------*/
// ROMヘッダ
//----------------------------------------------------------------------
typedef struct {
//
// 0x000 System Reserved
//
char title_name[12]; // Soft title name
u32 game_code; // Game code
u16 maker_code; // Maker code
u8 machine_code; // Machine code
u8 rom_type; // Rom type
u8 rom_size; // Rom size
u8 reserved_A[9]; // System Reserved A ( Set ALL 0 )
u8 soft_version; // Soft version
u8 comp_arm9_boot_area:1; // Compress arm9 boot area
u8 comp_arm7_boot_area:1; // Compress arm7 boot area
u8 inspectCard:1; // 検査カードフラグ
u8 disableClearMemoryPad:1; // IPL2メモリパッドクリア・ディセーブルフラグ
u8 :0;
//
// 0x020 for Static modules (Section:B)
//
// ARM9
u32 main_rom_offset; // ROM offset
void* main_entry_address; // Entry point
void* main_ram_address; // RAM address
u32 main_size; // Module size
// ARM7
u32 sub_rom_offset; // ROM offset
void* sub_entry_address; // Entry point
void* sub_ram_address; // RAM address
u32 sub_size; // Module size
//
// 0x040 for File Name Table[FNT] (Section:C)
//
u32 fnt_offset; // ROM offset
u32 fnt_size; // Table size
//
// 0x048 for File Allocation Table[FAT] (Section:E)
//
u32 fat_offset; // ROM offset
u32 fat_size; // Table size
//
// 0x050 for Overlay Tables[OVT] (Section:D)
//
// ARM9
u32 main_ovt_offset; // ROM offset
u32 main_ovt_size; // Table size
// ARM7
u32 sub_ovt_offset; // ROM offset
u32 sub_ovt_size; // Table size
// 0x060 for ROM control parameter
u8 reserved_A2[32];
// 0x080 - 0x0C0 System Reserved
u8 reserved_B[64]; // System Reserved B (Set 0)
// 0x0C0 for NINTENDO logo data
u8 nintendo_logo[0x9c]; // NINTENDO logo data
u16 nintendo_logo_crc16; // CRC-16
// 0x15E ROM header CRC-16
u16 header_crc16; // ROM header CRC-16
} RomHeader;
/* V-blank callback */
static void VBlankIntr(void)
{
OS_SetIrqCheckFlag(OS_IE_V_BLANK);
}
/*---------------------------------------------------------------------------*
Name: InitializeAllocateSystem
Description:
Arguments: None.
Returns: None.
*---------------------------------------------------------------------------*/
static void InitializeAllocateSystem(void)
{
void* tempLo;
OSHeapHandle hh;
// OS_Initは呼ばれているという前提
tempLo = OS_InitAlloc(
OS_ARENA_MAIN ,
OS_GetMainArenaLo() ,
OS_GetMainArenaHi() ,
1
);
OS_SetArenaLo(
OS_ARENA_MAIN ,
tempLo
);
hh = OS_CreateHeap(
OS_ARENA_MAIN ,
OS_GetMainArenaLo() ,
OS_GetMainArenaHi()
);
if( hh < 0 )
{
OS_Panic("ARM9: Fail to create heap...\n");
}
hh = OS_SetCurrentHeap(
OS_ARENA_MAIN ,
hh
);
}
//
static
void TestAC(char* iplfile, char* srlfile, char* sgnfile, FSFile* pfile )
{
RomHeader* pHeader;
const char* path;
BOOL fresult;
void* srl_ptr = 0;
long srl_len = 0;
void* key_ptr = 0;
long key_len = 0;
void* sgn_ptr = 0;
long sgn_len = 0;
if ( !pfile ) return ;
if ( !iplfile ) return ;
if ( !srlfile ) return ;
if ( !sgnfile ) return ;
path = iplfile;
if ( (fresult = FS_OpenFile(pfile, path)) )
{
key_len = FS_ReadFile( pfile, keyarray, sizeof keyarray );
key_ptr = keyarray;
fresult = FS_CloseFile( pfile );
}
if ( !fresult )
OS_Printf("file read error! %s\n", path );
path = srlfile;
if ( (fresult = FS_OpenFile(pfile, path)) )
{
srl_len = FS_ReadFile( pfile, binarray, sizeof binarray );
srl_ptr = binarray;
fresult = FS_CloseFile( pfile );
}
if ( !fresult )
OS_Printf("file read error! %s\n", path );
path = sgnfile; //"/data/sgn0.bin"; // sgn
if ( (fresult = FS_OpenFile(pfile, path)) )
{
sgn_len = FS_ReadFile( pfile, sgnarray, sizeof sgnarray );
sgn_ptr = sgnarray;
fresult = FS_CloseFile( pfile );
}
if ( !fresult )
OS_Printf("file read error! %s\n", path );
// 認証
if ( srl_ptr && srl_len && key_ptr && key_len && sgn_ptr && sgn_len )
{
long nSerial = 0;
pHeader = (RomHeader*)binarray;
MI_CpuFill8( bufferA, 0, sizeof bufferA );
MI_CpuFill8( bufferB, 0, sizeof bufferB );
#if 0
HMAC/Digtal Signature
>char seg_id[2]; //->"ac"に固定
>u16 version; //-> 1に固定
>u8 auth_code[20]/digital_sign[128]
>long serial_number
>char title_name[12]; // RomHeader.title_name
>u32 game_code; // RomHeader.game_code
>u16 maker_code; // RomHeader.make_code
>u8 machine_code; // RomHeader.machine_code
#endif
((unsigned char*)&nSerial)[0] = ((unsigned char*)sgn_ptr + 4 + 128)[0];
((unsigned char*)&nSerial)[1] = ((unsigned char*)sgn_ptr + 4 + 128)[1];
((unsigned char*)&nSerial)[2] = ((unsigned char*)sgn_ptr + 4 + 128)[2];
((unsigned char*)&nSerial)[3] = ((unsigned char*)sgn_ptr + 4 + 128)[3];
(void)ACSign_Decrypto( bufferA,
(char*)sgn_ptr + 4, // ファイル内の暗号化部分はへのオフセットをプラス
(char*)key_ptr + 16 ); // PC側でMODのみのファイルに対応すれば+16が不要
(void)ACSign_Digest( bufferB,
srl_ptr,
(char*)srl_ptr + pHeader->main_rom_offset,
pHeader->main_size,
(char*)srl_ptr + pHeader->sub_rom_offset,
pHeader->sub_size,
nSerial );
if ( ACSign_Compare( bufferA, bufferB ) )
{
OS_Printf( "Authentication_Code test : success! [%12s %12s] \n", srlfile, sgnfile );
}
else
{
OS_Printf( "Authentication_Code test : failure! [%12s %12s]\n", srlfile, sgnfile );
}
}
else
{
OS_Printf( "no test\n" );
}
OS_PrintServer();
}
void NitroMain(void)
{
FSFile file;
OS_InitPrintServer();
OS_Init();
OS_InitThread();
InitializeAllocateSystem();
OS_SetIrqFunction(OS_IE_V_BLANK, VBlankIntr);
(void)OS_EnableIrqMask(OS_IE_V_BLANK);
(void)OS_EnableIrqMask(OS_IE_FIFO_RECV);
(void)OS_EnableIrq();
if ( sizeof (int ) < sizeof ( long ) )
OS_Printf( "sizeof (int ) != sizeof ( long )\n" );
if ( sizeof ( RomHeader ) != 0x0160 )
OS_Printf( "sizeof ( RomHeader ) != 0x0160\n" );
/* initialize file-system */
FS_Init( (u32)MI_DMA_MAX_NUM ); /* use DMA-3 for FS */
/* always preload FS table for faster directory access. */
{
u32 need_size = FS_GetTableSize();
void *p_table = OS_Alloc(need_size);
SDK_ASSERT(p_table != NULL);
(void)FS_LoadTable(p_table, need_size);
}
// ファイル読み込み
FS_InitFile(&file);
//TestAC( "/data/iplpub.bin", "/data/main.srl", "/data/sgn.bin", &file );
TestAC( "/data/iplpub.bin", "/data/main0.srl", "/data/sgn0.bin", &file );
TestAC( "/data/iplpub.bin", "/data/main1.srl", "/data/sgn1.bin", &file );
TestAC( "/data/iplpub.bin", "/data/main2.srl", "/data/sgn2.bin", &file );
TestAC( "/data/iplpub.bin", "/data/main3.srl", "/data/sgn3.bin", &file );
TestAC( "/data/iplpub.bin", "/data/main4.srl", "/data/sgn4.bin", &file );
TestAC( "/data/iplpub.bin", "/data/main5.srl", "/data/sgn5.bin", &file );
TestAC( "/data/iplpub.bin", "/data/main6.srl", "/data/sgn6.bin", &file );
TestAC( "/data/iplpub.bin", "/data/main7.srl", "/data/sgn7.bin", &file );
TestAC( "/data/iplpub.bin", "/data/main0.srl", "/data/sgn7.bin", &file );
TestAC( "/data/iplpub.bin", "/data/main3.srl", "/data/sgn1.bin", &file );
TestAC( "/data/iplpub.bin", "/data/main5.srl", "/data/sgn5.bin", &file );
TestAC( "/data/iplpub.bin", "/data/main1.srl", "/data/sgn0.bin", &file );
TestAC( "/data/iplpub.bin", "/data/main0.srl", "/data/sgn1.bin", &file );
TestAC( "/data/iplpub.bin", "/data/main0.srl", "/data/sgn0.bin", &file );
OS_Terminate();
}

View File

@ -0,0 +1,412 @@
/*---------------------------------------------------------------------------*
Project: TwlIPL
File:
Copyright 2007 Nintendo. All rights reserved.
These coded instructions, statements, and computer programs contain
proprietary information of Nintendo of America Inc. and/or Nintendo
Company Ltd., and are protected by Federal copyright law. They may
not be disclosed to third parties or copied or duplicated in any form,
in whole or in part, without the prior written consent of Nintendo.
$Date:: $
$Rev$
$Author$
*---------------------------------------------------------------------------*/
/* MD5C.C - RSA Data Security, Inc., MD5 message-digest algorithm
*/
/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
rights reserved.
License to copy and use this software is granted provided that it
is identified as the "RSA Data Security, Inc. MD5 Message-Digest
Algorithm" in all material mentioning or referencing this software
or this function.
License is also granted to make and use derivative works provided
that such works are identified as "derived from the RSA Data
Security, Inc. MD5 Message-Digest Algorithm" in all material
mentioning or referencing the derived work.
RSA Data Security, Inc. makes no representations concerning either
the merchantability of this software or the suitability of this
software for any particular purpose. It is provided "as is"
without express or implied warranty of any kind.
These notices must be retained in any copies of any part of this
documentation and/or software.
*/
#include "md5.h"
/* Constants for MD5Transform routine. */
#define S11 7
#define S12 12
#define S13 17
#define S14 22
#define S21 5
#define S22 9
#define S23 14
#define S24 20
#define S31 4
#define S32 11
#define S33 16
#define S34 23
#define S41 6
#define S42 10
#define S43 15
#define S44 21
static void MD5Transform(unsigned long [4], unsigned char [64]);
static void Encode(unsigned char *, unsigned long *, unsigned int);
static void Decode(unsigned long *, unsigned char *, unsigned int);
static void MD5_memcpy(unsigned char*, unsigned char*, unsigned int);
static void MD5_memset(unsigned char*, int, unsigned int);
static unsigned char PADDING[64] = {
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
/* F, G, H and I are basic MD5 functions.
*/
#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
#define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
#define H(x, y, z) ((x) ^ (y) ^ (z))
#define I(x, y, z) ((y) ^ ((x) | (~z)))
/* ROTATE_LEFT rotates x left n bits.
*/
#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
/* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
Rotation is separate from addition to prevent recomputation.
*/
#define FF(a, b, c, d, x, s, ac) { \
(a) += F ((b), (c), (d)) + (x) + (unsigned long)(ac); \
(a) = ROTATE_LEFT ((a), (s)); \
(a) += (b); \
}
#define GG(a, b, c, d, x, s, ac) { \
(a) += G ((b), (c), (d)) + (x) + (unsigned long)(ac); \
(a) = ROTATE_LEFT ((a), (s)); \
(a) += (b); \
}
#define HH(a, b, c, d, x, s, ac) { \
(a) += H ((b), (c), (d)) + (x) + (unsigned long)(ac); \
(a) = ROTATE_LEFT ((a), (s)); \
(a) += (b); \
}
#define II(a, b, c, d, x, s, ac) { \
(a) += I ((b), (c), (d)) + (x) + (unsigned long)(ac); \
(a) = ROTATE_LEFT ((a), (s)); \
(a) += (b); \
}
/* MD5 initialization. Begins an MD5 operation, writing a new context.
*/
void MD5Init(context)
MD5_CTX *context; /* context */
{
context->count[0] = context->count[1] = 0;
/* Load magic initialization constants. */
context->state[0] = 0x67452301;
context->state[1] = 0xefcdab89;
context->state[2] = 0x98badcfe;
context->state[3] = 0x10325476;
}
/* MD5 block update operation. Continues an MD5 message-digest
operation, processing another message block, and updating the
context.
*/
void MD5Update(context, input, inputLen)
MD5_CTX *context; /* context */
unsigned char *input; /* input block */
unsigned int inputLen; /* length of input block */
{
unsigned int i, index, partLen;
/* Compute number of bytes mod 64 */
index = (unsigned int)((context->count[0] >> 3) & 0x3F);
/* Update number of bits */
if ((context->count[0] += ((unsigned long)inputLen << 3)) < ((unsigned long)inputLen << 3))
context->count[1]++;
context->count[1] += ((unsigned long)inputLen >> 29);
partLen = 64 - index;
/* Transform as many times as possible. */
if (inputLen >= partLen) {
MD5_memcpy((unsigned char*)&context->buffer[index], (unsigned char*)input, partLen);
MD5Transform (context->state, context->buffer);
for (i = partLen; i + 63 < inputLen; i += 64)
MD5Transform (context->state, &input[i]);
index = 0;
}
else
i = 0;
/* Buffer remaining input */
MD5_memcpy((unsigned char*)&context->buffer[index], (unsigned char*)&input[i], inputLen-i);
}
/* MD5 finalization. Ends an MD5 message-digest operation, writing the
the message digest and zeroizing the context.
*/
void MD5Final(digest, context)
unsigned char digest[16]; /* message digest */
MD5_CTX *context; /* context */
{
unsigned char bits[8];
unsigned int index, padLen;
/* Save number of bits */
Encode (bits, context->count, 8);
/* Pad out to 56 mod 64. */
index = (unsigned int)((context->count[0] >> 3) & 0x3f);
padLen = (index < 56) ? (56 - index) : (120 - index);
MD5Update (context, PADDING, padLen);
/* Append length (before padding) */
MD5Update (context, bits, 8);
/* Store state in digest */
Encode (digest, context->state, 16);
/* Zeroize sensitive information. */
MD5_memset ((unsigned char*)context, 0, sizeof (*context));
}
/* MD5 basic transformation. Transforms state based on block.
*/
static void MD5Transform (state, block)
unsigned long state[4];
unsigned char block[64];
{
unsigned long a = state[0], b = state[1], c = state[2], d = state[3], x[16];
Decode (x, block, 64);
/* Round 1 */
FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */
FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */
FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */
FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */
FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */
FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */
FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */
FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */
FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */
FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */
FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
/* Round 2 */
GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */
GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */
GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */
GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */
GG (d, a, b, c, x[10], S22, 0x2441453); /* 22 */
GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */
GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */
GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */
GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */
GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */
GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */
GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */
/* Round 3 */
HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */
HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */
HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */
HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */
HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */
HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */
HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */
HH (b, c, d, a, x[ 6], S34, 0x4881d05); /* 44 */
HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */
HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */
/* Round 4 */
II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */
II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */
II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */
II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */
II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */
II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */
II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */
II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */
II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */
II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */
state[0] += a;
state[1] += b;
state[2] += c;
state[3] += d;
/* Zeroize sensitive information. */
MD5_memset ((unsigned char*)x, 0, sizeof (x));
}
/* Encodes input (unsigned long) into output (unsigned char). Assumes len is
a multiple of 4.
*/
static void Encode(output, input, len)
unsigned char *output;
unsigned long *input;
unsigned int len;
{
unsigned int i, j;
for (i = 0, j = 0; j < len; i++, j += 4) {
output[j ] = (unsigned char)( input[i] & 0xff);
output[j+1] = (unsigned char)((input[i] >> 8) & 0xff);
output[j+2] = (unsigned char)((input[i] >> 16) & 0xff);
output[j+3] = (unsigned char)((input[i] >> 24) & 0xff);
}
}
/* Decodes input (unsigned char) into output (unsigned long). Assumes len is
a multiple of 4.
*/
static void Decode(output, input, len)
unsigned long *output;
unsigned char *input;
unsigned int len;
{
unsigned int i, j;
for (i = 0, j = 0; j < len; i++, j += 4)
output[i] = ((unsigned long)input[j]) | (((unsigned long)input[j+1]) << 8) |
(((unsigned long)input[j+2]) << 16) | (((unsigned long)input[j+3]) << 24);
}
/* Note: Replace "for loop" with standard memcpy if possible.
*/
static void MD5_memcpy(output, input, len)
unsigned char* output;
unsigned char* input;
unsigned int len;
{
unsigned int i;
for (i = 0; i < len; i++)
output[i] = input[i];
}
/* Note: Replace "for loop" with standard memset if possible.
*/
static void MD5_memset(output, value, len)
unsigned char* output;
int value;
unsigned int len;
{
unsigned int i;
for (i = 0; i < len; i++)
((char *)output)[i] = (char)value;
}
//////////////////////////////////////////////////////////////////////////////
#if defined( MD5_TEST )
#include <string.h>
char* samplearray[ 7 ] =
{
"",
"a",
"abc",
"message digest",
"abcdefghijklmnopqrstuvwxyz",
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
"1234567890" // x8
};
char* resultarray[ 7 ] =
{
"\xD4\x1D\x8C\xD9\x8F\x00\xB2\x04\xE9\x80\x09\x98\xEC\xF8\x42\x7E",
"\x0C\xC1\x75\xB9\xC0\xF1\xB6\xA8\x31\xC3\x99\xE2\x69\x77\x26\x61",
"\x90\x01\x50\x98\x3C\xD2\x4F\xB0\xD6\x96\x3F\x7D\x28\xE1\x7F\x72",
"\xF9\x6B\x69\x7D\x7C\xB7\x93\x8D\x52\x5A\x2F\x31\xAA\xF1\x61\xD0",
"\xC3\xFC\xD3\xD7\x61\x92\xE4\x00\x7D\xFB\x49\x6C\xCA\x67\xE1\x3B",
"\xD1\x74\xAB\x98\xD2\x77\xD9\xF5\xA5\x61\x1C\x2C\x9F\x41\x9D\x9F",
"\x57\xED\xF4\xA2\x2B\xE3\xC9\x55\xAC\x49\xDA\x2E\x21\x07\xB6\x7A"
};
int repeatarray[ 7 ] =
{
1,
1,
1,
1,
1,
1,
8
};
int MD5Test( )
{
MD5_CTX context;
unsigned char digest[16];
int i, j, error;
error = 0;
for ( j = 0; j < 7; j++ )
{
MD5Init(&context);
for ( i = 0; i < repeatarray[j]; i++ )
{
MD5Update (&context,
(unsigned char*)samplearray[j],
(unsigned int)strlen( samplearray[j]) );
}
MD5Final(digest, &context);
error = memcmp( digest, resultarray[j], 16 );
if ( error )
break;
}
return error ? 0 : 1;
}
#endif // MD5_TEST
//////////////////////////////////////////////////////////////////////////////

View File

@ -0,0 +1,470 @@
/*---------------------------------------------------------------------------*
Project: TwlIPL
File:
Copyright 2007 Nintendo. All rights reserved.
These coded instructions, statements, and computer programs contain
proprietary information of Nintendo of America Inc. and/or Nintendo
Company Ltd., and are protected by Federal copyright law. They may
not be disclosed to third parties or copied or duplicated in any form,
in whole or in part, without the prior written consent of Nintendo.
$Date:: $
$Rev$
$Author$
*---------------------------------------------------------------------------*/
/*
* 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 <stdint.h> (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
//////////////////////////////////////////////////////////////////////////////

View File

@ -0,0 +1,786 @@
/*---------------------------------------------------------------------------*
Project: TwlIPL
File:
Copyright 2007 Nintendo. All rights reserved.
These coded instructions, statements, and computer programs contain
proprietary information of Nintendo of America Inc. and/or Nintendo
Company Ltd., and are protected by Federal copyright law. They may
not be disclosed to third parties or copied or duplicated in any form,
in whole or in part, without the prior written consent of Nintendo.
$Date:: $
$Rev$
$Author$
*---------------------------------------------------------------------------*/
/*
* 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 (; i<SHA_LBLOCK; i++)
p[i]=0;
c->sha_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 (; sw<SHA_LBLOCK; sw++)
{
M_c2nl(data,l);
p[sw]=l;
}
len-=(SHA_CBLOCK-c->num);
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 (; i<SHA_LBLOCK; i++)
p[i]=0;
c->sha_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 */

View File

@ -0,0 +1,31 @@
#! make -f
#----------------------------------------------------------------------------
# Project: TwlIPL
# File: Makefile
#
# Copyright 2007 Nintendo. All rights reserved.
#
# These coded instructions, statements, and computer programs contain
# proprietary information of Nintendo of America Inc. and/or Nintendo
# Company Ltd., and are protected by Federal copyright law. They may
# not be disclosed to third parties or copied or duplicated in any form,
# in whole or in part, without the prior written consent of Nintendo.
#
# $Date:: 2007-09-27#$
# $Rev: 1203 $
# $Author: yada $
#----------------------------------------------------------------------------
SUBDIRS = ARM9
TARGET_FIRM = SYSTEMMENU
include $(TWLIPL_ROOT)/build/buildtools/commondefs
#----------------------------------------------------------------------------
do-build: $(TARGETS)
include $(TWLIPL_ROOT)/build/buildtools/modulerules
#===== End of Makefile =====

View File

@ -0,0 +1,53 @@
#! make -f
#----------------------------------------------------------------------------
# Project: TwlIPL
# File: Makefile
#
# Copyright 2007 Nintendo. All rights reserved.
#
# These coded instructions, statements, and computer programs contain
# proprietary information of Nintendo of America Inc. and/or Nintendo
# Company Ltd., and are protected by Federal copyright law. They may
# not be disclosed to third parties or copied or duplicated in any form,
# in whole or in part, without the prior written consent of Nintendo.
#
# $Date:: 2007-09-27#$
# $Rev: 1203 $
# $Author: yada $
#----------------------------------------------------------------------------
SUBDIRS =
#----------------------------------------------------------------------------
TARGET_FIRM = SYSTEMMENU
TARGET_PLATFORM = TWL
TWL_ARCHGEN = LIMITED
TWL_PROC = ARM7
#----------------------------------------------------------------------------
SRCDIR = ../common/src
INCDIR = ../common/include \
$(TWLSDK_ROOT)/build/libraries/mb/common/include
SRCS = mb_loader.c
TARGET_LIB = libmbloader_sp$(TWL_LIBSUFFIX).a
include $(TWLIPL_ROOT)/build/buildtools/commondefs
INSTALL_TARGETS = $(TARGETS)
INSTALL_DIR = $(SYSMENU_INSTALL_LIBDIR)
#----------------------------------------------------------------------------
do-build: $(TARGETS)
include $(TWLIPL_ROOT)/build/buildtools/modulerules
#===== End of Makefile =====

Some files were not shown because too many files have changed in this diff Show More