Use struct sm_cwa_session from sm.h in dnie (#955)
* Use cm_ctx instead of a custom cwa struct. Get rid of sc_reset. * Use ifd.sn and icc.sn from sm_cwa_session struct too * Minor typo with sizeof closes https://github.com/OpenSC/OpenSC/issues/930
This commit is contained in:
parent
68f8f0bfa7
commit
c906c5e375
|
@ -2147,7 +2147,7 @@ static int dnie_pin_change(struct sc_card *card, struct sc_pin_cmd_data * data)
|
|||
int res=SC_SUCCESS;
|
||||
LOG_FUNC_CALLED(card->ctx);
|
||||
/* Ensure that secure channel is established from reset */
|
||||
res = cwa_create_secure_channel(card, GET_DNIE_PRIV_DATA(card)->cwa_provider, CWA_SM_COLD);
|
||||
res = cwa_create_secure_channel(card, GET_DNIE_PRIV_DATA(card)->cwa_provider, CWA_SM_ON);
|
||||
LOG_TEST_RET(card->ctx, res, "Establish SM failed");
|
||||
LOG_FUNC_RETURN(card->ctx,SC_ERROR_NOT_SUPPORTED);
|
||||
}
|
||||
|
@ -2180,7 +2180,7 @@ static int dnie_pin_verify(struct sc_card *card,
|
|||
sc_log(card->ctx, "DNIe 3.0 detected doing PIN initialization");
|
||||
dnie_change_cwa_provider_to_pin(card);
|
||||
}
|
||||
res = cwa_create_secure_channel(card, GET_DNIE_PRIV_DATA(card)->cwa_provider, CWA_SM_COLD);
|
||||
res = cwa_create_secure_channel(card, GET_DNIE_PRIV_DATA(card)->cwa_provider, CWA_SM_ON);
|
||||
LOG_TEST_RET(card->ctx, res, "Establish SM failed");
|
||||
|
||||
data->apdu = &apdu; /* prepare apdu struct */
|
||||
|
@ -2222,7 +2222,7 @@ static int dnie_pin_verify(struct sc_card *card,
|
|||
if (card->atr.value[15] >= DNIE_30_VERSION) {
|
||||
sc_log(card->ctx, "DNIe 3.0 detected => re-establish secure channel");
|
||||
dnie_change_cwa_provider_to_secure(card);
|
||||
res = cwa_create_secure_channel(card, GET_DNIE_PRIV_DATA(card)->cwa_provider, CWA_SM_OVER);
|
||||
res = cwa_create_secure_channel(card, GET_DNIE_PRIV_DATA(card)->cwa_provider, CWA_SM_ON);
|
||||
}
|
||||
|
||||
LOG_FUNC_RETURN(card->ctx, res);
|
||||
|
|
|
@ -266,12 +266,6 @@ static u8 sn_ifd[] = { 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 };
|
|||
*/
|
||||
static u8 sn_ifd_pin[] = { 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01};
|
||||
|
||||
/**
|
||||
* Serial number for ICC card.
|
||||
* This buffer is to be filled at runtime
|
||||
*/
|
||||
static u8 sn_icc[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
||||
|
||||
/************ internal functions **********************************/
|
||||
|
||||
/**
|
||||
|
@ -738,9 +732,10 @@ static int dnie_get_icc_privkey_ref(sc_card_t * card, u8 ** buf, size_t * len)
|
|||
* @param buf where to store result (8 bytes)
|
||||
* @return SC_SUCCESS if ok; else error
|
||||
*/
|
||||
static int dnie_get_sn_ifd(sc_card_t * card, u8 ** buf)
|
||||
static int dnie_get_sn_ifd(sc_card_t * card)
|
||||
{
|
||||
*buf = sn_ifd;
|
||||
struct sm_cwa_session * sm = &card->sm_ctx.info.session.cwa;
|
||||
memcpy(sm->ifd.sn, sn_ifd, sizeof(sm->ifd.sn));
|
||||
return SC_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -752,13 +747,12 @@ static int dnie_get_sn_ifd(sc_card_t * card, u8 ** buf)
|
|||
* return SC_SUCCESS
|
||||
*
|
||||
* @param card pointer to card structure
|
||||
* @param buf where to store result (8 bytes)
|
||||
* @return SC_SUCCESS if ok; else error
|
||||
*/
|
||||
static int dnie_get_sn_ifd_pin(sc_card_t * card, u8 ** buf)
|
||||
static int dnie_get_sn_ifd_pin(sc_card_t * card)
|
||||
{
|
||||
LOG_FUNC_CALLED(card->ctx);
|
||||
*buf = sn_ifd_pin;
|
||||
struct sm_cwa_session * sm = &card->sm_ctx.info.session.cwa;
|
||||
memcpy(sm->ifd.sn, sn_ifd_pin, sizeof(sm->ifd.sn));
|
||||
return SC_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -768,21 +762,19 @@ static int dnie_get_sn_ifd_pin(sc_card_t * card, u8 ** buf)
|
|||
* Just retrieve it from cache and return success
|
||||
*
|
||||
* @param card pointer to card structure
|
||||
* @param buf where to store result (8 bytes)
|
||||
* @return SC_SUCCESS if ok; else error
|
||||
*/
|
||||
static int dnie_get_sn_icc(sc_card_t * card, u8 ** buf)
|
||||
static int dnie_get_sn_icc(sc_card_t * card)
|
||||
{
|
||||
int res=SC_SUCCESS;
|
||||
sc_serial_number_t serial;
|
||||
struct sm_cwa_session * sm = &card->sm_ctx.info.session.cwa;
|
||||
|
||||
res = sc_card_ctl(card, SC_CARDCTL_GET_SERIALNR, &serial);
|
||||
LOG_TEST_RET(card->ctx, res, "Error in gettting serial number");
|
||||
/* copy into sn_icc buffer.Remember that dnie sn has 7 bytes length */
|
||||
memset(&sn_icc[0], 0, sizeof(sn_icc));
|
||||
memcpy(&sn_icc[1], serial.value, 7);
|
||||
/* return data */
|
||||
*buf = &sn_icc[0];
|
||||
memset(sm->icc.sn, 0, sizeof(sm->icc.sn));
|
||||
memcpy(&sm->icc.sn[1], serial.value, 7);
|
||||
return SC_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -812,17 +804,6 @@ static int dnie_create_pre_ops(sc_card_t * card, cwa_provider_t * provider)
|
|||
return sc_card_ctl(card, SC_CARDCTL_GET_SERIALNR, &serial);
|
||||
}
|
||||
|
||||
/**
|
||||
* Now in DNIe the channel mode is changed to SM_MODE_TRANSMIT
|
||||
* after CWA initialization to be consistent with OpenSC
|
||||
*/
|
||||
static int dnie_create_post_ops(sc_card_t * card, cwa_provider_t * provider)
|
||||
{
|
||||
card->sm_ctx.sm_mode = SM_MODE_TRANSMIT;
|
||||
|
||||
return SC_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Main entry point for DNIe CWA14890 SM data provider.
|
||||
*
|
||||
|
@ -842,11 +823,9 @@ cwa_provider_t *dnie_get_cwa_provider(sc_card_t * card)
|
|||
|
||||
/* pre and post operations */
|
||||
res->cwa_create_pre_ops = dnie_create_pre_ops;
|
||||
res->cwa_create_post_ops = dnie_create_post_ops;
|
||||
|
||||
/* Get ICC intermediate CA path */
|
||||
res->cwa_get_icc_intermediate_ca_cert =
|
||||
dnie_get_icc_intermediate_ca_cert;
|
||||
res->cwa_get_icc_intermediate_ca_cert = dnie_get_icc_intermediate_ca_cert;
|
||||
/* Get ICC certificate path */
|
||||
res->cwa_get_icc_cert = dnie_get_icc_cert;
|
||||
|
||||
|
@ -864,8 +843,7 @@ cwa_provider_t *dnie_get_cwa_provider(sc_card_t * card)
|
|||
res->cwa_get_root_ca_pubkey_ref = dnie_get_root_ca_pubkey_ref;
|
||||
|
||||
/* Get public key reference for IFD intermediate CA certificate */
|
||||
res->cwa_get_intermediate_ca_pubkey_ref =
|
||||
dnie_get_intermediate_ca_pubkey_ref;
|
||||
res->cwa_get_intermediate_ca_pubkey_ref = dnie_get_intermediate_ca_pubkey_ref;
|
||||
|
||||
/* Get public key reference for IFD CVC certificate */
|
||||
res->cwa_get_ifd_pubkey_ref = dnie_get_ifd_pubkey_ref;
|
||||
|
@ -923,8 +901,7 @@ int dnie_transmit_apdu(sc_card_t * card, sc_apdu_t * apdu)
|
|||
cwa_provider_t *provider = NULL;
|
||||
ctx=card->ctx;
|
||||
provider = GET_DNIE_PRIV_DATA(card)->cwa_provider;
|
||||
if ((provider->status.session.state == CWA_SM_ACTIVE) &&
|
||||
(card->sm_ctx.sm_mode == SM_MODE_TRANSMIT)) {
|
||||
if (card->sm_ctx.sm_mode == SM_MODE_TRANSMIT) {
|
||||
res = sc_transmit_apdu(card, apdu);
|
||||
LOG_TEST_RET(ctx, res, "Error in dnie_wrap_apdu process");
|
||||
res = cwa_decode_response(card, provider, apdu);
|
||||
|
|
|
@ -143,19 +143,18 @@ static void cwa_trace_apdu(sc_card_t * card, sc_apdu_t * apdu, int flag)
|
|||
* Increase send sequence counter SSC.
|
||||
*
|
||||
* @param card smart card info structure
|
||||
* @param sm Secure Message session handling data structure
|
||||
* @return SC_SUCCESS if ok; else error code
|
||||
*
|
||||
* TODO: to further study: what about using bignum arithmetics?
|
||||
*/
|
||||
static int cwa_increase_ssc(sc_card_t * card, cwa_sm_session_t * sm)
|
||||
static int cwa_increase_ssc(sc_card_t * card)
|
||||
{
|
||||
int n;
|
||||
struct sm_cwa_session * sm = &card->sm_ctx.info.session.cwa;
|
||||
|
||||
/* preliminary checks */
|
||||
if (!card || !card->ctx )
|
||||
return SC_ERROR_INVALID_ARGUMENTS;
|
||||
if (!sm )
|
||||
return SC_ERROR_SM_NOT_INITIALIZED;
|
||||
LOG_FUNC_CALLED(card->ctx);
|
||||
/* u8 arithmetic; exit loop if no carry */
|
||||
sc_log(card->ctx, "Curr SSC: '%s'", sc_dump_hex(sm->ssc, 8));
|
||||
|
@ -504,13 +503,13 @@ static int cwa_set_security_env(sc_card_t * card,
|
|||
* Internal (Card) authentication (let the card verify sent ifd certs)
|
||||
*
|
||||
* @param card pointer to card data
|
||||
* @param sm secure message data pointer
|
||||
* @param sig signature buffer
|
||||
* @param dig_len signature buffer length
|
||||
* @param data data to be sent in apdu
|
||||
* @param datalen length of data to send
|
||||
* @return SC_SUCCESS if OK: else error code
|
||||
*/
|
||||
static int cwa_internal_auth(sc_card_t * card,
|
||||
cwa_sm_status_t * sm, u8 * data, size_t datalen)
|
||||
static int cwa_internal_auth(sc_card_t * card, u8 * sig, size_t sig_len, u8 * data, size_t datalen)
|
||||
{
|
||||
sc_apdu_t apdu;
|
||||
u8 rbuf[SC_MAX_APDU_BUFFER_SIZE];
|
||||
|
@ -536,9 +535,9 @@ static int cwa_internal_auth(sc_card_t * card,
|
|||
result = sc_check_sw(card, apdu.sw1, apdu.sw2);
|
||||
LOG_TEST_RET(ctx, result, "SM internal auth invalid response");
|
||||
|
||||
if (apdu.resplen != sizeof(sm->sig)) /* invalid number of bytes received */
|
||||
if (apdu.resplen != sig_len) /* invalid number of bytes received */
|
||||
LOG_FUNC_RETURN(ctx, SC_ERROR_UNKNOWN_DATA_RECEIVED);
|
||||
memcpy(sm->sig, apdu.resp, apdu.resplen); /* copy result to buffer */
|
||||
memcpy(sig, apdu.resp, apdu.resplen); /* copy result to buffer */
|
||||
LOG_FUNC_RETURN(ctx, SC_SUCCESS);
|
||||
}
|
||||
|
||||
|
@ -554,13 +553,15 @@ static int cwa_internal_auth(sc_card_t * card,
|
|||
* @param icc_pubkey public key of card
|
||||
* @param ifd_privkey private RSA key of ifd
|
||||
* @param sn_icc card serial number
|
||||
* @param sm pointer to cwa_internal_t data
|
||||
* @param sig signature buffer
|
||||
* @param sig_len signature buffer length
|
||||
* @return SC_SUCCESS if ok; else errorcode
|
||||
*/
|
||||
static int cwa_prepare_external_auth(sc_card_t * card,
|
||||
RSA * icc_pubkey,
|
||||
RSA * ifd_privkey,
|
||||
u8 * sn_icc, cwa_sm_status_t * sm)
|
||||
u8 * sig,
|
||||
size_t sig_len)
|
||||
{
|
||||
/* we have to compose following message:
|
||||
data = E[PK.ICC.AUT](SIGMIN)
|
||||
|
@ -594,6 +595,7 @@ static int cwa_prepare_external_auth(sc_card_t * card,
|
|||
BIGNUM *bnres = NULL;
|
||||
sc_context_t *ctx = NULL;
|
||||
const BIGNUM *ifd_privkey_n, *ifd_privkey_e, *ifd_privkey_d;
|
||||
struct sm_cwa_session * sm = &card->sm_ctx.info.session.cwa;
|
||||
|
||||
/* safety check */
|
||||
if (!card || !card->ctx)
|
||||
|
@ -601,7 +603,7 @@ static int cwa_prepare_external_auth(sc_card_t * card,
|
|||
ctx = card->ctx;
|
||||
LOG_FUNC_CALLED(ctx);
|
||||
/* check received arguments */
|
||||
if (!icc_pubkey || !ifd_privkey || !sn_icc || !sm)
|
||||
if (!icc_pubkey || !ifd_privkey || !sm)
|
||||
LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_ARGUMENTS);
|
||||
buf1 = calloc(128, sizeof(u8));
|
||||
buf2 = calloc(128, sizeof(u8));
|
||||
|
@ -618,21 +620,20 @@ static int cwa_prepare_external_auth(sc_card_t * card,
|
|||
/* compose buffer data */
|
||||
buf3[0] = 0x6A; /* iso padding */
|
||||
RAND_bytes(buf3 + 1, 74); /* pRND */
|
||||
RAND_bytes(sm->kifd, 32); /* Kifd */
|
||||
memcpy(buf3 + 1 + 74, sm->kifd, 32); /* copy Kifd into buffer */
|
||||
RAND_bytes(sm->ifd.k, 32); /* Kifd */
|
||||
memcpy(buf3 + 1 + 74, sm->ifd.k, 32); /* copy Kifd into buffer */
|
||||
/* prepare data to be hashed */
|
||||
memcpy(sha_buf, buf3 + 1, 74); /* copy pRND into sha_buf */
|
||||
memcpy(sha_buf + 74, buf3 + 1 + 74, 32); /* copy kifd into sha_buf */
|
||||
memcpy(sha_buf + 74 + 32, sm->rndicc, 8); /* copy 8 byte icc challenge */
|
||||
memcpy(sha_buf + 74 + 32 + 8, sn_icc, 8); /* copy serialnr, 8 bytes */
|
||||
memcpy(sha_buf + 74 + 32, sm->icc.rnd, 8); /* copy 8 byte icc challenge */
|
||||
memcpy(sha_buf + 74 + 32 + 8, sm->icc.sn, 8); /* copy serialnr, 8 bytes */
|
||||
SHA1(sha_buf, 74 + 32 + 8 + 8, sha_data);
|
||||
/* copy hashed data into buffer */
|
||||
memcpy(buf3 + 1 + 74 + 32, sha_data, SHA_DIGEST_LENGTH);
|
||||
buf3[127] = 0xBC; /* iso padding */
|
||||
|
||||
/* encrypt with ifd private key */
|
||||
len2 =
|
||||
RSA_private_decrypt(128, buf3, buf2, ifd_privkey, RSA_NO_PADDING);
|
||||
len2 = RSA_private_decrypt(128, buf3, buf2, ifd_privkey, RSA_NO_PADDING);
|
||||
if (len2 < 0) {
|
||||
msg = "Prepare external auth: ifd_privk encrypt failed";
|
||||
res = SC_ERROR_SM_ENCRYPT_FAILED;
|
||||
|
@ -669,14 +670,14 @@ static int cwa_prepare_external_auth(sc_card_t * card,
|
|||
|
||||
/* re-encrypt result with icc public key */
|
||||
len1 = RSA_public_encrypt(len3, buf3, buf1, icc_pubkey, RSA_NO_PADDING);
|
||||
if (len1 <= 0) {
|
||||
if (len1 <= 0 || (size_t) len1 != sig_len) {
|
||||
msg = "Prepare external auth: icc_pubk encrypt failed";
|
||||
res = SC_ERROR_SM_ENCRYPT_FAILED;
|
||||
goto prepare_external_auth_end;
|
||||
}
|
||||
|
||||
/* process done: copy result into cwa_internal buffer and return success */
|
||||
memcpy(sm->sig, buf1, len1);
|
||||
memcpy(sig, buf1, len1);
|
||||
res = SC_SUCCESS;
|
||||
|
||||
prepare_external_auth_end:
|
||||
|
@ -715,11 +716,12 @@ static int cwa_prepare_external_auth(sc_card_t * card,
|
|||
*
|
||||
* Perform external (IFD) authenticate procedure (8.4.1.2)
|
||||
*
|
||||
* @param data apdu signature content
|
||||
* @param datalen signature length (128)
|
||||
* @param card pointer to card data
|
||||
* @param sig signature buffer
|
||||
* @param sig signature buffer length
|
||||
* @return SC_SUCCESS if OK: else error code
|
||||
*/
|
||||
static int cwa_external_auth(sc_card_t * card, cwa_sm_status_t * sm)
|
||||
static int cwa_external_auth(sc_card_t * card, u8 * sig, size_t sig_len)
|
||||
{
|
||||
sc_apdu_t apdu;
|
||||
int result = SC_SUCCESS;
|
||||
|
@ -733,8 +735,8 @@ static int cwa_external_auth(sc_card_t * card, cwa_sm_status_t * sm)
|
|||
LOG_FUNC_CALLED(ctx);
|
||||
|
||||
/* compose apdu for External Authenticate cmd */
|
||||
dnie_format_apdu(card, &apdu, SC_APDU_CASE_4_SHORT, 0x82, 0x00, 0x00, 255, sizeof(sm->sig),
|
||||
resp, MAX_RESP_BUFFER_SIZE, sm->sig, sizeof(sm->sig));
|
||||
dnie_format_apdu(card, &apdu, SC_APDU_CASE_4_SHORT, 0x82, 0x00, 0x00, 255, sig_len,
|
||||
resp, MAX_RESP_BUFFER_SIZE, sig, sig_len);
|
||||
|
||||
/* send composed apdu and parse result */
|
||||
result = dnie_transmit_apdu(card, &apdu);
|
||||
|
@ -750,10 +752,9 @@ static int cwa_external_auth(sc_card_t * card, cwa_sm_status_t * sm)
|
|||
* Compute Kenc,Kmac, and SSC and store it into sm data
|
||||
*
|
||||
* @param card pointer to sc_card_t data
|
||||
* @param sm pointer to cwa_internal_t data
|
||||
* @return SC_SUCCESS if ok; else error code
|
||||
*/
|
||||
static int cwa_compute_session_keys(sc_card_t * card, cwa_sm_status_t * sm)
|
||||
static int cwa_compute_session_keys(sc_card_t * card)
|
||||
{
|
||||
|
||||
char *msg = NULL;
|
||||
|
@ -765,6 +766,7 @@ static int cwa_compute_session_keys(sc_card_t * card, cwa_sm_status_t * sm)
|
|||
u8 kenc[4] = { 0x00, 0x00, 0x00, 0x01 };
|
||||
u8 kmac[4] = { 0x00, 0x00, 0x00, 0x02 };
|
||||
sc_context_t *ctx = NULL;
|
||||
struct sm_cwa_session * sm = &card->sm_ctx.info.session.cwa;
|
||||
|
||||
/* safety check */
|
||||
if (!card || !card->ctx)
|
||||
|
@ -782,13 +784,13 @@ static int cwa_compute_session_keys(sc_card_t * card, cwa_sm_status_t * sm)
|
|||
}
|
||||
/* compose kseed (cwa-14890-1 sect 8.7.2) */
|
||||
for (n = 0; n < 32; n++)
|
||||
*(kseed + n) = sm->kicc[n] ^ sm->kifd[n];
|
||||
*(kseed + n) = sm->icc.k[n] ^ sm->ifd.k[n];
|
||||
|
||||
/* evaluate kenc (cwa-14890-1 sect 8.8) */
|
||||
memcpy(data, kseed, 32);
|
||||
memcpy(data + 32, kenc, 4);
|
||||
SHA1(data, 32 + 4, sha_data);
|
||||
memcpy(sm->session.kenc, sha_data, 16); /* kenc=16 fsb sha((kifd^kicc)||00000001) */
|
||||
memcpy(sm->session_enc, sha_data, 16); /* kenc=16 fsb sha((kifd^kicc)||00000001) */
|
||||
|
||||
/* evaluate kmac */
|
||||
memset(data, 0, 32 + 4);
|
||||
|
@ -797,11 +799,11 @@ static int cwa_compute_session_keys(sc_card_t * card, cwa_sm_status_t * sm)
|
|||
memcpy(data, kseed, 32);
|
||||
memcpy(data + 32, kmac, 4);
|
||||
SHA1(data, 32 + 4, sha_data);
|
||||
memcpy(sm->session.kmac, sha_data, 16); /* kmac=16 fsb sha((kifd^kicc)||00000002) */
|
||||
memcpy(sm->session_mac, sha_data, 16); /* kmac=16 fsb sha((kifd^kicc)||00000002) */
|
||||
|
||||
/* evaluate send sequence counter (cwa-14890-1 sect 8.9 & 9.6 */
|
||||
memcpy(sm->session.ssc, sm->rndicc + 4, 4); /* 4 least significant bytes of rndicc */
|
||||
memcpy(sm->session.ssc + 4, sm->rndifd + 4, 4); /* 4 least significant bytes of rndifd */
|
||||
memcpy(sm->ssc, sm->icc.rnd + 4, 4); /* 4 least significant bytes of rndicc */
|
||||
memcpy(sm->ssc + 4, sm->ifd.rnd + 4, 4); /* 4 least significant bytes of rndifd */
|
||||
|
||||
/* arriving here means process ok */
|
||||
res = SC_SUCCESS;
|
||||
|
@ -822,9 +824,9 @@ static int cwa_compute_session_keys(sc_card_t * card, cwa_sm_status_t * sm)
|
|||
if (res != SC_SUCCESS)
|
||||
sc_log(ctx, msg);
|
||||
else {
|
||||
sc_log(ctx, "Kenc: %s", sc_dump_hex(sm->session.kenc, 16));
|
||||
sc_log(ctx, "Kmac: %s", sc_dump_hex(sm->session.kmac, 16));
|
||||
sc_log(ctx, "SSC: %s", sc_dump_hex(sm->session.ssc, 8));
|
||||
sc_log(ctx, "Kenc: %s", sc_dump_hex(sm->session_enc, 16));
|
||||
sc_log(ctx, "Kmac: %s", sc_dump_hex(sm->session_mac, 16));
|
||||
sc_log(ctx, "SSC: %s", sc_dump_hex(sm->ssc, 8));
|
||||
}
|
||||
LOG_FUNC_RETURN(ctx, res);
|
||||
}
|
||||
|
@ -877,14 +879,17 @@ static int cwa_compare_signature(u8 * data, size_t dlen, u8 * ifd_data)
|
|||
* @param ifd_privkey ifd private key
|
||||
* @param ifdbuf buffer containing ( RND.IFD || SN.IFD )
|
||||
* @param ifdlen buffer length; should be 16
|
||||
* @param sm secure messaging internal data
|
||||
* @param sig signature buffer
|
||||
* @param sig_len signature buffer length
|
||||
* @return SC_SUCCESS if ok; else error code
|
||||
*/
|
||||
static int cwa_verify_internal_auth(sc_card_t * card,
|
||||
RSA * icc_pubkey,
|
||||
RSA * ifd_privkey,
|
||||
u8 * ifdbuf,
|
||||
size_t ifdlen, cwa_sm_status_t * sm)
|
||||
size_t ifdlen,
|
||||
u8 * sig,
|
||||
size_t sig_len)
|
||||
{
|
||||
int res = SC_SUCCESS;
|
||||
char *msg = NULL;
|
||||
|
@ -898,6 +903,7 @@ static int cwa_verify_internal_auth(sc_card_t * card,
|
|||
BIGNUM *sigbn = NULL;
|
||||
sc_context_t *ctx = NULL;
|
||||
const BIGNUM *icc_pubkey_n, *icc_pubkey_e, *icc_pubkey_d;
|
||||
struct sm_cwa_session * sm = &card->sm_ctx.info.session.cwa;
|
||||
|
||||
if (!card || !card->ctx)
|
||||
return SC_ERROR_INVALID_ARGUMENTS;
|
||||
|
@ -937,9 +943,7 @@ static int cwa_verify_internal_auth(sc_card_t * card,
|
|||
*/
|
||||
|
||||
/* decrypt data with our ifd priv key */
|
||||
len1 =
|
||||
RSA_private_decrypt(sizeof(sm->sig), sm->sig, buf1, ifd_privkey,
|
||||
RSA_NO_PADDING);
|
||||
len1 = RSA_private_decrypt(sig_len, sig, buf1, ifd_privkey, RSA_NO_PADDING);
|
||||
if (len1 <= 0) {
|
||||
msg = "Verify Signature: decrypt with ifd privk failed";
|
||||
res = SC_ERROR_SM_ENCRYPT_FAILED;
|
||||
|
@ -997,7 +1001,7 @@ static int cwa_verify_internal_auth(sc_card_t * card,
|
|||
}
|
||||
/* arriving here means OK: complete data structures */
|
||||
verify_internal_ok:
|
||||
memcpy(sm->kicc, buf3 + 1 + 74, 32); /* extract Kicc from buf3 */
|
||||
memcpy(sm->icc.k, buf3 + 1 + 74, 32); /* extract Kicc from buf3 */
|
||||
res = SC_SUCCESS;
|
||||
verify_internal_done:
|
||||
if (buf1)
|
||||
|
@ -1044,15 +1048,14 @@ int cwa_create_secure_channel(sc_card_t * card,
|
|||
int res = SC_SUCCESS;
|
||||
char *msg = "Success";
|
||||
|
||||
u8 *sn_icc = NULL;
|
||||
|
||||
/* data to get and parse certificates */
|
||||
X509 *icc_cert = NULL;
|
||||
X509 *ca_cert = NULL;
|
||||
EVP_PKEY *icc_pubkey = NULL;
|
||||
EVP_PKEY *ifd_privkey = NULL;
|
||||
sc_context_t *ctx = NULL;
|
||||
cwa_sm_status_t *sm = NULL;
|
||||
struct sm_cwa_session * sm = &card->sm_ctx.info.session.cwa;
|
||||
u8 sig[128];
|
||||
|
||||
/* several buffer and buffer pointers */
|
||||
u8 *buffer = NULL;
|
||||
|
@ -1068,34 +1071,17 @@ int cwa_create_secure_channel(sc_card_t * card,
|
|||
return SC_ERROR_SM_NOT_INITIALIZED;
|
||||
/* comodity vars */
|
||||
ctx = card->ctx;
|
||||
sm = &(provider->status);
|
||||
|
||||
LOG_FUNC_CALLED(ctx);
|
||||
|
||||
/* check requested initialization method */
|
||||
switch (flag) {
|
||||
case CWA_SM_OFF: /* disable SM */
|
||||
provider->status.session.state = CWA_SM_NONE; /* just mark channel inactive */
|
||||
card->sm_ctx.sm_mode = SM_MODE_NONE;
|
||||
sc_log(ctx, "Setting CWA SM status to none");
|
||||
LOG_FUNC_RETURN(ctx, SC_SUCCESS);
|
||||
case CWA_SM_WARM: /* only initialize if not already done */
|
||||
if (provider->status.session.state != CWA_SM_NONE) {
|
||||
sc_log(ctx,
|
||||
"Warm CWA SM requested: already in SM state");
|
||||
LOG_FUNC_RETURN(ctx, SC_SUCCESS);
|
||||
}
|
||||
case CWA_SM_COLD: /* force sm initialization process */
|
||||
sc_log(ctx, "CWA SM initialization requested => reset and re-initialize");
|
||||
sc_reset(card, 0);
|
||||
provider->status.session.state = CWA_SM_INPROGRESS;
|
||||
card->sm_ctx.sm_mode = SM_MODE_NONE;
|
||||
break;
|
||||
case CWA_SM_OVER: /* create another channel over an existing one */
|
||||
if (provider->status.session.state != CWA_SM_ACTIVE) {
|
||||
sc_log(ctx, "CWA SM over requested => not in active state");
|
||||
LOG_FUNC_RETURN(ctx, SC_ERROR_SM_INVALID_LEVEL);
|
||||
}
|
||||
case CWA_SM_ON: /* force sm initialization process */
|
||||
sc_log(ctx, "CWA SM initialization requested");
|
||||
break;
|
||||
default:
|
||||
sc_log(ctx, "Invalid provided SM initialization flag");
|
||||
|
@ -1118,7 +1104,7 @@ int cwa_create_secure_channel(sc_card_t * card,
|
|||
/* retrieve icc serial number */
|
||||
sc_log(ctx, "Retrieve ICC serial number");
|
||||
if (provider->cwa_get_sn_icc) {
|
||||
res = provider->cwa_get_sn_icc(card, &sn_icc);
|
||||
res = provider->cwa_get_sn_icc(card);
|
||||
if (res != SC_SUCCESS) {
|
||||
msg = "Retrieve ICC failed";
|
||||
sc_log(ctx, msg);
|
||||
|
@ -1308,15 +1294,15 @@ int cwa_create_secure_channel(sc_card_t * card,
|
|||
/* Internal (Card) authentication (let the card verify sent ifd certs)
|
||||
SN.IFD equals 8 lsb bytes of ifd.pubk ref according cwa14890 sec 8.4.1 */
|
||||
sc_log(ctx, "Step 8.4.1.10: Perform Internal authentication");
|
||||
res = provider->cwa_get_sn_ifd(card, &buffer);
|
||||
res = provider->cwa_get_sn_ifd(card);
|
||||
if (res != SC_SUCCESS) {
|
||||
msg = "Cannot get ifd serial number from provider";
|
||||
goto csc_end;
|
||||
}
|
||||
RAND_bytes(sm->rndifd, 8); /* generate 8 random bytes */
|
||||
memcpy(rndbuf, sm->rndifd, 8); /* insert RND.IFD into rndbuf */
|
||||
memcpy(rndbuf + 8, buffer, 8); /* insert SN.IFD into rndbuf */
|
||||
res = cwa_internal_auth(card, sm, rndbuf, 16);
|
||||
RAND_bytes(sm->ifd.rnd, 8); /* generate 8 random bytes */
|
||||
memcpy(rndbuf, sm->ifd.rnd, 8); /* insert RND.IFD into rndbuf */
|
||||
memcpy(rndbuf + 8, sm->ifd.sn, 8); /* insert SN.IFD into rndbuf */
|
||||
res = cwa_internal_auth(card, sig, 128, rndbuf, 16);
|
||||
if (res != SC_SUCCESS) {
|
||||
msg = "Internal auth cmd failed";
|
||||
goto csc_end;
|
||||
|
@ -1336,7 +1322,7 @@ int cwa_create_secure_channel(sc_card_t * card,
|
|||
EVP_PKEY_get0_RSA(ifd_privkey), /* evaluated from DGP's Manual Annex 3 Data */
|
||||
rndbuf, /* RND.IFD || SN.IFD */
|
||||
16, /* rndbuf length; should be 16 */
|
||||
sm /* sm data */
|
||||
sig, 128
|
||||
);
|
||||
if (res != SC_SUCCESS) {
|
||||
msg = "Internal Auth Verify failed";
|
||||
|
@ -1345,7 +1331,7 @@ int cwa_create_secure_channel(sc_card_t * card,
|
|||
|
||||
/* get challenge: retrieve 8 random bytes from card */
|
||||
sc_log(ctx, "Step 8.4.1.11: Prepare External Auth: Get Challenge");
|
||||
res = card->ops->get_challenge(card, sm->rndicc, sizeof(sm->rndicc));
|
||||
res = card->ops->get_challenge(card, sm->icc.rnd, sizeof(sm->icc.rnd));
|
||||
if (res != SC_SUCCESS) {
|
||||
msg = "Get Challenge failed";
|
||||
goto csc_end;
|
||||
|
@ -1354,7 +1340,7 @@ int cwa_create_secure_channel(sc_card_t * card,
|
|||
/* compose signature data for external auth */
|
||||
res = cwa_prepare_external_auth(card,
|
||||
EVP_PKEY_get0_RSA(icc_pubkey),
|
||||
EVP_PKEY_get0_RSA(ifd_privkey), sn_icc, sm);
|
||||
EVP_PKEY_get0_RSA(ifd_privkey), sig, 128);
|
||||
if (res != SC_SUCCESS) {
|
||||
msg = "Prepare external auth failed";
|
||||
goto csc_end;
|
||||
|
@ -1362,7 +1348,7 @@ int cwa_create_secure_channel(sc_card_t * card,
|
|||
|
||||
/* External (IFD) authentication */
|
||||
sc_log(ctx, "Step 8.4.1.12: Perform External (IFD) Authentication");
|
||||
res = cwa_external_auth(card, sm);
|
||||
res = cwa_external_auth(card, sig, 128);
|
||||
if (res != SC_SUCCESS) {
|
||||
msg = "External auth cmd failed";
|
||||
goto csc_end;
|
||||
|
@ -1370,7 +1356,7 @@ int cwa_create_secure_channel(sc_card_t * card,
|
|||
|
||||
/* Session key generation */
|
||||
sc_log(ctx, "Step 8.4.2: Compute Session Keys");
|
||||
res = cwa_compute_session_keys(card, sm);
|
||||
res = cwa_compute_session_keys(card);
|
||||
if (res != SC_SUCCESS) {
|
||||
msg = "Session Key generation failed";
|
||||
goto csc_end;
|
||||
|
@ -1401,9 +1387,9 @@ int cwa_create_secure_channel(sc_card_t * card,
|
|||
/* setup SM state according result */
|
||||
if (res != SC_SUCCESS) {
|
||||
sc_log(ctx, msg);
|
||||
provider->status.session.state = CWA_SM_NONE;
|
||||
card->sm_ctx.sm_mode = SM_MODE_NONE;
|
||||
} else {
|
||||
provider->status.session.state = CWA_SM_ACTIVE;
|
||||
card->sm_ctx.sm_mode = SM_MODE_TRANSMIT;
|
||||
}
|
||||
LOG_FUNC_RETURN(ctx, res);
|
||||
}
|
||||
|
@ -1439,7 +1425,7 @@ int cwa_encode_apdu(sc_card_t * card,
|
|||
size_t i, j; /* for xor loops */
|
||||
int res = SC_SUCCESS;
|
||||
sc_context_t *ctx = NULL;
|
||||
cwa_sm_session_t *sm_session = NULL;
|
||||
struct sm_cwa_session * sm_session = &card->sm_ctx.info.session.cwa;
|
||||
u8 *msgbuf = NULL; /* to encrypt apdu data */
|
||||
u8 *cryptbuf = NULL;
|
||||
|
||||
|
@ -1447,13 +1433,12 @@ int cwa_encode_apdu(sc_card_t * card,
|
|||
if (!card || !card->ctx || !provider)
|
||||
return SC_ERROR_INVALID_ARGUMENTS;
|
||||
ctx = card->ctx;
|
||||
sm_session = &(provider->status.session);
|
||||
|
||||
LOG_FUNC_CALLED(ctx);
|
||||
/* check remaining arguments */
|
||||
if (!from || !to || !sm_session)
|
||||
LOG_FUNC_RETURN(ctx, SC_ERROR_SM_NOT_INITIALIZED);
|
||||
if (sm_session->state != CWA_SM_ACTIVE)
|
||||
if (card->sm_ctx.sm_mode != SM_MODE_TRANSMIT)
|
||||
LOG_FUNC_RETURN(ctx, SC_ERROR_SM_INVALID_LEVEL);
|
||||
|
||||
/* reserve extra bytes for padding and tlv header */
|
||||
|
@ -1514,9 +1499,9 @@ int cwa_encode_apdu(sc_card_t * card,
|
|||
|
||||
/* prepare keys */
|
||||
DES_cblock iv = { 0, 0, 0, 0, 0, 0, 0, 0 };
|
||||
DES_set_key_unchecked((const_DES_cblock *) & (sm_session->kenc[0]),
|
||||
DES_set_key_unchecked((const_DES_cblock *) & (sm_session->session_enc[0]),
|
||||
&k1);
|
||||
DES_set_key_unchecked((const_DES_cblock *) & (sm_session->kenc[8]),
|
||||
DES_set_key_unchecked((const_DES_cblock *) & (sm_session->session_enc[8]),
|
||||
&k2);
|
||||
|
||||
/* pad message */
|
||||
|
@ -1562,14 +1547,14 @@ int cwa_encode_apdu(sc_card_t * card,
|
|||
|
||||
/* sc_log(ctx,"data to compose mac: %s",sc_dump_hex(ccbuf,cclen)); */
|
||||
/* compute MAC Cryptographic Checksum using kmac and increased SSC */
|
||||
res = cwa_increase_ssc(card, sm_session); /* increase send sequence counter */
|
||||
res = cwa_increase_ssc(card); /* increase send sequence counter */
|
||||
if (res != SC_SUCCESS) {
|
||||
msg = "Error in computing SSC";
|
||||
goto encode_end;
|
||||
}
|
||||
/* set up keys for mac computing */
|
||||
DES_set_key_unchecked((const_DES_cblock *) & (sm_session->kmac[0]),&k1);
|
||||
DES_set_key_unchecked((const_DES_cblock *) & (sm_session->kmac[8]),&k2);
|
||||
DES_set_key_unchecked((const_DES_cblock *) & (sm_session->session_mac[0]),&k1);
|
||||
DES_set_key_unchecked((const_DES_cblock *) & (sm_session->session_mac[8]),&k2);
|
||||
|
||||
memcpy(macbuf, sm_session->ssc, 8); /* start with computed SSC */
|
||||
for (i = 0; i < cclen; i += 8) { /* divide data in 8 byte blocks */
|
||||
|
@ -1649,19 +1634,18 @@ int cwa_decode_response(sc_card_t * card,
|
|||
int res = SC_SUCCESS;
|
||||
char *msg = NULL; /* to store error messages */
|
||||
sc_context_t *ctx = NULL;
|
||||
cwa_sm_session_t *sm_session = NULL;
|
||||
struct sm_cwa_session * sm_session = &card->sm_ctx.info.session.cwa;
|
||||
|
||||
/* mandatory check */
|
||||
if (!card || !card->ctx || !provider)
|
||||
return SC_ERROR_INVALID_ARGUMENTS;
|
||||
ctx = card->ctx;
|
||||
sm_session = &(provider->status.session);
|
||||
|
||||
LOG_FUNC_CALLED(ctx);
|
||||
/* check remaining arguments */
|
||||
if ((apdu == NULL) || (sm_session == NULL))
|
||||
LOG_FUNC_RETURN(ctx, SC_ERROR_SM_NOT_INITIALIZED);
|
||||
if (sm_session->state != CWA_SM_ACTIVE)
|
||||
if (card->sm_ctx.sm_mode != SM_MODE_TRANSMIT)
|
||||
LOG_FUNC_RETURN(ctx, SC_ERROR_SM_INVALID_LEVEL);
|
||||
|
||||
/* cwa14890 sect 9.3: check SW1 or SW2 for SM related errors */
|
||||
|
@ -1766,14 +1750,14 @@ int cwa_decode_response(sc_card_t * card,
|
|||
/* evaluate mac by mean of kmac and increased SendSequence Counter SSC */
|
||||
|
||||
/* increase SSC */
|
||||
res = cwa_increase_ssc(card, sm_session); /* increase send sequence counter */
|
||||
res = cwa_increase_ssc(card); /* increase send sequence counter */
|
||||
if (res != SC_SUCCESS) {
|
||||
msg = "Error in computing SSC";
|
||||
goto response_decode_end;
|
||||
}
|
||||
/* set up keys for mac computing */
|
||||
DES_set_key_unchecked((const_DES_cblock *) & (sm_session->kmac[0]), &k1);
|
||||
DES_set_key_unchecked((const_DES_cblock *) & (sm_session->kmac[8]), &k2);
|
||||
DES_set_key_unchecked((const_DES_cblock *) & (sm_session->session_mac[0]), &k1);
|
||||
DES_set_key_unchecked((const_DES_cblock *) & (sm_session->session_mac[8]), &k2);
|
||||
|
||||
memcpy(macbuf, sm_session->ssc, 8); /* start with computed SSC */
|
||||
for (i = 0; i < cclen; i += 8) { /* divide data in 8 byte blocks */
|
||||
|
@ -1834,9 +1818,9 @@ int cwa_decode_response(sc_card_t * card,
|
|||
goto response_decode_end;
|
||||
}
|
||||
/* prepare keys to decode */
|
||||
DES_set_key_unchecked((const_DES_cblock *) & (sm_session->kenc[0]),
|
||||
DES_set_key_unchecked((const_DES_cblock *) & (sm_session->session_enc[0]),
|
||||
&k1);
|
||||
DES_set_key_unchecked((const_DES_cblock *) & (sm_session->kenc[8]),
|
||||
DES_set_key_unchecked((const_DES_cblock *) & (sm_session->session_enc[8]),
|
||||
&k2);
|
||||
/* decrypt into response buffer
|
||||
* by using 3DES CBC by mean of kenc and iv={0,...0} */
|
||||
|
@ -1953,13 +1937,13 @@ static int default_get_icc_privkey_ref(sc_card_t * card, u8 ** buf,
|
|||
}
|
||||
|
||||
/* Retrieve SN.IFD (8 bytes left padded with zeroes if needed) */
|
||||
static int default_get_sn_ifd(sc_card_t * card, u8 ** buf)
|
||||
static int default_get_sn_ifd(sc_card_t * card)
|
||||
{
|
||||
return SC_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
/* Retrieve SN.ICC (8 bytes left padded with zeroes if needed) */
|
||||
static int default_get_sn_icc(sc_card_t * card, u8 ** buf)
|
||||
static int default_get_sn_icc(sc_card_t * card)
|
||||
{
|
||||
return SC_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
|
@ -1967,50 +1951,6 @@ static int default_get_sn_icc(sc_card_t * card, u8 ** buf)
|
|||
static cwa_provider_t default_cwa_provider = {
|
||||
|
||||
/************ data related with SM operations *************************/
|
||||
{
|
||||
{ /* KICC */
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
|
||||
{ /* KIFD */
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
|
||||
{ /* RND.ICC */
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
|
||||
{ /* RND.IFD */
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
|
||||
{ /* SigBuf */
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
|
||||
{ /* sm session */
|
||||
CWA_SM_NONE, /* state */
|
||||
{ /* Kenc */
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
|
||||
{ /* Kmac */
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
|
||||
{ /* SSC Send Sequence counter */
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
|
||||
}
|
||||
},
|
||||
|
||||
/************ operations related with secure channel creation *********/
|
||||
|
||||
|
|
|
@ -27,16 +27,9 @@
|
|||
|
||||
#if defined(ENABLE_OPENSSL) && defined(ENABLE_SM)
|
||||
|
||||
/* Secure Messaging state indicator */
|
||||
#define CWA_SM_NONE 0x00 /** No SM channel defined */
|
||||
#define CWA_SM_INPROGRESS 0x01 /** SM channel is being created: don't use */
|
||||
#define CWA_SM_ACTIVE 0x02 /** SM channel is active */
|
||||
|
||||
/* Flags for setting SM status */
|
||||
#define CWA_SM_OFF 0x00 /** Disable SM channel */
|
||||
#define CWA_SM_COLD 0x01 /** force creation of a new SM channel */
|
||||
#define CWA_SM_WARM 0x02 /** Create new SM channel only if state is NONE */
|
||||
#define CWA_SM_OVER 0x03 /** Create new SM channel only over another channel */
|
||||
#define CWA_SM_ON 0x01 /** Enable SM channel */
|
||||
|
||||
/* TAGS for encoded APDU's */
|
||||
#define CWA_SM_PLAIN_TAG 0x81 /** Plain value (to be protected by CC) */
|
||||
|
@ -52,40 +45,11 @@
|
|||
#include <openssl/x509.h>
|
||||
#include <openssl/des.h>
|
||||
|
||||
/**
|
||||
* Structure used to handle keys and sequence counter once SM session
|
||||
* is stablished
|
||||
*/
|
||||
typedef struct cwa_sm_session_st {
|
||||
/* variables used once SM is started */
|
||||
int state; /** one of NONE, INPROGRESS, or ACTIVE */
|
||||
u8 kenc[16]; /** key used for data encoding */
|
||||
u8 kmac[16]; /** key for mac checksum calculation */
|
||||
u8 ssc[8]; /** send sequence counter */
|
||||
} cwa_sm_session_t;
|
||||
|
||||
/**
|
||||
* Estructure used to compose and store variables related to SM setting
|
||||
* and encode/decode apdu messages.
|
||||
*/
|
||||
typedef struct cwa_sm_status_st {
|
||||
/* variables used in SM establishment */
|
||||
u8 kicc[32];
|
||||
u8 kifd[32];
|
||||
u8 rndicc[8]; /** 8 bytes random number generated by card */
|
||||
u8 rndifd[8]; /** 8 bytes random number generated by application */
|
||||
u8 sig[128]; /** buffer to store & compute signatures (1024 bits) */
|
||||
cwa_sm_session_t session; /** current session data */
|
||||
} cwa_sm_status_t;
|
||||
|
||||
/**
|
||||
* Data and function pointers to provide information to create and handle
|
||||
* Secure Channel.
|
||||
*/
|
||||
typedef struct cwa_provider_st {
|
||||
/************ data related with SM operations *************************/
|
||||
|
||||
cwa_sm_status_t status; /** sm status for this provider */
|
||||
|
||||
/************ operations related with secure channel creation *********/
|
||||
|
||||
|
@ -257,23 +221,23 @@ typedef struct cwa_provider_st {
|
|||
* Retrieve SN.IFD - Terminal Serial Number.
|
||||
*
|
||||
* Result SN is 8 bytes long left padded with zeroes if required.
|
||||
* The result should stored in card->sm_ctx.info.session.cwa.ifd.sn
|
||||
*
|
||||
* @param card pointer to card structure
|
||||
* @param buf where to store result (8 bytes)
|
||||
* @return SC_SUCCESS if ok; else error
|
||||
*/
|
||||
int (*cwa_get_sn_ifd) (sc_card_t * card, u8 ** buf);
|
||||
int (*cwa_get_sn_ifd) (sc_card_t * card);
|
||||
|
||||
/**
|
||||
* Get SN.ICC - Card Serial Number.
|
||||
*
|
||||
* Result value is 8 bytes long left padded with zeroes if needed)
|
||||
* The result should stored in card->sm_ctx.info.session.cwa.icc.sn
|
||||
*
|
||||
* @param card pointer to card structure
|
||||
* @param buf where to store result (8 bytes)
|
||||
* @return SC_SUCCESS if ok; else error
|
||||
*/
|
||||
int (*cwa_get_sn_icc) (sc_card_t * card, u8 ** buf);
|
||||
int (*cwa_get_sn_icc) (sc_card_t * card);
|
||||
|
||||
|
||||
} cwa_provider_t;
|
||||
|
|
Loading…
Reference in New Issue