ctr_eFuse/hsm_utils/import_ecdsa_keypair.c
kubodera_yuichi f748831d4a AESインポートの修正をECDSAインポートに逆輸入
git-svn-id: file:///Volumes/Transfer/gigaleak_20231201/2020-09-30%20-%20paladin.7z/paladin/ctr_eFuse@146 ff987cc8-cf2f-4642-8568-d52cce064691
2010-01-06 06:41:54 +00:00

969 lines
26 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// import key (+ encrypt, decrypt) test for nShield
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// openssl
#include <openssl/err.h>
#include <openssl/bn.h>
#include <openssl/sha.h>
#include <openssl/ec.h>
#include "ec_lcl.h"
#include <openssl/x509.h>
#include <openssl/aes.h>
#include <openssl/pem.h>
#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( &reg_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 <20>̍\<5C><><EFBFBD>v<EFBFBD>f<EFBFBD><66><EFBFBD>o<EFBFBD>C<EFBFBD>i<EFBFBD><69><EFBFBD>ɕϊ<C995>
{
// 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
// <20>o<EFBFBD>C<EFBFBD>i<EFBFBD><69><EFBFBD><EFBFBD>HSM<53><4D>Bignum<75>ɕϊ<C995>
{
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;
// <20><EFBFBD><E996A7><EFBFBD>ɂ<EFBFBD> DECRYPT <20><> SIGN
// <20><><EFBFBD>J<EFBFBD><4A><EFBFBD>ɂ<EFBFBD> ENCRYPT <20><> VERIFY <20><><EFBFBD><EFBFBD><EFBFBD>Z<EFBFBD>b<EFBFBD>g<EFBFBD>ł<EFBFBD><C582>Ȃ<EFBFBD><C882>H<EFBFBD>H
#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; // <20><><EFBFBD>O<EFBFBD><4F><EFBFBD>w<EFBFBD><EFBFBD><EFBFBD>Ƃ<EFBFBD>
cmd.args.import.data.data.ecprivate.d = privBn.d; // d <20><><EFBFBD><EFBFBD><EFBFBD>ݒ肷<DD92><E882B7><EFBFBD>Ηǂ<CE97>
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, &reg_key, NULL );
if ( result != Status_OK )
{
printf( "error(%d) : NFKM_newkey_makeblobsx\n", result );
return 1;
}
// record key to disk
result = NFKM_recordkey( handle, &reg_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( &reg_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 <20>̍\<5C><><EFBFBD>v<EFBFBD>f<EFBFBD><66><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EA82BC><EFBFBD>o<EFBFBD>C<EFBFBD>i<EFBFBD><69><EFBFBD>ɕϊ<C995>
{
// 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
// <20>o<EFBFBD>C<EFBFBD>i<EFBFBD><69><EFBFBD><EFBFBD>HSM<53><4D>Bignum<75>ɕϊ<C995>
{
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;
// <20><EFBFBD><E996A7><EFBFBD>ɂ<EFBFBD> DECRYPT <20><> SIGN
// <20><><EFBFBD>J<EFBFBD><4A><EFBFBD>ɂ<EFBFBD> ENCRYPT <20><> VERIFY <20><><EFBFBD><EFBFBD><EFBFBD>Z<EFBFBD>b<EFBFBD>g<EFBFBD>ł<EFBFBD><C582>Ȃ<EFBFBD><C882>H<EFBFBD>H
#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; // <20><><EFBFBD>O<EFBFBD><4F><EFBFBD>w<EFBFBD><EFBFBD><EFBFBD>Ƃ<EFBFBD>
cmd.args.import.data.data.ecpublic.Q.x = pubBn.qx; // qx
cmd.args.import.data.data.ecpublic.Q.y = pubBn.qy; // qy <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>w<EFBFBD><EFBFBD><E882B7><EFBFBD>΂悢<CE82>H
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, &reg_key, NULL );
if ( result != Status_OK )
{
printf( "error(%d) : NFKM_newkey_makeblobsx\n", result );
return 1;
}
// record key to disk
result = NFKM_recordkey( handle, &reg_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, &ltid );
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 <20>̃C<CC83><43><EFBFBD>|<7C>[<5B>g
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