sm: change SM data types, thanks to Frank Morgner for revision
http://www.opensc-project.org/pipermail/opensc-devel/2012-July/018232.html
This commit is contained in:
parent
7301715624
commit
c7827e5e4b
@ -2151,7 +2151,7 @@ authentic_sm_acl_init (struct sc_card *card, struct sm_info *sm_info, int cmd,
|
||||
unsigned char *resp, size_t *resp_len)
|
||||
{
|
||||
struct sc_context *ctx = card->ctx;
|
||||
struct sm_type_params_gp *params_gp = &sm_info->sm_params.gp;
|
||||
struct sm_type_params_gp *params_gp = &sm_info->session.gp.params;
|
||||
struct sc_remote_data rdata;
|
||||
int rv;
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
* iasecc.h Support for IAS/ECC smart cards
|
||||
*
|
||||
* Copyright (C) 2010 Viktor Tarasov <vtarasov@opentrust.com>
|
||||
* OpenTrust <www.opentrust.com>
|
||||
* OpenTrust <www.opentrust.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
@ -157,6 +157,7 @@ iasecc_sm_external_authentication(struct sc_card *card, unsigned skey_ref, int *
|
||||
struct sc_context *ctx = card->ctx;
|
||||
#ifdef ENABLE_SM
|
||||
struct sm_info *sm_info = &card->sm_ctx.info;
|
||||
struct sm_cwa_session *cwa_session = &sm_info->session.cwa;
|
||||
struct sc_remote_data rdata;
|
||||
struct sc_apdu apdu;
|
||||
unsigned char sbuf[0x100];
|
||||
@ -173,9 +174,9 @@ iasecc_sm_external_authentication(struct sc_card *card, unsigned skey_ref, int *
|
||||
sm_info->serialnr = card->serialnr;
|
||||
sm_info->card_type = card->type;
|
||||
sm_info->sm_type = SM_TYPE_CWA14890;
|
||||
sm_info->sm_params.cwa.crt_at.usage = IASECC_UQB_AT_EXTERNAL_AUTHENTICATION;
|
||||
sm_info->sm_params.cwa.crt_at.algo = IASECC_ALGORITHM_ROLE_AUTH;
|
||||
sm_info->sm_params.cwa.crt_at.refs[0] = skey_ref;
|
||||
cwa_session->params.crt_at.usage = IASECC_UQB_AT_EXTERNAL_AUTHENTICATION;
|
||||
cwa_session->params.crt_at.algo = IASECC_ALGORITHM_ROLE_AUTH;
|
||||
cwa_session->params.crt_at.refs[0] = skey_ref;
|
||||
|
||||
offs = 0;
|
||||
sbuf[offs++] = IASECC_CRT_TAG_ALGO;
|
||||
@ -195,7 +196,7 @@ iasecc_sm_external_authentication(struct sc_card *card, unsigned skey_ref, int *
|
||||
rv = sc_check_sw(card, apdu.sw1, apdu.sw2);
|
||||
LOG_TEST_RET(ctx, rv, "iasecc_sm_external_authentication(): set SE error");
|
||||
|
||||
rv = sc_get_challenge(card, sm_info->schannel.card_challenge, sizeof(sm_info->schannel.card_challenge));
|
||||
rv = sc_get_challenge(card, cwa_session->card_challenge, sizeof(cwa_session->card_challenge));
|
||||
LOG_TEST_RET(ctx, rv, "iasecc_sm_external_authentication(): set SE error");
|
||||
|
||||
sc_remote_data_init(&rdata);
|
||||
@ -227,7 +228,7 @@ iasecc_sm_se_mutual_authentication(struct sc_card *card, unsigned se_num)
|
||||
#ifdef ENABLE_SM
|
||||
struct sm_info *sm_info = &card->sm_ctx.info;
|
||||
struct iasecc_se_info se;
|
||||
struct sc_crt *crt = &sm_info->sm_params.cwa.crt_at;
|
||||
struct sc_crt *crt = &sm_info->session.cwa.params.crt_at;
|
||||
struct sc_apdu apdu;
|
||||
unsigned char sbuf[0x100];
|
||||
int rv, offs;
|
||||
@ -305,7 +306,7 @@ iasecc_sm_initialize(struct sc_card *card, unsigned se_num, unsigned cmd)
|
||||
struct sc_context *ctx = card->ctx;
|
||||
#ifdef ENABLE_SM
|
||||
struct sm_info *sm_info = &card->sm_ctx.info;
|
||||
struct sm_cwa_session *cwa_session = &sm_info->schannel.session.cwa;
|
||||
struct sm_cwa_session *cwa_session = &sm_info->session.cwa;
|
||||
struct sc_remote_data rdata;
|
||||
int rv;
|
||||
|
||||
@ -320,7 +321,7 @@ iasecc_sm_initialize(struct sc_card *card, unsigned se_num, unsigned cmd)
|
||||
rv = iasecc_sm_se_mutual_authentication(card, se_num);
|
||||
LOG_TEST_RET(ctx, rv, "iasecc_sm_initialize() MUTUAL AUTHENTICATION failed");
|
||||
|
||||
rv = iasecc_sm_get_challenge(card, sm_info->schannel.card_challenge, SM_SMALL_CHALLENGE_LEN);
|
||||
rv = iasecc_sm_get_challenge(card, cwa_session->card_challenge, SM_SMALL_CHALLENGE_LEN);
|
||||
LOG_TEST_RET(ctx, rv, "iasecc_sm_initialize() GET CHALLENGE failed");
|
||||
|
||||
sc_remote_data_init(&rdata);
|
||||
@ -351,7 +352,7 @@ iasecc_sm_initialize(struct sc_card *card, unsigned se_num, unsigned cmd)
|
||||
rdata.free(&rdata);
|
||||
|
||||
sc_log(ctx, "MA data(len:%i) '%s'", cwa_session->mdata_len, sc_dump_hex(cwa_session->mdata, cwa_session->mdata_len));
|
||||
if (sm_info->schannel.session.cwa.mdata_len != 0x48)
|
||||
if (cwa_session->mdata_len != 0x48)
|
||||
LOG_TEST_RET(ctx, SC_ERROR_INVALID_DATA, "iasecc_sm_initialize() invalid MUTUAL AUTHENTICATE result data");
|
||||
|
||||
LOG_FUNC_RETURN(ctx, SC_SUCCESS);
|
||||
@ -370,7 +371,7 @@ iasecc_sm_cmd(struct sc_card *card, struct sc_remote_data *rdata)
|
||||
struct sc_context *ctx = card->ctx;
|
||||
#ifdef ENABLE_SM
|
||||
struct sm_info *sm_info = &card->sm_ctx.info;
|
||||
struct sm_cwa_session *session = &sm_info->schannel.session.cwa;
|
||||
struct sm_cwa_session *session = &sm_info->session.cwa;
|
||||
struct sc_remote_apdu *rapdu = NULL;
|
||||
int rv;
|
||||
|
||||
|
@ -60,9 +60,9 @@ extern "C" {
|
||||
#define SM_CMD_FILE_CREATE 0x203
|
||||
#define SM_CMD_FILE_DELETE 0x204
|
||||
#define SM_CMD_PIN 0x300
|
||||
#define SM_CMD_PIN_VERIFY 0x301
|
||||
#define SM_CMD_PIN_VERIFY 0x301
|
||||
#define SM_CMD_PIN_RESET 0x302
|
||||
#define SM_CMD_PIN_SET_PIN 0x303
|
||||
#define SM_CMD_PIN_SET_PIN 0x303
|
||||
#define SM_CMD_PSO 0x400
|
||||
#define SM_CMD_PSO_DST 0x401
|
||||
#define SM_CMD_APDU 0x500
|
||||
@ -93,7 +93,7 @@ extern "C" {
|
||||
/* Global Platform (SCP01) data types */
|
||||
/*
|
||||
* @struct sm_type_params_gp
|
||||
* Global Platform SM channel parameters
|
||||
* Global Platform SM channel parameters
|
||||
*/
|
||||
struct sm_type_params_gp {
|
||||
unsigned level;
|
||||
@ -105,9 +105,9 @@ struct sm_type_params_gp {
|
||||
|
||||
/*
|
||||
* @struct sm_gp_keyset
|
||||
* Global Platform keyset:
|
||||
* - version, index;
|
||||
* - keyset presented in three parts: 'ENC', 'MAC' and 'KEK';
|
||||
* Global Platform keyset:
|
||||
* - version, index;
|
||||
* - keyset presented in three parts: 'ENC', 'MAC' and 'KEK';
|
||||
* - keyset presented in continuous manner - raw or 'to be diversified'.
|
||||
*/
|
||||
struct sm_gp_keyset {
|
||||
@ -123,9 +123,16 @@ struct sm_gp_keyset {
|
||||
|
||||
/*
|
||||
* @struct sm_gp_session
|
||||
* Global Platform SM session data
|
||||
* Global Platform SM session data
|
||||
*/
|
||||
struct sm_gp_session {
|
||||
struct sm_gp_keyset gp_keyset;
|
||||
|
||||
struct sm_type_params_gp params;
|
||||
|
||||
unsigned char host_challenge[SM_SMALL_CHALLENGE_LEN];
|
||||
unsigned char card_challenge[SM_SMALL_CHALLENGE_LEN];
|
||||
|
||||
unsigned char *session_enc, *session_mac, *session_kek;
|
||||
unsigned char mac_icv[8];
|
||||
};
|
||||
@ -142,9 +149,9 @@ struct sm_type_params_cwa {
|
||||
|
||||
/*
|
||||
* @struct sm_cwa_keyset
|
||||
* CWA keyset:
|
||||
* - SDO reference;
|
||||
* - 'ENC' and 'MAC' 3DES keys.
|
||||
* CWA keyset:
|
||||
* - SDO reference;
|
||||
* - 'ENC' and 'MAC' 3DES keys.
|
||||
*/
|
||||
struct sm_cwa_keyset {
|
||||
unsigned sdo_reference;
|
||||
@ -154,9 +161,9 @@ struct sm_cwa_keyset {
|
||||
|
||||
/*
|
||||
* @struct sm_cwa_token_data
|
||||
* CWA token data:
|
||||
* - serial;
|
||||
* - 'small' random;
|
||||
* CWA token data:
|
||||
* - serial;
|
||||
* - 'small' random;
|
||||
* - 'big' random.
|
||||
*/
|
||||
struct sm_cwa_token_data {
|
||||
@ -167,13 +174,17 @@ struct sm_cwa_token_data {
|
||||
|
||||
/*
|
||||
* @struct sm_cwa_session
|
||||
* CWA working SM session data:
|
||||
* - ICC and IFD token data;
|
||||
* - ENC and MAC session keys;
|
||||
* - SSC (SM Sequence Counter);
|
||||
* - 'mutual authentication' data.
|
||||
* CWA working SM session data:
|
||||
* - ICC and IFD token data;
|
||||
* - ENC and MAC session keys;
|
||||
* - SSC (SM Sequence Counter);
|
||||
* - 'mutual authentication' data.
|
||||
*/
|
||||
struct sm_cwa_session {
|
||||
struct sm_cwa_keyset cwa_keyset;
|
||||
|
||||
struct sm_type_params_cwa params;
|
||||
|
||||
struct sm_cwa_token_data icc;
|
||||
struct sm_cwa_token_data ifd;
|
||||
|
||||
@ -182,37 +193,20 @@ struct sm_cwa_session {
|
||||
|
||||
unsigned char ssc[8];
|
||||
|
||||
unsigned char host_challenge[SM_SMALL_CHALLENGE_LEN];
|
||||
unsigned char card_challenge[SM_SMALL_CHALLENGE_LEN];
|
||||
|
||||
unsigned char mdata[0x48];
|
||||
size_t mdata_len;
|
||||
};
|
||||
|
||||
/*
|
||||
* @struct sc_secure channel
|
||||
* data type to open and maintain the Secure Messaging session.
|
||||
*/
|
||||
struct sm_secure_channel {
|
||||
union {
|
||||
struct sm_gp_keyset gp;
|
||||
struct sm_cwa_keyset cwa;
|
||||
} keyset;
|
||||
|
||||
union {
|
||||
struct sm_gp_session gp;
|
||||
struct sm_cwa_session cwa;
|
||||
} session;
|
||||
|
||||
unsigned char host_challenge[SM_SMALL_CHALLENGE_LEN];
|
||||
unsigned char card_challenge[SM_SMALL_CHALLENGE_LEN];
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* @struct sc_info is the
|
||||
* placehold for the secure messaging working data:
|
||||
* - SM type;
|
||||
* - SM session state;
|
||||
* - command to execute by external SM module;
|
||||
* - data related to the current card context.
|
||||
* placehold for the secure messaging working data:
|
||||
* - SM type;
|
||||
* - SM session state;
|
||||
* - command to execute by external SM module;
|
||||
* - data related to the current card context.
|
||||
*/
|
||||
struct sm_info {
|
||||
char config_section[64];
|
||||
@ -223,9 +217,9 @@ struct sm_info {
|
||||
|
||||
unsigned sm_type;
|
||||
union {
|
||||
struct sm_type_params_gp gp;
|
||||
struct sm_type_params_cwa cwa;
|
||||
} sm_params;
|
||||
struct sm_gp_session gp;
|
||||
struct sm_cwa_session cwa;
|
||||
} session;
|
||||
|
||||
struct sc_serial_number serialnr;
|
||||
|
||||
@ -237,13 +231,11 @@ struct sm_info {
|
||||
|
||||
unsigned char *rdata;
|
||||
size_t rdata_len;
|
||||
|
||||
struct sm_secure_channel schannel;
|
||||
};
|
||||
|
||||
/*
|
||||
* @struct sm_card_response
|
||||
* data type to return card response.
|
||||
* data type to return card response.
|
||||
*/
|
||||
typedef struct sm_card_response {
|
||||
int num;
|
||||
@ -265,11 +257,11 @@ struct sc_card;
|
||||
|
||||
/*
|
||||
* @struct sm_card_operations
|
||||
* card driver handlers related to secure messaging (in 'APDU TRANSMIT' mode)
|
||||
* - 'open' - initialize SM session;
|
||||
* - 'encode apdu' - SM encoding of the raw APDU;
|
||||
* - 'decrypt response' - decode card answer;
|
||||
* - 'close' - close SM session.
|
||||
* card driver handlers related to secure messaging (in 'APDU TRANSMIT' mode)
|
||||
* - 'open' - initialize SM session;
|
||||
* - 'encode apdu' - SM encoding of the raw APDU;
|
||||
* - 'decrypt response' - decode card answer;
|
||||
* - 'close' - close SM session.
|
||||
*/
|
||||
struct sm_card_operations {
|
||||
int (*open)(struct sc_card *card);
|
||||
@ -285,12 +277,12 @@ struct sm_card_operations {
|
||||
|
||||
/*
|
||||
* @struct sm_module_operations
|
||||
* API to use external SM modules:
|
||||
* - 'initiliaze' - get APDU(s) to initialize SM session;
|
||||
* - 'get apdus' - get secured APDUs to execute particular command;
|
||||
* - 'finalize' - get APDU(s) to finalize SM session;
|
||||
* - 'module init' - initialize external module (allocate data, read configuration, ...);
|
||||
* - 'module cleanup' - free resources allocated by external module.
|
||||
* API to use external SM modules:
|
||||
* - 'initiliaze' - get APDU(s) to initialize SM session;
|
||||
* - 'get apdus' - get secured APDUs to execute particular command;
|
||||
* - 'finalize' - get APDU(s) to finalize SM session;
|
||||
* - 'module init' - initialize external module (allocate data, read configuration, ...);
|
||||
* - 'module cleanup' - free resources allocated by external module.
|
||||
*/
|
||||
struct sm_module_operations {
|
||||
int (*initialize)(struct sc_context *ctx, struct sm_info *info,
|
||||
@ -314,8 +306,8 @@ typedef struct sm_module {
|
||||
} sm_module_t;
|
||||
|
||||
/* @struct sm_context
|
||||
* SM context -- top level of the SM data type
|
||||
* - SM mode ('ACL' or 'APDU TRANSMIT'), flags;
|
||||
* SM context -- top level of the SM data type
|
||||
* - SM mode ('ACL' or 'APDU TRANSMIT'), flags;
|
||||
* - working SM data;
|
||||
* - card operations related to SM in 'APDU TRANSMIT' mode;
|
||||
* - external SM module;
|
||||
|
@ -48,25 +48,27 @@ static int
|
||||
sm_oberthur_diversify_keyset(struct sc_context *ctx, struct sm_info *sm_info,
|
||||
unsigned char *idata, size_t idata_len)
|
||||
{
|
||||
struct sm_secure_channel *schannel = &sm_info->schannel;
|
||||
struct sm_gp_keyset *keyset = &schannel->keyset.gp;
|
||||
struct sm_gp_session *gp_session = &sm_info->session.gp;
|
||||
struct sm_gp_keyset *gp_keyset = &sm_info->session.gp.gp_keyset;
|
||||
unsigned char master_key[16] = {
|
||||
0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F,
|
||||
};
|
||||
unsigned char *keys[3] = {
|
||||
keyset->enc,keyset->mac,keyset->kek
|
||||
gp_keyset->enc,
|
||||
gp_keyset->mac,
|
||||
gp_keyset->kek
|
||||
};
|
||||
unsigned char key_buff[16];
|
||||
unsigned char *tmp;
|
||||
unsigned char *tmp;
|
||||
int rv = 0, ii, tmp_len;
|
||||
|
||||
if (keyset->kmc_len == 48) {
|
||||
if (gp_keyset->kmc_len == 48) {
|
||||
for (ii=0; ii<3; ii++)
|
||||
memcpy(keys[ii], keyset->kmc + 16*ii, 16);
|
||||
memcpy(keys[ii], gp_keyset->kmc + 16*ii, 16);
|
||||
}
|
||||
else if (keyset->kmc_len == 16 || keyset->kmc_len == 0) {
|
||||
if (keyset->kmc_len == 16)
|
||||
memcpy(master_key, keyset->kmc, 16);
|
||||
else if (gp_keyset->kmc_len == 16 || gp_keyset->kmc_len == 0) {
|
||||
if (gp_keyset->kmc_len == 16)
|
||||
memcpy(master_key, gp_keyset->kmc, 16);
|
||||
sc_log(ctx, "KMC: %s", sc_dump_hex(master_key, sizeof(master_key)));
|
||||
for (ii=0; ii<3; ii++) {
|
||||
key_buff[0] = key_buff[8] = 0;
|
||||
@ -83,7 +85,7 @@ sm_oberthur_diversify_keyset(struct sc_context *ctx, struct sm_info *sm_info,
|
||||
rv = sm_encrypt_des_ecb3(master_key, key_buff, sizeof(key_buff), &tmp, &tmp_len);
|
||||
LOG_TEST_RET(ctx, rv, "GP init session: cannot derivate key");
|
||||
|
||||
memcpy(keys[ii], tmp, sizeof(keyset->enc));
|
||||
memcpy(keys[ii], tmp, sizeof(gp_keyset->enc));
|
||||
free(tmp);
|
||||
}
|
||||
}
|
||||
@ -95,20 +97,20 @@ sm_oberthur_diversify_keyset(struct sc_context *ctx, struct sm_info *sm_info,
|
||||
char dump_buf[2048];
|
||||
|
||||
sc_hex_dump(ctx, SC_LOG_DEBUG_NORMAL,
|
||||
schannel->card_challenge, sizeof(schannel->card_challenge), dump_buf, sizeof(dump_buf));
|
||||
gp_session->card_challenge, sizeof(gp_session->card_challenge), dump_buf, sizeof(dump_buf));
|
||||
sc_log(ctx, "Card challenge: %s", dump_buf);
|
||||
|
||||
sc_hex_dump(ctx, SC_LOG_DEBUG_NORMAL,
|
||||
schannel->host_challenge, sizeof(schannel->host_challenge), dump_buf, sizeof(dump_buf));
|
||||
gp_session->host_challenge, sizeof(gp_session->host_challenge), dump_buf, sizeof(dump_buf));
|
||||
sc_log(ctx, "Host challenge: %s", dump_buf);
|
||||
|
||||
sc_hex_dump(ctx, SC_LOG_DEBUG_NORMAL, keyset->enc, sizeof(keyset->enc), dump_buf, sizeof(dump_buf));
|
||||
sc_hex_dump(ctx, SC_LOG_DEBUG_NORMAL, gp_keyset->enc, sizeof(gp_keyset->enc), dump_buf, sizeof(dump_buf));
|
||||
sc_log(ctx, "ENC: %s", dump_buf);
|
||||
|
||||
sc_hex_dump(ctx, SC_LOG_DEBUG_NORMAL, keyset->mac, sizeof(keyset->mac), dump_buf, sizeof(dump_buf));
|
||||
sc_hex_dump(ctx, SC_LOG_DEBUG_NORMAL, gp_keyset->mac, sizeof(gp_keyset->mac), dump_buf, sizeof(dump_buf));
|
||||
sc_log(ctx, "MAC: %s", dump_buf);
|
||||
|
||||
sc_hex_dump(ctx, SC_LOG_DEBUG_NORMAL, keyset->kek, sizeof(keyset->kek), dump_buf, sizeof(dump_buf));
|
||||
sc_hex_dump(ctx, SC_LOG_DEBUG_NORMAL, gp_keyset->kek, sizeof(gp_keyset->kek), dump_buf, sizeof(dump_buf));
|
||||
sc_log(ctx, "KEK: %s", dump_buf);
|
||||
}
|
||||
|
||||
@ -328,7 +330,7 @@ sm_authentic_get_apdus(struct sc_context *ctx, struct sm_info *sm_info,
|
||||
rv = sm_authentic_get_apdu_release(ctx, sm_info, init_data, init_len, out, out_num);
|
||||
LOG_TEST_RET(ctx, rv, "SM get APDUs: add 'release' failed");
|
||||
|
||||
sm_gp_close_session(ctx, &sm_info->schannel);
|
||||
sm_gp_close_session(ctx, &sm_info->session.gp);
|
||||
}
|
||||
#endif
|
||||
LOG_FUNC_RETURN(ctx, rv);
|
||||
|
@ -597,8 +597,8 @@ int
|
||||
sm_iasecc_get_apdus(struct sc_context *ctx, struct sm_info *sm_info,
|
||||
unsigned char *init_data, size_t init_len, struct sc_remote_data *rdata, int release_sm)
|
||||
{
|
||||
struct sm_cwa_session *session_data = &sm_info->schannel.session.cwa;
|
||||
struct sm_cwa_keyset *keyset = &sm_info->schannel.keyset.cwa;
|
||||
struct sm_cwa_session *cwa_session = &sm_info->session.cwa;
|
||||
struct sm_cwa_keyset *cwa_keyset = &sm_info->session.cwa.cwa_keyset;
|
||||
int rv;
|
||||
|
||||
LOG_FUNC_CALLED(ctx);
|
||||
@ -609,15 +609,15 @@ sm_iasecc_get_apdus(struct sc_context *ctx, struct sm_info *sm_info,
|
||||
sc_log(ctx, "SM IAS/ECC get APDUs: rdata:%p", rdata);
|
||||
sc_log(ctx, "SM IAS/ECC get APDUs: serial %s", sc_dump_hex(sm_info->serialnr.value, sm_info->serialnr.len));
|
||||
|
||||
rv = sm_cwa_decode_authentication_data(ctx, keyset, session_data, init_data);
|
||||
rv = sm_cwa_decode_authentication_data(ctx, cwa_keyset, cwa_session, init_data);
|
||||
LOG_TEST_RET(ctx, rv, "SM IAS/ECC get APDUs: decode authentication data error");
|
||||
|
||||
rv = sm_cwa_init_session_keys(ctx, session_data, sm_info->sm_params.cwa.crt_at.algo);
|
||||
rv = sm_cwa_init_session_keys(ctx, cwa_session, cwa_session->params.crt_at.algo);
|
||||
LOG_TEST_RET(ctx, rv, "SM IAS/ECC get APDUs: cannot get session keys");
|
||||
|
||||
sc_log(ctx, "SKENC %s", sc_dump_hex(session_data->session_enc, sizeof(session_data->session_enc)));
|
||||
sc_log(ctx, "SKMAC %s", sc_dump_hex(session_data->session_mac, sizeof(session_data->session_mac)));
|
||||
sc_log(ctx, "SSC %s", sc_dump_hex(session_data->ssc, sizeof(session_data->ssc)));
|
||||
sc_log(ctx, "SKENC %s", sc_dump_hex(cwa_session->session_enc, sizeof(cwa_session->session_enc)));
|
||||
sc_log(ctx, "SKMAC %s", sc_dump_hex(cwa_session->session_mac, sizeof(cwa_session->session_mac)));
|
||||
sc_log(ctx, "SSC %s", sc_dump_hex(cwa_session->ssc, sizeof(cwa_session->ssc)));
|
||||
|
||||
switch (sm_info->cmd) {
|
||||
case SM_CMD_FILE_READ:
|
||||
@ -682,7 +682,7 @@ int
|
||||
sm_iasecc_decode_card_data(struct sc_context *ctx, struct sm_info *sm_info, struct sc_remote_data *rdata,
|
||||
unsigned char *out, size_t out_len)
|
||||
{
|
||||
struct sm_cwa_session *session_data = &sm_info->schannel.session.cwa;
|
||||
struct sm_cwa_session *session_data = &sm_info->session.cwa;
|
||||
struct sc_asn1_entry asn1_iasecc_sm_data_object[4];
|
||||
struct sc_remote_apdu *rapdu = NULL;
|
||||
int rv, offs = 0;
|
||||
|
@ -248,10 +248,10 @@ sm_cwa_incr_ssc(struct sm_cwa_session *session_data)
|
||||
int
|
||||
sm_cwa_initialize(struct sc_context *ctx, struct sm_info *sm_info, struct sc_remote_data *rdata)
|
||||
{
|
||||
struct sm_cwa_session *session_data = &sm_info->schannel.session.cwa;
|
||||
struct sm_cwa_keyset *keyset = &sm_info->schannel.keyset.cwa;
|
||||
struct sm_cwa_session *cwa_session = &sm_info->session.cwa;
|
||||
struct sm_cwa_keyset *cwa_keyset = &sm_info->session.cwa.cwa_keyset;
|
||||
struct sc_serial_number sn = sm_info->serialnr;
|
||||
size_t icc_sn_len = sizeof(session_data->icc.sn);
|
||||
size_t icc_sn_len = sizeof(cwa_session->icc.sn);
|
||||
struct sc_remote_apdu *new_rapdu = NULL;
|
||||
struct sc_apdu *apdu = NULL;
|
||||
unsigned char buf[0x100], *encrypted;
|
||||
@ -261,9 +261,9 @@ sm_cwa_initialize(struct sc_context *ctx, struct sm_info *sm_info, struct sc_rem
|
||||
|
||||
LOG_FUNC_CALLED(ctx);
|
||||
sc_log(ctx, "SM IAS/ECC initialize: serial %s", sc_dump_hex(sm_info->serialnr.value, sm_info->serialnr.len));
|
||||
sc_log(ctx, "SM IAS/ECC initialize: card challenge %s", sc_dump_hex(sm_info->schannel.card_challenge, 8));
|
||||
sc_log(ctx, "SM IAS/ECC initialize: card challenge %s", sc_dump_hex(cwa_session->card_challenge, 8));
|
||||
sc_log(ctx, "SM IAS/ECC initialize: current_df_path %s", sc_print_path(&sm_info->current_path_df));
|
||||
sc_log(ctx, "SM IAS/ECC initialize: CRT_AT reference 0x%X", sm_info->sm_params.cwa.crt_at.refs[0]);
|
||||
sc_log(ctx, "SM IAS/ECC initialize: CRT_AT reference 0x%X", cwa_session->params.crt_at.refs[0]);
|
||||
|
||||
if (!rdata || !rdata->alloc)
|
||||
LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_ARGUMENTS);
|
||||
@ -272,27 +272,27 @@ sm_cwa_initialize(struct sc_context *ctx, struct sm_info *sm_info, struct sc_rem
|
||||
LOG_TEST_RET(ctx, rv, "SM GP decode card answer: cannot allocate remote APDU");
|
||||
apdu = &new_rapdu->apdu;
|
||||
|
||||
memcpy(&session_data->icc.rnd[0], sm_info->schannel.card_challenge, 8);
|
||||
memcpy(&cwa_session->icc.rnd[0], cwa_session->card_challenge, 8);
|
||||
|
||||
if (sn.len > icc_sn_len)
|
||||
memcpy(&session_data->icc.sn[0], &sn.value[sn.len - icc_sn_len], icc_sn_len);
|
||||
memcpy(&cwa_session->icc.sn[0], &sn.value[sn.len - icc_sn_len], icc_sn_len);
|
||||
else
|
||||
memcpy(&session_data->icc.sn[icc_sn_len - sn.len], &sn.value[0], sn.len);
|
||||
memcpy(&cwa_session->icc.sn[icc_sn_len - sn.len], &sn.value[0], sn.len);
|
||||
|
||||
if (sm_info->cmd == SM_CMD_EXTERNAL_AUTH) {
|
||||
offs = sm_cwa_encode_external_auth_data(ctx, session_data, buf, sizeof(buf));
|
||||
offs = sm_cwa_encode_external_auth_data(ctx, cwa_session, buf, sizeof(buf));
|
||||
if (offs != 0x10)
|
||||
LOG_FUNC_RETURN(ctx, offs);
|
||||
}
|
||||
else {
|
||||
offs = sm_cwa_encode_mutual_auth_data(ctx, session_data, buf, sizeof(buf));
|
||||
offs = sm_cwa_encode_mutual_auth_data(ctx, cwa_session, buf, sizeof(buf));
|
||||
if (offs != 0x40)
|
||||
LOG_FUNC_RETURN(ctx, offs);
|
||||
}
|
||||
|
||||
sc_log(ctx, "S(%i) %s", offs, sc_dump_hex(buf, offs));
|
||||
|
||||
rv = sm_encrypt_des_cbc3(ctx, keyset->enc, buf, offs, &encrypted, &encrypted_len, 1);
|
||||
rv = sm_encrypt_des_cbc3(ctx, cwa_keyset->enc, buf, offs, &encrypted, &encrypted_len, 1);
|
||||
LOG_TEST_RET(ctx, rv, "_encrypt_des_cbc3() failed");
|
||||
|
||||
sc_log(ctx, "ENCed(%i) %s", encrypted_len, sc_dump_hex(encrypted, encrypted_len));
|
||||
@ -300,7 +300,7 @@ sm_cwa_initialize(struct sc_context *ctx, struct sm_info *sm_info, struct sc_rem
|
||||
memcpy(buf, encrypted, encrypted_len);
|
||||
offs = encrypted_len;
|
||||
|
||||
rv = sm_cwa_get_mac(ctx, keyset->mac, &icv, buf, offs, &cblock, 1);
|
||||
rv = sm_cwa_get_mac(ctx, cwa_keyset->mac, &icv, buf, offs, &cblock, 1);
|
||||
LOG_TEST_RET(ctx, rv, "sm_ecc_get_mac() failed");
|
||||
sc_log(ctx, "MACed(%i) %s", sizeof(cblock), sc_dump_hex(cblock, sizeof(cblock)));
|
||||
|
||||
@ -323,7 +323,7 @@ sm_cwa_initialize(struct sc_context *ctx, struct sm_info *sm_info, struct sc_rem
|
||||
int
|
||||
sm_cwa_securize_apdu(struct sc_context *ctx, struct sm_info *sm_info, struct sc_remote_apdu *rapdu)
|
||||
{
|
||||
struct sm_cwa_session *session_data = &sm_info->schannel.session.cwa;
|
||||
struct sm_cwa_session *session_data = &sm_info->session.cwa;
|
||||
struct sc_apdu *apdu = &rapdu->apdu;
|
||||
unsigned char sbuf[0x400];
|
||||
DES_cblock cblock, icv;
|
||||
|
@ -109,7 +109,7 @@ sm_gp_decode_card_answer(struct sc_context *ctx, struct sc_remote_data *rdata, u
|
||||
sc_format_asn1_entry(asn1_authentic_card_response + 2, &card_data, &card_data_len, 0);
|
||||
sc_format_asn1_entry(asn1_card_response + 0, asn1_authentic_card_response, NULL, 0);
|
||||
|
||||
rv = sc_asn1_decode(ctx, asn1_card_response, hex + hex_len - len_left, len_left, NULL, &len_left);
|
||||
rv = sc_asn1_decode(ctx, asn1_card_response, hex + hex_len - len_left, len_left, NULL, &len_left);
|
||||
if (rv) {
|
||||
sc_log(ctx, "SM GP decode card answer: ASN.1 parse error: %s", sc_strerror(rv));
|
||||
return rv;
|
||||
@ -141,6 +141,8 @@ int
|
||||
sm_gp_initialize(struct sc_context *ctx, struct sm_info *sm_info, struct sc_remote_data *rdata)
|
||||
{
|
||||
struct sc_serial_number sn = sm_info->serialnr;
|
||||
struct sm_gp_session *gp_session = &sm_info->session.gp;
|
||||
struct sm_gp_keyset *gp_keyset = &sm_info->session.gp.gp_keyset;
|
||||
struct sc_remote_apdu *new_rapdu = NULL;
|
||||
struct sc_apdu *apdu = NULL;
|
||||
int rv;
|
||||
@ -148,7 +150,7 @@ sm_gp_initialize(struct sc_context *ctx, struct sm_info *sm_info, struct sc_rem
|
||||
LOG_FUNC_CALLED(ctx);
|
||||
sc_log(ctx, "SM GP initialize: serial:%s", sc_dump_hex(sn.value, sn.len));
|
||||
sc_log(ctx, "SM GP initialize: current_df_path %s", sc_print_path(&sm_info->current_path_df));
|
||||
sc_log(ctx, "SM GP initialize: KMC length %i", sm_info->schannel.keyset.gp.kmc_len);
|
||||
sc_log(ctx, "SM GP initialize: KMC length %i", gp_keyset->kmc_len);
|
||||
|
||||
if (!rdata || !rdata->alloc)
|
||||
LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_ARGUMENTS);
|
||||
@ -157,7 +159,7 @@ sm_gp_initialize(struct sc_context *ctx, struct sm_info *sm_info, struct sc_rem
|
||||
LOG_TEST_RET(ctx, rv, "SM GP decode card answer: cannot allocate remote APDU");
|
||||
apdu = &new_rapdu->apdu;
|
||||
|
||||
rv = RAND_bytes(sm_info->schannel.host_challenge, SM_SMALL_CHALLENGE_LEN);
|
||||
rv = RAND_bytes(gp_session->host_challenge, SM_SMALL_CHALLENGE_LEN);
|
||||
if (!rv)
|
||||
LOG_FUNC_RETURN(ctx, SC_ERROR_SM_RAND_FAILED);
|
||||
|
||||
@ -169,24 +171,24 @@ sm_gp_initialize(struct sc_context *ctx, struct sm_info *sm_info, struct sc_rem
|
||||
apdu->lc = SM_SMALL_CHALLENGE_LEN;
|
||||
apdu->le = 0x1C;
|
||||
apdu->datalen = SM_SMALL_CHALLENGE_LEN;
|
||||
memcpy(&new_rapdu->sbuf[0], sm_info->schannel.host_challenge, SM_SMALL_CHALLENGE_LEN);
|
||||
memcpy(&new_rapdu->sbuf[0], gp_session->host_challenge, SM_SMALL_CHALLENGE_LEN);
|
||||
|
||||
LOG_FUNC_RETURN(ctx, SC_SUCCESS);
|
||||
}
|
||||
|
||||
|
||||
static unsigned char *
|
||||
sc_gp_get_session_key(struct sc_context *ctx, struct sm_secure_channel *sc,
|
||||
sc_gp_get_session_key(struct sc_context *ctx, struct sm_gp_session *gp_session,
|
||||
unsigned char *key)
|
||||
{
|
||||
int out_len;
|
||||
unsigned char *out;
|
||||
unsigned char deriv[16];
|
||||
|
||||
memcpy(deriv, sc->card_challenge + 4, 4);
|
||||
memcpy(deriv + 4, sc->host_challenge, 4);
|
||||
memcpy(deriv + 8, sc->card_challenge, 4);
|
||||
memcpy(deriv + 12, sc->host_challenge + 4, 4);
|
||||
memcpy(deriv, gp_session->card_challenge + 4, 4);
|
||||
memcpy(deriv + 4, gp_session->host_challenge, 4);
|
||||
memcpy(deriv + 8, gp_session->card_challenge, 4);
|
||||
memcpy(deriv + 12, gp_session->host_challenge + 4, 4);
|
||||
|
||||
if (sm_encrypt_des_ecb3(key, deriv, 16, &out, &out_len)) {
|
||||
if (ctx)
|
||||
@ -266,24 +268,27 @@ sm_gp_get_mac(unsigned char *key, DES_cblock *icv,
|
||||
|
||||
|
||||
static int
|
||||
sm_gp_parse_init_data(struct sc_context *ctx, struct sm_secure_channel *sc,
|
||||
sm_gp_parse_init_data(struct sc_context *ctx, struct sm_gp_session *gp_session,
|
||||
unsigned char *init_data, size_t init_len)
|
||||
{
|
||||
struct sm_gp_keyset *gp_keyset = &gp_session->gp_keyset;
|
||||
|
||||
if(init_len != 0x1C)
|
||||
return SC_ERROR_INVALID_DATA;
|
||||
|
||||
sc->keyset.gp.version = *(init_data + 10);
|
||||
sc->keyset.gp.index = *(init_data + 11);
|
||||
memcpy(sc->card_challenge, init_data + 12, SM_SMALL_CHALLENGE_LEN);
|
||||
gp_keyset->version = *(init_data + 10);
|
||||
gp_keyset->index = *(init_data + 11);
|
||||
memcpy(gp_session->card_challenge, init_data + 12, SM_SMALL_CHALLENGE_LEN);
|
||||
|
||||
return SC_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
sm_gp_init_session(struct sc_context *ctx, struct sm_secure_channel *sc,
|
||||
sm_gp_init_session(struct sc_context *ctx, struct sm_gp_session *gp_session,
|
||||
unsigned char *adata, size_t adata_len)
|
||||
{
|
||||
struct sm_gp_keyset *gp_keyset = &gp_session->gp_keyset;
|
||||
unsigned char cksum[8];
|
||||
int rv;
|
||||
|
||||
@ -293,19 +298,19 @@ sm_gp_init_session(struct sc_context *ctx, struct sm_secure_channel *sc,
|
||||
|
||||
sc_log(ctx, "SM GP init session: auth.data %s", sc_dump_hex(adata, 8));
|
||||
|
||||
sc->session.gp.session_enc = sc_gp_get_session_key(ctx, sc, sc->keyset.gp.enc);
|
||||
sc->session.gp.session_mac = sc_gp_get_session_key(ctx, sc, sc->keyset.gp.mac);
|
||||
sc->session.gp.session_kek = sc_gp_get_session_key(ctx, sc, sc->keyset.gp.kek);
|
||||
if (!sc->session.gp.session_enc || !sc->session.gp.session_mac || !sc->session.gp.session_kek)
|
||||
gp_session->session_enc = sc_gp_get_session_key(ctx, gp_session, gp_keyset->enc);
|
||||
gp_session->session_mac = sc_gp_get_session_key(ctx, gp_session, gp_keyset->mac);
|
||||
gp_session->session_kek = sc_gp_get_session_key(ctx, gp_session, gp_keyset->kek);
|
||||
if (!gp_session->session_enc || !gp_session->session_mac || !gp_session->session_kek)
|
||||
LOG_TEST_RET(ctx, SC_ERROR_SM_NO_SESSION_KEYS, "SM GP init session: get session keys error");
|
||||
memcpy(sc->session.gp.session_kek, sc->keyset.gp.kek, 16);
|
||||
memcpy(gp_session->session_kek, gp_keyset->kek, 16);
|
||||
|
||||
sc_log(ctx, "SM GP init session: session ENC: %s", sc_dump_hex(sc->session.gp.session_enc, 16));
|
||||
sc_log(ctx, "SM GP init session: session MAC: %s", sc_dump_hex(sc->session.gp.session_mac, 16));
|
||||
sc_log(ctx, "SM GP init session: session KEK: %s", sc_dump_hex(sc->session.gp.session_kek, 16));
|
||||
sc_log(ctx, "SM GP init session: session ENC: %s", sc_dump_hex(gp_session->session_enc, 16));
|
||||
sc_log(ctx, "SM GP init session: session MAC: %s", sc_dump_hex(gp_session->session_mac, 16));
|
||||
sc_log(ctx, "SM GP init session: session KEK: %s", sc_dump_hex(gp_session->session_kek, 16));
|
||||
|
||||
memset(cksum, 0, sizeof(cksum));
|
||||
rv = sm_gp_get_cryptogram(sc->session.gp.session_enc, sc->host_challenge, sc->card_challenge, cksum, sizeof(cksum));
|
||||
rv = sm_gp_get_cryptogram(gp_session->session_enc, gp_session->host_challenge, gp_session->card_challenge, cksum, sizeof(cksum));
|
||||
LOG_TEST_RET(ctx, rv, "SM GP init session: cannot get cryptogram");
|
||||
|
||||
sc_log(ctx, "SM GP init session: cryptogram: %s", sc_dump_hex(cksum, 8));
|
||||
@ -318,11 +323,11 @@ sm_gp_init_session(struct sc_context *ctx, struct sm_secure_channel *sc,
|
||||
|
||||
|
||||
void
|
||||
sm_gp_close_session(struct sc_context *ctx, struct sm_secure_channel *sc)
|
||||
sm_gp_close_session(struct sc_context *ctx, struct sm_gp_session *gp_session)
|
||||
{
|
||||
free(sc->session.gp.session_enc);
|
||||
free(sc->session.gp.session_mac);
|
||||
free(sc->session.gp.session_kek);
|
||||
free(gp_session->session_enc);
|
||||
free(gp_session->session_mac);
|
||||
free(gp_session->session_kek);
|
||||
}
|
||||
|
||||
|
||||
@ -336,7 +341,7 @@ sm_gp_external_authentication(struct sc_context *ctx, struct sm_info *sm_info,
|
||||
struct sc_remote_apdu *new_rapdu = NULL;
|
||||
struct sc_apdu *apdu = NULL;
|
||||
unsigned char host_cryptogram[8], raw_apdu[SC_MAX_APDU_BUFFER_SIZE];
|
||||
struct sm_secure_channel *schannel = &sm_info->schannel;
|
||||
struct sm_gp_session *gp_session = &sm_info->session.gp;
|
||||
DES_cblock mac;
|
||||
int rv, idx = 0, offs = 0;
|
||||
|
||||
@ -347,7 +352,7 @@ sm_gp_external_authentication(struct sc_context *ctx, struct sm_info *sm_info,
|
||||
if (init_len != 0x1C)
|
||||
LOG_TEST_RET(ctx, SC_ERROR_UNKNOWN_DATA_RECEIVED, "SM GP authentication: invalid auth data length");
|
||||
|
||||
rv = sm_gp_parse_init_data(ctx, schannel, init_data, init_len);
|
||||
rv = sm_gp_parse_init_data(ctx, gp_session, init_data, init_len);
|
||||
LOG_TEST_RET(ctx, rv, "SM GP authentication: 'INIT DATA' parse error");
|
||||
|
||||
if (diversify_keyset) {
|
||||
@ -355,10 +360,11 @@ sm_gp_external_authentication(struct sc_context *ctx, struct sm_info *sm_info,
|
||||
LOG_TEST_RET(ctx, rv, "SM GP authentication: keyset diversification error");
|
||||
}
|
||||
|
||||
rv = sm_gp_init_session(ctx, schannel, init_data + 20, 8);
|
||||
rv = sm_gp_init_session(ctx, gp_session, init_data + 20, 8);
|
||||
LOG_TEST_RET(ctx, rv, "SM GP authentication: init session error");
|
||||
|
||||
rv = sm_gp_get_cryptogram(schannel->session.gp.session_enc, schannel->card_challenge, schannel->host_challenge,
|
||||
rv = sm_gp_get_cryptogram(gp_session->session_enc,
|
||||
gp_session->card_challenge, gp_session->host_challenge,
|
||||
host_cryptogram, sizeof(host_cryptogram));
|
||||
LOG_TEST_RET(ctx, rv, "SM GP authentication: get host cryptogram error");
|
||||
|
||||
@ -372,19 +378,19 @@ sm_gp_external_authentication(struct sc_context *ctx, struct sm_info *sm_info,
|
||||
apdu->cse = SC_APDU_CASE_3_SHORT;
|
||||
apdu->cla = raw_apdu[offs++] = 0x84;
|
||||
apdu->ins = raw_apdu[offs++] = 0x82;
|
||||
apdu->p1 = raw_apdu[offs++] = sm_info->sm_params.gp.level;
|
||||
apdu->p1 = raw_apdu[offs++] = gp_session->params.level;
|
||||
apdu->p2 = raw_apdu[offs++] = 0;
|
||||
apdu->lc = raw_apdu[offs++] = 0x10;
|
||||
apdu->datalen = 0x10;
|
||||
|
||||
memcpy(raw_apdu + offs, host_cryptogram, 8);
|
||||
offs += 8;
|
||||
rv = sm_gp_get_mac(schannel->session.gp.session_mac, &schannel->session.gp.mac_icv, raw_apdu, offs, &mac);
|
||||
rv = sm_gp_get_mac(gp_session->session_mac, &gp_session->mac_icv, raw_apdu, offs, &mac);
|
||||
LOG_TEST_RET(ctx, rv, "SM GP authentication: get MAC error");
|
||||
|
||||
memcpy(new_rapdu->sbuf, host_cryptogram, 8);
|
||||
memcpy(new_rapdu->sbuf + 8, mac, 8);
|
||||
memcpy(schannel->session.gp.mac_icv, mac, 8);
|
||||
memcpy(gp_session->mac_icv, mac, 8);
|
||||
|
||||
LOG_FUNC_RETURN(ctx, 1);
|
||||
}
|
||||
@ -431,9 +437,9 @@ sm_gp_securize_apdu(struct sc_context *ctx, struct sm_info *sm_info,
|
||||
{
|
||||
unsigned char buff[SC_MAX_APDU_BUFFER_SIZE + 24];
|
||||
unsigned char *apdu_data = NULL;
|
||||
unsigned gp_level = sm_info->sm_params.gp.level;
|
||||
unsigned gp_index = sm_info->sm_params.gp.index;
|
||||
struct sm_gp_session *gp_session = &sm_info->schannel.session.gp;
|
||||
struct sm_gp_session *gp_session = &sm_info->session.gp;
|
||||
unsigned gp_level = sm_info->session.gp.params.level;
|
||||
unsigned gp_index = sm_info->session.gp.params.index;
|
||||
DES_cblock mac;
|
||||
unsigned char *encrypted = NULL;
|
||||
size_t encrypted_len = 0;
|
||||
@ -508,7 +514,7 @@ sm_gp_securize_apdu(struct sc_context *ctx, struct sm_info *sm_info,
|
||||
free(encrypted);
|
||||
}
|
||||
|
||||
memcpy(sm_info->schannel.session.gp.mac_icv, mac, 8);
|
||||
memcpy(sm_info->session.gp.mac_icv, mac, 8);
|
||||
|
||||
LOG_FUNC_RETURN(ctx, rv);
|
||||
}
|
||||
|
@ -62,7 +62,7 @@ int sm_gp_securize_apdu(struct sc_context *ctx, struct sm_info *sm_info,
|
||||
char *init_data, struct sc_apdu *apdu);
|
||||
int sm_gp_decode_card_answer(struct sc_context *ctx, struct sc_remote_data *rdata,
|
||||
unsigned char *out, size_t out_len);
|
||||
void sm_gp_close_session(struct sc_context *ctx, struct sm_secure_channel *sc);
|
||||
void sm_gp_close_session(struct sc_context *ctx, struct sm_gp_session *gp_session);
|
||||
|
||||
|
||||
/* CWA-14890 helper functions */
|
||||
|
@ -58,6 +58,8 @@ static int
|
||||
sm_gp_config_get_keyset(struct sc_context *ctx, struct sm_info *sm_info)
|
||||
{
|
||||
scconf_block *sm_conf_block = NULL, **blocks;
|
||||
struct sm_gp_keyset *gp_keyset = &sm_info->session.gp.gp_keyset;
|
||||
|
||||
const char *kmc = NULL;
|
||||
unsigned char hex[48];
|
||||
size_t hex_len = sizeof(hex);
|
||||
@ -89,8 +91,8 @@ sm_gp_config_get_keyset(struct sc_context *ctx, struct sm_info *sm_info)
|
||||
if (hex_len != 16 && hex_len != 48 )
|
||||
return SC_ERROR_INVALID_DATA;
|
||||
|
||||
memcpy(sm_info->schannel.keyset.gp.kmc, hex, hex_len);
|
||||
sm_info->schannel.keyset.gp.kmc_len = hex_len;
|
||||
memcpy(gp_keyset->kmc, hex, hex_len);
|
||||
gp_keyset->kmc_len = hex_len;
|
||||
|
||||
return SC_SUCCESS;
|
||||
}
|
||||
@ -99,9 +101,10 @@ sm_gp_config_get_keyset(struct sc_context *ctx, struct sm_info *sm_info)
|
||||
static int
|
||||
sm_cwa_config_get_keyset(struct sc_context *ctx, struct sm_info *sm_info)
|
||||
{
|
||||
struct sm_cwa_session *session_data = &sm_info->schannel.session.cwa;
|
||||
struct sm_cwa_session *cwa_session = &sm_info->session.cwa;
|
||||
struct sm_cwa_keyset *cwa_keyset = &sm_info->session.cwa.cwa_keyset;
|
||||
scconf_block *sm_conf_block = NULL, **blocks;
|
||||
struct sc_crt *crt_at = &sm_info->sm_params.cwa.crt_at;
|
||||
struct sc_crt *crt_at = &sm_info->session.cwa.params.crt_at;
|
||||
const char *value = NULL;
|
||||
char name[128];
|
||||
unsigned char hex[48];
|
||||
@ -134,7 +137,7 @@ sm_cwa_config_get_keyset(struct sc_context *ctx, struct sm_info *sm_info)
|
||||
|
||||
sc_log(ctx, "keyset::enc(%i) %s", strlen(value), value);
|
||||
if (strlen(value) == 16) {
|
||||
memcpy(sm_info->schannel.keyset.cwa.enc, value, 16);
|
||||
memcpy(cwa_keyset->enc, value, 16);
|
||||
}
|
||||
else {
|
||||
hex_len = sizeof(hex);
|
||||
@ -148,9 +151,9 @@ sm_cwa_config_get_keyset(struct sc_context *ctx, struct sm_info *sm_info)
|
||||
if (hex_len != 16)
|
||||
return SC_ERROR_INVALID_DATA;
|
||||
|
||||
memcpy(sm_info->schannel.keyset.cwa.enc, hex, hex_len);
|
||||
memcpy(cwa_keyset->enc, hex, hex_len);
|
||||
}
|
||||
sc_log(ctx, "%s %s", name, sc_dump_hex(sm_info->schannel.keyset.cwa.enc, 16));
|
||||
sc_log(ctx, "%s %s", name, sc_dump_hex(cwa_keyset->enc, 16));
|
||||
|
||||
/* Keyset MAC */
|
||||
if (sm_info->current_aid.len && (crt_at->refs[0] & IASECC_OBJECT_REF_LOCAL))
|
||||
@ -166,7 +169,7 @@ sm_cwa_config_get_keyset(struct sc_context *ctx, struct sm_info *sm_info)
|
||||
|
||||
sc_log(ctx, "keyset::mac(%i) %s", strlen(value), value);
|
||||
if (strlen(value) == 16) {
|
||||
memcpy(sm_info->schannel.keyset.cwa.mac, value, 16);
|
||||
memcpy(cwa_keyset->mac, value, 16);
|
||||
}
|
||||
else {
|
||||
hex_len = sizeof(hex);
|
||||
@ -180,15 +183,15 @@ sm_cwa_config_get_keyset(struct sc_context *ctx, struct sm_info *sm_info)
|
||||
if (hex_len != 16)
|
||||
return SC_ERROR_INVALID_DATA;
|
||||
|
||||
memcpy(sm_info->schannel.keyset.cwa.mac, hex, hex_len);
|
||||
memcpy(cwa_keyset->mac, hex, hex_len);
|
||||
}
|
||||
sc_log(ctx, "%s %s", name, sc_dump_hex(sm_info->schannel.keyset.cwa.mac, 16));
|
||||
sc_log(ctx, "%s %s", name, sc_dump_hex(cwa_keyset->mac, 16));
|
||||
|
||||
sm_info->schannel.keyset.cwa.sdo_reference = crt_at->refs[0];
|
||||
cwa_keyset->sdo_reference = crt_at->refs[0];
|
||||
|
||||
|
||||
/* IFD parameters */
|
||||
memset(session_data, 0, sizeof(struct sm_cwa_session));
|
||||
//memset(cwa_session, 0, sizeof(struct sm_cwa_session));
|
||||
value = scconf_get_str(sm_conf_block, "ifd_serial", NULL);
|
||||
if (!value)
|
||||
return SC_ERROR_SM_IFD_DATA_MISSING;
|
||||
@ -199,27 +202,27 @@ sm_cwa_config_get_keyset(struct sc_context *ctx, struct sm_info *sm_info)
|
||||
return SC_ERROR_UNKNOWN_DATA_RECEIVED;
|
||||
}
|
||||
|
||||
if (hex_len != sizeof(session_data->ifd.sn)) {
|
||||
if (hex_len != sizeof(cwa_session->ifd.sn)) {
|
||||
sc_log(ctx, "SM get 'ifd_serial': invalid IFD serial length: %i", hex_len);
|
||||
return SC_ERROR_UNKNOWN_DATA_RECEIVED;
|
||||
}
|
||||
|
||||
memcpy(session_data->ifd.sn, hex, hex_len);
|
||||
memcpy(cwa_session->ifd.sn, hex, hex_len);
|
||||
|
||||
rv = RAND_bytes(session_data->ifd.rnd, 8);
|
||||
rv = RAND_bytes(cwa_session->ifd.rnd, 8);
|
||||
if (!rv) {
|
||||
sc_log(ctx, "Generate random error: %i", rv);
|
||||
return SC_ERROR_SM_RAND_FAILED;
|
||||
}
|
||||
|
||||
rv = RAND_bytes(session_data->ifd.k, 32);
|
||||
rv = RAND_bytes(cwa_session->ifd.k, 32);
|
||||
if (!rv) {
|
||||
sc_log(ctx, "Generate random error: %i", rv);
|
||||
return SC_ERROR_SM_RAND_FAILED;
|
||||
}
|
||||
sc_log(ctx, "IFD.Serial: %s", sc_dump_hex(session_data->ifd.sn, sizeof(session_data->ifd.sn)));
|
||||
sc_log(ctx, "IFD.Rnd: %s", sc_dump_hex(session_data->ifd.rnd, sizeof(session_data->ifd.rnd)));
|
||||
sc_log(ctx, "IFD.K: %s", sc_dump_hex(session_data->ifd.k, sizeof(session_data->ifd.k)));
|
||||
sc_log(ctx, "IFD.Serial: %s", sc_dump_hex(cwa_session->ifd.sn, sizeof(cwa_session->ifd.sn)));
|
||||
sc_log(ctx, "IFD.Rnd: %s", sc_dump_hex(cwa_session->ifd.rnd, sizeof(cwa_session->ifd.rnd)));
|
||||
sc_log(ctx, "IFD.K: %s", sc_dump_hex(cwa_session->ifd.k, sizeof(cwa_session->ifd.k)));
|
||||
|
||||
return SC_SUCCESS;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user