-
Notifications
You must be signed in to change notification settings - Fork 23
Expand file tree
/
Copy pathmain.c
More file actions
223 lines (197 loc) · 7.87 KB
/
main.c
File metadata and controls
223 lines (197 loc) · 7.87 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
/**
* @file main.c
* @brief Example of reading information about the TROPIC01 chip and its firmware using Libtropic and
* USB devkit.
* @copyright Copyright (c) 2020-2026 Tropic Square s.r.o.
*
* @license For the license see LICENSE.md in the root directory of this source tree.
*/
#include <stdio.h>
#include <string.h>
#include <time.h>
#include "libtropic.h"
#include "libtropic_common.h"
#include "libtropic_mbedtls_v4.h"
#include "libtropic_port_posix_usb_dongle.h"
#include "psa/crypto.h"
int main(void)
{
// Cosmetics: Disable buffering to keep output in order. You do not need to do this in your app if
// you don't care about stdout/stderr output being shuffled or you use stdout only (or different
// output mechanism altogether).
setvbuf(stdout, NULL, _IONBF, 0);
setvbuf(stderr, NULL, _IONBF, 0);
printf("==============================================\n");
printf("==== TROPIC01 Chip Identification Example ====\n");
printf("==============================================\n");
// Cryptographic function provider initialization.
//
// In production, this would typically be done only once,
// usually at the start of the application or before
// the first use of cryptographic functions but no later than
// the first occurrence of any Libtropic function
psa_status_t status = psa_crypto_init();
if (status != PSA_SUCCESS) {
fprintf(stderr, "PSA Crypto initialization failed, status=%d (psa_status_t)\n", status);
return -1;
}
// Libtropic handle.
//
// It is declared here (on stack) for
// simplicity. In production, you put it on heap if needed.
lt_handle_t lt_handle = {0};
// Device structure.
//
// Modify this according to your environment. Default values
// are compatible with RPi and our RPi shield.
lt_dev_posix_usb_dongle_t device = {0};
// LT_USB_DEVKIT_PATH is defined in CMakeLists.txt. Pass -DLT_USB_DEVKIT_PATH=<path>
// to cmake if you want to change it.
int dev_path_len = snprintf(device.dev_path, sizeof(device.dev_path), "%s", LT_USB_DEVKIT_PATH);
if (dev_path_len < 0 || (size_t)dev_path_len >= sizeof(device.dev_path)) {
fprintf(
stderr,
"Error: LT_USB_DEVKIT_PATH is too long for device.dev_path buffer (limit is %zu bytes).\n",
sizeof(device.dev_path));
mbedtls_psa_crypto_free();
return -1;
}
device.baud_rate = 115200;
lt_handle.l2.device = &device;
// Crypto abstraction layer (CAL) context.
lt_ctx_mbedtls_v4_t crypto_ctx;
lt_handle.l3.crypto_ctx = &crypto_ctx;
printf("Initializing handle...");
lt_ret_t ret = lt_init(<_handle);
if (LT_OK != ret) {
fprintf(stderr, "\nFailed to initialize handle, ret=%s\n", lt_ret_verbose(ret));
mbedtls_psa_crypto_free();
return -1;
}
printf("OK\n");
// First, we check versions of both updateable firmwares. To do that, we need TROPIC01 to **not**
// be in the Start-up Mode. If there are valid firmwares, TROPIC01 will begin to execute them
// automatically on boot.
printf("Sending reboot request...");
ret = lt_reboot(<_handle, TR01_REBOOT);
if (ret != LT_OK) {
fprintf(stderr, "\nlt_reboot() failed, ret=%s\n", lt_ret_verbose(ret));
lt_deinit(<_handle);
mbedtls_psa_crypto_free();
return -1;
}
printf("OK\n");
printf("Reading data from chip...\n");
uint8_t fw_ver[4];
ret = lt_get_info_riscv_fw_ver(<_handle, fw_ver);
if (ret != LT_OK) {
fprintf(stderr, "Failed to get RISC-V FW version, ret=%s\n", lt_ret_verbose(ret));
lt_deinit(<_handle);
mbedtls_psa_crypto_free();
return -1;
}
printf(" RISC-V FW version: %" PRIX8 ".%" PRIX8 ".%" PRIX8 " (.%" PRIX8 ")\n", fw_ver[3],
fw_ver[2], fw_ver[1], fw_ver[0]);
ret = lt_get_info_spect_fw_ver(<_handle, fw_ver);
if (ret != LT_OK) {
fprintf(stderr, "Failed to get SPECT FW version, ret=%s\n", lt_ret_verbose(ret));
lt_deinit(<_handle);
mbedtls_psa_crypto_free();
return -1;
}
printf(" SPECT FW version: %" PRIX8 ".%" PRIX8 ".%" PRIX8 " (.%" PRIX8 ")\n", fw_ver[3],
fw_ver[2], fw_ver[1], fw_ver[0]);
// We need to do the maintenance reboot to check bootloader version and FW bank headers in the
// Startup Mode.
printf("Sending maintenance reboot request...");
ret = lt_reboot(<_handle, TR01_MAINTENANCE_REBOOT);
if (ret != LT_OK) {
fprintf(stderr, "\nlt_reboot() failed, ret=%s\n", lt_ret_verbose(ret));
lt_deinit(<_handle);
mbedtls_psa_crypto_free();
return -1;
}
printf("OK\n");
printf("Reading data from chip...\n");
// When TROPIC01 is in Start-up Mode, we can get RISC-V bootloader version the same way as we got
// RISC-V FW version.
ret = lt_get_info_riscv_fw_ver(<_handle, fw_ver);
if (ret != LT_OK) {
fprintf(stderr, "Failed to get RISC-V bootloader version, ret=%s\n", lt_ret_verbose(ret));
lt_deinit(<_handle);
mbedtls_psa_crypto_free();
return -1;
}
printf(" RISC-V bootloader version: %" PRIX8 ".%" PRIX8 ".%" PRIX8 " (.%" PRIX8 ")\n",
fw_ver[3] & 0x7f, fw_ver[2], fw_ver[1], fw_ver[0]);
printf("Firmware bank headers:\n");
ret = lt_print_fw_header(<_handle, TR01_FW_BANK_FW1, printf);
if (ret != LT_OK) {
fprintf(stderr, "Failed to print TR01_FW_BANK_FW1 header, ret=%s\n", lt_ret_verbose(ret));
lt_deinit(<_handle);
mbedtls_psa_crypto_free();
return -1;
}
ret = lt_print_fw_header(<_handle, TR01_FW_BANK_FW2, printf);
if (ret != LT_OK) {
fprintf(stderr, "Failed to print TR01_FW_BANK_FW2 header, ret=%s\n", lt_ret_verbose(ret));
lt_deinit(<_handle);
mbedtls_psa_crypto_free();
return -1;
}
ret = lt_print_fw_header(<_handle, TR01_FW_BANK_SPECT1, printf);
if (ret != LT_OK) {
fprintf(stderr, "Failed to print TR01_FW_BANK_SPECT1 header, ret=%s\n", lt_ret_verbose(ret));
lt_deinit(<_handle);
mbedtls_psa_crypto_free();
return -1;
}
ret = lt_print_fw_header(<_handle, TR01_FW_BANK_SPECT2, printf);
if (ret != LT_OK) {
fprintf(stderr, "Failed to print TR01_FW_BANK_SPECT2 header, ret=%s\n", lt_ret_verbose(ret));
lt_deinit(<_handle);
mbedtls_psa_crypto_free();
return -1;
}
struct lt_chip_id_t chip_id = {0};
printf("Chip ID data:\n");
ret = lt_get_info_chip_id(<_handle, &chip_id);
if (ret != LT_OK) {
fprintf(stderr, "Failed to get chip ID, ret=%s\n", lt_ret_verbose(ret));
lt_deinit(<_handle);
mbedtls_psa_crypto_free();
return -1;
}
printf("---------------------------------------------------------\n");
ret = lt_print_chip_id(&chip_id, printf);
if (ret != LT_OK) {
fprintf(stderr, "Failed to print chip ID, ret=%s\n", lt_ret_verbose(ret));
lt_deinit(<_handle);
mbedtls_psa_crypto_free();
return -1;
}
printf("---------------------------------------------------------\n");
printf("Sending reboot request...");
ret = lt_reboot(<_handle, TR01_REBOOT);
if (ret != LT_OK) {
fprintf(stderr, "\nlt_reboot() failed, ret=%s\n", lt_ret_verbose(ret));
lt_deinit(<_handle);
mbedtls_psa_crypto_free();
return -1;
}
printf("OK!\n");
printf("Deinitializing handle...");
ret = lt_deinit(<_handle);
if (LT_OK != ret) {
fprintf(stderr, "\nFailed to deinitialize handle, ret=%s\n", lt_ret_verbose(ret));
mbedtls_psa_crypto_free();
return -1;
}
printf("OK\n");
// Cryptographic function provider deinitialization.
//
// In production, this would be done only once, typically
// during termination of the application.
mbedtls_psa_crypto_free();
return 0;
}