bugfixes:
- sm.c: fixed mac data padding, when sending sm apdu without data. - pace.c: for iv calculation ecb is used instead of cbc - pace.c: fixed ssc incrementation git-svn-id: https://vsmartcard.svn.sourceforge.net/svnroot/vsmartcard@68 96b47cad-a561-4643-ad3b-153ac7d7599c
This commit is contained in:
53
ccid/pace.c
53
ccid/pace.c
@@ -828,16 +828,6 @@ int pace_test(sc_card_t *card)
|
|||||||
SC_TEST_RET(card->ctx, EstablishPACEChannel(card, in, &out, &outlen, &sctx),
|
SC_TEST_RET(card->ctx, EstablishPACEChannel(card, in, &out, &outlen, &sctx),
|
||||||
"Could not establish PACE channel.");
|
"Could not establish PACE channel.");
|
||||||
|
|
||||||
/* reset retry counter */
|
|
||||||
apdu.cla = 0x00;
|
|
||||||
apdu.ins = 0x2C;
|
|
||||||
apdu.p1 = 0x03;
|
|
||||||
apdu.p2 = 0x02;
|
|
||||||
apdu.cse = SC_APDU_CASE_1;
|
|
||||||
|
|
||||||
SC_TEST_RET(card->ctx, pace_transmit_apdu(&sctx, card, &apdu),
|
|
||||||
"Could not reset retry counter of CAN");
|
|
||||||
|
|
||||||
/* select CardSecurity */
|
/* select CardSecurity */
|
||||||
apdu.cla = 0x00;
|
apdu.cla = 0x00;
|
||||||
apdu.ins = 0xA4;
|
apdu.ins = 0xA4;
|
||||||
@@ -862,6 +852,16 @@ int pace_test(sc_card_t *card)
|
|||||||
apdu.le = 0x00;
|
apdu.le = 0x00;
|
||||||
apdu.cse = SC_APDU_CASE_2_SHORT;
|
apdu.cse = SC_APDU_CASE_2_SHORT;
|
||||||
|
|
||||||
|
/* reset retry counter */
|
||||||
|
apdu.cla = 0x00;
|
||||||
|
apdu.ins = 0x2C;
|
||||||
|
apdu.p1 = 0x03;
|
||||||
|
apdu.p2 = 0x02;
|
||||||
|
apdu.cse = SC_APDU_CASE_1;
|
||||||
|
|
||||||
|
SC_TEST_RET(card->ctx, pace_transmit_apdu(&sctx, card, &apdu),
|
||||||
|
"Could not reset retry counter of CAN");
|
||||||
|
|
||||||
SC_TEST_RET(card->ctx, pace_transmit_apdu(&sctx, card, &apdu),
|
SC_TEST_RET(card->ctx, pace_transmit_apdu(&sctx, card, &apdu),
|
||||||
"Could not read EF.CardSecurity");
|
"Could not read EF.CardSecurity");
|
||||||
|
|
||||||
@@ -907,6 +907,7 @@ update_iv(struct sm_ctx *ctx)
|
|||||||
return SC_ERROR_INVALID_ARGUMENTS;
|
return SC_ERROR_INVALID_ARGUMENTS;
|
||||||
|
|
||||||
BUF_MEM *sscbuf = NULL, *ivbuf = NULL;
|
BUF_MEM *sscbuf = NULL, *ivbuf = NULL;
|
||||||
|
EVP_CIPHER *ivcipher = NULL;
|
||||||
u8 *ssc = NULL;
|
u8 *ssc = NULL;
|
||||||
unsigned char *p;
|
unsigned char *p;
|
||||||
struct pace_sm_ctx *psmctx = ctx->cipher_ctx;
|
struct pace_sm_ctx *psmctx = ctx->cipher_ctx;
|
||||||
@@ -914,17 +915,26 @@ update_iv(struct sm_ctx *ctx)
|
|||||||
|
|
||||||
switch (psmctx->protocol) {
|
switch (psmctx->protocol) {
|
||||||
case NID_id_PACE_DH_GM_AES_CBC_CMAC_128:
|
case NID_id_PACE_DH_GM_AES_CBC_CMAC_128:
|
||||||
case NID_id_PACE_DH_GM_AES_CBC_CMAC_192:
|
|
||||||
case NID_id_PACE_DH_GM_AES_CBC_CMAC_256:
|
|
||||||
case NID_id_PACE_DH_IM_AES_CBC_CMAC_128:
|
case NID_id_PACE_DH_IM_AES_CBC_CMAC_128:
|
||||||
case NID_id_PACE_DH_IM_AES_CBC_CMAC_192:
|
|
||||||
case NID_id_PACE_DH_IM_AES_CBC_CMAC_256:
|
|
||||||
case NID_id_PACE_ECDH_GM_AES_CBC_CMAC_128:
|
case NID_id_PACE_ECDH_GM_AES_CBC_CMAC_128:
|
||||||
case NID_id_PACE_ECDH_GM_AES_CBC_CMAC_192:
|
|
||||||
case NID_id_PACE_ECDH_GM_AES_CBC_CMAC_256:
|
|
||||||
case NID_id_PACE_ECDH_IM_AES_CBC_CMAC_128:
|
case NID_id_PACE_ECDH_IM_AES_CBC_CMAC_128:
|
||||||
|
if (!ivcipher)
|
||||||
|
ivcipher = EVP_aes_128_ecb();
|
||||||
|
/* fall through */
|
||||||
|
case NID_id_PACE_DH_GM_AES_CBC_CMAC_192:
|
||||||
|
case NID_id_PACE_DH_IM_AES_CBC_CMAC_192:
|
||||||
|
case NID_id_PACE_ECDH_GM_AES_CBC_CMAC_192:
|
||||||
case NID_id_PACE_ECDH_IM_AES_CBC_CMAC_192:
|
case NID_id_PACE_ECDH_IM_AES_CBC_CMAC_192:
|
||||||
|
if (!ivcipher)
|
||||||
|
ivcipher = EVP_aes_192_ecb();
|
||||||
|
/* fall through */
|
||||||
|
case NID_id_PACE_DH_GM_AES_CBC_CMAC_256:
|
||||||
|
case NID_id_PACE_DH_IM_AES_CBC_CMAC_256:
|
||||||
|
case NID_id_PACE_ECDH_GM_AES_CBC_CMAC_256:
|
||||||
case NID_id_PACE_ECDH_IM_AES_CBC_CMAC_256:
|
case NID_id_PACE_ECDH_IM_AES_CBC_CMAC_256:
|
||||||
|
if (!ivcipher)
|
||||||
|
ivcipher = EVP_aes_256_ecb();
|
||||||
|
|
||||||
/* For AES decryption the IV is not needed,
|
/* For AES decryption the IV is not needed,
|
||||||
* so we always set it to the encryption IV=E(K_Enc, SSC) */
|
* so we always set it to the encryption IV=E(K_Enc, SSC) */
|
||||||
r = encode_ssc(psmctx->ssc, psmctx->ctx, &ssc);
|
r = encode_ssc(psmctx->ssc, psmctx->ctx, &ssc);
|
||||||
@@ -935,7 +945,10 @@ update_iv(struct sm_ctx *ctx)
|
|||||||
r = SC_ERROR_OUT_OF_MEMORY;
|
r = SC_ERROR_OUT_OF_MEMORY;
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
oldcipher = psmctx->ctx->cipher;
|
||||||
|
psmctx->ctx->cipher = ivcipher;
|
||||||
ivbuf = PACE_encrypt(psmctx->ctx, psmctx->key_enc, sscbuf);
|
ivbuf = PACE_encrypt(psmctx->ctx, psmctx->key_enc, sscbuf);
|
||||||
|
psmctx->ctx->cipher = oldcipher;
|
||||||
if (!ivbuf) {
|
if (!ivbuf) {
|
||||||
r = SC_ERROR_INTERNAL;
|
r = SC_ERROR_INTERNAL;
|
||||||
goto err;
|
goto err;
|
||||||
@@ -980,11 +993,7 @@ increment_ssc(struct sm_ctx *ctx)
|
|||||||
|
|
||||||
struct pace_sm_ctx *psmctx = ctx->cipher_ctx;
|
struct pace_sm_ctx *psmctx = ctx->cipher_ctx;
|
||||||
|
|
||||||
if (BN_is_zero(psmctx->ssc)) {
|
BN_add_word(psmctx->ssc, 1);
|
||||||
BN_set_word(psmctx->ssc, 2);
|
|
||||||
} else {
|
|
||||||
BN_add_word(psmctx->ssc, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
return update_iv(ctx);
|
return update_iv(ctx);
|
||||||
}
|
}
|
||||||
@@ -1153,9 +1162,9 @@ err:
|
|||||||
int pace_transmit_apdu(struct sm_ctx *sctx, sc_card_t *card,
|
int pace_transmit_apdu(struct sm_ctx *sctx, sc_card_t *card,
|
||||||
sc_apdu_t *apdu)
|
sc_apdu_t *apdu)
|
||||||
{
|
{
|
||||||
|
increment_ssc(sctx);
|
||||||
SC_TEST_RET(card->ctx, sm_transmit_apdu(sctx, card, apdu),
|
SC_TEST_RET(card->ctx, sm_transmit_apdu(sctx, card, apdu),
|
||||||
"Could not send SM APDU");
|
"Could not send SM APDU");
|
||||||
increment_ssc(sctx);
|
|
||||||
|
|
||||||
SC_FUNC_RETURN(card->ctx, SC_LOG_TYPE_DEBUG, SC_SUCCESS);
|
SC_FUNC_RETURN(card->ctx, SC_LOG_TYPE_DEBUG, SC_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|||||||
28
ccid/sm.c
28
ccid/sm.c
@@ -278,7 +278,7 @@ static int sm_encrypt(const struct sm_ctx *ctx, sc_card_t *card,
|
|||||||
sm_apdu->ins = apdu->ins;
|
sm_apdu->ins = apdu->ins;
|
||||||
sm_apdu->p1 = apdu->p1;
|
sm_apdu->p1 = apdu->p1;
|
||||||
sm_apdu->p2 = apdu->p2;
|
sm_apdu->p2 = apdu->p2;
|
||||||
r = format_head(ctx, apdu, &mac_data);
|
r = format_head(ctx, sm_apdu, &mac_data);
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
sc_error(card->ctx, "Could not format header of SM apdu");
|
sc_error(card->ctx, "Could not format header of SM apdu");
|
||||||
goto err;
|
goto err;
|
||||||
@@ -387,19 +387,21 @@ static int sm_encrypt(const struct sm_ctx *ctx, sc_card_t *card,
|
|||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
p = realloc(mac_data, mac_data_len + asn1_len);
|
if (asn1_len) {
|
||||||
if (!p) {
|
p = realloc(mac_data, mac_data_len + asn1_len);
|
||||||
r = SC_ERROR_OUT_OF_MEMORY;
|
if (!p) {
|
||||||
goto err;
|
r = SC_ERROR_OUT_OF_MEMORY;
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
mac_data = p;
|
||||||
|
memcpy(mac_data + mac_data_len, asn1, asn1_len);
|
||||||
|
mac_data_len += asn1_len;
|
||||||
|
r = add_padding(ctx, mac_data, mac_data_len, &mac_data);
|
||||||
|
if (r < 0) {
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
mac_data_len = r;
|
||||||
}
|
}
|
||||||
mac_data = p;
|
|
||||||
memcpy(mac_data + mac_data_len, asn1, asn1_len);
|
|
||||||
mac_data_len += asn1_len;
|
|
||||||
r = add_padding(ctx, mac_data, mac_data_len, &mac_data);
|
|
||||||
if (r < 0) {
|
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
mac_data_len = r;
|
|
||||||
bin_log(card->ctx, "Data to authenticate", mac_data, mac_data_len);
|
bin_log(card->ctx, "Data to authenticate", mac_data, mac_data_len);
|
||||||
|
|
||||||
r = ctx->authenticate(card, ctx, mac_data, mac_data_len,
|
r = ctx->authenticate(card, ctx, mac_data, mac_data_len,
|
||||||
|
|||||||
Reference in New Issue
Block a user