start overall skeleton

This commit is contained in:
Shiz 2020-04-10 23:02:19 +02:00
parent 3bd8e7246f
commit a456bb3a56
10 changed files with 329 additions and 5 deletions

46
src/dongle.c Normal file
View File

@ -0,0 +1,46 @@
#pragma once
#include "dongle.h"
void nsl_dongle_init(struct nsl_dongle *dongle)
{
dongle->tport = nsl_transport_select();
nsl_smartcard_init(&dongle->smartcard);
}
void nsl_dongle_process_control(struct nsl_dongle *dongle, struct nsl_control_message *msg, struct nsl_response *resp)
{
switch (msg->command)
{
case NSL_CONTROL_MESSAGE_RESET:
nsl_smartcard_reset(&dongle->smartcard);
break;
case NSL_CONTROL_MESSAGE_LED_ON:
case NSL_CONTROL_MESSAGE_LED_OFF:
/* unmplemented */
break;
case NSL_CONTROL_MESSAGE_SET_MODE:
/* TODO */
break;
default:
/* ??? */
break;
}
}
void nsl_dongle_process_transfer(struct nsl_dongle *dongle, struct nsl_transfer_message *msg, struct nsl_response *resp)
{
nsl_smartcard_process(&dongle->smartcard, msg->data, msg->len, resp->data, resp->len);
}
void nsl_dongle_dispatch(struct nsl_dongle *dongle)
{
struct nsl_message msg;
struct nsl_response resp = { 0 };
nsl_transport_recv(dongle->tport, &msg);
if (msg.type == NSL_MESSAGE_CONTROL) {
nsl_dongle_process_control(dongle, &msg.control.ctrl, &resp);
} else {
nsl_dongle_process_transfer(dongle, &msg.control.xfer, &resp);
}
nsl_transport_send(dongle->tport, &resp);
}

14
src/dongle.h Normal file
View File

@ -0,0 +1,14 @@
#pragma once
#include "transport/transport.h"
#include "smartcard/smartcard.h"
struct nsl_dongle
{
struct nsl_transport *tport;
struct nsl_smartcard smartcard;
};
int nsl_dongle_init(struct nsl_dongle *);
int nsl_dongle_dispatch(struct nsl_dongle *);

37
src/message.h Normal file
View File

@ -0,0 +1,37 @@
#pragma once
enum nsl_message_type {
NSL_MESSAGE_CONTROL = 1,
NSL_MESSAGE_TRANSFER,
};
enum nsl_control_message_cmd {
NSL_CONTROL_MESSAGE_RESET = 0x2,
NSL_CONTROL_MESSAGE_LED_ON = 0x4,
NSL_CONTROL_MESSAGE_LED_OFF = 0x8,
NSL_CONTROL_MESSAGE_SET_MODE = 0x7,
};
struct nsl_control_message {
enum nsl_control_message_cmd command;
};
struct nsl_transfer_message {
};
struct nsl_message {
enum nsl_message_type type;
union {
struct nsl_control_message ctrl;
struct nsl_transfer_message xfer;
} contents;
};
struct nsl_response {
char buf[1024];
size_t n;
}
int nsl_message_process(void *arg, const struct nsl_message *msg, struct nsl_response *resp);

31
src/smartcard/apdu.h Normal file
View File

@ -0,0 +1,31 @@
#pragma once
struct nsl_smartcard_apdu {
uint8_t class;
uint8_t instruction;
uint8_t params[2];
} __attribute__((packed));
enum nsl_smartcard_apdu_instruction{
NSL_SMARTCARD_APDU_INS_VERIFY = 0x20,
NSL_SMARTCARD_APDU_INS_SELECT_DIR = 0xA4,
NSL_SMARTCARD_APDU_INS_DELETE_DIR = 0x0E,
NSL_SMARTCARD_APDU_INS_GET_DATA = 0xCA,
NSL_SMARTCARD_APDU_INS_CREATE_FILE = 0xE0,
NSL_SMARTCARD_APDU_INS_UPDATE_BIN = 0xD6,
NSL_SMARTCARD_APDU_INS_EXECUTE = 0x32,
NSL_SMARTCARD_APDU_INS_NET_LICENSE = 0x3A,
NSL_SMARTCARD_APDU_INS_CONTROL_PIN = 0xD4,
};
enum nsl_smartcard_apdu_data_tag {
NSL_SMARTCARD_APDU_DATA_SERIAL_NUMBER = 0x2,
NSL_SMARTCARD_APDU_DATA_DF_SPACE = 0x3,
NSL_SMARTCARD_APDU_DATA_CURRENT_DF = 0x4,
NSL_SMARTCARD_APDU_DATA_DEVICE_TYPE = 0x6,
NSL_SMARTCARD_APDU_DATA_DEVICE_SUBTYPE = 0x7,
NSL_SMARTCARD_APDU_DATA_USABLE_SPACE = 0x8,
NSL_SMARTCARD_APDU_DATA_E2_FILE = 0x9,
NSL_SMARTCARD_APDU_DATA_METADATA = 0xA,
NSL_SMARTCARD_APDU_DATA_CURRENT_TIME = 0xB,
};

10
src/smartcard/smartcard.h Normal file
View File

@ -0,0 +1,10 @@
#pragma once
#include <stdint.h>
struct nsl_smartcard {
};
int nsl_smartcard_init(struct nsl_smartcard *smartcard);
int nsl_smartcard_reset(struct nsl_smartcard *smartcard);
int nsl_smartcard_process(struct nsl_smartcard *smartcard, const uint8_t *inbuf, size_t inlen, uint8_t *outbuf, size_t outlen);

29
src/transport/transport.h Normal file
View File

@ -0,0 +1,29 @@
#include "../message.h"
typedef int (*nsl_transport_recv_message_t)(void *arg, struct nsl_message *msg);
typedef int (*nsl_transport_send_message_t)(void *arg, struct nsl_response *resp);
struct nsl_transport {
const char *name;
void *arg;
nsl_transport_recv_message_t recv;
nsl_transport_send_message_t send;
};
int nsl_transport_init(void);
struct nsl_transport *nsl_transport_select(void);
int nsl_transport_register(struct nsl_transport *tport);
static inline int nsl_transport_recv(struct nsl_transport *tport, struct nsl_message *msg)
{
return tport->recv(tport->arg, msg);
}
static inline int nsl_transport_send(struct nsl_transport *tport, struct nsl_response *resp)
{
return tport->send(tport->arg, resp);
}

View File

@ -0,0 +1,130 @@
#include <stdint.h>
#include <tusb.h>
#include "usb.h"
/* Copied and modified from TinyUSB to just have an IN endpoint */
#define TUD_HID_IN_DESC_LEN (9 + 9 + 7)
#define TUD_HID_IN_DESCRIPTOR(_itfnum, _stridx, _boot_protocol, _report_desc_len, _epin, _epsize, _ep_interval) \
/* Interface */\
9, TUSB_DESC_INTERFACE, _itfnum, 0, 2, TUSB_CLASS_HID, (uint8_t)((_boot_protocol) ? HID_SUBCLASS_BOOT : 0), _boot_protocol, _stridx,\
/* HID descriptor */\
9, HID_DESC_TYPE_HID, U16_TO_U8S_LE(0x0111), 0, 1, HID_DESC_TYPE_REPORT, U16_TO_U8S_LE(_report_desc_len),\
/* Endpoint In */\
7, TUSB_DESC_ENDPOINT, _epin, TUSB_XFER_INTERRUPT, U16_TO_U8S_LE(_epsize), _ep_interval
#define TUD_HID_REPORT_DESC_GENERIC_IN(report_size, ...) \
HID_USAGE_PAGE_N ( HID_USAGE_PAGE_VENDOR, 2 ),\
HID_USAGE ( 0x01 ),\
HID_COLLECTION ( HID_COLLECTION_APPLICATION ),\
/* Report ID if any */\
__VA_ARGS__ \
/* Input */ \
HID_USAGE ( 0x02 ),\
HID_LOGICAL_MIN ( 0x00 ),\
HID_LOGICAL_MAX ( 0xff ),\
HID_REPORT_SIZE ( 8 ),\
HID_REPORT_COUNT( report_size ),\
HID_INPUT ( HID_DATA | HID_VARIABLE | HID_ABSOLUTE ),\
HID_COLLECTION_END \
#define NSL_USB_PACKET_SIZE 8
#define NSL_USB_POLL_INTERVAL 1
enum nsl_usb_string_id {
NSL_USB_STRING_ID_NONE = 0,
NSL_USB_STRING_ID_MANUFACTURER,
NSL_USB_STRING_ID_PRODUCT,
NSL_USB_STRING_ID_COUNT,
};
#define NSL_USB_STRING(s) = { (TUSB_DESC_STRING << 8) | (2 * sizeof(s)), L##s }
static const uint16_t nsl_usb_string_manufacturer[] = NSL_USB_STRING(NSL_USB_MANUFACTURER_STRING);
static const uint16_t nsl_usb_string_product[] = NSL_USB_STRING(NSL_USB_PRODUCT_STRING);
static const uint16_t *nsl_usb_strings[] = {
[NSL_USB_STRING_ID_NONE] = "",
[NSL_USB_STRING_ID_MANUFACTURER] = nsl_usb_string_manufacturer,
[NSL_USB_STRING_ID_PRODUCT] = nsl_usb_string_product,
};
static const tusb_desc_device_t nsl_usb_device_desc = {
.bLength = sizeof(descriptor),
.bDescriptorType = TUSB_DESC_DEVICE,
.bcdUSB = 0x110, /* USB 1.1 */
.bDeviceClass = TUSB_CLASS_UNSPECIFIED,
.bDeviceSubClass = TUSB_CLASS_UNSPECIFIED,
.bDeviceProtocol = 0,
.bMaxPacketSize0 = NSL_USB_PACKET_SIZE,
.idVendor = NSL_USB_VID,
.idProduct = NSL_USB_PID,
.bcdDevice = (NSL_USB_VERSION_MAJOR << 8) | NSL_USB_VERSION_MINOR,
.iManufacturer = NSL_USB_STRING_ID_MANUFACTURER,
.iProduct = NSL_USB_STRING_ID_PRODUCT,
.iSerialNumber = NSL_USB_STRING_ID_NONE,
.bNumConfigurations = 1,
};
static const uint8_t nsl_usb_hid_report[] = {
TUD_HID_REPORT_DESC_GENERIC_IN(NSL_USB_PACKET_SIZE)
};
enum nsl_usb_interface_id = {
NSL_USB_INTERFACE_HID = 0,
NSL_USB_INTERFACE_COUNT,
};
#define NSL_USB_INTERFACE_SIZE (TUD_CONFIG_DESC_LEN + TUD_CONFIG_HID_INOUT_DESC_LEN)
static const uint8_t nsl_usb_config_desc[] = {
TUD_CONFIG_DESCRIPTOR(
1,
NSL_USB_INTERFACE_COUNT,
NSL_USB_STRING_ID_NONE,
NSL_USB_INTERFACE_SIZE,
0,
NSL_USB_POWER
),
TUD_HID_IN_DESCRIPTOR(
NSL_USB_INTERFACE_HID,
NSL_USB_STRING_ID_NONE,
HID_PROTOCOL_NONE,
sizeof(nsl_usb_hid_report),
0x81,
NSL_USB_PACKET_SIZE,
NSL_USB_POLL_INTERVAL
),
}
const uint16_t *tud_descriptor_string_cb(uint8_t i, uint16_t lang)
{
if (i >= NSL_USB_STRING_ID_COUNT) {
return NULL;
}
return nsl_usb_strings[i];
}
const uint8_t *tud_descriptor_device_cb(void)
{
return &nsl_usb_device_desc;
}
const uint8_t *tud_descriptor_configuration_cb(void)
{
return &nsl_usb_config_desc;
}
const uint8_t *tud_hid_descriptor_report_cb(void)
{
return &nsl_usb_hid_report;
}

View File

@ -0,0 +1,21 @@
#include <tusb.h>
uint16_t tud_hid_get_report_cb(uint8_t report_id, hid_report_type_t report_type, uint8_t* buffer, uint16_t reqlen)
{
(void) report_id;
(void) report_type;
(void) buffer;
(void) reqlen;
return 0;
}
void tud_hid_set_report_cb(uint8_t report_id, hid_report_type_t report_type, uint8_t const* buffer, uint16_t bufsize)
{
// This example doesn't use multiple report and report ID
(void) report_id;
(void) report_type;
// echo back anything we received from host
tud_hid_report(0, buffer, bufsize);
}

11
src/transport/usb/usb.h Normal file
View File

@ -0,0 +1,11 @@
#define NSL_USB_VID 0x471 /* NXP */
#define NSL_USB_PID 0x485E /* Senselock EliteIV */
#define NSL_USB_MANUFACTURER_STRING "Senselock"
#define NSL_USB_PRODUCT_STRING "Elite4 2.x"
#define NSL_USB_GUID { 0xF7, 0x38, 0x16, 0x17, 0xAD, 0x1E, 0x73, 0x48, 0xBA, 0x98, 0xC9, 0x66, 0xAB, 0xCF, 0x01, 0x42 }
#define NSL_USB_VERSION_MAJOR 3
#define NSL_USB_VERSION_MINOR 3
#define NSL_USB_POWER 100

View File

@ -1,5 +0,0 @@
#define NSL_USB_VID 0x471 /* NXP */
#define NSL_USB_PID 0x485E /* Senselock EliteIV */
#define NSL_USB_VENDOR_STRING "Senselock"
#define NSL_USB_PRODUCT_STRING "Elite4 2.x"
#define NSL_USB_GUID { 0xF7, 0x38, 0x16, 0x17, 0xAD, 0x1E, 0x73, 0x48, 0xBA, 0x98, 0xC9, 0x66, 0xAB, 0xCF, 0x01, 0x42 }