mirror of
https://github.com/Next-Flip/Momentum-Firmware.git
synced 2026-04-24 03:29:57 -07:00
Merge remote-tracking branch 'ul/dev' into mntm-dev --nobuild
This commit is contained in:
@@ -105,6 +105,7 @@
|
|||||||
- Enable Asset Packs in NFC app again due to reduced RAM usage (#396 by @Willy-JL)
|
- Enable Asset Packs in NFC app again due to reduced RAM usage (#396 by @Willy-JL)
|
||||||
- Improve loading of parser plugins (by @Willy-JL)
|
- Improve loading of parser plugins (by @Willy-JL)
|
||||||
- UL: Use default UL/UL-C pwd/key as default value for key input (by @mishamyte)
|
- UL: Use default UL/UL-C pwd/key as default value for key input (by @mishamyte)
|
||||||
|
- UL: Attempt Ultralight C authentication with default key (by @mishamyte)
|
||||||
- OFW: Added naming for DESFire cards + fix MF3ICD40 cards unable to be read (by @Demae)
|
- OFW: Added naming for DESFire cards + fix MF3ICD40 cards unable to be read (by @Demae)
|
||||||
- OFW: FeliCa Protocol Expose Read Block API and Allow Specifying Service (by @zinongli)
|
- OFW: FeliCa Protocol Expose Read Block API and Allow Specifying Service (by @zinongli)
|
||||||
- OFW: Enable MFUL sync poller to be provided with passwords (by @GMMan)
|
- OFW: Enable MFUL sync poller to be provided with passwords (by @GMMan)
|
||||||
@@ -140,6 +141,7 @@
|
|||||||
- UL: Fix Hollarm protocol with more verification (by @xMasterX)
|
- UL: Fix Hollarm protocol with more verification (by @xMasterX)
|
||||||
- UL: Fix GangQi protocol (by @DoberBit and @mishamyte)
|
- UL: Fix GangQi protocol (by @DoberBit and @mishamyte)
|
||||||
- UL: Came Atomo button hold simulation with full cycle to allow proper pairing with receiver (by @xMasterX)
|
- UL: Came Atomo button hold simulation with full cycle to allow proper pairing with receiver (by @xMasterX)
|
||||||
|
- OFW: Fix sample durations when using external CC1101 (by @Aerosnail)
|
||||||
- OFW: NFC: ST25TB poller mode check (by @RebornedBrain)
|
- OFW: NFC: ST25TB poller mode check (by @RebornedBrain)
|
||||||
- OFW: RFID: Fix Detection Conflict Between Securakey and Noralsy Format (by @zinongli)
|
- OFW: RFID: Fix Detection Conflict Between Securakey and Noralsy Format (by @zinongli)
|
||||||
- Furi:
|
- Furi:
|
||||||
|
|||||||
@@ -644,11 +644,13 @@ void subghz_device_cc1101_ext_start_async_rx(
|
|||||||
furi_hal_bus_enable(FuriHalBusTIM17);
|
furi_hal_bus_enable(FuriHalBusTIM17);
|
||||||
|
|
||||||
// Configure TIM
|
// Configure TIM
|
||||||
|
LL_TIM_InitTypeDef TIM_InitStruct = {0};
|
||||||
//Set the timer resolution to 2 us
|
//Set the timer resolution to 2 us
|
||||||
LL_TIM_SetPrescaler(TIM17, (64 << 1) - 1);
|
TIM_InitStruct.Prescaler = (64 << 1) - 1;
|
||||||
LL_TIM_SetCounterMode(TIM17, LL_TIM_COUNTERMODE_UP);
|
TIM_InitStruct.CounterMode = LL_TIM_COUNTERMODE_UP;
|
||||||
LL_TIM_SetAutoReload(TIM17, 0xFFFF);
|
TIM_InitStruct.Autoreload = 0xFFFF;
|
||||||
LL_TIM_SetClockDivision(TIM17, LL_TIM_CLOCKDIVISION_DIV1);
|
TIM_InitStruct.ClockDivision = LL_TIM_CLOCKDIVISION_DIV1;
|
||||||
|
LL_TIM_Init(TIM17, &TIM_InitStruct);
|
||||||
|
|
||||||
// Timer: advanced
|
// Timer: advanced
|
||||||
LL_TIM_SetClockSource(TIM17, LL_TIM_CLOCKSOURCE_INTERNAL);
|
LL_TIM_SetClockSource(TIM17, LL_TIM_CLOCKSOURCE_INTERNAL);
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ typedef struct {
|
|||||||
} JsGpioPinInst;
|
} JsGpioPinInst;
|
||||||
|
|
||||||
ARRAY_DEF(ManagedPinsArray, JsGpioPinInst*, M_PTR_OPLIST); //-V575
|
ARRAY_DEF(ManagedPinsArray, JsGpioPinInst*, M_PTR_OPLIST); //-V575
|
||||||
|
#define M_OPL_ManagedPinsArray_t() ARRAY_OPLIST(ManagedPinsArray)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Per-module instance control structure
|
* Per-module instance control structure
|
||||||
@@ -444,20 +445,26 @@ static void js_gpio_destroy(void* inst) {
|
|||||||
JsGpioInst* module = (JsGpioInst*)inst;
|
JsGpioInst* module = (JsGpioInst*)inst;
|
||||||
|
|
||||||
// reset pins
|
// reset pins
|
||||||
ManagedPinsArray_it_t iterator;
|
for
|
||||||
for(ManagedPinsArray_it(iterator, module->managed_pins); !ManagedPinsArray_end_p(iterator);
|
M_EACH(item, module->managed_pins, ManagedPinsArray_t) {
|
||||||
ManagedPinsArray_next(iterator)) {
|
JsGpioPinInst* manager_data = *item;
|
||||||
JsGpioPinInst* manager_data = *ManagedPinsArray_cref(iterator);
|
|
||||||
if(manager_data->had_interrupt) {
|
if(manager_data->had_interrupt) {
|
||||||
furi_hal_gpio_disable_int_callback(manager_data->pin);
|
furi_hal_gpio_disable_int_callback(manager_data->pin);
|
||||||
furi_hal_gpio_remove_int_callback(manager_data->pin);
|
furi_hal_gpio_remove_int_callback(manager_data->pin);
|
||||||
|
}
|
||||||
|
if(manager_data->pwm_output != FuriHalPwmOutputIdNone) {
|
||||||
|
if(furi_hal_pwm_is_running(manager_data->pwm_output))
|
||||||
|
furi_hal_pwm_stop(manager_data->pwm_output);
|
||||||
|
}
|
||||||
|
furi_hal_gpio_init(manager_data->pin, GpioModeAnalog, GpioPullNo, GpioSpeedLow);
|
||||||
|
|
||||||
|
furi_event_loop_maybe_unsubscribe(module->loop, manager_data->interrupt_semaphore);
|
||||||
|
furi_semaphore_free(manager_data->interrupt_semaphore);
|
||||||
|
|
||||||
|
free(manager_data->interrupt_contract);
|
||||||
|
free(manager_data);
|
||||||
}
|
}
|
||||||
furi_hal_gpio_init(manager_data->pin, GpioModeAnalog, GpioPullNo, GpioSpeedLow);
|
|
||||||
furi_event_loop_maybe_unsubscribe(module->loop, manager_data->interrupt_semaphore);
|
|
||||||
furi_semaphore_free(manager_data->interrupt_semaphore);
|
|
||||||
free(manager_data->interrupt_contract);
|
|
||||||
free(manager_data);
|
|
||||||
}
|
|
||||||
|
|
||||||
// free buffers
|
// free buffers
|
||||||
furi_hal_adc_release(module->adc_handle);
|
furi_hal_adc_release(module->adc_handle);
|
||||||
|
|||||||
@@ -75,6 +75,7 @@ Watch this video to learn more and see how different boards can be programmed (v
|
|||||||
|
|
||||||
## Doorhan
|
## Doorhan
|
||||||
|
|
||||||
|
With access to the receiver box:
|
||||||
1. Create new remote with randomly generated serial: Go to SubGHz -> Add Manually -> KL: Doorhan 433Mhz or 315Mhz depends on your receiver (find out by reading your existing remote)
|
1. Create new remote with randomly generated serial: Go to SubGHz -> Add Manually -> KL: Doorhan 433Mhz or 315Mhz depends on your receiver (find out by reading your existing remote)
|
||||||
2. Open your new remote file
|
2. Open your new remote file
|
||||||
3. Push `P` button for ~2 sec, led will start flashing
|
3. Push `P` button for ~2 sec, led will start flashing
|
||||||
@@ -82,7 +83,29 @@ Watch this video to learn more and see how different boards can be programmed (v
|
|||||||
5. Led on the receiver board will flash and turn off
|
5. Led on the receiver board will flash and turn off
|
||||||
6. Done!
|
6. Done!
|
||||||
|
|
||||||
Also you can program new remote using old remote on newer boards! See first video below:
|
|
||||||
|
With existing remote:
|
||||||
|
1. Create new remote with randomly generated serial: Go to SubGHz -> Add Manually -> KL: Doorhan 433Mhz or 315Mhz depends on your receiver (find out by reading your existing remote)
|
||||||
|
2. Open your new remote file
|
||||||
|
3. For next steps be close to the receiver board, around 1-2 meters
|
||||||
|
4. Press second button (lowest one) on the old remote, do not release second button and press 1st (upper) button, hold buttons for 1 sec and release them
|
||||||
|
5. Press working button on the old remote (the button you use for operating the receiver, aka opening the gate, etc) hold for 1 sec and release
|
||||||
|
6. Actions with old remote must be done in 5 seconds time, do not hold buttons for too long, and do not make it very fast
|
||||||
|
7. Receiver will beep, you will have 10 seconds to add new remote, now press Send on new remote on flipper two times holding for at least 1 sec
|
||||||
|
8. Receiver will beep again telling that new remote is added sucessfuly!
|
||||||
|
9. Done!
|
||||||
|
|
||||||
|
With copy of existing remote on flipper:
|
||||||
|
1. Create new remote with randomly generated serial: Go to SubGHz -> Add Manually -> KL: Doorhan 433Mhz or 315Mhz depends on your receiver (find out by reading your existing remote)
|
||||||
|
2. Open your existing remote (original) file
|
||||||
|
3. For next steps be close to the receiver board, around 1-2 meters
|
||||||
|
4. Press left button (0x8) on the flipper, hold for 1 sec and release the button and press right (0xA) button, hold button for 1 sec and release
|
||||||
|
5. Press working button on the flipper, should be center one aka Send (the button you use for operating the receiver, aka opening the gate, etc) hold for 1 sec and release
|
||||||
|
6. Actions with original remote copy must be done in 5 seconds time, do not hold buttons for too long, and do not make it very fast
|
||||||
|
7. Receiver will beep, now hold back and open new remote file, you will have 10 seconds to add new remote, press Send on new remote on flipper two times holding for at least 1 sec
|
||||||
|
8. Receiver will beep again telling that new remote is added sucessfuly!
|
||||||
|
9. Done!
|
||||||
|
|
||||||
Watch this videos to learn more (videos in Russian language): https://www.youtube.com/watch?v=wZ5121HYv50 / https://www.youtube.com/watch?v=1ucrDKF3vWc
|
Watch this videos to learn more (videos in Russian language): https://www.youtube.com/watch?v=wZ5121HYv50 / https://www.youtube.com/watch?v=1ucrDKF3vWc
|
||||||
|
|
||||||
## Somfy Telis
|
## Somfy Telis
|
||||||
@@ -124,14 +147,24 @@ How to get seed to make full clone of your remote (**will conflict with original
|
|||||||
|
|
||||||
1. Open `Read` in SubGHz on your flipper
|
1. Open `Read` in SubGHz on your flipper
|
||||||
2. (ONLY FOR ORIGINAL REMOTES) Hold all buttons on your remote at same time, example -> for 2 button remote - press them both at same time and hold OR press hidden button on back of remote with a pin or paper clip
|
2. (ONLY FOR ORIGINAL REMOTES) Hold all buttons on your remote at same time, example -> for 2 button remote - press them both at same time and hold OR press hidden button on back of remote with a pin or paper clip
|
||||||
|
For 4 buttons remote press & hold two buttons at upper row
|
||||||
3. You will receive signal on your flipper, open that signal and see `Fix:` value, it should start from `F` like `F00F1C9B`
|
3. You will receive signal on your flipper, open that signal and see `Fix:` value, it should start from `F` like `F00F1C9B`
|
||||||
4. If `Fix:` is showing first `F` see `Hop:` value -> This is your remote Seed
|
4. If `Fix:` is showing first `F` see `Hop:` value -> This is your remote Seed (except first digit `F` (this is the button code, aka programming button pressed means `F`))
|
||||||
5. Write down Hop value
|
5. Write down Hop value and replace first digit - `F` with `0`
|
||||||
6. Press button on your remote that you want to clone and receive its signal on your flipper
|
6. Press button on your remote that you want to clone and receive its signal on your flipper
|
||||||
7. Open and write down `Fix:` value where first digit will be same as your button ID `Btn:`
|
7. Open and write down `Fix:` value where first digit will be same as your button ID `Btn:`
|
||||||
8. Create new remote using BFT Mitto [Manual] - Enter FIX from step 7, enter counter `FF F9`, enter seed from step 5
|
8. Create new remote using BFT Mitto [Manual] - Enter FIX from step 7, enter counter `FF F9`, enter seed from step 5
|
||||||
9. Using counter values like `FF F9` can help bypassing current original remote counter value, and in result it also can fully desync original remote, only one remote can work at same time using this method
|
9. Using counter values like `FF F9` can help bypassing current original remote counter value, and in result it also can fully desync original remote, only one remote can work at same time using this method
|
||||||
10. Throw away your original remote since now it needs to be re-added into receiver board :C
|
10. Also you can do this: Save your signal of the original remote (will say KL: Unknown),
|
||||||
|
then copy file to the PC and edit it and insert/replace those values after the `Key: 01 23 45 67 89 AB CD EF` (your key will have different value)
|
||||||
|
```
|
||||||
|
Seed: 0X XX XX XX
|
||||||
|
Manufacture: BFT
|
||||||
|
```
|
||||||
|
Replace `X`'s with digits from your Seed that you obtained by reading two button hold at the first steps,
|
||||||
|
Save and copy that file back to the flipper
|
||||||
|
Now you will have exact clone of your remote that will have same counter, by making couple presses you will make it higher than original and receiver will work with it, but original remote will reguire same amount of presses to work again, and vice versa.
|
||||||
|
11. Also your original remote may become non working since it needs to be re-added into receiver board if you made counter much higher than original :C
|
||||||
|
|
||||||
## CAME Atomo
|
## CAME Atomo
|
||||||
|
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|||||||
@@ -2767,6 +2767,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