#include #include #include #include #include #ifdef DEV_CYGWIN #include #else // Cygwin #include #include #endif // Linux #include #include #include "cr_generate_id.h" #include "cr_generate_id_private.h" #include "cr_alloc.h" extern int crypto_aes_dec( unsigned char *dst_buf, unsigned char *org_buf, u8 bonding_option ); int main(int argc, char *argv[]) { int ret_code = 0; int fileLen; int bondingOption = 0; u8 *pFileBuf = NULL; u8 err_buf[ 256 ]; if( argc < 3 ) { printf( "parameter error.\n" ); printf( "Usage: testSharpID.exe [bondingOption] [FILE]\n" ); return 1; } // ボンディングオプション読み込み bondingOption = atoi( argv[ 1 ] ); printf( "bondingOption = %d\n", bondingOption ); // eFuseIDサンプルファイル読み込み { FILE *fp; int readLen; struct stat fileStat; if( stat( argv[2], &fileStat ) || !S_ISREG( fileStat.st_mode ) ) { ret_code = 1; goto end; } fileLen = fileStat.st_size; if ( fileLen < 0 ) { ret_code = 1; goto end; } pFileBuf = malloc( fileLen ); if( pFileBuf == NULL ) { ret_code = 1; goto end; } memset( pFileBuf, 0, fileLen ); fp = fopen( argv[2], "rb" ); if( fp == NULL ) { fprintf( stderr, "failed to fopen %s\n", argv[2] ); } // 先頭2行を読み捨て if( fgets( pFileBuf, 1024, fp ) != NULL ) { fileLen -= strlen( pFileBuf ); } if( fgets( pFileBuf, 1024, fp ) != NULL ) { fileLen -= strlen( pFileBuf ); } // 実データ部分の読み込み readLen = fread( pFileBuf, 1, fileLen, fp ); fclose( fp ); if( readLen < fileLen ) { ret_code = 1; printf( "read error %x\n", readLen ); goto end; } } // cr_generate_id を使用する前に呼び出す ret_code = cr_generate_id_initialize( err_buf ); if ( ret_code != CR_GENID_SUCCESS ) { printf( "error : cr_generate_id_initialize\n" ); return 0; // error } // ファイルの内容を各eFuseIDに分解して、検証 { int completeLen = 0; int index = 0; int i; int serial[ 5 ]; u8 enc_buf[ sizeof(CR_ID_BUFFER) ]; u8 dec_buf[ sizeof(CR_ID_BUFFER) ]; char *pFile = pFileBuf; char *pEnc = (char *)enc_buf; while( 1 ) { int num; int temp; EC_KEY *deviceKeyPair = NULL; memset( serial, 0, sizeof(serial) ); memset( enc_buf, 0, sizeof(enc_buf) ); if( ( num = sscanf( pFile, "%08x, %08x %08x, %08x %08x, ", &serial[0], &serial[2], &serial[1], &serial[4], &serial[3] ) ) < 5 ) { printf( "sscanf NG.\n" ); ret_code = 2; break; } pFile += 48; for( i = 0; i < sizeof(CR_ID_BUFFER); i++ ) { if( sscanf( pFile, "%02x", &temp ) == 0 ) { ret_code = 2; printf( "sscanf 2 NG.\n" ); goto end; } pEnc[ i ] = (char)temp; pFile+=2; } pFile++; // \n completeLen += 48 + 512 + 1; DebugFileOutput( serial[ 0 ], "enc", pEnc, 256 ); { int i; int isFailed = 0; CR_ID_BUFFER *peFuse = (CR_ID_BUFFER *)dec_buf; u8 sha256buf[ SHA256_DIGEST_LENGTH ]; printf( "ID[ %04d ]:\n", index ); if( crypto_aes_dec( dec_buf, enc_buf, bondingOption ) != CR_GENID_SUCCESS ) { printf( " eFuse decrypto NG.\n" ); ret_code = 3; goto end; } DEBUG_PRINT_ARRAY( (char*)"dec_buf", (const char *)dec_buf, sizeof(CR_ID_BUFFER) ); // DebugFileOutput( serial[ 0 ], "raw", dec_buf, 256 ); // bondingOption チェック if( bondingOption == peFuse->bonding_option ) { printf( " bondingOption OK.\n" ); }else { printf( " bondingOption NG.\n" ); } // デバイス証明書期限の確認 { struct tm *gt = gmtime( &peFuse->expiryDate ); struct timeval tv; gettimeofday( &tv, NULL ); printf( " expiryDate : %d/%d/%d %d:%d:%d", gt->tm_year+1900, gt->tm_mon+1, gt->tm_mday, gt->tm_hour, gt->tm_min, gt->tm_sec ); if( peFuse->expiryDate >= tv.tv_sec + ( 60*60*24*365* 19 ) ) { printf( " OK.\n" ); }else { printf( " NG.\n" ); } } // serialNo. チェック for( i = 0; i < 5; i++ ) { if( serial[ i ] != peFuse->device_id[ i ] ) { isFailed = 1; printf( " serial[ %d ] NG : %08x %08x\n", i, (unsigned int)serial[ i ], (unsigned int)peFuse->device_id[ i ] ); } } if( !isFailed ) { printf( " serial OK.\n" ); } //--------------------------------------------- // openssl 使用区間 cr_mem_bufmgr_initialize(); OpenSSL_add_all_digests(); // SHA256ハッシュ チェック SHA256( dec_buf, CR_ID_BUF_SIZE - SHA256_DIGEST_LENGTH, sha256buf ); if( memcmp( peFuse->hash, sha256buf, SHA256_DIGEST_LENGTH ) == 0 ) { printf( " SHA256 hash OK.\n" ); }else { printf( " SHA256 hash NG.\n" ); } // デバイス署名のチェック ret_code = SetECCKeyPair( &deviceKeyPair, peFuse->devicePrivKey ); if ( ret_code != CR_GENID_SUCCESS ) { printf( " deviceKeyPair NG.\n" ); }else { if( CheckCTRDeviceCert( deviceKeyPair, peFuse->device_id[0], bondingOption, peFuse->deviceCertSign, peFuse->expiryDate, peFuse->version ) != CR_GENID_SUCCESS ) { printf( " deviceCert verify NG.\n" ); }else { printf( " deviceCert verify OK.\n" ); } if( deviceKeyPair ) { EC_KEY_free( deviceKeyPair ); } } ERR_remove_state(0); EVP_cleanup(); CRYPTO_cleanup_all_ex_data(); // openssl 使用区間終わり //------------------------------------------------ } if( completeLen >= fileLen ) break; index++; } } end: if( pFileBuf ) free( pFileBuf ); // cr_generate_id を使用した後に呼び出す ret_code = cr_generate_id_finalize( err_buf ); if ( ret_code != CR_GENID_SUCCESS ) { printf( "error : cr_generate_id_finalize\n" ); return 0; // error } printf("end of main\n"); return 0; }