示例#1
0
CAPDU build_CA_Step_C(const std::vector<unsigned char>& Puk_IFD_DH)
{
	GeneralAuthenticate authenticate = GeneralAuthenticate(
			GeneralAuthenticate::P1_NO_INFO, GeneralAuthenticate::P2_NO_INFO);
	authenticate.setNe(CAPDU::DATA_SHORT_MAX);

	std::vector<unsigned char> puk;
	puk.push_back(0x04);
	puk.insert(puk.end(), Puk_IFD_DH.begin(), Puk_IFD_DH.end());
	
	authenticate.setData(TLV_encode(0x7C, TLV_encode(0x80, puk)));

	return authenticate;
}
示例#2
0
CAPDU build_CA_Step_C(const std::vector<unsigned char>& Puk_IFD_DH)
{
	GeneralAuthenticate authenticate = GeneralAuthenticate(
			GeneralAuthenticate::P1_NO_INFO, GeneralAuthenticate::P2_NO_INFO);
	authenticate.setNe(CAPDU::DATA_SHORT_MAX);

	std::vector<unsigned char> puk;
	//The server sends the public ephemeral key already with 0x04
	//prefix. So we do not need to prepend it anymore.
	//puk.push_back(0x04);
	puk.insert(puk.end(), Puk_IFD_DH.begin(), Puk_IFD_DH.end());
	
	authenticate.setData(TLV_encode(0x7C, TLV_encode(0x80, puk)));

	return authenticate;
}
示例#3
0
static std::vector<unsigned char> buildDO87_AES(
	const std::vector<unsigned char>& kEnc,
	const std::vector<unsigned char>& data,
	unsigned long long ssc)
{
	std::vector<unsigned char> data_ = static_cast<std::vector<unsigned char> >(data);
	data_.push_back(0x80);

	while (data_.size() % kEnc.size())
		data_.push_back(0x00);

	unsigned char iv_[] = {
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
	};
	std::vector<unsigned char> ssc_;

	for (int i = 0; i < 8; i++)
		ssc_.push_back(0x00);

	ssc_.push_back((ssc << 56) & 0xFF);
	ssc_.push_back((ssc << 48) & 0xFF);
	ssc_.push_back((ssc << 40) & 0xFF);
	ssc_.push_back((ssc << 32) & 0xFF);
	ssc_.push_back((ssc << 24) & 0xFF);
	ssc_.push_back((ssc << 16) & 0xFF);
	ssc_.push_back((ssc << 8) & 0xFF);
	ssc_.push_back(ssc & 0xFF);
	Integer issc(ssc_.data(), kEnc.size());
	std::vector<unsigned char> vssc;
	vssc.resize(kEnc.size());
	issc.Encode(vssc.data(), kEnc.size());
	std::vector<unsigned char> calculatedIV_;
	CBC_Mode<AES>::Encryption AESCBC_encryption;

	if (false == AESCBC_encryption.IsValidKeyLength(kEnc.size()))
		return calculatedIV_;

	calculatedIV_.resize(kEnc.size());
	AESCBC_encryption.SetKeyWithIV(kEnc.data(), kEnc.size(), iv_);
	AESCBC_encryption.ProcessData(calculatedIV_.data(), vssc.data(), vssc.size());
	CBC_Mode<AES>::Encryption AESCBC_encryption1;
	std::vector<unsigned char> encryptedData_;
	encryptedData_.resize(data_.size());
	AESCBC_encryption1.SetKeyWithIV(kEnc.data(), kEnc.size(), calculatedIV_.data());
	AESCBC_encryption1.ProcessData(encryptedData_.data(), data_.data(), data_.size());
   
	// Append padding content indicator
	encryptedData_.insert(encryptedData_.begin(), BIT_PADDING);

	return TLV_encode(0x87, encryptedData_);
}
示例#4
0
CAPDU build_CA_Step_B(const OBJECT_IDENTIFIER_t& CA_OID, const unsigned char sessionid)
{
	MSE mse = MSE(MSE::P1_SET | MSE::P1_COMPUTE, MSE::P2_AT);
	// Build up command data field
	std::vector<unsigned char> oid(CA_OID.buf, CA_OID.buf+CA_OID.size);;
	std::vector<unsigned char> data = TLV_encode(0x80, oid);
	if (sessionid) {
		data.push_back(0xE0);
		data.push_back(0x03);
		data.push_back(0x81);
		data.push_back(0x01);
		data.push_back(sessionid);
	}
	mse.setData(data);

	return mse;
}
示例#5
0
CAPDU ePACard::applySM(const CAPDU &capdu)
{
	std::vector<unsigned char> do87_, do8E_, do97_, Le, sm_data;

	debug_CAPDU("Unencrypted", capdu);

	CAPDU sm_apdu = CAPDU(capdu.getCLA() | CAPDU::CLA_SM,
						  capdu.getINS(), capdu.getP1(), capdu.getP2());

	m_ssc++;

	if (!capdu.getData().empty()) {
		do87_ = buildDO87_AES(m_kEnc, capdu.getData(), m_ssc);
	}

	Le = capdu.encodedLe();

	if (!Le.empty()) {
		if (Le.size() > 2) {
			Le.erase(Le.begin());
		}
		do97_ = TLV_encode(0x97, Le);
	}

	/* here, sm_apdu is still a case 1 APDU with header only. */
	do8E_ = buildDO8E_AES(m_kMac, sm_apdu.asBuffer(), do87_, do97_, m_ssc);
	sm_data = do87_;
	sm_data.insert(sm_data.end(), do97_.begin(), do97_.end());
	sm_data.insert(sm_data.end(), do8E_.begin(), do8E_.end());
	sm_apdu.setData(sm_data);

	if (sm_apdu.isExtended() || capdu.isExtended())
		sm_apdu.setNe(CAPDU::DATA_EXTENDED_MAX);

	else
		sm_apdu.setNe(CAPDU::DATA_SHORT_MAX);

	return sm_apdu;
}
示例#6
0
static std::vector<unsigned char> buildDO8E_AES(
	const std::vector<unsigned char>& kMac,
	const std::vector<unsigned char>& data,
	const std::vector<unsigned char>& do87,
	const std::vector<unsigned char>& do97,
	unsigned long long &ssc)
{
	std::vector<unsigned char> mac;
	mac.resize(8);
	std::vector<unsigned char> data_ = static_cast<std::vector<unsigned char> >(data);

	// Do padding on APDU header
	data_.push_back(0x80);
	while (data_.size() % AES::BLOCKSIZE)
		data_.push_back(0x00);

	// Append the DO87 data
	for (size_t u = 0; u < do87.size(); u++)
		data_.push_back(do87[u]);

	// Append the DO97 data
	for (size_t u = 0; u < do97.size(); u++)
		data_.push_back(do97[u]);

	// Append padding to data part
	if (!do97.empty() || !do87.empty()) {
		data_.push_back(0x80);

		while (data_.size() % AES::BLOCKSIZE)
			data_.push_back(0x00);
	}

	std::vector<unsigned char> ssc_;

	for (int i = 0; i < 8; i++)
		ssc_.push_back(0x00);

	ssc_.push_back((ssc << 56) & 0xFF);
	ssc_.push_back((ssc << 48) & 0xFF);
	ssc_.push_back((ssc << 40) & 0xFF);
	ssc_.push_back((ssc << 32) & 0xFF);
	ssc_.push_back((ssc << 24) & 0xFF);
	ssc_.push_back((ssc << 16) & 0xFF);
	ssc_.push_back((ssc << 8) & 0xFF);
	ssc_.push_back(ssc & 0xFF);
	Integer issc(ssc_.data(), AES::BLOCKSIZE);
	std::vector<unsigned char> vssc;
	vssc.resize(AES::BLOCKSIZE);
	issc.Encode(vssc.data(), AES::BLOCKSIZE);
	issc.Encode(ssc_.data(), AES::BLOCKSIZE);
	ssc = 0;
	ssc += (unsigned long long) ssc_[8] << 56;
	ssc += (unsigned long long) ssc_[9] << 48;
	ssc += (unsigned long long) ssc_[10] << 40;
	ssc += (unsigned long long) ssc_[11] << 32;
	ssc += (unsigned long long) ssc_[12] << 24;
	ssc += (unsigned long long) ssc_[13] << 16;
	ssc += (unsigned long long) ssc_[14] << 8;
	ssc += (unsigned long long) ssc_[15];

	for (size_t t = 0; t < data_.size(); t++)
		vssc.push_back(data_[t]);

	std::vector<unsigned char> result_;
	result_.resize(vssc.size());
	CMAC<AES> cmac;
	cmac.SetKey(kMac.data(), kMac.size());
	cmac.Update(vssc.data(), vssc.size());
	cmac.Final(result_.data());
	result_.resize(8);

	return TLV_encode(0x8E, result_);
}