diff --git a/ccid/ccid.c b/ccid/ccid.c index 02592da..86f436e 100644 --- a/ccid/ccid.c +++ b/ccid/ccid.c @@ -74,13 +74,13 @@ ccid_desc = { .bMaxCCIDBusySlots = 0x01, }; -void +static void debug_sc_result(int sc_result) { sc_debug(ctx, sc_strerror(sc_result)); } -int +static int detect_card_presence(int slot) { int sc_result; @@ -168,7 +168,7 @@ void ccid_shutdown() sc_release_context(ctx); } -int build_apdu(const __u8 *buf, size_t len, sc_apdu_t *apdu) +static int build_apdu(const __u8 *buf, size_t len, sc_apdu_t *apdu) { const __u8 *p; size_t len0; @@ -233,7 +233,7 @@ int build_apdu(const __u8 *buf, size_t len, sc_apdu_t *apdu) SC_FUNC_RETURN(ctx, SC_LOG_TYPE_VERBOSE, SC_SUCCESS); } -int get_rapdu(sc_apdu_t *apdu, size_t slot, __u8 **buf, size_t *resplen) +static int get_rapdu(sc_apdu_t *apdu, size_t slot, __u8 **buf, size_t *resplen) { int sc_result; @@ -279,7 +279,7 @@ err: SC_FUNC_RETURN(ctx, SC_LOG_TYPE_VERBOSE, sc_result); } -__u8 get_bError(int sc_result) +static __u8 get_bError(int sc_result) { if (sc_result < 0) { switch (sc_result) { @@ -306,7 +306,7 @@ __u8 get_bError(int sc_result) return CCID_BERROR_OK; } -__u8 get_bStatus(int sc_result, __u8 bSlot) +static __u8 get_bStatus(int sc_result, __u8 bSlot) { int flags; __u8 result = 0; @@ -354,7 +354,7 @@ __u8 get_bStatus(int sc_result, __u8 bSlot) return result; } -int +static int get_RDR_to_PC_SlotStatus(__u8 bSlot, __u8 bSeq, int sc_result, RDR_to_PC_SlotStatus_t **out) { if (!out) @@ -376,7 +376,7 @@ get_RDR_to_PC_SlotStatus(__u8 bSlot, __u8 bSeq, int sc_result, RDR_to_PC_SlotSta SC_FUNC_RETURN(ctx, SC_LOG_TYPE_DEBUG, SC_SUCCESS); } -int +static int get_RDR_to_PC_DataBlock(__u8 bSlot, __u8 bSeq, int sc_result, RDR_to_PC_DataBlock_t **out) { if (!out) @@ -398,7 +398,7 @@ get_RDR_to_PC_DataBlock(__u8 bSlot, __u8 bSeq, int sc_result, RDR_to_PC_DataBloc SC_FUNC_RETURN(ctx, SC_LOG_TYPE_DEBUG, SC_SUCCESS); } -int +static int perform_PC_to_RDR_GetSlotStatus(const __u8 *in, __u8 **out, size_t *outlen) { const PC_to_RDR_GetSlotStatus_t *request = (PC_to_RDR_GetSlotStatus_t *) in; @@ -419,7 +419,7 @@ perform_PC_to_RDR_GetSlotStatus(const __u8 *in, __u8 **out, size_t *outlen) (RDR_to_PC_SlotStatus_t **) out)); } -int +static int perform_PC_to_RDR_IccPowerOn(const __u8 *in, __u8 **out, size_t *outlen) { const PC_to_RDR_IccPowerOn_t *request = (PC_to_RDR_IccPowerOn_t *) in; @@ -477,7 +477,7 @@ perform_PC_to_RDR_IccPowerOn(const __u8 *in, __u8 **out, size_t *outlen) SC_FUNC_RETURN(ctx, SC_LOG_TYPE_ERROR, SC_SUCCESS); } -int +static int perform_PC_to_RDR_IccPowerOff(const __u8 *in, __u8 **out, size_t *outlen) { const PC_to_RDR_IccPowerOff_t *request = (PC_to_RDR_IccPowerOff_t *) in; @@ -507,7 +507,7 @@ perform_PC_to_RDR_IccPowerOff(const __u8 *in, __u8 **out, size_t *outlen) SC_FUNC_RETURN(ctx, SC_LOG_TYPE_ERROR, SC_SUCCESS); } -int +static int perform_PC_to_RDR_XfrBlock(const u8 *in, __u8** out, size_t *outlen) { const PC_to_RDR_XfrBlock_t *request = (PC_to_RDR_XfrBlock_t *) in; @@ -566,7 +566,7 @@ perform_PC_to_RDR_XfrBlock(const u8 *in, __u8** out, size_t *outlen) SC_FUNC_RETURN(ctx, SC_LOG_TYPE_ERROR, SC_SUCCESS); } -int +static int perform_PC_to_RDR_GetParamters(const __u8 *in, __u8** out, size_t *outlen) { const PC_to_RDR_GetParameters_t *request = (PC_to_RDR_GetParameters_t *) in; @@ -662,7 +662,7 @@ invaliddata: SC_FUNC_RETURN(ctx, SC_LOG_TYPE_ERROR, SC_SUCCESS); } -int +static int get_effective_offset(uint8_t system_units, uint8_t off, size_t *eff_off, int *sc_result) { @@ -685,7 +685,7 @@ get_effective_offset(uint8_t system_units, uint8_t off, size_t *eff_off, return 1; } -int +static int write_pin_length(sc_apdu_t *apdu, const struct sc_pin_cmd_pin *pin, uint8_t system_units, uint8_t length_size, int *sc_result) { @@ -713,7 +713,7 @@ write_pin_length(sc_apdu_t *apdu, const struct sc_pin_cmd_pin *pin, return 1; } -int +static int encode_pin(u8 *buf, size_t buf_len, struct sc_pin_cmd_pin *pin, uint8_t encoding, int *sc_result) { @@ -789,7 +789,7 @@ encode_pin(u8 *buf, size_t buf_len, struct sc_pin_cmd_pin *pin, return 1; } -int +static int write_pin(sc_apdu_t *apdu, struct sc_pin_cmd_pin *pin, uint8_t blocksize, uint8_t justify_right, uint8_t encoding, int *sc_result) { @@ -820,7 +820,7 @@ write_pin(sc_apdu_t *apdu, struct sc_pin_cmd_pin *pin, uint8_t blocksize, blocksize - justify_offset, pin, encoding, sc_result); } -int +static int perform_PC_to_RDR_Secure(const __u8 *in, __u8** out, size_t *outlen) { int sc_result, r; @@ -1045,7 +1045,7 @@ err: SC_FUNC_RETURN(ctx, SC_LOG_TYPE_ERROR, r); } -int +static int get_RDR_to_PC_NotifySlotChange(RDR_to_PC_NotifySlotChange_t **out) { int i; @@ -1093,7 +1093,7 @@ get_RDR_to_PC_NotifySlotChange(RDR_to_PC_NotifySlotChange_t **out) SC_FUNC_RETURN(ctx, SC_LOG_TYPE_DEBUG, SC_SUCCESS); } -int +static int perform_unknown(const __u8 *in, __u8 **out, size_t *outlen) { const PC_to_RDR_GetSlotStatus_t *request = (PC_to_RDR_GetSlotStatus_t *) in; diff --git a/ccid/pace.c b/ccid/pace.c index 6ad0266..87c5ab7 100644 --- a/ccid/pace.c +++ b/ccid/pace.c @@ -173,7 +173,6 @@ int pace_sm_decrypt(sc_card_t *card, struct *sm_ctx, #include "apdu.h" const size_t maxresp = SC_MAX_APDU_BUFFER_SIZE - 2; -uint16_t ssc = 0; int GetReadersPACECapabilities(sc_card_t *card, const __u8 *in, __u8 **out, size_t *outlen) { @@ -196,7 +195,7 @@ int GetReadersPACECapabilities(sc_card_t *card, } /** select and read EF.CardAccess */ -int get_ef_card_access(sc_card_t *card, +static int get_ef_card_access(sc_card_t *card, __u8 **ef_cardaccess, size_t *length_ef_cardaccess) { int r; @@ -213,7 +212,6 @@ int get_ef_card_access(sc_card_t *card, memset(&file, 0, sizeof file); SC_TEST_RET(card->ctx, sc_select_file(card, &path, &file), "Could not select EF.CardAccess."); - ssc++; *length_ef_cardaccess = 0; while(1) { @@ -224,7 +222,6 @@ int get_ef_card_access(sc_card_t *card, r = sc_read_binary(card, *length_ef_cardaccess, *ef_cardaccess + *length_ef_cardaccess, maxresp, 0); - ssc++; if (r > 0 && r != maxresp) { *length_ef_cardaccess += r; @@ -244,7 +241,7 @@ int get_ef_card_access(sc_card_t *card, SC_FUNC_RETURN(card->ctx, SC_LOG_TYPE_DEBUG, SC_SUCCESS); } -int pace_mse_set_at(sc_card_t *card, +static int pace_mse_set_at(sc_card_t *card, int protocol, int secret_key, int reference) { sc_apdu_t apdu; @@ -294,7 +291,6 @@ int pace_mse_set_at(sc_card_t *card, bin_log(card->ctx, "MSE:Set AT command data", apdu.data, apdu.datalen); r = sc_transmit_apdu(card, &apdu); - ssc++; if (r < 0) goto err; @@ -345,7 +341,7 @@ err: SC_FUNC_RETURN(card->ctx, SC_LOG_TYPE_DEBUG, r); } -int pace_gen_auth(sc_card_t *card, +static int pace_gen_auth(sc_card_t *card, int step, const u8 *in, size_t in_len, u8 **out, size_t *out_len) { sc_apdu_t apdu; @@ -417,7 +413,6 @@ int pace_gen_auth(sc_card_t *card, apdu.resplen = maxresp; apdu.resp = malloc(apdu.resplen); r = my_transmit_apdu(card, &apdu); - ssc++; if (r < 0) goto err; @@ -534,7 +529,7 @@ err: SC_FUNC_RETURN(card->ctx, SC_LOG_TYPE_DEBUG, r); } -PACE_SEC * +static PACE_SEC * get_psec(sc_card_t *card, const char *pin, size_t length_pin, u8 pin_id) { sc_ui_hints_t hints; @@ -811,7 +806,6 @@ int pace_test(sc_card_t *card) __u8 *out = NULL; size_t outlen; struct sm_ctx sctx; - sc_apdu_t sm_apdu; sc_apdu_t apdu; memset(&sctx, 0, sizeof(sctx)); @@ -845,25 +839,12 @@ int pace_test(sc_card_t *card) apdu.le = 0x00; apdu.cse = SC_APDU_CASE_4_SHORT; - SC_TEST_RET(card->ctx, reset_ssc(&sctx), - "Could not reset send sequence counter."); - SC_TEST_RET(card->ctx, sm_encrypt(&sctx, card, &apdu, &sm_apdu), - "Could not encrypt APDU."); - bin_log(card->ctx, "SM APDU data", sm_apdu.data, sm_apdu.datalen); - sm_apdu.resplen = maxresp; - sm_apdu.resp = malloc(apdu.resplen); - SC_TEST_RET(card->ctx, my_transmit_apdu(card, &sm_apdu), - "Could not send SM APDU."); - SC_TEST_RET(card->ctx, sm_check_sw(card, sm_apdu.sw1, sm_apdu.sw2), - "Card returned error."); - SC_TEST_RET(card->ctx, sm_decrypt(&sctx, card, &sm_apdu, &apdu), - "Could not decrypt APDU."); - bin_log(card->ctx, "SM APDU response", sm_apdu.resp, apdu.resplen); + sm_transmit_apdu(&sctx, card, &apdu); return SC_SUCCESS; } -BUF_MEM * +static BUF_MEM * encoded_ssc(const uint16_t ssc, const PACE_CTX *ctx) { BUF_MEM * out = NULL; @@ -890,7 +871,7 @@ err: return NULL; } -int +static int update_iv(struct sm_ctx *ctx) { if (!ctx || !ctx->cipher_ctx) @@ -967,9 +948,7 @@ increment_ssc(struct sm_ctx *ctx) psmctx->ssc++; } - update_iv(ctx); - - return SC_SUCCESS; + return update_iv(ctx); } int @@ -981,7 +960,7 @@ reset_ssc(struct sm_ctx *ctx) struct pace_sm_ctx *psmctx = ctx->cipher_ctx; psmctx->ssc = 0; - return increment_ssc(ctx); + return update_iv(ctx); } int pace_sm_encrypt(sc_card_t *card, const struct sm_ctx *ctx, diff --git a/ccid/sm.c b/ccid/sm.c index dd0f528..5269a59 100644 --- a/ccid/sm.c +++ b/ccid/sm.c @@ -17,6 +17,7 @@ * ccid. If not, see . */ #include "sm.h" +#include "apdu.h" #include #include #include @@ -43,25 +44,6 @@ static const struct sc_asn1_entry c_sm_rapdu[] = { { NULL, 0, 0, 0, NULL, NULL } }; -static const struct sc_card_error sm_errors[] = { - { 0x6987, SC_ERROR_DATA_OBJECT_NOT_FOUND, "Secure Messaging data objects are missing" }, - { 0x6988, SC_ERROR_SECURITY_STATUS_NOT_SATISFIED, "Secure Messaging data objects are incorrect" }, -}; - -int sm_check_sw(sc_card_t *card, unsigned int sw1, unsigned int sw2) -{ - const int err_count = sizeof(sm_errors)/sizeof(sm_errors[0]); - int i; - - for (i = 0; i < err_count; i++) - if (sm_errors[i].SWs == ((sw1 << 8) | sw2)) { - sc_error(card->ctx, "%s\n", sm_errors[i].errorstr); - return sm_errors[i].errorno; - } - - return sc_check_sw(card, sw1, sw2); -} - void bin_log(sc_context_t *ctx, const char *label, const u8 *data, size_t len) { char buf[1024]; @@ -153,7 +135,7 @@ int no_padding(u8 padding_indicator, const u8 *data, size_t datalen) return len; } -u8 * format_le(size_t le_len, size_t le, struct sc_asn1_entry *le_entry) +static u8 * format_le(size_t le_len, size_t le, struct sc_asn1_entry *le_entry) { u8 * lebuf = malloc(le_len); if (lebuf) { @@ -181,7 +163,7 @@ u8 * format_le(size_t le_len, size_t le, struct sc_asn1_entry *le_entry) return lebuf; } -BUF_MEM * prefix_buf(u8 prefix, BUF_MEM *buf) +static BUF_MEM * prefix_buf(u8 prefix, BUF_MEM *buf) { if (!buf) return NULL; BUF_MEM *cat = BUF_MEM_create(buf->length + 1); @@ -193,7 +175,7 @@ BUF_MEM * prefix_buf(u8 prefix, BUF_MEM *buf) return cat; } -BUF_MEM * format_data(sc_card_t *card, const struct sm_ctx *ctx, const u8 *data, size_t datalen, +static BUF_MEM * format_data(sc_card_t *card, const struct sm_ctx *ctx, const u8 *data, size_t datalen, struct sc_asn1_entry *formatted_encrypted_data_entry) { int r; @@ -226,7 +208,7 @@ BUF_MEM * format_data(sc_card_t *card, const struct sm_ctx *ctx, const u8 *data, return indicator_encdata; } -BUF_MEM * format_head(const struct sm_ctx *ctx, const sc_apdu_t *apdu) +static BUF_MEM * format_head(const struct sm_ctx *ctx, const sc_apdu_t *apdu) { char head[4]; @@ -237,7 +219,7 @@ BUF_MEM * format_head(const struct sm_ctx *ctx, const sc_apdu_t *apdu) return add_padding(ctx, head, sizeof head); } -int sm_encrypt(const struct sm_ctx *ctx, sc_card_t *card, +static int sm_encrypt(const struct sm_ctx *ctx, sc_card_t *card, const sc_apdu_t *apdu, sc_apdu_t *sm_apdu) { struct sc_asn1_entry sm_capdu[4]; @@ -401,7 +383,6 @@ int sm_encrypt(const struct sm_ctx *ctx, sc_card_t *card, sm_apdu->le = 0; sm_apdu->cse = SC_APDU_CASE_4; bin_log(card->ctx, "sm apdu data", sm_apdu->data, sm_apdu->datalen); - printf("%s:%d\n", __FILE__, __LINE__); err: if (fdata) { @@ -423,7 +404,7 @@ err: SC_FUNC_RETURN(card->ctx, SC_LOG_TYPE_ERROR, r); } -int sm_decrypt(const struct sm_ctx *ctx, sc_card_t *card, +static int sm_decrypt(const struct sm_ctx *ctx, sc_card_t *card, const sc_apdu_t *sm_apdu, sc_apdu_t *apdu) { int r; @@ -513,3 +494,27 @@ err: SC_FUNC_RETURN(card->ctx, SC_LOG_TYPE_ERROR, r); } + +int sm_transmit_apdu(const struct sm_ctx *sctx, sc_card_t *card, + sc_apdu_t *apdu) +{ + sc_apdu_t sm_apdu; + u8 buf[SC_MAX_APDU_BUFFER_SIZE - 2]; + + SC_TEST_RET(card->ctx, sm_encrypt(sctx, card, apdu, &sm_apdu), + "Could not encrypt APDU."); + bin_log(card->ctx, "SM APDU data", sm_apdu.data, sm_apdu.datalen); + + sm_apdu.resplen = sizeof *buf; + sm_apdu.resp = buf; + SC_TEST_RET(card->ctx, my_transmit_apdu(card, &sm_apdu), + "Could not send SM APDU."); + + SC_TEST_RET(card->ctx, sc_check_sw(card, sm_apdu.sw1, sm_apdu.sw2), + "Card returned error."); + SC_TEST_RET(card->ctx, sm_decrypt(sctx, card, &sm_apdu, apdu), + "Could not decrypt APDU."); + bin_log(card->ctx, "SM APDU response", apdu->resp, apdu->resplen); + + SC_FUNC_RETURN(card->ctx, SC_LOG_TYPE_ERROR, SC_SUCCESS); +} diff --git a/ccid/sm.h b/ccid/sm.h index 7301dc9..6591f64 100644 --- a/ccid/sm.h +++ b/ccid/sm.h @@ -33,7 +33,6 @@ struct sm_ctx { u8 padding_indicator; size_t block_length; - void *authentication_ctx; int (*authenticate)(sc_card_t *card, const struct sm_ctx *ctx, const u8 *data, size_t datalen, u8 **outdata); @@ -48,12 +47,8 @@ struct sm_ctx { const u8 *enc, size_t enclen, u8 **data); }; -int sm_encrypt(const struct sm_ctx *ctx, sc_card_t *card, - const sc_apdu_t *apdu, sc_apdu_t *sm_apdu); -int sm_decrypt(const struct sm_ctx *ctx, sc_card_t *card, - const sc_apdu_t *sm_apdu, sc_apdu_t *apdu); - -int sm_check_sw(sc_card_t *card, unsigned int sw1, unsigned int sw2); +int sm_transmit_apdu(const struct sm_ctx *sctx, sc_card_t *card, + sc_apdu_t *apdu); BUF_MEM * add_iso_pad(const BUF_MEM * m, int block_size); BUF_MEM * add_padding(const struct sm_ctx *ctx, const char *data, size_t datalen);