This commit is contained in:
Philippe Teuwen
2023-10-11 10:28:45 +02:00
parent ffb6e00f1e
commit 4fe9e1ea5b
7 changed files with 48 additions and 60 deletions
+2 -1
View File
@@ -15,7 +15,8 @@ Starting from the top left, you find
- the *Device Name*: `Chameleon Ultra` or `Chameleon Lite` depending on the device connected ;
- the *Disconnect* button: pressing this icon cleanly disconnects the Chameleon. It is recommended to use this button whenever possible ;
- the *Connected Port*: it tells you where and how the chameleon is connected, followed by how it is connected (*Connection Method*), which displays a USB or Bluetooth icon. Last in that row is the *Battery Charge* display ;
- the *Connected Port*: it tells you where and how the chameleon is connected, followed by how it is connected (*Connection Method*), which displays a USB or Bluetooth icon ;
- the *Battery Charge* icon: you can press it long to get more details. Note that it is refreshed only when reopening the Homepage ;
- the *Used Slots*: it displays how many out of the 8 slots are used ;
- the *Slot Changer*: the currently selected slot is highlighted with a red circle, while enabled slots are filled in. Everything else is a hollow circle. The arrows left and right allow you to change the currently selected slot ;
- the *Firmware version*: the version is pulled from the device displayed, as well as git commit information ;
+10 -9
View File
@@ -128,19 +128,20 @@ Make sure to be in the `software/` directory and run the Python CLI from there.
- Connect to the CLI: `hw connect`
- Check which slot can be used: `hw slot list`
- Change the slot type, here using slot 8 for a MFC 1k emulation: `hw slot type -s8 -t3`
- Init the slot content: `hw slot init -s8 -t3`
- or load an existing dump and set UID and anticollision data, cf `hf mf eload -h` and `hf mf sim -h`
- Enable the slot: `hw slot enable -s8 -e1`
- Change to the new slot: `hw slot change -s8`
- Activate the detection: `hf detection enable -e1`
- Change the slot type, here using slot 8 for a MFC 1k emulation: `hw slot type -s 8 -t MIFARE_1024`
- Init the slot content: `hw slot init -s 8 -t MIFARE_1024`
- or load an existing dump and set UID and anticollision data, cf `hf mf eload -h` and `hf mf econfig -h`
- Enable the slot: `hw slot enable -s 8 --hf`
- Change to the new slot: `hw slot change -s 8`
- Activate the authentication logs: `hf mf econfig --enable-log`
Now disconnect, go to a reader and swipe it a few times
- Come back and connect to the CLI: `hw connect`
- See if nonces were collected: `hf detection count`
- See if nonces were collected: `hf mf elog`
- We need 2 nonces per key to recover
- Recover the key(s) based on the collected nonces: `hf detection decrypt`. Output example:
- Recover the key(s) based on the collected nonces: `hf mf elog --decrypt`.
Output example:
```
- MF1 detection log count = 6, start download.
- Download done (144bytes), start parse and decrypt
@@ -153,7 +154,7 @@ Now disconnect, go to a reader and swipe it a few times
```
- To clean the logged detection nonces: `hf detection enable -e0` then `hf detection enable -e1`
- To clean the logged detection nonces: `hf mf econfig --disable-log` then `hf mf econfig --enable-log`
+2 -2
View File
@@ -65,7 +65,7 @@ The Chameleon can be awaken:
The white LED labeled RF lights up when it detects a field, again only if the active slot supports it.
In some situations, it can be cumbersome to wait for the boot-up animation. This is configurable, cf e.g. the CLI command `hw settings animation set -h`.
In some situations, it can be cumbersome to wait for the boot-up animation. This is configurable, cf e.g. the CLI command `hw settings animation -h`.
On a new Chameleon (or after a factory reset), 3 slots are defined, slot 1 holding both a HF and a LF:
@@ -116,5 +116,5 @@ We are using the [SoftDevice S140](https://infocenter.nordicsemi.com/index.jsp?t
## The User Data
The Chameleon has a reserved space of memory and flash where it stores application settings, active slot and slots configurations and data. This will not be overwritten by DFU updates and the data will only be reset by either issuing `hw factory_reset --i-know-what-im-doing` in the CLI or clicking `Factory reset` in a GUI.
The Chameleon has a reserved space of memory and flash where it stores application settings, active slot and slots configurations and data. This will not be overwritten by DFU updates and the data will only be reset by either issuing `hw factory_reset --force` in the CLI or clicking `Factory reset` in a GUI.
*Warning:* Settings and/or data might be reset to defaults if you downgrade the firmware version up to a version not supporting the newer format.
+32 -31
View File
@@ -64,11 +64,11 @@ In the following list, "CLI" refers to one typical CLI command using the describ
### 1001: CHANGE_DEVICE_MODE
* Command: 1 byte. `0x00`=emulator mode, `0x01`=reader mode
* Response: no data
* CLI: cf `hw mode set`
* CLI: cf `hw mode`
### 1002: GET_DEVICE_MODE
* Command: no data
* Response: data: 1 byte. `0x00`=emulator mode, `0x01`=reader mode
* CLI: cf `hw mode get`
* CLI: cf `hw mode`
### 1003: SET_ACTIVE_SLOT
* Command: 1 byte. `slot_number` between 0 and 7
* Response: no data
@@ -84,19 +84,19 @@ In the following list, "CLI" refers to one typical CLI command using the describ
### 1006: SET_SLOT_ENABLE
* Command: 3 bytes. `slot_number|sense_type|enable` with `slot_number` between 0 and 7, `sense_type` according to `tag_sense_type_t` enum and `enable` = `0x01` to enable, `0x00` to disable
* Response: no data
* CLI: cf `hw slot enable`
* CLI: cf `hw slot enable`/`hw slot disable`
### 1007: SET_SLOT_TAG_NICK
* Command: 2+N bytes. `slot_number|sense_type|name[N]` with `slot_number` between 0 and 7, `sense_type` according to `tag_sense_type_t` enum and `name` a UTF-8 encoded string of max 32 bytes, no null terminator.
* Response: no data
* CLI: cf `hw slot nick set`
* CLI: cf `hw slot nick`
### 1008: GET_SLOT_TAG_NICK
* Command: 2 bytes. `slot_number|sense_type` with `slot_number` between 0 and 7 and `sense_type` according to `tag_sense_type_t` enum.
* Response: a UTF-8 encoded string of max 32 bytes, no null terminator. If no nick name has been recorded in Flash, response status is `STATUS_FLASH_READ_FAIL`.
* CLI: cf `hw slot nick get`
* CLI: cf `hw slot nick`
### 1009: SLOT_DATA_CONFIG_SAVE
* Command: no data
* Response: no data
* CLI: cf `hw slot update`
* CLI: cf `hw slot store`
### 1010: ENTER_BOOTLOADER
* Command: no data
* Response: this special command does not return and will interrupt the communication link while rebooting in bootloader mode, needed for DFU.
@@ -104,11 +104,11 @@ In the following list, "CLI" refers to one typical CLI command using the describ
### 1011: GET_DEVICE_CHIP_ID
* Command: no data
* Response: 8 bytes. nRF `DEVICEID[8]` U64 in Network byte order.
* CLI: cf `hw chipid get`
* CLI: cf `hw chipid`
### 1012: GET_DEVICE_ADDRESS
* Command: no data
* Response: 6 bytes. nRF `DEVICEADDR[6]` U48 in Network byte order. First 2 MSBits forced to `0b11` to match BLE static address.
* CLI: cf `hw address get`
* CLI: cf `hw address`
### 1013: SAVE_SETTINGS
* Command: no data
* Response: no data
@@ -120,11 +120,11 @@ In the following list, "CLI" refers to one typical CLI command using the describ
### 1015: SET_ANIMATION_MODE
* Command: 1 byte, according to `settings_animation_mode_t` enum.
* Response: no data
* CLI: cf `hw settings animation set`
* CLI: cf `hw settings animation`
### 1016: GET_ANIMATION_MODE
* Command: no data
* Response: 1 byte, according to `settings_animation_mode_t` enum.
* CLI: cf `hw settings animation get`
* CLI: cf `hw settings animation`
### 1017: GET_GIT_VERSION
* Command: no data
* Response: n bytes, a UTF-8 encoded string, no null terminator.
@@ -149,14 +149,15 @@ Notes: the returned string is the output of `git describe --abbrev=7 --dirty --a
### 1021: DELETE_SLOT_TAG_NICK
* Command: 2 bytes. `slot_number|sense_type` with `slot_number` between 0 and 7 and `sense_type` according to `tag_sense_type_t` enum.
* Response: no data
* CLI: cf `hw slot nick delete`
* CLI: cf `hw slot nick`
### 1023: GET_ENABLED_SLOTS
* Command: no data
* Response: 16 bytes, 8*2 bool = `0x00` or `0x01`, 2 bytes for each slot from 0 to 7, as `enabled_hf|enabled_lf`
* CLI: cf `hw slot list`
### 1024: DELETE_SLOT_SENSE_TYPE
* Command: 2 bytes. `slot_number|sense_type` with `slot_number` between 0 and 7 and `sense_type` according to `tag_sense_type_t` enum.
* Response: no data
* CLI: cf `hw factory_reset`
* CLI: cf `hw slot delete`
### 1025: GET_BATTERY_INFO
* Command: no data
* Response: 3 bytes, `voltage[2]|percentage`. Voltage: U16 in Network byte order.
@@ -166,19 +167,19 @@ Notes: wait about 5 seconds after wake-up, before querying the battery status, e
### 1026: GET_BUTTON_PRESS_CONFIG
* Command: 1 byte. Char `A` or `B` (`a`/`b` tolerated too)
* Response: 1 byte, `button_function` according to `settings_button_function_t` enum.
* CLI: cf `hw settings btnpress get`
* CLI: cf `hw settings btnpress`
### 1027: SET_BUTTON_PRESS_CONFIG
* Command: 2 bytes. `button|button_function` with `button` char `A` or `B` (`a`/`b` tolerated too) and `button_function` according to `settings_button_function_t` enum.
* Response: no data
* CLI: cf `hw settings btnpress set`
* CLI: cf `hw settings btnpress`
### 1028: GET_LONG_BUTTON_PRESS_CONFIG
* Command: 1 byte. Char `A` or `B` (`a`/`b` tolerated too)
* Response: 1 byte, `button_function` according to `settings_button_function_t` enum.
* CLI: cf `hw settings btnpress get`
* CLI: cf `hw settings btnpress`
### 1029: SET_LONG_BUTTON_PRESS_CONFIG
* Command: 2 bytes. `button|button_function` with `button` char `A` or `B` (`a`/`b` tolerated too) and `button_function` according to `settings_button_function_t` enum.
* Response: no data
* CLI: cf `hw settings btnpress set`
* CLI: cf `hw settings btnpress`
### 1030: SET_BLE_PAIRING_KEY
* Command: 6 bytes. 6 ASCII-encoded digits.
* Response: no data
@@ -190,7 +191,7 @@ Notes: wait about 5 seconds after wake-up, before querying the battery status, e
### 1032: DELETE_ALL_BLE_BONDS
* Command: no data
* Response: no data
* CLI: cf `hw ble bonds clear`
* CLI: cf `hw settings bleclearbonds`
### 1033: GET_DEVICE_MODEL
* Command: no data
* Response: 1 byte. `hw_version` aka `NRF_DFU_HW_VERSION` according to `chameleon_device_type_t` enum (0=Ultra, 1=Lite)
@@ -292,11 +293,11 @@ Notes:
### 3000: EM410X_SCAN
* Command: no data
* Response: 5 bytes. `id[5]`. ID as 5 bytes.
* CLI: cf `lf em read`
* CLI: cf `lf em 410x read`
### 3001: EM410X_WRITE_TO_T55XX
* Command: 9+N*4 bytes: `id[5]|new_key[4]|old_key1[4]|old_key2[4]|...` (N>=1). . ID as 5 bytes. Keys as 4 bytes.
* Response: no data
* CLI: cf `lf em write`
* CLI: cf `lf em 410x write`
### 4000: MF1_WRITE_EMU_BLOCK_DATA
* Command: 1+N*16 bytes: `block_start|block_data1[16]|block_data2[16]|...` (1<=N<=31)
* Response: no data
@@ -304,15 +305,15 @@ Notes:
### 4001: HF14A_SET_ANTI_COLL_DATA
* Command: N bytes: `uidlen|uid[uidlen]|atqa[2]|sak|atslen|ats[atslen]`. UID, ATQA, SAK and ATS as bytes.
* Response: no data
* CLI: cf `hf mf sim`
* CLI: cf `hf mf econfig`/`hf mfu econfig`
### 4004: MF1_SET_DETECTION_ENABLE
* Command: 1 byte, bool = `0x00` or `0x01`
* Response: no data
* CLI: cf `hf detection enable`
* CLI: cf `hf mf econfig`
### 4005: MF1_GET_DETECTION_COUNT
* Command: no data
* Response: 4 bytes, `count[4]`, U32 in Network byte order.
* CLI: cf `hf detection count`
* CLI: cf `hf mf elog`
### 4006: MF1_GET_DETECTION_LOG
* Command: 4 bytes, `index`, U32 in Network byte order.
* Response: N*18 bytes. 0<=N<=28
@@ -322,7 +323,7 @@ Notes:
* `nt[4]` ?
* `nr[4]` ?
* `ar[4]` ?
* CLI: cf `hf detection decrypt`
* CLI: cf `hf mf elog`
### 4007: MF1_GET_DETECTION_ENABLE
* Command: no data
* Response: 1 byte, bool = `0x00` or `0x01`
@@ -339,7 +340,7 @@ Notes:
* `gen2_mode`, cf [MF1_GET_GEN2_MODE](#4012-mf1_get_gen2_mode)
* `block_anti_coll_mode`, cf [MF1_GET_BLOCK_ANTI_COLL_MODE](#4014-mf1_get_block_anti_coll_mode)
* `write_mode`, cf [MF1_GET_WRITE_MODE](#4016-mf1_get_write_mode)
* CLI: cf `hw slot list`
* CLI: cf `hf mf econfig`
### 4010: MF1_GET_GEN1A_MODE
* Command: no data
* Response: 1 byte, bool = `0x00` or `0x01`
@@ -347,7 +348,7 @@ Notes:
### 4011: MF1_SET_GEN1A_MODE
* Command: 1 byte, bool = `0x00` or `0x01`
* Response: no data
* CLI: cf `hf mf settings`
* CLI: cf `hf mf econfig`
### 4012: MF1_GET_GEN2_MODE
* Command: no data
* Response: 1 byte, bool = `0x00` or `0x01`
@@ -355,7 +356,7 @@ Notes:
### 4013: MF1_SET_GEN2_MODE
* Command: 1 byte, bool = `0x00` or `0x01`
* Response: no data
* CLI: cf `hf mf settings`
* CLI: cf `hf mf econfig`
### 4014: MF1_GET_BLOCK_ANTI_COLL_MODE
* Command: no data
* Response: 1 byte, bool = `0x00` or `0x01`
@@ -363,7 +364,7 @@ Notes:
### 4015: MF1_SET_BLOCK_ANTI_COLL_MODE
* Command: 1 byte, bool = `0x00` or `0x01`
* Response: no data
* CLI: cf `hf mf settings`
* CLI: cf `hf mf econfig`
### 4016: MF1_GET_WRITE_MODE
* Command: no data
* Response: 1 byte, according to `nfc_tag_mf1_write_mode_t` aka `MifareClassicWriteMode` enum
@@ -371,19 +372,19 @@ Notes:
### 4017: MF1_SET_WRITE_MODE
* Command: 1 byte, according to `nfc_tag_mf1_write_mode_t` aka `MifareClassicWriteMode` enum
* Response: no data
* CLI: cf `hf mf settings`
* CLI: cf `hf mf econfig`
### 4018: HF14A_GET_ANTI_COLL_DATA
* Command: no data
* Response: no data or N bytes: `uidlen|uid[uidlen]|atqa[2]|sak|atslen|ats[atslen]`. UID, ATQA, SAK and ATS as bytes.
* CLI: cf `hf mf info`
* CLI: cf `hw slot list`/`hf mf econfig`/`hf mfu econfig`
### 5000: EM410X_SET_EMU_ID
* Command: 5 bytes. `id[5]`. ID as 5 bytes.
* Response: no data
* CLI: cf `lf em sim set`
* CLI: cf `lf em 410x econfig`
### 5001: EM410X_GET_EMU_ID
* Command: no data
* Response: 5 bytes. `id[5]`. ID as 5 bytes.
* CLI: cf `lf em sim get`
* CLI: cf `lf em 410x econfig`
## New data payloads: guidelines for developers
+1 -1
View File
@@ -22,7 +22,7 @@ On Android make sure your location is turned, as that allows for scanning of blu
After BLE pairing, both the phone and ChameleonUltra will save a secret key for encrypted communication. If either party deletes the pairing record, it will result in communication failure. If Bluetooth cannot be connected, clearing the pairing information on the other side can solve the problem:
* Find the Bluetooth settings in the phone's system settings and cancel pairing with the ChameleonUltra.
* In the CLI of ChameleonUltra, execute the `hw ble bonds clear` command to clear all pairing records.
* In the CLI of ChameleonUltra, execute the `hw settings bleclearbonds` command to clear all pairing records.
Default BLE connect key(passkey) is `123456`
-15
View File
@@ -837,7 +837,6 @@ class HFMFRDBL(MF1AuthArgsUnit):
parser.description = 'Mifare Classic read one block'
return parser
# hf mf rdbl -b 2 -t A -k FFFFFFFFFFFF
def on_exec(self, args: argparse.Namespace):
param = self.get_param(args)
resp = self.cmd.mf1_read_one_block(param.block, param.type, param.key)
@@ -853,7 +852,6 @@ class HFMFWRBL(MF1AuthArgsUnit):
help="Your block data, as hex string.")
return parser
# hf mf wrbl -b 2 -t A -k FFFFFFFFFFFF -d 00000000000000000000000000000122
def on_exec(self, args: argparse.Namespace):
param = self.get_param(args)
if not re.match(r"^[a-fA-F0-9]{32}$", args.data):
@@ -989,8 +987,6 @@ class HFMFELoad(SlotIndexArgsAndGoUnit, DeviceRequiredUnit):
parser.add_argument('-t', '--type', type=str, required=False, help="content type", choices=['bin', 'hex'])
return parser
# hf mf eload -f test.bin -t bin
# hf mf eload -f test.eml -t hex
def on_exec(self, args: argparse.Namespace):
file = args.file
if args.type is None:
@@ -1238,8 +1234,6 @@ class HFMFEConfig(SlotIndexArgsAndGoUnit, HF14AAntiCollArgsUnit, DeviceRequiredU
@hf_mfu.command('rdpg')
class HFMFURDPG(MFUAuthArgsUnit):
# hf mfu rdpg -p 2
def args_parser(self) -> ArgumentParserNoExit:
parser = super().args_parser()
parser.description = 'MIFARE Ultralight read one page'
@@ -1271,7 +1265,6 @@ class HFMFURDPG(MFUAuthArgsUnit):
@hf_mfu.command('dump')
class HFMFUDUMP(MFUAuthArgsUnit):
# hf mfu dump [-p start_page] [-q number_pages] [-f output_file]
def args_parser(self) -> ArgumentParserNoExit:
parser = super().args_parser()
parser.description = 'MIFARE Ultralight dump pages'
@@ -1391,7 +1384,6 @@ class LFEM410xWriteT55xx(LFEMIdArgsUnit, ReaderRequiredUnit):
b2 = super(ReaderRequiredUnit, self).before_exec(args)
return b1 and b2
# lf em write --id 4400999559
def on_exec(self, args: argparse.Namespace):
id_hex = args.id
id_bytes = bytes.fromhex(id_hex)
@@ -1418,7 +1410,6 @@ class HWSlotList(DeviceRequiredUnit):
name = "UTF8 Err"
return {'baselen': len(name), 'metalen': len(CC+C0), 'name': f'{CC}{name}{C0}'}
# hw slot list
def on_exec(self, args: argparse.Namespace):
slotinfo = self.cmd.get_slot_info()
selected = chameleon_cmd.SlotNumber.from_fw(self.cmd.get_active_slot())
@@ -1509,7 +1500,6 @@ class HWSlotSet(SlotIndexArgsUnit):
parser.description = 'Set emulation tag slot activated'
return self.add_slot_args(parser, mandatory=True)
# hw slot change -s 1
def on_exec(self, args: argparse.Namespace):
slot_index = args.slot
self.cmd.set_active_slot(slot_index)
@@ -1525,7 +1515,6 @@ class HWSlotType(TagTypeArgsUnit, SlotIndexArgsUnit):
self.add_type_args(parser)
return parser
# hw slot type -t 2
def on_exec(self, args: argparse.Namespace):
tag_type = chameleon_cmd.TagSpecificType[args.type]
if args.slot is not None:
@@ -1567,8 +1556,6 @@ class HWSlotInit(TagTypeArgsUnit, SlotIndexArgsUnit):
self.add_type_args(parser)
return parser
# m1 1k card emulation hw slot init -s 1 -t 3
# em id card simulation hw slot init -s 1 -t 1
def on_exec(self, args: argparse.Namespace):
tag_type = chameleon_cmd.TagSpecificType[args.type]
if args.slot is not None:
@@ -1695,7 +1682,6 @@ class HWSlotOpenAll(DeviceRequiredUnit):
parser.description = 'Open all slot and set to default data'
return parser
# hw slot openall
def on_exec(self, args: argparse.Namespace):
# what type you need set to default?
hf_type = chameleon_cmd.TagSpecificType.MIFARE_1024
@@ -1727,7 +1713,6 @@ class HWDFU(DeviceRequiredUnit):
parser.description = 'Restart application to bootloader/DFU mode'
return parser
# hw dfu
def on_exec(self, args: argparse.Namespace):
print("Application restarting...")
self.cmd.enter_bootloader()
+1 -1
View File
@@ -130,7 +130,7 @@ class CLITree:
:param name: Name of the command (e.g. "set")
:param help_text: Hint displayed for the command
:param fullname: Full name of the command that includes previous commands (e.g. "hw mode set")
:param fullname: Full name of the command that includes previous commands (e.g. "hw settings animation")
:param cls: A BaseCLIUnit instance handling the command
"""