// import key (+ encrypt, decrypt) test for nShield #include #include #include #include // openssl #include #include #include #include #include "ec_lcl.h" #include #include #include #include "nfastapp.h" #include "nfkm.h" #include "rqcard-applic.h" #include "rqcard-fips.h" #include "my_hsm_bignum.h" #include "my_hsm_alloc.h" #define PRIV_KEY_FILE "/opt/nfast/work/ctr_eFuse/hsm_utils/real_key/hoge/NintendoCTR2_privkey_prod.der" #define PUB_KEY_FILE "/opt/nfast/work/ctr_eFuse/hsm_utils/real_key/hoge/NintendoCTR2_pubkey_prod.der" #define MODULE_ID 1 #define DATA_LEN 256 // bytes #define SIGN_MECH Mech_ECDSA #define CROSS_VERIFY //#define CARD_PROTECT //#define EXPORT_KEY //#define STRICT_FIPS // ECDSA private key data typedef struct { struct NFast_Bignum *d; } ECDSAPrivateKeyDataBn; // ECDSA public key data typedef struct { struct NFast_Bignum *qx; struct NFast_Bignum *qy; } ECDSAPublicKeyDataBn; // global variable NFast_AppHandle handle; NFastApp_Connection nc; NFKM_WorldInfo *world = NULL; RQCard card; 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*)"nct2-priv-hoge" }; const NFKM_KeyIdent pub_keyident = { (char*)"simple", (char*)"nct2-pub-hoge" }; 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 ); int verifyECDSAKeyPair( NFKM_KeyIdent priv_keyident, NFKM_KeyIdent pub_keyident ); void PrintArray( char *pStr, const unsigned char *pData, int length ); int importECDSAPrivate( NFKM_KeyIdent keyident ) { int result = Status_OK; FILE *fp; unsigned char *dPtr = NULL; int dLen = 0; M_Command cmd; M_Reply reply; NFKM_MakeACLParams map; NFKM_MakeBlobsParams mbp; NFKM_Key reg_key; ECDSAPrivateKeyDataBn privBn; memset( &cmd, 0, sizeof( cmd ) ); memset( &reply, 0, sizeof( reply ) ); memset( &map, 0, sizeof( map ) ); memset( &mbp, 0, sizeof( mbp ) ); memset( ®_key, 0, sizeof( reg_key ) ); memset( &privBn, 0, sizeof( privBn ) ); // key data open printf( "priv key file : %s\n", PRIV_KEY_FILE ); fp = fopen( PRIV_KEY_FILE, "rb" ); if ( !fp ) { printf( "error : open %s file\n", PRIV_KEY_FILE ); return 1; } ecPriv = d2i_ECPrivateKey_fp( fp, NULL ); if ( !ecPriv ) { printf( "error : d2i_ECPrivateKey_fp\n" ); return 1; } fclose( fp ); #if 1 printf( "\nEC(d) = " ); BN_print_fp( stdout, ecPriv->priv_key ); printf( "\n" ); #endif #if 0 printf( "EC bignum(Openssl) size\n" ); printf( "EC(d) : %d bytes\n", BN_num_bytes( privkey->priv_key ) ); #endif // ECDSA priv key の構成要素をバイナリに変換 { // d dLen = BN_num_bytes( ecPriv->priv_key ); dPtr = (unsigned char *)malloc( dLen ); if ( dLen != BN_bn2bin( ecPriv->priv_key, dPtr ) ) { printf( "BN_bn2bin failed!(d)\n" ); return 1; } } // ec bignum(openssl) -> bin #if 0 printf( "EC bin addr\n" ); printf( "EC(d) : 0x%08X\n", (unsigned int)dPtr ); #endif // バイナリをHSMのBignumに変換 { my_bin2bignum( &(privBn.d), handle, dPtr, dLen ); free( dPtr ); } #if 0 my_printbignum ( stdout, "EC(d)", privBn.d ); #endif #if 0 printf( "EC bn addr\n" ); printf( "EC(d) : 0x%08X\n", (unsigned int)privBn.d ); #endif // make ACL if ( cardset != NULL ) map.f = NFKM_NKF_RecoveryEnabled | NFKM_NKF_ProtectionCardSet; else 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 ) { printf( "error(%d) : NFKM_newkey_makeaclx\n", result ); return result; } // import key cmd.cmd = Cmd_Import; cmd.args.import.module = MODULE_ID; cmd.args.import.data.type = KeyType_ECDSAPrivate; cmd.args.import.data.data.ecprivate.curve.name = ECName_NISTB233; // 名前を指定することで cmd.args.import.data.data.ecprivate.d = privBn.d; // d だけ設定すれば良い result = NFastApp_Transact( nc, NULL, &cmd, &reply, NULL ); if ( result != Status_OK ) { printf( "error(%d) : Cmd_Import\n", result ); return 1; } result = reply.status; if ( result != Status_OK ) { printf( "error(%d) : Cmd_Import(reply)\n", result ); return 1; } // make blobs //reg_key.v = Key__maxversion; // TORIAEZU : Key__maxversion = 8 reg_key.name = keyident.ident; reg_key.appname = keyident.appname; reg_key.ident = keyident.ident; time( &(reg_key.gentime) ); mbp.f = map.f; mbp.kpriv = reply.reply.import.key; mbp.lt = ltid; mbp.cs = cardset; result = NFKM_newkey_makeblobsx( handle, nc, world, &mbp, ®_key, NULL ); if ( result != Status_OK ) { printf( "error(%d) : NFKM_newkey_makeblobsx\n", result ); return 1; } // record key to disk result = NFKM_recordkey( handle, ®_key, NULL ); if ( result != Status_OK ) { printf( "error(%d) : NFKM_recordkey\n", result ); return 1; } // destroy key result = NFKM_cmd_destroy( handle, nc, 0, reply.reply.import.key, "destroy import key", NULL ); if ( result != Status_OK ) { printf( "error(%d) : NFKM_cmd_destroy\n", result ); return 1; } printf( "priv key record success : appname=%s, ident=%s\n", priv_keyident.appname, priv_keyident.ident ); return result; } // importECDSAPrivate int importECDSAPublic( NFKM_KeyIdent keyident ) { int result = Status_OK; FILE *fp; unsigned char *qxPtr, *qyPtr; int qxLen, qyLen; M_Command cmd; M_Reply reply; NFKM_MakeACLParams map; NFKM_MakeBlobsParams mbp; NFKM_Key reg_key; ECDSAPublicKeyDataBn pubBn; qxPtr = qyPtr = NULL; qxLen = qyLen = 0; memset( &cmd, 0, sizeof( cmd ) ); memset( &reply, 0, sizeof( reply ) ); memset( &map, 0, sizeof( map ) ); memset( &mbp, 0, sizeof( mbp ) ); memset( ®_key, 0, sizeof( reg_key ) ); memset( &pubBn, 0, sizeof( pubBn ) ); // key data open printf( "pub key file : %s\n", PUB_KEY_FILE ); fp = fopen( PUB_KEY_FILE, "rb" ); if ( !fp ) { printf( "error : open %s file\n", PUB_KEY_FILE ); return 1; } 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 ) ); printf( "EC(qy) : %d bytes\n", BN_num_bytes( &pubkey->pub_key->Y ) ); #endif // ECDSA public key の構成要素をそれぞれバイナリに変換 { // qx qxLen = BN_num_bytes( &ecPub->pub_key->X ); qxPtr = (unsigned char *)malloc( qxLen ); if ( qxLen != BN_bn2bin( &ecPub->pub_key->X, qxPtr ) ) { printf( "BN_bn2bin failed!(qx)\n" ); return 1; } // qy qyLen = BN_num_bytes( &ecPub->pub_key->Y ); qyPtr = (unsigned char *)malloc( qyLen ); if ( qyLen != BN_bn2bin( &ecPub->pub_key->Y, qyPtr ) ) { printf( "BN_bn2bin failed!(qy)\n" ); return 1; } } // ECDSA bignum(openssl) -> bin #if 0 printf( "EC bin addr\n" ); printf( "EC(qx) : 0x%08X\n", (unsigned int)qxPtr ); printf( "EC(qy) : 0x%08X\n", (unsigned int)qyPtr ); #endif // バイナリをHSMのBignumに変換 { my_bin2bignum( &(pubBn.qx), handle, qxPtr, qxLen ); my_bin2bignum( &(pubBn.qy), handle, qyPtr, qyLen ); free( qxPtr ); free( qyPtr ); } #if 0 printf( "EC bn addr\n" ); printf( "EC(qx) : 0x%08X\n", (unsigned int)pubBn.qx ); printf( "EC(qy) : 0x%08X\n", (unsigned int)pubBn.qy ); #endif // make ACL if ( cardset != NULL ) map.f = NFKM_NKF_RecoveryEnabled | NFKM_NKF_ProtectionCardSet | NFKM_NKF_PublicKey; else 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 ) { printf( "error(%d) : NFKM_newkey_makeaclx\n", result ); return result; } // import key cmd.cmd = Cmd_Import; cmd.args.import.module = MODULE_ID; cmd.args.import.data.type = KeyType_ECDSAPublic; cmd.args.import.data.data.ecpublic.curve.name = ECName_NISTB233; // 名前を指定することで cmd.args.import.data.data.ecpublic.Q.x = pubBn.qx; // qx cmd.args.import.data.data.ecpublic.Q.y = pubBn.qy; // qy だけを指定すればよい? result = NFastApp_Transact( nc, NULL, &cmd, &reply, NULL ); if ( result != Status_OK ) { printf( "error(%d) : Cmd_Import\n", result ); return 1; } result = reply.status; if ( result != Status_OK ) { printf( "error(%d) : Cmd_Import(reply)\n", result ); return 1; } // make blobs //reg_key.v = Key__maxversion; // TORIAEZU : Key__maxversion = 8 reg_key.name = keyident.ident; reg_key.appname = keyident.appname; reg_key.ident = keyident.ident; time( &(reg_key.gentime) ); mbp.f = map.f; mbp.kpub = reply.reply.import.key; mbp.lt = ltid; mbp.cs = cardset; result = NFKM_newkey_makeblobsx( handle, nc, world, &mbp, ®_key, NULL ); if ( result != Status_OK ) { printf( "error(%d) : NFKM_newkey_makeblobsx\n", result ); return 1; } // record key to disk result = NFKM_recordkey( handle, ®_key, NULL ); if ( result != Status_OK ) { printf( "error(%d) : NFKM_recordkey\n", result ); return 1; } // destroy key result = NFKM_cmd_destroy( handle, nc, 0, reply.reply.import.key, "destroy import key", NULL ); if ( result != Status_OK ) { printf( "error(%d) : NFKM_cmd_destroy\n", result ); return 1; } printf( "pub key record success : appname=%s, ident=%s\n", pub_keyident.appname, pub_keyident.ident ); return result; } // importECDSAPublic int verifyECDSAKeyPair( NFKM_KeyIdent priv_ident, NFKM_KeyIdent pub_ident ) { int i; int result = Status_OK; M_ByteBlock *blobptr = NULL; M_KeyID priv_keyid, pub_keyid; NFKM_Key *keyinfo = NULL; M_Command cmd; M_Reply reply; priv_keyid = pub_keyid = 0; memset( &cmd, 0, sizeof( cmd ) ); memset( &reply, 0, sizeof( reply ) ); // find priv key result = NFKM_findkey( handle, priv_ident, &keyinfo, NULL ); if ( result != Status_OK ) { printf( "error(%d) : NFKM_findkey(priv)\n", result ); return result; } // load priv key blob blobptr = &(keyinfo->privblob); result = NFKM_cmd_loadblob( handle, nc, moduleinfo->module, blobptr, ltid, &priv_keyid, "loading priv key blob", NULL ); if ( result != Status_OK ) { printf( "error(%d) : NFKM_cmd_loadblob(priv)\n", result ); return result; } NFKM_freekey( handle, keyinfo, NULL ); keyinfo = NULL; #if 0 // get priv key info cmd.cmd = Cmd_GetKeyInfo; cmd.args.getkeyinfo.key = priv_keyid; result = NFastApp_Transact( nc, NULL, &cmd, &reply, NULL ); if ( result != Status_OK ) { printf( "error(%d) : FastApp_Transact(Cmd_GetKeyInfo)\n", result ); return result; } printf( "priv key ID : %08X\n", (unsigned int)priv_keyid ); printf( "priv keytype : %d\n", reply.reply.getkeyinfo.type ); NFastApp_Free_Command( handle, NULL, NULL, &cmd ); NFastApp_Free_Reply( handle, NULL, NULL, &reply ); memset( &cmd, 0, sizeof( cmd ) ); memset( &reply, 0, sizeof( reply ) ); #endif // find pub key result = NFKM_findkey( handle, pub_ident, &keyinfo, NULL ); if ( result != Status_OK ) { printf( "error(%d) : NFKM_findkey(pub)\n", result ); return result; } // load pub key blob blobptr = &(keyinfo->pubblob); // pub dakedo privblob result = NFKM_cmd_loadblob( handle, nc, moduleinfo->module, blobptr, ltid, &pub_keyid, "loading pub key blob", NULL ); if ( result != Status_OK ) { printf( "error(%d) : NFKM_cmd_loadblob(pub)\n", result ); return result; } NFKM_freekey( handle, keyinfo, NULL ); keyinfo = NULL; #if 0 // get priv key info cmd.cmd = Cmd_GetKeyInfo; cmd.args.getkeyinfo.key = pub_keyid; result = NFastApp_Transact( nc, NULL, &cmd, &reply, NULL ); if ( result != Status_OK ) { printf( "error(%d) : FastApp_Transact(Cmd_GetKeyInfo)\n", result ); return result; } printf( "pub key ID : %08X\n", (unsigned int)pub_keyid ); printf( "pub keytype : %d\n", reply.reply.getkeyinfo.type ); NFastApp_Free_Command( handle, NULL, NULL, &cmd ); NFastApp_Free_Reply( handle, NULL, NULL, &reply ); memset( &cmd, 0, sizeof( cmd ) ); memset( &reply, 0, sizeof( reply ) ); 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_Hash hash; struct NFast_Bignum *rBn, *sBn; unsigned char *rPtr, *sPtr; int rLen, sLen; rBn = sBn = NULL; rPtr = sPtr = NULL; rLen = sLen = 0; // hash data for ( i = 0; i < 20; i++ ) hash.bytes[i] = i+1; #if 1 PrintArray( (char*)"hash", hash.bytes, 20 ); #endif // sign transact cmd.cmd = Cmd_Sign; 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_Hash; cmd.args.sign.plain.data.hash.data = hash; result = NFastApp_Transact( nc, NULL, &cmd, &reply, NULL ); if ( result != Status_OK ) { printf( "error(%d) : FastApp_Transact(Cmd_Sign)\n", result ); return 1; } result = reply.status; if ( result != Status_OK ) { printf( "error(%d) : reply.status(Cmd_Sign)\n", result ); return 1; } if ( SIGN_MECH != reply.reply.sign.sig.mech ) { printf( "error : reply mech isn't match %d!\n", SIGN_MECH ); return 1; } printf( "ECDSA sign ok\n" ); // signature bignum -> bin printf ( "sig mech : %d\n", reply.reply.sign.sig.mech ); rLen = reply.reply.sign.sig.data.ecdsa.r->nbytes; rPtr = (unsigned char*)malloc( rLen ); my_bignum2bin ( rPtr, rLen, handle, reply.reply.sign.sig.data.ecdsa.r ); sLen = reply.reply.sign.sig.data.ecdsa.s->nbytes; sPtr = (unsigned char*)malloc( sLen ); my_bignum2bin ( sPtr, sLen, handle, reply.reply.sign.sig.data.ecdsa.s ); my_bignumCopy( &rBn, reply.reply.sign.sig.data.ecdsa.r, handle ); my_bignumCopy( &sBn, reply.reply.sign.sig.data.ecdsa.s, handle ); #if 1 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 ) ); 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 = rBn; cmd.args.verify.sig.data.ecdsa.s = sBn; 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( "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; } // verifyECDSAkeypair void PrintArray( char *pStr, const unsigned char *pData, int length ) { int i; printf( "%s(%d bytes)", pStr, length ); for ( i = 0; i < length; i++ ) { if ( (i % 16) == 0 ) printf( "\n" ); printf( "%02X ", pData[ i ] ); } printf( "\n" ); } // PrintArray int main( int argc, char *argv[] ) { int result = Status_OK; M_Command cmd; M_Reply reply; memset( &cmd, 0, sizeof( cmd ) ); memset( &reply, 0, sizeof( reply ) ); // init nFast result = NFastApp_InitEx( &handle, NULL, NULL ); if ( result != Status_OK ) { printf( "error(%d) : NFastApp_InitEx\n", result ); return 1; } // connecting to hardserver result = NFastApp_Connect( handle, &nc, 0, NULL ); if ( result != Status_OK ) { printf( "error(%d) : NFastApp_Connect\n", result ); return 1; } // set bignum upcalls setting result = NFastApp_SetBignumUpcalls( handle, my_bignumreceiveupcall, my_bignumsendlenupcall, my_bignumsendupcall, my_bignumfreeupcall, my_bignumformatupcall, NULL ); if ( result != Status_OK ) { printf( "error(%d) : NFastApp_SetBignumUpcalls\n", result ); return 1; } // NFKM getinfo result = NFKM_getinfo( handle, &world, NULL ); if ( result != Status_OK ) { printf( "error(%d) : NFKM_getinfo\n", result ); return 1; } // init card-loading lib result = RQCard_init( &card, handle, nc, world, NULL ); if ( result != Status_OK ) { printf( "error(%d) : RQCard_init\n", result ); return 1; } // init FIPS state result = RQCard_fips_init( &card, &fips ); if ( result != Status_OK ) { printf( "error(%d) : RQCard_fips_init\n", result ); return 1; } // ui select result = RQCard_ui_default( &card ); if ( result != Status_OK ) { printf( "error(%d) : RQCard_ui_default\n", result ); return 1; } // get strict-FIPS authorization #ifdef STRICT_FIPS NFKM_FIPS140AuthHandle fipsHandle; M_SlotID slotId; result = RQCard_fips_get( &fips, 1, &fipsHandle, &slotId ); if ( result != Status_OK ) { printf( "error(%d) : RQCard_fips_get\n", result ); return 0; } if ( fipsHandle == NULL ) { printf( "this sworld isn't strict-FIPS.\n" ); } #endif #ifdef CARD_PROTECT // list cardsets int card_num; NFKM_CardSetIdent *cardident = NULL; result = NFKM_listcardsets( handle, &card_num, &cardident, NULL ); if ( result != Status_OK ) { printf( "error(%d) : NFKM_listcardsets\n", result ); return 0; } // find cardsets result = NFKM_findcardset( handle, cardident, &cardset, NULL ); if ( result != Status_OK ) { printf( "error(%d) : NFKM_findcardset\n", result ); return 0; } // load cardset result = RQCard_logic_ocs_specific( &card, &(cardset->hkltu), "Load Cardset" ); if ( result != Status_OK ) { printf( "error(%d) : RQCard_logic_ocs_specific\n", result ); return 0; } // use specific module : #1 // important!! : if you set resultplace=NULL, abort. (possibility is 100%) result = RQCard_whichmodule_specific( &card, world->modules[0]->module, <id ); if ( result != Status_OK ) { printf( "error(%d) : RQCard_whichmodule_specific\n", result ); } // wait event loop result = card.uf->eventloop( &card ); if ( result != Status_OK ) { printf( "error(%d) : card module event loop\n", result ); } #endif // CARD_PROTECT // get usable module moduleinfo = world->modules[0]; result = NFKM_getusablemodule( world, MODULE_ID, &moduleinfo ); if ( result != Status_OK ) { printf( "error(%d) : NFKM_getusablemodule\n", result ); return 1; } // ECDSA privkey のインポート result = importECDSAPrivate( priv_keyident ); if ( result != Status_OK ) { printf( "error : importECDSAPrivate\n" ); return 1; } printf( "ECDSA privkey import success.\n" ); // ECDSA pubkey result = importECDSAPublic( pub_keyident ); if ( result != Status_OK ) { printf( "error : importECDSAPublic\n" ); return 1; } printf( "ECDSA pubkey import success.\n" ); // list key #if 0 int key_num; NFKM_KeyIdent *keylist = NULL; result = NFKM_listkeys( handle, &key_num, &keylist, "simple", NULL ); if ( result != Status_OK ) { printf( "error(%d) : NFKM_listkeys\n", result ); } NFKM_KeyIdent **tkp = &keylist; for ( i = 0; i < key_num; i++ ) { printf( "appname : %s, ident : %s\n", tkp[i]->appname, tkp[i]->ident ); } #endif // verify key pair result = verifyECDSAKeyPair( priv_keyident, pub_keyident ); if ( result != Status_OK ) { printf( "error : verifyECDSAKeyPair\n" ); return 1; } printf( "ECDSA keypair verify success.\n" ); // end processing RQCard_fips_free( &card, &fips ); RQCard_destroy( &card ); NFKM_freeinfo( handle, &world, NULL ); NFastApp_Disconnect( nc, NULL ); NFastApp_Finish( handle, NULL ); return 0; } // main