Skip to content

Commit ff54461

Browse files
Support retrieving derivation_path from elf and use it for derivation
1 parent 4d03434 commit ff54461

9 files changed

Lines changed: 393 additions & 10 deletions

File tree

.vscode/settings.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
"emulate.h": "c",
1212
"os.h": "c",
1313
"os_types.h": "c",
14-
"errors.h": "c"
14+
"errors.h": "c",
15+
"launcher.h": "c"
1516
}
1617
}

CHANGELOG.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,12 @@ All notable changes to this project will be documented in this file.
55
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
66
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
77

8-
## [0.25.10] 2025-12-02
8+
## [0.25.10] 2025-12-04
99

1010
### Added
1111
- Support throwing exceptions from OS (mainly Cx syscalls) like on real devices
1212
- Support retrieving appflags from elf and use it for derivation
13+
- Support retrieving derivation_path from elf and use it for derivation
1314

1415
## [0.25.9] 2025-11-19
1516

speculos/main.py

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,8 +52,11 @@ class ElfInfo:
5252
shared_ram_addr: int = 0
5353
shared_ram_size: int = 0
5454
pic_init_addr: int = 0
55+
derivation_path: bytes = b''
5556

5657

58+
BOLOS_TAG_DERIVEPATH = 0x04
59+
5760
DEFAULT_SEED = ('glory promote mansion idle axis finger extra february uncover one trip resource lawn turtle enact '
5861
'monster seven myth punch hobby comfort wild raise skin')
5962

@@ -138,6 +141,38 @@ def get_elf_infos(app_path, use_bagl, args):
138141
supp_ram_section = elf.get_section_by_name('.rfbss')
139142
ei.ram_addr, ei.ram_size = \
140143
(supp_ram_section['sh_addr'], supp_ram_section['sh_size']) if supp_ram_section is not None else (0, 0)
144+
145+
# look at install_parameters
146+
install_parameters = symtab_section.get_symbol_by_name('install_parameters')
147+
if install_parameters is not None:
148+
sym_addr = install_parameters[0]['st_value']
149+
sym_size = install_parameters[0]['st_size']
150+
# 2. Get section containing the symbol
151+
sec_offset_in_file = text_section['sh_offset']
152+
sec_addr_in_memory = text_section['sh_addr']
153+
154+
# 3. Compute offset of symbol in ELF
155+
file_offset = sec_offset_in_file + (sym_addr - sec_addr_in_memory)
156+
# 4. Read bytes
157+
fp.seek(file_offset)
158+
data = fp.read(sym_size)
159+
# 5. Parse TLVs to find APP_FLAGS one
160+
offset = 0
161+
while offset < sym_size:
162+
tag = data[offset]
163+
offset += 1
164+
len = data[offset]
165+
offset += 1
166+
if len == 0x81:
167+
len = data[offset]
168+
offset += 1
169+
elif len == 0x82:
170+
len = int.from_bytes(data[offset: offset + 2], 'big')
171+
offset += 2
172+
if tag == BOLOS_TAG_DERIVEPATH:
173+
ei.derivation_path = data[offset: offset + len]
174+
offset += len
175+
141176
ei.stack_size = estack - ei.stack_addr
142177
return ei
143178

@@ -272,6 +307,11 @@ def run_qemu(s1: socket.socket, s2: socket.socket, args: argparse.Namespace) ->
272307
lib_arg += f':{1 if args.load_nvram else 0}'
273308
lib_arg += f':{1 if args.save_nvram else 0}'
274309
lib_arg += f':{1 if not use_bagl else 0}'
310+
if len(ei.derivation_path) > 0:
311+
lib_arg += f':{ei.derivation_path.hex()}'
312+
else:
313+
# if no derivationèpath found in binary, use 0 to indicate to launcher that it's not valid
314+
lib_arg += ':0'
275315
argv.append(lib_arg)
276316

277317
# for NBGL apps, fonts binary file is mandatory before API Level 23

src/bolos/io/sdk/include/errors.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@
1919
#if !defined(ERRORS_H)
2020
#define ERRORS_H
2121

22+
#include "os_errors.h"
23+
2224
/**
2325
* Applications-reserved error codes ranges.
2426
* The Operating System do not use any error code within these ranges.
@@ -124,8 +126,6 @@ enum sdk_generic_identifiers {
124126
#define SWO_IOL_BLE_0C (ERR_IOL_BLE + ERR_GEN_ID_0C) // 0x150C
125127
#endif // HAVE_BLE
126128

127-
#define SWO_SEC_PIN_15 0x5515
128-
129129
/**
130130
* The process is successful.
131131
*/
Lines changed: 210 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,210 @@
1+
#ifndef OS_ERRORS_H
2+
#define OS_ERRORS_H
3+
4+
#include <stdint.h>
5+
6+
/**
7+
* The OS error codes are encoded on two bytes (0xabcd), with the following
8+
* structure:
9+
* 'a': The error code category,
10+
* 'b': The error code subcategory,
11+
* 'cd': The error code identifier (depends on the two previous fields).
12+
* The 'B000' - 'EFFF' range is reserved for applications, if they want to
13+
* have the same uniqueness mechanism in their error codes.
14+
*/
15+
16+
#define ERR_PAR_RANGE 0x4000
17+
#define ERR_SEC_RANGE 0x5000
18+
19+
// Generic subcategories.
20+
#define ERR_OS_GEN_SUB_01 0x0100
21+
#define ERR_OS_GEN_SUB_02 0x0200
22+
#define ERR_OS_GEN_SUB_03 0x0300
23+
#define ERR_OS_GEN_SUB_04 0x0400
24+
#define ERR_OS_GEN_SUB_05 0x0500
25+
#define ERR_OS_GEN_SUB_06 0x0600
26+
#define ERR_OS_GEN_SUB_07 0x0700
27+
#define ERR_OS_GEN_SUB_08 0x0800
28+
#define ERR_OS_GEN_SUB_09 0x0900
29+
#define ERR_OS_GEN_SUB_0D 0x0D00
30+
#define ERR_OS_GEN_SUB_0E 0x0E00
31+
32+
// Generic identifiers.
33+
enum generic_identifiers {
34+
ERR_OS_GEN_ID_01 = 0x01,
35+
ERR_OS_GEN_ID_02,
36+
ERR_OS_GEN_ID_03,
37+
ERR_OS_GEN_ID_04,
38+
ERR_OS_GEN_ID_05,
39+
ERR_OS_GEN_ID_06,
40+
ERR_OS_GEN_ID_07,
41+
ERR_OS_GEN_ID_08,
42+
ERR_OS_GEN_ID_09,
43+
ERR_OS_GEN_ID_0A,
44+
ERR_OS_GEN_ID_0B,
45+
ERR_OS_GEN_ID_0C,
46+
ERR_OS_GEN_ID_0D,
47+
ERR_OS_GEN_ID_0E,
48+
ERR_OS_GEN_ID_0F,
49+
ERR_OS_GEN_ID_10,
50+
ERR_OS_GEN_ID_11,
51+
ERR_OS_GEN_ID_12,
52+
ERR_OS_GEN_ID_13,
53+
ERR_OS_GEN_ID_14,
54+
ERR_OS_GEN_ID_15,
55+
ERR_OS_GEN_ID_16,
56+
ERR_OS_GEN_ID_17,
57+
ERR_OS_GEN_ID_18,
58+
ERR_OS_GEN_ID_19,
59+
ERR_OS_GEN_ID_1A,
60+
ERR_OS_GEN_ID_1B,
61+
ERR_OS_GEN_ID_1C,
62+
ERR_OS_GEN_ID_1D,
63+
ERR_OS_GEN_ID_1E,
64+
ERR_OS_GEN_ID_1F,
65+
ERR_OS_GEN_ID_20,
66+
ERR_OS_GEN_ID_21,
67+
ERR_OS_GEN_ID_22,
68+
ERR_OS_GEN_ID_23,
69+
ERR_OS_GEN_ID_24,
70+
ERR_OS_GEN_ID_25,
71+
ERR_OS_GEN_ID_26,
72+
ERR_OS_GEN_ID_27,
73+
ERR_OS_GEN_ID_28,
74+
ERR_OS_GEN_ID_29,
75+
ERR_OS_GEN_ID_2A,
76+
ERR_OS_GEN_ID_2B,
77+
ERR_OS_GEN_ID_2C,
78+
ERR_OS_GEN_ID_2D,
79+
ERR_OS_GEN_ID_2E,
80+
ERR_OS_GEN_ID_2F,
81+
ERR_OS_GEN_ID_30,
82+
ERR_OS_GEN_ID_31,
83+
ERR_OS_GEN_ID_32,
84+
ERR_OS_GEN_ID_33,
85+
ERR_OS_GEN_ID_34,
86+
ERR_OS_GEN_ID_35,
87+
ERR_OS_GEN_ID_36,
88+
ERR_OS_GEN_ID_37,
89+
ERR_OS_GEN_ID_38,
90+
ERR_OS_GEN_ID_39,
91+
ERR_OS_GEN_ID_3A,
92+
ERR_OS_GEN_ID_3B,
93+
ERR_OS_GEN_ID_3C,
94+
ERR_OS_GEN_ID_3D,
95+
ERR_OS_GEN_ID_3E,
96+
ERR_OS_GEN_ID_3F,
97+
ERR_OS_GEN_ID_40,
98+
ERR_OS_GEN_ID_41,
99+
ERR_OS_GEN_ID_42,
100+
ERR_OS_GEN_ID_43,
101+
ERR_OS_GEN_ID_44,
102+
ERR_OS_GEN_ID_45,
103+
ERR_OS_GEN_ID_46,
104+
ERR_OS_GEN_ID_47,
105+
ERR_OS_GEN_ID_48,
106+
ERR_OS_GEN_ID_49,
107+
ERR_OS_GEN_ID_4A,
108+
ERR_OS_GEN_ID_4B,
109+
ERR_OS_GEN_ID_4C,
110+
ERR_OS_GEN_ID_4D,
111+
ERR_OS_GEN_ID_4E,
112+
ERR_OS_GEN_ID_4F,
113+
ERR_OS_GEN_ID_50,
114+
ERR_OS_GEN_ID_51,
115+
ERR_OS_GEN_ID_52,
116+
ERR_OS_GEN_ID_53,
117+
ERR_OS_GEN_ID_54,
118+
ERR_OS_GEN_ID_55,
119+
ERR_OS_GEN_ID_56,
120+
ERR_OS_GEN_ID_57,
121+
ERR_OS_GEN_ID_58,
122+
ERR_OS_GEN_ID_59,
123+
ERR_OS_GEN_ID_5A,
124+
ERR_OS_GEN_ID_5B,
125+
ERR_OS_GEN_ID_5C,
126+
ERR_OS_GEN_ID_5D,
127+
ERR_OS_GEN_ID_5E,
128+
ERR_OS_GEN_ID_5F,
129+
ERR_OS_GEN_ID_60,
130+
ERR_OS_GEN_ID_61,
131+
ERR_OS_GEN_ID_62,
132+
ERR_OS_GEN_ID_63,
133+
ERR_OS_GEN_ID_64,
134+
ERR_OS_GEN_ID_65,
135+
};
136+
137+
/**
138+
* OS (except cryptography) parameter-related issues are categorized into:
139+
* Lengths mismatch in functions (LEN),
140+
* Values mismatch in functions (VAL).
141+
*/
142+
#define ERR_PAR_LEN (ERR_PAR_RANGE + ERR_OS_GEN_SUB_01)
143+
#define ERR_PAR_VAL (ERR_PAR_RANGE + ERR_OS_GEN_SUB_02)
144+
145+
#define SWO_PAR_VAL_01 (ERR_PAR_VAL + ERR_OS_GEN_ID_01) // 0x4201
146+
#define SWO_PAR_VAL_02 (ERR_PAR_VAL + ERR_OS_GEN_ID_02) // 0x4202
147+
#define SWO_PAR_VAL_03 (ERR_PAR_VAL + ERR_OS_GEN_ID_03) // 0x4203
148+
#define SWO_PAR_VAL_04 (ERR_PAR_VAL + ERR_OS_GEN_ID_04) // 0x4204
149+
#define SWO_PAR_VAL_05 (ERR_PAR_VAL + ERR_OS_GEN_ID_05) // 0x4205
150+
#define SWO_PAR_VAL_06 (ERR_PAR_VAL + ERR_OS_GEN_ID_06) // 0x4206
151+
#define SWO_PAR_VAL_07 (ERR_PAR_VAL + ERR_OS_GEN_ID_07) // 0x4207
152+
#define SWO_PAR_VAL_08 (ERR_PAR_VAL + ERR_OS_GEN_ID_08) // 0x4208
153+
#define SWO_PAR_VAL_09 (ERR_PAR_VAL + ERR_OS_GEN_ID_09) // 0x4209
154+
#define SWO_PAR_VAL_0A (ERR_PAR_VAL + ERR_OS_GEN_ID_0A) // 0x420A
155+
#define SWO_PAR_VAL_0B (ERR_PAR_VAL + ERR_OS_GEN_ID_0B) // 0x420B
156+
#define SWO_PAR_VAL_0C (ERR_PAR_VAL + ERR_OS_GEN_ID_0C) // 0x420C
157+
#define SWO_PAR_VAL_0D (ERR_PAR_VAL + ERR_OS_GEN_ID_0D) // 0x420D
158+
#define SWO_PAR_VAL_0E (ERR_PAR_VAL + ERR_OS_GEN_ID_0E) // 0x420E
159+
#define SWO_PAR_VAL_0F (ERR_PAR_VAL + ERR_OS_GEN_ID_0F) // 0x420F
160+
#define SWO_PAR_VAL_10 (ERR_PAR_VAL + ERR_OS_GEN_ID_10) // 0x4210
161+
#define SWO_PAR_VAL_11 (ERR_PAR_VAL + ERR_OS_GEN_ID_11) // 0x4211
162+
#define SWO_PAR_VAL_12 (ERR_PAR_VAL + ERR_OS_GEN_ID_12) // 0x4212
163+
#define SWO_PAR_VAL_13 (ERR_PAR_VAL + ERR_OS_GEN_ID_13) // 0x4213
164+
#define SWO_PAR_VAL_14 (ERR_PAR_VAL + ERR_OS_GEN_ID_14) // 0x4214
165+
#define SWO_PAR_VAL_15 (ERR_PAR_VAL + ERR_OS_GEN_ID_15) // 0x4215
166+
#define SWO_PAR_VAL_16 (ERR_PAR_VAL + ERR_OS_GEN_ID_16) // 0x4216
167+
#define SWO_PAR_VAL_17 (ERR_PAR_VAL + ERR_OS_GEN_ID_17) // 0x4217
168+
#define SWO_PAR_VAL_18 (ERR_PAR_VAL + ERR_OS_GEN_ID_18) // 0x4218
169+
#define SWO_PAR_VAL_19 (ERR_PAR_VAL + ERR_OS_GEN_ID_19) // 0x4219
170+
#define SWO_PAR_VAL_1A (ERR_PAR_VAL + ERR_OS_GEN_ID_1A) // 0x421A
171+
#define SWO_PAR_VAL_1B (ERR_PAR_VAL + ERR_OS_GEN_ID_1B) // 0x421B
172+
#define SWO_PAR_VAL_1C (ERR_PAR_VAL + ERR_OS_GEN_ID_1C) // 0x421C
173+
#define SWO_PAR_VAL_1D (ERR_PAR_VAL + ERR_OS_GEN_ID_1D) // 0x421D
174+
#define SWO_PAR_VAL_1E (ERR_PAR_VAL + ERR_OS_GEN_ID_1E) // 0x421E
175+
#define SWO_PAR_VAL_1F (ERR_PAR_VAL + ERR_OS_GEN_ID_1F) // 0x421F
176+
#define SWO_PAR_VAL_20 (ERR_PAR_VAL + ERR_OS_GEN_ID_20) // 0x4220
177+
#define SWO_PAR_VAL_21 (ERR_PAR_VAL + ERR_OS_GEN_ID_21) // 0x4221
178+
#define SWO_PAR_VAL_22 (ERR_PAR_VAL + ERR_OS_GEN_ID_22) // 0x4222
179+
#define SWO_PAR_VAL_23 (ERR_PAR_VAL + ERR_OS_GEN_ID_23) // 0x4223
180+
#define SWO_PAR_VAL_24 (ERR_PAR_VAL + ERR_OS_GEN_ID_24) // 0x4224
181+
#define SWO_PAR_VAL_25 (ERR_PAR_VAL + ERR_OS_GEN_ID_25) // 0x4225
182+
#define SWO_PAR_VAL_26 (ERR_PAR_VAL + ERR_OS_GEN_ID_26) // 0x4226
183+
#define SWO_PAR_VAL_27 (ERR_PAR_VAL + ERR_OS_GEN_ID_27) // 0x4227
184+
#define SWO_PAR_VAL_28 (ERR_PAR_VAL + ERR_OS_GEN_ID_28) // 0x4228
185+
#define SWO_PAR_VAL_29 (ERR_PAR_VAL + ERR_OS_GEN_ID_29) // 0x4229
186+
#define SWO_PAR_VAL_2A (ERR_PAR_VAL + ERR_OS_GEN_ID_2A) // 0x422A
187+
#define SWO_PAR_VAL_2B (ERR_PAR_VAL + ERR_OS_GEN_ID_2B) // 0x422B
188+
#define SWO_PAR_VAL_2C (ERR_PAR_VAL + ERR_OS_GEN_ID_2C) // 0x422C
189+
#define SWO_PAR_VAL_2D (ERR_PAR_VAL + ERR_OS_GEN_ID_2D) // 0x422D
190+
#define SWO_PAR_VAL_2E (ERR_PAR_VAL + ERR_OS_GEN_ID_2E) // 0x422E
191+
#define SWO_PAR_VAL_2F (ERR_PAR_VAL + ERR_OS_GEN_ID_2F) // 0x422F
192+
#define SWO_PAR_VAL_30 (ERR_PAR_VAL + ERR_OS_GEN_ID_30) // 0x4230
193+
#define SWO_PAR_VAL_31 (ERR_PAR_VAL + ERR_OS_GEN_ID_31) // 0x4231
194+
#define SWO_PAR_VAL_32 (ERR_PAR_VAL + ERR_OS_GEN_ID_32) // 0x4232
195+
#define SWO_PAR_VAL_33 (ERR_PAR_VAL + ERR_OS_GEN_ID_33) // 0x4233
196+
#define SWO_PAR_VAL_34 (ERR_PAR_VAL + ERR_OS_GEN_ID_34) // 0x4234
197+
#define SWO_PAR_VAL_35 (ERR_PAR_VAL + ERR_OS_GEN_ID_35) // 0x4235
198+
#define SWO_PAR_VAL_36 (ERR_PAR_VAL + ERR_OS_GEN_ID_36) // 0x4236
199+
#define SWO_PAR_VAL_37 (ERR_PAR_VAL + ERR_OS_GEN_ID_37) // 0x4237
200+
#define SWO_PAR_VAL_38 (ERR_PAR_VAL + ERR_OS_GEN_ID_38) // 0x4238
201+
#define SWO_PAR_VAL_39 (ERR_PAR_VAL + ERR_OS_GEN_ID_39) // 0x4239
202+
#define SWO_PAR_VAL_3A (ERR_PAR_VAL + ERR_OS_GEN_ID_3A) // 0x423A
203+
#define SWO_PAR_VAL_3B (ERR_PAR_VAL + ERR_OS_GEN_ID_3B) // 0x423B
204+
#define SWO_PAR_VAL_3C (ERR_PAR_VAL + ERR_OS_GEN_ID_3C) // 0x423C
205+
#define SWO_PAR_VAL_3D (ERR_PAR_VAL + ERR_OS_GEN_ID_3D) // 0x423D
206+
207+
#define ERR_SEC_PIN (ERR_SEC_RANGE + ERR_OS_GEN_SUB_05)
208+
#define SWO_SEC_PIN_15 (ERR_SEC_PIN + ERR_OS_GEN_ID_15) // 0x5515
209+
210+
#endif /* OS_ERRORS_H */

0 commit comments

Comments
 (0)