ctr_eFuse/trunk/main3.c
n2460 7900fdfa34 outputSharpID:getopt でコマンドライン引数の処理を一新。
git-svn-id: file:///Volumes/Transfer/gigaleak_20231201/2020-09-30%20-%20paladin.7z/paladin/ctr_eFuse@218 ff987cc8-cf2f-4642-8568-d52cce064691
2013-06-25 06:58:53 +00:00

440 lines
12 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
testSharpID に対応したフォーマットで ID の出力を行います。
*注意1* HSM の使える環境(Linux) で出力したファイルを Windows(Cygwin) で検証する場合、
文字コードを Shift-JIS の CR+LF として解釈するためうまくいきません(2つめのレコードでコケる)
Windows 側で検証する場合は LF として保存しなおす必要があります。
*注意2*
testSharpID で検証する場合は真の鍵で行う必要があります。
そのため Makefile.testSharpID において
(1) dummyKey フォルダの dev, prod それぞれに対して
eFuse_aesKey.bin, eFuse_privKey.der, eFuse_pubKey.der を差し替える (他はそのままで OK)
(2) realKey フォルダの dev, prod それぞれに対して
eFuse_aesKey.bin, eFuse_privKey.der, eFuse_pubKey.der を置く。
dummyKey フォルダの dev, prod の NCT2_priv.der, NCT2_priv.pem, NCT2_pub.pem を置く。
上記を行った上で Makefile.testSharpID の ifeq ($(USE_DUMMY_KEY),TRUE) endif の間にある
DEV_DER_KEY_DIR = ./dummyKey/dev -> ./realKey/dev
PROD_DER_KEY_DIR = ./dummyKey/prod -> ./realKey/prod
と変更する。
のいづれかの対応をします。
*/
#define RAND_MAX 0xffffffff
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <sys/time.h>
#include <unistd.h>
#ifdef DEV_CYGWIN
#include <conio.h>
#else // Cygwin
#include <termios.h>
#endif // Linux
#include "cr_generate_id.h"
#define BONDING_OPTION_PROD 0 // 製品用ID
#define BONDING_OPTION_DEV 1 // 開発用ID
#define BONDING_OPTION_DEBUGGER 2 // デバッガ
#define DEFAULT_OUTPUT_PATH_BASE "ID"
// extern const int isDummyPrivateKey;
/*
gen_id.exe 0x01 0x02
gen_id.exe 0x01 0x02 ctrid090716.dat
gen_id.exe 0x01 0x03 ctrid090728.dat
*/
#ifndef DEV_CYGWIN
static struct termios initial_setting, new_setting;
static int peek_character = -1;
void keyboard_initialize( void )
{
tcgetattr( 0, &initial_setting );
new_setting = initial_setting;
new_setting.c_lflag &= ~ICANON;
new_setting.c_lflag &= ~ECHO;
new_setting.c_lflag &= ~ISIG;
new_setting.c_cc[VMIN] = 0;
new_setting.c_cc[VTIME] = 0;
tcsetattr( 0, TCSANOW, &initial_setting );
} // keyboard_initialize
void keyboard_finalize( void )
{
tcsetattr( 0, TCSANOW, &initial_setting );
} // keyboard_finalize
int kbhit( void )
{
char ch;
int nread;
if ( peek_character != -1 )
{
return 1;
}
new_setting.c_cc[VMIN] = 0;
tcsetattr( 0, TCSANOW, &new_setting );
nread = read( 0, &ch, 1 );
new_setting.c_cc[VMIN] = 1;
tcsetattr( 0, TCSANOW, &new_setting );
if ( nread == 1 )
{
peek_character = ch;
return 1;
}
return 0;
} // kbhit
int getch( void )
{
char ch;
if ( peek_character != -1 )
{
ch = peek_character;
peek_character = -1;
return ch;
}
read( 0, &ch, 1 );
return ch;
} // readch
#endif // DEV_CYGWIN
// char *str = "0x11111111";
static int str_to_u32(u32 *num, const char *str)
{
u32 c;
int shift = 0;
char *s;
int hex_mode = 0;
*num = 0;
if( *str == '0' && *(str+1) == 'x' )
{
hex_mode = 1;
s = (char *)(str + 2);
}
else
{
s = (char *)str;
}
while( *s != '\0' )
{
if( shift > 8 )
{
return -1; /* error */
}
if( hex_mode )
{
if( '0' <= *s && *s <= '9' )
{
c = (u32)(*s - '0');
}
else if( 'a' <= *s && *s <= 'f' )
{
c = (u32)(*s - 'a') + 10;
}
else if( 'A' <= *s && *s <= 'F' )
{
c = (u32)(*s - 'A') + 10;
}
else
{
return -1; /* error */
}
*num <<= 4;
*num |= c;
}
else
{
if( '0' <= *s && *s <= '9' )
{
c = (u32)(*s - '0');
}
else
{
return -1; /* error */
}
*num *= 10;
*num += c;
}
shift++;
s++;
}
return 0;
}
static double gettimeofday_sec(void)
{
struct timeval tv;
#if 0
struct timeval
{
time_t tv_sec; /* 秒 */
suseconds_t tv_usec; /* マイクロ秒 */
};
struct timezone
{
int tz_minuteswest; /* グリニッジ標準時との差 (西方に分単位) */
int tz_dsttime; /* 夏時間調整の型 */
};
int gettimeofday(struct timeval *tv, struct timezone *tz);
#endif
gettimeofday(&tv, NULL);
return tv.tv_sec + (double)tv.tv_usec*1e-6;
}
void showHelp(const char* program)
{
printf( "%s [OPTION]\n", program );
printf( "\t-b bonding_option : Default=0, 0(Prod) 1(Dev) 2(Dev Debugger)\n" );
printf( "\t-p output_path : Default=%s[PID]_[BONDING_OPTION].txt\n", DEFAULT_OUTPUT_PATH_BASE );
printf( "\t-n output_number : Default=4294967295(0xffffffff)\n" );
printf( "\t-h : Show this Help\n" );
}
int main(int argc, char *argv[])
{
u8 bonding_option = BONDING_OPTION_PROD;
char output_path[512] = "";
u32 output_number = 0xffffffff;
u32 device_id[CR_NUM_OF_DEVICEID];
u8 id[CR_ID_BUF_SIZE]; /* 256byte(2048bit) */
int ret_code;
int c;
FILE *fp;
double time_start,time_end;
long double time_total = 0;
int time_count = 0;
int myseed;
time_t tloc;
u32 counter0, counter0_bak;
u64 counter1, counter1_bak;
u64 counter2, counter2_bak;
u32 i;
#ifndef DEV_CYGWIN
keyboard_initialize();
#endif
// コマンドライン引数チェック
int opt;
while ((opt = getopt( argc, argv, "b:p:n:h")) != -1)
{
switch (opt)
{
case 'b' :
{
u32 temp;
str_to_u32( &temp, optarg );
if (temp != BONDING_OPTION_PROD && temp != BONDING_OPTION_DEV && temp != BONDING_OPTION_DEBUGGER)
{
printf( "Invalid Bonding Option!\n" );
showHelp( argv[0] );
return 0;
}
bonding_option = temp;
break;
}
case 'p' :
{
sprintf( output_path, "%s", optarg );
break;
}
case 'n' :
{
str_to_u32( &output_number, optarg );
break;
}
case 'h' :
{
showHelp( argv[0] );
return 0;
}
}
}
// デフォルトパス設定
if (output_path[0] == '\0')
{
sprintf( output_path, "%s_pid%d_bond%d.txt", DEFAULT_OUTPUT_PATH_BASE, getpid(), bonding_option );
}
// 設定表示
printf( "bonding_option = %d\n", bonding_option );
printf( "output_file = %s\n", output_path );
printf( "output_number = %u\n", (unsigned int)output_number );
// ファイルを開く
fp = fopen( output_path, "w" );
if( fp == NULL )
{
fprintf( stderr, "failed to fopen %s\n", argv[2] );
return 0;
}
// ヘッダを書き込む
fprintf( fp, "SerialNo, Crypto Key1, Crypto Key2, ID\n" );
fprintf( fp, "--------------------------------------\n" );
#ifdef USE_DUMMY_KEY
printf( "[TEST MODE] Use dummy key.\n");
#endif
time(&tloc);
myseed = tloc;
srand(myseed);
// ID生成前にカウンタ加算をするなら、初期値は 0 で OK
counter0 = 0x00000000;
counter1 = 0x0000000000000000ll;
counter2 = 0x0000000000000000ll;
// cr_generate_id を使用する前に呼び出す
ret_code = cr_generate_id_initialize( id );
if ( ret_code != CR_GENID_SUCCESS )
{
printf( "error : cr_generate_id_initialize\n" );
goto end;
}
for( i = 0 ; i < output_number; i++ )
{
u64 unit;
counter0_bak = counter0;
counter1_bak = counter1;
counter2_bak = counter2;
// counter0 は、1 ずつ加算
counter0 = i + 1;
if( counter0 == 0 )
{
counter0 = 1;
}
// counter1 は、"14 の乱数値" を加算
unit = (u64)( ( rand() & 0x03 ) + 1 );
counter1 += unit;
// counter2 は、"0 以外の 32bit 乱数値" を加算
do {
unit = ((u64)rand() & 0xffff) | ( ((u64)rand() & 0xffff) << 16 );
} while( unit == 0 );
counter2 += unit;
// カウンタオーバーフローチェック
if( counter0 < counter0_bak )
{
fprintf(stderr,"counter0 overflow : %08x\n", (unsigned int)counter0 );
}
if( counter1 < counter1_bak )
{
fprintf(stderr,"counter1 overflow : %08x%08x\n", (unsigned int)( counter1 >> 32 ), (unsigned int)counter2 );
}
if( counter2 < counter2_bak )
{
fprintf(stderr,"counter2 overflow : %08x%08x\n", (unsigned int)( counter2 >> 32 ), (unsigned int)counter2 );
}
device_id[0] = counter0;
device_id[1] = (u32)(counter1 & 0xffffffff);
device_id[2] = (u32)((counter1 >> 32) & 0xffffffff);
device_id[3] = (u32)(counter2 & 0xffffffff);
device_id[4] = (u32)((counter2 >> 32) & 0xffffffff);
time_start = gettimeofday_sec();
ret_code = cr_generate_id( device_id, id, bonding_option );
if( ret_code != 0 )
{
fprintf(stderr,"generate_id failed\n");
goto end;
}
else
{
time_end = gettimeofday_sec();
time_total += (long double)(time_end - time_start);
time_count++;
/* printf("generate_id success\n"); */
}
// 書き込み
{
int i;
fprintf( fp, "%08X, %08X %08X, %08X %08X, ",
(unsigned int)device_id[0], (unsigned int)device_id[2], (unsigned int)device_id[1], (unsigned int)device_id[4], (unsigned int)device_id[3] );
for (i = 0; i < CR_ID_BUF_SIZE; i++ )
{
fprintf( fp, "%02X", id[i] );
}
fprintf( fp, "\n" );
}
if (kbhit())
{
c = getch();
if( 'p' == c )
{
printf("ID[0] = 0x%08x\n", (unsigned int)device_id[0]);
printf("ID[1] = 0x%08x%08x\n", (unsigned int)device_id[2], (unsigned int)device_id[1] );
printf("ID[2] = 0x%08x%08x\n", (unsigned int)device_id[4], (unsigned int)device_id[3] );
printf("time av. = %8.8f sec\n", (double)(time_total/(long double)time_count));
cr_print_flag = 1;
}
else if( c == 'q' )
{
goto end;
}
}
else
{
cr_print_flag = 0;
}
}
end:
// ファイルのクローズ
if (fp)
{
fclose(fp);
}
// cr_generate_id を使用した後に呼び出す
ret_code = cr_generate_id_finalize( id );
if ( ret_code != CR_GENID_SUCCESS )
{
printf( "error : cr_generate_id_finalize\n" );
return 0; // error
}
#ifndef DEV_CYGWIN
keyboard_finalize();
#endif
printf("end of main\n");
return 0;
}