mirror of
https://github.com/librekeys/pico-hsm-sf.git
synced 2026-07-28 08:01:04 -07:00
First commit. Attempting to emulate a CCID device. Not easy with RP2040
Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
This commit is contained in:
@@ -0,0 +1,17 @@
|
||||
cmake_minimum_required(VERSION 3.13)
|
||||
|
||||
include(pico_sdk_import.cmake)
|
||||
|
||||
project(hsm2040 C CXX ASM)
|
||||
|
||||
set(CMAKE_C_STANDARD 11)
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
|
||||
pico_sdk_init()
|
||||
|
||||
add_executable(hsm2040
|
||||
hsm2040.c
|
||||
)
|
||||
|
||||
pico_add_extra_outputs(hsm2040)
|
||||
target_link_libraries(hsm2040 PRIVATE pico_stdlib hardware_resets hardware_irq)
|
||||
@@ -0,0 +1,141 @@
|
||||
/**
|
||||
* Copyright (c) 2020 Raspberry Pi (Trading) Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef DEV_LOWLEVEL_H_
|
||||
#define DEV_LOWLEVEL_H_
|
||||
|
||||
#include "usb_common.h"
|
||||
|
||||
// Struct in which we keep the endpoint configuration
|
||||
typedef void (*usb_ep_handler)(uint8_t *buf, uint16_t len);
|
||||
struct usb_endpoint_configuration {
|
||||
const struct usb_endpoint_descriptor *descriptor;
|
||||
usb_ep_handler handler;
|
||||
|
||||
// Pointers to endpoint + buffer control registers
|
||||
// in the USB controller DPSRAM
|
||||
volatile uint32_t *endpoint_control;
|
||||
volatile uint32_t *buffer_control;
|
||||
volatile uint8_t *data_buffer;
|
||||
|
||||
// Toggle after each packet (unless replying to a SETUP)
|
||||
uint8_t next_pid;
|
||||
};
|
||||
|
||||
// Struct in which we keep the device configuration
|
||||
struct usb_device_configuration {
|
||||
const struct usb_device_descriptor *device_descriptor;
|
||||
const struct usb_interface_descriptor *interface_descriptor;
|
||||
const struct usb_configuration_descriptor *config_descriptor;
|
||||
const unsigned char *lang_descriptor;
|
||||
const unsigned char **descriptor_strings;
|
||||
// USB num endpoints is 16
|
||||
struct usb_endpoint_configuration endpoints[USB_NUM_ENDPOINTS];
|
||||
};
|
||||
|
||||
#define EP0_IN_ADDR (USB_DIR_IN | 0)
|
||||
#define EP0_OUT_ADDR (USB_DIR_OUT | 0)
|
||||
#define EP1_OUT_ADDR (USB_DIR_OUT | 1)
|
||||
#define EP2_IN_ADDR (USB_DIR_IN | 2)
|
||||
|
||||
// EP0 IN and OUT
|
||||
static const struct usb_endpoint_descriptor ep0_out = {
|
||||
.bLength = sizeof(struct usb_endpoint_descriptor),
|
||||
.bDescriptorType = USB_DT_ENDPOINT,
|
||||
.bEndpointAddress = EP0_OUT_ADDR, // EP number 0, OUT from host (rx to device)
|
||||
.bmAttributes = USB_TRANSFER_TYPE_CONTROL,
|
||||
.wMaxPacketSize = 64,
|
||||
.bInterval = 0
|
||||
};
|
||||
|
||||
static const struct usb_endpoint_descriptor ep0_in = {
|
||||
.bLength = sizeof(struct usb_endpoint_descriptor),
|
||||
.bDescriptorType = USB_DT_ENDPOINT,
|
||||
.bEndpointAddress = EP0_IN_ADDR, // EP number 0, OUT from host (rx to device)
|
||||
.bmAttributes = USB_TRANSFER_TYPE_CONTROL,
|
||||
.wMaxPacketSize = 64,
|
||||
.bInterval = 0
|
||||
};
|
||||
|
||||
// Descriptors
|
||||
static const struct usb_device_descriptor device_descriptor = {
|
||||
.bLength = sizeof(struct usb_device_descriptor),
|
||||
.bDescriptorType = USB_DT_DEVICE,
|
||||
.bcdUSB = 0x0200, // USB 1.1 device
|
||||
.bDeviceClass = 0, // Specified in interface descriptor
|
||||
.bDeviceSubClass = 0, // No subclass
|
||||
.bDeviceProtocol = 0, // No protocol
|
||||
.bMaxPacketSize0 = 64, // Max packet size for ep0
|
||||
.idVendor = 0x0D46, // Your vendor id
|
||||
.idProduct = 0x3010, // Your product ID
|
||||
.bcdDevice = 0, // No device revision number
|
||||
.iManufacturer = 1, // Manufacturer string index
|
||||
.iProduct = 2, // Product string index
|
||||
.iSerialNumber = 3, // No serial number
|
||||
.bNumConfigurations = 1 // One configuration
|
||||
};
|
||||
|
||||
static const struct usb_interface_descriptor interface_descriptor = {
|
||||
.bLength = sizeof(struct usb_interface_descriptor),
|
||||
.bDescriptorType = USB_DT_INTERFACE,
|
||||
.bInterfaceNumber = 0,
|
||||
.bAlternateSetting = 0,
|
||||
.bNumEndpoints = 2, // Interface has 2 endpoints
|
||||
.bInterfaceClass = 0x0b, // Vendor specific endpoint
|
||||
.bInterfaceSubClass = 0,
|
||||
.bInterfaceProtocol = 0,
|
||||
.iInterface = 4
|
||||
};
|
||||
|
||||
static const struct usb_endpoint_descriptor ep1_out = {
|
||||
.bLength = sizeof(struct usb_endpoint_descriptor),
|
||||
.bDescriptorType = USB_DT_ENDPOINT,
|
||||
.bEndpointAddress = EP1_OUT_ADDR, // EP number 1, OUT from host (rx to device)
|
||||
.bmAttributes = USB_TRANSFER_TYPE_BULK,
|
||||
.wMaxPacketSize = 64,
|
||||
.bInterval = 0
|
||||
};
|
||||
|
||||
static const struct usb_endpoint_descriptor ep2_in = {
|
||||
.bLength = sizeof(struct usb_endpoint_descriptor),
|
||||
.bDescriptorType = USB_DT_ENDPOINT,
|
||||
.bEndpointAddress = EP2_IN_ADDR, // EP number 2, IN from host (tx from device)
|
||||
.bmAttributes = USB_TRANSFER_TYPE_BULK,
|
||||
.wMaxPacketSize = 64,
|
||||
.bInterval = 0
|
||||
};
|
||||
|
||||
static const struct usb_configuration_descriptor config_descriptor = {
|
||||
.bLength = sizeof(struct usb_configuration_descriptor),
|
||||
.bDescriptorType = USB_DT_CONFIG,
|
||||
.wTotalLength = (sizeof(config_descriptor) +
|
||||
sizeof(interface_descriptor) +
|
||||
sizeof(ep1_out) +
|
||||
sizeof(ep2_in)),
|
||||
.bNumInterfaces = 1,
|
||||
.bConfigurationValue = 1, // Configuration 1
|
||||
.iConfiguration = 4, // No string
|
||||
.bmAttributes = 0xc0, // attributes: self powered, no remote wakeup
|
||||
.bMaxPower = 0x32 // 100ma
|
||||
};
|
||||
|
||||
static const unsigned char lang_descriptor[] = {
|
||||
4, // bLength
|
||||
0x03, // bDescriptorType == String Descriptor
|
||||
0x09, 0x04 // language id = us english
|
||||
};
|
||||
|
||||
static const unsigned char *descriptor_strings[] = {
|
||||
(unsigned char *) "Virtual SC", // Vendor
|
||||
(unsigned char *) "CCID", // Product
|
||||
(unsigned char *) "11223344",
|
||||
(unsigned char *) "Configuration rocks",
|
||||
(unsigned char *) "Interface rocks"
|
||||
};
|
||||
|
||||
#define USB_REQ_CCID 0xA1
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,62 @@
|
||||
# This is a copy of <PICO_SDK_PATH>/external/pico_sdk_import.cmake
|
||||
|
||||
# This can be dropped into an external project to help locate this SDK
|
||||
# It should be include()ed prior to project()
|
||||
|
||||
if (DEFINED ENV{PICO_SDK_PATH} AND (NOT PICO_SDK_PATH))
|
||||
set(PICO_SDK_PATH $ENV{PICO_SDK_PATH})
|
||||
message("Using PICO_SDK_PATH from environment ('${PICO_SDK_PATH}')")
|
||||
endif ()
|
||||
|
||||
if (DEFINED ENV{PICO_SDK_FETCH_FROM_GIT} AND (NOT PICO_SDK_FETCH_FROM_GIT))
|
||||
set(PICO_SDK_FETCH_FROM_GIT $ENV{PICO_SDK_FETCH_FROM_GIT})
|
||||
message("Using PICO_SDK_FETCH_FROM_GIT from environment ('${PICO_SDK_FETCH_FROM_GIT}')")
|
||||
endif ()
|
||||
|
||||
if (DEFINED ENV{PICO_SDK_FETCH_FROM_GIT_PATH} AND (NOT PICO_SDK_FETCH_FROM_GIT_PATH))
|
||||
set(PICO_SDK_FETCH_FROM_GIT_PATH $ENV{PICO_SDK_FETCH_FROM_GIT_PATH})
|
||||
message("Using PICO_SDK_FETCH_FROM_GIT_PATH from environment ('${PICO_SDK_FETCH_FROM_GIT_PATH}')")
|
||||
endif ()
|
||||
|
||||
set(PICO_SDK_PATH "${PICO_SDK_PATH}" CACHE PATH "Path to the Raspberry Pi Pico SDK")
|
||||
set(PICO_SDK_FETCH_FROM_GIT "${PICO_SDK_FETCH_FROM_GIT}" CACHE BOOL "Set to ON to fetch copy of SDK from git if not otherwise locatable")
|
||||
set(PICO_SDK_FETCH_FROM_GIT_PATH "${PICO_SDK_FETCH_FROM_GIT_PATH}" CACHE FILEPATH "location to download SDK")
|
||||
|
||||
if (NOT PICO_SDK_PATH)
|
||||
if (PICO_SDK_FETCH_FROM_GIT)
|
||||
include(FetchContent)
|
||||
set(FETCHCONTENT_BASE_DIR_SAVE ${FETCHCONTENT_BASE_DIR})
|
||||
if (PICO_SDK_FETCH_FROM_GIT_PATH)
|
||||
get_filename_component(FETCHCONTENT_BASE_DIR "${PICO_SDK_FETCH_FROM_GIT_PATH}" REALPATH BASE_DIR "${CMAKE_SOURCE_DIR}")
|
||||
endif ()
|
||||
FetchContent_Declare(
|
||||
pico_sdk
|
||||
GIT_REPOSITORY https://github.com/raspberrypi/pico-sdk
|
||||
GIT_TAG master
|
||||
)
|
||||
if (NOT pico_sdk)
|
||||
message("Downloading Raspberry Pi Pico SDK")
|
||||
FetchContent_Populate(pico_sdk)
|
||||
set(PICO_SDK_PATH ${pico_sdk_SOURCE_DIR})
|
||||
endif ()
|
||||
set(FETCHCONTENT_BASE_DIR ${FETCHCONTENT_BASE_DIR_SAVE})
|
||||
else ()
|
||||
message(FATAL_ERROR
|
||||
"SDK location was not specified. Please set PICO_SDK_PATH or set PICO_SDK_FETCH_FROM_GIT to on to fetch from git."
|
||||
)
|
||||
endif ()
|
||||
endif ()
|
||||
|
||||
get_filename_component(PICO_SDK_PATH "${PICO_SDK_PATH}" REALPATH BASE_DIR "${CMAKE_BINARY_DIR}")
|
||||
if (NOT EXISTS ${PICO_SDK_PATH})
|
||||
message(FATAL_ERROR "Directory '${PICO_SDK_PATH}' not found")
|
||||
endif ()
|
||||
|
||||
set(PICO_SDK_INIT_CMAKE_FILE ${PICO_SDK_PATH}/pico_sdk_init.cmake)
|
||||
if (NOT EXISTS ${PICO_SDK_INIT_CMAKE_FILE})
|
||||
message(FATAL_ERROR "Directory '${PICO_SDK_PATH}' does not appear to contain the Raspberry Pi Pico SDK")
|
||||
endif ()
|
||||
|
||||
set(PICO_SDK_PATH ${PICO_SDK_PATH} CACHE PATH "Path to the Raspberry Pi Pico SDK" FORCE)
|
||||
|
||||
include(${PICO_SDK_INIT_CMAKE_FILE})
|
||||
+134
@@ -0,0 +1,134 @@
|
||||
/*
|
||||
* Copyright (c) 2020 Raspberry Pi (Trading) Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef _USB_COMMON_H
|
||||
#define _USB_COMMON_H
|
||||
|
||||
#include "pico/types.h"
|
||||
#include "hardware/structs/usb.h"
|
||||
|
||||
// bmRequestType bit definitions
|
||||
#define USB_REQ_TYPE_STANDARD 0x00u
|
||||
#define USB_REQ_TYPE_TYPE_MASK 0x60u
|
||||
#define USB_REQ_TYPE_TYPE_CLASS 0x20u
|
||||
#define USB_REQ_TYPE_TYPE_VENDOR 0x40u
|
||||
|
||||
#define USB_REQ_TYPE_RECIPIENT_MASK 0x1fu
|
||||
#define USB_REQ_TYPE_RECIPIENT_DEVICE 0x00u
|
||||
#define USB_REQ_TYPE_RECIPIENT_INTERFACE 0x01u
|
||||
#define USB_REQ_TYPE_RECIPIENT_ENDPOINT 0x02u
|
||||
|
||||
#define USB_DIR_OUT 0x00u
|
||||
#define USB_DIR_IN 0x80u
|
||||
|
||||
#define USB_TRANSFER_TYPE_CONTROL 0x0
|
||||
#define USB_TRANSFER_TYPE_ISOCHRONOUS 0x1
|
||||
#define USB_TRANSFER_TYPE_BULK 0x2
|
||||
#define USB_TRANSFER_TYPE_INTERRUPT 0x3
|
||||
#define USB_TRANSFER_TYPE_BITS 0x3
|
||||
|
||||
// Descriptor types
|
||||
#define USB_DT_DEVICE 0x01
|
||||
#define USB_DT_CONFIG 0x02
|
||||
#define USB_DT_STRING 0x03
|
||||
#define USB_DT_INTERFACE 0x04
|
||||
#define USB_DT_ENDPOINT 0x05
|
||||
|
||||
#define USB_REQUEST_GET_STATUS 0x0
|
||||
#define USB_REQUEST_CLEAR_FEATURE 0x01
|
||||
#define USB_REQUEST_SET_FEATURE 0x03
|
||||
#define USB_REQUEST_SET_ADDRESS 0x05
|
||||
#define USB_REQUEST_GET_DESCRIPTOR 0x06
|
||||
#define USB_REQUEST_SET_DESCRIPTOR 0x07
|
||||
#define USB_REQUEST_GET_CONFIGURATION 0x08
|
||||
#define USB_REQUEST_SET_CONFIGURATION 0x09
|
||||
#define USB_REQUEST_GET_INTERFACE 0x0a
|
||||
#define USB_REQUEST_SET_INTERFACE 0x0b
|
||||
#define USB_REQUEST_SYNC_FRAME 0x0c
|
||||
|
||||
#define USB_REQUEST_MSC_GET_MAX_LUN 0xfe
|
||||
#define USB_REQUEST_MSC_RESET 0xff
|
||||
|
||||
#define USB_FEAT_ENDPOINT_HALT 0x00
|
||||
#define USB_FEAT_DEVICE_REMOTE_WAKEUP 0x01
|
||||
#define USB_FEAT_TEST_MODE 0x02
|
||||
|
||||
#define USB_DESCRIPTOR_TYPE_ENDPOINT 0x05
|
||||
|
||||
struct usb_setup_packet {
|
||||
uint8_t bmRequestType;
|
||||
uint8_t bRequest;
|
||||
uint16_t wValue;
|
||||
uint16_t wIndex;
|
||||
uint16_t wLength;
|
||||
} __packed;
|
||||
|
||||
struct usb_descriptor {
|
||||
uint8_t bLength;
|
||||
uint8_t bDescriptorType;
|
||||
};
|
||||
|
||||
struct usb_device_descriptor {
|
||||
uint8_t bLength;
|
||||
uint8_t bDescriptorType;
|
||||
uint16_t bcdUSB;
|
||||
uint8_t bDeviceClass;
|
||||
uint8_t bDeviceSubClass;
|
||||
uint8_t bDeviceProtocol;
|
||||
uint8_t bMaxPacketSize0;
|
||||
uint16_t idVendor;
|
||||
uint16_t idProduct;
|
||||
uint16_t bcdDevice;
|
||||
uint8_t iManufacturer;
|
||||
uint8_t iProduct;
|
||||
uint8_t iSerialNumber;
|
||||
uint8_t bNumConfigurations;
|
||||
} __packed;
|
||||
|
||||
struct usb_configuration_descriptor {
|
||||
uint8_t bLength;
|
||||
uint8_t bDescriptorType;
|
||||
uint16_t wTotalLength;
|
||||
uint8_t bNumInterfaces;
|
||||
uint8_t bConfigurationValue;
|
||||
uint8_t iConfiguration;
|
||||
uint8_t bmAttributes;
|
||||
uint8_t bMaxPower;
|
||||
} __packed;
|
||||
|
||||
struct usb_interface_descriptor {
|
||||
uint8_t bLength;
|
||||
uint8_t bDescriptorType;
|
||||
uint8_t bInterfaceNumber;
|
||||
uint8_t bAlternateSetting;
|
||||
uint8_t bNumEndpoints;
|
||||
uint8_t bInterfaceClass;
|
||||
uint8_t bInterfaceSubClass;
|
||||
uint8_t bInterfaceProtocol;
|
||||
uint8_t iInterface;
|
||||
} __packed;
|
||||
|
||||
struct usb_endpoint_descriptor {
|
||||
uint8_t bLength;
|
||||
uint8_t bDescriptorType;
|
||||
uint8_t bEndpointAddress;
|
||||
uint8_t bmAttributes;
|
||||
uint16_t wMaxPacketSize;
|
||||
uint8_t bInterval;
|
||||
} __packed;
|
||||
|
||||
struct usb_endpoint_descriptor_long {
|
||||
uint8_t bLength;
|
||||
uint8_t bDescriptorType;
|
||||
uint8_t bEndpointAddress;
|
||||
uint8_t bmAttributes;
|
||||
uint16_t wMaxPacketSize;
|
||||
uint8_t bInterval;
|
||||
uint8_t bRefresh;
|
||||
uint8_t bSyncAddr;
|
||||
} __attribute__((packed));
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user