git-svn-id: file:///Users/lillianskinner/Downloads/platinum/twl/TwlToolsRED@385 7061adef-622a-194b-ae81-725974e89856

This commit is contained in:
miya 2009-07-27 00:14:28 +00:00
parent bc25bec6f4
commit b720f43691
28 changed files with 4743 additions and 362 deletions

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,44 @@
#ifndef _MY_AES_H_
#define _MY_AES_H_
#ifdef __cplusplus
extern "C" {
#endif
#define AES_ENCRYPT 1
#define AES_DECRYPT 0
/* Because array size can't be a const in C, the following two are macros.
Both sizes are in bytes. */
#define AES_MAXNR 14
#define AES_BLOCK_SIZE 16
typedef struct {
unsigned long rd_key[4 *(AES_MAXNR + 1)];
int rounds;
} AES_KEY;
int AES_set_encrypt_key(const unsigned char *userKey, const int bits,
AES_KEY *key);
int AES_set_decrypt_key(const unsigned char *userKey, const int bits,
AES_KEY *key);
void AES_encrypt(const unsigned char *in, unsigned char *out,
const AES_KEY *key);
void AES_decrypt(const unsigned char *in, unsigned char *out,
const AES_KEY *key);
void AES_cbc_encrypt(const unsigned char *in, unsigned char *out,
size_t length, const AES_KEY *key,
unsigned char *ivec, const int enc);
#ifdef __cplusplus
}
#endif
#endif /* _MY_AES_H_ */

View File

@ -2822,7 +2822,9 @@ BOOL CleanSDCardFiles(char *log_file_name)
}
else if( STD_StrCmp(direntry.longname, "nup_log.txt") == 0 ) {
}
else if( STD_StrCmp(direntry.longname, "tads") == 0 ) {
else if( STD_StrCmp(direntry.longname, "sdtads") == 0 ) {
}
else if( STD_StrCmp(direntry.longname, "sdtaddevs") == 0 ) {
}
else if( direntry.attributes & FS_ATTRIBUTE_DOS_VOLUME ) {
}

View File

@ -21,6 +21,7 @@ extern "C" {
typedef struct {
u64 tid;
int is_personalized;
int version;
BOOL install_success_flag;
} MY_USER_APP_TID;

View File

@ -0,0 +1,618 @@
#include <twl.h>
#include <nitro/os.h>
#include <nitro/crypto.h>
#include <nitro/std.h>
#include <string.h>
#define MY_RSA_SIGN_DEBUG 1
#ifdef MY_RSA_SIGN_DEBUG
#include "text.h"
#include "mprintf.h"
#endif /* MY_RSA_SIGN_DEBUG */
#include "my_rsa_sign.h"
static const unsigned char rsa512_sec[]={
0x30,0x82,0x02,0x5c,0x02,0x01,0x00,0x02,0x81,0x81,0x00,0xeb,0x72,0xe2,0x05,0x45,
0x37,0xd9,0x78,0x35,0xb5,0x8d,0x70,0x9a,0xe7,0x17,0x42,0xe9,0xf3,0x26,0x73,0x4e,
0xdf,0x5e,0x96,0x5f,0xcf,0xf2,0xf1,0x2d,0xc0,0x41,0x31,0xb6,0x3b,0xe8,0xa4,0xd7,
0x70,0xdb,0x3c,0xfd,0x66,0x0d,0xea,0x2f,0xb8,0x7b,0xf0,0x2d,0x70,0xe0,0xf1,0x05,
0x55,0xe6,0x33,0x8f,0x3a,0xde,0x79,0xce,0xd0,0x11,0xbf,0xda,0x78,0xe1,0xef,0x8b,
0x0e,0x2e,0xa7,0xe2,0x61,0x88,0x58,0x90,0x1d,0x0c,0x6d,0x5b,0x40,0xbf,0x6f,0xc7,
0x18,0xde,0xe8,0xfd,0xd9,0xd9,0x1e,0xb9,0xe4,0xa3,0x4d,0x04,0x39,0x4b,0x8f,0x5b,
0x13,0xad,0x14,0x0b,0xf8,0x53,0xbc,0xae,0x72,0x91,0x6b,0xcd,0xf9,0x39,0x8d,0x17,
0x3d,0xc8,0xee,0xc9,0xcc,0x95,0x35,0x38,0xb0,0x80,0x53,0x02,0x03,0x01,0x00,0x01,
0x02,0x81,0x80,0x52,0x5d,0x37,0xef,0xfc,0x0c,0xd3,0x88,0x97,0xd1,0x51,0x0f,0x49,
0x40,0xfa,0x04,0x30,0x6f,0x1c,0xce,0x4d,0x93,0x1a,0x35,0xa4,0x82,0xcc,0x4b,0xce,
0x63,0x68,0xeb,0x09,0x02,0xe0,0x19,0x7a,0x3c,0x42,0x95,0x8d,0x57,0x7c,0x1a,0xa6,
0x62,0xf5,0x08,0x49,0xfd,0x28,0xd3,0x67,0xb8,0x6a,0xf5,0x32,0x6f,0xb7,0x90,0x08,
0xe7,0x04,0xad,0xda,0xc8,0x70,0x10,0x3a,0x61,0x92,0x9b,0x03,0x96,0x8e,0xc7,0x59,
0x0c,0x47,0xcb,0xbd,0xb6,0x6a,0x18,0xfc,0x29,0x69,0x80,0x17,0x82,0x90,0x59,0x1b,
0xc6,0x3d,0x89,0x64,0x76,0x4d,0x73,0x63,0x7f,0xa5,0x3a,0xf8,0x81,0x7e,0x85,0xf0,
0x4b,0xf3,0x9e,0x0c,0x9f,0x0f,0x59,0x91,0x25,0x32,0x84,0x5f,0x01,0xb8,0xa9,0xa2,
0xad,0x05,0x31,0x02,0x41,0x00,0xff,0xa1,0x02,0xce,0x09,0xcb,0xde,0x21,0x8c,0xe9,
0xa1,0xe6,0x6d,0x2a,0x94,0xee,0x7a,0x66,0xc7,0x9e,0x4e,0xea,0x7c,0xb7,0xcf,0xcf,
0x1e,0x48,0xa9,0x67,0xfe,0x0d,0xc7,0xeb,0x45,0xdc,0x86,0x4d,0x12,0x79,0xcd,0x47,
0x4a,0x82,0xf3,0x72,0x2b,0xdf,0x56,0x74,0x32,0x3f,0x13,0x83,0x2a,0xa5,0x1a,0xdd,
0xc8,0x32,0x31,0x7a,0x6f,0xad,0x02,0x41,0x00,0xeb,0xca,0x5f,0x89,0x5e,0x94,0x1b,
0xb9,0x40,0x14,0x11,0x9d,0xb5,0xa7,0xaa,0x41,0xf5,0xcc,0x3c,0x4c,0x0d,0x06,0x3b,
0xac,0x77,0xb0,0x1a,0xf0,0x03,0x7f,0x1c,0x1b,0x19,0xea,0x71,0x0e,0x2f,0x08,0x7a,
0x30,0xdc,0x16,0x5e,0xd5,0x4a,0x83,0x4a,0x2b,0x34,0x88,0x0b,0x34,0xba,0x78,0x17,
0xc8,0x5c,0x1f,0x3e,0x83,0x8f,0x74,0xaf,0xff,0x02,0x41,0x00,0x9a,0x75,0xff,0xeb,
0xdf,0x9f,0x80,0x29,0x65,0xac,0x06,0x57,0xe5,0xbe,0xc5,0x1f,0x14,0x76,0xe6,0x47,
0x92,0x07,0xbe,0x34,0x93,0x2c,0xe3,0x6f,0xa4,0x6d,0x61,0xe5,0x91,0xd7,0x67,0xef,
0x48,0x77,0x69,0xa2,0x8f,0x97,0x74,0x3e,0x8c,0x3b,0x80,0xa7,0x02,0xe6,0x53,0x36,
0x29,0xe4,0x27,0xf0,0x7b,0xbb,0x67,0x2c,0x6d,0x19,0x3e,0x41,0x02,0x40,0x1a,0x2f,
0x59,0x38,0xba,0x26,0x1c,0x86,0x10,0x15,0xaa,0x77,0x27,0x2b,0x3d,0x7f,0x21,0xba,
0xd2,0x9f,0x67,0x7a,0xdf,0xb9,0xa1,0x79,0x0f,0x24,0xc4,0x5e,0xa3,0x52,0x67,0x28,
0x5f,0xf1,0xc1,0x4b,0x61,0xb6,0x77,0x5a,0x8c,0xa1,0x87,0x2a,0xd9,0x5b,0xbe,0xf3,
0xb4,0xba,0xe0,0x52,0x61,0xe1,0xc0,0x49,0x3f,0xfa,0x00,0x3e,0x67,0x25,0x02,0x40,
0x58,0x37,0xc2,0x52,0x77,0x1b,0xd1,0xc9,0x05,0x62,0x18,0x12,0x5e,0xb4,0xad,0x0a,
0x9e,0x15,0x29,0x3e,0xa5,0x25,0xdc,0x6c,0x83,0x12,0x8c,0x72,0x47,0xa2,0x1e,0x01,
0xb9,0xc2,0xb9,0xa1,0xe9,0x83,0x34,0xb0,0xf0,0xc2,0xf7,0xfd,0x58,0x5a,0xfa,0xf7,
0xbc,0x17,0x77,0x20,0x77,0xfa,0xcb,0xfd,0x2f,0xe4,0xf3,0x9f,0xea,0x10,0x5c,0x02
};
static const int rsa512_sec_len = sizeof rsa512_sec;
static void* MyAlloc(u32 size)
{
void* ptr;
ptr = OS_Alloc(size);
return ptr;
}
static void MyFree(void* ptr)
{
OS_Free(ptr);
}
#ifndef MIN
#define MIN(a, b) (((a) < (b)) ? (a) : (b))
#endif
static void* MyRealloc(void* ptr, u32 new_size, u32 old_size)
{
void *buf;
if ((buf = OS_Alloc(new_size)) == NULL)
{
return NULL;
}
MI_CpuCopy8(ptr, buf, MIN(new_size, old_size));
OS_Free(ptr);
return buf;
}
#define PrintResultEq( a, b, f ) \
{ OS_TPrintf( ((a) == (b)) ? "[--OK--] " : "[**NG**] " ); (f) = (f) && ((a) == (b)); }
#define CheckAndPrintErr( result, str ) \
{ if(OS_IsRunOnTwl() == TRUE){ \
if(result < 0) { OS_TPrintf( "Error: %d (%s)\n", result, str ); return FALSE;} \
}else{ \
if(result >= 0){ OS_TPrintf( "Error: %d (%s)\n", result, str ); return FALSE;} \
} \
}
BOOL RsaTestInit(void)
{
static BOOL init_flag = FALSE;
if( init_flag == TRUE ) {
return TRUE;
}
CRYPTO_SetMemAllocator(MyAlloc, MyFree, MyRealloc);
init_flag = TRUE;
return TRUE;
}
int RsaTestDecrypt(char *input, int in_len, char *output, int outlen)
{
s32 result;
s32 outcount = 0;
CRYPTORSAContext context;
CRYPTORSADecryptInitParam decinitparam;
CRYPTORSADecryptParam decparam;
void *key;
memset((void *)&context, 0, sizeof(CRYPTORSAContext));
memset((void *)&decinitparam, 0, sizeof(CRYPTORSADecryptInitParam));
memset((void *)&decparam, 0, sizeof(CRYPTORSADecryptParam));
/* RSA decode */
/*
typedef struct CRYPTORSADecryptInitParam {
void *key;
u32 key_len;
} CRYPTORSADecryptInitParam;
key RSA秘密鍵を格納した文字列のアドレスを指定します
key_len RSA秘密鍵の文字列長を指定します
RSA復号のための初期化処理に必要な情報を指定するための構造体です
keyで指定したアドレスにはDER形式のRSA秘密鍵イメージ全体を格納してください
*/
key = (void *)OS_Alloc(rsa512_sec_len);
if( key == NULL ) {
OS_TPrintf("Error:alloc %s %d",__FUNCTION__,__LINE__);
return 0;
}
memcpy(key, (void*)rsa512_sec, rsa512_sec_len);
// decinitparam.key = (void*)rsa512_sec;
decinitparam.key = key;
decinitparam.key_len = rsa512_sec_len;
result = CRYPTO_RSA_DecryptInit(&context, &decinitparam);
CheckAndPrintErr(result, "CRYPTO_RSA_DecryptInit");
/*
typedef struct CRYPTORSADecryptParam {
void *in;
u32 in_len;
void *out;
u32 out_size;
} CRYPTORSADecryptParam;
in RSAで復号する文字列のアドレスを指定します
in_len RSAで復号する文字列の長さを指定します
out
out_size outのバッファサイズを指定します
RSA復号処理を行う文字列および出力先に関する情報を指定するための構造体です
*/
//BOOL RsaTestDecrypt(char *input, int in_len, char *output, int outlen)
decparam.in = input;
decparam.in_len = (u32)in_len;
decparam.out = output;
decparam.out_size = (u32)outlen;
outcount = 0;
outcount = CRYPTO_RSA_Decrypt(&context, &decparam);
CheckAndPrintErr(result, "CRYPTO_RSA_Decrypt");
result = CRYPTO_RSA_DecryptTerminate(&context);
CheckAndPrintErr(result, "CRYPTO_RSA_DecryptTerminate");
OS_Free(key);
// OS_TPrintf("in_len = %d outcount = %d\n",in_len, outcount);
return outcount;
}
/* ************* SHA256 ************** */
#define MD32_REG_T long
#define SHA_LONG unsigned long
#define SHA_LBLOCK 16
#define SHA_CBLOCK (SHA_LBLOCK*4) /* SHA treats input data as a
* contiguous array of 32 bit
* wide big-endian values. */
#define SHA_LAST_BLOCK (SHA_CBLOCK-8)
#define SHA256_CBLOCK (SHA_LBLOCK*4) /* SHA-256 treats input data as a
* contiguous array of 32 bit
* wide big-endian values. */
#define SHA224_DIGEST_LENGTH 28
#define SHA256_DIGEST_LENGTH 32
typedef struct SHA256state_st
{
SHA_LONG h[8];
SHA_LONG Nl,Nh;
SHA_LONG data[SHA_LBLOCK];
unsigned int num,md_len;
} SHA256_CTX;
static int SHA256_Init(SHA256_CTX *c);
static int SHA256_Update(SHA256_CTX *c, const void *data, size_t len);
static int SHA256_Final(unsigned char *md, SHA256_CTX *c);
void SHA256(const unsigned char *d, size_t n, unsigned char *md)
{
SHA256_CTX c;
SHA256_Init(&c);
SHA256_Update(&c,d,n);
SHA256_Final(md,&c);
// OPENSSL_cleanse(&c,sizeof(c));
}
static int SHA256_Init (SHA256_CTX *c)
{
memset (c,0,sizeof(*c));
c->h[0]=0x6a09e667UL; c->h[1]=0xbb67ae85UL;
c->h[2]=0x3c6ef372UL; c->h[3]=0xa54ff53aUL;
c->h[4]=0x510e527fUL; c->h[5]=0x9b05688cUL;
c->h[6]=0x1f83d9abUL; c->h[7]=0x5be0cd19UL;
c->md_len=SHA256_DIGEST_LENGTH;
return 1;
}
#define HASH_BLOCK_DATA_ORDER sha256_block_data_order
static void sha256_block_data_order (SHA256_CTX *ctx, const void *in, size_t num);
#define DATA_ORDER_IS_BIG_ENDIAN
#define HASH_LONG SHA_LONG
#define HASH_CTX SHA256_CTX
#define HASH_CBLOCK SHA_CBLOCK
#if defined(DATA_ORDER_IS_BIG_ENDIAN)
#define HOST_c2l(c,l) (l =(((unsigned long)(*((c)++)))<<24), \
l|=(((unsigned long)(*((c)++)))<<16), \
l|=(((unsigned long)(*((c)++)))<< 8), \
l|=(((unsigned long)(*((c)++))) ))
#define HOST_l2c(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))
#elif defined(DATA_ORDER_IS_LITTLE_ENDIAN)
#define HOST_c2l(c,l) (l =(((unsigned long)(*((c)++))) ), \
l|=(((unsigned long)(*((c)++)))<< 8), \
l|=(((unsigned long)(*((c)++)))<<16), \
l|=(((unsigned long)(*((c)++)))<<24))
#define HOST_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))
#endif
#define HASH_MAKE_STRING(c,s) do { \
unsigned long ll; \
unsigned int nn; \
switch ((c)->md_len) \
{ case SHA224_DIGEST_LENGTH: \
for (nn=0;nn<SHA224_DIGEST_LENGTH/4;nn++) \
{ ll=(c)->h[nn]; HOST_l2c(ll,(s)); } \
break; \
case SHA256_DIGEST_LENGTH: \
for (nn=0;nn<SHA256_DIGEST_LENGTH/4;nn++) \
{ ll=(c)->h[nn]; HOST_l2c(ll,(s)); } \
break; \
default: \
if ((c)->md_len > SHA256_DIGEST_LENGTH) \
return 0; \
for (nn=0;nn<(c)->md_len/4;nn++) \
{ ll=(c)->h[nn]; HOST_l2c(ll,(s)); } \
break; \
} \
} while (0)
static int SHA256_Update(HASH_CTX *c, const void *data_, size_t len)
{
const unsigned char *data=data_;
unsigned char *p;
HASH_LONG l;
size_t n;
if (len==0) return 1;
l=(c->Nl+(((HASH_LONG)len)<<3))&0xffffffffUL;
/* 95-05-24 eay Fixed a bug with the overflow handling, thanks to
* Wei Dai <weidai@eskimo.com> for pointing it out. */
if (l < c->Nl) /* overflow */
c->Nh++;
c->Nh+=(HASH_LONG)(len>>29); /* might cause compiler warning on 16-bit */
c->Nl=l;
n = c->num;
if (n != 0)
{
p=(unsigned char *)c->data;
if (len >= HASH_CBLOCK || len+n >= HASH_CBLOCK)
{
memcpy (p+n,data,HASH_CBLOCK-n);
HASH_BLOCK_DATA_ORDER (c,p,1);
n = HASH_CBLOCK-n;
data += n;
len -= n;
c->num = 0;
memset (p,0,HASH_CBLOCK); /* keep it zeroed */
}
else
{
memcpy (p+n,data,len);
c->num += (unsigned int)len;
return 1;
}
}
n = len/HASH_CBLOCK;
if (n > 0)
{
HASH_BLOCK_DATA_ORDER (c,data,n);
n *= HASH_CBLOCK;
data += n;
len -= n;
}
if (len != 0)
{
p = (unsigned char *)c->data;
c->num = (unsigned int)len;
memcpy (p,data,len);
}
return 1;
}
static int SHA256_Final(unsigned char *md, HASH_CTX *c)
{
unsigned char *p = (unsigned char *)c->data;
size_t n = c->num;
p[n] = 0x80; /* there is always room for one */
n++;
if (n > (HASH_CBLOCK-8))
{
memset (p+n,0,HASH_CBLOCK-n);
n=0;
HASH_BLOCK_DATA_ORDER (c,p,1);
}
memset (p+n,0,HASH_CBLOCK-8-n);
p += HASH_CBLOCK-8;
#if defined(DATA_ORDER_IS_BIG_ENDIAN)
(void)HOST_l2c(c->Nh,p);
(void)HOST_l2c(c->Nl,p);
#elif defined(DATA_ORDER_IS_LITTLE_ENDIAN)
(void)HOST_l2c(c->Nl,p);
(void)HOST_l2c(c->Nh,p);
#endif
p -= HASH_CBLOCK;
HASH_BLOCK_DATA_ORDER (c,p,1);
c->num=0;
memset (p,0,HASH_CBLOCK);
#ifndef HASH_MAKE_STRING
#error "HASH_MAKE_STRING must be defined!"
#else
HASH_MAKE_STRING(c,md);
#endif
return 1;
}
static const SHA_LONG K256[64] = {
0x428a2f98UL,0x71374491UL,0xb5c0fbcfUL,0xe9b5dba5UL,
0x3956c25bUL,0x59f111f1UL,0x923f82a4UL,0xab1c5ed5UL,
0xd807aa98UL,0x12835b01UL,0x243185beUL,0x550c7dc3UL,
0x72be5d74UL,0x80deb1feUL,0x9bdc06a7UL,0xc19bf174UL,
0xe49b69c1UL,0xefbe4786UL,0x0fc19dc6UL,0x240ca1ccUL,
0x2de92c6fUL,0x4a7484aaUL,0x5cb0a9dcUL,0x76f988daUL,
0x983e5152UL,0xa831c66dUL,0xb00327c8UL,0xbf597fc7UL,
0xc6e00bf3UL,0xd5a79147UL,0x06ca6351UL,0x14292967UL,
0x27b70a85UL,0x2e1b2138UL,0x4d2c6dfcUL,0x53380d13UL,
0x650a7354UL,0x766a0abbUL,0x81c2c92eUL,0x92722c85UL,
0xa2bfe8a1UL,0xa81a664bUL,0xc24b8b70UL,0xc76c51a3UL,
0xd192e819UL,0xd6990624UL,0xf40e3585UL,0x106aa070UL,
0x19a4c116UL,0x1e376c08UL,0x2748774cUL,0x34b0bcb5UL,
0x391c0cb3UL,0x4ed8aa4aUL,0x5b9cca4fUL,0x682e6ff3UL,
0x748f82eeUL,0x78a5636fUL,0x84c87814UL,0x8cc70208UL,
0x90befffaUL,0xa4506cebUL,0xbef9a3f7UL,0xc67178f2UL };
#define ROTATE(a,n) (((a)<<(n))|(((a)&0xffffffff)>>(32-(n))))
#define Sigma0(x) (ROTATE((x),30) ^ ROTATE((x),19) ^ ROTATE((x),10))
#define Sigma1(x) (ROTATE((x),26) ^ ROTATE((x),21) ^ ROTATE((x),7))
#define sigma0(x) (ROTATE((x),25) ^ ROTATE((x),14) ^ ((x)>>3))
#define sigma1(x) (ROTATE((x),15) ^ ROTATE((x),13) ^ ((x)>>10))
#define Ch(x,y,z) (((x) & (y)) ^ ((~(x)) & (z)))
#define Maj(x,y,z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z)))
#define ROUND_00_15(i,a,b,c,d,e,f,g,h) do { \
T1 += h + Sigma1(e) + Ch(e,f,g) + K256[i]; \
h = Sigma0(a) + Maj(a,b,c); \
d += T1; h += T1; } while (0)
#define ROUND_16_63(i,a,b,c,d,e,f,g,h,X) do { \
s0 = X[(i+1)&0x0f]; s0 = sigma0(s0); \
s1 = X[(i+14)&0x0f]; s1 = sigma1(s1); \
T1 = X[(i)&0x0f] += s0 + s1 + X[(i+9)&0x0f]; \
ROUND_00_15(i,a,b,c,d,e,f,g,h); } while (0)
static void sha256_block_data_order (SHA256_CTX *ctx, const void *in, size_t num)
{
unsigned MD32_REG_T a,b,c,d,e,f,g,h,s0,s1,T1;
SHA_LONG X[16];
int i;
const unsigned char *data=in;
const union { long one; char little; } is_endian = {1};
while (num--) {
a = ctx->h[0]; b = ctx->h[1]; c = ctx->h[2]; d = ctx->h[3];
e = ctx->h[4]; f = ctx->h[5]; g = ctx->h[6]; h = ctx->h[7];
if (!is_endian.little && sizeof(SHA_LONG)==4 && ((size_t)in%4)==0)
{
const SHA_LONG *W=(const SHA_LONG *)data;
T1 = X[0] = W[0]; ROUND_00_15(0,a,b,c,d,e,f,g,h);
T1 = X[1] = W[1]; ROUND_00_15(1,h,a,b,c,d,e,f,g);
T1 = X[2] = W[2]; ROUND_00_15(2,g,h,a,b,c,d,e,f);
T1 = X[3] = W[3]; ROUND_00_15(3,f,g,h,a,b,c,d,e);
T1 = X[4] = W[4]; ROUND_00_15(4,e,f,g,h,a,b,c,d);
T1 = X[5] = W[5]; ROUND_00_15(5,d,e,f,g,h,a,b,c);
T1 = X[6] = W[6]; ROUND_00_15(6,c,d,e,f,g,h,a,b);
T1 = X[7] = W[7]; ROUND_00_15(7,b,c,d,e,f,g,h,a);
T1 = X[8] = W[8]; ROUND_00_15(8,a,b,c,d,e,f,g,h);
T1 = X[9] = W[9]; ROUND_00_15(9,h,a,b,c,d,e,f,g);
T1 = X[10] = W[10]; ROUND_00_15(10,g,h,a,b,c,d,e,f);
T1 = X[11] = W[11]; ROUND_00_15(11,f,g,h,a,b,c,d,e);
T1 = X[12] = W[12]; ROUND_00_15(12,e,f,g,h,a,b,c,d);
T1 = X[13] = W[13]; ROUND_00_15(13,d,e,f,g,h,a,b,c);
T1 = X[14] = W[14]; ROUND_00_15(14,c,d,e,f,g,h,a,b);
T1 = X[15] = W[15]; ROUND_00_15(15,b,c,d,e,f,g,h,a);
data += SHA256_CBLOCK;
}
else
{
SHA_LONG l;
HOST_c2l(data,l); T1 = X[0] = l; ROUND_00_15(0,a,b,c,d,e,f,g,h);
HOST_c2l(data,l); T1 = X[1] = l; ROUND_00_15(1,h,a,b,c,d,e,f,g);
HOST_c2l(data,l); T1 = X[2] = l; ROUND_00_15(2,g,h,a,b,c,d,e,f);
HOST_c2l(data,l); T1 = X[3] = l; ROUND_00_15(3,f,g,h,a,b,c,d,e);
HOST_c2l(data,l); T1 = X[4] = l; ROUND_00_15(4,e,f,g,h,a,b,c,d);
HOST_c2l(data,l); T1 = X[5] = l; ROUND_00_15(5,d,e,f,g,h,a,b,c);
HOST_c2l(data,l); T1 = X[6] = l; ROUND_00_15(6,c,d,e,f,g,h,a,b);
HOST_c2l(data,l); T1 = X[7] = l; ROUND_00_15(7,b,c,d,e,f,g,h,a);
HOST_c2l(data,l); T1 = X[8] = l; ROUND_00_15(8,a,b,c,d,e,f,g,h);
HOST_c2l(data,l); T1 = X[9] = l; ROUND_00_15(9,h,a,b,c,d,e,f,g);
HOST_c2l(data,l); T1 = X[10] = l; ROUND_00_15(10,g,h,a,b,c,d,e,f);
HOST_c2l(data,l); T1 = X[11] = l; ROUND_00_15(11,f,g,h,a,b,c,d,e);
HOST_c2l(data,l); T1 = X[12] = l; ROUND_00_15(12,e,f,g,h,a,b,c,d);
HOST_c2l(data,l); T1 = X[13] = l; ROUND_00_15(13,d,e,f,g,h,a,b,c);
HOST_c2l(data,l); T1 = X[14] = l; ROUND_00_15(14,c,d,e,f,g,h,a,b);
HOST_c2l(data,l); T1 = X[15] = l; ROUND_00_15(15,b,c,d,e,f,g,h,a);
}
for (i=16;i<64;i+=8)
{
ROUND_16_63(i+0,a,b,c,d,e,f,g,h,X);
ROUND_16_63(i+1,h,a,b,c,d,e,f,g,X);
ROUND_16_63(i+2,g,h,a,b,c,d,e,f,X);
ROUND_16_63(i+3,f,g,h,a,b,c,d,e,X);
ROUND_16_63(i+4,e,f,g,h,a,b,c,d,X);
ROUND_16_63(i+5,d,e,f,g,h,a,b,c,X);
ROUND_16_63(i+6,c,d,e,f,g,h,a,b,X);
ROUND_16_63(i+7,b,c,d,e,f,g,h,a,X);
}
ctx->h[0] += a; ctx->h[1] += b; ctx->h[2] += c; ctx->h[3] += d;
ctx->h[4] += e; ctx->h[5] += f; ctx->h[6] += g; ctx->h[7] += h;
}
}
/* ******************* */
int my_rsa_sign( u8 *inbuf, u8 *outbuf, int buf_size, int *output_size )
{
int i;
u8 hash_data[MY_RSA_SIGN_HASH_SIZE];
u8 hash_calc[MY_RSA_SIGN_HASH_SIZE];
BOOL hash_check_flag = TRUE;
int decrypt_size = 0;
u8 decrypt_buf[MY_RSA_SIGN_RSA_SIZE];
int org_file_size = 0;
if( TRUE != RsaTestInit() ) {
#ifdef MY_RSA_SIGN_DEBUG
mprintf("RSA Init failed\n");
#endif /* MY_RSA_SIGN_DEBUG */
return MY_RSA_SIGN_ERROR_RSA_INIT_FAILED;
}
#ifdef MY_RSA_SIGN_DEBUG
mprintf("RSA Init success\n");
#endif /* MY_RSA_SIGN_DEBUG */
if( 0 == RsaTestDecrypt((char *)inbuf, MY_RSA_SIGN_RSA_SIZE, (char *)outbuf, buf_size) ) {
#ifdef MY_RSA_SIGN_DEBUG
mprintf("RSA Decrypt failed\n");
#endif /* MY_RSA_SIGN_DEBUG */
return MY_RSA_SIGN_ERROR_RSA_HASH_DECRYPT_FAILED;
}
#ifdef MY_RSA_SIGN_DEBUG
mprintf("RSA Decrypt success 1\n");
#endif /* MY_RSA_SIGN_DEBUG */
memcpy(hash_data, outbuf, MY_RSA_SIGN_HASH_SIZE);
SHA256( inbuf + MY_RSA_SIGN_RSA_SIZE, (u32)(buf_size - MY_RSA_SIGN_RSA_SIZE), hash_calc);
for( i = 0 ; i < MY_RSA_SIGN_HASH_SIZE ; i++ ) {
if( hash_calc[i] != hash_data[i] ) {
hash_check_flag = FALSE;
}
}
if( hash_check_flag == FALSE ) {
OS_TPrintf("invalid hash\n");
return MY_RSA_SIGN_ERROR_HASH_CHECK_FAILED;
}
#ifdef MY_RSA_SIGN_DEBUG
mprintf("hash check pass!\n");
#endif /* MY_RSA_SIGN_DEBUG */
org_file_size = *(int *)(inbuf + MY_RSA_SIGN_RSA_SIZE);
*output_size = 0;
for( i = 0 ; i < org_file_size ; i += MY_RSA_SIGN_RSA_SIZE ) {
decrypt_size = RsaTestDecrypt((char *)(inbuf + MY_RSA_SIGN_RSA_SIZE + 4 + i), MY_RSA_SIGN_RSA_SIZE,
(char *)decrypt_buf, MY_RSA_SIGN_RSA_SIZE );
if( 0 != decrypt_size ) {
//OS_TPrintf("RSA Decrypt success dec_size=%d\n",decrypt_size);
//mprintf("RSA Decrypt success 2\n");
memcpy( (char *)(outbuf + *output_size), decrypt_buf, (u32)decrypt_size);
*output_size += decrypt_size;
}
else {
#ifdef MY_RSA_SIGN_DEBUG
mprintf("RSA Decrypt Error dec_size=%d\n",decrypt_size);
#endif /* MY_RSA_SIGN_DEBUG */
return MY_RSA_SIGN_ERROR_RSA_CONTENT_DECRYPT_FAILED;
}
}
OS_TPrintf("output_size = %d\n",*output_size );
OS_TPrintf("org_file_size = %d\n",org_file_size );
return MY_RSA_SIGN_SUCCESS;
}
/* ************************ */

View File

@ -0,0 +1,32 @@
#ifndef _MY_RSA_SIGN_H_
#define _MY_RSA_SIGN_H_
#ifdef __cplusplus
extern "C" {
#endif
#define MY_RSA_SIGN_HASH_SIZE 32
#define MY_RSA_SIGN_RSA_SIZE 128
#define MY_RSA_SIGN_SUCCESS 0
#define MY_RSA_SIGN_ERROR_RSA_INIT_FAILED 1
#define MY_RSA_SIGN_ERROR_RSA_HASH_DECRYPT_FAILED 2
#define MY_RSA_SIGN_ERROR_HASH_CHECK_FAILED 3
#define MY_RSA_SIGN_ERROR_RSA_CONTENT_DECRYPT_FAILED 4
int my_rsa_sign( u8 *inbuf, u8 *outbuf, int buf_size, int *output_size );
BOOL RsaTestInit(void);
int RsaTestDecrypt(char *input, int in_len, char *output, int outlen);
void SHA256(const unsigned char *d, size_t n, unsigned char *md);
#ifdef __cplusplus
}
#endif
#endif /* _MY_RSA_SIGN_H_ */

View File

@ -0,0 +1,360 @@
#include <twl.h>
#include <stddef.h>
#include <string.h>
#include "my_rsa_sign.h"
#include "my_aes.h"
#include "my_sign.h"
#define AES_KEY_BIT_LEN 256
#define AES_KEY_BYTE_LEN (AES_KEY_BIT_LEN/8)
static BOOL my_sign_check(MY_SIGN_SIGNATURE *encrypted_sign, u8 *buf, int buf_size)
{
u8 hash_temp[MY_SIGN_HASH_SIZE] ATTRIBUTE_ALIGN(32);
MY_SIGN_SIGNATURE tmp_sign ATTRIBUTE_ALIGN(32);
int outlen;
int i;
if( encrypted_sign == NULL ) {
OS_TPrintf("func=%s line=%d error!\n",__FUNCTION__,__LINE__);
return FALSE;
}
if( buf == NULL ) {
OS_TPrintf("func=%s line=%d error!\n",__FUNCTION__,__LINE__);
return FALSE;
}
if( buf_size == 0 ) {
OS_TPrintf("func=%s line=%d error!\n",__FUNCTION__,__LINE__);
return FALSE;
}
memset(hash_temp, 0, MY_SIGN_HASH_SIZE );
memset((void *)&tmp_sign, 0, sizeof(MY_SIGN_SIGNATURE));
SHA256(buf, (u32)buf_size, hash_temp);
outlen = RsaTestDecrypt((char *)encrypted_sign, sizeof(MY_SIGN_SIGNATURE),
(char *)&tmp_sign, sizeof(MY_SIGN_SIGNATURE));
// OS_TPrintf("decrypt outlen = %d\n",outlen);
if( outlen < MY_SIGN_HASH_SIZE ) {
OS_TPrintf("line=%d RSA Decrypt error! outlen=%d\n",__LINE__,outlen);
return FALSE;
}
for( i = 0 ; i < MY_SIGN_HASH_SIZE ; i++ ) {
// OS_TPrintf("hash[0x%02x] chk=0x%02x cal=0x%02x\n",i,tmp_sign.hash[i],hash_temp[i]);
if( tmp_sign.hash[i] != hash_temp[i] ) {
OS_TPrintf("Hash check error i=%d chk=0x%02x cal=0x%02x\n", i , tmp_sign.hash[i] , hash_temp[i] );
return FALSE;
}
}
return TRUE;
}
void my_sign_FS_InitFile(MY_SIGN_File *msfile)
{
msfile->open_flag = FALSE;
}
BOOL my_sign_FS_SeekFile(MY_SIGN_File *msfile, int offset, int whence)
{
if( msfile->open_flag != TRUE ) {
return FALSE; /* error */
}
switch( whence ) {
case FS_SEEK_SET:
msfile->pos = offset;
break;
case FS_SEEK_CUR:
msfile->pos += offset;
break;
case FS_SEEK_END:
msfile->pos = msfile->header.org_file_size + offset;
break;
}
if( msfile->pos < 0 ) {
msfile->pos = 0;
}
else if( msfile->pos >= msfile->header.org_file_size ) {
msfile->pos = msfile->header.org_file_size - 1;
}
return TRUE;
}
BOOL my_sign_FS_SeekFileToBegin(MY_SIGN_File *msfile)
{
if( msfile->open_flag != TRUE ) {
return FALSE; /* error */
}
msfile->pos = 0;
return TRUE;
}
u32 my_sign_FS_GetLength(MY_SIGN_File *msfile)
{
if( msfile->open_flag != TRUE ) {
return 0; /* error */
}
return (u32)(msfile->header.org_file_size);
}
BOOL my_sign_FS_OpenFile(MY_SIGN_File *msfile, char *path)
{
MY_SIGN_SIGNATURE temp_sign;
// MY_SIGN_SIGNATURE *L2_sign_table_temp;
// int rest_readlen = 0;
// int outlen = 0;
int readlen;
int L2_sign_table_size;
if( msfile == NULL ) {
return FALSE;
}
// OS_TPrintf("hash offset = %d\n",offsetof(MY_SIGN_SIGNATURE, hash));
RsaTestInit();
FS_InitFile(&(msfile->f));
if( FALSE == FS_OpenFileEx(&(msfile->f), path, FS_FILEMODE_R) ) {
OS_TPrintf("%s Failed Open File %s\n",__FUNCTION__,path);
return FALSE;
}
/*
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)
.
.
*/
readlen = FS_ReadFile(&(msfile->f), &(msfile->header), sizeof(MY_SIGN_HEADER) );
if( readlen != sizeof(MY_SIGN_HEADER) ) {
OS_TPrintf("%s Failed read File readlen=%d\n",__FUNCTION__, readlen);
return FALSE;
}
// OS_TPrintf("%s %d\n",__FUNCTION__, __LINE__);
/* ヘッダーの読み込み */
readlen = FS_ReadFile(&(msfile->f), &temp_sign, sizeof(MY_SIGN_SIGNATURE) );
if( readlen != sizeof(MY_SIGN_SIGNATURE) ) {
OS_TPrintf("%s Failed read File readlen=%d\n",__FUNCTION__, readlen);
return FALSE;
}
/* ヘッダーの署名チェック */
if( FALSE == my_sign_check(&temp_sign, (u8 *)&(msfile->header), sizeof(MY_SIGN_HEADER)) ) {
OS_TPrintf("line=%d Header signature chech error!\n",__LINE__);
return FALSE;
}
#if 0
OS_TPrintf("header.magic_code = 0x%08x\n",(int)msfile->header.magic_code);
OS_TPrintf("header.org_file_size = %d\n",(int)msfile->header.org_file_size);
OS_TPrintf("header.num_of_block = %d\n",(int)msfile->header.num_of_block);
#endif
// rest_readlen = (int)msfile->header.org_file_size;
// header.file_offset_L2_sign_table;
// header.file_offset_data_block;
L2_sign_table_size = (int)(msfile->header.num_of_block * sizeof(MY_SIGN_SIGNATURE));
msfile->L2_sign_table = (MY_SIGN_SIGNATURE *)OS_Alloc( (u32)L2_sign_table_size );
if(msfile->L2_sign_table == NULL ) {
OS_TPrintf("%s Failed alloc line=%d\n",__LINE__);
return FALSE;
}
// L2_sign_table_temp = msfile->L2_sign_table;
readlen = FS_ReadFile(&(msfile->f), (u8 *)(msfile->L2_sign_table), L2_sign_table_size );
if( readlen != L2_sign_table_size ) {
OS_TPrintf("%s Failed read File readlen=%d\n",__FUNCTION__, readlen);
return FALSE;
}
/* L2署名テーブルの署名チェック */
if( FALSE == my_sign_check(&(msfile->header.L2_sign), (u8 *)(msfile->L2_sign_table), L2_sign_table_size) ) {
OS_TPrintf("L2_sign Hash check error!\n");
return FALSE;
}
msfile->block_buf_in = (u8 *)OS_Alloc( MY_SIGN_BLOCK_SIZE );
if( msfile->block_buf_in == NULL ) {
return FALSE;
}
msfile->block_buf_out = (u8 *)OS_Alloc( MY_SIGN_BLOCK_SIZE );
if( msfile->block_buf_out == NULL ) {
return FALSE;
}
msfile->open_flag = TRUE;
msfile->pos = 0; /* original file pos */
// OS_TPrintf("%s %d\n",__FUNCTION__, __LINE__);
end:
return TRUE;
}
int my_sign_FS_ReadFile(MY_SIGN_File *msfile, u8 *buf, int buf_size)
{
int i;
int block_no;
int enc_file_pos;
MY_SIGN_SIGNATURE *L2_sign_table_temp;
AES_KEY aes_key;
u8 aes_key_buf[AES_KEY_BYTE_LEN];
unsigned char aes_iv[ AES_BLOCK_SIZE ];
int block_buf_out_pos;
int user_buf_size;
u8 *user_buf_ptr;
int num = 0;
int readlen;
if( msfile->open_flag != TRUE ) {
return -1; /* error */
}
// msfile->pos = 0; /* original file pos */
// MY_SIGN_BLOCK_SIZE
/*
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;
*/
// header.file_offset_data_block;
// OS_TPrintf("%s %d\n",__FUNCTION__, __LINE__);
user_buf_size = buf_size;
user_buf_ptr = buf;
if( msfile->pos >= (int)(msfile->header.org_file_size) ) {
return 0;
}
loop_0:
block_no = msfile->pos / MY_SIGN_BLOCK_SIZE;
block_buf_out_pos = msfile->pos % MY_SIGN_BLOCK_SIZE;
if( block_no >= (int)msfile->header.num_of_block ) {
return -1;
}
// OS_TPrintf("%s %d pos = %d block_no = %d\n",__FUNCTION__, __LINE__,msfile->pos, block_no);
enc_file_pos = (int)msfile->header.file_offset_data_block + block_no * MY_SIGN_BLOCK_SIZE;
if( FALSE == FS_SeekFile(&(msfile->f), enc_file_pos , FS_SEEK_SET) ) {
return -1;
}
readlen = FS_ReadFile(&(msfile->f), msfile->block_buf_in, MY_SIGN_BLOCK_SIZE);
if( readlen != MY_SIGN_BLOCK_SIZE ) {
OS_TPrintf("%s %d Failed read File readlen=%d\n",__FUNCTION__, __LINE__, readlen);
return -1;
}
L2_sign_table_temp = msfile->L2_sign_table + block_no;
/* データブロックの署名チェック */
if( FALSE == my_sign_check( L2_sign_table_temp, msfile->block_buf_in, MY_SIGN_BLOCK_SIZE) ) {
OS_TPrintf("Data Hash check Error!\n");
return -1;
}
/* AESキーのセット */
for( i = 0 ; i < AES_KEY_BYTE_LEN ; i++ ) {
aes_key_buf[i] = (u8)i;
}
AES_set_decrypt_key(aes_key_buf, AES_KEY_BIT_LEN, &aes_key);
for( i = 0 ; i < AES_BLOCK_SIZE ; i++ ) {
aes_iv[i] = (u8)i;
}
memset(msfile->block_buf_out, 0 , MY_SIGN_BLOCK_SIZE);
/* AES復号化 */
for( i = 0 ; i < (MY_SIGN_BLOCK_SIZE / AES_BLOCK_SIZE) ; i++ ) {
AES_cbc_encrypt( &(msfile->block_buf_in[AES_BLOCK_SIZE*i]), &(msfile->block_buf_out[AES_BLOCK_SIZE*i]),
AES_BLOCK_SIZE, &aes_key, aes_iv, AES_DECRYPT );
}
// block_no
while( user_buf_size ) {
if( msfile->pos >= (int)msfile->header.org_file_size ) {
goto end;
}
if( block_buf_out_pos >= MY_SIGN_BLOCK_SIZE ) {
break;
}
*user_buf_ptr++ = msfile->block_buf_out[block_buf_out_pos];
block_buf_out_pos++;
msfile->pos++;
user_buf_size--;
num++;
}
if( user_buf_size > 0 ) {
goto loop_0;
}
end:
return num;
}
BOOL my_sign_FS_CloseFile(MY_SIGN_File *msfile)
{
if( msfile ) {
if( msfile->L2_sign_table ) {
OS_Free( msfile->L2_sign_table );
}
if( msfile->block_buf_in ) {
OS_Free( msfile->block_buf_in );
}
if( msfile->block_buf_out ) {
OS_Free( msfile->block_buf_out );
}
}
(void)FS_CloseFile(&(msfile->f));
return TRUE;
}

View File

@ -0,0 +1,56 @@
#ifndef _MY_SIGN_H_
#define _MY_SIGN_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;
s32 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;
typedef struct {
FSFile f;
BOOL open_flag;
int pos; /* original file pos */
MY_SIGN_SIGNATURE *L2_sign_table;
MY_SIGN_HEADER header;
u8 *block_buf_in;
u8 *block_buf_out;
} MY_SIGN_File;
BOOL my_sign_FS_OpenFile(MY_SIGN_File *msfile, char *path);
int my_sign_FS_ReadFile(MY_SIGN_File *msfile, u8 *buf, int buf_size);
BOOL my_sign_FS_CloseFile(MY_SIGN_File *msfile);
u32 my_sign_FS_GetLength(MY_SIGN_File *msfile);
BOOL my_sign_FS_SeekFileToBegin(MY_SIGN_File *msfile);
BOOL my_sign_FS_SeekFile(MY_SIGN_File *msfile, int offset, int whence);
void my_sign_FS_InitFile(MY_SIGN_File *msfile);
#ifdef __cplusplus
}
#endif
#endif /* _MY_SIGN_H_ */

View File

@ -3,7 +3,7 @@
#define MY_DATA_VERSION_MAJOR 1
#define MY_DATA_VERSION_MINOR 5
#define MY_DATA_VERSION_MINOR 6
typedef struct {
u8 version_major;

File diff suppressed because it is too large Load Diff

View File

@ -5,9 +5,11 @@
extern "C" {
#endif
BOOL myImportTad(char* file_name, FSFile *log_fd);
BOOL myImportTad(char* file_name, int org_version, FSFile *log_fd);
BOOL myImportTad_sign(char* full_path, int org_version, FSFile *log_fd);
BOOL myDeleteTitle(u64 tid, BOOL with_ticket, FSFile *log_fd);
BOOL my_NAM_ImportTadTicketOnly(const char* path);
BOOL my_NAM_ImportTadTicketOnly_sign(const char* path);
#ifdef __cplusplus
}

View File

@ -12,46 +12,51 @@
#include "my_fs_util.h"
#include "myimport.h"
#include "my_sign.h"
#include "pre_install.h"
#define PRE_INSTALL_TABLE_FILE_NAND "rom:/tads/tad_table.txt"
#define PRE_INSTALL_TABLE_DEV_FILE_NAND "rom:/taddevs/taddev_table.txt"
#define PRE_INSTALL_TABLE_FILE_SD "sdmc:/tads/tad_table.txt"
#define PRE_INSTALL_TABLE_FILE_SD "sdmc:/sdtads/en_sdtad_table.txt"
#define PRE_INSTALL_TABLE_DEV_FILE_SD "sdmc:/sdtaddevs/en_sdtad_table.txt"
static PRE_INSTALL_FILE *pre_install_file_list = NULL;
#if 1
//char *pre_install_search_tid(u64 tid, FSFile *log_fd);
static BOOL pre_install_discard_list(void);
static void pre_install_print_list(FSFile *log_fd);
#endif
BOOL pre_install_get_version(u64 tid, u16 *version)
{
NAMTitleInfo titleInfoTmp;
if ( NAM_ReadTitleInfo(&titleInfoTmp, tid) == NAM_OK ) {
// NANDに既にインストールされているかどうか確認する
if (tid == titleInfoTmp.titleId) {
if( version != NULL ) {
*version = titleInfoTmp.version;
OS_TPrintf( "tid=0x%08x%08x version = %d\n",
(u32)(titleInfoTmp.titleId >> 32), (u32)(titleInfoTmp.titleId & 0xffffffff), titleInfoTmp.version);
return TRUE;
}
}
}
return FALSE;
}
BOOL pre_install_check_download_or_pre_install(u64 tid, int *flag, FSFile *log_fd)
{
ESError rv;
ESTicketView *ticketViews;
u32 numTickets;
u32 i;
#if 0
typedef u32 ESId; /* 32-bit device identity */
typedef struct {
ESVersion version; /* eTicket data structure version */
ESTicketId ticketId; /* eTicket ID */
ESId deviceId; /* device ID 0->common else->personalized */
ESTitleId titleId; /* title ID */
ESSysAccessMask sysAccessMask; /* 16 bit cidx mask */
u16 ticketVersion; /* 16 bit ticket version */
u32 accessTitleId; /* 32 bit title id for access control*/
u32 accessTitleMask; /* 32 bit title id mask */
u8 licenseType; /* for infrastructure use */
ESTicketReserved reserved; /* 48 bytes reserved info */
u8 audit; /* for infrastructure use */
ESCidxMask cidxMask; /* 512 bits of cidx mask */
ESLpEntry limits[ES_MAX_LIMIT_TYPE]; /* limit algorithm and limit */
} ESTicketView;
ESError ES_GetTicketViews(ESTitleId titleId, ESTicketView* ticketViewList, u32* ticketViewCnt);
#endif
if( flag == NULL ) {
return FALSE;
}
@ -67,22 +72,27 @@ BOOL pre_install_check_download_or_pre_install(u64 tid, int *flag, FSFile *log_f
if(numTickets) {
ticketViews = OS_Alloc(sizeof(ESTicketView) * numTickets);
if( ticketViews == NULL ) {
miya_log_fprintf(log_fd,"%s OS_Alloc failed: tid=0x%08x%08x\n",
__FUNCTION__, (u32)(tid >> 32) , (u32)(tid & 0xffffffff));
return FALSE;
}
rv = ES_GetTicketViews(tid, ticketViews, &numTickets);
if (rv != ES_ERR_OK) {
miya_log_fprintf(log_fd,"ES_GetTicketViews failed: %d tid=0x%08x%08x\n",
rv, (u32)(tid >> 32) , (u32)(tid & 0xffffffff) );
OS_Free(ticketViews );
return FALSE;
}
}
else {
#if 0
miya_log_fprintf(log_fd,"ES_GetTicketViews failed numTickets = 0: %d tid=0x%08x%08x\n",
miya_log_fprintf(log_fd,"ES_GetTicketViews numTickets = 0: %d tid=0x%08x%08x\n",
rv, (u32)(tid >> 32) , (u32)(tid & 0xffffffff) );
#if 0
return FALSE;
#endif
/* error ??? */
*flag = 0;
return TRUE;
}
@ -94,15 +104,23 @@ BOOL pre_install_check_download_or_pre_install(u64 tid, int *flag, FSFile *log_f
rv = ES_CheckLaunchRights(t->titleId, &t->ticketViews[0]);
#endif
if( ticketViews[0].deviceId == 0 ) {
/* common */
*flag = 1;
}
else {
/* personalized */
*flag = 2;
for( i = 0 ; i < numTickets ; i++ ) {
if( ticketViews[i].deviceId == 0 ) {
/* common */
*flag = 1;
/* 個でもcommonがあればcommon扱い */
break;
}
else {
/* personalized */
*flag = 2;
}
}
if( ticketViews ) {
OS_Free(ticketViews );
}
return TRUE;
}
@ -140,11 +158,10 @@ static BOOL pre_install_add_list(u64 tid, u8 region, u8 country_code, char *temp
}
temp_list->next = temp_pre_install_file;
}
return TRUE;
}
char *pre_install_search_tid(u64 tid, FSFile *log_fd)
static char *pre_install_search_tid(u64 tid, FSFile *log_fd, BOOL *is_in_sd)
{
PRE_INSTALL_FILE *temp_list;
@ -153,6 +170,12 @@ char *pre_install_search_tid(u64 tid, FSFile *log_fd)
miya_log_fprintf(log_fd,"\ntad file entry tid=0x%08x%08x\n%s\n",
(u32)(tid >> 32) , (u32)(tid & 0xffffffff), temp_list->file_name );
if( !STD_StrNCmp( temp_list->file_name, "sdmc:" , STD_StrLen("sdmc:")) ) {
*is_in_sd = TRUE;
}
else {
*is_in_sd = FALSE;
}
return temp_list->file_name;
}
}
@ -162,7 +185,7 @@ char *pre_install_search_tid(u64 tid, FSFile *log_fd)
}
BOOL pre_install_discard_list(void)
static BOOL pre_install_discard_list(void)
{
PRE_INSTALL_FILE *temp_list;
PRE_INSTALL_FILE *temp_list2;
@ -177,8 +200,7 @@ BOOL pre_install_discard_list(void)
return TRUE;
}
void pre_install_print_list(FSFile *log_fd)
static void pre_install_print_list(FSFile *log_fd)
{
PRE_INSTALL_FILE *temp_list;
u64 tid;
@ -190,8 +212,6 @@ void pre_install_print_list(FSFile *log_fd)
}
}
static int ReadLine(FSFile *f, char *buf, int buf_size)
{
char c;
@ -212,7 +232,37 @@ static int ReadLine(FSFile *f, char *buf, int buf_size)
*buf = '\0';
break;
}
*buf = c;
buf++;
if( count > buf_size ) {
buf--;
*buf = '\0';
break;
}
}
return count;
}
static int my_sign_ReadLine(MY_SIGN_File *f, char *buf, int buf_size)
{
char c;
s32 readSize;
int count = 0;
while( 1 ) {
readSize = my_sign_FS_ReadFile(f, (void *)&c, (s32)1 );
if( readSize == 0 ) {
/* EOF */
break;
}
count++;
if( c == '\r' ) {
*buf = '\0';
break;
}
else if(c == '\n' ) {
*buf = '\0';
break;
}
*buf = c;
buf++;
if( count > buf_size ) {
@ -238,7 +288,8 @@ static int my_char_to_hex(char c)
return -1; /* error */
}
BOOL pre_install_load_file(char *path, FSFile *log_fd)
/* main() -> pre_install_process() -> pre_install_load_file()で呼ばれる。 */
static BOOL pre_install_load_file(char *path, FSFile *log_fd)
{
FSFile file;
BOOL bSuccess = TRUE;
@ -401,6 +452,169 @@ label_last:
}
static BOOL pre_install_load_sd_file(char *path, FSFile *log_fd)
{
MY_SIGN_File file;
BOOL bSuccess = TRUE;
// s32 result;
s32 readSize;
// FSResult fsres;
int buf_counter;
int buf_state;
#define LINE_BUF_SIZE 512
char line_buf[LINE_BUF_SIZE];
// PRE_INSTALL_FILE temp_pre_install_file;
char temp_file_name[FS_FILE_NAME_MAX];
u64 temp_tid;
u8 temp_region;
u8 temp_country_code;
int temp_hex;
int temp_filename_count;
char c;
my_sign_FS_InitFile(&file);
bSuccess = my_sign_FS_OpenFile(&file, path);
if( ! bSuccess ) {
// fsres = FS_GetArchiveResultCode(path);
miya_log_fprintf(log_fd,"Error:%s %s open file failed %s\n",__FILE__,__FUNCTION__,path);
// miya_log_fprintf(log_fd, " Failed open file:%s\n", my_fs_util_get_fs_result_word( fsres ));
return FALSE; /* open error! */
}
/*
title id
0x00000000 00000000, region , country code, file name,
*/
while( 1 ) {
next_line_read:
buf_state = 0;
readSize = my_sign_ReadLine(&file, line_buf, LINE_BUF_SIZE );
if( readSize == 0 ) {
/* EOF */
OS_TPrintf("%s %s %d : End of File\n", __FILE__,__FUNCTION__,__LINE__);
break;
}
if( !STD_StrNCmp( line_buf, "0x" , STD_StrLen("0x")) ) {
OS_TPrintf("%s\n", line_buf);
buf_counter = STD_StrLen("0x");
buf_state = 1;
temp_tid = 0;
temp_region = 0;
temp_country_code = 0;
temp_filename_count = 0;
while( readSize > buf_counter ) {
c = line_buf[buf_counter];
switch( buf_state ) {
case 1: /* TID */
if( c == ',') {
if( buf_counter == 18 ) {
// OS_TPrintf("temp_tid=0x%08x %08x\n", (u32)(temp_tid >> 32) , (u32)(temp_tid & 0xffffffff));
buf_state = 2; /* next state */
}
else {
/* format error */
miya_log_fprintf(log_fd,"Error:%s %s %d format error \n",__FILE__,__FUNCTION__,__LINE__);
goto next_line_read;
// break;
}
}
else {
temp_hex = my_char_to_hex(c);
if( temp_hex != -1 ) {
temp_tid |= ( ((u64)temp_hex) << (64 - (4 * (buf_counter-1))) );
}
else {
/* format error */
miya_log_fprintf(log_fd,"Error:%s %s %d format error\n",__FILE__,__FUNCTION__,__LINE__);
goto next_line_read;
// break;
}
}
break;
case 2: /* region */
if( c == ' ' ) {
}
else if( c == ',' ) {
buf_state = 3; /* next state */
}
else {
temp_hex = my_char_to_hex(c);
if( temp_hex != -1 ) {
temp_region = (u8)temp_hex;
}
else {
/* format error */
miya_log_fprintf(log_fd,"Error:%s %s %d format error\n",__FILE__,__FUNCTION__,__LINE__);
goto next_line_read;
}
}
break;
case 3: /* country code */
if( c == ' ' ) {
}
else if( c == ',' ) {
buf_state = 4; /* next state */
}
else {
temp_hex = my_char_to_hex(c);
if( temp_hex != -1 ) {
temp_country_code = (u8)temp_hex;
}
else {
/* format error */
miya_log_fprintf(log_fd,"Error:%s %s %d format error\n",__FILE__,__FUNCTION__,__LINE__);
goto next_line_read;
}
}
break;
case 4: /* file name */
if( c == ',' ) {
temp_file_name[temp_filename_count] = '\0';
/* add list */
if( TRUE != pre_install_add_list(temp_tid, temp_region, temp_country_code, temp_file_name, log_fd) ) {
OS_TPrintf("Error: add list error %s %s %d\n", __FILE__,__FUNCTION__,__LINE__);
}
buf_state = 5; /* next state */
}
else {
if( c != ' ' ) {
temp_file_name[temp_filename_count] = c;
temp_filename_count++;
}
}
break;
case 5: /* until line end */
break;
default:
/* error */
break;
}
buf_counter++;
}
}
else {
/* 妙なフォーマットは全部コメント扱い. */
}
}
label_last:
(void)my_sign_FS_CloseFile(&file);
return bSuccess;
}
BOOL pre_install_Cleanup_User_Titles( FSFile *log_fd )
{
@ -481,6 +695,7 @@ BOOL pre_install_Cleanup_User_Titles( FSFile *log_fd )
}
BOOL pre_install_command(FSFile *log_fd, u64 *tid_array, int tid_count, int command, BOOL development_version_flag )
{
char *tad_file_name;
@ -488,14 +703,20 @@ BOOL pre_install_command(FSFile *log_fd, u64 *tid_array, int tid_count, int com
u64 tid;
char game_code_buf[5];
BOOL ret_flag;
BOOL is_in_sd = FALSE;
int org_version =-1;
if( development_version_flag ) {
(void)pre_install_load_sd_file(PRE_INSTALL_TABLE_DEV_FILE_SD, log_fd);
(void)pre_install_load_file(PRE_INSTALL_TABLE_DEV_FILE_NAND, log_fd);
}
else {
(void)pre_install_load_sd_file(PRE_INSTALL_TABLE_FILE_SD, log_fd);
(void)pre_install_load_file(PRE_INSTALL_TABLE_FILE_NAND, log_fd);
}
pre_install_print_list(log_fd);
switch( command ) {
case 1:
mprintf("Install App.\n");
@ -513,6 +734,8 @@ BOOL pre_install_command(FSFile *log_fd, u64 *tid_array, int tid_count, int com
break;
}
for( i = 0 ; i < tid_count ; i++ ) {
ret_flag = TRUE;
tid = tid_array[i];
@ -528,18 +751,28 @@ BOOL pre_install_command(FSFile *log_fd, u64 *tid_array, int tid_count, int com
case 1:
mprintf("IA ");
miya_log_fprintf(log_fd, "IA ");
tad_file_name = pre_install_search_tid( tid , log_fd);
tad_file_name = pre_install_search_tid( tid , log_fd, &is_in_sd);
if( tad_file_name ) {
ret_flag = myImportTad( tad_file_name , log_fd );
if( is_in_sd == TRUE ) {
ret_flag = myImportTad_sign( tad_file_name , org_version, log_fd );
}
else {
ret_flag = myImportTad( tad_file_name , org_version, log_fd );
}
}
break;
case 2:
mprintf("TO ");
miya_log_fprintf(log_fd, "TO ");
tad_file_name = pre_install_search_tid( tid , log_fd);
tad_file_name = pre_install_search_tid( tid , log_fd, &is_in_sd);
if( tad_file_name ) {
ret_flag = my_NAM_ImportTadTicketOnly( tad_file_name );
if( is_in_sd == TRUE ) {
ret_flag = my_NAM_ImportTadTicketOnly_sign( tad_file_name );
}
else {
ret_flag = my_NAM_ImportTadTicketOnly( tad_file_name );
}
}
break;
case 3:
@ -583,6 +816,22 @@ BOOL pre_install_command(FSFile *log_fd, u64 *tid_array, int tid_count, int com
}
BOOL pre_install_debug(FSFile *log_fd, BOOL development_version_flag )
{
if( development_version_flag ) {
(void)pre_install_load_sd_file(PRE_INSTALL_TABLE_DEV_FILE_SD, log_fd);
(void)pre_install_load_file(PRE_INSTALL_TABLE_DEV_FILE_NAND, log_fd);
}
else {
(void)pre_install_load_sd_file(PRE_INSTALL_TABLE_FILE_SD, log_fd);
(void)pre_install_load_file(PRE_INSTALL_TABLE_FILE_NAND, log_fd);
}
pre_install_print_list(NULL);
return TRUE;
}
BOOL pre_install_process( FSFile *log_fd, MY_USER_APP_TID *title_id_buf_ptr, int title_id_count,
u64 *ticket_id_array, int ticket_id_count, BOOL development_version_flag )
{
@ -591,25 +840,21 @@ BOOL pre_install_process( FSFile *log_fd, MY_USER_APP_TID *title_id_buf_ptr, int
u64 tid;
char game_code_buf[5];
BOOL ret_flag = TRUE;
#if 0
/* セキュリティ的にちょっと・・・ */
(void)pre_install_load_file(PRE_INSTALL_TABLE_FILE_SD, log_fd);
#endif
BOOL is_in_sd = FALSE;
int version;
if( development_version_flag ) {
(void)pre_install_load_sd_file(PRE_INSTALL_TABLE_DEV_FILE_SD, log_fd);
(void)pre_install_load_file(PRE_INSTALL_TABLE_DEV_FILE_NAND, log_fd);
}
else {
(void)pre_install_load_sd_file(PRE_INSTALL_TABLE_FILE_SD, log_fd);
(void)pre_install_load_file(PRE_INSTALL_TABLE_FILE_NAND, log_fd);
}
pre_install_print_list(NULL);
/* チケットだけのインストール */
for( i = 0 ; i < ticket_id_count ; i++ ) {
tid = ticket_id_array[i];
@ -621,9 +866,16 @@ BOOL pre_install_process( FSFile *log_fd, MY_USER_APP_TID *title_id_buf_ptr, int
continue;
}
tad_file_name = pre_install_search_tid( tid , log_fd);
tad_file_name = pre_install_search_tid( tid , log_fd, &is_in_sd);
if( tad_file_name ) {
if( FALSE == my_NAM_ImportTadTicketOnly( tad_file_name ) ) {
if( is_in_sd == TRUE ) {
ret_flag = my_NAM_ImportTadTicketOnly_sign( tad_file_name );
}
else {
ret_flag = my_NAM_ImportTadTicketOnly( tad_file_name );
}
if( FALSE == ret_flag ) {
/* error チケットインストール失敗? */
miya_log_fprintf(log_fd, "NG.\n");
m_set_palette(tc[0], M_TEXT_COLOR_RED ); /* green */
@ -666,13 +918,23 @@ BOOL pre_install_process( FSFile *log_fd, MY_USER_APP_TID *title_id_buf_ptr, int
0x000300044B47554A "rom:/tads/TWL-HNGJ-v256.tad.out"
*/
tid = title_id_buf_ptr[i].tid;
version = title_id_buf_ptr[i].version;
(void)my_fs_Tid_To_GameCode(tid, game_code_buf);
mprintf(" AP %08X %08X [%s] ", (u32)(tid >> 32), (u32)tid, game_code_buf);
miya_log_fprintf(log_fd, " AP %08X %08X [%s] ", (u32)(tid >> 32), (u32)tid, game_code_buf);
tad_file_name = pre_install_search_tid( tid , log_fd);
tad_file_name = pre_install_search_tid( tid , log_fd, &is_in_sd);
if( tad_file_name ) {
if( FALSE == myImportTad( tad_file_name , log_fd) ) {
if( is_in_sd == TRUE ) {
ret_flag = myImportTad_sign( tad_file_name , version, log_fd);
}
else {
ret_flag = myImportTad( tad_file_name , version, log_fd);
}
if( FALSE == ret_flag ) {
miya_log_fprintf(log_fd, "NG.\n");
m_set_palette(tc[0], M_TEXT_COLOR_RED ); /* green */
mprintf("NG.\n");
@ -705,173 +967,3 @@ BOOL pre_install_process( FSFile *log_fd, MY_USER_APP_TID *title_id_buf_ptr, int
(void)pre_install_discard_list();
return ret_flag;
}
#if 0
// リージョンコード
typedef enum OSTWLRegionCode
{
OS_TWL_REGION_JAPAN = 0,
OS_TWL_REGION_AMERICA = 1,
OS_TWL_REGION_EUROPE = 2,
OS_TWL_REGION_AUSTRALIA = 3,
OS_TWL_REGION_CHINA = 4,
OS_TWL_REGION_KOREA = 5,
OS_TWL_REGION_MAX
} OSTWLRegion;
// 言語設定コード
typedef enum LCFGTWLCountryCode
{
LCFG_TWL_COUNTRY_UNDEFINED = 0, // 未設定
// JPNリージョン
LCFG_TWL_COUNTRY_JAPAN = 1, // 日本
// USAリージョン
LCFG_TWL_COUNTRY_Anguilla = 8, // アンギラ
LCFG_TWL_COUNTRY_ANTIGUA_AND_BARBUDA, // アンティグア・バーブーダ
LCFG_TWL_COUNTRY_ARGENTINA = 10, // アルゼンチン
LCFG_TWL_COUNTRY_ARUBA, // アルバ
LCFG_TWL_COUNTRY_BAHAMAS, // バハマ
LCFG_TWL_COUNTRY_BARBADOS, // バルバドス
LCFG_TWL_COUNTRY_BELIZE, // ベリーズ
LCFG_TWL_COUNTRY_BOLIVIA, // ボリビア
LCFG_TWL_COUNTRY_BRAZIL, // ブラジル
LCFG_TWL_COUNTRY_BRITISH_VIRGIN_ISLANDS, // 英領ヴァージン諸島
LCFG_TWL_COUNTRY_CANADA, // カナダ
LCFG_TWL_COUNTRY_CAYMAN_ISLANDS, // ケイマン諸島
LCFG_TWL_COUNTRY_CHILE = 20, // チリ
LCFG_TWL_COUNTRY_COLOMBIA, // コロンビア
LCFG_TWL_COUNTRY_COSTA_RICA, // コスタリカ
LCFG_TWL_COUNTRY_DOMINICA, // ドミニカ国
LCFG_TWL_COUNTRY_DOMINICAN_REPUBLIC, // ドミニカ共和国
LCFG_TWL_COUNTRY_ECUADOR, // エクアドル
LCFG_TWL_COUNTRY_EL_SALVADOR, // エルサルバドル
LCFG_TWL_COUNTRY_FRENCH_GUIANA, // フランス領ギアナ
LCFG_TWL_COUNTRY_GRENADA, // グレナダ
LCFG_TWL_COUNTRY_GUADELOUPE, // グアドループ
LCFG_TWL_COUNTRY_GUATEMALA = 30, // グアテマラ
LCFG_TWL_COUNTRY_GUYANA, // ガイアナ
LCFG_TWL_COUNTRY_HAITI, // ハイチ
LCFG_TWL_COUNTRY_HONDURAS, // ホンジュラス
LCFG_TWL_COUNTRY_JAMAICA, // ジャマイカ
LCFG_TWL_COUNTRY_MARTINIQUE, // マルティニーク
LCFG_TWL_COUNTRY_MEXICO, // メキシコ
LCFG_TWL_COUNTRY_MONTSERRAT, // モントセラト
LCFG_TWL_COUNTRY_NETHERLANDS_ANTILLES, // オランダ領アンティル
LCFG_TWL_COUNTRY_NICARAGUA, // ニカラグア
LCFG_TWL_COUNTRY_PANAMA = 40, // パナマ
LCFG_TWL_COUNTRY_PARAGUAY, // パラグアイ
LCFG_TWL_COUNTRY_PERU, // ペルー
LCFG_TWL_COUNTRY_ST_KITTS_AND_NEVIS, // セントキッツ・ネイビス
LCFG_TWL_COUNTRY_ST_LUCIA, // セントルシア
LCFG_TWL_COUNTRY_ST_VINCENT_AND_THE_GRENADINES, // セントビンセント・グレナディーン
LCFG_TWL_COUNTRY_SURINAME, // スリナム
LCFG_TWL_COUNTRY_TRINIDAD_AND_TOBAGO, // トリニダード・トバゴ
LCFG_TWL_COUNTRY_TURKS_AND_CAICOS_ISLANDS, // タークス・カイコス諸島
LCFG_TWL_COUNTRY_UNITED_STATES, // アメリカ
LCFG_TWL_COUNTRY_URUGUAY = 50, // ウルグアイ
LCFG_TWL_COUNTRY_US_VIRGIN_ISLANDS, // 米領バージン諸島
LCFG_TWL_COUNTRY_VENEZUELA, // ベネズエラ
// EUR, NAL リージョン
LCFG_TWL_COUNTRY_ALBANIA = 64, // アルバニア
LCFG_TWL_COUNTRY_AUSTRALIA, // オーストラリア
LCFG_TWL_COUNTRY_AUSTRIA, // オーストリア
LCFG_TWL_COUNTRY_BELGIUM, // ベルギー
LCFG_TWL_COUNTRY_BOSNIA_AND_HERZEGOVINA, // ボスニア・ヘルツェゴビナ
LCFG_TWL_COUNTRY_BOTSWANA, // ボツワナ
LCFG_TWL_COUNTRY_BULGARIA = 70, // ブルガリア
LCFG_TWL_COUNTRY_CROATIA, // クロアチア
LCFG_TWL_COUNTRY_CYPRUS, // キプロス
LCFG_TWL_COUNTRY_CZECH_REPUBLIC, // チェコ
LCFG_TWL_COUNTRY_DENMARK, // デンマーク
LCFG_TWL_COUNTRY_ESTONIA, // エストニア
LCFG_TWL_COUNTRY_FINLAND, // フィンランド
LCFG_TWL_COUNTRY_FRANCE, // フランス
LCFG_TWL_COUNTRY_GERMANY, // ドイツ
LCFG_TWL_COUNTRY_GREECE, // ギリシャ
LCFG_TWL_COUNTRY_HUNGARY = 80, // ハンガリー
LCFG_TWL_COUNTRY_ICELAND, // アイスランド
LCFG_TWL_COUNTRY_IRELAND, // アイルランド
LCFG_TWL_COUNTRY_ITALY, // イタリア
LCFG_TWL_COUNTRY_LATVIA, // ラトビア
LCFG_TWL_COUNTRY_LESOTHO, // レソト
LCFG_TWL_COUNTRY_LIECHTENSTEIN, // リヒテンシュタイン
LCFG_TWL_COUNTRY_LITHUANIA, // リトアニア
LCFG_TWL_COUNTRY_LUXEMBOURG, // ルクセンブルク
LCFG_TWL_COUNTRY_MACEDONIA, // マケドニア
LCFG_TWL_COUNTRY_MALTA = 90, // マルタ
LCFG_TWL_COUNTRY_MONTENEGRO, // モンテネグロ
LCFG_TWL_COUNTRY_MOZAMBIQUE, // モザンビーク
LCFG_TWL_COUNTRY_NAMIBIA, // ナミビア
LCFG_TWL_COUNTRY_NETHERLANDS, // オランダ
LCFG_TWL_COUNTRY_NEW_ZEALAND, // ニュージーランド
LCFG_TWL_COUNTRY_NORWAY, // ノルウェー
LCFG_TWL_COUNTRY_POLAND, // ポーランド
LCFG_TWL_COUNTRY_PORTUGAL, // ポルトガル
LCFG_TWL_COUNTRY_ROMANIA, // ルーマニア
LCFG_TWL_COUNTRY_RUSSIA = 100, // ロシア
LCFG_TWL_COUNTRY_SERBIA, // セルビア
LCFG_TWL_COUNTRY_SLOVAKIA, // スロバキア
LCFG_TWL_COUNTRY_SLOVENIA, // スロベニア
LCFG_TWL_COUNTRY_SOUTH_AFRICA, // 南アフリカ
LCFG_TWL_COUNTRY_SPAIN, // スペイン
LCFG_TWL_COUNTRY_SWAZILAND, // スワジランド
LCFG_TWL_COUNTRY_SWEDEN, // スウェーデン
LCFG_TWL_COUNTRY_SWITZERLAND, // スイス
LCFG_TWL_COUNTRY_TURKEY, // トルコ
LCFG_TWL_COUNTRY_UNITED_KINGDOM = 110, // イギリス
LCFG_TWL_COUNTRY_ZAMBIA, // ザンビア
LCFG_TWL_COUNTRY_ZIMBABWE, // ジンバブエ
// TWNリージョン
LCFG_TWL_COUNTRY_TAIWAN = 128, // 台湾
// KORリージョン
LCFG_TWL_COUNTRY_SOUTH_KOREA = 136, // 韓国
// HKGリージョンWiiの国リストに存在
LCFG_TWL_COUNTRY_HONG_KONG = 144, // ホンコン
LCFG_TWL_COUNTRY_MACAU, // マカオ
// ASIリージョンWiiの国リストに存在
LCFG_TWL_COUNTRY_INDONESIA = 152, // インドネシア
// USAリージョン
LCFG_TWL_COUNTRY_SINGAPORE = 153, // シンガポール
// ASIリージョン再び
LCFG_TWL_COUNTRY_THAILAND = 154, // タイ
LCFG_TWL_COUNTRY_PHILIPPINES, // フィリピン
LCFG_TWL_COUNTRY_MALAYSIA, // マレーシア
// 未定義リージョンIQueリージョン
LCFG_TWL_COUNTRY_CHINA = 160, // 中国
// USAリージョン
LCFG_TWL_COUNTRY_UAE = 168, // アラブ首長国連邦
// 未定義リージョン
LCFG_TWL_COUNTRY_INDIA = 169, // インド
LCFG_TWL_COUNTRY_EGYPT = 170, // エジプト
LCFG_TWL_COUNTRY_OMAN, // オマーン
LCFG_TWL_COUNTRY_QATAR, // カタール
LCFG_TWL_COUNTRY_KUWAIT, // クウェート
LCFG_TWL_COUNTRY_SAUDI_ARABIA, // サウジアラビア
LCFG_TWL_COUNTRY_SYRIA, // シリア
LCFG_TWL_COUNTRY_BAHRAIN, // バーレーン
LCFG_TWL_COUNTRY_JORDAN, // ヨルダン
LCFG_TWL_COUNTRY_OTHERS = 254,
LCFG_TWL_COUNTRY_UNKNOWN = 255,
LCFG_TWL_COUNTRY_MAX
} LCFGTWLCountryCode;
#endif

View File

@ -16,13 +16,13 @@ extern "C" {
#endif
BOOL pre_install_Cleanup_User_Titles( FSFile *log_fd );
BOOL pre_install_load_file(char *path, FSFile *log_fd);
char *pre_install_search_tid(u64 tid, FSFile *log_fd);
BOOL pre_install_discard_list(void);
BOOL pre_install_process( FSFile *log_fd, MY_USER_APP_TID *title_id_buf_ptr, int tile_id_count,
u64 *ticket_id_array, int ticket_id_count ,BOOL development_version_flag );
BOOL pre_install_check_download_or_pre_install(u64 tid, int *flag, FSFile *log_fd);
void pre_install_print_list(FSFile *log_fd);
BOOL pre_install_get_version(u64 tid, u16 *version);
BOOL pre_install_debug(FSFile *log_fd, BOOL development_version_flag );
BOOL pre_install_command(FSFile *log_fd, u64 *tid_array, int tid_count, int command, BOOL development_version_flag );
#ifdef __cplusplus

View File

@ -90,12 +90,9 @@ static u8 strm_rbuf[STRM_BUF_SIZE] ATTRIBUTE_ALIGN(32);
static u8 strm_tmp[STRM_BUF_PAGESIZE * 2] ATTRIBUTE_ALIGN(32);
// ファイル名
//const char filename2[] = "kart_title.32.wav";
//const char filename1[] = "fanfare.32.wav";
const char filename0[] = "cursor.wav";
const char filename1[] = "ok.wav";
const char filename2[] = "ng.wav";
//const char filename3[] = "fanfare.32.wav";
static StreamInfo strm;

View File

@ -27,7 +27,9 @@ SRCS = main.c mfiler.c key.c font.c text.c mprintf.c logprintf.c \
hatamotolib.cpp miya_mcu.c error_report.c \
sitedefs.c wcm_control.c netconnect.c mywlan.c \
mynuc.c nuc_error_msg.c stream.c myfilename.c menu_version.c \
ntp.c myimport.c pre_install.c
ntp.c myimport.c pre_install.c \
my_rsa_sign.c my_aes.c my_sign.c
TARGET_BIN = copy_dst.srl
ROM_SPEC = copy_dst.rsf

View File

@ -855,6 +855,9 @@ static BOOL DownloadTitles(MY_USER_APP_TID* pTitleIds, u32 numTitleIds)
return ret_flag;
}
//int ECDownload(const NAMTitleId* pTitleIds, u32 numTitleIds)
int ECDownload(MY_USER_APP_TID *pTitleIds, u32 numTitleIds)
{
@ -911,6 +914,7 @@ int ECDownload(MY_USER_APP_TID *pTitleIds, u32 numTitleIds)
miya_log_fprintf(log_fd, " already registered. please delete acount.\n");
return ECDOWNLOAD_FAILURE;
}
else if( (status != 'P') && (status != 'T') ) {
m_set_palette(tc[0], M_TEXT_COLOR_RED );
mprintf("NG.\n");
@ -1011,6 +1015,315 @@ int ECDownload(MY_USER_APP_TID *pTitleIds, u32 numTitleIds)
}
static BOOL DownloadTitles_Auto(MY_USER_APP_TID* pTitleIds, u32 numTitleIds)
{
s32 progress;
NAMTitleId tid;
BOOL ret_flag = TRUE;
// ECDL_LOG("download");
char game_code_buf[5];
for( u32 i = 0; i < numTitleIds; i++ ) {
// tid = pTitleIds[i];
if( pTitleIds[i].is_personalized == 1 ) {
/*
personalized ticketのときは何もしない
pTitleIds[i].is_personalized = 1 -> common
pTitleIds[i].is_personalized = 2 -> personalized
*/
}
else {
tid = pTitleIds[i].tid;
/*
typedef struct {
char amount [EC_AMOUNT_BUF_SIZE];
char currency[EC_CURRENCY_BUF_SIZE];
} ECMoney;
typedef ECMoney ECPrice;
typedef struct
{
// The id should be set to empty string
// (i.e., id[0] = 0;) to use the default
// account for the device. When id[0] == 0,
// the device accountId and deviceToken are used.
char id[EC_ACCOUNT_ID_BUF_SIZE];
char password[EC_ACCOUNT_PW_BUF_SIZE];
} ECAccountPayment;
typedef struct {
u32 code; // limit algorithm
u32 limit; // and limit
u32 consumed;
s32 hasConsumption;
} ECTitleLimit;
function getTitleLimits()
{
// Examples of using ECTitleLimit and ECTitleLimits
// /**********
var limits = new ECTitleLimits ();
limits.set(0, "TR", 60*60*24*31); // 31 days
limits.set(1, "LR", 10); // 10 launches
limits.set("1", "LR", "10"); // 10 launches
limits.set(8, "TR", 60*60*24*31); // invalid index
showLimits (limits);
// or
var limits2 = new ECTitleLimits ();
setTitleLimits (limits2); // passes obj by reference
showLimits (limits2);
// or
var limits3 = getTitleLimits2()
showLimits (limits3);
// or
var no_limits = new ECTitleLimits (); // default is PR
return no_limits;
}
{
var downloadContent = true;
var itemId = "109792"; // lab7
var amount = "0";
var currency = "POINTS"
var price = new ECPrice (amount, currency);
var payment = new ECAccountPayment(); // buy with points
var limits = getTitleLimits();
var purchaseInfo = null;
var taxes = null;
var discount = null;
var progress = ec.purchaseTitle (titleId, itemId,
price, payment,
limits,
downloadContent, // optional
taxes, // optional
purchaseInfo, // optional
discount); // optional
s32 EC_PurchaseTitleEx (ESTitleId titleId,
s32 itemId,
ECPrice price,
const ECPayment *payment,
const ESLpEntry *limits,
u32 nLimits,
s32 downloadContent,
const char* taxes,
const char* purchaseInfo,
const char* discount);
s32 EC_PurchaseTitle (ESTitleId titleId,
s32 itemId,
s32 points,
const ESLpEntry *limits,
u32 nLimits);
*/
progress = EC_DownloadTitle(tid, EC_DT_UPDATE_REQUIRED_CONTENTS);
// mprintf("-check registration.. ");
(void)my_fs_Tid_To_GameCode((u64)tid, game_code_buf);
game_code_buf[4] = '\0';
mprintf(" downloading.. [%s] ", game_code_buf);
if( FALSE == WaitEC_with_NG_print(progress) ) {
/* EC_ERROR_NET_CONTENTはずすエラーにせずにバックアップだけ復活してやるか */
miya_log_fprintf(log_fd, " %s download NG.\n",game_code_buf);
ret_flag = FALSE;
}
else {
pTitleIds[i].install_success_flag = TRUE;
m_set_palette(tc[0], M_TEXT_COLOR_GREEN ); /* green */
mprintf("OK.\n");
m_set_palette(tc[0], M_TEXT_COLOR_WHITE );
miya_log_fprintf(log_fd, " %s download OK.\n",game_code_buf);
}
}
}
return ret_flag;
}
int ECDownload_Auto(MY_USER_APP_TID *pTitleIds, u32 numTitleIds)
{
char challenge[EC_CHALLENGE_BUF_SIZE];
char status;
// BOOL ret_flag;
STD_MemSet((void *)challenge,(int)0, EC_CHALLENGE_BUF_SIZE);
/*********************************/
mprintf("-check registration.. ");
miya_log_fprintf(log_fd, "-check registration...");
if( FALSE == CheckRegistration( &status ) ) {
return ECDOWNLOAD_FAILURE;
}
// U unregistered
// R registered
// P pending
// T transfered
if( status == '\0' ) {
miya_log_fprintf(log_fd, "NG.\n");
m_set_palette(tc[0], M_TEXT_COLOR_RED );
mprintf("NG.\n");
m_set_palette(tc[0], M_TEXT_COLOR_WHITE );
mprintf(" my error.\n");
miya_log_fprintf(log_fd, " my error.\n");
return ECDOWNLOAD_FAILURE;
}
else if( status == 'U') {
miya_log_fprintf(log_fd, "NG.\n");
m_set_palette(tc[0], M_TEXT_COLOR_RED );
mprintf("NG.\n");
m_set_palette(tc[0], M_TEXT_COLOR_YELLOW );
mprintf(" acount not transfered yet.\n");
// mprintf(" OR, acount already cleared\n\n");
m_set_palette(tc[0], M_TEXT_COLOR_WHITE );
miya_log_fprintf(log_fd, " acount not transfered yet.\n");
// miya_log_fprintf(log_fd, " OR acount already cleared by user.\n");
// 「ご利用記録の削除」をした場合、ここでエラーになる。
// ここでOKにする?
return ECDOWNLOAD_FAILURE;
// return ECDOWNLOAD_NO_REGISTER;
}
else if( status == 'R') {
/* auto_pre_install のときだけ外す? */
/* miya 2009/06/09 */
goto ok_label;
miya_log_fprintf(log_fd, "NG.\n");
m_set_palette(tc[0], M_TEXT_COLOR_RED );
mprintf("NG.\n");
m_set_palette(tc[0], M_TEXT_COLOR_YELLOW );
mprintf(" already registered.\n please delete acount.\n");
m_set_palette(tc[0], M_TEXT_COLOR_WHITE );
miya_log_fprintf(log_fd, " already registered. please delete acount.\n");
return ECDOWNLOAD_FAILURE;
}
else if( (status != 'P') && (status != 'T') ) {
m_set_palette(tc[0], M_TEXT_COLOR_RED );
mprintf("NG.\n");
m_set_palette(tc[0], M_TEXT_COLOR_YELLOW );
mprintf(" invalid registration status '%c'\n", status );
m_set_palette(tc[0], M_TEXT_COLOR_WHITE );
miya_log_fprintf(log_fd, " invalid registration status '%c'\n", status );
return ECDOWNLOAD_FAILURE;
}
else {
ok_label:
miya_log_fprintf(log_fd, "OK.\n");
m_set_palette(tc[0], M_TEXT_COLOR_GREEN );
mprintf("OK.\n");
m_set_palette(tc[0], M_TEXT_COLOR_WHITE );
}
#if 0 /* miya 2009/06/09 */
/*********************************/
miya_log_fprintf(log_fd, "-get challenge1..");
mprintf("-get challenge1 ");
if( FALSE == GetChallenge(challenge) ) {
return ECDOWNLOAD_FAILURE;
}
else {
miya_log_fprintf(log_fd, "OK.\n");
m_set_palette(tc[0], M_TEXT_COLOR_GREEN );
mprintf("OK.\n");
m_set_palette(tc[0], M_TEXT_COLOR_WHITE );
}
/*********************************/
miya_log_fprintf(log_fd, "-transfer.. ");
mprintf("-transfer ");
if( FALSE == Transfer(challenge) ) {
return ECDOWNLOAD_FAILURE;
}
else {
miya_log_fprintf(log_fd, "OK.\n");
m_set_palette(tc[0], M_TEXT_COLOR_GREEN ); /* green */
mprintf("OK.\n");
m_set_palette(tc[0], M_TEXT_COLOR_WHITE );
}
#endif
/*********************************/
miya_log_fprintf(log_fd, "-get challenge.. ");
mprintf("-get challenge2 ");
if( FALSE == GetChallenge(challenge) ) {
return ECDOWNLOAD_FAILURE;
}
else {
miya_log_fprintf(log_fd, "OK.\n");
m_set_palette(tc[0], M_TEXT_COLOR_GREEN ); /* green */
mprintf("OK.\n");
m_set_palette(tc[0], M_TEXT_COLOR_WHITE );
}
/*********************************/
miya_log_fprintf(log_fd, "-sync registration..");
mprintf("-sync registration ");
if( FALSE == SyncRegistration(challenge) ) {
return ECDOWNLOAD_FAILURE;
}
else {
miya_log_fprintf(log_fd, "OK.\n");
m_set_palette(tc[0], M_TEXT_COLOR_GREEN ); /* green */
mprintf("OK.\n");
m_set_palette(tc[0], M_TEXT_COLOR_WHITE );
}
/*********************************/
miya_log_fprintf(log_fd, "-sync tickets..");
mprintf("-sync tickets ");
if( FALSE == SyncTickets() ) {
return ECDOWNLOAD_FAILURE;
}
else {
miya_log_fprintf(log_fd, "OK.\n");
m_set_palette(tc[0], M_TEXT_COLOR_GREEN ); /* green */
mprintf("OK.\n");
m_set_palette(tc[0], M_TEXT_COLOR_WHITE );
}
/*********************************/
// ここでアプリをダウンロードしている
miya_log_fprintf(log_fd, "-download titles\n");
mprintf("-download titles\n");
if( FALSE == DownloadTitles_Auto(pTitleIds, numTitleIds) ) {
return ECDOWNLOAD_FAILURE;
}
//#define ECDOWNLOAD_DUMMY 0
//#define ECDOWNLOAD_SUCCESS 1
//#define ECDOWNLOAD_NO_REGISTER 2
//#define ECDOWNLOAD_FAILURE 3
return ECDOWNLOAD_SUCCESS;
}
BOOL KPSClient()
{
s32 progress;

View File

@ -13,6 +13,7 @@ extern "C" {
// int ECDownload(const NAMTitleId* pTitleIds, u32 numTitleIds);
int ECDownload(MY_USER_APP_TID * pTitleIds, u32 numTitleIds);
int ECDownload_Auto(MY_USER_APP_TID *pTitleIds, u32 numTitleIds);
BOOL KPSClient();
// BOOL WaitEC(ECOpId opId);

View File

@ -1611,6 +1611,7 @@ void TwlMain(void)
Gfx_Set_BG1_line_Color(1, 2, (u16)M_TEXT_COLOR_ORANGE);
while( 1 ) {
Gfx_Render( vram_num_main , vram_num_sub );
OS_WaitVBlankIntr();
@ -1664,22 +1665,7 @@ void TwlMain(void)
MydataLoadDecrypt_dir_flag = TRUE;
MydataLoadDecrypt_success_flag = TRUE;
#if 1
start_my_thread( THREAD_COMMAND_WIFI_FUNCTION );
#else
if( TRUE == RestoreFromSDCard3() ) {
if( TRUE == stream_play_is_end() ) {
stream_play1(); /* ok.aiff */
}
Gfx_Set_BG1_Color((u16)M_TEXT_COLOR_DARKGREEN);
}
else {
if( TRUE == stream_play_is_end() ) {
stream_play2(); /* ng.aiff */
}
Gfx_Set_BG1_Color((u16)M_TEXT_COLOR_DARKRED);
}
#endif
}
else if( user_and_wifi_config_data_trans_flag == TRUE ) {
/* ユーザー設定と無線設定のみリストアする */
@ -1689,22 +1675,8 @@ void TwlMain(void)
MydataLoadDecrypt_message_flag = TRUE;
MydataLoadDecrypt_dir_flag = TRUE;
MydataLoadDecrypt_success_flag = TRUE;
#if 1
start_my_thread( THREAD_COMMAND_USERDATA_AND_WIFI_FUNCTION );
#else
if( (TRUE == RestoreFromSDCard4()) && (TRUE == RestoreFromSDCard3() ) ) {
if( TRUE == stream_play_is_end() ) {
stream_play1(); /* ok.aiff */
}
Gfx_Set_BG1_Color((u16)M_TEXT_COLOR_DARKGREEN);
}
else {
if( TRUE == stream_play_is_end() ) {
stream_play2(); /* ng.aiff */
}
Gfx_Set_BG1_Color((u16)M_TEXT_COLOR_DARKRED);
}
#endif
}
else {
mprintf("Personal data. restore ");

View File

@ -100,7 +100,10 @@ static LCFGTWLHWSecureInfo hws_info;
#define NAM_TITLE_ID_S 128
static NAMTitleId array_eticket_only_titles[NAM_TITLE_ID_S];
// static int array_eticket_only_titles_version[NAM_TITLE_ID_S];
static NAMTitleId array_app_titles[NAM_TITLE_ID_S];
// static int array_app_titles_version[NAM_TITLE_ID_S];
static int num_of_eticket_only_titles = 0;
static int num_of_app_titles = 0;
static int num_of_all_titles = 0;
@ -167,6 +170,7 @@ static int Check_User_Titles_ETicket_Only(void)
u64 id;
char game_code[5];
int common_or_personalized_flag;
// u16 version = 0;
// num = NAM_GetNumTitles();
num = NAM_GetNumInstalledTitles();
@ -216,15 +220,20 @@ static int Check_User_Titles_ETicket_Only(void)
if( common_or_personalized_flag == 1 ) {
OS_TPrintf(" usr.:%3d:0x%llx %s common\n", i, id, game_code);
array_eticket_only_titles[user_title_count] = id;
#if 0
if( TRUE == pre_install_get_version(id, &version) ) {
array_eticket_only_titles_version[user_title_count] = (int)version;
}
else {
array_eticket_only_titles_version[user_title_count] = -1;
}
#endif
user_title_count++;
}
else {
OS_TPrintf(" usr.:%3d:0x%llx %s personalized\n", i, id, game_code);
}
}
}
}
}
@ -247,6 +256,7 @@ static int Check_User_Titles(void)
int user_tilte_count = 0;
u64 id;
char game_code[5];
// u16 version;
num = NAM_GetNumTitles();
if( num >= 0 ) {
@ -283,6 +293,14 @@ static int Check_User_Titles(void)
OS_TPrintf(" usr.:%3d:0x%llx %s\n", i, id, game_code);
user_tilte_count++;
}
#if 0
if( TRUE == pre_install_get_version(id, &version) ) {
array_app_titles_version[i] = (int)version;
}
else {
array_app_titles_version[i] = -1;
}
#endif
}
}
else {
@ -545,6 +563,7 @@ static BOOL SDBackupToSDCard7(void)
int j;
BOOL flag = TRUE;
int common_or_presonalized_flag;
u16 version;
/* ƒ^ƒCƒgƒƒŠƒXƒgÌ<E2809A><EFBFBD>¬ */
/*
@ -618,6 +637,20 @@ static BOOL SDBackupToSDCard7(void)
}
if( TRUE == pre_install_check_download_or_pre_install(ptr->tid, &common_or_presonalized_flag, NULL) ) {
if( TRUE == pre_install_get_version(ptr->tid, &version) ) {
ptr->version = (int)version;
}
else {
ptr->version = -1;
}
OS_TPrintf(" ver.%d",ptr->version);
mfprintf(tc[2]," ver.%d",ptr->version);
if( no_sd_clean_flag == TRUE ) {
mprintf(" ver.%d",ptr->version);
}
ptr->is_personalized = common_or_presonalized_flag;
if( ptr->is_personalized == 1 ) {
OS_TPrintf(" common");

View File

@ -0,0 +1,46 @@
PACKAGE = cryptopc
OPENSSL_DIR = c:/OpenSSL/openssl-1.0.0-beta2
# SRCS = main.c
SRCS = m.c
HEADS = my_sign.h
OBJS = $(SRCS:.c=.o)
CC := C:/Cygwin/bin/gcc
CFLAGS = -mno-cygwin -Wall
# openssl-1.0.0-beta2
CPPFLAGS= -I. -I$(OPENSSL_DIR)/include -I$(OPENSSL_DIR)/crypto/ec
LD = C:/Cygwin/bin/gcc
LDFLAGS = -Wl,--subsystem,console -mwindows -mno-cygwin -L$(OPENSSL_DIR)
LDLIBS = -lcrypto -lssl
.SUFFIXES:
.SUFFIXES: .o .c
all: $(PACKAGE)
# 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

View File

@ -0,0 +1,455 @@
/* cryptopc *.der infile outfile
cryptopc miya1024.der main.c main.enc
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <conio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <openssl/err.h>
#include <openssl/rsa.h>
#include <openssl/aes.h>
#include <openssl/pem.h>
#include <openssl/sha.h>
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"
/*
RSAがバイトなんでバイト
/ 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;
static int my_sign_make(MY_SIGN_SIGNATURE *encrypted_sign, u8 *buf, int buf_size)
{
MY_SIGN_SIGNATURE temp_sign;
int outlen = 0;
RSA *rsa_key;
// int i;
if( 0 != fseek(fp_key, 0 , SEEK_SET) ) {
fprintf(stderr,"fseek error %s %d\n",__FUNCTION__,__LINE__);
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 {
fprintf(stderr, "Error:d2i_RSAPrivateKey_fp(read key) NULL!\n");
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 1
if(rsaSize != (outlen = RSA_public_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;
}
#else
if(rsaSize != (outlen = RSA_public_encrypt(rsaSize, (u8 *)&temp_sign, (u8 *)encrypted_sign,
rsa_key, RSA_NO_PADDING ))) {
fprintf(stderr,"encrypt error rsaSize=%d outlen=%d\n",rsaSize, outlen);
return -1;
}
#endif
RSA_free(rsa_key);
return 0;
}
int main(int ac, char *argv[])
{
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 ];
printf("hash offset = %d\n",offsetof(MY_SIGN_SIGNATURE, hash));
ERR_load_crypto_strings();
if( ac == 4 ) {
if( 0 != stat( argv[2], &st_buf) ) {
fprintf(stderr, "failed to stat %s\n",argv[2]);
goto end;
}
if( (fp_key = fopen( argv[1], "rb" )) == NULL ) {
fprintf(stderr, "failed to fopen %s\n",argv[1]);
goto end;
}
else {
#if 0
rsa_key = RSA_new();
if( rsa_key == NULL ) {
fprintf(stdout,"Error:RSA_new(key alloc) NULL!\n");
}
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 {
fprintf(stderr, "Error:d2i_RSAPrivateKey_fp(read key) NULL!\n");
goto end;
}
#endif
}
if( (fp_in = fopen( argv[2], "rb" )) == NULL ) {
fprintf(stderr, "Error:failed to fopen input file(%s)\n",argv[2]);
goto end;
}
if( (fp_out = fopen( argv[3], "wb+" )) == NULL ) {
fprintf(stderr, "failed to fopen output file(%s)\n",argv[3]);
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__);
goto end;
}
memset(L2_sign_table, 0 , L2_sign_table_size );
L2_sign_table_temp = L2_sign_table;
#if 1
if( 0 != fseek(fp_out, header.file_offset_data_block , SEEK_SET) ) {
fprintf(stderr,"fseek error %s %d\n",__FUNCTION__,__LINE__);
goto end;
}
#else
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テーブルを出力ファイルに書き込み */
#endif
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] = (u8)i;
}
AES_set_encrypt_key(aes_key_buf, AES_KEY_BIT_LEN, &aes_key);
for( i = 0 ; i < AES_BLOCK_SIZE ; i++ ) {
aes_iv[i] = (u8)i;
}
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++;
}
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( fp_key ) {
fclose(fp_key);
}
if( rsa_error_flag == 0 ) {
printf("success\n");
}
// fprintf(stderr,"Invalid argument!\n");
// fprintf(stderr,"Usage: %s\n", argv[0]);
// fprintf(stderr,"Usage: %s SerialNo.(32bit) filename.dat\n", argv[0]);
}
return 0;
}

View File

@ -1,12 +1,6 @@
/*
gcc -mwindows -Wl,--subsystem,console -mno-cygwin -o titleidchecker titleidchecker.c
titleidchecker TWL-HNGJ-v256.tad.out
titleidchecker nandAppSample.tad
Makefile.TadIncludesも作る
[ROMp] make_tad_table.exe -dir . -o table_file.txt -var MAKEROM_TAD_ROMFILES -fdir tads -mk Makefile.inc
[SDp] make_tad_table.exe -dir . -o table_file.txt -fdir tads_sd
*/
#include <stdio.h>