Substrate Service
As part of the Milestone 2 we have developed a reference implementation of the signing service to showcase a possible usage configuration of the board.
To that end, there's currently 3 distinct parts of the project:
- The TA (trusted application) to be run in a TEE (trusted execution environment)
- The Host (host application) to be run in a "rich" execution environment (REE)
- The keystore interface crate for the substrate node
Source code
Trusted Application
The trusted application simply decodes the input received via the OPTEE API from the Host, then executes the command (if valid) based on said input, generating the private keys where necessary and storing it inside the TEE, never exposing them to any output buffer or memory locations readable from other TEEs or the REE.
The application doesn't support multi-threading and the feature is disabled so if an attempt is made to instantiate the application in 'multi-threaded mode' the OPTEE API would simply fail.
Not supporting this mode of operation avoids us from having to secure multi-threaded access to resources (such as keys) and avoid complex double signing detection logic.
Host Application
The host application is less trivial than the TA, as it exposes a listening ductile
TCP socket which uses bincode
for all the serializations and deserializations necessary for the requests and responses to be sent over the wire.
After the request has been received it is then serialized once again for the constraints of the TEE and passed over to the TA.
The reply would then follow the same path but in reverse, converting the response to one that will be encoded by bincode
and passed back to the socket to the keystore crate interface.
A separate serialization/deserialization phase for communication with the TEE is to both allow the Host Application to prepare the data so that the TA can read it more easily, but also to provide a design that is decouple from the interface accessing the Host Application.
In practical terms this means that we can switch the way we communicate with the Host Application, for example via JSON RPC, without having to change anything in the TA side .
Keystore
The keystore crate is just a simple frontend to the ductile
socket.
TEEKeystore
is the entrypoint of this interace, it implements the required traits (SyncCryptoStore
and CryptoStore
),
conveying all the requests via the ductile
socket opened when the keystore is connected
The connection phase is separate from the initialization phase, to be in line with how the other keystores work.