-
-
Notifications
You must be signed in to change notification settings - Fork 683
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Introduce TROPIC01 from Tropic Square #4172
base: main
Are you sure you want to change the base?
Conversation
"vendor/libtropic/src/lt_l2_frame_check.c", | ||
"vendor/libtropic/src/lt_l3.c", | ||
"vendor/libtropic/src/lt_random.c", | ||
"vendor/libtropic/hal//port/unix/lt_port_unix.c", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"vendor/libtropic/hal//port/unix/lt_port_unix.c", | |
"vendor/libtropic/hal/port/unix/lt_port_unix.c", |
"vendor/libtropic/hal/crypto/trezor_crypto/lt_crypto_trezor_sha256.c", | ||
"vendor/libtropic/hal/crypto/trezor_crypto/lt_crypto_trezor_x25519.c", | ||
] | ||
defines += ["USE_TREZOR_CRYPTO"] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe this should be USE_TS_CRYPTO
, no?
defines += ["USE_TREZOR_CRYPTO"] | |
defines += ["USE_TS_CRYPTO"] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe this should be
USE_TS_CRYPTO
, no?
Actually, I was thinking not, because this is the emulator build, in which we would still use TREZOR_CRYPTO
, because the TS chip is not there. What do you think, @pavelpolach321?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In libtropic we use USE_TREZOR_CRYPTO define if we want to use trezor_crypto as a source of cryptographic code which is running on host (MCU) side.
Example: https://github.com/tropicsquare/libtropic/blob/master/hal/crypto/trezor_crypto/ts_trezor_x25519.c#L1
Therefore I think that passing USE_TREZOR_CRYPTO to compilation of libtropic files will work in your case?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So we are good on this?
vstr_t vstr = {0}; | ||
vstr_init_len(&vstr, 1024); | ||
|
||
bytes_to_chars(X509_cert, vstr.buf, 512); | ||
|
||
return mp_obj_new_str_from_vstr(&mp_type_bytes, &vstr); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why convert to hex here? IMHO just return raw binary bytes and if we need hex we can call foo.hex()
in Python.
vstr_t vstr = {0}; | |
vstr_init_len(&vstr, 1024); | |
bytes_to_chars(X509_cert, vstr.buf, 512); | |
return mp_obj_new_str_from_vstr(&mp_type_bytes, &vstr); | |
return mp_obj_new_str_copy(&mp_type_str, X509_cert, 512); |
f41ec36
to
e91f6cb
Compare
c9485c3
to
47d4427
Compare
4b65b70
to
94517e4
Compare
94517e4
to
3c77bf0
Compare
Hello @ibz, I wanted to ask if you could use fixup commits instead of force-pushing. Fixup commits make it easier to track which suggestions have already been addressed. We usually squash the fixup commits just before merging the pull request. |
As one of the developers involved in integrating Optiga into Trezor, I would like to document the architecture we used for the integration. The following diagrams shows the dependencies of all relevant functions where Optiga is utilized: graph TD
subgraph optiga_transport["core∕embed∕trezorhal∕optiga∕optiga_transport.c"]
optiga_sec_chan_handshake
optiga_init
optiga_execute_command
end
subgraph optiga_commands["core∕embed∕trezorhal∕optiga∕optiga_commands.c"]
optiga_calc_sign --> optiga_execute_command
optiga_get_data_object --> optiga_execute_command
optiga_set_autostate --> optiga_execute_command
optiga_get_random --> optiga_execute_command
end
subgraph optiga["core∕embed∕trezorhal∕optiga∕optiga.c"]
optiga_sign --> optiga_calc_sign
optiga_read_cert --> optiga_get_data_object
optiga_random_buffer --> optiga_get_random
optiga_pin_verify --> optiga_set_autostate
end
subgraph storage["storage∕storage.c"]
storage_unlock --> optiga_pin_verify
end
subgraph modoptiga["core∕embed∕extmod∕modtrezorcrypto∕modtrezorcrypto_optiga.h"]
sign --> optiga_sign
get_cert --> optiga_read_cert
end
subgraph modconfig["core∕embed∕extmod∕modtrezorconfig∕modtrezorconfig.c"]
unlock --> storage_unlock
end
subgraph modrandom["core∕embed∕extmod∕modtrezorcrypto∕modtrezorcrypto_random.c"]
random_bytes --> optiga_random_buffer
end
subgraph modmain["core∕embed∕kernel∕main.c"]
driver_init --> optiga_sec_chan_handshake
driver_init --> optiga_init
end
Note that the functions I am not claiming that the architecture is perfect nor that there are no reasons to integrate Tropic differently. However, it would be nice, if we could keep it consistent. One significant difference is that we don't have an Optiga emulator. How will the code in this pull request differ if we use a physical device instead of an emulator? |
3c77bf0
to
7283ff6
Compare
Got it, sorry for that! BTW, I just force-pushed again, because I rebased on |
Indeed, I can move
By this did you mean just the above part, about The way I see it ... we have the |
One reason for initializing optiga in main.c was that the handshake process uses a secret stored in a memory location that becomes inaccessible once the firmware enters unprivileged mode. It seems to me that this concept applies to tropic as well. It would be beneficial to store the production handshake keys in this area.
This is something I don't quite understand. Does it mean that |
Hello, libtropic manages the communication by using its platform specific c file during compilation. For compiling for embedded target, use this file in your makefile: https://github.com/tropicsquare/libtropic/blob/develop/hal/port/stm32/lt_port_stm32.c - have a look from line 241 to the end. edit: you could also define transport layer's primitives for your embedded environment. For example within your codebase create lt_port_trezor.c and fill it with definitions for interfaces described by this header file: https://github.com/tropicsquare/libtropic/blob/develop/include/libtropic_port.h |
Thank you for the explanation. It makes sense to me now. This line is what causes the build to use an emulator instead of a physical device. I still don't understand whether we have to perform a handshake before every command. See this comment. Trezor with optiga performs a handshake once during startup and then reuses the handle. Is there any benefit in performing the handshake for each individual command? |
We don't. That is my mistake. Will fix. |
My suggestion is to:
Once we want to use a physical tropic, we will implement The tropic commands can then be called either directly using I am still uncertain about the variable naming. Does this approach make sense to you? |
832300b
to
21d26d6
Compare
7d1b655
to
413e9b1
Compare
######## | ||
# USE_TROPIC should eventually be enabled when building with the 'tropic' feature | ||
# but for now we don't have the model running, which would crash the emulator on startup. | ||
# defines += ["USE_TROPIC=1"] | ||
######## |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If I understand it correctly, this implies that there is no test in the CI that would at least ensure this pull request compiles without errors.
What do you think about
- introducing a new model that would be the same as T3W1 but with
USE_TROPIC=1
and - adding a pipeline that will build the emulator for this model?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Indeed, I agree this is not ideal (not building it at least).
I like your idea actually, and that could be good in the future also, not only for building the tropic code as part of the CI.
I assume most development locally would be done against T3W1 "plain" and the T3W1_TROPIC emulator would only be started when needed (to debug code that interacts with Tropic), because it needs the model running and it is not necessary for most firmware work.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
USE_TROPIC=1 is set for T3W1 hardware builds so that ensures general buildability of this code.
i don't really see a point of building this for emulator until we have the model widely available, and if the code somehow drifts between now and then, we'll fix it then. merging now, without CI involvement, is much better than letting it linger for longer (heh)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
USE_TROPIC=1 is set for T3W1 hardware builds so that ensures general buildability of this code.
No. As far as I know, USE_TROPIC=1
is not set for T3W1, because "tropic"
is not listed in FEATURES_WANTED
. And the build actually fails if I list it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i see, you're right. should we add "tropic" in SConscript.firmware then? cc @TychoVrahe
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what does tropic_init()
actually do?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Three more things:
- I don't like that you have to launch the the tropic emulator manually if you want to run the device tests locally.
- We must not forget about device tests, they will also require the tropic emulator.
- The tropic emulator is statefull and we want to reset the state between individual tests.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
3. The tropic emulator is statefull and we want to reset the state between individual tests.
this should be part of WipeDevice
flow, and we'll need it as a feature of the firmware
2. We must not forget about device tests, they will also require the tropic emulator.
i'm thinking that this may be a good reason to introduce "T3W1 without tropic" as a separate matrix item, so that we can run the test suite in CI without involving the model. (but for now it's not super important, given that the model isn't actually doing anything)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what does tropic_init() actually do?
It sets up the secure channel between trezor and tropic.
this should be part of WipeDevice flow, and we'll need it as a feature of the firmware
Yes, but WipeDevice
resolves the issue in the device tests but not in the unit tests.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, but
WipeDevice
resolves the issue in the device tests but not in the unit tests.
right, so there should be a function exposed to python to do this (which will also get called in the WipeDevice flow)
and Tropic unit tests will do a setUp()
that calls this?
8ee1b8a
to
2ec58c2
Compare
[no changelog]
2ec58c2
to
5034e58
Compare
[no changelog]
5034e58
to
404544b
Compare
[no changelog]
419e257
to
c757bf6
Compare
[no changelog]
[no changelog]
[no changelog]
c757bf6
to
c7aae24
Compare
@@ -196,6 +196,7 @@ jobs: | |||
submodules: recursive | |||
- uses: ./.github/actions/environment | |||
- run: nix-shell --run "poetry run make -C core build_unix" | |||
- run: nix-shell --run "cd vendor/ts-tvl/tvl/server/model_config && poetry install && poetry run model_server tcp -c model_config.yml &" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think poetry install
can be omitted. The python environment should already be installed at this point.
unix
(Trezor emulator),libtropic
requires the Tropic model to be running and accepting connections over TCP, while the actual devicelibtropic
will talk directly to the TROPIC01 chipcore/
emu.py
) has a way to run the Tropic model automatically - this is for convenience, when testing manually using the emulator. The added benefit of this is little actually, since one could just run it separately with a single command, but havingemu.py
do it also serves as a way to document (via code) how it is done and to enforce a path where everybody using the model will have it set up, for consistency.#4718 is a follow-up for this PR, so we can merge this even before we have access to the open sourced model!