Expand description
§Bitwarden Cryptographic primitives
This crate contains the cryptographic primitives used throughout the SDK. The general aspiration is for this crate to handle all the difficult cryptographic operations and expose higher level concepts to the rest of the SDK.
§Example:
use bitwarden_crypto::{SymmetricCryptoKey, KeyEncryptable, KeyDecryptable, CryptoError};
async fn example() -> Result<(), CryptoError> {
let key = SymmetricCryptoKey::make_aes256_cbc_hmac_key();
let data = "Hello, World!".to_owned();
let encrypted = data.clone().encrypt_with_key(&key)?;
let decrypted: String = encrypted.decrypt_with_key(&key)?;
assert_eq!(data, decrypted);
Ok(())
}
§Development considerations
This crate is expected to provide long term support for cryptographic operations. To that end, the following considerations should be taken into account when making changes to this crate:
- Limit public interfaces to the bare minimum.
- Breaking changes should be rare and well communicated.
- Serializable representation of keys and encrypted data must be supported indefinitely as we have no way to update all data.
§Conventions:
- Pure Functions that deterministically “derive” keys from input are prefixed with
derive_
. - Functions that generate non deterministically keys are prefixed with
make_
.
§Differences from clients
There are some noteworthy differences compared to the other Bitwarden clients. These changes are made in an effort to introduce conventions in how we name things, improve best practices and abstracting away internal complexity.
CryptoService.makeSendKey
&AccessService.createAccessToken
are replaced by the genericderive_shareable_key
- MasterKey operations such as
makeMasterKey
andhashMasterKey
are moved to the MasterKey struct.
§Crate features
no-memory-hardening
- Disables memory hardening which ensures that allocated memory is zeroed on drop. This feature primarily exists in case you do not want to use the standard allocator, and we advise to still define aglobal_allocator
using theZeroizingAllocator
.
§Pinned heap data
This crate uses a Pin<Box<>>
strategy to ensure data is stored on the heap and not moved
around. This pattern is commonly used for GenericArray
since it’s equivalent to [u8; N]
which is a Copy type placed on the stack. To keep the compiler from making stack copies when
moving this struct around, we use a Box to keep the values on the heap. We also pin the box to
make sure that the contents can’t be pulled out of the box and moved.
Modules§
- aes 🔒
- AES operations
- content_
format 🔒 - cose 🔒
- This file contains private-use constants for COSE encoded key types and algorithms. Standardized values from https://www.iana.org/assignments/cose/cose.xhtml should always be preferred unless there is a a clear benefit, such as a clear cryptographic benefit, which MUST be documented publicly.
- enc_
string 🔒 - Encrypted string types
- error 🔒
- fingerprint 🔒
- Fingerprint
- keys 🔒
- rsa 🔒
- signing 🔒
- Signing is used to assert integrity of a message to others or to oneself.
- store 🔒
- This module contains all the necessary parts to create an in-memory key store that can be used to securely store key and use them for encryption/decryption operations.
- traits 🔒
- uniffi_
support 🔒 - util 🔒
- wordlist 🔒
- xchacha20 🔒
- XChaCha20Poly1305 operations
Macros§
- key_ids
- Just a small derive_like macro that can be used to generate the key identifier enums. Example usage:
Structs§
- Aes256
CbcHmac Key - Aes256CbcHmacKey is a symmetric encryption key consisting of two 256-bit keys, one for encryption and one for MAC
- Aes256
CbcKey - Aes256CbcKey is a symmetric encryption key, consisting of one 256-bit key, used to decrypt legacy type 0 enc strings. The data is not authenticated so this should be used with caution, and removed where possible.
- Asymmetric
Crypto Key - Private key of a key pair used in a public key encryption scheme. It is used for decrypting data that was encrypted with the corresponding public key.
- Asymmetric
Public Crypto Key - Public key of a key pair used in a public key encryption scheme. It is used for encrypting data.
- Bitwarden
Legacy KeyContent Format - A legacy content format for Bitwarden keys. See
ContentFormat::BitwardenLegacyKey
- Bytes
- A serialized byte array with a specific content format. This is used to represent data that has a specific format, such as UTF-8 encoded text, raw bytes, or COSE keys. The content format is used to determine how the bytes should be interpreted when encrypting or decrypting the data.
- Cose
KeyContent Format - Content format for COSE keys.
- Cose
Sign1 Content Format - Content format for COSE Sign1 messages.
- Device
Key - Device Key
- KeyStore
- An in-memory key store that provides a safe and secure way to store keys and use them for encryption/decryption operations. The store API is designed to work only on key identifiers (KeyId). These identifiers are user-defined types that contain no key material, which means the API users don’t have to worry about accidentally leaking keys.
- KeyStore
Context - The context of a crypto operation using super::KeyStore
- Octet
Stream Content Format - Content format for raw bytes. Used for attachments and send seed keys.
- PinKey
- Pin Key.
- Pkcs8
Private KeyDer Content Format - Content format for PKCS8 private keys in DER format.
- Rotated
User Keys - Rotated set of account keys
- RsaKey
Pair - RSA Key Pair
- Serialized
Message - A message (struct) to be signed, serialized to a byte array, along with the content format of the bytes.
- Signature
- A signature cryptographically attests to a (namespace, data) pair. The namespace is included in the signature object, the data is not. One data object can be signed multiple times, with different namespaces / by different signers, depending on the application needs.
- Signed
Object - A signed object is a message containing a payload and signature that attests the payload’s integrity and authenticity for a specific namespace and signature key. In order to gain access to the payload, the caller must provide the correct namespace and verifying key, ensuring that the caller cannot forget to validate the signature before using the payload.
- Signed
Public Key SignedAsymmetricPublicKey
is a public encryption key, signed by the owner of the encryption keypair. This wrapping ensures that the consumer of the public key MUST verify the identity of the Signer before they can use the public key for encryption.- Signed
Public KeyMessage SignedAsymmetricPublicKeyMessage
is a message that once signed, makes a claim towards owning a public encryption key.- Signing
Key - A signing key is a private key used for signing data. An associated
VerifyingKey
can be derived from it. - Spki
Public KeyDer Content Format - Content format for SPKI public keys in DER format.
- Trust
Device Response - UserKey
- User Key
- Verifying
Key - A verifying key is a public key used for verifying signatures. It can be published to other
users, who can use it to verify that messages were signed by the holder of the corresponding
SigningKey
. - XCha
Cha20 Poly1305 Key - XChaCha20Poly1305Key is a symmetric encryption key consisting of one 256-bit key, and contains a key id. In contrast to the Aes256CbcKey and Aes256CbcHmacKey, this key type is used to create CoseEncrypt0 messages.
- Zeroizing
Allocator - Allocator wrapper that zeros on free
Enums§
- Crypto
Error - EncString
- Encrypted string primitive
- Hash
Purpose - Kdf
- Key Derivation Function for Bitwarden Account
- Master
Key - Master Key.
- Public
KeyEncryption Algorithm - Algorithm / public key encryption scheme used for encryption/decryption.
- Signature
Algorithm - The type of key / signature scheme used for signing and verifying.
- Signing
Namespace - Signing is domain-separated within bitwarden, to prevent cross protocol attacks.
- Symmetric
Crypto Key - A symmetric encryption key. Used to encrypt and decrypt
EncString
- Unsigned
Shared Key - Encrypted string primitive
Constants§
- EFF_
LONG_ WORD_ LIST - EFF’s Long Wordlist from https://www.eff.org/dice
- UNIFFI_
META_ 🔒CONST_ NAMESPACE_ BITWARDEN_ CRYPTO - Export namespace metadata.
Traits§
- Composite
Encryptable - An encryption operation that takes the input value and encrypts the fields on it recursively. Implementations should generally consist of calling PrimitiveEncryptable::encrypt for all the fields of the type. Sometimes, it is necessary to call CompositeEncryptable::encrypt_composite, if the object is not a flat struct.
- Const
Content Format - This trait is used to instantiate different typed byte vectors with a specific content format,
using
SerializedBytes<C>
. This allows for compile-time guarantees about the content format of the serialized bytes. The exception here is the escape hatch using e.g.from(Vec<u8>)
, which can still be mis-used, but has to be misused explicitly. - Cose
Content Format - A marker trait for COSE content formats.
- Cose
Serializable - Trait for structs that are serializable to COSE objects.
- Crypto
Key - Decryptable
- A decryption operation that takes the input value and decrypts it into the output value. Implementations should generally consist of calling Decryptable::decrypt for all the fields of the type.
- Identify
Key - Types implementing IdentifyKey are capable of knowing which cryptographic key is needed to encrypt/decrypt them.
- KeyContainer
- KeyDecryptable
- KeyEncryptable
- An encryption operation that takes the input value and encrypts it into the output value using a key reference. Implementing this requires a content type to be specified in the implementation.
- KeyId
- Represents a key identifier that can be used to identify cryptographic keys in the key store. It is used to avoid exposing the key material directly in the public API.
- KeyIds
- Represents a set of all the key identifiers that need to be defined to use a key store. At the moment it’s just symmetric and asymmetric keys.
- Primitive
Encryptable - An encryption operation that takes the input value - a primitive such as
String
and encrypts it into the output value. The implementation decides the content format.
Functions§
- dangerous_
derive_ kdf_ material Deprecated - Derives KDF material given a password, salt and kdf configuration. This function is a stop-gap solution and should not be used outside of PureCrypto.
- dangerous_
get_ v2_ rotated_ account_ keys - Re-encrypts the user’s keys with the provided symmetric key for a v2 user.
- default_
argon2_ iterations - Default Argon2 iterations
- default_
argon2_ memory - Default Argon2 memory
- default_
argon2_ parallelism - Default Argon2 parallelism
- default_
pbkdf2_ iterations - Default PBKDF2 iterations
- derive_
shareable_ key - Derive a shareable key using hkdf from secret and name.
- fingerprint
- Computes a fingerprint of the given
fingerprint_material
using the givenpublic_key
. - generate_
random_ alphanumeric - Generate a random alphanumeric string of a given length
- generate_
random_ bytes - Generate random bytes that are cryptographically secure
- pbkdf2
- Derive pbkdf2 of a given password and salt
Type Aliases§
- Bitwarden
Legacy KeyBytes - BitwardenLegacyKeyBytes is a type alias for Bytes with
BitwardenLegacyKeyContentFormat
. This is used for the legacy format for symmetric keys. A description of the format is available in theContentFormat::BitwardenLegacyKey
documentation. - Cose
KeyBytes - CoseKeyBytes is a type alias for Bytes with
CoseKeyContentFormat
. This is used for serialized CoseKey objects. - Cose
Sign1 Bytes - CoseSign1Bytes is a type alias for Bytes with
CoseSign1ContentFormat
. This is used for serialized COSE Sign1 messages. - Octet
Stream Bytes - OctetStreamBytes is a type alias for Bytes with
OctetStreamContentFormat
. This should be used for e.g. attachments and other data without an explicit content format. - Pkcs8
Private KeyBytes - Pkcs8PrivateKeyBytes is a type alias for Bytes with
Pkcs8PrivateKeyDerContentFormat
. This is used for PKCS8 private keys in DER format. - Spki
Public KeyBytes - SpkiPublicKeyBytes is a type alias for Bytes with
SpkiPublicKeyDerContentFormat
. This is used for SPKI public keys in DER format.