Ejemplo n.º 1
0
int ChangeSoPin(const char *oldsopin, const char *newsopin)
{
	uint16 sw1sw2;
	int rc;
	uint8 so_pin_so_pin[8 + 8];
	if (strlen(oldsopin) != 16) {
		printf("old SO_PIN must have 16 hex-digits\n");
		return ERR_INVALID;
	}
	rc = Hex2Bin(oldsopin, 16, so_pin_so_pin);
	if (rc)
		return rc;
	if (strlen(newsopin) != 16) {
		printf("new SO_PIN must have 16 hex-digits\n");
		return ERR_INVALID;
	}
	rc = Hex2Bin(newsopin, 16, so_pin_so_pin + 8);
	if (rc)
		return rc;
	rc = SC_Open(0, 0);
	if (rc < 0)
		return rc;
	/* - SmartCard-HSM: CHANGE REFERENCE DATA */
	rc = SC_ProcessAPDU(
		0, 0x00,0x24,0x00,0x88,
		so_pin_so_pin, 8 + 8,
		NULL, 0,
		&sw1sw2);
	SC_Close();
	if (rc < 0)
		return rc;
	return sw1sw2;
}
Ejemplo n.º 2
0
//---------------------------------------------------------------------------
void __fastcall TForm1::Button4Click(TObject *Sender)
{
    memset(file_buf, 0xFF, sizeof(file_buf));
    Hex2Bin(edtWorkFilename->Text, false);

    if (ComboBox1->ItemIndex == 0)
    {
        TFileStream * file = new TFileStream(ExtractFilePath(Application->ExeName)+"csp850aupdate.bin", fmCreate);
        file->Write(file_buf+0x4000, max_address-0x4000);
        delete file;
        ShowMessage("生成升级文件");
    }
    else if (ComboBox1->ItemIndex == 1)
    {
        TFileStream * file = new TFileStream(ExtractFilePath(Application->ExeName)+"smartpower_update.bin", fmCreate);
        //xor 0x87
        for (int i=0x4000;i<max_address;i++)
        {
            file_buf[i] ^= 0x87;
        }
        file->Write(file_buf+0x4000, max_address-0x4000);
        delete file;
        ShowMessage("生成升级文件");
    }
}
Ejemplo n.º 3
0
/*将两个数据异或,从data中输出结果*/
char *   XOR(  char* data,   char* data2,int len,char * _______XOR)
{
	int i ;
	int bLenght=len/2;
	unsigned char b[strlen(data)/2];
	unsigned char b2[strlen(data2)/2];
	Hex2Bin(data,b);
	Hex2Bin(data2,b2);
	for ( i = 0; i < bLenght; i++)
	{
		b[i] =  b[i]  ^  b2[i];
	}
	Bin2Hex(b,bLenght,_______XOR);
	return _______XOR;

}
Ejemplo n.º 4
0
int UnlockPin(const char *sopin)
{
	uint16 sw1sw2;
	int rc;
	uint8 so_pin[8];
	if (strlen(sopin) != 16) {
		printf("SO_PIN must have 16 hex-digits\n");
		return ERR_INVALID;
	}
	rc = Hex2Bin(sopin, 16, so_pin);
	if (rc)
		return rc;
	rc = SC_Open(0, 0);
	if (rc < 0)
		return rc;
	/* - SmartCard-HSM: RESET RETRY COUNTER */
	rc = SC_ProcessAPDU(
		0, 0x00,0x2C,0x01,0x81,
		so_pin, 8,
		NULL, 0,
		&sw1sw2);
	SC_Close();
	if (rc < 0)
		return rc;
	return sw1sw2;
}
Ejemplo n.º 5
0
 MD5Hash HashFromString(const char* str)
 {
   MD5Hash result;
   Require(std::strlen(str) == 2 * result.size());
   for (MD5Hash::iterator it = result.begin(), lim = result.end(); it != lim; ++it)
   {
     *it = Hex2Bin(str[0], str[1]);
     str += 2;
   }
   return result;
 }
Ejemplo n.º 6
0
//---------------------------------------------------------------------------
void __fastcall TForm1::Button3Click(TObject *Sender)
{
    memset(file_buf, 0xFF, sizeof(file_buf));
    Hex2Bin(edtIapFilename->Text, false);
    Hex2Bin(edtWorkFilename->Text, false);

    if (ComboBox1->ItemIndex == 0)
    {
        TFileStream * file = new TFileStream(ExtractFilePath(Application->ExeName)+"CSP850A_iap.bin", fmCreate);
        file->Write(file_buf, 65536);
        delete file;
        ShowMessage("生成下载文件");
    }
    else if (ComboBox1->ItemIndex == 1)
    {
        TFileStream * file = new TFileStream(ExtractFilePath(Application->ExeName)+"smartpower_iap.bin", fmCreate);
        file->Write(file_buf, 131072);
        delete file;
        ShowMessage("生成下载文件");
    }
}
Ejemplo n.º 7
0
__LIB_NAME_SPACE_BEGIN__
void TerminalTagSet::Load(const char *name)
{
	XMLCfgFile cfg;
	cfg.Load(name);
	auto tmp = cfg.GetList<const char *>("TLV");

	map_.clear();
	for (auto &x : tmp)
	{
		Add(BerTLV(Hex2Bin(x)));
	}
}
Ejemplo n.º 8
0
bool CPrefsDialog::CancelClicked()
{
	char s[256];
	
	ResetFontSheet();
	
	SetOn("autorecalc", fAutoRecalc);
	SetOn("displayzero", fDisplayZero);
	
	s[1] = 0;
	s[0] = gDecimalPoint;
	SetText("decsep", s);
	s[0] = gThousandSeparator;
	SetText("thoussep", s);
	s[0] = gListSeparator;
	SetText("listsep", s);
	s[0] = gTimeSeparator;
	SetText("timesep", s);
	s[0] = gDateSeparator;
	SetText("datesep", s);
	fDMY->FindItem(gPrefs->GetPrefString("date order"))->SetMarked(true);
	SetOn("24 hours", g24Hours);
	SetOn("excel", gPrefs->GetPrefInt("Excel keys", 0));
	SetOn("grayselect", gPrefs->GetPrefInt("Select Gray", 0));
	SetOn(gPrefs->GetPrefInt("start with new", 1) ? "donew" : "doopen", B_CONTROL_ON);
	SetOn("formula starts with equal", gPrefs->GetPrefInt("formula starts with equal", 0));
	SetOn("dark gridlines", gPrefs->GetPrefInt("dark gridlines"));
	
	SetText("c_symbol", gPrefs->GetPrefString("c_symbol", "$"));
	SetOn(gPrefs->GetPrefInt("c_before", 1) ? "c_before" : "c_after", B_CONTROL_ON);
	SetOn("c_neg_par", gPrefs->GetPrefInt("c_neg_par", 1) ? B_CONTROL_ON : B_CONTROL_OFF);
	sprintf(s, "%d", gPrefs->GetPrefInt("c_digits"));
	SetText("c_digits", s);

	if (fPageSetup) FREE(fPageSetup);
	fPageSetup = (char *)Hex2Bin(gPrefs->GetPrefString("default page setup", ""), fPageSetupSize);
	
	SetOn("prgrid", fPrGrid);
	SetOn("prhead", fPrBorders);
	SetOn("dispgrid", fShGrid);
	SetOn("disphead", fShBorders);
	
	BButton *b;
	b = (BButton *)FindView("ok");
	b->SetEnabled(false);
	b = (BButton *)FindView("cancel");
	b->SetEnabled(false);
	
	return false;
} /* CPrefsDialog::CancelClicked */
Ejemplo n.º 9
0
int GetBinData( const char* p_szInput, char* p_pData, int* p_pLen )
{
    switch ( p_szInput[0] )
    {
    case 's' :
    case 'S':
		*p_pLen = sprintf(p_pData, p_szInput+2) + 1;
        //strcpy( p_pData, p_szInput + 2 );
        //LOG("Sz data: %s", p_pData );
        //*p_pLen = strlen(p_pData)+1;
        break;
    case 'x':
    case 'X':
        {
            *p_pLen = Hex2Bin( p_szInput+2, p_pData );
            break;
        }
    }

    return 1;
}
Ejemplo n.º 10
0
int SetPin(const char *pin, const char *sopin)
{
	uint16 sw1sw2;
	int rc;
	uint8 so_pin_pin[8 + 16];
	int pin_len = strlen(pin);
	if (!(6 <= pin_len && pin_len <= 16)) {
		printf("PIN must have 6 - 16 chars\n");
		return ERR_INVALID;
	}
	if (sopin == 0) {
		memcpy(so_pin_pin, "\x35\x37\x36\x32\x31\x38\x38\x30", 8);
	} else {
		if (strlen(sopin) != 16) {
			printf("SO_PIN must have 16 hex-digits\n");
			return ERR_INVALID;
		}
		rc = Hex2Bin(sopin, 16, so_pin_pin);
		if (rc)
			return rc;
	}
	memcpy(so_pin_pin + 8, pin, pin_len); /* no 0 terminator */
	rc = SC_Open(0, 0);
	if (rc < 0)
		return rc;
	/* - SmartCard-HSM: RESET RETRY COUNTER */
	rc = SC_ProcessAPDU(
		0, 0x00,0x2C,0x00,0x81,
		so_pin_pin, 8 + pin_len,
		NULL, 0,
		&sw1sw2);
	SC_Close();
	if (rc < 0)
		return rc;
	return sw1sw2;
}
Ejemplo n.º 11
0
char * MAC(char* data,int dataLength, char * ran, char * key16)
{
	int key16Length =32 ;
	char keya[17];
	char keyb[17];
	char d3[17];
	char d4[17];
	char result[17];
	memcpy( keya ,key16, key16Length / 2);
	memcpy( keyb  , (char*)&key16[key16Length / 2],key16Length / 2);
	keya[16]=0;
	keyb[16]=0;
	memset( d3 ,0x00,sizeof(d3));
	memset( d4 ,0x00,sizeof(d3));
	memset( result,0x00,sizeof(16));
	echomac("bb");
	if (dataLength >= 16)
	{
		unsigned char Ran9[9];
		unsigned char PrTemp[17];
		memcpy(d3, data, 16);
		PrTemp[16] = 0x00;
		d3[16]=0;
		XOR(PadRight(Substring(ran,0,8,Ran9), 16, '0',PrTemp),  d3,16,result);
		echomac("bb");
		if (dataLength % 16 == 0)
		{
			int i ;
			for ( i = 1; i <dataLength / 16; i++)
			{
				unsigned char resultBin[8],keyaBin[8] ;				;
				enc(Hex2Bin(keya,keyaBin), Hex2Bin(result,resultBin));
				Bin2Hex(resultBin,8,result);
				printf( result);
				Substring(data,i * 16, 16,d3);
				XOR(result, d3,16,result);
				memcpy(d4 , (char*)&"8000000000000000",16);
				echomac("bb");
			}
			if (dataLength == 16) 
			{
				memcpy(d4 ,"8000000000000000",16);
			}
			echomac("bb");
			unsigned char temp222[8];Hex2Bin(result,temp222);
			unsigned char keyaXXX[8];Hex2Bin(keya,keyaXXX);
			unsigned char keybXXX[8];Hex2Bin(keyb,keybXXX);
			enc(keyaXXX, temp222);
			Bin2Hex(temp222,8,result);			
			XOR(result, d4,16,result);			
			Hex2Bin(result,temp222);
			enc(keyaXXX, temp222);
			Bin2Hex(temp222,8,result);			
			dec(keybXXX, temp222);
			Bin2Hex(temp222,8,result);			
			enc(keyaXXX, temp222);
			Bin2Hex(temp222,8,result);	
			echomac("bb");
		}
		else
		{
			
			int i ;
			unsigned char keyaXXX1[8];Hex2Bin(keya,keyaXXX1);
			unsigned char keybXXX1[8];Hex2Bin(keyb,keybXXX1);
			echomac("bb");
			for ( i = 1; i < dataLength / 16; i++)
			{
				unsigned char temp4441[8];Hex2Bin(result,temp4441);
				unsigned char temp4442keya[8];Hex2Bin(keya,temp4442keya);
				enc(temp4442keya, temp4441);
				Bin2Hex(temp4441,8,result);
				Substring(data, i * 16, 16,d3);
				XOR(result, d3,16,result);
			}
			Substring(data,dataLength - dataLength % 16, dataLength % 16,d4);
			strcat(d4,"8");//可能有问题
			PadRight(d4,16, '0',d4);
			unsigned char temp555[8];Hex2Bin(result,temp555);
			enc(keyaXXX1, temp555);
			Bin2Hex(temp555,8,result);
			XOR(result,  d4,16,result);
			Hex2Bin(result,temp555);//temp555=Hex2Bin(result);
			enc(keyaXXX1, temp555);
			dec(keybXXX1, temp555);
			enc(keyaXXX1, temp555);
			Bin2Hex(temp555,8,result);
			echomac("bb");
		}
	}
	else
	{
		echomac("bb");
		unsigned char Ran9[9];
		unsigned char temp4442keya[8];Hex2Bin(keya,temp4442keya);
		unsigned char temp4442keyb[8];Hex2Bin(keyb,temp4442keyb);
		sprintf(d3,"%s%s",data,"8");
		PadRight(d3,16, '0',d3);
		PadRight(Substring(ran,0,8,Ran9),16,'0',result);
		XOR( result, d3,16,result);
		unsigned char temp777[8];Hex2Bin(result,temp777);
		enc(temp4442keya, temp777);
		Bin2Hex(temp777,8,result);;
		dec(temp4442keyb, temp777);
		Bin2Hex(temp777,8,result);
		enc(temp4442keya, temp777);
		Bin2Hex(temp777,8,result);
		echomac("bb");
	}
	memset(___MAC,0x00,9);
	memcpy(___MAC,result,8);
	return ___MAC;

}
Ejemplo n.º 12
0
 uint8_t Hex2Bin(char hi, char lo)
 {
   return Hex2Bin(hi) * 16 + Hex2Bin(lo);
 }
Ejemplo n.º 13
0
// read from gw_ini_cmds.ini file
// initialising for target = all and when = dev_init
bool GatewayConfig::InitGwCmds()
{
    WHartUniqueID devUniqueID;
    m_oDeviceInitCmds.clear();
    m_oDeviceTargetedCmds.clear();
    CIniParser gw_commands_parser;

    if (!gw_commands_parser.Load(FILE_PATH))
    {
        return 0;
    }

    for (int i = 0; gw_commands_parser.FindGroup("command", i); i++)
    {
        char target[255];
        char when[255];
        int target_len;
        int cmd_id;
        unsigned char cmd_data[256];
        int cmd_len;
        uint8_t output[5];

        if (gw_commands_parser.GetVar(NULL, "when", when, sizeof(when)) <= 0)
            continue;

        if (strcmp(when, "dev_init") != 0)
        {
            continue;
        }

        if (gw_commands_parser.GetVar(NULL, "target", target, sizeof(target)) <= 0)
            continue;

        if (!gw_commands_parser.GetVar(NULL, "cmd_id", &cmd_id))
            continue;

        if ((cmd_len = gw_commands_parser.GetVar(NULL, "cmd_data", cmd_data, sizeof(cmd_data))) < 0)
            continue;

        if (strcmp(target, "all") == 0)
        {
            // new element in Cmds List
            CHartCmdWrapper::Ptr new_element(new CHartCmdWrapper);

            new_element->LoadRaw((uint16_t) cmd_id, cmd_len, cmd_data);
            m_oDeviceInitCmds.push_back(new_element);
        }
        else
        {
            target_len = Hex2Bin(target, (char *) output);

            if (target_len != sizeof(devUniqueID.bytes))
            {
                LOG_INFO("target=" << target << " inavlid len=" << target_len);
                continue;
            }

            memcpy(devUniqueID.bytes, output, target_len);

            CHartCmdWrapper::Ptr new_element(new CHartCmdWrapper);
            new_element->LoadRaw((uint16_t) cmd_id, cmd_len, cmd_data);

            m_oDeviceTargetedCmds[devUniqueID].push_back(new_element);
        }
        LOG(" target=%s cmdId=%d  data=%s", target, cmd_id, GetHex(cmd_data, cmd_len, ' '));

    }

    return true;
}
Ejemplo n.º 14
0
int main(int argc, char **argv)
{
	int i, rc;
#if defined(_WIN32) && defined(_DEBUG)
	atexit((void(*)(void))_CrtDumpMemoryLeaks);
#endif
	if (argc < 2)
		return Usage();

	if (strcmp(argv[1], "--get-pin-status") == 0) {
		rc = GetPinStatus();
		printf("get-pin-status returns: 0x%4x\n", rc);
		return 0;
	}
	if (strcmp(argv[1], "--save-files") == 0) {
		DumpAllFiles(argc >= 3 ? argv[2] : 0);
		return 0;
	}
	if (argc < 3)
		return Usage();

	if (strcmp(argv[1], "--restore-files") == 0) {
		int rc = SC_Open(argv[2], 0);
		if (rc < 0)
			return rc;
		for (i = 3; i < argc; i++) {
			const char *name = argv[i];
			int dataLen, off;
			uint8 *pData;
			uint8 afid[2];
			uint16 fid;
			if (strlen(name) != 8 || strcmp(name + 4, ".asn") || Hex2Bin(name, 4, afid)) {
				printf("filename '%s' must be 'abcd.asn' where abcd is a valid hex number\n", name);
				continue;
			}
			fid = afid[0] << 8 | afid[1];
			if (fid == 0x2f02) {
				printf("filename '%s' skipped, EF_DevAut is readonly\n", name);
				continue;
			}
			ReadFromFile(name, pData, dataLen);
			if (pData == NULL) {
				printf("cant read file '%s'\n", name);
				continue;
			}
			if (dataLen == 0) {
				free(pData);
				printf("file '%s' empty\n", name);
				continue;
			}
			rc = 0;
			for (off = 0; off < dataLen;) {
				int len = dataLen - off;
				if (len > MAX_OUT_IN - 6)
					len = MAX_OUT_IN - 6;
				rc = SC_WriteFile(fid, off, pData + off, len);
				if (rc < 0)
					break;
				off += len;
			}
			free(pData);
			if (rc < 0) {
				printf("write error %d file '%s'\n", rc, name);
				continue;
			}
			printf("file '%s' successfully restored\n", name);
		}
		SC_Close();
		return 0;
	}
	if (strcmp(argv[1], "--init-token") == 0) {
		int len;
		uint8* buf;
		switch (argc) {
		default:
			return Usage();
		case 3:
			rc = InitializeToken(argv[2], NULL, 0, NULL);
			break;
		case 4:
			rc = InitializeToken(argv[2], argv[3], 0, NULL);
			break;
		case 5:
			ReadFromFile(argv[4], buf, len);
			if (buf == NULL) {
				printf("file '%s' not found\n", argv[4]);
				return ERR_INVALID;
			}
			if (len < 32 || (len & 31)) {
				free(buf);
				printf("file length of '%s' must be a positive multiple of 32\n", argv[4]);
				return ERR_INVALID;
			}
			rc = InitializeToken(argv[2], argv[3], len / 32, buf);
			free(buf);
			break;
		}
		printf("init-token returns: 0x%4x\n", rc);
		return rc == 0x9000 ? 0 : rc;
	}
	if (strcmp(argv[1], "--unlock-pin") == 0) {
		if (!(3 <= argc && argc <= 3))
			return Usage();
		rc = UnlockPin(argv[2]);
		printf("unlock-pin returns: 0x%4x\n", rc);
		return rc == 0x9000 ? 0 : rc;
	}
	if (strcmp(argv[1], "--set-pin") == 0) {
		if (!(3 <= argc && argc <= 4))
			return Usage();
		rc = SetPin(argv[2], argc == 3 ? NULL : argv[3]);
		printf("set-pin returns: 0x%4x\n", rc);
		return rc == 0x9000 ? 0 : rc;
	}
	if (strcmp(argv[1], "--change-pin") == 0) {
		if (!(4 <= argc && argc <= 4))
			return Usage();
		rc = ChangePin(argv[2], argv[3]);
		printf("change-pin returns: 0x%4x\n", rc);
		return rc == 0x9000 ? 0 : rc;
	}
	if (strcmp(argv[1], "--change-so-pin") == 0) {
		if (!(4 <= argc && argc <= 4))
			return Usage();
		rc = ChangeSoPin(argv[2], argv[3]);
		printf("change-pin returns: 0x%4x\n", rc);
		return rc == 0x9000 ? 0 : rc;
	}
	if (strcmp(argv[1], "--wrap-key") == 0) {
		if (!(5 <= argc && argc <= 5))
			return Usage();
		rc = WrapKey(argv[2], atoi(argv[3]), argv[4]);
		printf("wrap-key returns: 0x%4x\n", rc);
		return rc == 0x9000 ? 0 : rc;
	}
	if (strcmp(argv[1], "--unwrap-key") == 0) {
		if (!(5 <= argc && argc <= 5))
			return Usage();
		rc = UnwrapKey(argv[2], atoi(argv[3]), argv[4]);
		printf("unwrap-key returns: 0x%4x\n", rc);
		return rc == 0x9000 ? 0 : rc;
	}
	return Usage();
}
Ejemplo n.º 15
0
//convert hex string in binary data
//suppose that p_pOutput has allocated (strlen(p_szInput)+2)/2
//return the len of the bin buffer
int Hex2Bin( const char* p_szInput, char* p_pOutput )
{
	return Hex2Bin(p_szInput, strlen(p_szInput), p_pOutput );
}
Ejemplo n.º 16
0
EXPORT char *   MAC8(char * data,int dataLength, char * ran, char * key8)
{
	char result[17] ;
	char d3[17] ;
	char d4[17];
	unsigned char Ran9[9];
	unsigned char Prtwmp[17];
	unsigned char key8aaa[strlen(key8)/2];Hex2Bin(key8,key8aaa);
	if (dataLength >= 16)
	{
		
		Substring(data,0, 16,d3);
		Prtwmp[16] = 0x00;
		XOR(PadRight( Substring(ran,0,8,Ran9),16,'0',Prtwmp),d3,dataLength,result);
		result[16]=0;
		if (dataLength % 16 == 0)
		{
			unsigned char temp777[8];
			int i;
			for (  i = 1; i < dataLength / 16; i++)
			{
				Hex2Bin(result,temp777);//temp777=Hex2Bin(result);
				enc(key8aaa, temp777);
				Bin2Hex(temp777,8,result);
				Substring(data,i * 16, 16,d3);
				XOR(result, d3,16,result);
				memcpy(d4,(char *)"8000000000000000",16);
				d4[16] = 0x00;
			}
			if (dataLength == 16) 
			{
				memcpy(d4,(char*)"8000000000000000",16);
				d4[16] = 0x00;
			}
			Hex2Bin(result,temp777);
			enc(key8aaa, temp777);
			Bin2Hex(temp777,8,result);
			XOR(result, d4,16,result);
			Hex2Bin(result,temp777);
			enc(key8aaa, temp777);
			Bin2Hex(temp777,8,result);

		}
		else
		{
			int i;
			unsigned char tmp999[8];
			char *tmpx99x;
			unsigned char tmp999keya[strlen(key8)/2];Hex2Bin(key8,tmp999keya);
			for ( i= 1; i < dataLength / 16; i++)
			{
				unsigned char tmp888[8];Hex2Bin(result,tmp888);
				enc(key8aaa, tmp888);
				Substring(data,i * 16, 16,d3);
				Bin2Hex(tmp888,8,result);
				XOR(result, d3,16,result);

			}

			Substring(data,dataLength - dataLength % 16, dataLength % 16,d4);			
			strcat(d4,"8");
			PadRight(d4,16, '0',d4);
			Hex2Bin(result,tmp999);
			enc(tmp999keya, tmp999);
			Bin2Hex(tmp999,8,result);
			XOR(result, d4,16,result);
			Hex2Bin(result,tmp999);
			enc(tmp999keya, tmp999);
			Bin2Hex(tmp999,8,result);
		}
	}
	else
	{
		unsigned char tmp888111[8];
		unsigned char PdTemp[17];
		sprintf(d3,"%s%s", data, "8");
		PadRight(d3,16, '0',d3);
		PdTemp[16] = 0;
		XOR(PadRight( Substring(ran,0, 8,Ran9),16, '0',PdTemp), d3,16,result);
		Hex2Bin(result,tmp888111);
		enc(key8aaa, tmp888111);
		Bin2Hex(tmp888111,8,result);
	}
	memset(___MAC8,0x00,9);
	memcpy(___MAC8,result,8);
	return ___MAC8;
}
Ejemplo n.º 17
0
int InitializeToken(const char *pin, const char *sopin, int dkeksCount, uint8 *dkeks)
{
	uint16 sw1sw2;
	int rc, i;
	uint8 data[2 + 2 + 18 + 18 + 2 + 2];
	uint8 *p = data;
	int pin_len = strlen(pin);
	if (!(6 <= pin_len && pin_len <= 16)) {
		printf("PIN must have 6 - 16 chars\n");
		return ERR_INVALID;
	}
	/* Configuration Options (currently '0001') */
	*p++ = 0x80; *p++ = 0x02; *p++ = 0x00; *p++ = 0x01;
	/* Initial PIN value */
	*p++ = 0x81; *p++ = (uint8)pin_len; memcpy(p, pin, pin_len); p += pin_len;
	/* Initialization Code (== SO_PIN) */
	*p++ = 0x82; *p++ = 0x08;
	if (sopin == 0) {
		memcpy(p, "\x35\x37\x36\x32\x31\x38\x38\x30", 8);
	} else {
		if (strlen(sopin) != 16) {
			printf("SO_PIN must have 16 hex-digits\n");
			return ERR_INVALID;
		}
		rc = Hex2Bin(sopin, 16, p);
		if (rc)
			return rc;
	}
	p += 8;
	/* Retry Counter Initial Value */
	*p++ = 0x91; *p++ = 0x01; *p++ = 3;
	/* Number of Device Encryption Key shares */
	if (dkeksCount) {
		*p++ = 0x92; *p++ = 0x01; *p++ = dkeksCount;
	}

	rc = SC_Open(0, 0);
	if (rc < 0)
		return rc;
	/* - SmartCard-HSM: INITIALIZE DEVICE */
	rc = SC_ProcessAPDU(
		0, 0x80,0x50,0x00,0x00,
		data, (int)(p - data),
		NULL, 0,
		&sw1sw2);
	if (rc < 0) {
		SC_Close();
		return rc;
	}
	if (sw1sw2 != 0x9000) {
		SC_Close();
		return sw1sw2;
	}
	for (i = 0, p = dkeks; i < dkeksCount; i++, p += 0x20) {
		uint8 buf[10];
		/* - SmartCard-HSM: IMPORT DKEK SHARE */
		rc = SC_ProcessAPDU(
			0, 0x80,0x52,0x00,0x00,
			p, 0x20,
			buf, 10,
			&sw1sw2);
		if (rc < 0) {
			SC_Close();
			return rc;
		}
		if (sw1sw2 != 0x9000) {
			SC_Close();
			return sw1sw2;
		}
		printf("total shares: %d, outstanding shares: %d, key check value: %02x%02x%02x%02x%02x%02x%02x%02x\n",
			buf[0],
			buf[1],
			buf[2], buf[3], buf[4], buf[5], buf[6], buf[7], buf[8], buf[9]);
	}
	SC_Close();
	return sw1sw2;
}