mirror of
https://github.com/RfidResearchGroup/ChameleonUltra.git
synced 2026-09-11 18:30:14 -07:00
SEOS emulation support
This commit is contained in:
@@ -31,6 +31,7 @@ SRC_FILES += \
|
||||
$(PROJ_DIR)/rfid/nfctag/hf/nfc_14a_4.c \
|
||||
$(PROJ_DIR)/rfid/nfctag/hf/nfc_mf1.c \
|
||||
$(PROJ_DIR)/rfid/nfctag/hf/nfc_mf0_ntag.c \
|
||||
$(PROJ_DIR)/rfid/nfctag/hf/nfc_seos.c \
|
||||
$(PROJ_DIR)/rfid/nfctag/lf/lf_tag_em.c \
|
||||
$(PROJ_DIR)/rfid/nfctag/lf/utils/fskdemod.c \
|
||||
$(PROJ_DIR)/rfid/nfctag/lf/utils/circular_buffer.c \
|
||||
|
||||
@@ -1163,6 +1163,88 @@ static data_frame_tx_t *cmd_processor_idteck_get_emu_id(uint16_t cmd, uint16_t s
|
||||
return data_frame_make(cmd, STATUS_SUCCESS, LF_IDTECK_TAG_ID_SIZE, buffer->buffer);
|
||||
}
|
||||
|
||||
static data_frame_tx_t *cmd_processor_seos_read_emu_data(uint16_t cmd, uint16_t status, uint16_t length, uint8_t *data) {
|
||||
tag_data_buffer_t *buffer = get_buffer_by_tag_type(TAG_TYPE_SEOS);
|
||||
nfc_tag_seos_information_t *info = (nfc_tag_seos_information_t *)buffer->buffer;
|
||||
|
||||
uint8_t output[1+info->diversifier_len + 1+info->oid_len + 1+info->data_tag_len + 1+info->data_len + 2];
|
||||
uint16_t offset = 0;
|
||||
|
||||
output[offset++] = info->data_len;
|
||||
memcpy(output+offset, info->data, info->data_len);
|
||||
offset += info->data_len;
|
||||
|
||||
output[offset++] = info->oid_len;
|
||||
memcpy(output+offset, info->oid, info->oid_len);
|
||||
offset += info->oid_len;
|
||||
|
||||
output[offset++] = info->data_tag_len;
|
||||
memcpy(output+offset, info->data_tag, info->data_tag_len);
|
||||
offset += info->data_tag_len;
|
||||
|
||||
output[offset++] = info->diversifier_len;
|
||||
memcpy(output+offset, info->diversifier, info->diversifier_len);
|
||||
offset += info->diversifier_len;
|
||||
|
||||
output[offset++] = info->hash_alg;
|
||||
output[offset++] = info->encr_alg;
|
||||
|
||||
return data_frame_make(cmd, STATUS_SUCCESS, sizeof(output), output);
|
||||
}
|
||||
|
||||
static data_frame_tx_t *cmd_processor_seos_write_emu_data(uint16_t cmd, uint16_t status, uint16_t length, uint8_t *data) {
|
||||
if (length < 6) {
|
||||
return data_frame_make(cmd, STATUS_PAR_ERR, 0, NULL);
|
||||
}
|
||||
tag_data_buffer_t *buffer = get_buffer_by_tag_type(TAG_TYPE_SEOS);
|
||||
nfc_tag_seos_information_t *info = (nfc_tag_seos_information_t *)buffer->buffer;
|
||||
|
||||
uint16_t offset = 0;
|
||||
|
||||
uint8_t len = data[offset++];
|
||||
if (len > NFC_TAG_SEOS_DATA_MAX) return data_frame_make(cmd, STATUS_PAR_ERR, 0, NULL);
|
||||
info->data_len = len;
|
||||
memcpy(info->data, data+offset, len);
|
||||
offset += len;
|
||||
|
||||
len = data[offset++];
|
||||
if (len > NFC_TAG_SEOS_OID_MAX) return data_frame_make(cmd, STATUS_PAR_ERR, 0, NULL);
|
||||
info->oid_len = len;
|
||||
memcpy(info->oid, data+offset, len);
|
||||
offset += len;
|
||||
|
||||
len = data[offset++];
|
||||
if (len > NFC_TAG_SEOS_DATA_TAG_MAX) return data_frame_make(cmd, STATUS_PAR_ERR, 0, NULL);
|
||||
info->data_tag_len = len;
|
||||
memcpy(info->data_tag, data+offset, len);
|
||||
offset += len;
|
||||
|
||||
len = data[offset++];
|
||||
if (len > NFC_TAG_SEOS_DIVERSIFIER_MAX) return data_frame_make(cmd, STATUS_PAR_ERR, 0, NULL);
|
||||
info->diversifier_len = len;
|
||||
memcpy(info->diversifier, data+offset, len);
|
||||
offset += len;
|
||||
|
||||
info->hash_alg = data[offset++];
|
||||
info->encr_alg = data[offset++];
|
||||
|
||||
return data_frame_make(cmd, STATUS_SUCCESS, 0, NULL);
|
||||
}
|
||||
|
||||
static data_frame_tx_t *cmd_processor_seos_write_emu_keys(uint16_t cmd, uint16_t status, uint16_t length, uint8_t *data) {
|
||||
if (length != 16 * 3) {
|
||||
return data_frame_make(cmd, STATUS_PAR_ERR, 0, NULL);
|
||||
}
|
||||
tag_data_buffer_t *buffer = get_buffer_by_tag_type(TAG_TYPE_SEOS);
|
||||
nfc_tag_seos_information_t *info = (nfc_tag_seos_information_t *)buffer->buffer;
|
||||
|
||||
memcpy(info->authkey, data+ 0, 16);
|
||||
memcpy(info->privenc, data+16, 16);
|
||||
memcpy(info->privmac, data+32, 16);
|
||||
|
||||
return data_frame_make(cmd, STATUS_SUCCESS, 0, NULL);
|
||||
}
|
||||
|
||||
#if defined(PROJECT_CHAMELEON_ULTRA)
|
||||
// T55xx clone is only available on Chameleon Ultra; the Lite firmware
|
||||
// has no LF reader hardware and does not compile the write_*_to_t55xx
|
||||
@@ -1284,6 +1366,9 @@ static nfc_tag_14a_coll_res_reference_t *get_coll_res_data(bool write) {
|
||||
case TAG_TYPE_HF14A_4:
|
||||
info = nfc_tag_14a_4_get_coll_res();
|
||||
break;
|
||||
case TAG_TYPE_SEOS:
|
||||
info = nfc_tag_seos_get_coll_res();
|
||||
break;
|
||||
default:
|
||||
// no collision resolution data for slot
|
||||
info = NULL;
|
||||
@@ -3121,6 +3206,11 @@ static cmd_data_map_t m_data_cmd_map[] = {
|
||||
{ DATA_CMD_JABLOTRON_GET_EMU_ID, NULL, cmd_processor_jablotron_get_emu_id, NULL },
|
||||
{ DATA_CMD_IDTECK_SET_EMU_ID, NULL, cmd_processor_idteck_set_emu_id, NULL },
|
||||
{ DATA_CMD_IDTECK_GET_EMU_ID, NULL, cmd_processor_idteck_get_emu_id, NULL },
|
||||
|
||||
{ DATA_CMD_SEOS_READ_EMU_DATA, NULL, cmd_processor_seos_read_emu_data, NULL },
|
||||
{ DATA_CMD_SEOS_WRITE_EMU_DATA, NULL, cmd_processor_seos_write_emu_data, NULL },
|
||||
{ DATA_CMD_SEOS_WRITE_EMU_KEYS, NULL, cmd_processor_seos_write_emu_keys, NULL },
|
||||
|
||||
/* ISO14443-4 T=CL emulation */
|
||||
#if defined(PROJECT_CHAMELEON_ULTRA)
|
||||
/* ISO14443-4 T=CL emulation */
|
||||
|
||||
@@ -165,6 +165,9 @@
|
||||
#define DATA_CMD_MF1_GET_FIELD_OFF_DO_RESET (4039)
|
||||
#define DATA_CMD_MF1_GET_PRNG_TYPE (4040) // 0=static 1=weak(LFSR) 2=hard(rand)
|
||||
#define DATA_CMD_MF1_SET_PRNG_TYPE (4041)
|
||||
#define DATA_CMD_SEOS_READ_EMU_DATA (4042)
|
||||
#define DATA_CMD_SEOS_WRITE_EMU_DATA (4043)
|
||||
#define DATA_CMD_SEOS_WRITE_EMU_KEYS (4044)
|
||||
//
|
||||
// ******************************************************************
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,48 @@
|
||||
#ifndef NFC_SEOS_H
|
||||
#define NFC_SEOS_H
|
||||
|
||||
#include "nfc_14a.h"
|
||||
#include "tag_emulation.h"
|
||||
|
||||
#define NFC_TAG_SEOS_DATA_MAX 255
|
||||
#define NFC_TAG_SEOS_OID_MAX 32
|
||||
#define NFC_TAG_SEOS_DATA_TAG_MAX 2
|
||||
#define NFC_TAG_SEOS_DIVERSIFIER_MAX 16
|
||||
|
||||
/**
|
||||
* Per-slot persistent data layout stored in FDS flash.
|
||||
*/
|
||||
typedef struct __attribute__((packed)) {
|
||||
nfc_tag_14a_coll_res_entity_t res_coll;
|
||||
|
||||
uint8_t data[NFC_TAG_SEOS_DATA_MAX];
|
||||
uint8_t data_len;
|
||||
|
||||
uint8_t oid[NFC_TAG_SEOS_OID_MAX];
|
||||
uint8_t oid_len;
|
||||
|
||||
uint8_t data_tag[NFC_TAG_SEOS_DATA_TAG_MAX];
|
||||
uint8_t data_tag_len;
|
||||
|
||||
uint8_t diversifier[NFC_TAG_SEOS_DIVERSIFIER_MAX];
|
||||
uint8_t diversifier_len;
|
||||
|
||||
uint8_t hash_alg;
|
||||
uint8_t encr_alg;
|
||||
|
||||
// Keys
|
||||
uint8_t authkey[16];
|
||||
uint8_t privenc[16];
|
||||
uint8_t privmac[16];
|
||||
}
|
||||
nfc_tag_seos_information_t;
|
||||
|
||||
/* Anti-collision resource — used by get_coll_res_data in app_cmd.c */
|
||||
nfc_tag_14a_coll_res_reference_t *nfc_tag_seos_get_coll_res(void);
|
||||
|
||||
/* tag_base_map callbacks */
|
||||
int nfc_tag_seos_data_loadcb(tag_specific_type_t type, tag_data_buffer_t *buffer);
|
||||
int nfc_tag_seos_data_savecb(tag_specific_type_t type, tag_data_buffer_t *buffer);
|
||||
bool nfc_tag_seos_data_factory(uint8_t slot, tag_specific_type_t tag_type);
|
||||
|
||||
#endif
|
||||
@@ -94,6 +94,7 @@ typedef enum {
|
||||
|
||||
// HF14A-4 series 3000
|
||||
TAG_TYPE_HF14A_4 = 3000,
|
||||
TAG_TYPE_SEOS,
|
||||
|
||||
} tag_specific_type_t;
|
||||
|
||||
@@ -124,7 +125,7 @@ typedef enum {
|
||||
TAG_TYPE_MIFARE_4096, TAG_TYPE_NTAG_213, TAG_TYPE_NTAG_215, \
|
||||
TAG_TYPE_NTAG_216, TAG_TYPE_MF0ICU1, TAG_TYPE_MF0ICU2, \
|
||||
TAG_TYPE_MF0UL11, TAG_TYPE_MF0UL21, TAG_TYPE_NTAG_210, \
|
||||
TAG_TYPE_NTAG_212, TAG_TYPE_HF14A_4
|
||||
TAG_TYPE_NTAG_212, TAG_TYPE_HF14A_4, TAG_TYPE_SEOS
|
||||
|
||||
typedef struct {
|
||||
tag_specific_type_t tag_hf;
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#include "nfc_mf0_ntag.h"
|
||||
#include "nfc_mf1.h"
|
||||
#include "nfc_14a_4.h"
|
||||
#include "nfc_seos.h"
|
||||
#include "rgb_marquee.h"
|
||||
#include "tag_persistence.h"
|
||||
|
||||
@@ -116,6 +117,7 @@ static tag_base_handler_map_t tag_base_map[] = {
|
||||
{TAG_SENSE_HF, TAG_TYPE_MF0UL21, nfc_tag_mf0_ntag_data_loadcb, nfc_tag_mf0_ntag_data_savecb, nfc_tag_mf0_ntag_data_factory, &m_tag_data_hf},
|
||||
// ISO14443-4 T=CL emulation
|
||||
{TAG_SENSE_HF, TAG_TYPE_HF14A_4, nfc_tag_14a_4_data_loadcb, nfc_tag_14a_4_data_savecb, nfc_tag_14a_4_data_factory, &m_tag_data_hf},
|
||||
{TAG_SENSE_HF, TAG_TYPE_SEOS, nfc_tag_seos_data_loadcb, nfc_tag_seos_data_savecb, nfc_tag_seos_data_factory, &m_tag_data_hf},
|
||||
};
|
||||
|
||||
static void tag_emulation_load_config(void);
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#include "nfc_14a.h"
|
||||
#include "nfc_mf0_ntag.h"
|
||||
#include "nfc_mf1.h"
|
||||
#include "nfc_seos.h"
|
||||
#include "nrf_gpio.h"
|
||||
#include "tag_emulation.h"
|
||||
|
||||
|
||||
@@ -64,7 +64,7 @@ type_id_SAK_dict = {
|
||||
0x18: "MIFARE Classic 4K | Plus S 4K | Plus X 4K",
|
||||
0x19: "MIFARE Classic 2K",
|
||||
0x20: "MIFARE Plus EV1/EV2 | DESFire EV1/EV2/EV3 | DESFire Light | NTAG 4xx | "
|
||||
"MIFARE Plus S 2/4K | MIFARE Plus X 2/4K | MIFARE Plus SE 1K",
|
||||
"MIFARE Plus S 2/4K | MIFARE Plus X 2/4K | MIFARE Plus SE 1K | SEOS",
|
||||
0x28: "SmartMX with MIFARE Classic 1K",
|
||||
0x38: "SmartMX with MIFARE Classic 4K",
|
||||
}
|
||||
@@ -883,6 +883,7 @@ hf_14a = hf.subgroup("14a", "ISO14443-a commands")
|
||||
hf_mf = hf.subgroup("mf", "MIFARE Classic commands")
|
||||
hf_mfu = hf.subgroup("mfu", "MIFARE Ultralight / NTAG commands")
|
||||
hf_des = hf.subgroup("des", "MIFARE DESFire commands")
|
||||
hf_seos = hf.subgroup("seos", "SEOS commands")
|
||||
|
||||
lf = root.subgroup("lf", "Low Frequency commands")
|
||||
lf_em = lf.subgroup("em", "EM commands")
|
||||
@@ -10555,4 +10556,160 @@ class HfDesChk(ReaderRequiredUnit):
|
||||
for algo, aid, kno, key_hex in found:
|
||||
print(f"\n {CG}{algo:8s} AID {aid} key#{kno} {key_hex}{C0}")
|
||||
else:
|
||||
print(f"\n {CR}No keys found{C0}")
|
||||
print(f"\n {CR}No keys found{C0}")
|
||||
|
||||
@hf_seos.command("eview")
|
||||
class HFSeosEView(SlotIndexArgsAndGoUnit, DeviceRequiredUnit):
|
||||
def args_parser(self) -> ArgumentParserNoExit:
|
||||
parser = ArgumentParserNoExit()
|
||||
parser.description = "View data from emulator memory"
|
||||
self.add_slot_args(parser)
|
||||
return parser
|
||||
|
||||
def on_exec(self, args: argparse.Namespace):
|
||||
selected_slot = self.cmd.get_active_slot()
|
||||
slot_info = self.cmd.get_slot_info()
|
||||
tag_type = TagSpecificType(slot_info[selected_slot]["hf"])
|
||||
|
||||
if tag_type != TagSpecificType.SEOS:
|
||||
raise Exception(
|
||||
"Card in current slot is not SEOS"
|
||||
)
|
||||
data = self.cmd.seos_read_emu_data()
|
||||
|
||||
print("[=] Data:", data["data"].hex().upper())
|
||||
print("[=] OID:", data["oid"].hex().upper())
|
||||
print("[=] Tag:", data["tag"].hex().upper())
|
||||
print("[=] Diversifier:", data["diversifier"].hex().upper())
|
||||
|
||||
@hf_seos.command("eload")
|
||||
class HFSeosELoad(SlotIndexArgsAndGoUnit, HF14AAntiCollArgsUnit, DeviceRequiredUnit):
|
||||
def args_parser(self) -> ArgumentParserNoExit:
|
||||
parser = ArgumentParserNoExit()
|
||||
parser.description = "Load data into emulator memory"
|
||||
self.add_slot_args(parser)
|
||||
self.add_hf14a_anticoll_args(parser)
|
||||
parser.add_argument("-d", "--data", type=str, default=None, metavar="<hex>",
|
||||
help="Data to present to reader (2-255 bytes). Must be valid BER-TLV.")
|
||||
parser.add_argument("-o", "--oid", type=str, default=None, metavar="<hex>",
|
||||
help=f"Target OID (1-32 bytes).")
|
||||
parser.add_argument("-t", "--tag", type=str, default=None, metavar="<hex>",
|
||||
help=f"Tag of presented data (1-2 bytes).")
|
||||
parser.add_argument("--diversifier", type=str, default=None, metavar="<hex>",
|
||||
help=f"Simulated card diversifier (1-16 bytes).")
|
||||
return parser
|
||||
|
||||
def on_exec(self, args: argparse.Namespace):
|
||||
selected_slot = self.cmd.get_active_slot()
|
||||
slot_info = self.cmd.get_slot_info()
|
||||
tag_type = TagSpecificType(slot_info[selected_slot]["hf"])
|
||||
|
||||
if tag_type != TagSpecificType.SEOS:
|
||||
raise Exception(
|
||||
"Card in current slot is not SEOS"
|
||||
)
|
||||
|
||||
# Handle ISO14443-A anticollision changes
|
||||
anti_coll_data = self.cmd.hf14a_get_anti_coll_data()
|
||||
if anti_coll_data is None or len(anti_coll_data) == 0:
|
||||
print(
|
||||
f"{color_string((CR, f'Slot does not contain any HF 14A config'))}"
|
||||
)
|
||||
return
|
||||
uid = anti_coll_data["uid"]
|
||||
atqa = anti_coll_data["atqa"]
|
||||
sak = anti_coll_data["sak"]
|
||||
ats = anti_coll_data["ats"]
|
||||
|
||||
change_requested, change_done, uid, atqa, sak, ats = self.update_hf14a_anticoll(
|
||||
args, uid, atqa, sak, ats
|
||||
)
|
||||
|
||||
if (
|
||||
args.data is None and
|
||||
args.oid is None and
|
||||
args.tag is None and
|
||||
args.diversifier is None and
|
||||
change_requested is False
|
||||
):
|
||||
print(color_string((CR, "Error: No changes were requested.")))
|
||||
|
||||
|
||||
seos_data = self.cmd.seos_read_emu_data()
|
||||
|
||||
# Parse args
|
||||
data = bytes.fromhex(args.data) if args.data else seos_data["data"]
|
||||
oid = bytes.fromhex(args.oid) if args.oid else seos_data["oid"]
|
||||
tag = bytes.fromhex(args.tag) if args.tag else seos_data["tag"]
|
||||
diversifier = bytes.fromhex(args.diversifier) if args.diversifier else seos_data["diversifier"]
|
||||
|
||||
# These are not currently configurable
|
||||
hash_alg = seos_data["hash_alg"]
|
||||
encr_alg = seos_data["encr_alg"]
|
||||
|
||||
if len(data) < 2 or len(data) > 255:
|
||||
print(color_string((CR, "Error: invalid data length. Accepts 2-255 bytes.")))
|
||||
return
|
||||
if len(oid) < 1 or len(oid) > 32:
|
||||
print(color_string((CR, "Error: invalid OID length. Accepts 1-32 bytes.")))
|
||||
return
|
||||
if len(tag) < 1 or len(tag) > 2:
|
||||
print(color_string((CR, "Error: invalid tag length. Accepts 1-2 bytes.")))
|
||||
return
|
||||
if len(diversifier) < 1 or len(diversifier) > 16:
|
||||
print(color_string((CR, "Error: invalid diversifier length. Accepts 1-16 bytes.")))
|
||||
return
|
||||
|
||||
self.cmd.seos_write_emu_data(
|
||||
data=data,
|
||||
oid=oid,
|
||||
tag=tag,
|
||||
diversifier=diversifier,
|
||||
hash_alg=hash_alg,
|
||||
encr_alg=encr_alg
|
||||
)
|
||||
|
||||
@hf_seos.command("keys")
|
||||
class HFSeosKeys(SlotIndexArgsAndGoUnit, DeviceRequiredUnit):
|
||||
def args_parser(self) -> ArgumentParserNoExit:
|
||||
parser = ArgumentParserNoExit()
|
||||
parser.description = "Load data into emulator memory"
|
||||
self.add_slot_args(parser)
|
||||
parser.add_argument("-a", "--auth", type=str, metavar="<hex>", required=True,
|
||||
help="Auth key (16 bytes)")
|
||||
parser.add_argument("-e", "--privenc", type=str, metavar="<hex>", required=True,
|
||||
help="PrivEnc key (16 bytes)")
|
||||
parser.add_argument("-m", "--privmac", type=str, metavar="<hex>", required=True,
|
||||
help="PrivMac key (16 bytes)")
|
||||
return parser
|
||||
|
||||
def on_exec(self, args: argparse.Namespace):
|
||||
selected_slot = self.cmd.get_active_slot()
|
||||
slot_info = self.cmd.get_slot_info()
|
||||
tag_type = TagSpecificType(slot_info[selected_slot]["hf"])
|
||||
|
||||
if tag_type != TagSpecificType.SEOS:
|
||||
raise Exception(
|
||||
"Card in current slot is not SEOS"
|
||||
)
|
||||
|
||||
# Parse args
|
||||
auth = bytes.fromhex(args.auth)
|
||||
privenc = bytes.fromhex(args.privenc)
|
||||
privmac = bytes.fromhex(args.privmac)
|
||||
|
||||
if len(auth) != 16:
|
||||
print(color_string((CR, "Error: invalid auth key length. Accepts 16 bytes.")))
|
||||
return
|
||||
if len(privenc) != 16:
|
||||
print(color_string((CR, "Error: invalid PrivEnc key length. Accepts 16 bytes.")))
|
||||
return
|
||||
if len(privmac) != 16:
|
||||
print(color_string((CR, "Error: invalid PrivMac key length. Accepts 16 bytes.")))
|
||||
return
|
||||
|
||||
self.cmd.seos_write_emu_keys(
|
||||
auth=auth,
|
||||
privenc=privenc,
|
||||
privmac=privmac
|
||||
)
|
||||
|
||||
@@ -1823,6 +1823,49 @@ class ChameleonCMD:
|
||||
data = struct.pack('!B', enabled)
|
||||
return self.device.send_cmd_sync(Command.MF1_SET_FIELD_OFF_DO_RESET, data)
|
||||
|
||||
@expect_response(Status.SUCCESS)
|
||||
def seos_read_emu_data(self):
|
||||
resp = self.device.send_cmd_sync(Command.SEOS_READ_EMU_DATA, None)
|
||||
resp.parsed = {}
|
||||
|
||||
def extract_next():
|
||||
length = resp.data[0]
|
||||
value = resp.data[1:length+1]
|
||||
resp.data = resp.data[length+1:]
|
||||
return value
|
||||
|
||||
data, oid, tag, diversifier = extract_next(), extract_next(), extract_next(), extract_next()
|
||||
hash_alg, encr_alg = struct.unpack('!BB', resp.data)
|
||||
|
||||
resp.parsed = {
|
||||
"data": data, "oid": oid, "tag": tag, "diversifier": diversifier,
|
||||
"hash_alg": hash_alg, "encr_alg": encr_alg
|
||||
}
|
||||
|
||||
return resp
|
||||
|
||||
@expect_response(Status.SUCCESS)
|
||||
def seos_write_emu_data(self, data: bytes, oid: bytes, tag: bytes, diversifier: bytes, hash_alg: int, encr_alg: int):
|
||||
data = bytes([len(data)]) + data
|
||||
oid = bytes([len(oid)]) + oid
|
||||
tag = bytes([len(tag)]) + tag
|
||||
diversifier = bytes([len(diversifier)]) + diversifier
|
||||
|
||||
payload = (
|
||||
data + oid + tag + diversifier +
|
||||
struct.pack('!BB', hash_alg, encr_alg)
|
||||
)
|
||||
|
||||
if len(payload) > 4096:
|
||||
raise ValueError("Too much provided data")
|
||||
|
||||
return self.device.send_cmd_sync(Command.SEOS_WRITE_EMU_DATA, payload)
|
||||
|
||||
@expect_response(Status.SUCCESS)
|
||||
def seos_write_emu_keys(self, auth: bytes, privenc: bytes, privmac: bytes):
|
||||
payload = auth + privenc + privmac
|
||||
return self.device.send_cmd_sync(Command.SEOS_WRITE_EMU_KEYS, payload)
|
||||
|
||||
|
||||
def test_fn():
|
||||
# connect to chameleon
|
||||
|
||||
@@ -150,6 +150,10 @@ class Command(enum.IntEnum):
|
||||
MF1_GET_PRNG_TYPE = 4040
|
||||
MF1_SET_PRNG_TYPE = 4041
|
||||
|
||||
SEOS_READ_EMU_DATA = 4042
|
||||
SEOS_WRITE_EMU_DATA = 4043
|
||||
SEOS_WRITE_EMU_KEYS = 4044
|
||||
|
||||
# ISO14443-4 T=CL emulation
|
||||
HF14A_4_APDU_RECV = 6000
|
||||
HF14A_4_APDU_SEND = 6001
|
||||
@@ -360,6 +364,7 @@ class TagSpecificType(enum.IntEnum):
|
||||
|
||||
# ISO14443-4 T=CL emulation
|
||||
HF14A_4 = 3000
|
||||
SEOS = 3001
|
||||
|
||||
@staticmethod
|
||||
def list(exclude_meta=True):
|
||||
@@ -438,6 +443,8 @@ class TagSpecificType(enum.IntEnum):
|
||||
return "NTAG 210"
|
||||
elif self == TagSpecificType.NTAG_212:
|
||||
return "NTAG 212"
|
||||
elif self == TagSpecificType.SEOS:
|
||||
return "SEOS"
|
||||
elif self < TagSpecificType.OLD_TAG_TYPES_END:
|
||||
return "Old tag type, must be migrated! Upgrade fw!"
|
||||
return "Invalid"
|
||||
|
||||
Reference in New Issue
Block a user