mirror of
https://github.com/Next-Flip/Momentum-Firmware.git
synced 2026-05-20 04:54:45 -07:00
[FL-3835] Ultralight C authentication with des key (#3720)
* Update api_symbols.csv * Ultralight C 3des implementation added * Access check for Ultralight cards is now splitted into 2 functions one for ULC card and another for common * Ultralight C authentication command handlers added * Update api_symbols.csv and api_symbols.csv * Length added to ultralight encrypt function * New structure for storing 3des key added * Reseting of 3des_key added * des_context init/deinit added to poller * New poller step for ultralight c auth added * Added ultralight c des key to application * Renamed felica unlock scenes to more generic des auth scenes, because they are now used also for ultralight c * Show different menus for different ultralight card types * Update api_symbols.csv and api_symbols.csv * Some macro defines added * Different amount of pages will be now read for ultralight C and others * New unit test for ultralight C * Some comments and macro replacements * New function added to api * Now all data read checks mfulC separately * Adjusted listener to handle missing 3des_key properly * Now poller populates 3des_key after reading with auth to card data * Nfc: rename _3des_key to tdes_key * Bump API Symbols * Mute PVS Warnings Co-authored-by: hedger <hedger@users.noreply.github.com> Co-authored-by: gornekich <n.gorbadey@gmail.com> Co-authored-by: Aleksandr Kutuzov <alleteam@gmail.com>
This commit is contained in:
@@ -624,15 +624,19 @@ bool mf_ultralight_is_all_data_read(const MfUltralightData* data) {
|
||||
furi_check(data);
|
||||
|
||||
bool all_read = false;
|
||||
if(data->pages_read == data->pages_total ||
|
||||
(data->type == MfUltralightTypeMfulC && data->pages_read == data->pages_total - 4)) {
|
||||
// Having read all the pages doesn't mean that we've got everything.
|
||||
// By default PWD is 0xFFFFFFFF, but if read back it is always 0x00000000,
|
||||
// so a default read on an auth-supported NTAG is never complete.
|
||||
|
||||
if(data->pages_read == data->pages_total) {
|
||||
uint32_t feature_set = mf_ultralight_get_feature_support_set(data->type);
|
||||
if(!mf_ultralight_support_feature(feature_set, MfUltralightFeatureSupportPasswordAuth)) {
|
||||
if((data->type == MfUltralightTypeMfulC) &&
|
||||
mf_ultralight_support_feature(feature_set, MfUltralightFeatureSupportAuthenticate)) {
|
||||
all_read = true;
|
||||
} else if(!mf_ultralight_support_feature(
|
||||
feature_set, MfUltralightFeatureSupportPasswordAuth)) {
|
||||
all_read = true;
|
||||
} else {
|
||||
// Having read all the pages doesn't mean that we've got everything.
|
||||
// By default PWD is 0xFFFFFFFF, but if read back it is always 0x00000000,
|
||||
// so a default read on an auth-supported NTAG is never complete.
|
||||
MfUltralightConfigPages* config = NULL;
|
||||
if(mf_ultralight_get_config_page(data, &config)) {
|
||||
uint32_t pass = bit_lib_bytes_to_num_be(
|
||||
@@ -669,3 +673,61 @@ bool mf_ultralight_is_counter_configured(const MfUltralightData* data) {
|
||||
|
||||
return configured;
|
||||
}
|
||||
|
||||
void mf_ultralight_3des_shift_data(uint8_t* const data) {
|
||||
furi_check(data);
|
||||
|
||||
uint8_t buf = data[0];
|
||||
for(uint8_t i = 1; i < MF_ULTRALIGHT_C_AUTH_RND_BLOCK_SIZE; i++) {
|
||||
data[i - 1] = data[i];
|
||||
}
|
||||
data[MF_ULTRALIGHT_C_AUTH_RND_BLOCK_SIZE - 1] = buf;
|
||||
}
|
||||
|
||||
bool mf_ultralight_3des_key_valid(const MfUltralightData* data) {
|
||||
furi_check(data);
|
||||
furi_check(data->type == MfUltralightTypeMfulC);
|
||||
|
||||
return !(data->pages_read == data->pages_total - 4);
|
||||
}
|
||||
|
||||
const uint8_t* mf_ultralight_3des_get_key(const MfUltralightData* data) {
|
||||
furi_check(data);
|
||||
furi_check(data->type == MfUltralightTypeMfulC);
|
||||
|
||||
return data->page[44].data;
|
||||
}
|
||||
|
||||
void mf_ultralight_3des_encrypt(
|
||||
mbedtls_des3_context* ctx,
|
||||
const uint8_t* ck,
|
||||
const uint8_t* iv,
|
||||
const uint8_t* input,
|
||||
const uint8_t length,
|
||||
uint8_t* out) {
|
||||
furi_check(ctx);
|
||||
furi_check(ck);
|
||||
furi_check(iv);
|
||||
furi_check(input);
|
||||
furi_check(out);
|
||||
|
||||
mbedtls_des3_set2key_enc(ctx, ck);
|
||||
mbedtls_des3_crypt_cbc(ctx, MBEDTLS_DES_ENCRYPT, length, (uint8_t*)iv, input, out);
|
||||
}
|
||||
|
||||
void mf_ultralight_3des_decrypt(
|
||||
mbedtls_des3_context* ctx,
|
||||
const uint8_t* ck,
|
||||
const uint8_t* iv,
|
||||
const uint8_t* input,
|
||||
const uint8_t length,
|
||||
uint8_t* out) {
|
||||
furi_check(ctx);
|
||||
furi_check(ck);
|
||||
furi_check(iv);
|
||||
furi_check(input);
|
||||
furi_check(out);
|
||||
|
||||
mbedtls_des3_set2key_dec(ctx, ck);
|
||||
mbedtls_des3_crypt_cbc(ctx, MBEDTLS_DES_DECRYPT, length, (uint8_t*)iv, input, out);
|
||||
}
|
||||
Reference in New Issue
Block a user