From 40e0ed1237d5791ec57675bf16fedd082a87920c Mon Sep 17 00:00:00 2001 From: miya Date: Wed, 7 Oct 2009 01:27:25 +0000 Subject: [PATCH] =?UTF-8?q?OpenSSL=E3=83=A9=E3=82=A4=E3=83=96=E3=83=A9?= =?UTF-8?q?=E3=83=AA=E3=81=8C=E3=81=AA=E3=81=84=E3=81=A8=E3=82=B3=E3=83=B3?= =?UTF-8?q?=E3=83=91=E3=82=A4=E3=83=AB=E3=81=A7=E3=81=8D=E3=81=AA=E3=81=84?= =?UTF-8?q?=E3=81=91=E3=81=A9=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: file:///Users/lillianskinner/Downloads/platinum/twl/TwlToolsRED@404 7061adef-622a-194b-ae81-725974e89856 --- build/tools/sctools/makesdtd/LICENSE_en.txt | 127 +++ build/tools/sctools/makesdtd/LICENSE_jp.txt | 37 + build/tools/sctools/makesdtd/Makefile | 48 + build/tools/sctools/makesdtd/makesdtd.c | 933 +++++++++++++++++++ build/tools/sctools/makesdtd/my_sign.c | 437 +++++++++ build/tools/sctools/makesdtd/my_sign.h | 14 + build/tools/sctools/makesdtd/my_sign_local.h | 40 + 7 files changed, 1636 insertions(+) create mode 100644 build/tools/sctools/makesdtd/LICENSE_en.txt create mode 100644 build/tools/sctools/makesdtd/LICENSE_jp.txt create mode 100644 build/tools/sctools/makesdtd/Makefile create mode 100644 build/tools/sctools/makesdtd/makesdtd.c create mode 100644 build/tools/sctools/makesdtd/my_sign.c create mode 100644 build/tools/sctools/makesdtd/my_sign.h create mode 100644 build/tools/sctools/makesdtd/my_sign_local.h diff --git a/build/tools/sctools/makesdtd/LICENSE_en.txt b/build/tools/sctools/makesdtd/LICENSE_en.txt new file mode 100644 index 0000000..728fe8c --- /dev/null +++ b/build/tools/sctools/makesdtd/LICENSE_en.txt @@ -0,0 +1,127 @@ + + LICENSE ISSUES + ============== + + The OpenSSL toolkit stays under a dual license, i.e. both the conditions of + the OpenSSL License and the original SSLeay license apply to the toolkit. + See below for the actual license texts. Actually both licenses are BSD-style + Open Source licenses. In case of any license issues related to OpenSSL + please contact openssl-core@openssl.org. + + OpenSSL License + --------------- + +/* ==================================================================== + * Copyright (c) 1998-2008 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + + Original SSLeay License + ----------------------- + +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + diff --git a/build/tools/sctools/makesdtd/LICENSE_jp.txt b/build/tools/sctools/makesdtd/LICENSE_jp.txt new file mode 100644 index 0000000..341e934 --- /dev/null +++ b/build/tools/sctools/makesdtd/LICENSE_jp.txt @@ -0,0 +1,37 @@ +OpenSSL ライセンス +Copyright (c) 1998-2001 The OpenSSL Project. All rights reserved. + +ソースおよびバイナリー形式での再配布および使用は、変更の有無に拘らず、次の条件を満たす場合に許可されます。 + +ソース・コードを再配布する場合には、上記の著作権表示、この使用条件および以下の免責表示を含める必要があります。 +バイナリー形式で再配布する場合には、上記の著作権表示、以下の使用条件および免責表示を、配布に際して提供する関連文書および資料に記載する必要があります。 +このソフトウェアの機能または使用について言及するすべての広告用材料では、次の謝辞を表示する必要があります。「この製品には、OpenSSL Toolkit で使用するために OpenSSL Project によって開発されたソフトウェアが組み込まれています。 (http://www.openssl.org/)」 +事前の書面による許可がなければ、「OpenSSL Toolkit」と「OpenSSL Project」の名前を、このソフトウェアから派生した製品の承認または促進に使用してはなりません。書面による許可が必要な場合は、openssl-core@openssl.org に連絡してください。 +OpenSSL Project の事前の書面による許可がなければ、このソフトウェアから派生した製品を「OpenSSL」と呼ぶことはできませんし、また、それらの製品の名前に「OpenSSL」が含まれていてはなりません。 +いかなる形の再配布にも、次の謝辞を表示する必要があります。「この製品には、OpenSSL Toolkit で使用するために OpenSSL Project によって開発されたソフトウェアが含まれています。(http://www.openssl.org/)」 +OpenSSL Project は、このソフトウェアを特定物として現存するままの状態で提供し、法律上の瑕疵担保責任、商品性の保証および特定目的適合性の保証を含むすべての明示もしくは黙示の保証責任を負いません。 起こりうる損害について予見の有無を問わず、「ソフトウェア」を使用したために生じる、直接的、間接的、付帯的、特別、懲罰的、または結果的損害 (代替の製品またはサービスの調達、データまたは利益の喪失、事業の中断などを含み、他のいかなる場合も含む) については、それが契約、厳格な責任、不法行為 (過失の場合もそうでない場合も含む) など、いかなる責任の理論においても、OpenSSL Project およびその寄稿者はその責任を負いません。 + +この製品には、Eric Young (eay@cryptsoft.com) により作成された暗号化ソフトウェアが含まれています。この製品には、Tim Hudson (tjh@cryptsoft.com) により作成されたソフトウェアが含まれています。 + + + +SSLeay ライセンス + +Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) All rights reserved. + +このパッケージは、Eric Young (eay@cryptsoft.com) により作成された SSL インプリメンテーションです。このインプリメンテーションは、Netscape SSL に準拠するように作成されています。 + +このライブラリーは、以下の条件に従う限り、無料での商業および非商業の使用が許可されます。以下の条件は、単に SSL コードだけでなく、この配布に含まれるすべてのコードに適用されます。この場合、そのコードが RC4、RSA、lhash、DES、などにいずれであっても構いません。この配布に含まれる SSL 資料は、著作権所有者が Tim Hudson (tjh@cryptsoft.com) である点を除き、同一著作権によってカバーされます。 + +著作権は Eric Young が所有していますので、コードの著作権表示を除去してはなりません。このパッケージをいずれかの製品に使用する場合は、使用するライブラリー部分の作成者として Eric Young を特定する必要があります。これは、プログラム始動時に、またはこのパッケージと一緒に提供される資料 (オンラインまたはテキスト) にテキスト形式のメッセージとして含めることができます。 + +ソースおよびバイナリー形式での再配布および使用は、変更の有無に拘らず、次の条件を満たす場合に許可されます。 + +ソース・コードを再配布する場合には、この著作権表示、この使用条件および以下の免責表示を含める必要があります。 +バイナリー形式で再配布する場合には、上記の著作権表示、以下の使用条件および免責表示を、配布に際して提供する関連文書および資料に記載する必要があります。 +このソフトウェアの機能と使用に言及するすべての広告用材料では、次のような謝辞を表示する必要があります。「この製品には、Eric Young 氏 (eay@cryptsoft.com) によって作成された暗号ソフトウェアが含まれています」。使用するライブラリーからのルーチンが暗号に関係ない場合は、「暗号」という語を省略することができます。 +apps ディレクトリー (アプリケーション・コード) からの Windows 固有のコード (またはその派生物) を組み込む場合は、次の謝辞を表示する必要があります。「この製品には、Tim Hudson 氏 (tjh@cryptsoft.com) によって作成されたソフトウェアが含まれています。」 +Eric Young は、このソフトウェアを特定物として現存するままの状態で提供し、法律上の瑕疵担保責任、商品性の保証および特定目的適合性の保証を含むすべての明示もしくは黙示の保証責任を負いません。 起こりうる損害について予見の有無を問わず、「ソフトウェア」を使用したために生じる、直接的、間接的、付帯的、特別、懲罰的、または結果的損害 (代替の製品またはサービスの調達、データまたは利益の喪失、事業の中断などを含み、他のいかなる場合も含む) については、それが契約、厳格な責任、不法行為 (過失の場合もそうでない場合も含む) など、いかなる責任の理論においても、作成者および寄稿者はその責任を負いません。 + +このコードのすべての公開済みバージョンまたは派生物のライセンスおよび配布条件は、変更できません。すなわち、このコードは、単にコピーすることも、他の配布ライセンス (GNU Public Licence も含む) に含めることもできません。 + diff --git a/build/tools/sctools/makesdtd/Makefile b/build/tools/sctools/makesdtd/Makefile new file mode 100644 index 0000000..00bc0d1 --- /dev/null +++ b/build/tools/sctools/makesdtd/Makefile @@ -0,0 +1,48 @@ + +OPENSSL_DIR = c:/OpenSSL/openssl-1.0.0-beta2 + + +PACKAGE = makesdtd + +SRCS = makesdtd.c my_sign.c + +HEADS = my_sign.h + + +OBJS = $(SRCS:.c=.o) + +CC := C:/Cygwin/bin/gcc + + +CFLAGS = -mno-cygwin -Wall + + +CPPFLAGS= -I. -I$(OPENSSL_DIR)/include -I$(OPENSSL_DIR)/crypto/ec + +LD = gcc +LDFLAGS = -Wl,--subsystem,console -mwindows -mno-cygwin -L$(OPENSSL_DIR) +LDLIBS = -lcrypto -lssl + +RM = rm.exe -f + +.SUFFIXES: +.SUFFIXES: .o .c + +all: install + +install: $(PACKAGE) + install -c -m 777 $(PACKAGE) ../bin + +$(PACKAGE): $(OBJS) + $(LD) $(LDFLAGS) $(OBJS) -o $@ $(LDLIBS) + +$(OBJS): $(HEADS) Makefile + +.c.o: + $(CC) $(CFLAGS) $(CPPFLAGS) -c $< -o $@ + + +.PHONY: clean clobber +clean clobber: + $(RM) $(OBJS) $(PACKAGE).exe + diff --git a/build/tools/sctools/makesdtd/makesdtd.c b/build/tools/sctools/makesdtd/makesdtd.c new file mode 100644 index 0000000..8e971fc --- /dev/null +++ b/build/tools/sctools/makesdtd/makesdtd.c @@ -0,0 +1,933 @@ +/* + [ROM用] make_sdtad_table.exe -dir test-tad -odir [dir] -var MAKEROM_TAD_ROMFILES -fdir tads -mk Makefile.inc + [SD用] make_sdtad_table.exe -sd -dir test-tad -odir [dir] -fdir sdtads + + table_file.txt 名前固定 + + makesdtd.exe -indir [inputdir] -odir sdtads + makesdtd.exe -indir test-tad -odir sdtads + +*/ + + +/* + #include + char *getcwd(char *buf, size_t size); + char *getwd(char *buf); + char *get_current_dir_name(void); +*/ + + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "my_sign.h" + +typedef unsigned char u8; +typedef unsigned short u16; +typedef unsigned long u32; +typedef unsigned long long u64; +typedef int BOOL; + +#ifndef TRUE +#define TRUE 1 +#endif + +#ifndef FALSE +#define FALSE 0 +#endif + + +/* グローバルデータ */ + +#define MAX_TITLE_IDS 2048 +static int num_of_title_ids = 0; +static u32 title_id_hi_array[MAX_TITLE_IDS]; +static u32 title_id_lo_array[MAX_TITLE_IDS]; +static u16 title_ver_array[MAX_TITLE_IDS]; +static u16 title_gid_array[MAX_TITLE_IDS]; +static char title_rom_file_full_path[MAX_TITLE_IDS][256]; +static char key_file_path[256]; + + +/* tadのデータは基本的にビッグエンディアン */ + +typedef struct { + u32 hdrSize; + u16 tadType; + u16 tadVersion; + u32 certSize; + u32 crlSize; + u32 ticketSize; + u32 tmdSize; + u32 contentSize; + u32 metaSize; + + u32 certOffset; + u32 crlOffset; + u32 ticketOffset; + u32 tmdOffset; + u32 contentOffset; + u32 metaOffset; + u32 fileSize; +} TAD_INFO; + +typedef struct NAMiTADHeader +{ + u32 hdrSize; // Size of TADHeader1 96 + u8 tadType[2]; + u16 tadVersion; // TAD_VERSION_1 + u32 certSize; + u32 crlSize; + u32 ticketSize; + u32 tmdSize; + u32 contentSize; + u32 metaSize; +} NAMiTADHeader; + +typedef u64 OSTitleId; +typedef OSTitleId NAMTitleId; + +typedef struct NAMTitleInfo +{ + NAMTitleId titleId; + u16 companyCode; + u16 version; + u32 publicSaveSize; + u32 privateSaveSize; + u32 blockSize; +} NAMTitleInfo; + +typedef struct NAMTadInfo +{ + NAMTitleInfo titleInfo; + u32 fileSize; +} NAMTadInfo; + + +#define ES_APP_ENC_HANDLE 6 + +#define ES_ROOT_NAME "Root" +#define ES_CA_PREFIX "CA" +#define ES_XS_PREFIX "XS" +#define ES_MS_PREFIX "MS" +#define ES_CP_PREFIX "CP" +#define ES_APP_CERT_PREFIX "AP" + +#define ES_BUF_SIZE 256 + +typedef u32 ESId; /* 32-bit device identity */ +typedef u32 ESContentId; /* 32-bit content identity */ +typedef u64 ESTitleId; /* 64-bit title identity */ +typedef u64 ESTicketId; /* 64-bit ticket id */ +typedef u8 ESVersion; /* 8-bit data structure version */ +typedef u16 ESTitleVersion; /* 16-bit title version */ +typedef ESTitleId ESSysVersion; /* 64-bit system software version */ +typedef u32 ESTitleType; /* title type */ +typedef u16 ESContentType; /* content type */ +typedef u8 ESTmdReserved[62]; /* reserved field in TMD structure */ +typedef u8 ESTicketReserved[47]; /* reserved field in eTicket structure */ +typedef u8 ESSysAccessMask[2]; /* 16 bit cidx Mask to indicate which + + content can be accessed by sys app */ +#if !defined(__ES_INTERNAL__) +/* IOSC types */ +typedef u8 IOSCAesKey[16]; +typedef u8 IOSCHash[20]; +typedef u8 IOSCName[64]; +typedef u8 IOSCSigDummy[60]; +typedef u8 IOSCCertPad[52]; +typedef u8 IOSCEccCertPad[4]; +typedef u8 IOSCRsaSig2048[256]; +typedef enum { + IOSC_SIG_RSA4096 = 0x00010000, /* RSA 4096 bit signature */ + IOSC_SIG_RSA2048, /* RSA 2048 bit signature */ + IOSC_SIG_ECC /* ECC signature 512 bits*/ +} IOSCCertSigType; +typedef enum { + IOSC_PUBKEY_RSA4096, /* RSA 4096 bit key */ + IOSC_PUBKEY_RSA2048, /* RSA 2048 bit key */ + IOSC_PUBKEY_ECC /* ECC pub key 512 bits*/ +} IOSCCertPubKeyType; +typedef u8 IOSCEccSig[60]; +typedef u8 IOSCEccPublicKey[60]; + +typedef struct { + IOSCCertSigType sigType; + IOSCRsaSig2048 sig; + IOSCSigDummy dummy; + IOSCName issuer; +} IOSCSigRsa2048; + +typedef u8 IOSCEccPrivatePad[2]; +typedef u8 IOSCEccPublicPad[4]; +typedef struct { + IOSCCertSigType sigType; + IOSCEccSig sig; + IOSCEccPublicPad eccPad; + IOSCSigDummy dummy; + IOSCName issuer; +} IOSCSigEcc; + +typedef u8 IOSCDeviceId[64]; +typedef u8 IOSCServerId[64]; +typedef struct { + IOSCCertPubKeyType pubKeyType; + union { + IOSCServerId serverId; + IOSCDeviceId deviceId; + } name; + u32 date; +} IOSCCertHeader; +typedef struct { + IOSCSigEcc sig; /* ECC signature struct */ + IOSCCertHeader head; + IOSCEccPublicKey pubKey; /* 60 byte ECC public key */ + IOSCEccPublicPad eccPad; + IOSCCertPad pad; + IOSCEccCertPad pad2; +} IOSCEccEccCert; +#endif + +#define ES_TMD_VERSION 0 +#define ES_TICKET_VERSION 0 + +/* TMD View */ +#define ES_MAX_CONTENT 512 + +#define ES_TITLE_TYPE_NC_TITLE 0 /* NC title */ +#define ES_TITLE_TYPE_NG_TITLE 1 /* NG title */ +#define ES_TITLE_TYPE_DS_TITLE 2 /* DS title for NC */ +#define ES_TITLE_TYPE_STREAM 4 /* stream title */ +#define ES_TITLE_TYPE_DATA 8 /* data title */ +#define ES_CONTENT_TYPE_SHARED (1<<15) /* shared content */ +#define ES_CONTENT_TYPE_OPTIONAL (1<<14) /* optional content */ +#define ES_CONTENT_TYPE_DISC (1<< 1) /* disc content */ +#define ES_CONTENT_TYPE_NC_EXE 0 /* NC merged elf */ +#define ES_CONTENT_TYPE_NG_EXE 1 /* NG content */ + +#define ES_LICENSE_MASK 0x0f /* allow 16 licensing types */ +#define ES_LICENSE_PERMANENT 0x00 /* e.g., regular game with permanent rights */ +#define ES_LICENSE_DEMO 0x01 /* e.g., demo game with permanent rights */ +#define ES_LICENSE_TRIAL 0x02 /* e.g., regular game with limited rights */ +#define ES_LICENSE_RENTAL 0x03 /* TBD */ +#define ES_LICENSE_SUBSCRIPTION 0x04 /* TBD */ +#define ES_LICENSE_GIFT_MASK 0x80 /* this is a gift */ + +/* TMD */ +typedef struct { + ESContentId cid; /* 32 bit content id */ + u16 index; /* content index, unique per title */ + ESContentType type; /* content type*/ + u64 size; /* unencrypted content size in bytes */ + IOSCHash hash; /* 160-bit SHA1 hash of the content */ +} ESContentMeta; + +typedef struct { + ESVersion version; /* TMD version number */ + ESVersion caCrlVersion; /* CA CRL version number */ + ESVersion signerCrlVersion; /* signer CRL version number */ + ESSysVersion sysVersion; /* required system software version number */ + + ESTitleId titleId; /* 64 bit title id */ + ESTitleType type; /* 32 bit title type */ + u16 groupId; + ESTmdReserved reserved; /* 62 bytes reserved info for Nintendo */ + u32 accessRights; /* title's access rights to use + system resources */ + ESTitleVersion titleVersion; /* 16 bit title version */ + u16 numContents; /* number of contents per title */ + u16 bootIndex; /* boot content index */ +} ESTitleMetaHeader; + +typedef struct { + IOSCSigRsa2048 sig; /* RSA 2048bit sign of all the data in + the TMD file */ + ESTitleMetaHeader head; + ESContentMeta contents[ES_MAX_CONTENT]; +} ESTitleMeta; + +/* TMD View */ +typedef struct { + ESVersion version; /* TMD data structure version */ + ESSysVersion sysVersion; /* required system software + version number */ + ESTitleId titleId; /* 64 bit title id */ + ESTitleType type; /* 32 bit title type */ + u16 groupId; + ESTmdReserved reserved; /* 62 bytes reserved info */ + ESTitleVersion titleVersion; /* 16 bit title version */ + u16 numContents; /* number of contents in the title */ +} ESTmdViewHeader; + +typedef struct { + ESContentId cid; /* 32 bit content id */ + u16 index; /* 16 bit content index */ + ESContentType type; /* 16 bit content type */ + u64 size; /* 64 bit content size */ +} ESCmdView; + +typedef struct { + ESTmdViewHeader head; + ESCmdView contents[ES_MAX_CONTENT]; +} ESTmdView; + + + +typedef struct NAMiTadParams +{ + u32 cert; + u32 crl; + u32 ticket; + u32 tmd; + u32 content; + u32 meta; +} +NAMiTadParams; + +//---- tad 構成情報 +typedef struct NAMiTadInfo +{ + NAMiTadParams sizes; // 各領域のサイズ + NAMiTadParams offsets; // ファイル先頭から各領域へのオフセット +} +NAMiTadInfo; + +#if 0 +static my_NAM_ReadTadInfoWithFile(FILE *fp, TAD_INFO *tad_info) +{ + NAMiTadInfo tadInfo; + ESTitleMeta tmd; + int result; + + result = my_sign_ReadTadHeader(fp, &tadInfo); + + // TMD を読む + fread(&tmd, tmd-size, fp); + result = NAMi_Load_sign( fp, (void*)tmd, tadInfo.sizes.tmd, + tadInfo.offsets.tmd, + + + NAMi_CopyTmdReservedInfo(&pInfo->titleInfo, &pTmd->head.reserved); + pInfo->titleInfo.titleId = NAMi_EndianU64(pTmd->head.titleId); + pInfo->titleInfo.companyCode = NAMi_EndianU16(pTmd->head.groupId); + pInfo->titleInfo.version = NAMi_EndianU16(pTmd->head.titleVersion); + pInfo->titleInfo.blockSize = my_NAMi_CalcTitleBlocksFromTmd(pTmd); + pInfo->fileSize = my_sign_FS_GetLength(pTadFile); + + NAMi_Free(pTmd); + +} +#endif + +#if 0 +static void test(void) +{ + NAMiTadInfo* pInfo; + // ESTitleMeta tmd; +#if 0 + typedef struct { + ESVersion version; /* TMD version number */ + ESVersion caCrlVersion; /* CA CRL version number */ + ESVersion signerCrlVersion; /* signer CRL version number */ + ESSysVersion sysVersion; /* required system software version number */ + + ESTitleId titleId; // 8 + ESTitleType type; // 4 + u16 groupId; // 2 + ESTmdReserved reserved; /* 62 bytes reserved info for Nintendo */ + u32 accessRights; /* title's access rights to use + system resources */ + ESTitleVersion titleVersion; /* 16 bit title version */ + u16 numContents; /* number of contents per title */ + u16 bootIndex; /* boot content index */ + } ESTitleMetaHeader; +#endif + + printf("TMD head offset = %d 0x%04x\n", offsetof(ESTitleMeta, head), offsetof(ESTitleMeta, head)); + printf("ESTitleMetaHeader titleId offset = %d 0x%04x\n", offsetof(ESTitleMetaHeader ,titleId ), offsetof(ESTitleMetaHeader ,titleId)); + + printf("ESTitleMetaHeader titleVersion offset = %d 0x%04x\n", offsetof(ESTitleMetaHeader ,titleVersion ), offsetof(ESTitleMetaHeader ,titleVersion)); + + + printf("ESTitleMetaHeader groupId offset = %d 0x%04x\n", offsetof(ESTitleMetaHeader ,groupId ), offsetof(ESTitleMetaHeader ,groupId)); + + printf("ESTitleMetaHeader numContents offset = %d 0x%04x\n", offsetof(ESTitleMetaHeader ,numContents ), offsetof(ESTitleMetaHeader ,numContents)); + + + + printf("NAMiTADHeader = %d 0x%04x\n",sizeof(NAMiTADHeader),sizeof(NAMiTADHeader)); + printf("ESTmdView = %d 0x%04x\n",sizeof(ESTmdView),sizeof(ESTmdView)); + printf("ESTmdViewHeader = %d 0x%04x\n",sizeof(ESTmdViewHeader),sizeof(ESTmdViewHeader)); + printf("ESCmdView = %d 0x%04x\n",sizeof(ESCmdView),sizeof(ESCmdView)); +#if 0 + + printf(" = %d 0x%04x\n",sizeof(),sizeof()); + printf(" = %d 0x%04x\n",sizeof(),sizeof()); + printf(" = %d 0x%04x\n",sizeof(),sizeof()); + printf(" = %d 0x%04x\n",sizeof(),sizeof()); + printf(" = %d 0x%04x\n",sizeof(),sizeof()); +#endif + +} +#endif + + + + + + + + + + + +static BOOL debug_print_flag = FALSE; + + +static u32 reverseEndian4( const u32 v ) +{ + u32 ret = (v<<24) | ((v<<8) & 0x00FF0000) | ((v>>8) & 0x0000FF00) | (v>>24); + return ret; +} + +static u16 reverseEndian2( const u16 v ) +{ + u16 ret = (v<<8) | (v>>8); + return ret; +} + +static u32 roundUp4( const u32 v, const u32 align ) +{ + u32 r = ((v + align - 1) / align) * align; + return r; +} + +#if 0 +/* unused */ +static u16 roundUp2( const u16 v, const u16 align ) +{ + u16 r = ((v + align - 1) / align) * align; + return r; +} +#endif + +static u16 read2bytes(FILE *fp) +{ + u16 buf; + if( 2 != fread(&buf,1,2,fp) ) { + fprintf(stderr, "Error: %s %s %d\n",__FILE__,__FUNCTION__,__LINE__); + exit(-1); + } + return buf; +} + +static u32 read4bytes(FILE *fp) +{ + u32 buf; + if( 4 != fread(&buf,1,4,fp) ) { + fprintf(stderr, "Error: %s %s %d\n",__FILE__,__FUNCTION__,__LINE__); + exit(-1); + } + return buf; +} + + +static BOOL read_tad_info(FILE *fp, TAD_INFO *tad_info) +{ + + tad_info->hdrSize = reverseEndian4( read4bytes(fp) ); // 基本的にビッグエンディアン + tad_info->tadType = reverseEndian2( read2bytes(fp) ); + tad_info->tadVersion = reverseEndian2( read2bytes(fp) ); + tad_info->certSize = reverseEndian4( read4bytes(fp) ); + tad_info->crlSize = reverseEndian4( read4bytes(fp) ); + tad_info->ticketSize = reverseEndian4( read4bytes(fp) ); + tad_info->tmdSize = reverseEndian4( read4bytes(fp) ); + tad_info->contentSize = reverseEndian4( read4bytes(fp) ); + tad_info->metaSize = reverseEndian4( read4bytes(fp) ); + + if( tad_info->hdrSize != 32) { + return FALSE; + } + + if( debug_print_flag ) { + printf( "hdrSize %d\n", (int)tad_info->hdrSize ); + printf( "tadType %c%c\n", tad_info->tadType>>8, tad_info->tadType&0xFF ); + printf( "tadVersion %d\n", (int)tad_info->tadVersion ); + printf( "certSize %d\n", (int)tad_info->certSize ); + printf( "crlSize %d\n", (int)tad_info->crlSize ); + printf( "ticketSize %d\n", (int)tad_info->ticketSize ); + printf( "tmdSize %d\n", (int)tad_info->tmdSize ); + printf( "contentSize %d\n", (int)tad_info->contentSize ); + printf( "metaSize %d\n", (int)tad_info->metaSize ); + } + + + tad_info->certOffset = roundUp4( tad_info->hdrSize , 64 ); + tad_info->crlOffset = roundUp4( tad_info->certOffset + tad_info->certSize , 64 ); + tad_info->ticketOffset = roundUp4( tad_info->crlOffset + tad_info->crlSize , 64 ); + tad_info->tmdOffset = roundUp4( tad_info->ticketOffset + tad_info->ticketSize , 64 ); + tad_info->contentOffset = roundUp4( tad_info->tmdOffset + tad_info->tmdSize , 64 ); + tad_info->metaOffset = roundUp4( tad_info->contentOffset+ tad_info->contentSize , 64 ); + tad_info->fileSize = roundUp4( tad_info->metaOffset + tad_info->metaSize , 64 ); + + return TRUE; +} + + +static u8 *alloc_and_read(FILE *fp, int offset, int size) +{ + u8 *buf; + if( fp == NULL || size < 1 ) { + fprintf(stderr, "Error %s open file\n",__FUNCTION__); + return NULL; + } + + buf = malloc(size); + if( buf == NULL ) { + fprintf(stderr, "Error %s memory allocate \n",__FUNCTION__); + return NULL; + } + + if( -1 == fseek( fp, offset, SEEK_SET ) ) { + fprintf(stderr, "Error: %s %s %d fseek offset=%d\n",__FILE__,__FUNCTION__,__LINE__,offset); + return NULL; + } + if( size != fread(buf,1,size,fp) ) { + fprintf(stderr, "Error: %s %s %d fread size=%d\n",__FILE__,__FUNCTION__,__LINE__,size); + return NULL; + } + return buf; +} + +#if 0 +/* unused */ +static BOOL saveFile(char *name, char *buf, int size) +{ + FILE *fp; + fp = fopen(name, "wb"); + if( fp == NULL ) { + fprintf(stderr, "Error %s %d file open\n",__FUNCTION__,__LINE__); + return FALSE; + } + if( fwrite(buf, 1, size, fp) != size ) { + fprintf(stderr, "Error %s %d file write\n",__FUNCTION__,__LINE__); + return FALSE; + } + fclose( fp ); + return TRUE; +} +#endif + +#if 0 +static void print_gamecode(u32 tid_lo) +{ + char gamecode[5]; + + char *str; + str = gamecode; + *str++ = (char)((tid_lo >> 24) & 0xff); + *str++ = (char)((tid_lo >> 16) & 0xff); + *str++ = (char)((tid_lo >> 8) & 0xff); + *str++ = (char)(tid_lo & 0xff); + *str = '\0'; + printf( "%s", gamecode ); +} +#endif + + +#if 0 +static write_tad_table_form(FILE *fp, u32 tid_hi, u32 tid_lo, char *filename) +{ + fprintf(fp, "0x%08x%08x, %d , %d , rom:/tads/%s\n",tid_hi, tid_lo, 0 , 0 , filename); +} +#endif + +static BOOL read_file_and_print_titleid( char *path , char *d_name, FILE *fp_out, FILE *fp_mk) +{ + FILE *fp_in = NULL; + TAD_INFO tad_info; + u8 *tmd = NULL; + u32 titleid_hi = 0; + u32 titleid_lo = 0; + u16 t_ver; + u16 gid; + int i; + BOOL ret_flag = TRUE; + + + fp_in = fopen(path,"rb"); /* fseek効かすため */ + if( fp_in == NULL ) { + fprintf(stderr, "error: file open %s\n",path); + ret_flag = FALSE; + goto end_file; + } + + /* TADファイルかどうかチェック */ + if( FALSE == read_tad_info(fp_in, &tad_info) ) { + // fprintf(stderr, "error:%s %d\n",__FUNCTION__,__LINE__); + ret_flag = FALSE; + goto end_file; + } + + + fseek( fp_in, 0, SEEK_END ); + if( tad_info.fileSize != ftell( fp_in ) ) { + printf( "file size is not expected size(=%d)", (int)tad_info.fileSize ); + ret_flag = FALSE; + goto end_file; + } + + tmd = alloc_and_read( fp_in, tad_info.tmdOffset, tad_info.tmdSize ); + + + titleid_hi = reverseEndian4( *((u32 *)( tmd + 0x18C )) ); + titleid_lo = reverseEndian4( *((u32 *)( tmd + 0x18C + 4 )) ); + + t_ver = reverseEndian2( *((u16 *)( tmd + 0x1DC )) ); + gid = reverseEndian2( *((u16 *)( tmd + 0x198)) ); +#if 0 + printf("0x%08x%08x ver=0x%04x gid=0x%04x\n",titleid_hi, titleid_lo, + t_ver,groupId); +#endif + + if( debug_print_flag ) { + printf("inputfile = %s\n", path); + } + + + /* ここでタイトルIDの重複チェックする */ + for( i = 0 ; i < num_of_title_ids ; i++ ) { + if( (title_id_hi_array[i] == titleid_hi) && (title_id_lo_array[i] == titleid_lo) ) { + if( title_ver_array[i] == t_ver ) { + /* バージョンも含めて重複してる! */ + fprintf(stderr, "Error: title exists redundantly\n"); + } + else { + /* バージョン違いだけど重複してる */ + fprintf(stderr, "Warning: title exists in different versions\n"); + } + + fprintf(stderr, " 0x%08x%08x, 0x%04x , 0x%04x %s\n", + (int)title_id_hi_array[i], (int)title_id_lo_array[i], + title_ver_array[i], title_gid_array[i], title_rom_file_full_path[i] ); + fprintf(stderr, " 0x%08x%08x, 0x%04x , 0x%04x %s\n", (int)titleid_hi, (int)titleid_lo, t_ver , gid , path); + } + } + + + title_id_hi_array[ num_of_title_ids ] = titleid_hi; + title_id_lo_array[ num_of_title_ids ] = titleid_lo; + title_ver_array[ num_of_title_ids ] = t_ver; + title_gid_array[ num_of_title_ids ] = gid; + strcpy( title_rom_file_full_path[num_of_title_ids], path); + + num_of_title_ids++; + + if( fp_out ) { + fprintf(fp_out, "0x%08x%08x, 0x%04x , 0x%04x , sdmc:/%s,\n", + (int)titleid_hi, (int)titleid_lo, t_ver , gid , d_name); + if( fp_mk ) { + fprintf(fp_mk, "\t\t%s \\\n", d_name); + } + } + else { + printf("0x%08x%08x, 0x%04x , 0x%04x , sdmc:/%s,\n", + (int)titleid_hi, (int)titleid_lo, t_ver , gid , d_name); + } + + end_file: + if(tmd) { + free(tmd); + } + + if( fp_in ) { + fclose(fp_in); + } + + return ret_flag; +} + +int main(int argc, char **argv) +{ + int i; + FILE *fp_in = NULL; + FILE *fp_out = NULL; + FILE *fp_mk = NULL; + char *infile = NULL; + char *outfile = NULL; + + char *outdir_name = NULL; + char *indir_name = NULL; + + BOOL read_file_flag = FALSE; + BOOL write_file_flag = FALSE; + BOOL write_dir_flag = FALSE; + BOOL dir_read_flag = FALSE; + + char *prog; + int badops = 0; + u8 *ticket = NULL; + u8 *tmd = NULL; + u8 *content = NULL; + // u64 titleid = 0; +#if 0 + TAD_INFO tad_info; + u32 titleid_hi = 0; + u32 titleid_lo = 0; + u16 groupid = 0; +#endif + DIR *indir; + DIR *outdir; + struct dirent *dr; + struct stat st; + char *full_path; + char rom_file_full_path[256]; + BOOL func_ret_flag; + char out_file_full_path[256]; + char table_file_full_path[256]; + char en_table_file_full_path[256]; + int len; + int pos; + + + prog=argv[0]; + argc--; + argv++; + + + // printf("d = %s\n", prog); + + + strcpy(key_file_path, ".\\"); + strcat(key_file_path, prog); + + len = strlen(key_file_path); + for( pos = len - 1 ; pos > 0 ; pos--) { + if( key_file_path[pos] == '\\' ) { + strcpy( &(key_file_path[pos]), "\\tad1024.der"); + break; + } + } + + + printf("key_file_path = %s\n",key_file_path ); + + + while (argc >= 1) { + if (strcmp(*argv,"-indir") == 0 && !dir_read_flag ) { + if (--argc < 1) { + goto bad; + } + indir_name = *++argv; + dir_read_flag = TRUE; + } + else if (strcmp(*argv,"-odir") == 0 && !write_dir_flag ) { + if (--argc < 1) { + goto bad; + } + outdir_name = *++argv; + write_dir_flag = TRUE; + } + else if (strcmp(*argv,"-d") == 0 ) { + debug_print_flag = TRUE; + } + else if ( !read_file_flag ) { + infile = *argv; + read_file_flag = TRUE; + } + else { + goto bad; + } + argc--; + argv++; + } + + + + if (badops) { + bad: + fprintf(stderr, "%s -indir dirname -odir dirname\n",prog); + goto end; + } + + + if( debug_print_flag ) { + printf("dir name = %s\n", indir_name); + } + indir = opendir(indir_name); + if( indir == NULL ) { + fprintf(stderr, "error: dir open %s\n",indir_name); + goto end; + } + + + if( write_dir_flag ) { + outdir = opendir(outdir_name); + if( outdir == NULL ) { + // fprintf(stderr, "error: dir open %s\n",indir_name); + /* + EACCES + アクセス権限がない。 + EBADF + fd が読み出し用にオープンされた、有効なファイルディスクリプタではない。 + EMFILE + プロセスが使用中のファイルディスクリプタが多すぎる。 + ENFILE + システムでオープンされているファイルが多すぎる。 + ENOENT + ディレクトリが存在しないか、または name が空文字列である。 + ENOMEM + 命令を実行するのに充分なメモリがない。 + ENOTDIR + name はディレクトリではない。 + */ + if( -1 == mkdir(outdir_name) ) { + fprintf(stderr, "error: mkdir %s\n",indir_name); + goto end; + } + + } + else { + closedir(outdir); + } + + + + strcpy(table_file_full_path, outdir_name); + strcat(table_file_full_path, "/table_file.txt"); + outfile = table_file_full_path; + + strcpy(en_table_file_full_path, outdir_name); + strcat(en_table_file_full_path, "/en_sdtad_table.txt"); + + fp_out = fopen(outfile,"wb"); /* fseek効かすため */ + if( fp_out == NULL ) { + fprintf(stderr, "error: file open %s\n",outfile); + goto end; + } + write_file_flag = TRUE; + } + + + + if( 0 != cryptopc_init( key_file_path ) ) { + fprintf(stderr, "error: cryptopc\n"); + goto end; + } + + + /* チェック用のテーブル初期化(いらんけど) */ + num_of_title_ids = 0; + for( i = 0 ; i < MAX_TITLE_IDS ; i++ ) { + title_id_hi_array[i] = 0; + title_id_lo_array[i] = 0; + title_ver_array[i] = 0; + title_gid_array[i] = 0; + title_rom_file_full_path[i][0] = 0; + } + + /* ディレクトリ中のTADファイルをリストにして表示する。 */ + while( (dr = readdir(indir)) != NULL ) { + if (!strcmp(dr->d_name, ".") || !strcmp(dr->d_name, "..")) { + continue; + } + + full_path = malloc( strlen(indir_name) + strlen(dr->d_name) + 2); + strcpy(full_path, indir_name); + strcat(full_path, "/"); + strcat(full_path, dr->d_name); + + // printf("%s\n", full_path); + if ( stat(full_path, &st) != 0 ) { + free( full_path); + continue; + } + + if (S_ISDIR(st.st_mode) == 1) { + if( debug_print_flag ) { + printf("DIR %s\n", dr->d_name); + } + } + else { + if( debug_print_flag ) { + printf("FILE %s\n", dr->d_name); + } + if( st.st_size >= 32 ) { + // strcpy( rom_file_full_path, file_dir); + // strcat( rom_file_full_path, "/"); + // strcat( rom_file_full_path, "en_"); + strcpy( rom_file_full_path, "sdtads/en_"); + strcat( rom_file_full_path, dr->d_name); + func_ret_flag = read_file_and_print_titleid( full_path ,rom_file_full_path, fp_out , fp_mk ); + + if( func_ret_flag == TRUE ) { + strcpy(out_file_full_path, outdir_name); + strcat(out_file_full_path, "/en_"); + strcat(out_file_full_path, dr->d_name); + // printf("cryptopc tad1024.der %s %s\n",full_path, out_file_full_path); + putchar('.'); + (void)cryptopc(full_path, out_file_full_path); + /* + tadファイルだったのでテーブルファイルに登録された。 + なので暗号化をついでにする。 + */ + } + } + } + free( full_path); + } + putchar('\n'); + + if( indir ) { + (void)closedir( indir ); + } + + if( write_file_flag ) { + if( fp_out ) { + fclose(fp_out); + fp_out = NULL; + } + /* table_file.txt も暗号化する */ + (void)cryptopc(table_file_full_path, en_table_file_full_path); + // char en_table_file_full_path[256]; + } + + end: + + if( ticket ) { + free(ticket); + } + if(tmd) { + free(tmd); + } + if(content) { + free(content); + } + if( fp_in ) { + fclose(fp_in); + } + if( fp_out ) { + fclose(fp_out); + } + + if( fp_mk ) { + fclose(fp_mk); + } + + cryptopc_end(); + + + return 0; +} + + + + + diff --git a/build/tools/sctools/makesdtd/my_sign.c b/build/tools/sctools/makesdtd/my_sign.c new file mode 100644 index 0000000..4c63e41 --- /dev/null +++ b/build/tools/sctools/makesdtd/my_sign.c @@ -0,0 +1,437 @@ +/* cryptopc *.der infile outfile + cryptopc miya1024.der main.c main.enc +*/ + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include + +typedef signed char s8; +typedef unsigned char u8; +typedef unsigned short u16; +typedef unsigned long u32; +typedef unsigned long long u64; + + + +#include "my_sign.h" +#include "my_sign_local.h" +/* + データのハッシュの単位は32KB + + ・ヘッダー + ・ヘッダーの署名(ハッシュは32バイトだがRSAが128バイトなんで128バイト) + ・ + + オリジナルのファイルサイズ / 32KB -> ハッシュの数。 + num_of_block = org_file_size / 32KB; + if( org_file_size % 32KB ) { + num_of_block += 1 + } + + L2ハッシュサイズ * num_of_block -> L2ハッシュブロックサイズ + L2_hash_block_size = 32B * num_of_block; + + +*/ + + +/* + flen must be less than RSA_size(rsa) - 11 for the PKCS #1 v1.5 based + padding modes, and less than RSA_size(rsa) - 41 for + RSA_PKCS1_OAEP_PADDING. The random number generator must be seeded + prior to calling RSA_public_encrypt(). + */ + + +/* + FILE format: + ----- + MY_SIGN_HEADER header; + MY_SIGN_SIGNATURE header_sign; + L2_sign[0]; + L2_sign[1]; + L2_sign[2]; + L2_sign[ ]; + . + . + enc_data_block[0](32KB) + enc_data_block[1](32KB) + enc_data_block[2](32KB) + . + . + */ + +static FILE *fp_key = NULL; +static int rsaSize = 0; +static RSA *rsa_key = NULL; + +static u8 my_sign_aes_key[AES_KEY_BYTE_LEN] = { + 0x02,0xB6,0x01,0xD8,0x01,0x80,0x01,0x77,0xB4,0x01,0xCB,0x01,0xBD,0x5F,0x18,0x0F, + 0xF6,0x39,0x9C,0xC6,0x90,0xAC,0xC1,0x0D,0x03,0x74,0x6E,0x8D,0xD1,0xBA,0x37,0x46 +}; + +static u8 my_sign_aes_iv[AES_BLOCK_SIZE] = { + 0xC3,0x85,0x93,0xFE,0xA8,0x2D,0xBF,0xFB,0xED,0x42,0xE0,0x42,0xFD,0x17,0x04,0xB0 +}; + + +static int my_sign_make(MY_SIGN_SIGNATURE *encrypted_sign, u8 *buf, int buf_size) +{ + MY_SIGN_SIGNATURE temp_sign; + int outlen = 0; + // int i; + if( encrypted_sign == NULL ) { + return -1; + } + if( buf == NULL ) { + return -1; + } + if( buf_size < 1 ) { + return -1; + } + if( rsa_key == NULL ) { + return -1; + } + if( rsaSize < 1 ) { + return -1; + } + + memset((u8 *)&temp_sign, 0 , sizeof(MY_SIGN_SIGNATURE)); + memset((u8 *)encrypted_sign, 0 , sizeof(MY_SIGN_SIGNATURE)); + + // printf( "%s buf_size = %d\n",__FUNCTION__, buf_size); + SHA256(buf, buf_size, temp_sign.hash); +#if 0 + for( i = 0 ; i < 32 ; i++ ) { + printf("hash[0x%02x]=0x%02x\n",i,temp_sign.hash[i]); + } +#endif + temp_sign.pad[0] = 1; + temp_sign.pad[1] = 1; + temp_sign.pad[2] = 1; + temp_sign.pad[3] = 1; + + //RSA_PKCS1_OAEP_PADDING + //RSA_NO_PADDING +#if 0 +#define RSA_PKCS1_PADDING 1 +#define RSA_SSLV23_PADDING 2 +#define RSA_NO_PADDING 3 +#define RSA_PKCS1_OAEP_PADDING 4 +#define RSA_X931_PADDING 5 + +#define RSA_PKCS1_PADDING_SIZE 11 +#endif + + if(rsaSize != (outlen = RSA_private_encrypt(rsaSize - RSA_PKCS1_PADDING_SIZE, + (u8 *)&temp_sign, (u8 *)encrypted_sign, + rsa_key, RSA_PKCS1_PADDING ))) { + + fprintf(stderr,"encrypt error rsaSize=%d outlen=%d\n",rsaSize, outlen); + return -1; + } + + return 0; +} + +int cryptopc_init(char *key_file) +{ + ERR_load_crypto_strings(); + + // printf("hash offset = %d\n",offsetof(MY_SIGN_SIGNATURE, hash)); + if( (fp_key = fopen( key_file, "rb" )) == NULL ) { + fprintf(stderr, "failed to fopen %s\n",key_file); + return -1; + } + + rsa_key = RSA_new(); + + if( rsa_key == NULL ) { + fprintf(stdout,"Error:RSA_new(key alloc) NULL!\n"); + return -1; + } + d2i_RSAPrivateKey_fp(fp_key, &rsa_key); + // d2i_RSAPublicKey_fp(fp_key, &key); + + if( rsa_key != NULL ) { + // RSA_print_fp(stdout, key, 0); + rsaSize = RSA_size( rsa_key ); + // printf("rsaSize = %d bit\n",rsaSize * 8); + } + else { + RSA_free(rsa_key); + rsa_key = NULL; + fprintf(stderr, "Error:d2i_RSAPrivateKey_fp(read key) NULL!\n"); + return -1; + } + return 0; +} + +void cryptopc_end(void) +{ + if( fp_key ) { + fclose(fp_key); + } + if( rsa_key ) { + RSA_free(rsa_key); + } +} + +int cryptopc(char *input_file, char *output_file) +{ + FILE *fp_in = NULL; + FILE *fp_out = NULL; + + struct stat st_buf; + int readlen; + int outlen = 0; + int rsa_error_flag = 0; + int i; + MY_SIGN_HEADER header; + MY_SIGN_SIGNATURE header_sign; + MY_SIGN_SIGNATURE *L2_sign_table; + MY_SIGN_SIGNATURE *L2_sign_table_temp; + int L2_sign_table_size; + int block_no; + u8 block_buf_in[MY_SIGN_BLOCK_SIZE]; + u8 block_buf_out[MY_SIGN_BLOCK_SIZE]; + + u8 aes_key_buf[AES_KEY_BYTE_LEN]; + AES_KEY aes_key; + unsigned char aes_iv[ AES_BLOCK_SIZE ]; + + + if( 0 != stat( input_file, &st_buf) ) { + fprintf(stderr, "failed to stat %s\n", input_file); + rsa_error_flag = 1; + goto end; + } + + + if( (fp_in = fopen( input_file, "rb" )) == NULL ) { + fprintf(stderr, "Error:failed to fopen input file(%s)\n", input_file); + rsa_error_flag = 1; + goto end; + } + + if( (fp_out = fopen( output_file, "wb+" )) == NULL ) { + fprintf(stderr, "failed to fopen output file(%s)\n",output_file); + rsa_error_flag = 1; + goto end; + } + + /* + FILE format: + ----- + MY_SIGN_HEADER header; + MY_SIGN_SIGNATURE header_sign; + L2_sign_table[0]; + L2_sign_table[1]; + L2_sign_table[2]; + L2_sign_table[ ]; + . + . + aes_enc_data_block[0](32KB) + aes_enc_data_block[1](32KB) + aes_enc_data_block[2](32KB) + . + . + . + . + + + #define RSA_SIZE 128 + #define HASH_SIZE 0x20 + #define BLOCK_SIZE (32*1024) + + typedef struct { + u8 hash[HASH_SIZE]; + u8 dummy[RSA_SIZE - HASH_SIZE]; + } SIGNATURE; + + typedef struct { + u32 magic_code; + u32 org_file_size; + u32 num_of_block; + u32 file_offset_L2_sign_table; + u32 file_offset_data_block; + SIGNATURE L2_sign; + } HEADER; + + */ + + memset(&header, 0 , sizeof(MY_SIGN_HEADER)); + header.magic_code = 0xdeadbeef; + header.org_file_size = st_buf.st_size; + header.num_of_block = st_buf.st_size / MY_SIGN_BLOCK_SIZE; + if( st_buf.st_size % MY_SIGN_BLOCK_SIZE ) { + header.num_of_block += 1; + } + + header.file_offset_L2_sign_table = sizeof(MY_SIGN_HEADER) + sizeof(MY_SIGN_SIGNATURE); + + L2_sign_table_size = sizeof(MY_SIGN_SIGNATURE) * header.num_of_block; + + header.file_offset_data_block = header.file_offset_L2_sign_table + L2_sign_table_size; + + + // printf("header.org_file_size = %d\n",(int)header.org_file_size); + // printf("header.num_of_block = %d\n",(int)header.num_of_block); + + + L2_sign_table = (MY_SIGN_SIGNATURE *)malloc( L2_sign_table_size ); + if( L2_sign_table == NULL ) { + fprintf(stderr,"L2_sign_table malloc error %s %d\n",__FUNCTION__,__LINE__); + rsa_error_flag = 1; + goto end; + } + memset(L2_sign_table, 0 , L2_sign_table_size ); + L2_sign_table_temp = L2_sign_table; + + + + if( 0 != fseek(fp_out, header.file_offset_data_block , SEEK_SET) ) { + fprintf(stderr,"fseek error %s %d\n",__FUNCTION__,__LINE__); + rsa_error_flag = 1; + goto end; + } + + block_no = 0; + + while( (readlen = fread(block_buf_in, 1, MY_SIGN_BLOCK_SIZE, fp_in)) > 0 ) { + + if( readlen < MY_SIGN_BLOCK_SIZE ) { + for( i = readlen ; i < MY_SIGN_BLOCK_SIZE ; i++ ) { + block_buf_in[i] = 0; /* padding.. */ + } + } + + + /* AESキーのセット */ + for( i = 0 ; i < AES_KEY_BYTE_LEN ; i++ ) { + aes_key_buf[i] = my_sign_aes_key[i]; + } + for( i = 0 ; i < AES_BLOCK_SIZE ; i++ ) { + aes_iv[i] = my_sign_aes_iv[i]; + } + + AES_set_encrypt_key(aes_key_buf, AES_KEY_BIT_LEN, &aes_key); + + memset(block_buf_out, 0 , MY_SIGN_BLOCK_SIZE); + for( i = 0 ; i < (MY_SIGN_BLOCK_SIZE / AES_BLOCK_SIZE) ; i++ ) { + // AES_encrypt( &(block_buf_in[AES_BLOCK_SIZE*i]), &(block_buf_out[AES_BLOCK_SIZE*i]),&aes_key); + AES_cbc_encrypt( &(block_buf_in[AES_BLOCK_SIZE*i]), &(block_buf_out[AES_BLOCK_SIZE*i]), + AES_BLOCK_SIZE, &aes_key, aes_iv, AES_ENCRYPT ); + + } + + if( MY_SIGN_BLOCK_SIZE != (outlen = fwrite( block_buf_out, 1, MY_SIGN_BLOCK_SIZE, fp_out)) ) { + fprintf(stderr,"Error:fwrite line=%d outlen=%d\n", __LINE__,outlen); + fprintf(stderr,"%s\n", ERR_error_string(ERR_get_error(), NULL)); + rsa_error_flag = 1; + goto end; + } + + /* データブロックの署名計算 */ + if( 0 != my_sign_make( L2_sign_table_temp , block_buf_out, MY_SIGN_BLOCK_SIZE ) ) { + fprintf(stderr,"make Data Block signature error line=%d\n",__LINE__); + rsa_error_flag = 1; + goto end; + } + + + + L2_sign_table_temp++; + block_no++; + } + + //miya printf("last block no = %d\n",block_no); + + + /* L2signテーブルの署名計算 */ + if( 0 != my_sign_make(&header.L2_sign, (u8 *)L2_sign_table, L2_sign_table_size ) ) { + fprintf(stderr,"make L2_sign signature error line=%d\n",__LINE__); + rsa_error_flag = 1; + goto end; + } + + + /* ヘッダーの署名計算 */ + if( 0 != my_sign_make(&header_sign, (u8 *)&header, sizeof(MY_SIGN_HEADER)) ) { + fprintf(stderr,"make signature error line=%d\n",__LINE__); + rsa_error_flag = 1; + goto end; + } + + + + + /* ヘッダーを出力ファイルに書き込み */ + if( 0 != fseek(fp_out, 0 , SEEK_SET) ) { + fprintf(stderr,"fseek error %s %d\n",__FUNCTION__,__LINE__); + goto end; + } + + if( sizeof(MY_SIGN_HEADER) != (outlen = fwrite( &header, 1, sizeof(MY_SIGN_HEADER), fp_out)) ) { + fprintf(stderr, "Error:fwrite line=%d outlen=%d\n", __LINE__,outlen); + rsa_error_flag = 1; + goto end; + } + + + /* ヘッダーの署名を出力ファイルに書き込み */ + + if( sizeof(MY_SIGN_SIGNATURE) != (outlen = fwrite( &header_sign, 1, sizeof(MY_SIGN_SIGNATURE), fp_out)) ) { + fprintf(stderr, "Error:fwrite line=%d outlen=%d\n", __LINE__,outlen); + rsa_error_flag = 1; + goto end; + } + + /* L2_signテーブルを出力ファイルに書き込み */ + if( L2_sign_table_size != (outlen = fwrite( (u8 *)L2_sign_table, 1, L2_sign_table_size, fp_out)) ) { + fprintf(stderr, "Error:fwrite line=%d outlen=%d\n", __LINE__,outlen); + rsa_error_flag = 1; + goto end; + } + + + if( rsa_error_flag == 1 ) { + printf("Error: %s %s %d\n",__FILE__,__FUNCTION__,__LINE__); + } + + end: + + if( L2_sign_table != NULL ) { + free( L2_sign_table ); + } + + if( fp_in ) { + fclose(fp_in); + } + + if( fp_out ) { + fclose(fp_out); + } + + if( rsa_error_flag == 0 ) { + //printf("success\n"); + return 0; + + } + return -1; /* error */ +} + + + diff --git a/build/tools/sctools/makesdtd/my_sign.h b/build/tools/sctools/makesdtd/my_sign.h new file mode 100644 index 0000000..85451f2 --- /dev/null +++ b/build/tools/sctools/makesdtd/my_sign.h @@ -0,0 +1,14 @@ +#ifndef _MY_SIGN_H_ +#define _MY_SIGN_H_ + + +int cryptopc(char *input_file, char *output_file); +void cryptopc_end(void); +int cryptopc_init(char *key_file); + + +#ifdef __cplusplus +} +#endif + +#endif /* _MY_SIGN_H_ */ diff --git a/build/tools/sctools/makesdtd/my_sign_local.h b/build/tools/sctools/makesdtd/my_sign_local.h new file mode 100644 index 0000000..bed0802 --- /dev/null +++ b/build/tools/sctools/makesdtd/my_sign_local.h @@ -0,0 +1,40 @@ +#ifndef _MY_SIGN_LOCAL_H_ +#define _MY_SIGN_LOCAL_H_ + + +// #define MY_RSA_SIGN_HASH_SIZE 32 +// #define MY_RSA_SIGN_RSA_SIZE 128 +#define MY_SIGN_RSA_SIZE 128 +#define MY_SIGN_HASH_SIZE 0x20 +#define MY_SIGN_BLOCK_SIZE (32*1024) + + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct { + u8 pad[16]; + u8 hash[MY_SIGN_HASH_SIZE]; + u8 dummy[MY_SIGN_RSA_SIZE - MY_SIGN_HASH_SIZE - 16]; +} MY_SIGN_SIGNATURE; + +typedef struct { + u32 magic_code; + u32 org_file_size; + u32 num_of_block; + u32 file_offset_L2_sign_table; + u32 file_offset_data_block; + u32 dummy[3]; + MY_SIGN_SIGNATURE L2_sign; +} MY_SIGN_HEADER; + +#define AES_KEY_BIT_LEN 256 +#define AES_KEY_BYTE_LEN (AES_KEY_BIT_LEN/8) + + +#ifdef __cplusplus +} +#endif + +#endif /* _MY_SIGN_LOCAL_H_ */