diff --git a/hsm_utils/import_ecdsa_keypair.c b/hsm_utils/import_ecdsa_keypair.c index b480199..85898f8 100644 --- a/hsm_utils/import_ecdsa_keypair.c +++ b/hsm_utils/import_ecdsa_keypair.c @@ -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 );