Skip to content

Commit aacf14a

Browse files
Add support for iAP2 over seph protocol
1 parent e055acf commit aacf14a

File tree

7 files changed

+225
-0
lines changed

7 files changed

+225
-0
lines changed

include/seproxyhal_protocol.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,9 @@ enum seph_protocol_evt_usb_mask {
124124
SEPROXYHAL_TAG_USB_EP_XFER_OUT = 0x04,
125125
};
126126

127+
// EVT : USB IAP2 DATA
128+
#define SEPROXYHAL_TAG_USB_IAP_EVENT (0x11)
129+
127130
// EVT : MCU CHUNK READ RSP
128131
#define SEPROXYHAL_TAG_UNSEC_CHUNK_EVENT (0x12)
129132

@@ -265,6 +268,9 @@ enum seph_protocol_cmd_usb_prepare_type {
265268
SEPROXYHAL_TAG_USB_EP_PREPARE_DIR_UNSTALL = 0x80,
266269
};
267270

271+
// CMD : USB SEND IAP2 DATA
272+
#define SEPROXYHAL_TAG_USB_IAP_SEND (0x51)
273+
268274
// CMD : REQUEST STATUS
269275
#define SEPROXYHAL_TAG_REQUEST_STATUS (0x52)
270276

io/include/os_io.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ typedef enum {
4646
OS_IO_PACKET_TYPE_USB_U2F_HID_CANCEL = 0x25,
4747
OS_IO_PACKET_TYPE_USB_U2F_HID_RAW = 0x26,
4848
OS_IO_PACKET_TYPE_USB_CDC_RAW = 0x29,
49+
OS_IO_PACKET_TYPE_USB_IAP_APDU = 0x2A,
4950

5051
OS_IO_PACKET_TYPE_BLE_MASK = 0x30,
5152
OS_IO_PACKET_TYPE_BLE_APDU = 0x30,
@@ -69,6 +70,7 @@ typedef enum {
6970
APDU_TYPE_USB_U2F_CANCEL = OS_IO_PACKET_TYPE_USB_U2F_HID_CANCEL,
7071
APDU_TYPE_BLE = OS_IO_PACKET_TYPE_BLE_APDU,
7172
APDU_TYPE_NFC = OS_IO_PACKET_TYPE_NFC_APDU,
73+
APDU_TYPE_IAP = OS_IO_PACKET_TYPE_USB_IAP_APDU,
7274
} apdu_type_t;
7375

7476
typedef enum {

io/src/os_io.c

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,9 @@
1313
#ifndef HAVE_CDCUSB
1414
#include "usbd_ledger_hid_u2f.h"
1515
#endif // HAVE_CDCUSB
16+
#ifdef HAVE_IAPUSB
17+
#include "usb_iap.h"
18+
#endif // HAVE_IAPUSB
1619
#endif // HAVE_IO_USB
1720

1821
#ifdef HAVE_BLE
@@ -177,6 +180,9 @@ int os_io_init(os_io_init_t *init)
177180

178181
#ifdef HAVE_IO_USB
179182
USBD_LEDGER_init(&init->usb, force_restart);
183+
#ifdef HAVE_IAPUSB
184+
USB_LEDGER_IAP_init();
185+
#endif // HAVE_IAPUSB
180186
#endif // HAVE_IO_USB
181187

182188
#ifdef HAVE_BLE
@@ -282,6 +288,13 @@ int os_io_rx_evt(unsigned char *buffer,
282288
case SEPROXYHAL_TAG_USB_EP_XFER_EVENT:
283289
status = USBD_LEDGER_rx_seph_evt(G_io_seph_buffer, length, buffer, buffer_max_length);
284290
break;
291+
292+
#ifdef HAVE_IAPUSB
293+
case SEPROXYHAL_TAG_USB_IAP_EVENT:
294+
status
295+
= USB_LEDGER_iap_rx_seph_evt(G_io_seph_buffer, length, buffer, buffer_max_length);
296+
break;
297+
#endif // HAVE_IAPUSB
285298
#endif // HAVE_IO_USB
286299

287300
#ifdef HAVE_BLE
@@ -354,6 +367,12 @@ int os_io_tx_cmd(uint8_t type,
354367
// TODO_IO test error code
355368
USBD_LEDGER_send(USBD_LEDGER_CLASS_HID, type, buffer, length, 0);
356369
break;
370+
371+
#ifdef HAVE_IAPUSB
372+
case OS_IO_PACKET_TYPE_USB_IAP_APDU:
373+
USB_LEDGER_IAP_send_apdu(buffer, length);
374+
break;
375+
#endif // HAVE_IAPUSB
357376
#ifdef HAVE_WEBUSB
358377
case OS_IO_PACKET_TYPE_USB_WEBUSB_APDU:
359378
USBD_LEDGER_send(USBD_LEDGER_CLASS_WEBUSB, type, buffer, length, 0);
@@ -473,6 +492,7 @@ unsigned int os_io_handle_ux_event_reject_apdu(void)
473492
case OS_IO_PACKET_TYPE_USB_CCID_APDU:
474493
case OS_IO_PACKET_TYPE_BLE_APDU:
475494
case OS_IO_PACKET_TYPE_NFC_APDU:
495+
case OS_IO_PACKET_TYPE_USB_IAP_APDU:
476496
os_io_tx_cmd(G_io_tx_buffer[0], err_buffer, sizeof(err_buffer), 0);
477497
break;
478498

io_legacy/include/os_io_legacy_types.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ typedef enum {
3434
IO_APDU_MEDIA_RAW,
3535
IO_APDU_MEDIA_U2F,
3636
IO_APDU_MEDIA_CDC,
37+
IO_APDU_MEDIA_IAP,
3738
} io_apdu_media_t;
3839

3940
typedef enum {

io_legacy/src/os_io_legacy.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,9 @@ static io_apdu_media_t get_media_from_apdu_type(apdu_type_t apdu_type)
105105
if (apdu_type == APDU_TYPE_NFC) {
106106
return IO_APDU_MEDIA_NFC;
107107
}
108+
if (apdu_type == APDU_TYPE_IAP) {
109+
return IO_APDU_MEDIA_IAP;
110+
}
108111
return IO_APDU_MEDIA_NONE;
109112
}
110113

@@ -153,6 +156,7 @@ void io_seproxyhal_io_heartbeat(void)
153156
case OS_IO_PACKET_TYPE_USB_U2F_HID_APDU:
154157
case OS_IO_PACKET_TYPE_BLE_APDU:
155158
case OS_IO_PACKET_TYPE_NFC_APDU:
159+
case OS_IO_PACKET_TYPE_USB_IAP_APDU:
156160
os_io_tx_cmd(G_io_rx_buffer[0], err_buffer, sizeof(err_buffer), 0);
157161
break;
158162

@@ -392,6 +396,7 @@ int io_legacy_apdu_rx(uint8_t handle_ux_events)
392396
case OS_IO_PACKET_TYPE_USB_U2F_HID_RAW:
393397
case OS_IO_PACKET_TYPE_BLE_APDU:
394398
case OS_IO_PACKET_TYPE_NFC_APDU:
399+
case OS_IO_PACKET_TYPE_USB_IAP_APDU:
395400
io_os_legacy_apdu_type = G_io_rx_buffer[0];
396401
if (os_perso_is_pin_set() == BOLOS_TRUE
397402
&& os_global_pin_is_validated() != BOLOS_TRUE) {

lib_stusb/include/usb_iap.h

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
/*****************************************************************************
2+
* (c) 2025 Ledger SAS.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*****************************************************************************/
16+
17+
#ifndef USB_LEDGER_IAP_H
18+
#define USB_LEDGER_IAP_H
19+
20+
/* Includes ------------------------------------------------------------------*/
21+
#include <stdint.h>
22+
#include "usbd_def.h"
23+
#include "usbd_ledger_types.h"
24+
25+
/* Exported enumerations -----------------------------------------------------*/
26+
27+
/* Exported defines --------------------------------------------------------*/
28+
29+
/* Exported types, structures, unions ----------------------------------------*/
30+
31+
/* Exported macros------------------------------------------------------------*/
32+
33+
/* Exported variables --------------------------------------------------------*/
34+
35+
/* Exported functions --------------------------------------------------------*/
36+
37+
void USB_LEDGER_IAP_init(void);
38+
39+
int USB_LEDGER_iap_rx_seph_evt(uint8_t *seph_buffer,
40+
uint16_t seph_buffer_length,
41+
uint8_t *apdu_buffer,
42+
uint16_t apdu_buffer_max_length);
43+
44+
int USB_LEDGER_IAP_send_apdu(const uint8_t *apdu_buf, uint16_t apdu_buf_length);
45+
46+
#endif // USBD_LEDGER_WEBUSB_H

lib_stusb/src/usb_iap.c

Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
/*****************************************************************************
2+
* (c) 2025 Ledger SAS.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*****************************************************************************/
16+
17+
/* Includes ------------------------------------------------------------------*/
18+
#include "ledger_protocol.h"
19+
#include "usbd_ledger.h"
20+
#include "usb_iap.h"
21+
#include "seproxyhal_protocol.h"
22+
23+
/* Private enumerations ------------------------------------------------------*/
24+
25+
/* Private defines------------------------------------------------------------*/
26+
27+
/* Private types, structures, unions -----------------------------------------*/
28+
29+
/* Private macros-------------------------------------------------------------*/
30+
31+
/* Private functions prototypes ----------------------------------------------*/
32+
33+
/* Private variables ---------------------------------------------------------*/
34+
static ledger_protocol_t protocol_data = {};
35+
36+
/* Exported variables --------------------------------------------------------*/
37+
38+
/* Private functions ---------------------------------------------------------*/
39+
static void USB_LEDGER_IAP_send_packet(uint8_t *buffer, uint16_t length)
40+
{
41+
if (length) {
42+
unsigned char hdr[3];
43+
hdr[0] = SEPROXYHAL_TAG_USB_IAP_SEND;
44+
hdr[1] = length >> 8;
45+
hdr[2] = length;
46+
os_io_tx_cmd(OS_IO_PACKET_TYPE_SEPH, hdr, 3, NULL);
47+
os_io_tx_cmd(OS_IO_PACKET_TYPE_SEPH, buffer, length, NULL);
48+
}
49+
}
50+
51+
/* Exported functions --------------------------------------------------------*/
52+
53+
void USB_LEDGER_IAP_init(void)
54+
{
55+
memset(&protocol_data, 0, sizeof(protocol_data));
56+
protocol_data.mtu = sizeof(USBD_LEDGER_protocol_chunk_buffer);
57+
58+
LEDGER_PROTOCOL_init(&protocol_data, OS_IO_PACKET_TYPE_USB_IAP_APDU);
59+
}
60+
61+
int USB_LEDGER_IAP_send_apdu(const uint8_t *apdu_buf, uint16_t apdu_buf_length)
62+
{
63+
uint32_t status = -1;
64+
65+
ledger_protocol_result_t result = LEDGER_PROTOCOL_tx(&protocol_data,
66+
apdu_buf,
67+
apdu_buf_length,
68+
USBD_LEDGER_protocol_chunk_buffer,
69+
sizeof(USBD_LEDGER_protocol_chunk_buffer),
70+
0);
71+
72+
if (result != LP_SUCCESS) {
73+
goto error;
74+
}
75+
if (protocol_data.tx_chunk_length >= 2) {
76+
USB_LEDGER_IAP_send_packet(USBD_LEDGER_protocol_chunk_buffer,
77+
protocol_data.tx_chunk_length);
78+
}
79+
80+
while (protocol_data.tx_apdu_buffer) {
81+
result = LEDGER_PROTOCOL_tx(&protocol_data,
82+
NULL,
83+
0,
84+
USBD_LEDGER_protocol_chunk_buffer,
85+
sizeof(USBD_LEDGER_protocol_chunk_buffer),
86+
0);
87+
if (result != LP_SUCCESS) {
88+
goto error;
89+
}
90+
if (protocol_data.tx_chunk_length >= 2) {
91+
USB_LEDGER_IAP_send_packet(USBD_LEDGER_protocol_chunk_buffer,
92+
protocol_data.tx_chunk_length);
93+
}
94+
}
95+
status = 0;
96+
97+
error:
98+
return status;
99+
}
100+
101+
int USB_LEDGER_iap_rx_seph_evt(uint8_t *seph_buffer,
102+
uint16_t seph_buffer_length,
103+
uint8_t *apdu_buffer,
104+
uint16_t apdu_buffer_max_length)
105+
{
106+
int status = -1;
107+
108+
if (seph_buffer[1] != SEPROXYHAL_TAG_USB_IAP_EVENT || seph_buffer_length < 4) {
109+
goto error;
110+
}
111+
112+
ledger_protocol_result_t result = LEDGER_PROTOCOL_rx(&protocol_data,
113+
&seph_buffer[4],
114+
seph_buffer_length - 4,
115+
USBD_LEDGER_protocol_chunk_buffer,
116+
sizeof(USBD_LEDGER_protocol_chunk_buffer),
117+
apdu_buffer,
118+
apdu_buffer_max_length,
119+
0);
120+
if (result != LP_SUCCESS) {
121+
goto error;
122+
}
123+
124+
if (protocol_data.tx_chunk_length > 0) {
125+
// Tx chunck was generated while processing rx
126+
// For example MTU request -> MTU response
127+
USB_LEDGER_IAP_send_packet(USBD_LEDGER_protocol_chunk_buffer,
128+
protocol_data.tx_chunk_length);
129+
protocol_data.tx_chunk_length = 0;
130+
}
131+
132+
if (protocol_data.rx_apdu_status == APDU_STATUS_COMPLETE) {
133+
// Should not happen as it is verified by LEDGER_PROTOCOL_rx() already
134+
if (apdu_buffer_max_length < protocol_data.rx_apdu_length) {
135+
status = -1;
136+
}
137+
else {
138+
status = protocol_data.rx_apdu_length;
139+
}
140+
protocol_data.rx_apdu_status = APDU_STATUS_WAITING;
141+
}
142+
143+
error:
144+
return status;
145+
}

0 commit comments

Comments
 (0)