Embedded SDK
Embedded SDK
Loading...
Searching...
No Matches
io.c
Go to the documentation of this file.
1/*****************************************************************************
2 * (c) 2021 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#include <stdint.h>
18#include <string.h>
19
20#include "os.h"
21#include "os_io_legacy_types.h"
22#include "os_io_seph_cmd.h"
23#include "os_io_seph_ux.h"
24#include "os_io_default_apdu.h"
25#include "seproxyhal_protocol.h"
26#include "write.h"
27#include "offsets.h"
28#include "io.h"
29
30#ifdef HAVE_IO_USB
31#include "usbd_ledger.h"
32#endif // HAVE_IO_USB
33
34#ifdef HAVE_BLE
35#include "ble_ledger.h"
36#endif // HAVE_BLE
37
38#ifdef HAVE_NFC_READER
39#include "nfc_ledger.h"
40#endif // HAVE_NFC_READER
41
42#ifdef HAVE_SWAP
43#include "swap.h"
44#endif
45
46#include "status_words.h"
47
48static uint8_t need_to_start_io;
49
50uint8_t G_io_seproxyhal_spi_buffer[OS_IO_SEPH_BUFFER_SIZE];
51
52#ifdef HAVE_BAGL
53WEAK void io_seproxyhal_display(const bagl_element_t *element)
54{
55 io_seph_ux_display_bagl_element(element);
56}
57#endif // HAVE_BAGL
58
59// This function can be used to declare a callback to SEPROXYHAL_TAG_TICKER_EVENT in the application
61
62WEAK unsigned char io_event(unsigned char channel)
63{
64 UNUSED(channel);
65 switch (G_io_seproxyhal_spi_buffer[0]) {
66 case SEPROXYHAL_TAG_BUTTON_PUSH_EVENT:
68 break;
69#ifdef HAVE_SE_TOUCH
70 case SEPROXYHAL_TAG_FINGER_EVENT:
72 break;
73#endif // HAVE_SE_TOUCH
74 case SEPROXYHAL_TAG_TICKER_EVENT:
77 break;
78 default:
80 break;
81 }
82
83 return 1;
84}
85
87{
88 need_to_start_io = 1;
89}
90
92{
93 int status = 0;
94
95 if (need_to_start_io) {
96#ifndef USE_OS_IO_STACK
97 io_seproxyhal_io_heartbeat();
98 io_seproxyhal_io_heartbeat();
99 io_seproxyhal_io_heartbeat();
100#endif // USE_OS_IO_STACK
101 os_io_start();
102 need_to_start_io = 0;
103 }
104
105#ifdef FUZZING
106 for (uint8_t retries = 5; retries && status <= 0; retries--) {
107#else
108 while (status <= 0) {
109#endif
110 status = io_legacy_apdu_rx(1);
111 }
112
113 return status;
114}
115
116WEAK int io_send_response_buffers(const buffer_t *rdatalist, size_t count, uint16_t sw)
117{
118 int status = 0;
119 size_t length = 0;
120
121 if (rdatalist && count > 0) {
122 for (size_t i = 0; i < count; i++) {
123 const buffer_t *rdata = &rdatalist[i];
124
125 if (!buffer_copy(rdata, G_io_tx_buffer + length, sizeof(G_io_tx_buffer) - length - 2)) {
126 return io_send_sw(SWO_INSUFFICIENT_MEMORY);
127 }
128 length += rdata->size - rdata->offset;
129 if (count > 1) {
130 PRINTF("<= FRAG (%u/%u) RData=%.*H\n", i + 1, count, rdata->size, rdata->ptr);
131 }
132 }
133 PRINTF("<= SW=%04X | RData=%.*H\n", sw, length, G_io_tx_buffer);
134 }
135 else {
136 PRINTF("<= SW=%04X | RData=\n", sw);
137 }
138
139 write_u16_be(G_io_tx_buffer, length, sw);
140 length += 2;
141
142#ifdef HAVE_SWAP
143 // If we are in swap mode and have validated a TX, we send it and immediately quit
145 PRINTF("Swap answer is processed. Send it\n");
146
147 if (io_legacy_apdu_tx(G_io_tx_buffer, length) >= 0) {
148 PRINTF("Returning to Exchange with status %d\n", (sw == SWO_SUCCESS));
149 *G_swap_signing_return_value_address = (sw == SWO_SUCCESS);
150 PRINTF("os_lib_end\n");
151 os_lib_end();
152 }
153 else {
154 PRINTF("Unrecoverable\n");
155#ifndef USE_OS_IO_STACK
156 os_io_stop();
157#endif // USE_OS_IO_STACK
158 os_sched_exit(-1);
159 }
160 }
161#endif // HAVE_SWAP
162
163 status = io_legacy_apdu_tx(G_io_tx_buffer, length);
164
165 if (status < 0) {
166 status = -1;
167 }
168
169 return status;
170}
171
172#ifdef STANDARD_APP_SYNC_RAPDU
173WEAK bool io_recv_and_process_event(void)
174{
175 int status = io_legacy_apdu_rx(1);
176 if (status > 0) {
177 return true;
178 }
179
180 return false;
181}
182#endif
bool buffer_copy(const buffer_t *buffer, uint8_t *out, size_t out_len)
Definition buffer.c:153
uint8_t G_io_seproxyhal_spi_buffer[OS_IO_SEPH_BUFFER_SIZE]
Definition io.c:50
WEAK unsigned char io_event(unsigned char channel)
Definition io.c:62
WEAK int io_send_response_buffers(const buffer_t *rdatalist, size_t count, uint16_t sw)
Definition io.c:116
WEAK void io_init()
Definition io.c:86
WEAK int io_recv_command()
Definition io.c:91
WEAK void app_ticker_event_callback(void)
Definition io.c:60
#define WEAK
Definition macros.h:8
const uint8_t * ptr
Definition buffer.h:19
size_t size
Pointer to byte buffer.
Definition buffer.h:20
size_t offset
Size of byte buffer.
Definition buffer.h:21
volatile bool G_called_from_swap
volatile bool G_swap_response_ready
volatile uint8_t * G_swap_signing_return_value_address
#define UX_TICKER_EVENT(seph_packet, callback)
Definition ux_bagl.h:517
#define UX_FINGER_EVENT(seph_packet)
Definition ux_bagl.h:512
void io_seproxyhal_display(const bagl_element_t *element)
#define UX_DEFAULT_EVENT()
Definition ux_bagl.h:544
#define UX_BUTTON_PUSH_EVENT(seph_packet)
Definition ux_bagl.h:501
void write_u16_be(uint8_t *ptr, size_t offset, uint16_t value)
Definition write.c:20