diff --git a/firmware/targets/f7/api_symbols.csv b/firmware/targets/f7/api_symbols.csv index f77640f09..ee0dd0c31 100644 --- a/firmware/targets/f7/api_symbols.csv +++ b/firmware/targets/f7/api_symbols.csv @@ -893,7 +893,6 @@ Function,-,felica_estimate_timing_us,uint_least32_t,"uint_least8_t, uint_least8_ Function,-,felica_get_ic_type,FelicaICType,uint8_t* Function,-,felica_get_service_name,FuriString*,FelicaService* Function,-,felica_get_system_name,FuriString*,FelicaSystem* -Function,-,felica_lite_can_read_without_mac,_Bool,"uint8_t*, uint8_t" Function,-,felica_lite_dump_data,_Bool,"FuriHalNfcTxRxContext*, FelicaReader*, FelicaData*, FelicaSystem*" Function,-,felica_lite_is_issued,_Bool,FelicaLiteInfo* Function,-,felica_lite_prepare_unencrypted_read,uint8_t,"uint8_t*, const FelicaReader*, _Bool, const uint8_t*, uint8_t" diff --git a/lib/nfc/nfc_device.c b/lib/nfc/nfc_device.c index c2d866c03..cd1f86de7 100644 --- a/lib/nfc/nfc_device.c +++ b/lib/nfc/nfc_device.c @@ -1120,59 +1120,60 @@ static bool nfc_device_save_mifare_classic_data(FlipperFormat* file, NfcDevice* static bool nfc_device_save_felica_lite(FlipperFormat* file, FelicaLiteInfo* info) { bool saved = false; FuriString* key = furi_string_alloc(); + FuriString* temp = furi_string_alloc(); do { flipper_format_write_comment_cstr(file, "Lite(-S) System"); flipper_format_write_hex( - file, "Data Format Code", info->data_format_code, sizeof(uint16_t)); + file, "Data Format Code", (uint8_t*)&info->data_format_code, sizeof(uint16_t)); flipper_format_write_hex(file, "ID Arbitrary Value", info->ID_value, 6); flipper_format_write_hex(file, "Memory Config", info->memory_config, FELICA_BLOCK_SIZE); for(uint8_t block_num = 0; block_num < 14; block_num++) { - FuriString* spad_str = furi_string_alloc(); + furi_string_reset(temp); for(size_t i = 0; i < FELICA_BLOCK_SIZE; i++) { if(info->S_PAD[block_num] != NULL) { - furi_string_cat_printf(spad_str, "%02X ", info->S_PAD[block_num][i]); + furi_string_cat_printf(temp, "%02X ", info->S_PAD[block_num][i]); } else { - furi_string_cat_printf(spad_str, "?? "); + furi_string_cat_printf(temp, "?? "); } } furi_string_printf(key, "S_PAD%d", block_num); - flipper_format_write_string(file, furi_string_get_cstr(key), spad_str); + flipper_format_write_string(file, furi_string_get_cstr(key), temp); } - FuriString* reg_str = furi_string_alloc(); + furi_string_reset(temp); for(size_t i = 0; i < FELICA_BLOCK_SIZE; i++) { if(info->REG != NULL) { - furi_string_cat_printf(reg_str, "%02X ", info->REG[i]); + furi_string_cat_printf(temp, "%02X ", info->REG[i]); } else { - furi_string_cat_printf(reg_str, "?? "); + furi_string_cat_printf(temp, "?? "); } } - flipper_format_write_string(file, "REG", reg_str); + flipper_format_write_string(file, "REG", temp); flipper_format_write_hex( - file, "Card Key Version", &info->card_key_version, sizeof(uint16_t)); - FuriString* ck1_str = furi_string_alloc(); + file, "Card Key Version", (uint8_t*)&info->card_key_version, sizeof(uint16_t)); + furi_string_reset(temp); for(size_t i = 0; i < FELICA_BLOCK_SIZE; i++) { if(info->REG != NULL) { - furi_string_cat_printf(ck1_str, "%02X ", info->card_key_1[i]); + furi_string_cat_printf(temp, "%02X ", info->card_key_1[i]); } else { - furi_string_cat_printf(ck1_str, "?? "); + furi_string_cat_printf(temp, "?? "); } } - flipper_format_write_string(file, "Card Key 1", ck1_str); + flipper_format_write_string(file, "Card Key 1", temp); - FuriString* ck2_str = furi_string_alloc(); + furi_string_reset(temp); for(size_t i = 0; i < FELICA_BLOCK_SIZE; i++) { if(info->REG != NULL) { - furi_string_cat_printf(ck2_str, "%02X ", info->card_key_2[i]); + furi_string_cat_printf(temp, "%02X ", info->card_key_2[i]); } else { - furi_string_cat_printf(ck2_str, "?? "); + furi_string_cat_printf(temp, "?? "); } } - flipper_format_write_string(file, "Card Key 2", ck2_str); + flipper_format_write_string(file, "Card Key 2", temp); flipper_format_write_hex(file, "Fixed Challenge MAC Response", info->MAC, 8); @@ -1184,18 +1185,22 @@ static bool nfc_device_save_felica_lite(FlipperFormat* file, FelicaLiteInfo* inf } while(false); + furi_string_free(temp); + furi_string_free(key); return saved; } +static bool nfc_device_save_felica_node(FlipperFormat* file, FelicaNode* node); + static bool nfc_device_save_felica_area(FlipperFormat* file, FelicaArea* area) { bool saved = false; FuriString* prefix = furi_string_alloc_printf("Area %d", area->number); FuriString* key = furi_string_alloc(); do { - furi_string_printf(key, "%s Can Create Subareas", prefix); + furi_string_printf(key, "%s Can Create Subareas", furi_string_get_cstr(prefix)); flipper_format_write_bool(file, furi_string_get_cstr(key), &area->can_create_subareas, 1); - furi_string_printf(key, "%s End Service Code", prefix); + furi_string_printf(key, "%s End Service Code", furi_string_get_cstr(prefix)); flipper_format_write_hex( file, furi_string_get_cstr(key), (uint8_t*)&area->end_service_code, sizeof(uint16_t)); @@ -1212,6 +1217,8 @@ static bool nfc_device_save_felica_area(FlipperFormat* file, FelicaArea* area) { saved = true; } while(false); + furi_string_free(prefix); + furi_string_free(key); return saved; } @@ -1221,40 +1228,40 @@ static bool nfc_device_save_felica_service(FlipperFormat* file, FelicaService* s FuriString* key = furi_string_alloc(); do { - furi_string_printf(key, "%s Is Extended Overlap", prefix); + furi_string_printf(key, "%s Is Extended Overlap", furi_string_get_cstr(prefix)); flipper_format_write_bool( file, furi_string_get_cstr(key), &service->is_extended_overlap, 1); if(service->is_extended_overlap) { - furi_string_printf(key, "%s Overlap Target", prefix); + furi_string_printf(key, "%s Overlap Target", furi_string_get_cstr(prefix)); flipper_format_write_hex( file, furi_string_get_cstr(key), (uint8_t*)&service->overlap_target, sizeof(uint16_t)); - furi_string_printf(key, "%s Block Start", prefix); + furi_string_printf(key, "%s Block Start", furi_string_get_cstr(prefix)); const uint32_t block_start = service->block_start; flipper_format_write_uint32(file, furi_string_get_cstr(key), &block_start, 1); - furi_string_printf(key, "%s Block Count", prefix); + furi_string_printf(key, "%s Block Count", furi_string_get_cstr(prefix)); const uint32_t block_count = service->block_count; flipper_format_write_uint32(file, furi_string_get_cstr(key), &block_count, 1); uint32_t i = 0; for M_EACH(block, service->blocks, FelicaBlockArray_t) { - furi_string_printf(key, "%s Block %d", prefix, i); + furi_string_printf(key, "%s Block %ld", furi_string_get_cstr(prefix), i); flipper_format_write_hex( file, furi_string_get_cstr(key), block->data, FELICA_BLOCK_SIZE); } } else { - furi_string_printf(key, "%s Block Count", prefix); + furi_string_printf(key, "%s Block Count", furi_string_get_cstr(prefix)); uint32_t block_count = FelicaBlockArray_size(service->blocks); flipper_format_write_uint32(file, furi_string_get_cstr(key), &block_count, 1); uint32_t i = 0; for M_EACH(block, service->blocks, FelicaBlockArray_t) { - furi_string_printf(key, "%s Block %d", prefix, i); + furi_string_printf(key, "%s Block %ld", furi_string_get_cstr(prefix), i); flipper_format_write_hex( file, furi_string_get_cstr(key), block->data, FELICA_BLOCK_SIZE); } @@ -1262,20 +1269,23 @@ static bool nfc_device_save_felica_service(FlipperFormat* file, FelicaService* s saved = true; } while(false); + + furi_string_free(prefix); + furi_string_free(key); + return saved; } static bool nfc_device_save_felica_node(FlipperFormat* file, FelicaNode* node) { bool saved = false; - FuriString* key = furi_string_alloc(); do { if(node->type == FelicaNodeTypeArea) { - if(!nfc_device_save_felica_node(file, node->area)) { + if(!nfc_device_save_felica_area(file, node->area)) { saved = false; break; } } else if(node->type == FelicaNodeTypeService) { - if(!nfc_device_save_felica_service(file, node->area)) { + if(!nfc_device_save_felica_service(file, node->service)) { saved = false; break; } diff --git a/lib/nfc/protocols/felica.c b/lib/nfc/protocols/felica.c index bf9da65f5..182893527 100644 --- a/lib/nfc/protocols/felica.c +++ b/lib/nfc/protocols/felica.c @@ -152,214 +152,214 @@ FelicaICType felica_get_ic_type(uint8_t* PMm) { return FelicaICType2K; } -static void felica_lite_diversify_key(uint8_t* id_block, uint8_t* master_key, uint8_t* card_key) { - uint8_t ZERO[8] = {0}; - uint8_t L[8]; - mbedtls_des3_context ctx; - mbedtls_des3_init(&ctx); - mbedtls_des3_set3key_enc(&ctx, master_key); - mbedtls_des3_crypt_ecb(&ctx, ZERO, L); - mbedtls_des3_free(&ctx); +// static void felica_lite_diversify_key(uint8_t* id_block, uint8_t* master_key, uint8_t* card_key) { +// uint8_t ZERO[8] = {0}; +// uint8_t L[8]; +// mbedtls_des3_context ctx; +// mbedtls_des3_init(&ctx); +// mbedtls_des3_set3key_enc(&ctx, master_key); +// mbedtls_des3_crypt_ecb(&ctx, ZERO, L); +// mbedtls_des3_free(&ctx); - uint8_t K1[8]; - for(int i = 0; i < 8; i++) { - K1[i] = L[i] << 1; - if(i < 7) { - K1[i] |= (L[i + 1] >> 7); - } - } +// uint8_t K1[8]; +// for(int i = 0; i < 8; i++) { +// K1[i] = L[i] << 1; +// if(i < 7) { +// K1[i] |= (L[i + 1] >> 7); +// } +// } - if((L[0] ^ 0x80) == 0) { - K1[7] ^= 0x1B; - } +// if((L[0] ^ 0x80) == 0) { +// K1[7] ^= 0x1B; +// } - uint8_t M1[8]; - uint8_t M2[8]; - memcpy(M1, id_block, 8); - memcpy(M2, id_block + 8, 8); - for(int i = 0; i < 8; i++) { - M2[i] ^= K1[i]; - } +// uint8_t M1[8]; +// uint8_t M2[8]; +// memcpy(M1, id_block, 8); +// memcpy(M2, id_block + 8, 8); +// for(int i = 0; i < 8; i++) { +// M2[i] ^= K1[i]; +// } - uint8_t C1[8]; - mbedtls_des3_init(&ctx); - mbedtls_des3_set3key_enc(&ctx, master_key); - mbedtls_des3_crypt_ecb(&ctx, M1, C1); - for(int i = 0; i < 8; i++) { - C1[i] ^= M2[i]; - } +// uint8_t C1[8]; +// mbedtls_des3_init(&ctx); +// mbedtls_des3_set3key_enc(&ctx, master_key); +// mbedtls_des3_crypt_ecb(&ctx, M1, C1); +// for(int i = 0; i < 8; i++) { +// C1[i] ^= M2[i]; +// } - mbedtls_des3_crypt_ecb(&ctx, C1, card_key); // T +// mbedtls_des3_crypt_ecb(&ctx, C1, card_key); // T - M1[0] ^= 0x80; // M'1 - mbedtls_des3_crypt_ecb(&ctx, M1, C1); // C'1 - for(int i = 0; i < 8; i++) { - C1[i] ^= M2[i]; - } +// M1[0] ^= 0x80; // M'1 +// mbedtls_des3_crypt_ecb(&ctx, M1, C1); // C'1 +// for(int i = 0; i < 8; i++) { +// C1[i] ^= M2[i]; +// } - mbedtls_des3_crypt_ecb(&ctx, C1, card_key + 8); // T' - mbedtls_des3_free(&ctx); -} +// mbedtls_des3_crypt_ecb(&ctx, C1, card_key + 8); // T' +// mbedtls_des3_free(&ctx); +// } -static void felica_lite_generate_session_key( - uint8_t* random_challenge, - uint8_t* card_key, - uint8_t* session_key) { - uint8_t RC1[8]; - uint8_t RC2[8]; - uint8_t CK[16]; +// static void felica_lite_generate_session_key( +// uint8_t* random_challenge, +// uint8_t* card_key, +// uint8_t* session_key) { +// uint8_t RC1[8]; +// uint8_t RC2[8]; +// uint8_t CK[16]; - for(int i = 0; i < 8; i++) { - RC1[i] = random_challenge[7 - i]; - RC2[i] = random_challenge[i]; - CK[i] = card_key[7 - i]; - CK[i + 8] = card_key[15 - i]; - } +// for(int i = 0; i < 8; i++) { +// RC1[i] = random_challenge[7 - i]; +// RC2[i] = random_challenge[i]; +// CK[i] = card_key[7 - i]; +// CK[i + 8] = card_key[15 - i]; +// } - mbedtls_des3_context ctx; +// mbedtls_des3_context ctx; - uint8_t SK1[8]; - mbedtls_des3_init(&ctx); - mbedtls_des3_set2key_enc(&ctx, CK); - mbedtls_des3_crypt_ecb(&ctx, RC1, SK1); +// uint8_t SK1[8]; +// mbedtls_des3_init(&ctx); +// mbedtls_des3_set2key_enc(&ctx, CK); +// mbedtls_des3_crypt_ecb(&ctx, RC1, SK1); - uint8_t SK2[8]; - for(int i = 0; i < 8; i++) { - RC2[i] ^= SK1[i]; - } - mbedtls_des3_crypt_ecb(&ctx, RC2, SK2); - mbedtls_des3_free(&ctx); +// uint8_t SK2[8]; +// for(int i = 0; i < 8; i++) { +// RC2[i] ^= SK1[i]; +// } +// mbedtls_des3_crypt_ecb(&ctx, RC2, SK2); +// mbedtls_des3_free(&ctx); - for(int i = 0; i < 8; i++) { - session_key[i] = SK1[7 - i]; - session_key[i + 8] = SK2[7 - i]; - } -} +// for(int i = 0; i < 8; i++) { +// session_key[i] = SK1[7 - i]; +// session_key[i + 8] = SK2[7 - i]; +// } +// } -static void felica_lite_calculate_mac( - uint8_t* random_challenge, - uint8_t* session_key, - uint8_t* block_data, - size_t block_count, - uint8_t* MAC) { - uint8_t SK[16]; +// static void felica_lite_calculate_mac( +// uint8_t* random_challenge, +// uint8_t* session_key, +// uint8_t* block_data, +// size_t block_count, +// uint8_t* MAC) { +// uint8_t SK[16]; - for(int i = 0; i < 8; i++) { - MAC[i] = random_challenge[7 - i]; - SK[i] = session_key[7 - i]; - SK[i + 8] = session_key[15 - i]; - } +// for(int i = 0; i < 8; i++) { +// MAC[i] = random_challenge[7 - i]; +// SK[i] = session_key[7 - i]; +// SK[i + 8] = session_key[15 - i]; +// } - mbedtls_des3_context ctx; - mbedtls_des3_init(&ctx); - mbedtls_des3_set3key_enc(&ctx, SK); +// mbedtls_des3_context ctx; +// mbedtls_des3_init(&ctx); +// mbedtls_des3_set3key_enc(&ctx, SK); - for(size_t block_num = 0; block_num < block_count; block_num++) { - for(int i = 0; i < 8; i++) { - MAC[i] ^= block_data[block_num * FELICA_BLOCK_SIZE + 7 - i]; - } +// for(size_t block_num = 0; block_num < block_count; block_num++) { +// for(int i = 0; i < 8; i++) { +// MAC[i] ^= block_data[block_num * FELICA_BLOCK_SIZE + 7 - i]; +// } - uint8_t intermediate[8]; - mbedtls_des3_crypt_ecb(&ctx, MAC, intermediate); - for(int i = 0; i < 8; i++) { - intermediate[i] ^= block_data[block_num * FELICA_BLOCK_SIZE + 15 - i]; - } +// uint8_t intermediate[8]; +// mbedtls_des3_crypt_ecb(&ctx, MAC, intermediate); +// for(int i = 0; i < 8; i++) { +// intermediate[i] ^= block_data[block_num * FELICA_BLOCK_SIZE + 15 - i]; +// } - mbedtls_des3_crypt_ecb(&ctx, intermediate, MAC); - } +// mbedtls_des3_crypt_ecb(&ctx, intermediate, MAC); +// } - mbedtls_des3_free(&ctx); -} +// mbedtls_des3_free(&ctx); +// } -static void felica_lite_calculate_mac_a( - uint8_t* random_challenge, - uint8_t* session_key, - uint8_t* iv, - uint8_t* block_data, - size_t block_count, - uint8_t* MAC_A) { - uint8_t SK[16]; - uint8_t intermediate_a[8]; - uint8_t intermediate_b[8]; +// static void felica_lite_calculate_mac_a( +// uint8_t* random_challenge, +// uint8_t* session_key, +// uint8_t* iv, +// uint8_t* block_data, +// size_t block_count, +// uint8_t* MAC_A) { +// uint8_t SK[16]; +// uint8_t intermediate_a[8]; +// uint8_t intermediate_b[8]; - for(int i = 0; i < 8; i++) { - intermediate_a[i] = iv[7 - 1] ^ random_challenge[7 - i]; - SK[i] = session_key[7 - i]; - SK[i + 8] = session_key[15 - i]; - } +// for(int i = 0; i < 8; i++) { +// intermediate_a[i] = iv[7 - 1] ^ random_challenge[7 - i]; +// SK[i] = session_key[7 - i]; +// SK[i + 8] = session_key[15 - i]; +// } - mbedtls_des3_context ctx; - mbedtls_des3_init(&ctx); - mbedtls_des3_set3key_enc(&ctx, SK); - mbedtls_des3_crypt_ecb(&ctx, intermediate_a, intermediate_b); +// mbedtls_des3_context ctx; +// mbedtls_des3_init(&ctx); +// mbedtls_des3_set3key_enc(&ctx, SK); +// mbedtls_des3_crypt_ecb(&ctx, intermediate_a, intermediate_b); - for(size_t block_num = 0; block_num < block_count; block_num++) { - for(int i = 0; i < 8; i++) { - intermediate_b[i] ^= block_data[block_num * FELICA_BLOCK_SIZE + 7 - i]; - } +// for(size_t block_num = 0; block_num < block_count; block_num++) { +// for(int i = 0; i < 8; i++) { +// intermediate_b[i] ^= block_data[block_num * FELICA_BLOCK_SIZE + 7 - i]; +// } - mbedtls_des3_crypt_ecb(&ctx, intermediate_b, intermediate_a); - for(int i = 0; i < 8; i++) { - intermediate_a[i] ^= block_data[block_num * FELICA_BLOCK_SIZE + 7 - i]; - } +// mbedtls_des3_crypt_ecb(&ctx, intermediate_b, intermediate_a); +// for(int i = 0; i < 8; i++) { +// intermediate_a[i] ^= block_data[block_num * FELICA_BLOCK_SIZE + 7 - i]; +// } - mbedtls_des3_crypt_ecb(&ctx, intermediate_a, intermediate_b); - } +// mbedtls_des3_crypt_ecb(&ctx, intermediate_a, intermediate_b); +// } - for(int i = 0; i < 8; i++) { - MAC_A[i] = intermediate_b[7 - 1]; - } -} +// for(int i = 0; i < 8; i++) { +// MAC_A[i] = intermediate_b[7 - 1]; +// } +// } -static void felica_lite_calculate_mac_a_for_write( - uint8_t* random_challenge, - uint8_t* session_key, - uint32_t write_count, - uint8_t block_number, - uint8_t* block_data, - uint8_t* MAC_A) { - uint8_t iv[8]; - nfc_util_num2bytes(write_count, 3, iv); - iv[3] = 0x00; - iv[4] = block_number; - iv[5] = 0x00; - iv[6] = 0x91; - iv[7] = 0x00; +// static void felica_lite_calculate_mac_a_for_write( +// uint8_t* random_challenge, +// uint8_t* session_key, +// uint32_t write_count, +// uint8_t block_number, +// uint8_t* block_data, +// uint8_t* MAC_A) { +// uint8_t iv[8]; +// nfc_util_num2bytes(write_count, 3, iv); +// iv[3] = 0x00; +// iv[4] = block_number; +// iv[5] = 0x00; +// iv[6] = 0x91; +// iv[7] = 0x00; - uint8_t SK[16]; - for(int i = 0; i < 8; i++) { - SK[i] = session_key[i + 8]; - SK[i + 8] = session_key[i]; - } +// uint8_t SK[16]; +// for(int i = 0; i < 8; i++) { +// SK[i] = session_key[i + 8]; +// SK[i + 8] = session_key[i]; +// } - felica_lite_calculate_mac_a(random_challenge, SK, iv, block_data, 1, MAC_A); -} +// felica_lite_calculate_mac_a(random_challenge, SK, iv, block_data, 1, MAC_A); +// } -static void felica_lite_calculate_mac_a_for_read( - uint8_t* random_challenge, - uint8_t* session_key, - uint8_t* block_list, - uint8_t block_list_count, - uint8_t* block_data, - uint8_t block_count, - uint8_t* MAC_A) { - uint8_t iv[8] = {0}; +// static void felica_lite_calculate_mac_a_for_read( +// uint8_t* random_challenge, +// uint8_t* session_key, +// uint8_t* block_list, +// uint8_t block_list_count, +// uint8_t* block_data, +// uint8_t block_count, +// uint8_t* MAC_A) { +// uint8_t iv[8] = {0}; - uint8_t block_list_to_write = MIN(block_list_count, 4); - for(int i = 0; i < block_list_to_write; i++) { - iv[i * 2] = block_list[i]; - } - if(block_list_to_write < 4) { - iv[6] = 0xFF; - iv[7] = 0xFF; - } - if(block_list_to_write < 3) { - iv[4] = 0xFF; - iv[5] = 0xFF; - } +// uint8_t block_list_to_write = MIN(block_list_count, 4); +// for(int i = 0; i < block_list_to_write; i++) { +// iv[i * 2] = block_list[i]; +// } +// if(block_list_to_write < 4) { +// iv[6] = 0xFF; +// iv[7] = 0xFF; +// } +// if(block_list_to_write < 3) { +// iv[4] = 0xFF; +// iv[5] = 0xFF; +// } - felica_lite_calculate_mac_a(random_challenge, session_key, iv, block_data, block_count, MAC_A); -} +// felica_lite_calculate_mac_a(random_challenge, session_key, iv, block_data, block_count, MAC_A); +// } /** Parse common FeliCa response headers. * @@ -940,4 +940,4 @@ void felica_clear(FelicaData* data) { } } FelicaSystemArray_clear(data->systems); -} \ No newline at end of file +}