mirror of
https://github.com/rvtr/ctr_eFuse.git
synced 2025-11-02 00:11:04 -04:00
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:
parent
d9ade4c7f2
commit
c1c8920dd9
@ -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 );
|
||||
|
||||
Loading…
Reference in New Issue
Block a user