Data
SealVault stores the following data on the user's device:
- Data and key encryption keys.
- Asymmetric keys for digital signatures.
- Blockchain addresses derived from public keys of the user.
- Profiles and profile images.
- Metadata about dapps that the user has interacted with, eg.:
- Smart contract addresses,
- URLs.
- Blockchain and dapp specific user settings.
- Timestamps for user actions.
SealVault doesn't store any data remotely.
SealVault sends crash reports to Sentry. Secrets are
never sent to Sentry. This is enforced by Rust's type system at compile time due
to lack of or opaque Debug
and Display
trait implementations for secret
values. For other user data, we do our best to prevent leaking personally
identifiable information into crash reports by carefully considering what is
included in error messages and what is logged.
Device Storage
Requirements
- Encryption on disk.
- Minimize potential key exposure window and allow wiping keys from memory.
- Allows performing tasks that don't need keys in the background.
- Easy to back up.
- Cross-platform.1
Solution
We store data on the user's device in a SQLite database file encrypted by iOS Data Protection with the “Protected Until First User Authentication” class. This means that data is always encrypted on disk, but the decryption key for the database file is stored in memory after the user has unlocked the device for the first time after boot. Older iOS devices use 128-bit keys while newer devices use 256-bit keys for file encryption with AES-XTS.
Secret-Key-Encryption-Keys
We store secret keys fo digital signatures (SKs) in the SQLite database encrypted with our chosen AEAD construct. The SK data-encryption-key (SK-DEK) is also stored in the database with envelope encryption wrapped by the key-encryption-key for SKs (SK-KEK). The SK-KEK is stored on the user's local (device only) iOS Keychain with the “When Unlocked” data protection class. This means that SKs can be only decrypted when the device is unlocked by the user.
This layered encryption approach lets us decrypt SKs only when they're needed to sign a transaction and wipe them from memory immediately after while letting us perform other tasks like backups in the background when the device is locked. Finally, storing all data (including SKs) in a single SQLite database makes it easy to create backups with integrity and the same approach can be used on other platforms as well.
-
While we focus on the iOS platform initially, we want to be able to use the same storage solution when we expand to other platforms. ↩