diff --git a/trunk/cr_device_cert.c b/trunk/cr_device_cert.c index 8548ca4..adbbc88 100644 --- a/trunk/cr_device_cert.c +++ b/trunk/cr_device_cert.c @@ -146,12 +146,15 @@ u8 tempSign[ 70 ]; // TWL device cert base +// total size = 384 bytes +// fields are big-endian +//string fields are padded with zero to full size typedef struct CR_DeviceCert { u8 sigType [ 4 ]; // 0x000 - 0x003 : 0x00010005, signature type is ECDSA + SHA256 u8 eccSignature[ 60 ]; // 0x004 - 0x03F : ECDSA using SHA-256 and CA key u8 padding0 [ 64 ]; // 0x040 - 0x07F : zero-filled - u8 issuerName [ 64 ]; // 0x080 - 0x0BF : issuer name, "Root-CA00000002-MS00000008" + u8 issuerName [ 64 ]; // 0x080 - 0x0BF : issuer name, "Nintendo CA - G3_NintendoCTR2dev" or "Nintendo CA - G3_NintendoCTR2prod" u8 keyType [ 4 ]; // 0x0C0 - 0x0C3 : 0x00000002, cert public key type is ECC233 u8 subject [ 64 ]; // 0x0C4 - 0x103 : subject field, "CTxxxxxxxx-yy" u32 expiryDate; // 0x104 - 0x107 : second from Epoch (Jan 1, 1970 00:00) @@ -167,7 +170,8 @@ const u8 issuerName[] = { }; static void BN2BinWithPadding( BIGNUM *pBn, u8 *pDst, int dstLen ); -static void ConstructCTRDeviceCert( CR_DeviceCert *pDeviceCert, EC_KEY *pECkey, u8 bonding_option, u32 device_id, u32 expiryDate ); +static void ConstructCTRDeviceCert( CR_DeviceCert *pDeviceCert, EC_KEY *pECkey, u8 bonding_option, u32 device_id, u32 expiryDate, u8 eFuseVersion ); +static void SetReverseEndian( u8 *pDst, const u8 *pSrc, u32 byteLength ); // create CTR Device cert @@ -215,7 +219,7 @@ int GenerateCTRDeviceCert( EC_KEY *pECkey, u32 device_id, u8 bonding_option, u8 // expiryDate +20years *pExpiryDate += CR_CERT_EXPIRE_SECS; // ID_BUFにも証明書期限をセットする。 - deviceCert.expiryDate = *pExpiryDate; + SetReverseEndian( (u8 *)&deviceCert.expiryDate, (const u8 *)pExpiryDate, 4 ); // eccPubKey BN2BinWithPadding( &pECkey->pub_key->X, &deviceCert.eccPubKey[ 0 ], 30 ); @@ -419,7 +423,9 @@ int GenerateCTRDeviceCert( EC_KEY *pECkey, u32 device_id, u8 bonding_option, u8 printf( "expiryDate : 0x%08X\n", (unsigned int)deviceCert.expiryDate ); { struct tm *tmt; - tmt = gmtime( &deviceCert.expiryDate ); + u32 expiryDate_le; + SetReverseEndian( (u8 *)&expiryDate_le, (const u8 *)&deviceCert.expiryDate, 4 ); + tmt = gmtime( &expiryDate_le ); printf( " GMT:%d-%02d-%02d %02d:%02d:%02d\n", tmt->tm_year+1900, tmt->tm_mon+1, tmt->tm_mday, tmt->tm_hour, tmt->tm_min, tmt->tm_sec ); } @@ -455,14 +461,14 @@ static void BN2BinWithPadding( BIGNUM *pBN, u8 *pDst, int dstLen ) // eFuseIDをもとにデバイス署名のチェック -int CheckCTRDeviceCert( EC_KEY *pECkey, u32 device_id, u8 bonding_option, u8 *pDevCertSign, u32 expiryDate ) +int CheckCTRDeviceCert( EC_KEY *pECkey, u32 device_id, u8 bonding_option, u8 *pDevCertSign, u32 expiryDate, u8 eFuseVersion ) { int ret_code = CR_GENID_SUCCESS; CR_DeviceCert deviceCert; EC_KEY *NCT2 = NULL; u8 sha256Buf[ SHA256_DIGEST_LENGTH ]; - ConstructCTRDeviceCert( &deviceCert, pECkey, bonding_option, device_id, expiryDate ); + ConstructCTRDeviceCert( &deviceCert, pECkey, bonding_option, device_id, expiryDate, eFuseVersion ); // CR_DeviceCertのSHA256計算 SHA256( deviceCert.issuerName, (int)&deviceCert + sizeof(CR_DeviceCert) - (int)deviceCert.issuerName, sha256Buf ); @@ -523,7 +529,7 @@ end: // 指定パラメータをもとにデバイス証明書を構築(署名なし) -static void ConstructCTRDeviceCert( CR_DeviceCert *pDeviceCert, EC_KEY *pECkey, u8 bonding_option, u32 device_id, u32 expiryDate ) +static void ConstructCTRDeviceCert( CR_DeviceCert *pDeviceCert, EC_KEY *pECkey, u8 bonding_option, u32 device_id, u32 expiryDate, u8 eFuseVersion ) { int i; @@ -556,8 +562,11 @@ static void ConstructCTRDeviceCert( CR_DeviceCert *pDeviceCert, EC_KEY *pECkey, sprintf( pDeviceCert->subject, "CT%08X-%02X", (unsigned int)device_id, bonding_option ); // expiryDate - pDeviceCert->expiryDate = expiryDate; - + if( eFuseVersion < 5 ) { + pDeviceCert->expiryDate = expiryDate; + }else { + SetReverseEndian( (u8 *)&pDeviceCert->expiryDate, (const u8 *)&expiryDate, 4 ); + } // eccPubKey BN2BinWithPadding( &pECkey->pub_key->X, &pDeviceCert->eccPubKey[ 0 ], 30 ); BN2BinWithPadding( &pECkey->pub_key->Y, &pDeviceCert->eccPubKey[ 30 ], 30 ); @@ -565,3 +574,13 @@ static void ConstructCTRDeviceCert( CR_DeviceCert *pDeviceCert, EC_KEY *pECkey, DEBUG_PRINT_ARRAY( (char*)"deviceCert", (const char *)pDeviceCert, sizeof(CR_DeviceCert) ); } + +// エンディアンを逆転してセット +static void SetReverseEndian( u8 *pDst, const u8 *pSrc, u32 byteLength ) +{ + int i; + pSrc += byteLength - 1; + for( i = 0; i < byteLength; i++ ) { + *pDst++ = *pSrc--; + } +} diff --git a/trunk/cr_generate_id_private.h b/trunk/cr_generate_id_private.h index 543b63f..087848b 100644 --- a/trunk/cr_generate_id_private.h +++ b/trunk/cr_generate_id_private.h @@ -137,8 +137,9 @@ extern "C" { #define ENCRYPT_AES 1 // `LFIX.iꂪ`̏ꍇAID̈ÍRSAɂȂBj -#define CR_GEN_ID_VERSION 4 // V[vւ̃[XƂUPB +#define CR_GEN_ID_VERSION 5 // V[vւ̃[XƂUPB // 2010/02/02 Release ver.4 + // 2010/03/15 Release ver.5 #ifdef USE_HSM #define CR_GEN_ID_MAGICCODE 0xdeadb00f; /* ŏIIɂ͂œB0xdeadbeefɂRSAŃRPB */ #else // !USE_HSM @@ -222,7 +223,7 @@ extern void GetErrorInfo( char *stack, u8 *size ); extern int TestECDSA( EC_KEY *pECkey ); extern int GenerateCTRDeviceCert( EC_KEY *pECkey, u32 device_id, u8 bonding_option, u8 *pDevCertSign, u32 *pExpiryDate ); -extern int CheckCTRDeviceCert( EC_KEY *pECkey, u32 device_id, u8 bonding_option, u8 *pDevCertSign, u32 expiryDate ); +extern int CheckCTRDeviceCert( EC_KEY *pECkey, u32 device_id, u8 bonding_option, u8 *pDevCertSign, u32 expiryDate, u8 eFuseVersion ); extern int EncryptID( unsigned char *dst_buf, unsigned char *org_buf, u8 bonding_option ); extern void DebugPrintArray( char *pStr, const u8 *pData, int length ); extern void DebugFileOutput( u32 device_id, char *pSuffix, const u8 *pSrc, int length ); diff --git a/trunk/main2.c b/trunk/main2.c index 31da7dd..8f52e1f 100644 --- a/trunk/main2.c +++ b/trunk/main2.c @@ -201,7 +201,7 @@ int main(int argc, char *argv[]) printf( " deviceKeyPair NG.\n" ); }else { if( CheckCTRDeviceCert( deviceKeyPair, peFuse->device_id[0], bondingOption, - peFuse->deviceCertSign, peFuse->expiryDate ) != CR_GENID_SUCCESS ) { + peFuse->deviceCertSign, peFuse->expiryDate, peFuse->version ) != CR_GENID_SUCCESS ) { printf( " deviceCert verify NG.\n" ); }else { printf( " deviceCert verify OK.\n" );