components/os_crypt/async/README.md
OS Crypt Async
This directory contains the new version of OSCrypt that supports asynchronous
initialization and pluggable providers. It has replaced the legacy synchronous
OSCrypt implementation.
Main interfaces
browser/ should only be included by code that lives in the browser process. An
instance of OSCryptAsync should be constructed and held in browser and is
responsible for minting Encryptor instances. //chrome holds a browser-wide
instance that's accessible from g_browser_process using os_crypt_async()
method.
GetInstance can be called as many times as necessary to obtain instances of
Encryptor that should be used for encryption operations. When calling
GetInstance an Encryptor hint can be supplied. This can change the Encryption
behavior of the resulting Encryptor instance, see encryptor.h for details. Note
that all Encryptor instances returned from the same instance of OSCryptAsync
will always be able to decrypt each other's data.
common/ can be included by any code in any process and allows Encryptor
instances to perform encrypt/decrypt operations. These EncryptString and
DecryptString operations are sync and can be called on any thread.
Encryptor instances can be passed over mojo if necessary, as mojo traits exist
to serialize and deserialize. If an Encryptor instance is passed to a process
then that process will be able to decrypt any data encrypted with
OSCryptAsync.
It is preferred to use the base::span EncryptData and DecryptData APIs,
however the EncryptString and DecryptString APIs are provided for ease of
compatibility with existing callers. The string and span APIs are compatible
with one another.
Integration Guide
OSCryptAsync is currently integrated into the Cookie encryption within the
network service, and this code can be used as a full end-to-end example of how
to integrate OSCryptAsync into your existing code.
There are a few considerations that are important for integrators:
GetInstance() must be called on the same sequence that it was created on,
which, if you are using the instance managed by //chrome is the UI thread.
Therefore, plan for your GetInstance calls to be made on this sequence.
Callbacks will also arrive on this sequence, and note that the callback
might be executed before GetInstance returns, if the Encryptor is already
available. Once you have an Encryptor it can be safely passed and used on
another sequence, though.OSCryptAsync is likely being used to seal valuable data so all precautions
should be made to avoid any potential data loss.
GetInstance and handling the
callback. The Encryptor instance that is returned can then be used as
if the code were calling directly to a sync API but since the
Encryptor is move-only it will have to be held by an object on the
calling sequence to make the calls themselves. If multiple sequences
need to make encryption calls, that's supported, but you'll need to get
an Encryptor for each sequence and explicitly pass it to those
sequences. In this phase, it is highly recommended to:
GetInstance with the kEncryptSyncCompat option. This will
ask the Encryptor to always encrypt any data in a format that is
backwards compatible with previously encrypted data.kEncryptSyncCompat and a feature flag, the code can be iterated on
without risk to any permanent data loss for users.OSCryptAsync might not yet
have obtained a valid Encryptor instance.kEncryptSyncCompat option passed to GetInstance from all calls, and
data will now start being encrypted with the keys managed by the
installed OSCryptAsync key providers in a potentially non-backwards
compatible way. In this phase, for example, data might start being
encrypted with App-Bound encryption on supported platforms. At this
point you will want to double check no data loss caused by encrypting
data with the new keys, although core OSCryptAsync metrics themselves
are used as guardrails against this scenario.OSCryptAsync depending on when it
was originally encrypted) should be read in from persistent storage,
decrypted, re-encrypted, and then and written back to persistent
storage. This ensures that all data is now encrypted with OSCryptAsync
and secured by new keys.