Skip to content

Commit

Permalink
Add more docs to crypto crate (#722)
Browse files Browse the repository at this point in the history
Add some more documentation for crypto crate.
  • Loading branch information
Hinton authored Apr 22, 2024
1 parent dfe067e commit a5f6fd5
Show file tree
Hide file tree
Showing 9 changed files with 57 additions and 12 deletions.
3 changes: 2 additions & 1 deletion bacon.toml
Original file line number Diff line number Diff line change
Expand Up @@ -66,8 +66,9 @@ command = [
"--document-private-items",
"--open",
]
allow_warnings = true
need_stdout = false
on_success = "back"
on_success = "job:doc-internal"

# You may define here keybindings that would be specific to
# a project, for example a shortcut to launch a specific job.
Expand Down
9 changes: 9 additions & 0 deletions crates/bitwarden-crypto/src/keys/master_key.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ use serde::{Deserialize, Serialize};
use super::utils::{derive_kdf_key, stretch_kdf_key};
use crate::{util, CryptoError, EncString, KeyDecryptable, Result, SymmetricCryptoKey, UserKey};

/// Key Derivation Function for Bitwarden Account
///
/// In Bitwarden accounts can use multiple KDFs to derive their master key from their password. This
/// Enum represents all the possible KDFs.
#[derive(Serialize, Deserialize, Debug, JsonSchema, Clone)]
#[serde(rename_all = "camelCase", deny_unknown_fields)]
#[cfg_attr(feature = "mobile", derive(uniffi::Enum))]
Expand All @@ -22,22 +26,27 @@ pub enum Kdf {
}

impl Default for Kdf {
/// Default KDF for new accounts.
fn default() -> Self {
Kdf::PBKDF2 {
iterations: default_pbkdf2_iterations(),
}
}
}

/// Default PBKDF2 iterations
pub fn default_pbkdf2_iterations() -> NonZeroU32 {
NonZeroU32::new(600_000).expect("Non-zero number")
}
/// Default Argon2 iterations
pub fn default_argon2_iterations() -> NonZeroU32 {
NonZeroU32::new(3).expect("Non-zero number")
}
/// Default Argon2 memory
pub fn default_argon2_memory() -> NonZeroU32 {
NonZeroU32::new(64).expect("Non-zero number")
}
/// Default Argon2 parallelism
pub fn default_argon2_parallelism() -> NonZeroU32 {
NonZeroU32::new(4).expect("Non-zero number")
}
Expand Down
42 changes: 37 additions & 5 deletions crates/bitwarden-crypto/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,47 @@
//! # Bitwarden Cryptographic primitives
//!
//! This crate contains the cryptographic primitives used throughout the SDK. The crate makes a
//! best effort to abstract away cryptographic concepts into concepts such as [`EncString`],
//! [`AsymmetricEncString`] and [`SymmetricCryptoKey`].
//! 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.
//!
//! ## Conventions:
//! <div class="warning">
//! Generally you should <b>not</b> find yourself needing to edit this crate! Everything written
//! here requires additional care and attention to ensure that the cryptographic primitives are
//! secure. </div>
//!
//! ## Example:
//!
//! ```rust
//! use bitwarden_crypto::{SymmetricCryptoKey, KeyEncryptable, KeyDecryptable, CryptoError};
//!
//! async fn example() -> Result<(), CryptoError> {
//! let key = SymmetricCryptoKey::generate(rand::thread_rng());
//!
//! 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`
//! ### Differences from `clients`
//!
//! There are some noteworthy differences compared to the other Bitwarden
//! [clients](https://github.com/bitwarden/clients). These changes are made in an effort to
Expand Down
2 changes: 2 additions & 0 deletions crates/bitwarden-crypto/src/rsa.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ pub struct RsaKeyPair {
pub private: EncString,
}

/// Generate a new RSA key pair of 2048 bits
pub(crate) fn make_key_pair(key: &SymmetricCryptoKey) -> Result<RsaKeyPair> {
let mut rng = rand::thread_rng();
let bits = 2048;
Expand Down Expand Up @@ -48,6 +49,7 @@ pub(crate) fn make_key_pair(key: &SymmetricCryptoKey) -> Result<RsaKeyPair> {
})
}

/// Encrypt data using RSA-OAEP-SHA1 with a 2048 bit key
pub(super) fn encrypt_rsa2048_oaep_sha1(public_key: &RsaPublicKey, data: &[u8]) -> Result<Vec<u8>> {
let mut rng = rand::thread_rng();

Expand Down
2 changes: 1 addition & 1 deletion crates/bitwarden-crypto/src/wordlist.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// EFF's Long Wordlist from https://www.eff.org/dice
/// EFF's Long Wordlist from <https://www.eff.org/dice>
pub const EFF_LONG_WORD_LIST: &[&str] = &[
"abacus",
"abdomen",
Expand Down
2 changes: 1 addition & 1 deletion crates/bitwarden-exporters/src/csv.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ pub(crate) fn export_csv(folders: Vec<Folder>, ciphers: Vec<Cipher>) -> Result<S
String::from_utf8(wtr.into_inner().map_err(|_| CsvError::Csv)?).map_err(|_| CsvError::Csv)
}

/// CSV export format. See https://bitwarden.com/help/condition-bitwarden-import/#condition-a-csv
/// CSV export format. See <https://bitwarden.com/help/condition-bitwarden-import/#condition-a-csv>
///
/// Be careful when changing this struct to maintain compatibility with old exports.
#[derive(serde::Serialize)]
Expand Down
4 changes: 2 additions & 2 deletions crates/bitwarden-generators/src/username.rs
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,7 @@ fn random_number(mut rng: impl RngCore) -> String {
}

/// Generate a username using a plus addressed email address
/// The format is <username>+<random-or-website>@<domain>
/// The format is `<username>+<random-or-website>@<domain>`
fn username_subaddress(mut rng: impl RngCore, r#type: AppendType, email: String) -> String {
if email.len() < 3 {
return email;
Expand All @@ -195,7 +195,7 @@ fn username_subaddress(mut rng: impl RngCore, r#type: AppendType, email: String)
}

/// Generate a username using a catchall email address
/// The format is <random-or-website>@<domain>
/// The format is `<random-or-website>@<domain>`
fn username_catchall(mut rng: impl RngCore, r#type: AppendType, domain: String) -> String {
if domain.is_empty() {
return domain;
Expand Down
1 change: 1 addition & 0 deletions crates/bitwarden/src/client/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ pub(crate) enum ServiceAccountLoginMethod {
},
}

/// The main struct to interact with the Bitwarden SDK.
#[derive(Debug)]
pub struct Client {
token: Option<String>,
Expand Down
4 changes: 2 additions & 2 deletions crates/bitwarden/src/mobile/crypto.rs
Original file line number Diff line number Diff line change
Expand Up @@ -231,9 +231,9 @@ pub fn update_password(
#[serde(rename_all = "camelCase", deny_unknown_fields)]
#[cfg_attr(feature = "mobile", derive(uniffi::Record))]
pub struct DerivePinKeyResponse {
/// [UserKey] protected by PIN
/// [UserKey](bitwarden_crypto::UserKey) protected by PIN
pin_protected_user_key: EncString,
/// PIN protected by [UserKey]
/// PIN protected by [UserKey](bitwarden_crypto::UserKey)
encrypted_pin: EncString,
}

Expand Down

0 comments on commit a5f6fd5

Please sign in to comment.