-
Notifications
You must be signed in to change notification settings - Fork 62
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
NFC Magic: New functions for Gen4 cards (DW to block 0/shadow mode) (#98
- Loading branch information
1 parent
6664fe9
commit 922a87c
Showing
28 changed files
with
1,188 additions
and
358 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,120 @@ | ||
#include "gen4.h" | ||
#include "core/check.h" | ||
|
||
Gen4* gen4_alloc() { | ||
Gen4* instance = malloc(sizeof(Gen4)); | ||
|
||
return instance; | ||
} | ||
|
||
void gen4_free(Gen4* instance) { | ||
furi_check(instance); | ||
|
||
free(instance); | ||
} | ||
|
||
void gen4_reset(Gen4* instance) { | ||
furi_check(instance); | ||
|
||
memset(&instance->config, 0, sizeof(Gen4Config)); | ||
memset(&instance->revision, 0, sizeof(Gen4Revision)); | ||
} | ||
|
||
void gen4_copy(Gen4* dest, const Gen4* source) { | ||
furi_check(dest); | ||
furi_check(source); | ||
|
||
memcpy(dest, source, sizeof(Gen4)); | ||
} | ||
|
||
bool gen4_password_is_set(const Gen4Password* instance) { | ||
furi_check(instance); | ||
|
||
return (instance->bytes[0] || instance->bytes[1] || instance->bytes[2] || instance->bytes[3]); | ||
} | ||
|
||
void gen4_password_reset(Gen4Password* instance) { | ||
furi_check(instance); | ||
|
||
memset(instance->bytes, 0, GEN4_PASSWORD_LEN); | ||
} | ||
|
||
void gen4_password_copy(Gen4Password* dest, const Gen4Password* source) { | ||
furi_check(dest); | ||
furi_check(source); | ||
|
||
memcpy(dest->bytes, source->bytes, GEN4_PASSWORD_LEN); | ||
} | ||
|
||
const char* gen4_get_shadow_mode_name(Gen4ShadowMode mode) { | ||
switch(mode) { | ||
case Gen4ShadowModePreWrite: | ||
return "Pre-Write"; | ||
case Gen4ShadowModeRestore: | ||
return "Restore"; | ||
case Gen4ShadowModeDisabled: | ||
return "Disabled"; | ||
case Gen4ShadowModeHighSpeedDisabled: | ||
return "Disabled (High-speed)"; | ||
case Gen4ShadowModeSplit: | ||
return "Split"; | ||
default: | ||
return "Unknown"; | ||
} | ||
} | ||
|
||
const char* gen4_get_direct_write_mode_name(Gen4DirectWriteBlock0Mode mode) { | ||
switch(mode) { | ||
case Gen4DirectWriteBlock0ModeEnabled: | ||
return "Enabled"; | ||
case Gen4DirectWriteBlock0ModeDisabled: | ||
return "Disabled"; | ||
case Gen4DirectWriteBlock0ModeDefault: | ||
return "Default"; | ||
default: | ||
return "Unknown"; | ||
} | ||
} | ||
|
||
const char* gen4_get_uid_len_num(Gen4UIDLength code) { | ||
switch(code) { | ||
case Gen4UIDLengthSingle: | ||
return "4"; | ||
case Gen4UIDLengthDouble: | ||
return "7"; | ||
case Gen4UIDLengthTriple: | ||
return "10"; | ||
default: | ||
return "Unknown"; | ||
} | ||
} | ||
|
||
const char* gen4_get_configuration_name(const Gen4Config* config) { | ||
switch(config->data_parsed.protocol) { | ||
case Gen4ProtocolMfClassic: { | ||
switch(config->data_parsed.total_blocks) { | ||
case 255: | ||
return "MIFARE Classic 4K"; | ||
case 63: | ||
return "MIFARE Classic 1K"; | ||
case 19: | ||
return "MIFARE Classic Mini (0.3K)"; | ||
default: | ||
return "Unknown"; | ||
} | ||
} break; | ||
case Gen4ProtocolMfUltralight: { | ||
switch(config->data_parsed.total_blocks) { | ||
case 63: | ||
return "MIFARE Ultralight"; | ||
case 127: | ||
return "NTAG 2XX"; | ||
default: | ||
return "Unknown"; | ||
} | ||
} break; | ||
default: | ||
return "Unknown"; | ||
break; | ||
}; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,105 @@ | ||
#pragma once | ||
|
||
#include "core/common_defines.h" | ||
#include <stdint.h> | ||
|
||
#define GEN4_CONFIG_SIZE (32) | ||
#define GEN4_REVISION_SIZE (5) | ||
|
||
#define GEN4_PASSWORD_LEN (4) | ||
#define GEN4_ATS_MAX_LEN (16) | ||
#define GEN4_ATQA_LEN (2) | ||
#define GEN4_CRC_LEN (2) | ||
|
||
typedef enum { | ||
Gen4ProtocolMfClassic = 0x00, | ||
Gen4ProtocolMfUltralight = 0x01, | ||
} Gen4Protocol; | ||
|
||
typedef struct { | ||
uint8_t bytes[GEN4_PASSWORD_LEN]; | ||
} Gen4Password; | ||
|
||
typedef enum { | ||
Gen4UIDLengthSingle = 0x00, | ||
Gen4UIDLengthDouble = 0x01, | ||
Gen4UIDLengthTriple = 0x02 | ||
} Gen4UIDLength; | ||
|
||
typedef enum { | ||
Gen4UltralightModeUL_EV1 = 0x00, | ||
Gen4UltralightModeNTAG = 0x01, | ||
Gen4UltralightModeUL_C = 0x02, | ||
Gen4UltralightModeUL = 0x03 | ||
} Gen4UltralightMode; | ||
|
||
typedef enum { | ||
// for writing original (shadow) data | ||
Gen4ShadowModePreWrite = 0x00, | ||
// written data can be read once before restored to original | ||
Gen4ShadowModeRestore = 0x01, | ||
// shadow mode disabled | ||
Gen4ShadowModeDisabled = 0x02, | ||
// apparently for UL? | ||
Gen4ShadowModeHighSpeedDisabled = 0x03, | ||
// work with new UMC. With old UMC is untested | ||
Gen4ShadowModeSplit = 0x04, | ||
} Gen4ShadowMode; | ||
|
||
typedef enum { | ||
// gen2 card behavour | ||
Gen4DirectWriteBlock0ModeEnabled = 0x00, | ||
// common card behavour | ||
Gen4DirectWriteBlock0ModeDisabled = 0x01, | ||
// default mode. same behavour as Gen4DirectWriteBlock0ModeActivate | ||
Gen4DirectWriteBlock0ModeDefault = 0x02, | ||
} Gen4DirectWriteBlock0Mode; | ||
|
||
typedef union { | ||
uint8_t data_raw[GEN4_CONFIG_SIZE]; | ||
struct { | ||
Gen4Protocol protocol; | ||
Gen4UIDLength uid_len_code; | ||
Gen4Password password; | ||
Gen4ShadowMode gtu_mode; | ||
uint8_t ats_len; | ||
uint8_t ats[GEN4_ATS_MAX_LEN]; // mb another class? | ||
uint8_t atqa[GEN4_ATQA_LEN]; | ||
uint8_t sak; | ||
Gen4UltralightMode mfu_mode; | ||
uint8_t total_blocks; | ||
Gen4DirectWriteBlock0Mode direct_write_mode; | ||
uint8_t crc[GEN4_CRC_LEN]; | ||
} FURI_PACKED data_parsed; | ||
} Gen4Config; | ||
|
||
typedef struct { | ||
uint8_t data[GEN4_REVISION_SIZE]; | ||
} Gen4Revision; | ||
|
||
typedef struct { | ||
Gen4Config config; | ||
Gen4Revision revision; | ||
} Gen4; | ||
|
||
Gen4* gen4_alloc(); | ||
|
||
void gen4_free(Gen4* instance); | ||
|
||
void gen4_reset(Gen4* instance); | ||
|
||
void gen4_copy(Gen4* dest, const Gen4* source); | ||
|
||
bool gen4_password_is_set(const Gen4Password* instance); | ||
|
||
void gen4_password_reset(Gen4Password* instance); | ||
|
||
void gen4_password_copy(Gen4Password* dest, const Gen4Password* source); | ||
|
||
const char* gen4_get_shadow_mode_name(Gen4ShadowMode mode); | ||
|
||
const char* gen4_get_direct_write_mode_name(Gen4DirectWriteBlock0Mode mode); | ||
|
||
const char* gen4_get_uid_len_num(Gen4UIDLength code); | ||
|
||
const char* gen4_get_configuration_name(const Gen4Config* config); |
Oops, something went wrong.