This page tries to give a somehow detailed explanation of the cryptography used in the TSM.
Recall that the TSM consists of a number of MPC nodes. Each MPC node is controlled by its own SDK, or a single SDK may control all MPC nodes. Via the SDKs users can instruct the MPC nodes to do various MPC operations such as key generation and signing. If so, the MPC nodes connect via pairwise channels to execute secure multiparty (MPC) protocols. Key generation results in each MPC node generating its own share of the key. Each MPC node connects to its own database where it stores, among other things, its own key shares.
Each MPC node has a configuration file which contains information about how to communicate with the other MPC nodes (its own private key and the URLs and public keys of the other nodes), information about how to connect to its database, how to encrypt its database contents, supported MPC protocols, security threshold, etc.
When starting an MPC node the EncryptorMasterPassword (or the EncryptorKeyFile) from the configuration file is used to derive a key encryption key (KEK) using PBKDF2. This KEK is used to decrypt the master encryption key (MK) stored in the database (automatically generated on first startup). When encrypting and decrypting sensitive database content, a content encryption key (CEK) is derived from the MK and some additional (non secret) data (i.e. KeyID) using HKDF. The actual data is encrypted under this CEK. All encryptions are done using AES-GCM with 256 bit keys.
This encryption method can also be used to encrypt the configuration file itself, with exception of the database section as that is needed to instantiate the encryptor. To avoid having the encryption password stored in the clear, the database encryption key can also be read from a file (e.g. on a USB stick that is only present during startup) or read from the command line
The MPC nodes are pairwise connected via 2-way TLS v1.3. The MPC nodes use their private key from the configuration file to set up their TLS server, and the public keys for the other nodes to do public key pinning, i.e. we do not rely on a certificate authority.
Each MPC node is controlled by an SDK. The SDK connects to its MPC node using HTTP or HTTPS.
If HTTPS is used, the SDK will validate the MPC node’s certificate using the certificate store from the operating system (public key pinning is also possible). Note that HTTP is not recommended in production unless the communication channel is secured in some other way. If the user is a password authenticated user, the SDK then sends the user’s password over the channel and gets a JWT token back.
Alternatively, users can be authenticated using TLS. In this case the connection between the SDK and the MPC node will be a 2-way TLS where not only the MPC node, but also the user holds a private key.
A third alternative is to configure the MPC node to use OIDC, where the user is authenticated via a 3rd party OIDC provider, such as Google or Auth0.
The authentication method can be configured in the MPC node’s configuration file.
When an MPC node starts from a clean database, a single initial admin user can be created. This generates a password for the initial admin user. Passwords are returned by the TSM when a user is created (44 character random strings ~256-bit entropy) so a user cannot choose his password. Admin users are always authenticated via password, and therefore cannot use 2-way TLS or OIDC.
The initial admin can create additional admin users as well as regular key users. Regular key users cannot create new users, but only do key operations such as create key and sign message with key.
In the case of 2-way TLS and OIDC, users do not have to be explicitly created by an admin. Instead, users are created the first time their client certificate passes authentication. The user’s username is (a hash of) his distinguished name (DN) or his OIDC identifier.
The TSM can run distributed MPC protocols where the MPC nodes exchange a number of messages in order to generate keys or produce signatures using the generated keys. The keys are stored as secret sharings between the MPC nodes.
To run a distributed MPC protocol (such as generating an RSA or ECDSA signature on a message), each of the MPC nodes in the TSM must be told to start the given operation via an SDK call to e.g. SignPKCS1v15.
For this to work, the SDK users (which may be users from different organizations) need to agree on a unique session ID. Each user must then call SignPKCS1v15 on his own SDK using this session ID. Note that this means that an RSA signature can only be generated on a given message if one (authorized) user at each MPC node agrees to call the SignPKCS1v15 method on its SDK for that message.
The operations allowed can be controlled via the MPC node config file. E.g., to enable RSA signatures, the MPC configuration file has to contain a section that enables the RSA MPC protocol.
When a session is about to start, all nodes compare their metadata about the session (including a hash of the message to sign, if it is a signing operation), and abort the session if there is a disagreement about which operation is about to be performed.
The TSM can work in a special “multi-tenant” mode, where there can be many instances of the first MPC node. This node will then typically be run on a mobile device. The other MPC nodes will be static servers, and they will accept to execute MPC protocols with any of the instances of the first MPC node.
Note that in this mode, the configuration file cannot contain a public key for the first MPC node as there are many instances of that node (e.g., many mobile devices). In order to start an operation in this scenario, one must first agree on a session ID (as before) and then call (via the SDK) RegisterTenantPublicKey on each of the static MPC nodes using the public key of the first MPC node and the session ID. This allows the holder of the corresponding private key to run the given session.
Updated 8 months ago