Cryptographic Utilities

RecipeCratesCategories
subtlesubtlecat-cryptography
zeroizezeroizecat-cryptography

zeroize

zeroize zeroize-crates.io zeroize-github zeroize-lib.rs cat-cryptography cat-memory-management cat-os cat-no-std

"Zeroize" refers to the process of securely erasing sensitive data, such as cryptographic keys, passwords, or any other confidential information, from memory or storage. The goal is to ensure that the data cannot be recovered or reconstructed, preventing unauthorized access.

The zeroize crate securely clear secrets from memory. It guarantees that memory is zeroed, using an operation that will not be optimized away by the compiler. It is a portable pure-Rust implementation that works everywhere, even with WASM.

use zeroize::Zeroize;

/// Demonstrates the use of the `zeroize` crate to securely clear sensitive data
/// from memory.
fn main() {
    // Create a vector of sensitive data, e.g., a password or key.
    let mut sensitive_data = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 0];

    // Print the sensitive data before zeroizing.
    println!("Sensitive data before zeroizing: {:?}", sensitive_data);

    // Securely zeroize the sensitive data:
    sensitive_data.zeroize();

    println!("Sensitive data after zeroizing: {:?}", sensitive_data);
}

subtle

subtle-website subtle subtle-crates.io subtle-github subtle-lib.rs cat-cryptography cat-no-std

subtle provides pure-Rust traits and utilities for writing constant-time cryptographic code. In cryptography, timing attacks exploit variations in execution time to infer secret information. Constant-time code aims to eliminate these variations, ensuring that the execution time of an operation is independent of the secret data.

It consists of a Choice type, and a collection of traits using Choice instead of bool, which are intended to execute in constant-time. The Choice type is a wrapper around a u8 that holds a 0 or 1.

The subtle crate is a low-level library and doesn't implement cryptographic algorithms itself. Instead, it provides the building blocks for developers to implement cryptographic algorithms in a way that minimizes the risk of timing attacks. It's typically used in low-level cryptographic libraries or when implementing custom cryptographic protocols.

//! This example demonstrates the usage of the `subtle` crate for
//! constant-time cryptographic operations.

use subtle::Choice;
use subtle::ConditionallySelectable;
use subtle::ConstantTimeEq;
use subtle::CtOption;

// The `subtle` crate provides traits and utilities for writing
// constant-time cryptographic code, which is crucial for preventing
// timing attacks.

fn main() {
    // Example 1: Constant-time equality:
    let a = 10u8;
    let b = 10u8;
    let c = 20u8;

    let a_eq_b: Choice = a.ct_eq(&b);
    let a_eq_c: Choice = a.ct_eq(&c);
    // `unwrap_u8()` returns 1 if the choice is true, 0 otherwise.
    println!("a == b: {}", a_eq_b.unwrap_u8() == 1);
    println!("a == c: {}", a_eq_c.unwrap_u8() == 1);

    // Example 2: Conditional selection:
    // `conditional_select()` selects one of two values based on a
    // `Choice` in constant time.
    let x = 5u32;
    let y = 10u32;

    let condition = Choice::from(1); // 1 means true
    let selected: u32 = u32::conditional_select(&x, &y, condition);
    println!("Selected (condition true): {}", selected); // Output: 10

    let condition = Choice::from(0); // 0 means false
    let selected: u32 = u32::conditional_select(&x, &y, condition);
    println!("Selected (condition false): {}", selected); // Output: 5

    // Example 3: CtOption for handling potential failures in constant time:
    // The `CtOption<T>` type represents an optional value similar to the
    // `Option<T>` type but is intended for use in constant time APIs.
    fn try_parse(s: &str) -> CtOption<u32> {
        if s.len() < 3 {
            CtOption::new(0, Choice::from(0)) // Return 0 and a false choice if the string is too short
        } else {
            CtOption::new(s.len() as u32, Choice::from(1)) // Return length and a true choice otherwise
        }
    }

    let short_str = "ab";
    let long_str = "abcd";

    let short_result: CtOption<u32> = try_parse(short_str);
    let long_result: CtOption<u32> = try_parse(long_str);

    let is_some: Choice = long_result.is_some();
    let is_none: Choice = short_result.is_none();
    println!("Long string is some: {}", is_some.unwrap_u8() == 1);
    println!("Short string is none: {}", is_none.unwrap_u8() == 1);

    // Example 4: Using `unwrap_or` to expose the underlying value:
    // `unwrap_or()` returns the underlying value if the `CtOption` is
    // `Some`, otherwise it returns the provided default value.
    let opt: CtOption<u8> = CtOption::new(10u8, Choice::from(1));
    let val: u8 = opt.unwrap_or(0);
    println!("Unwrapped value: {}", val);

    let none_opt: CtOption<u8> = CtOption::new(5u8, Choice::from(0));
    let default_val = none_opt.unwrap_or(0);
    println!("Unwrapped default value: {}", default_val);
}

Related Topics

  • Memory Management.