Crate bitwarden_crypto

Source
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.

Generally you should not find yourself needing to edit this crate! Everything written here requires additional care and attention to ensure that the cryptographic primitives are secure.

§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 generic derive_shareable_key
  • MasterKey operations such as makeMasterKey and hashMasterKey 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 a global_allocator using the ZeroizingAllocator.

§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
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 🔒
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§

Aes256CbcHmacKey
Aes256CbcHmacKey is a symmetric encryption key consisting of two 256-bit keys, one for encryption and one for MAC
Aes256CbcKey
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.
AsymmetricCryptoKey
An asymmetric encryption key. Contains both the public and private key. Can be used to both encrypt and decrypt UnsignedSharedKey.
AsymmetricPublicCryptoKey
An asymmetric public encryption key. Can only encrypt UnsignedSharedKey, usually accompanied by a AsymmetricCryptoKey
DeviceKey
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.
KeyStoreContext
The context of a crypto operation using super::KeyStore
PinKey
Pin Key.
RsaKeyPair
RSA Key Pair
TrustDeviceResponse
UserKey
User Key
XChaCha20Poly1305Key
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.
ZeroizingAllocator
Allocator wrapper that zeros on free

Enums§

CryptoError
EncString
Encrypted string primitive
HashPurpose
Kdf
Key Derivation Function for Bitwarden Account
MasterKey
Master Key.
SymmetricCryptoKey
A symmetric encryption key. Used to encrypt and decrypt EncString
UnsignedSharedKey
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§

AsymmetricEncryptable
Trait to allow both AsymmetricCryptoKey and AsymmetricPublicCryptoKey to be used to encrypt UnsignedSharedKey.
CryptoKey
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.
Encryptable
An encryption operation that takes the input value and encrypts it into the output value. Implementations should generally consist of calling Encryptable::encrypt for all the fields of the type.
IdentifyKey
Types implementing IdentifyKey are capable of knowing which cryptographic key is needed to encrypt/decrypt them.
KeyContainer
KeyDecryptable
KeyEncryptable
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.

Functions§

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 given public_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