Skip to content

Commit

Permalink
v0.1.3-beta; pair emulated keyboard to recent receivers
Browse files Browse the repository at this point in the history
  • Loading branch information
mame82 committed Aug 15, 2019
1 parent 66c663f commit f414073
Show file tree
Hide file tree
Showing 25 changed files with 34,294 additions and 33,043 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,5 @@ pca10059/blank/armgcc/_build
apr-dongle/blank/armgcc/_build/
cmake-build-debug

build/uf2conv.py
build/convert.sh
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# LOGITacker v0.1.2-beta
# LOGITacker v0.1.3-beta

- experimental Logitech LIGHTSPEED support (G-Series, tested with G603)
- adjusted device listing with `devices` command (prints more data, especially for devices obtained from sniffed pairing)
Expand Down
1 change: 1 addition & 0 deletions apr-dongle/blank/armgcc/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ SRC_FILES += \
$(PROJ_DIR)/logitacker/logitacker_processor_pair_sniff.c \
$(PROJ_DIR)/logitacker/logitacker_processor_active_enum.c \
$(PROJ_DIR)/logitacker/logitacker_processor_passive_enum.c \
$(PROJ_DIR)/logitacker/logitacker_processor_prx.c \
$(PROJ_DIR)/logitacker/logitacker_processor_pair_device.c \
$(PROJ_DIR)/logitacker/logitacker_processor_inject.c \
$(PROJ_DIR)/logitacker/logitacker_tx_pay_provider_string_to_keys.c \
Expand Down
2 changes: 1 addition & 1 deletion apr-dongle/blank/config/sdk_config.h
Original file line number Diff line number Diff line change
Expand Up @@ -1975,7 +1975,7 @@
// <i> Note: This value is not editable in Configuration Wizard.
// <i> Serial number that is defined the same way like in @ref APP_USBD_STRINGS_MANUFACTURER.
#ifndef APP_USBD_STRING_SERIAL
#define APP_USBD_STRING_SERIAL APP_USBD_STRING_DESC("v0.1.2-beta")
#define APP_USBD_STRING_SERIAL APP_USBD_STRING_DESC("v0.1.3-beta")
#endif

// </e>
Expand Down
16,675 changes: 8,421 additions & 8,254 deletions build/logitacker_aprdongle.hex

Large diffs are not rendered by default.

Binary file modified build/logitacker_aprdongle.uf2
Binary file not shown.
16,684 changes: 8,424 additions & 8,260 deletions build/logitacker_mdk.hex

Large diffs are not rendered by default.

16,675 changes: 8,419 additions & 8,256 deletions build/logitacker_mdk_dongle.hex

Large diffs are not rendered by default.

16,675 changes: 8,421 additions & 8,254 deletions build/logitacker_pca10059.hex

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion esb_illegalmod/nrf_esb_illegalmod.c
Original file line number Diff line number Diff line change
Expand Up @@ -1383,7 +1383,7 @@ static void clear_events_do_not_restart_rx(void)

static void on_radio_disabled_rx(void)
{
NRF_LOG_INFO("on_rx_disabled");
NRF_LOG_DEBUG("on_rx_disabled");
bool ack = false;
bool retransmit_payload = false;
bool send_rx_event = true;
Expand Down
30 changes: 20 additions & 10 deletions logitacker/logitacker.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#include "logitacker_processor.h"
#include "logitacker_processor_active_enum.h"
#include "logitacker_processor_passive_enum.h"
#include "logitacker_processor_prx.h"
#include "logitacker_processor_pair_device.h"
#include "logitacker_processor_inject.h"
#include "logitacker_usb.h"
Expand Down Expand Up @@ -145,6 +146,15 @@ void logitacker_enter_mode_passive_enum(uint8_t *rf_address) {
sprintf(g_logitacker_cli_name, "LOGITacker (passive enum) $ ");
}

void logitacker_enter_mode_prx(uint8_t *rf_address) {
if (p_processor != NULL && p_processor->p_deinit_func != NULL) (*p_processor->p_deinit_func)(p_processor);
p_processor = new_processor_prx(rf_address);
p_processor->p_init_func(p_processor);

m_state_local.mainstate = LOGITACKER_MODE_PRX;
sprintf(g_logitacker_cli_name, "LOGITacker (prx) $ ");
}


void logitacker_enter_mode_pair_sniff() {
if (p_processor != NULL && p_processor->p_deinit_func != NULL) (*p_processor->p_deinit_func)(p_processor);
Expand Down Expand Up @@ -174,20 +184,20 @@ void logitacker_enter_mode_pair_device(uint8_t const *rf_address) {
char dev_name[] = "LOGITacker";
logitacker_pairing_info_t pi = {
.device_name_len = sizeof(dev_name),
.device_usability_info = LOGITACKER_DEVICE_USABILITY_INFO_PS_LOCATION_OTHER,
.device_nonce = {0x011, 0x22, 0x33, 0x44},
.device_usability_info = LOGITACKER_DEVICE_USABILITY_INFO_PS_LOCATION_ON_THE_TOP_EDGE,
.device_nonce = {0xde, 0xad, 0xbe, 0xef},
.device_report_types = LOGITACKER_DEVICE_REPORT_TYPES_KEYBOARD |
LOGITACKER_DEVICE_REPORT_TYPES_POWER_KEYS |
LOGITACKER_DEVICE_REPORT_TYPES_MULTIMEDIA |
LOGITACKER_DEVICE_REPORT_TYPES_MEDIA_CENTER |
// LOGITACKER_DEVICE_REPORT_TYPES_MEDIA_CENTER |
LOGITACKER_DEVICE_REPORT_TYPES_MOUSE |
LOGITACKER_DEVICE_REPORT_TYPES_KEYBOARD_LED |
LOGITACKER_DEVICE_REPORT_TYPES_SHORT_HIDPP |
LOGITACKER_DEVICE_REPORT_TYPES_LONG_HIDPP,
.device_serial = { 0xde, 0xad, 0x13, temp_dev_id++ },
.device_caps = LOGITACKER_DEVICE_CAPS_UNIFYING_COMPATIBLE, // no link encryption (we could enable and calculate keys if we like)
.device_type = LOGITACKER_DEVICE_UNIFYING_TYPE_MOUSE, // of course this is shown as a mouse in Unifying software
.device_wpid = { 0x04, 0x02 }, // random
// LOGITACKER_DEVICE_REPORT_TYPES_SHORT_HIDPP |
// LOGITACKER_DEVICE_REPORT_TYPES_LONG_HIDPP |
LOGITACKER_DEVICE_REPORT_TYPES_KEYBOARD_LED,
.device_serial = { 0x2d, 0x9a, 0x9f, temp_dev_id++ },
.device_caps = LOGITACKER_DEVICE_CAPS_UNIFYING_COMPATIBLE | LOGITACKER_DEVICE_CAPS_LINK_ENCRYPTION, // use link encryption, to account for MouseJack patched firmwares
.device_type = LOGITACKER_DEVICE_UNIFYING_TYPE_KEYBOARD, // use keyboard, for latest receiver firmwares character keys [a-zA-Z] are blacklisted for non-keyboard devices
.device_wpid = { 0x13, 0x37 }, // random
};
memcpy(pi.device_name, dev_name, pi.device_name_len);

Expand Down
8 changes: 7 additions & 1 deletion logitacker/logitacker.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ extern "C" {
#include "nrf_esb_illegalmod.h"
#include "logitacker_keyboard_map.h"

#define VERSION_STRING "v0.1.2-beta"
#define VERSION_STRING "v0.1.3-beta"

//#define PAIRING_REQ_MARKER_BYTE 0xee // byte used as device ID in pairing requests
#define ACTIVE_ENUM_INNER_LOOP_MAX 20 //how many CAPS presses / key releases get send
Expand All @@ -25,6 +25,9 @@ extern "C" {
#define LOGITACKER_PASSIVE_ENUM_STAY_ON_CHANNEL_AFTER_RX_MS 1300 // time in ms to stop channel hopping in passive mode, once a valid ESB frame is received
#define LOGITACKER_PASSIVE_ENUM_CHANNEL_HOP_INTERVAL_MS 30 // channel hop interval in passive enum mode

#define LOGITACKER_PRX_STAY_ON_CHANNEL_AFTER_RX_MS 1300 // time in ms to stop channel hopping in passive mode, once a valid ESB frame is received
#define LOGITACKER_PRX_ENUM_CHANNEL_HOP_INTERVAL_MS 30 // channel hop interval in passive enum mode

#define LOGITACKER_SNIFF_PAIR_STAY_ON_CHANNEL_AFTER_RX_MS 1300
#define LOGITACKER_SNIFF_PAIR_CHANNEL_HOP_INTERVAL_MS 10

Expand All @@ -35,6 +38,7 @@ typedef enum {
LOGITACKER_MODE_PASSIVE_ENUMERATION, // radio in SNIFF mode, collecting device frames to determin caps
LOGITACKER_MODE_SNIFF_PAIRING,
LOGITACKER_MODE_PAIR_DEVICE,
LOGITACKER_MODE_PRX,
LOGITACKER_MODE_INJECT,
LOGITACKER_MODE_IDLE
} logitacker_mode_t;
Expand All @@ -46,6 +50,8 @@ uint32_t logitacker_init();
void logitacker_enter_mode_discovery();


void logitacker_enter_mode_prx(uint8_t *rf_address);

void logitacker_enter_mode_passive_enum(uint8_t *rf_address);

void logitacker_enter_mode_active_enum(uint8_t *rf_address);
Expand Down
27 changes: 27 additions & 0 deletions logitacker/logitacker_cli.c
Original file line number Diff line number Diff line change
Expand Up @@ -1105,6 +1105,29 @@ static void cmd_enum_passive(nrf_cli_t const * p_cli, size_t argc, char **argv)
}
}

#ifdef CLI_TEST_COMMANDS
static void cmd_prx(nrf_cli_t const * p_cli, size_t argc, char **argv) {
if (argc > 1)
{

//parse arg 1 as address
uint8_t addr[5];
if (helper_hex_str_to_addr(addr, 5, argv[1]) != NRF_SUCCESS) {
nrf_cli_fprintf(p_cli, NRF_CLI_ERROR, "invalid address parameter, format has to be xx:xx:xx:xx:xx\r\n");
return;
}

char tmp_addr_str[16];
helper_addr_to_hex_str(tmp_addr_str, 5, addr);
nrf_cli_fprintf(p_cli, NRF_CLI_VT100_COLOR_GREEN, "Starting PRX with address %s\r\n", tmp_addr_str);
logitacker_enter_mode_prx(addr);
return;
} else {
nrf_cli_fprintf(p_cli, NRF_CLI_ERROR, "invalid address parameter, format has to be xx:xx:xx:xx:xx\r\n");
}
}
#endif

static void cmd_enum_active(nrf_cli_t const * p_cli, size_t argc, char **argv) {
if (argc > 1)
{
Expand Down Expand Up @@ -1237,6 +1260,10 @@ NRF_CLI_CREATE_DYNAMIC_CMD(m_sub_enum_device_list, dynamic_device_addr_list_ram)
NRF_CLI_CMD_REGISTER(active_enum, &m_sub_enum_device_list, "start active enumeration of given device", cmd_enum_active);
NRF_CLI_CMD_REGISTER(passive_enum, &m_sub_enum_device_list, "start passive enumeration of given device", cmd_enum_passive);

#ifdef CLI_TEST_COMMANDS
NRF_CLI_CMD_REGISTER(prx, &m_sub_enum_device_list, "start a PRX for the given device address", cmd_prx);
#endif

NRF_CLI_CMD_REGISTER(erase_flash, NULL, "erase all data stored on flash", cmd_erase_flash);

NRF_CLI_CMD_REGISTER(version, NULL, "print version string", cmd_version);
Expand Down
3 changes: 3 additions & 0 deletions logitacker/logitacker_flash.c
Original file line number Diff line number Diff line change
Expand Up @@ -67,18 +67,21 @@ uint32_t logitacker_flash_init() {
NRF_LOG_ERROR("failed to initialize flash-storage, event handler registration failed: %d", ret);
return ret;
}
NRF_LOG_INFO("fds_register main callback succeeded")

ret = fds_register(logitacker_script_engine_fds_event_handler);
if (ret != NRF_SUCCESS) {
NRF_LOG_ERROR("failed to register FDS event handler for script processor: %d", ret);
return ret;
}
NRF_LOG_INFO("fds_register script callback succeeded")

ret = fds_init();
if (ret != NRF_SUCCESS) {
NRF_LOG_ERROR("failed to initialize flash-storage: %d", ret);
return ret;
}
NRF_LOG_INFO("fds_init")

wait_for_fds_ready();
NRF_LOG_INFO("flash-storage initialized");
Expand Down
66 changes: 65 additions & 1 deletion logitacker/logitacker_processor_pair_device.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@

#define NRF_LOG_MODULE_NAME LOGITACKER_PROCESSOR_PAIR_DEVICE
#include "nrf_log.h"
#include "logitacker_options.h"
#include "logitacker_flash.h"

NRF_LOG_MODULE_REGISTER();

// ToDo: implement error conditions leading to failed pairing
Expand Down Expand Up @@ -186,7 +189,7 @@ void processor_pair_device_deinit_func(logitacker_processor_t *p_processor) {
void processor_pair_device_deinit_func_(logitacker_processor_pair_device_ctx_t *self) {
*self->p_logitacker_mainstate = LOGITACKER_MODE_IDLE;

NRF_LOG_INFO("DEINIT active enumeration for address %s", addr_str_buff);
NRF_LOG_INFO("DEINIT device pairing of address %s", addr_str_buff);

radio_disable_rx_timeout_event(); // disable RX timeouts
radio_stop_channel_hopping(); // disable channel hopping
Expand Down Expand Up @@ -280,6 +283,61 @@ void processor_pair_device_esb_handler_func_(logitacker_processor_pair_device_ct


if (self->phase == PAIR_DEVICE_PHASE_SUCCEEDED) {

//retrieve device or add new and update data
logitacker_devices_unifying_device_t * p_device = NULL;
//couldn't fetch device, try to create (gets existing one in case it is already defined)
logitacker_devices_create_device(&p_device, self->device_pairing_info.device_rf_address);
if (p_device == NULL) {
NRF_LOG_ERROR("failed adding device entry for newly paired device");
} else {
// copy pairing info to device data
logitacker_pairing_info_t pi = self->device_pairing_info;
memcpy(p_device->serial, pi.device_serial, 4);
memcpy(p_device->device_name, pi.device_name, pi.device_name_len);
p_device->device_name_len = pi.device_name_len;
memcpy(p_device->key, pi.device_key, 16);
memcpy(p_device->raw_key_data, pi.device_raw_key_material, 16);
memcpy(p_device->rf_address, pi.device_rf_address, 5);
memcpy(p_device->wpid, pi.device_wpid, 2);
p_device->caps = pi.device_caps;
p_device->report_types = pi.device_report_types;


if (p_device->p_dongle == NULL) {
NRF_LOG_ERROR("device doesn't point to dongle");
} else {
logitacker_devices_unifying_dongle_t *p_dongle = p_device->p_dongle;
memcpy(p_dongle->wpid, pi.dongle_wpid, 2);

p_dongle->classification = DONGLE_CLASSIFICATION_IS_LOGITECH_UNIFYING;
if (p_dongle->wpid[0] == 0x88 && p_dongle->wpid[1] == 0x02) p_dongle->is_nordic = true;
if (p_dongle->wpid[0] == 0x88 && p_dongle->wpid[1] == 0x08) p_dongle->is_texas_instruments = true;
if (p_dongle->wpid[0] == 0x80 && p_dongle->wpid[1] == 0x0D) {
p_dongle->is_texas_instruments = true;
p_dongle->classification = DONGLE_CLASSIFICATION_IS_LOGITECH_LIGHTSPEED;
}

}
p_device->key_known = pi.key_material_complete;

// if auto store is enabled, store to flash
if (g_logitacker_global_config.auto_store_sniffed_pairing_devices) {
//check if already stored
logitacker_devices_unifying_device_t dummy_device;
if (logitacker_flash_get_device(&dummy_device, p_device->rf_address) != NRF_SUCCESS) {
// not existing on flash create it
if (logitacker_devices_store_ram_device_to_flash(p_device->rf_address) == NRF_SUCCESS) {
NRF_LOG_INFO("device automatically stored to flash");
} else {
NRF_LOG_WARNING("failed to store device to flash");
}
} else {
NRF_LOG_INFO("device already exists on flash");
}
}
}

NRF_LOG_WARNING("Device pairing succeeded, switching mode to discover");
logitacker_enter_mode_discovery();
return;
Expand Down Expand Up @@ -411,6 +469,12 @@ bool processor_pair_device_parse_rsp2_pay(logitacker_processor_pair_device_ctx_t

memcpy(self->device_pairing_info.dongle_nonce, &self->tmp_rx_payload.data[3], 4); //nonce from dongle

if ((self->device_pairing_info.device_caps & LOGITACKER_DEVICE_CAPS_LINK_ENCRYPTION) > 0) {
logitacker_pairing_derive_key_material(&self->device_pairing_info);
logitacker_pairing_derive_key(&self->device_pairing_info);
self->device_pairing_info.key_material_complete = true;
}

// byte 7 onwards should be copy of request phase 2 (ignored)

return true;
Expand Down
4 changes: 4 additions & 0 deletions logitacker/logitacker_processor_pair_device.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,8 @@

logitacker_processor_t * new_processor_pair_device(uint8_t const *target_rf_address, logitacker_pairing_info_t const * pairing_info, app_timer_id_t timer_next_action);

// export methods for key calculation
bool logitacker_pairing_derive_key_material(logitacker_pairing_info_t * pi);
bool logitacker_pairing_derive_key(logitacker_pairing_info_t * pi);

#endif //LOGITACKER_PROCESSOR_PAIR_DEVICE_H
2 changes: 1 addition & 1 deletion logitacker/logitacker_processor_passive_enum.c
Original file line number Diff line number Diff line change
Expand Up @@ -327,7 +327,7 @@ void passive_enum_process_rx(logitacker_processor_passive_enum_ctx_t *self) {
pseudo_frame.pid = self->tmp_rx_payload.pid;
pseudo_frame.rx_channel = self->tmp_rx_payload.rx_channel;
pseudo_frame.data[0] = self->tmp_rx_payload.data[0];
pseudo_frame.data[1] = 0x51; //HID++ long with keep alive bit
pseudo_frame.data[1] = unifying_is_keep_alive ? 0x51 : 0x11; //HID++ long (with keep alive bit if it was set for the encrypted version)
memcpy(&pseudo_frame.data[2], m_hidpp_long_report_decryption_buffer, 19);
logitacker_unifying_payload_update_checksum(pseudo_frame.data, 22);
pseudo_frame.length = 22;
Expand Down
Loading

0 comments on commit f414073

Please sign in to comment.