// import key (+ encrypt, decrypt) test for nShield #include #include #include #include // openssl #include #include #include #include #include #include #include #include "nfastapp.h" #include "nfkm.h" #include "rqcard-applic.h" #include "rqcard-fips.h" #include "simplebignum.h" #include "ncthread-upcalls.h" //#include "picky-upcalls.h" #include "simplecmd.h" #define PRIV_KEY_FILE "/opt/nfast/work/rsa-priv-key2048.der" #define PUB_KEY_FILE "/opt/nfast/work/rsa-pub-key2048.der" #define MODULE_ID 1 #define DATA_LEN 256 // bytes typedef struct _NFast_Call_Context { int notused; } NFast_Call_Context; NFast_Call_Context context; // RSA private key data typedef struct { struct NFast_Bignum *p; struct NFast_Bignum *q; struct NFast_Bignum *dmp1; struct NFast_Bignum *dmq1; struct NFast_Bignum *iqmp; struct NFast_Bignum *e; } RSAPrivateKeyData; // RSA public key data typedef struct { struct NFast_Bignum *e; struct NFast_Bignum *n; } RSAPublicKeyData; static void *my_malloc( size_t nbytes, struct NFast_Call_Context *cctx, struct NFast_Transaction_Context *tctx ); static void *my_realloc( void *ptr, size_t nbytes, struct NFast_Call_Context *cctx, struct NFast_Transaction_Context *tctx ); static void my_free( void *ptr, struct NFast_Call_Context *cctx, struct NFast_Transaction_Context *tctx ); int sbn_bin2bignum ( struct NFast_Bignum **ppBN_out, struct NFast_Application *app, const unsigned char *bin, const int size ); void PrintArray( char *pStr, const unsigned char *pData, int length ); // bignum upcalls int my_bignumreceiveupcall(struct NFast_Application *app, struct NFast_Call_Context *cctx, struct NFast_Transaction_Context *tctx, M_Bignum *bignum, int nbytes, const void *source, int msbitfirst, int mswordfirst); int my_bignumsendlenupcall( struct NFast_Application *app, struct NFast_Call_Context *cctx, struct NFast_Transaction_Context *tctx, const M_Bignum *bignum, int *nbytes_r ); int my_bignumsendupcall(struct NFast_Application *app, struct NFast_Call_Context *cctx, struct NFast_Transaction_Context *tctx, const M_Bignum *bignum, int nbytes, void *dest, int msbitfirst, int mswordfirst); void my_bignumfreeupcall(struct NFast_Application *app, struct NFast_Call_Context *cctx, struct NFast_Transaction_Context *tctx, M_Bignum *bignum); int my_bignumformatupcall(struct NFast_Application *app, struct NFast_Call_Context *cctx, struct NFast_Transaction_Context *tctx, int *msbitfirst_io, int *mswordfirst_io); const NFast_MallocUpcalls my_malloc_upcalls = { my_malloc, my_realloc, my_free }; static void *my_malloc( size_t nbytes, struct NFast_Call_Context *cctx, struct NFast_Transaction_Context *tctx ) { return malloc( nbytes ); } static void *my_realloc( void *ptr, size_t nbytes, struct NFast_Call_Context *cctx, struct NFast_Transaction_Context *tctx ) { return realloc( ptr, nbytes ); } static void my_free( void *ptr, struct NFast_Call_Context *cctx, struct NFast_Transaction_Context *tctx ) { free( ptr ); } int my_bignumreceiveupcall(struct NFast_Application *app, struct NFast_Call_Context *cctx, struct NFast_Transaction_Context *tctx, M_Bignum *bignum, int nbytes, const void *source, int msbitfirst, int mswordfirst) { struct NFast_Bignum *pBN; printf( "my_bignumreceiveupcall\n" ); if ( nbytes > MAXBIGNUMBITS/8 ) return Status_OutOfRange; assert( (nbytes & 3)==0 ); pBN = (struct NFast_Bignum *)NFastApp_Malloc(app, sizeof(struct NFast_Bignum), cctx, tctx); if ( !pBN ) return NOMEM; nfutil_copybytes(pBN->bytes, (const unsigned char *)source, nbytes, 0, 0); pBN->msb_first = msbitfirst; pBN->msw_first = mswordfirst; pBN->nbytes=nbytes; *bignum=pBN; return Status_OK; } int my_bignumsendlenupcall( struct NFast_Application *app, struct NFast_Call_Context *cctx, struct NFast_Transaction_Context *tctx, const M_Bignum *bignum, int *nbytes_r ) { printf( "my_bignumsendlenupcall\n" ); assert( ((*bignum)->nbytes & 3)==0 ); *nbytes_r= (*bignum)->nbytes; return Status_OK; } int my_bignumsendupcall(struct NFast_Application *app, struct NFast_Call_Context *cctx, struct NFast_Transaction_Context *tctx, const M_Bignum *bignum, int nbytes, void *dest, int msbitfirst, int mswordfirst) { int swapends, swapwords; struct NFast_Bignum *pBN = *bignum; printf( "my_bignumsendupcall\n" ); assert( pBN->nbytes==nbytes ); /* Is format which we're sending in the same as that of the bignumber? (NB '!' used to constrain result to 0,1 range) If not, work out which ends to swap. */ swapends = (!msbitfirst) ^ (!pBN->msb_first); swapwords = (!mswordfirst) ^ (!pBN->msw_first); nfutil_copybytes( (unsigned char *)dest, (*bignum)->bytes, nbytes, swapends, swapwords ); return Status_OK; } void my_bignumfreeupcall(struct NFast_Application *app, struct NFast_Call_Context *cctx, struct NFast_Transaction_Context *tctx, M_Bignum *bignum) { printf( "my_bignumfreeupcall\n" ); NFastApp_Free(app, (*bignum), cctx, tctx); *bignum=NULL; } int my_bignumformatupcall(struct NFast_Application *app, struct NFast_Call_Context *cctx, struct NFast_Transaction_Context *tctx, int *msbitfirst_io, int *mswordfirst_io) { printf( "my_bignumformatupcall\n" ); /* Send to the module in little-endian format. (This is not officially necessary. However, some versions of the monitor (Maintenance mode) don't accept big-endian bignums due to a bug) */ *msbitfirst_io=0; *mswordfirst_io=0; return Status_OK; } // bin データを NFastApp の BigNum データに変換する int sbn_bin2bignum ( struct NFast_Bignum **ppBN_out, struct NFast_Application *app, const unsigned char *bin, const int size ) { struct NFast_Bignum *pBN; int len, i; len = size; if ( len > MAXBIGNUMBITS/4 ) return Status_OutOfRange; pBN = (struct NFast_Bignum *)NFastApp_Malloc( app, sizeof(struct NFast_Bignum), NULL, NULL ); if ( !pBN ) return NOMEM; pBN->msb_first = 0; pBN->msw_first = 0; for ( i = 0; i < len; i++ ) pBN->bytes[i] = bin[len-1-i]; while ( (i & 3) != 0 ) pBN->bytes[i++] = 0; pBN->nbytes = i; *ppBN_out = pBN; #if 0 PrintArray( (char*)"bin2bn array", (const char*)pBN->bytes, pBN->nbytes ); #endif return Status_OK; } // sbn_bin2bignum 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" ); } int main( int argc, char *argv[] ) { int i; int result = 0; int rand_size = 80; M_Command cmd; M_Reply reply; memset( &cmd, 0, sizeof( cmd ) ); memset( &reply, 0, sizeof( reply ) ); NFast_AppHandle handle; NFastApp_Connection nc; NFKM_WorldInfo *world = NULL; RQCard card; RQCard_FIPS fips; M_KeyID ltid; // the cardset loaded into the module M_KeyID keyid; NFKM_Key *keyinfo; if ( argc == 2 ) rand_size = atoi( argv[1] ); // load rsa data (private) RSA *privkey = NULL; FILE *fp; fp = fopen( PRIV_KEY_FILE, "rb" ); if ( !fp ) { printf( "error : open %s file\n", PRIV_KEY_FILE ); return 0; } privkey = d2i_RSAPrivateKey_fp( fp, NULL ); if ( !privkey ) { printf( "error : d2i_RSAPrivateKey_fp\n" ); return 0; } #if 0 printf( "RSA(p) : %d bytes\n", BN_num_bytes( privkey->p ) ); printf( "RSA(q) : %d bytes\n", BN_num_bytes( privkey->q ) ); printf( "RSA(dmp1) : %d bytes\n", BN_num_bytes( privkey->dmp1 ) ); printf( "RSA(dmq1) : %d bytes\n", BN_num_bytes( privkey->dmq1 ) ); printf( "RSA(iqmp) : %d bytes\n", BN_num_bytes( privkey->iqmp ) ); printf( "RSA(e) : %d bytes\n", BN_num_bytes( privkey->e ) ); #endif // p unsigned char *pPtr; int pLen = BN_num_bytes( privkey->p ); pPtr = (char *)malloc( pLen ); if ( pLen != BN_bn2bin( privkey->p, pPtr ) ) { printf( "BN_bn2bin failed!(p)\n" ); } // q unsigned char *qPtr; int qLen = BN_num_bytes( privkey->q ); qPtr = (char *)malloc( qLen ); if ( qLen != BN_bn2bin( privkey->q, qPtr ) ) { printf( "BN_bn2bin failed!(q)\n" ); } // dmp1 unsigned char *dmp1Ptr; int dmp1Len = BN_num_bytes( privkey->dmp1 ); dmp1Ptr = (char *)malloc( dmp1Len ); if ( dmp1Len != BN_bn2bin( privkey->dmp1, dmp1Ptr ) ) { printf( "BN_bn2bin failed!(dmp1)\n" ); } // dmq1 unsigned char *dmq1Ptr; int dmq1Len = BN_num_bytes( privkey->dmq1 ); dmq1Ptr = (char *)malloc( dmq1Len ); if ( dmq1Len != BN_bn2bin( privkey->dmq1, dmq1Ptr ) ) { printf( "BN_bn2bin failed!(dmq1)\n" ); } // iqmp unsigned char *iqmpPtr; int iqmpLen = BN_num_bytes( privkey->iqmp ); iqmpPtr = (char *)malloc( iqmpLen ); if ( iqmpLen != BN_bn2bin( privkey->iqmp, iqmpPtr ) ) { printf( "BN_bn2bin failed!(dmq1)\n" ); } // e unsigned char *ePtr; int eLen = BN_num_bytes( privkey->e ); ePtr = (char *)malloc( eLen ); if ( eLen != BN_bn2bin( privkey->e, ePtr ) ) { printf( "BN_bn2bin failed!(e)\n" ); } printf( "\n" ); #if 0 printf( "RSA(p) : 0x%08X\n", (unsigned int)pPtr ); printf( "RSA(q) : 0x%08X\n", (unsigned int)qPtr ); printf( "RSA(dmp1) : 0x%08X\n", (unsigned int)dmp1Ptr ); printf( "RSA(dmq1) : 0x%08X\n", (unsigned int)dmq1Ptr ); printf( "RSA(iqmp) : 0x%08X\n", (unsigned int)iqmpPtr ); printf( "RSA(e) : 0x%08X\n", (unsigned int)ePtr ); #endif // init nFast result = NFastApp_InitEx( &handle, NULL, NULL ); if ( result != Status_OK ) { printf( "error(%d) : NFastApp_InitEx\n", result ); return 0; } // connecting to hardserver result = NFastApp_Connect( handle, &nc, 0, NULL ); if ( result != Status_OK ) { printf( "error(%d) : NFastApp_Connect\n", result ); return 0; } // set bignum upcalls setting result = NFastApp_SetBignumUpcalls( handle, sbn_bignumreceiveupcall, sbn_bignumsendlenupcall, sbn_bignumsendupcall, sbn_bignumfreeupcall, sbn_bignumformatupcall, NULL ); if ( result != Status_OK ) { printf( "error(%d) : NFastApp_SetBignumUpcalls\n", result ); return 0; } // NFKM getinfo result = NFKM_getinfo( handle, &world, NULL ); if ( result != Status_OK ) { printf( "error(%d) : NFKM_getinfo\n", result ); return 0; } // init card-loading lib result = RQCard_init( &card, handle, nc, world, NULL ); if ( result != Status_OK ) { printf( "error(%d) : RQCard_init\n", result ); return 0; } // init FIPS state result = RQCard_fips_init( &card, &fips ); if ( result != Status_OK ) { printf( "error(%d) : RQCard_fips_init\n", result ); return 0; } // ui select result = RQCard_ui_default( &card ); if ( result != Status_OK ) { printf( "error(%d) : RQCard_ui_default\n", result ); return 0; } // get strict-FIPS authorization #if 0 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 #if 1 // 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 NFKM_CardSet *cardset = NULL; 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 // get usable module NFKM_ModuleInfo *moduleinfo = world->modules[0]; result = NFKM_getusablemodule( world, MODULE_ID, &moduleinfo ); if ( result != Status_OK ) { printf( "error(%d) : NFKM_getusablemodule\n", result ); } // make ACL NFKM_MakeACLParams map; memset( &map, 0, sizeof( map ) ); map.f = NFKM_NKF_RecoveryEnabled | NFKM_NKF_ProtectionCardSet; // 暗号化と復号化、署名とベリファイなど、相反する操作を持たせることはできない(エラーになる) // e.g. NFKM_DEFOPPERMS_SIGN | NFKM_DEFOPPERMS_VERIFY -> エラー // e.g. NFKM_DEFOPPERMS_ENCRYPT | NFKM_DEFOPPERMS_DECRYPT -> エラー map.op_base = NFKM_DEFOPPERMS_SIGN | NFKM_DEFOPPERMS_DECRYPT; 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 ); } #if 0 // 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 ); } #endif // convert bin -> M_Bignum struct NFast_Bignum *pBn = NULL; struct NFast_Bignum *qBn = NULL; struct NFast_Bignum *dmp1Bn = NULL; struct NFast_Bignum *dmq1Bn = NULL; struct NFast_Bignum *iqmpBn = NULL; struct NFast_Bignum *eBn = NULL; { // p result = sbn_bin2bignum( &pBn, handle, pPtr, pLen ); if ( result != Status_OK ) { printf( "error(%d) : sbn_bin2bignum( p )\n", result ); return 0; } // q result = sbn_bin2bignum( &qBn, handle, qPtr, qLen ); if ( result != Status_OK ) { printf( "error(%d) : sbn_bin2bignum( q )\n", result ); return 0; } // dmp1 result = sbn_bin2bignum( &dmp1Bn, handle, dmp1Ptr, dmp1Len ); if ( result != Status_OK ) { printf( "error(%d) : sbn_bin2bignum( dmp1 )\n", result ); return 0; } // dmq1 result = sbn_bin2bignum( &dmq1Bn, handle, dmq1Ptr, dmq1Len ); if ( result != Status_OK ) { printf( "error(%d) : sbn_bin2bignum( dmq1 )\n", result ); return 0; } // iqmp result = sbn_bin2bignum( &iqmpBn, handle, iqmpPtr, iqmpLen ); if ( result != Status_OK ) { printf( "error(%d) : sbn_bin2bignum( iqmp )\n", result ); return 0; } // e result = sbn_bin2bignum( &eBn, handle, ePtr, eLen ); if ( result != Status_OK ) { printf( "error(%d) : sbn_bin2bignum( e )\n", result ); return 0; } } printf( "import ...\n" ); // import key NFKM_KeyIdent keyident = { (char*)"simple", (char*)"rsa-import-privkey" }; cmd.cmd = Cmd_Import; cmd.args.import.module = MODULE_ID; cmd.args.import.data.type = KeyType_RSAPrivate; cmd.args.import.data.data.rsaprivate.p = pBn; cmd.args.import.data.data.rsaprivate.q = qBn; cmd.args.import.data.data.rsaprivate.dmp1 = dmp1Bn; cmd.args.import.data.data.rsaprivate.dmq1 = dmq1Bn; cmd.args.import.data.data.rsaprivate.iqmp = iqmpBn; cmd.args.import.data.data.rsaprivate.e = eBn; result = NFastApp_Transact( nc, NULL, &cmd, &reply, NULL ); if ( result != Status_OK ) { printf( "error(%d) : Cmd_Import\n", result ); } result = reply.status; if ( result != Status_OK ) { printf( "error(%d) : Cmd_Import(reply)\n", result ); } printf( "keyid : 0x%08X\n", (unsigned int)reply.reply.import.key ); printf( "done. next : make blob ...\n" ); // make blobs NFKM_MakeBlobsParams mbp; NFKM_Key reg_key; memset( &mbp, 0, sizeof( mbp ) ); memset( ®_key, 0, sizeof( reg_key ) ); reg_key.v = Key__maxversion; // TORIAEZU Version Max (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 0; } printf( "done. next : record blob ...\n" ); // record key to disk result = NFKM_recordkey( handle, ®_key, NULL ); if ( result != Status_OK ) { printf( "error(%d) : NFKM_recordkey\n", result ); } printf( "record key success?\n" ); // destroy key result = NFKM_cmd_destroy( handle, nc, 0, reply.reply.import.key, "import.key", NULL ); // 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 // find key NFKM_KeyIdent ki_v = { (char*)"simple", (char*)"rsa-import-privkey" }; printf( "appname : %s, ident : %s\n", ki_v.appname, ki_v.ident ); result = NFKM_findkey( handle, ki_v, &keyinfo, NULL ); if ( result != Status_OK ) { printf( "error(%d) : NFKM_findkey\n", result ); } // load blob M_ByteBlock *blobptr; if ( keyinfo->pubblob.len) blobptr = &keyinfo->pubblob; else { blobptr = &keyinfo->privblob; } result = NFKM_cmd_loadblob( handle, nc, moduleinfo->module, blobptr, ltid, &keyid, "loading key blob", NULL ); if ( result != Status_OK ) { printf( "error(%d) : NFKM_cmd_loadblob\n", result ); } printf( "key ID : %u\n", (unsigned int)keyid ); // get key info cmd.cmd = Cmd_GetKeyInfo; cmd.args.getkeyinfo.key = keyid; result = NFastApp_Transact( nc, NULL, &cmd, &reply, NULL ); if ( result != Status_OK ) { printf( "error(%d) : FastApp_Transact(Cmd_GetKeyInfo)\n", result ); } // if type == 30 then Rijndael(AES) printf( "keytype : %d\n", reply.reply.getkeyinfo.type ); // encrypt & dectypt test { M_ByteBlock enc_input, dec_input; M_ByteBlock enc_output, dec_output; M_IV base_iv, enc_iv, dec_iv; // data setting enc_input.len = DATA_LEN; enc_input.ptr = (unsigned char*)malloc( DATA_LEN ); for ( i = 0; i < enc_input.len; i++ ) enc_input.ptr[i] = i; base_iv.mech = Mech_RijndaelmCBCpNONE; for ( i = 0; i < 16; i++ ) base_iv.iv.generic128.iv.bytes[i] = i; enc_iv = base_iv; dec_iv = base_iv; // encrypt : my ver cmd.cmd = Cmd_Encrypt; cmd.args.encrypt.key = keyid; cmd.args.encrypt.mech = Mech_RijndaelmCBCpNONE; cmd.args.encrypt.plain.type = PlainTextType_Bytes; cmd.args.encrypt.plain.data.bytes.data = enc_input; cmd.args.encrypt.flags = Cmd_Encrypt_Args_flags_given_iv_present; cmd.args.encrypt.given_iv = &enc_iv; result = NFastApp_Transact( nc, NULL, &cmd, &reply, NULL ); if ( result != Status_OK ) { printf( "error(%d) : FastApp_Transact(Cmd_Encrypt)\n", result ); } result = reply.status; if ( result != Status_OK ) { printf( "error(%d) : reply.status(Cmd_Encrypt)\n", result ); } enc_output.len = reply.reply.encrypt.cipher.data.generic128.cipher.len; if ( enc_output.len != DATA_LEN ) { printf( "error : output data size isn't %d bytes(Cmd_Encrypt)\n", (int)enc_output.len ); } enc_output.ptr = (unsigned char*)malloc( enc_output.len ); memcpy( enc_output.ptr, reply.reply.encrypt.cipher.data.generic128.cipher.ptr, enc_output.len ); printf( "encrypt ok\n" ); dec_input.len = enc_output.len; dec_input.ptr = (unsigned char*)malloc( dec_input.len ); memcpy( dec_input.ptr, enc_output.ptr, DATA_LEN ); NFastApp_Free_Reply( handle, NULL, NULL, &reply ); // decrypt : my ver cmd.cmd = Cmd_Decrypt; cmd.args.decrypt.flags = 0; cmd.args.decrypt.key = keyid; cmd.args.decrypt.mech = Mech_RSApPKCS1; cmd.args.decrypt.cipher.mech = Mech_RSApPKCS1; cmd.args.decrypt.cipher.data.generic128.cipher = dec_input; cmd.args.decrypt.cipher.iv = dec_iv.iv; cmd.args.decrypt.reply_type = PlainTextType_Bytes; result = NFastApp_Transact( nc, NULL, &cmd, &reply, NULL ); if ( result != Status_OK ) { printf( "error(%d) : FastApp_Transact(Cmd_Decrypt)\n", result ); } result = reply.status; if ( result != Status_OK ) { printf( "error(%d) : reply.status(Cmd_Decrypt)\n", result ); } dec_output.len = reply.reply.decrypt.plain.data.bytes.data.len; if ( dec_output.len != DATA_LEN ) { printf( "error : output size isn't %d bytes(Cmd_Decrypt)\n", (int)enc_output.len ); } dec_output.ptr = (unsigned char*)malloc( dec_output.len ); memcpy( dec_output.ptr, reply.reply.decrypt.plain.data.bytes.data.ptr, dec_output.len ); printf( "decrypt ok\n" ); NFastApp_Free_Reply( handle, NULL, NULL, &reply ); // key destroy memset( &cmd, 0, sizeof( cmd ) ); // fail if NFastApp_Free_Command cmd.cmd = Cmd_Destroy; cmd.args.destroy.key = keyid; result = NFastApp_Transact( nc, NULL, &cmd, &reply, NULL ); if ( result != Status_OK ) { printf( "error(%d) : NFastApp_Transact(Cmd_Destroy)\n", result ); } NFastApp_Free_Reply( handle, NULL, NULL, &reply ); // data show printf( "enc_input : (%d bytes)", (int)enc_input.len ); for ( i = 0; i < enc_input.len; i++ ) { if ( i % 16 == 0 ) printf( "\n" ); printf( "%02X ", enc_input.ptr[i] ); } printf( "\n" ); printf( "\nenc_output : (%d bytes)", (int)enc_output.len ); for ( i = 0; i < enc_output.len; i++ ) { if ( i % 16 == 0 ) printf( "\n" ); printf( "%02X ", enc_output.ptr[i] ); } printf( "\n" ); printf( "\ndec_output : (%d bytes)", (int)dec_output.len ); for ( i = 0; i < dec_output.len; i++ ) { if ( i % 16 == 0 ) printf( "\n" ); printf( "%02X ", dec_output.ptr[i] ); } printf( "\n" ); } // encrypt & decrypt // end processing RQCard_fips_free( &card, &fips ); RQCard_destroy( &card ); NFKM_freekey( handle, keyinfo, NULL ); NFKM_freeinfo( handle, &world, NULL ); NFastApp_Disconnect( nc, NULL ); NFastApp_Finish( handle, NULL ); return 0; } // main