Wire Sysio Wire Sysion 1.0.0
Loading...
Searching...
No Matches
yubihsm_libusb.c File Reference
#include <libusb.h>
#include <string.h>
#include "yubihsm.h"
#include "internal.h"
#include "yubihsm_usb.h"
#include "debug_lib.h"
Include dependency graph for yubihsm_libusb.c:

Go to the source code of this file.

Classes

struct  state
 

Functions

void usb_set_serial (yh_backend *state, unsigned long serial)
 
void usb_close (yh_backend *state)
 
void usb_destroy (yh_backend **state)
 
yh_backendbackend_create (void)
 
bool usb_open_device (yh_backend *backend)
 
int usb_write (yh_backend *state, unsigned char *buf, long unsigned len)
 
int usb_read (yh_backend *state, unsigned char *buf, unsigned long *len)
 

Function Documentation

◆ backend_create()

yh_backend * backend_create ( void )

Definition at line 60 of file yubihsm_libusb.c.

60 {
61 yh_backend *backend = calloc(1, sizeof(yh_backend));
62 if (backend) {
63 libusb_init(&backend->ctx);
64 }
65 return backend;
66}
libusb_context * ctx

◆ usb_close()

void usb_close ( yh_backend * state)

Definition at line 40 of file yubihsm_libusb.c.

40 {
41 if (state && state->handle) {
42 libusb_release_interface(state->handle, 0);
43 libusb_close(state->handle);
44 state->handle = NULL;
45 }
46}
libusb_device_handle * handle
Here is the caller graph for this function:

◆ usb_destroy()

void usb_destroy ( yh_backend ** state)

Definition at line 48 of file yubihsm_libusb.c.

48 {
49 if (state && *state) {
51 if ((*state)->ctx) {
52 libusb_exit((*state)->ctx);
53 (*state)->ctx = NULL;
54 }
55 free(*state);
56 *state = NULL;
57 }
58}
void usb_close(yh_backend *state)
Here is the call graph for this function:

◆ usb_open_device()

bool usb_open_device ( yh_backend * backend)

Definition at line 68 of file yubihsm_libusb.c.

68 {
69 libusb_device **list;
70 libusb_device_handle *h = NULL;
71 ssize_t cnt = libusb_get_device_list(backend->ctx, &list);
72
73 if (backend->handle) {
74 usb_close(backend);
75 }
76
77 if (cnt < 0) {
78 DBG_ERR("Failed to get device list: %s", libusb_strerror(cnt));
79 return NULL;
80 }
81
82 for (ssize_t i = 0; i < cnt; i++) {
83 struct libusb_device_descriptor desc;
84 int ret = libusb_get_device_descriptor(list[i], &desc);
85 if (ret != 0) {
86 DBG_INFO("Failed to get descriptor for device %zd: %s", i,
87 libusb_strerror(ret));
88 continue;
89 }
90 if (desc.idVendor == YH_VID && desc.idProduct == YH_PID) {
91 ret = libusb_open(list[i], &h);
92 if (ret != 0 || h == NULL) {
93 DBG_INFO("Failed to open device for index %zd: %s", i,
94 libusb_strerror(ret));
95 continue;
96 }
97 if (backend->serial != 0) {
98 unsigned char data[16] = {0};
99
100 ret = libusb_get_string_descriptor_ascii(h, desc.iSerialNumber, data,
101 sizeof(data));
102
103 unsigned long devSerial = strtoul((char *) data, NULL, 10);
104
105 if (devSerial != backend->serial) {
106 DBG_INFO("Device %zd has serial %lu, not matching searched %lu", i,
107 devSerial, backend->serial);
108 goto next;
109 }
110 }
111
112 ret = libusb_claim_interface(h, 0);
113 if (ret != 0) {
114 DBG_ERR("Failed to claim interface: %s of device %zd",
115 libusb_strerror(ret), i);
116 goto next;
117 }
118
119 break;
120 next:
121 libusb_close(h);
122 h = NULL;
123 }
124 }
125
126 libusb_free_device_list(list, 1);
127 backend->handle = h;
128 if (h) {
129 // we set up a dummy read with a 1ms timeout here. The reason for doing this
130 // is that there might be data left in th e device buffers from earlier
131 // transactions, this should flush it.
132 unsigned char buf[YH_MSG_BUF_SIZE];
133 int transferred = 0;
134 if (libusb_bulk_transfer(h, 0x81, buf, sizeof(buf), &transferred, 1) == 0) {
135 DBG_INFO("%d bytes of stale data read from device", transferred);
136 }
137 return true;
138 } else {
139 return false;
140 }
141}
#define DBG_ERR(...)
Definition debug_lib.h:76
#define DBG_INFO(...)
Definition debug_lib.h:63
uint32_t next(octet_iterator &it, octet_iterator end)
Definition checked.h:137
unsigned long serial
#define YH_PID
Device product ID.
Definition yubihsm.h:99
#define YH_MSG_BUF_SIZE
Maximum length of message buffer.
Definition yubihsm.h:93
#define YH_VID
Device vendor ID.
Definition yubihsm.h:97
CK_RV ret
uint8_t buf[2048]
Here is the call graph for this function:

◆ usb_read()

int usb_read ( yh_backend * state,
unsigned char * buf,
unsigned long * len )

Definition at line 167 of file yubihsm_libusb.c.

167 {
168 int transferred = 0;
169 int ret;
170
171 if (state->handle == NULL) {
172 DBG_ERR("Handle is not connected");
173 return 0;
174 }
175
176 DBG_INFO("Doing usb read");
177
178 /* TODO: does this need to loop for all data?*/
179 ret = libusb_bulk_transfer(state->handle, 0x81, buf, *len, &transferred, 0);
180 if (ret != 0) {
181 DBG_ERR("Failed usb_read with ret: %d", ret);
182 return 0;
183 }
184 DBG_INFO("Read, transfer %d", transferred);
185 *len = transferred;
186 return 1;
187}
size_t len

◆ usb_set_serial()

void usb_set_serial ( yh_backend * state,
unsigned long serial )

Definition at line 36 of file yubihsm_libusb.c.

36 {
38}
uint32_t serial

◆ usb_write()

int usb_write ( yh_backend * state,
unsigned char * buf,
long unsigned len )

Definition at line 143 of file yubihsm_libusb.c.

143 {
144 int transferred = 0;
145 if (state->handle == NULL) {
146 DBG_ERR("Handle is not connected");
147 return 0;
148 }
149 /* TODO: does this need to loop and transmit several times? */
150 int ret =
151 libusb_bulk_transfer(state->handle, 0x01, buf, len, &transferred, 0);
152 DBG_INFO("Write of %lu %d, err %d", len, transferred, ret);
153 if (ret != 0 || transferred != (int) len) {
154 DBG_ERR("Transferred did not match len of write %d-%lu", transferred, len);
155 return 0;
156 }
157 if (len % 64 == 0) {
158 /* this writes the ZLP */
159 ret = libusb_bulk_transfer(state->handle, 0x01, buf, 0, &transferred, 0);
160 if (ret != 0) {
161 return 0;
162 }
163 }
164 return 1;
165}