static int cardos_init(sc_card_t *card) { unsigned long flags, rsa_2048 = 0; card->name = "CardOS M4"; card->cla = 0x00; /* Set up algorithm info. */ flags = SC_ALGORITHM_NEED_USAGE | SC_ALGORITHM_RSA_RAW | SC_ALGORITHM_RSA_HASH_NONE | SC_ALGORITHM_ONBOARD_KEY_GEN ; _sc_card_add_rsa_alg(card, 512, flags, 0); _sc_card_add_rsa_alg(card, 768, flags, 0); _sc_card_add_rsa_alg(card, 1024, flags, 0); if (card->type == SC_CARD_TYPE_CARDOS_M4_2) { int r = cardos_have_2048bit_package(card); if (r < 0) return r; if (r == 1) rsa_2048 = 1; card->caps |= SC_CARD_CAP_APDU_EXT; } else if (card->type == SC_CARD_TYPE_CARDOS_M4_3 || card->type == SC_CARD_TYPE_CARDOS_M4_2B || card->type == SC_CARD_TYPE_CARDOS_M4_2C || card->type == SC_CARD_TYPE_CARDOS_M4_4 || card->type == SC_CARD_TYPE_CARDOS_V5_0) { rsa_2048 = 1; card->caps |= SC_CARD_CAP_APDU_EXT; } if (rsa_2048 == 1) { _sc_card_add_rsa_alg(card, 1280, flags, 0); _sc_card_add_rsa_alg(card, 1536, flags, 0); _sc_card_add_rsa_alg(card, 1792, flags, 0); _sc_card_add_rsa_alg(card, 2048, flags, 0); } return 0; }
static int cardos_init(sc_card_t *card) { unsigned long flags, rsa_2048 = 0; size_t data_field_length; sc_apdu_t apdu; u8 rbuf[2]; card->name = "CardOS M4"; card->cla = 0x00; /* Set up algorithm info. */ flags = SC_ALGORITHM_NEED_USAGE | SC_ALGORITHM_RSA_RAW | SC_ALGORITHM_RSA_HASH_NONE | SC_ALGORITHM_ONBOARD_KEY_GEN ; _sc_card_add_rsa_alg(card, 512, flags, 0); _sc_card_add_rsa_alg(card, 768, flags, 0); _sc_card_add_rsa_alg(card, 1024, flags, 0); if (card->type == SC_CARD_TYPE_CARDOS_M4_2) { int r = cardos_have_2048bit_package(card); if (r < 0) return r; if (r == 1) rsa_2048 = 1; card->caps |= SC_CARD_CAP_APDU_EXT; } else if (card->type == SC_CARD_TYPE_CARDOS_M4_3 || card->type == SC_CARD_TYPE_CARDOS_M4_2B || card->type == SC_CARD_TYPE_CARDOS_M4_2C || card->type == SC_CARD_TYPE_CARDOS_M4_4 || card->type == SC_CARD_TYPE_CARDOS_V5_0) { rsa_2048 = 1; card->caps |= SC_CARD_CAP_APDU_EXT; } /* probe DATA FIELD LENGTH with GET DATA */ sc_format_apdu(card, &apdu, SC_APDU_CASE_2_SHORT, 0xca, 0x01, 0x8D); apdu.le = sizeof rbuf; apdu.resp = rbuf; apdu.resplen = sizeof(rbuf); SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, sc_transmit_apdu(card, &apdu), "APDU transmit failed"); SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, sc_check_sw(card, apdu.sw1, apdu.sw2), "GET DATA command returned error"); if (apdu.resplen != 2) return SC_ERROR_WRONG_LENGTH; data_field_length = ((rbuf[0] << 8) | rbuf[1]); /* strip the length of possible Lc and Le bytes */ if (card->caps & SC_CARD_CAP_APDU_EXT) card->max_send_size = data_field_length - 6; else card->max_send_size = data_field_length - 3; /* strip the length of SW bytes */ card->max_recv_size = data_field_length - 2; if (rsa_2048 == 1) { _sc_card_add_rsa_alg(card, 1280, flags, 0); _sc_card_add_rsa_alg(card, 1536, flags, 0); _sc_card_add_rsa_alg(card, 1792, flags, 0); _sc_card_add_rsa_alg(card, 2048, flags, 0); } return 0; }