ECDSA鍵インポート、OpenSSLでの検証処理追加

git-svn-id: file:///Volumes/Transfer/gigaleak_20231201/2020-09-30%20-%20paladin.7z/paladin/ctr_eFuse@130 ff987cc8-cf2f-4642-8568-d52cce064691
This commit is contained in:
kubodera_yuichi 2010-01-05 05:15:11 +00:00
parent d9ade4c7f2
commit c1c8920dd9

View File

@ -24,13 +24,18 @@
#include "my_hsm_bignum.h"
#include "my_hsm_alloc.h"
#define PRIV_KEY_FILE "./test_key/test-ecdsa-privkey.der"
#define PUB_KEY_FILE "./test_key/test-ecdsa-pubkey.der"
#define PRIV_KEY_FILE "/opt/nfast/work/hoge/ctr_eFuse/dummyKey/dev/NintendoCTR2_priv_dummy.der"
#define PUB_KEY_FILE "/opt/nfast/work/hoge/ctr_eFuse/dummyKey/dev/NintendoCTR2_pub_dummy.der"
#define MODULE_ID 1
#define DATA_LEN 256 // bytes
#define SIGN_MECH Mech_ECDSAhSHA256
#define SIGN_MECH Mech_ECDSA
#define CROSS_VERIFY
//#define CARD_PROTECT
//#define EXPORT_KEY
//#define STRICT_FIPS
// ECDSA private key data
typedef struct
@ -56,11 +61,15 @@ RQCard_FIPS fips;
M_KeyID ltid = 0; // the cardset loaded into the module
NFKM_CardSet *cardset = NULL;
NFKM_ModuleInfo *moduleinfo = NULL;
const NFKM_KeyIdent priv_keyident = { (char*)"simple", (char*)"ecdsa-import-privkey" };
const NFKM_KeyIdent pub_keyident = { (char*)"simple", (char*)"ecdsa-import-pubkey" };
const NFKM_KeyIdent priv_keyident = { (char*)"simple", (char*)"nintendo-ctr2-priv-dummy-dev" };
const NFKM_KeyIdent pub_keyident = { (char*)"simple", (char*)"nintendo-ctr2-pub-dummy-dev" };
unsigned char save_enc[DATA_LEN];
// global var
EC_KEY *ecPriv = NULL;
EC_KEY *ecPub = NULL;
// function
int importECDSAPrivate( NFKM_KeyIdent keyident );
int importECDSAPublic( NFKM_KeyIdent keyident );
@ -71,7 +80,6 @@ int importECDSAPrivate( NFKM_KeyIdent keyident )
{
int result = Status_OK;
EC_KEY *privkey = NULL;
FILE *fp;
unsigned char *dPtr = NULL;
@ -98,17 +106,17 @@ int importECDSAPrivate( NFKM_KeyIdent keyident )
printf( "error : open %s file\n", PRIV_KEY_FILE );
return 1;
}
privkey = d2i_ECPrivateKey_fp( fp, NULL );
if ( !privkey )
ecPriv = d2i_ECPrivateKey_fp( fp, NULL );
if ( !ecPriv )
{
printf( "error : d2i_ECPrivateKey_fp\n" );
return 1;
}
fclose( fp );
#if 0
#if 1
printf( "\nEC(d) = " );
BN_print_fp( stdout, privkey->priv_key );
BN_print_fp( stdout, ecPriv->priv_key );
printf( "\n" );
#endif
@ -120,9 +128,9 @@ int importECDSAPrivate( NFKM_KeyIdent keyident )
// ECDSA priv key の構成要素をバイナリに変換
{
// d
dLen = BN_num_bytes( privkey->priv_key );
dLen = BN_num_bytes( ecPriv->priv_key );
dPtr = (unsigned char *)malloc( dLen );
if ( dLen != BN_bn2bin( privkey->priv_key, dPtr ) )
if ( dLen != BN_bn2bin( ecPriv->priv_key, dPtr ) )
{
printf( "BN_bn2bin failed!(d)\n" );
return 1;
@ -156,7 +164,11 @@ int importECDSAPrivate( NFKM_KeyIdent keyident )
map.f = NFKM_NKF_RecoveryEnabled | NFKM_NKF_ProtectionModule;
// 秘密鍵には DECRYPT と SIGN
// 公開鍵には ENCRYPT と VERIFY しかセットできない??
#ifdef EXPORT_KEY
map.op_base = NFKM_DEFOPPERMS_SIGN | Act_OpPermissions_Details_perms_ExportAsPlain; // for debug
#else
map.op_base = NFKM_DEFOPPERMS_SIGN; // ECDSA priv key : sign only
#endif // EXPORT_KEY
map.cs = cardset;
result = NFKM_newkey_makeaclx( handle, nc, world, &map, &(cmd.args.import.acl), NULL );
if ( result != Status_OK )
@ -224,7 +236,6 @@ int importECDSAPublic( NFKM_KeyIdent keyident )
{
int result = Status_OK;
EC_KEY *pubkey = NULL;
FILE *fp;
unsigned char *qxPtr, *qyPtr;
@ -253,14 +264,22 @@ int importECDSAPublic( NFKM_KeyIdent keyident )
printf( "error : open %s file\n", PUB_KEY_FILE );
return 1;
}
pubkey = d2i_EC_PUBKEY_fp( fp, NULL );
if ( !pubkey )
ecPub = d2i_EC_PUBKEY_fp( fp, NULL );
if ( !ecPub )
{
printf( "error : d2i_EC_PUBKEY_fp\n" );
return 1;
}
fclose( fp );
#if 1
printf( "\nEC(Q->x) = " );
BN_print_fp( stdout, &(ecPub->pub_key->X) );
printf( "\nEC(Q->y) = " );
BN_print_fp( stdout, &(ecPub->pub_key->Y) );
printf( "\n" );
#endif
#if 0
printf( "EC bignum(Openssl) size\n" );
printf( "EC(qx) : %d bytes\n", BN_num_bytes( &pubkey->pub_key->X ) );
@ -271,17 +290,17 @@ int importECDSAPublic( NFKM_KeyIdent keyident )
// ECDSA public key の構成要素をそれぞれバイナリに変換
{
// qx
qxLen = BN_num_bytes( &pubkey->pub_key->X );
qxLen = BN_num_bytes( &ecPub->pub_key->X );
qxPtr = (unsigned char *)malloc( qxLen );
if ( qxLen != BN_bn2bin( &pubkey->pub_key->X, qxPtr ) )
if ( qxLen != BN_bn2bin( &ecPub->pub_key->X, qxPtr ) )
{
printf( "BN_bn2bin failed!(qx)\n" );
return 1;
}
// qy
qyLen = BN_num_bytes( &pubkey->pub_key->Y );
qyLen = BN_num_bytes( &ecPub->pub_key->Y );
qyPtr = (unsigned char *)malloc( qyLen );
if ( qyLen != BN_bn2bin( &pubkey->pub_key->Y, qyPtr ) )
if ( qyLen != BN_bn2bin( &ecPub->pub_key->Y, qyPtr ) )
{
printf( "BN_bn2bin failed!(qy)\n" );
return 1;
@ -315,7 +334,11 @@ int importECDSAPublic( NFKM_KeyIdent keyident )
map.f = NFKM_NKF_RecoveryEnabled | NFKM_NKF_ProtectionModule | NFKM_NKF_PublicKey;
// 秘密鍵には DECRYPT と SIGN
// 公開鍵には ENCRYPT と VERIFY しかセットできない??
#ifdef EXPORT_KEY
map.op_base = NFKM_DEFOPPERMS_VERIFY | Act_OpPermissions_Details_perms_ExportAsPlain; // for debug (maybe, pub key has an export permission as default.)
#else
map.op_base = NFKM_DEFOPPERMS_VERIFY; // ECDSA public key : verify only
#endif // EXPORT_KEY
map.cs = cardset;
result = NFKM_newkey_makeaclx( handle, nc, world, &map, &(cmd.args.import.acl), NULL );
if ( result != Status_OK )
@ -471,9 +494,65 @@ int verifyECDSAKeyPair( NFKM_KeyIdent priv_ident, NFKM_KeyIdent pub_ident )
keyinfo = NULL;
#endif
// export key pair
#ifdef EXPORT_KEY
// priv key export
cmd.cmd = Cmd_Export;
cmd.args.export.key = priv_keyid;
result = NFastApp_Transact( nc, NULL, &cmd, &reply, NULL );
if ( result != Status_OK )
{
printf( "error(%d) : FastApp_Transact(Cmd_Export)\n", result );
return 1;
}
result = reply.status;
if ( result != Status_OK )
{
printf( "error(%d) : reply.status(Cmd_Export)\n", result );
return 1;
}
printf( "----- export : priv key -----\n" );
printf( "key type : %d\n", reply.reply.export.data.type );
printf( "curve namee : %d\n", reply.reply.export.data.data.ecprivate.curve.name );
my_printbignum( stdout, "d", reply.reply.export.data.data.ecprivate.d );
printf( "-----------------------------\n" );
NFastApp_Free_Reply( handle, NULL, NULL, &reply );
memset( &cmd, 0, sizeof( cmd ) );
memset( &reply, 0, sizeof( reply ) );
// pub key export
cmd.cmd = Cmd_Export;
cmd.args.export.key = pub_keyid;
result = NFastApp_Transact( nc, NULL, &cmd, &reply, NULL );
if ( result != Status_OK )
{
printf( "error(%d) : FastApp_Transact(Cmd_Export)\n", result );
return 1;
}
result = reply.status;
if ( result != Status_OK )
{
printf( "error(%d) : reply.status(Cmd_Export)\n", result );
return 1;
}
printf( "----- export : priv key -----\n" );
printf( "key type : %d\n", reply.reply.export.data.type );
printf( "curve namee : %d\n", reply.reply.export.data.data.ecpublic.curve.name );
my_printbignum( stdout, "Q->x", reply.reply.export.data.data.ecpublic.Q.x );
my_printbignum( stdout, "Q->y", reply.reply.export.data.data.ecpublic.Q.y );
printf( "-----------------------------\n" );
NFastApp_Free_Reply( handle, NULL, NULL, &reply );
memset( &cmd, 0, sizeof( cmd ) );
memset( &reply, 0, sizeof( reply ) );
#endif // EXPORT_KEY
// sign & verify test
{
M_Hash32 hash;
M_Hash hash;
struct NFast_Bignum *rBn, *sBn;
unsigned char *rPtr, *sPtr;
@ -484,10 +563,10 @@ int verifyECDSAKeyPair( NFKM_KeyIdent priv_ident, NFKM_KeyIdent pub_ident )
rLen = sLen = 0;
// hash data
for ( i = 0; i < 32; i++ )
hash.bytes[i] = i*2;
for ( i = 0; i < 20; i++ )
hash.bytes[i] = i+1;
#if 1
PrintArray( (char*)"hash", hash.bytes, 32 );
PrintArray( (char*)"hash", hash.bytes, 20 );
#endif
// sign transact
@ -495,8 +574,9 @@ int verifyECDSAKeyPair( NFKM_KeyIdent priv_ident, NFKM_KeyIdent pub_ident )
cmd.args.sign.flags = 0; // Cmd_Sign_Args_flags_given_iv_present;
cmd.args.sign.key = priv_keyid;
cmd.args.sign.mech = SIGN_MECH;
cmd.args.sign.plain.type = PlainTextType_Hash32;
cmd.args.sign.plain.data.hash32.data = hash;
cmd.args.sign.plain.type = PlainTextType_Hash;
cmd.args.sign.plain.data.hash.data = hash;
result = NFastApp_Transact( nc, NULL, &cmd, &reply, NULL );
if ( result != Status_OK )
{
@ -514,7 +594,7 @@ int verifyECDSAKeyPair( NFKM_KeyIdent priv_ident, NFKM_KeyIdent pub_ident )
printf( "error : reply mech isn't match %d!\n", SIGN_MECH );
return 1;
}
printf( "ECDSAhSHA256 sign ok\n" );
printf( "ECDSA sign ok\n" );
// signature bignum -> bin
printf ( "sig mech : %d\n", reply.reply.sign.sig.mech );
@ -530,7 +610,7 @@ int verifyECDSAKeyPair( NFKM_KeyIdent priv_ident, NFKM_KeyIdent pub_ident )
PrintArray( (char*)"sig r", rPtr, rLen );
PrintArray( (char*)"sig s", sPtr, sLen );
#endif
//NFastApp_Free_Command( handle, NULL, NULL, &cmd );
NFastApp_Free_Reply( handle, NULL, NULL, &reply );
memset( &cmd, 0, sizeof( cmd ) );
@ -541,8 +621,8 @@ int verifyECDSAKeyPair( NFKM_KeyIdent priv_ident, NFKM_KeyIdent pub_ident )
cmd.args.verify.flags = 0;
cmd.args.verify.key = pub_keyid;
cmd.args.verify.mech = SIGN_MECH;
cmd.args.verify.plain.type = PlainTextType_Hash32;
cmd.args.verify.plain.data.hash32.data = hash;
cmd.args.verify.plain.type = PlainTextType_Hash;
cmd.args.verify.plain.data.hash.data = hash;
cmd.args.verify.sig.mech = SIGN_MECH;
cmd.args.verify.sig.data.ecdsa.r = rBn;
cmd.args.verify.sig.data.ecdsa.s = sBn;
@ -559,10 +639,114 @@ int verifyECDSAKeyPair( NFKM_KeyIdent priv_ident, NFKM_KeyIdent pub_ident )
return 1;
}
printf( "ECDSAhSHA256 verify ok\n" );
printf( "ECDSA verify ok!\n" );
NFastApp_Free_Command( handle, NULL, NULL, &cmd );
NFastApp_Free_Reply( handle, NULL, NULL, &reply );
#ifdef CROSS_VERIFY
unsigned char compareBuf[0x80];
int sigLen = 0;
const unsigned char *pECDSAsig = compareBuf;
ECDSA_SIG *sig = NULL;
unsigned char *rOPtr, *sOPtr;
int rOLen, sOLen;
struct NFast_Bignum *rBnO, *sBnO;
memset( compareBuf, 0, sizeof( compareBuf ) );
result = ECDSA_sign( 0, hash.bytes, 20, compareBuf, &sigLen, ecPriv );
if ( result == 0)
{
printf( "error : ECDSA_sign(by OpenSSL)!\n" );
return 1;
}
sig = d2i_ECDSA_SIG( NULL, &pECDSAsig, sigLen );
if( sig == NULL )
{
printf( "error : d2i_ECDSA_SIG(by OpenSSL)!\n" );
return 1;
}
#if 0
PrintArray( (char*)"OpenSSL:sig r", (const char*)sig->r->d, sig->r->dmax*4 );
PrintArray( (char*)"OpenSSL:sig s", (const char*)sig->s->d, sig->s->dmax*4 );
#endif
// OpenSSL r&S -> bin -> HSM r&s
rOLen = BN_num_bytes( sig->r );
rOPtr = (unsigned char *)malloc( rOLen );
if ( rOLen != BN_bn2bin( sig->r, rOPtr ) )
{
printf( "BN_bn2bin failed!(sig->r)\n" );
return 1;
}
sOLen = BN_num_bytes( sig->s );
sOPtr = (unsigned char *)malloc( sOLen );
if ( sOLen != BN_bn2bin( sig->s, sOPtr ) )
{
printf( "BN_bn2bin failed!(sig->s)\n" );
return 1;
}
my_bin2bignum( &rBnO, handle, rOPtr, rOLen );
my_bin2bignum( &sBnO, handle, sOPtr, sOLen );
// verify sign for HSM hash
//NFastApp_Free_Command( handle, NULL, NULL, &cmd );
NFastApp_Free_Reply( handle, NULL, NULL, &reply );
memset( &cmd, 0, sizeof( cmd ) );
memset( &reply, 0, sizeof( reply ) );
// verify transact
cmd.cmd = Cmd_Verify;
cmd.args.verify.flags = 0;
cmd.args.verify.key = pub_keyid;
cmd.args.verify.mech = SIGN_MECH;
cmd.args.verify.plain.type = PlainTextType_Hash;
cmd.args.verify.plain.data.hash.data = hash;
cmd.args.verify.sig.mech = SIGN_MECH;
cmd.args.verify.sig.data.ecdsa.r = rBnO;
cmd.args.verify.sig.data.ecdsa.s = sBnO;
result = NFastApp_Transact( nc, NULL, &cmd, &reply, NULL );
if ( result != Status_OK )
{
printf( "error(%d) : FastApp_Transact(Cmd_Decrypt)\n", result );
return 1;
}
result = reply.status;
if ( result != Status_OK )
{
printf( "error(%d) : reply.status(Cmd_Decrypt)\n", result );
return 1;
}
printf( "OpenSSL sign(r&s) verified by HSM!\n" );
// verify HSM signature by OpenSSL
{
unsigned char tempSign[70];
tempSign[0] = 0x30;
tempSign[1] = 0x3E;
tempSign[2] = 0x02;
tempSign[3] = 0x1D;
memcpy( &tempSign[4], &rPtr[3], 0x1D );
tempSign[0x21] = 0x02;
tempSign[0x22] = 0x1D;
memcpy( &tempSign[0x23], &sPtr[3], 0x1D );
PrintArray( (char*)"tempSign(HSM)", (const char *)tempSign, 0x3E + 2 );
result = ECDSA_verify( 0, hash.bytes, 20, tempSign, 0x3E + 2, ecPub );
if( result != 1)
{
printf( "error : ECDSA_verify(by OpenSSL)!\n" );
return 1;
}
}
printf( "HSM sign(r&s) verified by OpenSSL!\n" );
result = 0;
#endif // CROSS_VERIFY
} // encrypt & decrypt
return result;
@ -654,7 +838,7 @@ int main( int argc, char *argv[] )
}
// get strict-FIPS authorization
#if 0
#ifdef STRICT_FIPS
NFKM_FIPS140AuthHandle fipsHandle;
M_SlotID slotId;
result = RQCard_fips_get( &fips, 1, &fipsHandle, &slotId );
@ -669,7 +853,7 @@ int main( int argc, char *argv[] )
}
#endif
#if 0
#ifdef CARD_PROTECT
// list cardsets
int card_num;
NFKM_CardSetIdent *cardident = NULL;
@ -710,7 +894,7 @@ int main( int argc, char *argv[] )
{
printf( "error(%d) : card module event loop\n", result );
}
#endif
#endif // CARD_PROTECT
// get usable module
moduleinfo = world->modules[0];
@ -763,7 +947,7 @@ int main( int argc, char *argv[] )
return 1;
}
printf( "ECDSA keypair verify success.\n" );
// end processing
RQCard_fips_free( &card, &fips );
RQCard_destroy( &card );