|
@@ -30,12 +30,32 @@ static void nfc_generate_mf_classic_uid(uint8_t* uid, uint8_t length) {
|
|
|
furi_hal_random_fill_buf(&uid[1], length - 1);
|
|
furi_hal_random_fill_buf(&uid[1], length - 1);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-static void nfc_generate_mf_classic_block_0(uint8_t* block, uint8_t uid_len) {
|
|
|
|
|
|
|
+static void nfc_generate_mf_classic_block_0(
|
|
|
|
|
+ uint8_t* block,
|
|
|
|
|
+ uint8_t uid_len,
|
|
|
|
|
+ uint8_t sak,
|
|
|
|
|
+ uint8_t atqa0,
|
|
|
|
|
+ uint8_t atqa1) {
|
|
|
// Block length is always 16 bytes, and the UID can be either 4 or 7 bytes
|
|
// Block length is always 16 bytes, and the UID can be either 4 or 7 bytes
|
|
|
furi_assert(uid_len == 4 || uid_len == 7);
|
|
furi_assert(uid_len == 4 || uid_len == 7);
|
|
|
furi_assert(block);
|
|
furi_assert(block);
|
|
|
- nfc_generate_mf_classic_uid(block, uid_len);
|
|
|
|
|
- for(int i = uid_len; i < 16; i++) {
|
|
|
|
|
|
|
+
|
|
|
|
|
+ if(uid_len == 4) {
|
|
|
|
|
+ // Calculate BCC
|
|
|
|
|
+ block[uid_len] = 0;
|
|
|
|
|
+
|
|
|
|
|
+ for(int i = 0; i < uid_len; i++) {
|
|
|
|
|
+ block[uid_len] ^= block[i];
|
|
|
|
|
+ }
|
|
|
|
|
+ } else {
|
|
|
|
|
+ uid_len -= 1;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ block[uid_len + 1] = sak;
|
|
|
|
|
+ block[uid_len + 2] = atqa0;
|
|
|
|
|
+ block[uid_len + 3] = atqa1;
|
|
|
|
|
+
|
|
|
|
|
+ for(int i = uid_len + 4; i < 16; i++) {
|
|
|
block[i] = 0xFF;
|
|
block[i] = 0xFF;
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
@@ -74,7 +94,6 @@ static void
|
|
|
data->nfc_data.type = FuriHalNfcTypeA;
|
|
data->nfc_data.type = FuriHalNfcTypeA;
|
|
|
data->nfc_data.interface = FuriHalNfcInterfaceRf;
|
|
data->nfc_data.interface = FuriHalNfcInterfaceRf;
|
|
|
data->nfc_data.uid_len = uid_len;
|
|
data->nfc_data.uid_len = uid_len;
|
|
|
- nfc_generate_mf_classic_block_0(data->mf_classic_data.block[0].value, uid_len);
|
|
|
|
|
data->nfc_data.atqa[0] = 0x44;
|
|
data->nfc_data.atqa[0] = 0x44;
|
|
|
data->nfc_data.atqa[1] = 0x00;
|
|
data->nfc_data.atqa[1] = 0x00;
|
|
|
data->nfc_data.sak = 0x08;
|
|
data->nfc_data.sak = 0x08;
|
|
@@ -316,6 +335,7 @@ static void nfc_generate_ntag_i2c_plus_2k(NfcDeviceData* data) {
|
|
|
|
|
|
|
|
void nfc_generate_mf_classic(NfcDeviceData* data, uint8_t uid_len, MfClassicType type) {
|
|
void nfc_generate_mf_classic(NfcDeviceData* data, uint8_t uid_len, MfClassicType type) {
|
|
|
nfc_generate_common_start(data);
|
|
nfc_generate_common_start(data);
|
|
|
|
|
+ nfc_generate_mf_classic_uid(data->mf_classic_data.block[0].value, uid_len);
|
|
|
nfc_generate_mf_classic_common(data, uid_len, type);
|
|
nfc_generate_mf_classic_common(data, uid_len, type);
|
|
|
|
|
|
|
|
// Set the UID
|
|
// Set the UID
|
|
@@ -339,7 +359,6 @@ void nfc_generate_mf_classic(NfcDeviceData* data, uint8_t uid_len, MfClassicType
|
|
|
}
|
|
}
|
|
|
// Set SAK to 18
|
|
// Set SAK to 18
|
|
|
data->nfc_data.sak = 0x18;
|
|
data->nfc_data.sak = 0x18;
|
|
|
-
|
|
|
|
|
} else if(type == MfClassicType1k) {
|
|
} else if(type == MfClassicType1k) {
|
|
|
// Set every block to 0xFF
|
|
// Set every block to 0xFF
|
|
|
for(uint16_t i = 1; i < MF_CLASSIC_1K_TOTAL_SECTORS_NUM * 4; i += 1) {
|
|
for(uint16_t i = 1; i < MF_CLASSIC_1K_TOTAL_SECTORS_NUM * 4; i += 1) {
|
|
@@ -366,6 +385,13 @@ void nfc_generate_mf_classic(NfcDeviceData* data, uint8_t uid_len, MfClassicType
|
|
|
data->nfc_data.sak = 0x09;
|
|
data->nfc_data.sak = 0x09;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ nfc_generate_mf_classic_block_0(
|
|
|
|
|
+ data->mf_classic_data.block[0].value,
|
|
|
|
|
+ uid_len,
|
|
|
|
|
+ data->nfc_data.sak,
|
|
|
|
|
+ data->nfc_data.atqa[0],
|
|
|
|
|
+ data->nfc_data.atqa[1]);
|
|
|
|
|
+
|
|
|
mfc->type = type;
|
|
mfc->type = type;
|
|
|
}
|
|
}
|
|
|
|
|
|