mirror of
https://github.com/DarkFlippers/unleashed-firmware.git
synced 2025-12-12 20:49:49 +04:00
Merge pull request #898 from mishamyte/feature/ul-c-try-auth-with-default-pass
[NFC]: Ultralight C. Attempt of authentication with default key
This commit is contained in:
@@ -445,43 +445,35 @@ static NfcCommand mf_ultralight_poller_handler_auth(MfUltralightPoller* instance
|
|||||||
static NfcCommand mf_ultralight_poller_handler_auth_ultralight_c(MfUltralightPoller* instance) {
|
static NfcCommand mf_ultralight_poller_handler_auth_ultralight_c(MfUltralightPoller* instance) {
|
||||||
NfcCommand command = NfcCommandContinue;
|
NfcCommand command = NfcCommandContinue;
|
||||||
FURI_LOG_D(TAG, "MfulC auth");
|
FURI_LOG_D(TAG, "MfulC auth");
|
||||||
if(mf_ultralight_support_feature(
|
|
||||||
instance->feature_set, MfUltralightFeatureSupportAuthenticate)) {
|
|
||||||
instance->mfu_event.type = MfUltralightPollerEventTypeAuthRequest;
|
|
||||||
|
|
||||||
command = instance->callback(instance->general_event, instance->context);
|
do {
|
||||||
if(!instance->mfu_event.data->auth_context.skip_auth) {
|
if(mf_ultralight_support_feature(
|
||||||
FURI_LOG_D(TAG, "Trying to authenticate with 3des key");
|
instance->feature_set, MfUltralightFeatureSupportAuthenticate)) {
|
||||||
instance->auth_context.tdes_key = instance->mfu_event.data->auth_context.tdes_key;
|
instance->mfu_event.type = MfUltralightPollerEventTypeAuthRequest;
|
||||||
do {
|
|
||||||
uint8_t output[MF_ULTRALIGHT_C_AUTH_DATA_SIZE];
|
|
||||||
uint8_t RndA[MF_ULTRALIGHT_C_AUTH_RND_BLOCK_SIZE] = {0};
|
|
||||||
furi_hal_random_fill_buf(RndA, sizeof(RndA));
|
|
||||||
instance->error = mf_ultralight_poller_authenticate_start(instance, RndA, output);
|
|
||||||
if(instance->error != MfUltralightErrorNone) break;
|
|
||||||
|
|
||||||
uint8_t decoded_shifted_RndA[MF_ULTRALIGHT_C_AUTH_RND_BLOCK_SIZE] = {0};
|
command = instance->callback(instance->general_event, instance->context);
|
||||||
const uint8_t* RndB = output + MF_ULTRALIGHT_C_AUTH_RND_B_BLOCK_OFFSET;
|
if(!instance->mfu_event.data->auth_context.skip_auth) {
|
||||||
instance->error = mf_ultralight_poller_authenticate_end(
|
FURI_LOG_D(TAG, "Trying to authenticate with 3des key");
|
||||||
instance, RndB, output, decoded_shifted_RndA);
|
instance->auth_context.tdes_key = instance->mfu_event.data->auth_context.tdes_key;
|
||||||
if(instance->error != MfUltralightErrorNone) break;
|
instance->error =
|
||||||
|
mf_ultralight_poller_auth_tdes(instance, &instance->auth_context);
|
||||||
|
|
||||||
mf_ultralight_3des_shift_data(RndA);
|
if(instance->error == MfUltralightErrorNone &&
|
||||||
instance->auth_context.auth_success =
|
instance->auth_context.auth_success) {
|
||||||
(memcmp(RndA, decoded_shifted_RndA, sizeof(decoded_shifted_RndA)) == 0);
|
|
||||||
|
|
||||||
if(instance->auth_context.auth_success) {
|
|
||||||
FURI_LOG_D(TAG, "Auth success");
|
FURI_LOG_D(TAG, "Auth success");
|
||||||
|
} else {
|
||||||
|
FURI_LOG_D(TAG, "Auth failed");
|
||||||
|
iso14443_3a_poller_halt(instance->iso14443_3a_poller);
|
||||||
}
|
}
|
||||||
} while(false);
|
} else {
|
||||||
|
// We assume here that it is card read without explicitly provided key
|
||||||
if(instance->error != MfUltralightErrorNone || !instance->auth_context.auth_success) {
|
// So we try to auth with default one
|
||||||
FURI_LOG_D(TAG, "Auth failed");
|
instance->state = MfUltralightPollerStateTryDefaultMfulCKey;
|
||||||
iso14443_3a_poller_halt(instance->iso14443_3a_poller);
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
instance->state = MfUltralightPollerStateReadPages;
|
||||||
instance->state = MfUltralightPollerStateReadPages;
|
} while(false);
|
||||||
|
|
||||||
return command;
|
return command;
|
||||||
}
|
}
|
||||||
@@ -578,6 +570,40 @@ static NfcCommand mf_ultralight_poller_handler_try_default_pass(MfUltralightPoll
|
|||||||
return NfcCommandContinue;
|
return NfcCommandContinue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static NfcCommand
|
||||||
|
mf_ultralight_poller_handler_try_default_ultralight_c_key(MfUltralightPoller* instance) {
|
||||||
|
do {
|
||||||
|
if(!mf_ultralight_support_feature(
|
||||||
|
instance->feature_set, MfUltralightFeatureSupportAuthenticate)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(instance->auth_context.auth_success) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
FURI_LOG_D(TAG, "Trying authentication with default 3DES key");
|
||||||
|
|
||||||
|
memcpy(
|
||||||
|
&instance->auth_context.tdes_key.data,
|
||||||
|
MF_ULTRALIGHT_C_DEFAULT_KEY,
|
||||||
|
MF_ULTRALIGHT_C_AUTH_DES_KEY_SIZE);
|
||||||
|
|
||||||
|
instance->error = mf_ultralight_poller_auth_tdes(instance, &instance->auth_context);
|
||||||
|
|
||||||
|
if(instance->error == MfUltralightErrorNone && instance->auth_context.auth_success) {
|
||||||
|
FURI_LOG_D(TAG, "Default 3DES key detected");
|
||||||
|
} else {
|
||||||
|
FURI_LOG_D(TAG, "Authentication attempt with default 3DES key failed");
|
||||||
|
iso14443_3a_poller_halt(instance->iso14443_3a_poller);
|
||||||
|
}
|
||||||
|
|
||||||
|
} while(false);
|
||||||
|
|
||||||
|
instance->state = MfUltralightPollerStateReadPages;
|
||||||
|
return NfcCommandContinue;
|
||||||
|
}
|
||||||
|
|
||||||
static NfcCommand
|
static NfcCommand
|
||||||
mf_ultralight_poller_handler_check_mfuc_auth_status(MfUltralightPoller* instance) {
|
mf_ultralight_poller_handler_check_mfuc_auth_status(MfUltralightPoller* instance) {
|
||||||
instance->state = MfUltralightPollerStateReadSuccess;
|
instance->state = MfUltralightPollerStateReadSuccess;
|
||||||
@@ -742,6 +768,8 @@ static const MfUltralightPollerReadHandler
|
|||||||
mf_ultralight_poller_handler_read_tearing_flags,
|
mf_ultralight_poller_handler_read_tearing_flags,
|
||||||
[MfUltralightPollerStateAuth] = mf_ultralight_poller_handler_auth,
|
[MfUltralightPollerStateAuth] = mf_ultralight_poller_handler_auth,
|
||||||
[MfUltralightPollerStateTryDefaultPass] = mf_ultralight_poller_handler_try_default_pass,
|
[MfUltralightPollerStateTryDefaultPass] = mf_ultralight_poller_handler_try_default_pass,
|
||||||
|
[MfUltralightPollerStateTryDefaultMfulCKey] =
|
||||||
|
mf_ultralight_poller_handler_try_default_ultralight_c_key,
|
||||||
[MfUltralightPollerStateCheckMfulCAuthStatus] =
|
[MfUltralightPollerStateCheckMfulCAuthStatus] =
|
||||||
mf_ultralight_poller_handler_check_mfuc_auth_status,
|
mf_ultralight_poller_handler_check_mfuc_auth_status,
|
||||||
[MfUltralightPollerStateAuthMfulC] = mf_ultralight_poller_handler_auth_ultralight_c,
|
[MfUltralightPollerStateAuthMfulC] = mf_ultralight_poller_handler_auth_ultralight_c,
|
||||||
|
|||||||
@@ -81,6 +81,19 @@ MfUltralightError mf_ultralight_poller_auth_pwd(
|
|||||||
MfUltralightPoller* instance,
|
MfUltralightPoller* instance,
|
||||||
MfUltralightPollerAuthContext* data);
|
MfUltralightPollerAuthContext* data);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Perform 3DES authentication with key.
|
||||||
|
*
|
||||||
|
* Must ONLY be used inside the callback function.
|
||||||
|
*
|
||||||
|
* @param[in, out] instance pointer to the instance to be used in the transaction.
|
||||||
|
* @param[in, out] data pointer to the authentication context.
|
||||||
|
* @return MfUltralightErrorNone on success, an error code on failure.
|
||||||
|
*/
|
||||||
|
MfUltralightError mf_ultralight_poller_auth_tdes(
|
||||||
|
MfUltralightPoller* instance,
|
||||||
|
MfUltralightPollerAuthContext* data);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Start authentication procedure.
|
* @brief Start authentication procedure.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
#include "mf_ultralight_poller_i.h"
|
#include "mf_ultralight_poller_i.h"
|
||||||
|
|
||||||
#include <furi.h>
|
#include <furi.h>
|
||||||
|
#include <furi_hal.h>
|
||||||
|
|
||||||
#define TAG "MfUltralightPoller"
|
#define TAG "MfUltralightPoller"
|
||||||
|
|
||||||
@@ -62,6 +63,38 @@ MfUltralightError mf_ultralight_poller_auth_pwd(
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MfUltralightError mf_ultralight_poller_auth_tdes(
|
||||||
|
MfUltralightPoller* instance,
|
||||||
|
MfUltralightPollerAuthContext* data) {
|
||||||
|
furi_check(instance);
|
||||||
|
furi_check(data);
|
||||||
|
|
||||||
|
MfUltralightError ret = MfUltralightErrorNone;
|
||||||
|
|
||||||
|
uint8_t output[MF_ULTRALIGHT_C_AUTH_DATA_SIZE];
|
||||||
|
uint8_t RndA[MF_ULTRALIGHT_C_AUTH_RND_BLOCK_SIZE] = {0};
|
||||||
|
furi_hal_random_fill_buf(RndA, sizeof(RndA));
|
||||||
|
|
||||||
|
ret = mf_ultralight_poller_authenticate_start(instance, RndA, output);
|
||||||
|
|
||||||
|
if(ret != MfUltralightErrorNone) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t decoded_shifted_RndA[MF_ULTRALIGHT_C_AUTH_RND_BLOCK_SIZE] = {0};
|
||||||
|
const uint8_t* RndB = output + MF_ULTRALIGHT_C_AUTH_RND_B_BLOCK_OFFSET;
|
||||||
|
ret = mf_ultralight_poller_authenticate_end(instance, RndB, output, decoded_shifted_RndA);
|
||||||
|
|
||||||
|
if(ret != MfUltralightErrorNone) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
mf_ultralight_3des_shift_data(RndA);
|
||||||
|
data->auth_success = (memcmp(RndA, decoded_shifted_RndA, sizeof(decoded_shifted_RndA)) == 0);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
static MfUltralightError mf_ultralight_poller_send_authenticate_cmd(
|
static MfUltralightError mf_ultralight_poller_send_authenticate_cmd(
|
||||||
MfUltralightPoller* instance,
|
MfUltralightPoller* instance,
|
||||||
const uint8_t* cmd,
|
const uint8_t* cmd,
|
||||||
@@ -134,7 +167,7 @@ MfUltralightError mf_ultralight_poller_authenticate_start(
|
|||||||
uint8_t* RndB = output + MF_ULTRALIGHT_C_AUTH_RND_B_BLOCK_OFFSET;
|
uint8_t* RndB = output + MF_ULTRALIGHT_C_AUTH_RND_B_BLOCK_OFFSET;
|
||||||
mf_ultralight_3des_decrypt(
|
mf_ultralight_3des_decrypt(
|
||||||
&instance->des_context,
|
&instance->des_context,
|
||||||
instance->mfu_event.data->auth_context.tdes_key.data,
|
instance->auth_context.tdes_key.data,
|
||||||
iv,
|
iv,
|
||||||
encRndB,
|
encRndB,
|
||||||
sizeof(encRndB),
|
sizeof(encRndB),
|
||||||
@@ -145,7 +178,7 @@ MfUltralightError mf_ultralight_poller_authenticate_start(
|
|||||||
|
|
||||||
mf_ultralight_3des_encrypt(
|
mf_ultralight_3des_encrypt(
|
||||||
&instance->des_context,
|
&instance->des_context,
|
||||||
instance->mfu_event.data->auth_context.tdes_key.data,
|
instance->auth_context.tdes_key.data,
|
||||||
encRndB,
|
encRndB,
|
||||||
output,
|
output,
|
||||||
MF_ULTRALIGHT_C_AUTH_DATA_SIZE,
|
MF_ULTRALIGHT_C_AUTH_DATA_SIZE,
|
||||||
@@ -179,7 +212,7 @@ MfUltralightError mf_ultralight_poller_authenticate_end(
|
|||||||
|
|
||||||
mf_ultralight_3des_decrypt(
|
mf_ultralight_3des_decrypt(
|
||||||
&instance->des_context,
|
&instance->des_context,
|
||||||
instance->mfu_event.data->auth_context.tdes_key.data,
|
instance->auth_context.tdes_key.data,
|
||||||
RndB,
|
RndB,
|
||||||
bit_buffer_get_data(instance->rx_buffer) + 1,
|
bit_buffer_get_data(instance->rx_buffer) + 1,
|
||||||
MF_ULTRALIGHT_C_AUTH_RND_BLOCK_SIZE,
|
MF_ULTRALIGHT_C_AUTH_RND_BLOCK_SIZE,
|
||||||
|
|||||||
@@ -59,6 +59,7 @@ typedef enum {
|
|||||||
MfUltralightPollerStateAuthMfulC,
|
MfUltralightPollerStateAuthMfulC,
|
||||||
MfUltralightPollerStateReadPages,
|
MfUltralightPollerStateReadPages,
|
||||||
MfUltralightPollerStateTryDefaultPass,
|
MfUltralightPollerStateTryDefaultPass,
|
||||||
|
MfUltralightPollerStateTryDefaultMfulCKey,
|
||||||
MfUltralightPollerStateCheckMfulCAuthStatus,
|
MfUltralightPollerStateCheckMfulCAuthStatus,
|
||||||
MfUltralightPollerStateReadFailed,
|
MfUltralightPollerStateReadFailed,
|
||||||
MfUltralightPollerStateReadSuccess,
|
MfUltralightPollerStateReadSuccess,
|
||||||
|
|||||||
@@ -2741,6 +2741,7 @@ Function,+,mf_ultralight_is_equal,_Bool,"const MfUltralightData*, const MfUltral
|
|||||||
Function,+,mf_ultralight_is_page_pwd_or_pack,_Bool,"MfUltralightType, uint16_t"
|
Function,+,mf_ultralight_is_page_pwd_or_pack,_Bool,"MfUltralightType, uint16_t"
|
||||||
Function,+,mf_ultralight_load,_Bool,"MfUltralightData*, FlipperFormat*, uint32_t"
|
Function,+,mf_ultralight_load,_Bool,"MfUltralightData*, FlipperFormat*, uint32_t"
|
||||||
Function,+,mf_ultralight_poller_auth_pwd,MfUltralightError,"MfUltralightPoller*, MfUltralightPollerAuthContext*"
|
Function,+,mf_ultralight_poller_auth_pwd,MfUltralightError,"MfUltralightPoller*, MfUltralightPollerAuthContext*"
|
||||||
|
Function,+,mf_ultralight_poller_auth_tdes,MfUltralightError,"MfUltralightPoller*, MfUltralightPollerAuthContext*"
|
||||||
Function,+,mf_ultralight_poller_authenticate_end,MfUltralightError,"MfUltralightPoller*, const uint8_t*, const uint8_t*, uint8_t*"
|
Function,+,mf_ultralight_poller_authenticate_end,MfUltralightError,"MfUltralightPoller*, const uint8_t*, const uint8_t*, uint8_t*"
|
||||||
Function,+,mf_ultralight_poller_authenticate_start,MfUltralightError,"MfUltralightPoller*, const uint8_t*, uint8_t*"
|
Function,+,mf_ultralight_poller_authenticate_start,MfUltralightError,"MfUltralightPoller*, const uint8_t*, uint8_t*"
|
||||||
Function,+,mf_ultralight_poller_read_counter,MfUltralightError,"MfUltralightPoller*, uint8_t, MfUltralightCounter*"
|
Function,+,mf_ultralight_poller_read_counter,MfUltralightError,"MfUltralightPoller*, uint8_t, MfUltralightCounter*"
|
||||||
|
|||||||
|
Reference in New Issue
Block a user