// import key (+ encrypt, decrypt) test for nShield #include #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 MODULE_ID 1 #define DATA_LEN 256 // bytes #define KEY_FILE "/opt/nfast/work/ctr_eFuse/hsm_utils/real_key/dev/eFuse_aesKey.bin" const NFKM_KeyIdent keyident = { (char*)"simple", (char*)"efuse-aes-dev" }; //#define CARD_PROTECT //#define EXPORT_KEY //#define STRICT_FIPS unsigned char aes_key_data[32]; typedef struct _NFast_Call_Context { int notused; } NFast_Call_Context; NFast_Call_Context context; typedef struct NFast_Transaction_Context { M_Command cmd; M_Reply reply; } NFast_Transaction_Context; NFast_Transaction_Context tc; int main( int argc, char *argv[] ) { int i; int result = 0; 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 M_KeyID keyid; NFKM_Key *keyinfo; NFKM_CardSet *cardset = NULL; FILE *fp; unsigned char aesData[16]; // key data open & read printf( "filename : %s\n", KEY_FILE ); fp = fopen( KEY_FILE, "rb" ); if ( !fp ) { printf( "error : fopen\n" ); return 0; } fread( aesData, 16, 1, fp ); for( i = 0; i < 16; i++ ) printf( "%02X ", aesData[i] ); printf( "\n" ); // 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, my_bignumreceiveupcall, my_bignumsendlenupcall, my_bignumsendupcall, my_bignumfreeupcall, my_bignumformatupcall, NULL ); // 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 ); result = RQCard_ui_scroll( &card ); if ( result != Status_OK ) { printf( "error(%d) : RQCard_ui_xxx\n", result ); return 0; } // 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 ); return 0; } // wait event loop result = card.uf->eventloop( &card ); if ( result != Status_OK ) { printf( "error(%d) : card module event loop\n", result ); return 0; } #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 ); return 0; } // make ACL NFKM_MakeACLParams map; NFKM_MakeBlobsParams mbp; memset( &map, 0, sizeof( map ) ); if ( cardset != NULL ) map.f = NFKM_NKF_RecoveryEnabled | NFKM_NKF_ProtectionCardSet; else map.f = NFKM_NKF_RecoveryEnabled | NFKM_NKF_ProtectionModule; map.op_base = ( NFKM_DEFOPPERMS_ENCRYPT | NFKM_DEFOPPERMS_DECRYPT ); map.cs = cardset; result = NFKM_newkey_makeaclx( handle, nc, world, &map, &(tc.cmd.args.import.acl), NULL ); if ( result != Status_OK ) { printf( "error(%d) : NFKM_newkey_makeaclx\n", result ); return 0; } // import key tc.cmd.cmd = Cmd_Import; tc.cmd.args.import.module = MODULE_ID; tc.cmd.args.import.data.type = KeyType_Rijndael; tc.cmd.args.import.data.data.random.k.len = 16; tc.cmd.args.import.data.data.random.k.ptr = aesData; result = NFastApp_Transact( nc, NULL, &(tc.cmd), &(tc.reply), NULL ); if ( result != Status_OK ) { printf( "error(%d) : NFKM_newkey_makeaclx\n", result ); return 0; } // make blobs NFKM_Key reg_key; memset( &mbp, 0, sizeof( mbp ) ); memset( ®_key, 0, sizeof( reg_key ) ); mbp.f = map.f; mbp.kpriv = tc.reply.reply.import.key; mbp.lt = ltid; mbp.cs = cardset; 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) ); result = NFKM_newkey_makeblobsx( handle, nc, world, &mbp, ®_key, NULL ); if ( result != Status_OK ) { printf( "error(%d) : NFKM_newkey_makeblobsx\n", result ); return 0; } // record key to disk result = NFKM_recordkey( handle, ®_key, NULL ); if ( result != Status_OK ) { printf( "error(%d) : NFKM_recordkey\n", result ); return 0; } printf( "record key success : appname=%s, ident=%s\n", keyident.appname, keyident.ident ); // destroy key result = NFKM_cmd_destroy( handle, nc, 0, tc.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 ); return 0; } 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 result = NFKM_findkey( handle, keyident, &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 { printf( "aes is symmetric key!\n" ); 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 ); return 0; } #if 0 // get key info tc.cmd.cmd = Cmd_GetKeyInfo; tc.cmd.args.getkeyinfo.key = keyid; result = NFastApp_Transact( nc, NULL, &(tc.cmd), &(tc.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", tc.reply.reply.getkeyinfo.type ); #endif // 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 tc.cmd.cmd = Cmd_Encrypt; tc.cmd.args.encrypt.key = keyid; tc.cmd.args.encrypt.mech = Mech_RijndaelmCBCpNONE; tc.cmd.args.encrypt.plain.type = PlainTextType_Bytes; tc.cmd.args.encrypt.plain.data.bytes.data = enc_input; tc.cmd.args.encrypt.flags = Cmd_Encrypt_Args_flags_given_iv_present; tc.cmd.args.encrypt.given_iv = &enc_iv; result = NFastApp_Transact( nc, NULL, &(tc.cmd), &(tc.reply), NULL ); if ( result != Status_OK ) { printf( "error(%d) : FastApp_Transact(Cmd_Encrypt)\n", result ); return 0; } result = tc.reply.status; if ( result != Status_OK ) { printf( "error(%d) : reply.status(Cmd_Encrypt)\n", result ); return 0; } enc_output.len = tc.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 ); return 0; } enc_output.ptr = (unsigned char*)malloc( enc_output.len ); memcpy( enc_output.ptr, tc.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, &(tc.reply) ); // decrypt : my ver tc.cmd.cmd = Cmd_Decrypt; tc.cmd.args.decrypt.flags = 0; tc.cmd.args.decrypt.key = keyid; tc.cmd.args.decrypt.mech = Mech_RijndaelmCBCpNONE; tc.cmd.args.decrypt.cipher.mech = Mech_RijndaelmCBCpNONE; tc.cmd.args.decrypt.cipher.data.generic128.cipher = dec_input; tc.cmd.args.decrypt.cipher.iv = dec_iv.iv; tc.cmd.args.decrypt.reply_type = PlainTextType_Bytes; result = NFastApp_Transact( nc, NULL, &(tc.cmd), &(tc.reply), NULL ); if ( result != Status_OK ) { printf( "error(%d) : FastApp_Transact(Cmd_Decrypt)\n", result ); return 0; } result = tc.reply.status; if ( result != Status_OK ) { printf( "error(%d) : reply.status(Cmd_Decrypt)\n", result ); return 0; } dec_output.len = tc.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 ); return 0; } dec_output.ptr = (unsigned char*)malloc( dec_output.len ); memcpy( dec_output.ptr, tc.reply.reply.decrypt.plain.data.bytes.data.ptr, dec_output.len ); printf( "decrypt ok.\n" ); NFastApp_Free_Reply( handle, NULL, NULL, &(tc.reply) ); // key destroy memset( &(tc.cmd), 0, sizeof( tc.cmd ) ); // fail if NFastApp_Free_Command tc.cmd.cmd = Cmd_Destroy; tc.cmd.args.destroy.key = keyid; result = NFastApp_Transact( nc, NULL, &(tc.cmd), &(tc.reply), NULL ); if ( result != Status_OK ) { printf( "error(%d) : NFastApp_Transact(Cmd_Destroy)\n", result ); return 0; } NFastApp_Free_Reply( handle, NULL, NULL, &(tc.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