Skip to content

Commit

Permalink
Allow libcrux to be compiled for no_std (embedded) environments
Browse files Browse the repository at this point in the history
This allows libcrux to be compiled with the minimal Rust runtime,
also known as `no_std`. This is necessary for some highly-constrained
code environments, such as embedded devices, kernels, etc., where the
full dependency set of the Rust standard library is too large or
requires capabilities that do not exist in the target environment.

To do this, I added a new Cargo "feature" to the crate, called `std`.
This feature is enabled by default. To target a `no_std` environment,
you must first disable the default feature, then opt-in to only the
features that your target environment needs.

The `rand` crate itself currently has a dependency on `std`, so the
`rand` feature depends on `std`. If the `rand` crate itself provides
a `no_std` environment, then this requirement could be lifted.
  • Loading branch information
Arlie Davis committed Jan 26, 2024
1 parent 6e08950 commit 847c890
Show file tree
Hide file tree
Showing 20 changed files with 54 additions and 7 deletions.
4 changes: 3 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,8 @@ wasm-bindgen-test = "0.3"

[features]
hacspec = [] # TODO: #7 Use specs instead of efficient implementations
rand = []
rand = ["std"] # rand requires std because of std::error::Error
wasm = ["wasm-bindgen"]
log = ["dep:log"]
default = ["std"]
std = []
2 changes: 2 additions & 0 deletions src/aead.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
use crate::hacl::aesgcm;
use crate::hacl::chacha20_poly1305;

use alloc::vec::Vec;

use libcrux_platform::{aes_ni_support, simd128_support, simd256_support};

/// The AEAD Errors.
Expand Down
1 change: 1 addition & 0 deletions src/digest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ use crate::hacl::{
};

use libcrux_platform::{simd128_support, simd256_support};
use alloc::vec::Vec;

#[derive(Debug)]
pub enum Error {
Expand Down
18 changes: 16 additions & 2 deletions src/drbg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

use crate::hacl::drbg;
// re-export here for convenience
use alloc::vec;
use alloc::vec::Vec;
pub use rand::{CryptoRng, RngCore};

#[derive(Debug)]
Expand All @@ -16,12 +18,23 @@ pub enum Error {
UnableToGenerate,
}

impl std::fmt::Display for Error {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
impl core::fmt::Display for Error {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
f.write_fmt(format_args!("{self:?}"))
}
}

// The `Error` trait is defined in `core::error::Error` but it is not yet stabilized.
// See: https://github.com/rust-lang/rust/issues/103765
//
// When `core::error::Error` is stablized, this should be changed to `impl core::error::Error`
// and the #[cfg] should be removed.
//
// Because of this, the `rand` feature depends on the `std` feature. The `rand` crate itself
// necessarily depends on std because it is exporting a type that depends on `std::error::Error`.
// If `core::error::Error` is stabilized and the `rand` crate moves to it, then no_std becomes
// viable for both `rand` and this crate.
#[cfg(feature = "std")]
impl std::error::Error for Error {}

pub struct Drbg {
Expand Down Expand Up @@ -169,6 +182,7 @@ impl Drbg {
}

/// Implementation of the [`RngCore`] trait for the [`Drbg`].
#[cfg(feature = "rand")]
impl RngCore for Drbg {
fn next_u32(&mut self) -> u32 {
let mut bytes: [u8; 4] = [0; 4];
Expand Down
5 changes: 5 additions & 0 deletions src/ecdh.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
//! For P256 the portable HACL implementation is used.

use crate::hacl;
use alloc::string::String;
use alloc::vec::Vec;

#[derive(Debug, PartialEq, Eq)]
pub enum LowLevelError {
Expand Down Expand Up @@ -47,6 +49,7 @@ pub enum Algorithm {

pub(crate) mod x25519 {
use rand::{CryptoRng, Rng};
use alloc::format;

use super::Error;

Expand Down Expand Up @@ -231,6 +234,8 @@ pub use x25519::key_gen as x25519_key_gen;

pub(crate) mod p256 {
use rand::{CryptoRng, Rng};
use alloc::format;


// P256 we only have in HACL
use crate::hacl::p256;
Expand Down
4 changes: 2 additions & 2 deletions src/hacl/aesgcm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ macro_rules! implement {
let mut tag = Tag::default();
hardware_support()?;
let ok = unsafe {
let mut state_ptr: *mut EverCrypt_AEAD_state_s = std::ptr::null_mut();
let mut state_ptr: *mut EverCrypt_AEAD_state_s = core::ptr::null_mut();
let e = EverCrypt_AEAD_create_in($alg as u8, &mut state_ptr, key.as_ptr() as _);
if e != 0 {
return Err(Error::EncryptionError);
Expand Down Expand Up @@ -99,7 +99,7 @@ macro_rules! implement {
) -> Result<(), Error> {
hardware_support()?;
let ok = unsafe {
let mut state_ptr: *mut EverCrypt_AEAD_state_s = std::ptr::null_mut();
let mut state_ptr: *mut EverCrypt_AEAD_state_s = core::ptr::null_mut();
let e = EverCrypt_AEAD_create_in($alg as u8, &mut state_ptr, key.as_ptr() as _);
if e != 0 {
return Err(Error::EncryptionError);
Expand Down
2 changes: 2 additions & 0 deletions src/hacl/hkdf.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,8 @@ macro_rules! impl_hkdf {
/// length is not const.
pub mod vec {
use super::super::Error;
use alloc::vec::Vec;
use alloc::vec;

/// HKDF expand using the pre-key material `prk` and `info`. The output length
/// is defined through the result type.
Expand Down
1 change: 1 addition & 0 deletions src/hkdf.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
//! HKDF
//!
//! This module implements HKDF on SHA 1 and SHA 2 (except for SHA 224).
use alloc::vec::Vec;

/// The HKDF algorithm defining the used hash function.
#[derive(Copy, Clone, Debug, PartialEq)]
Expand Down
1 change: 1 addition & 0 deletions src/hmac.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
//! This module implements HMAC on SHA 1 and SHA 2 (except for SHA 224).

use crate::hkdf;
use alloc::vec::Vec;

/// The HMAC algorithm defining the used hash function.
#[derive(Copy, Clone, Debug, PartialEq)]
Expand Down
1 change: 1 addition & 0 deletions src/hpke/aead.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ use crate::{
aead::{self, *},
hmac::tag_size,
};
use alloc::vec::Vec;

use super::errors::*;

Expand Down
1 change: 1 addition & 0 deletions src/hpke/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ pub enum HpkeError {
/// An opaque error happened in a crypto operation outside of this code.
CryptoError,
}
use alloc::vec::Vec;

/// A [`Result`] type that returns a [`Bytes`] or an [`HpkeError`].
pub type HpkeBytesResult = Result<Vec<u8>, HpkeError>;
Expand Down
3 changes: 3 additions & 0 deletions src/hpke/hpke.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ use super::kem::*;

use super::errors::*;

use alloc::vec::Vec;
use alloc::vec;

// === Constants ===

/// A one-byte value indicating the HPKE mode, defined in the following table.
Expand Down
2 changes: 2 additions & 0 deletions src/hpke/kdf.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
use crate::hkdf::Algorithm;

use super::errors::*;
use alloc::vec::Vec;
use alloc::vec;

/// ## Key Derivation Functions (KDFs)
///
Expand Down
3 changes: 3 additions & 0 deletions src/hpke/kem.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ use crate::kem::{kyber::KyberKeyPair, kyber768_generate_keypair_derand, *};
use super::errors::*;
use super::kdf::*;

use alloc::vec::Vec;
use alloc::vec;

/// ## Key Encapsulation Mechanisms (KEMs)
///
/// | Value | KEM | Nsecret | Nenc | Npk | Nsk | Auth | Reference |
Expand Down
1 change: 1 addition & 0 deletions src/kem.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
//! # Key Encapsulation Mechanism
//!
//! A KEM interface.
use alloc::vec::Vec;

use rand::{CryptoRng, Rng};

Expand Down
2 changes: 1 addition & 1 deletion src/kem/kyber/ind_cpa.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use std::usize;
use core::usize;

use super::{
arithmetic::PolynomialRingElement,
Expand Down
3 changes: 3 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@
//!
//! The unified, formally verified, cryptography library.

#![cfg_attr(all(not(test), not(feature = "std")), no_std)]

pub use libcrux_platform::aes_ni_support;
extern crate alloc;

// Jasmin
#[cfg(all(target_arch = "x86_64", any(target_os = "linux", target_os = "macos")))]
Expand Down
3 changes: 3 additions & 0 deletions src/signature.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ use crate::{
hacl::{self, ed25519, p256},
};
use rand::{CryptoRng, Rng, RngCore};
use alloc::vec::Vec;

use self::rsa_pss::RsaPssSignature;

Expand Down Expand Up @@ -85,6 +86,8 @@ pub mod rsa_pss {
};

use super::{DigestAlgorithm, Error};
use alloc::vec::Vec;
use alloc::vec;

/// A [`Algorithm::RsaPss`] Signature
#[derive(Debug, Clone, PartialEq, Eq)]
Expand Down
2 changes: 2 additions & 0 deletions sys/hacl/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ bindgen = { version = "0.69", optional = true }

[features]
bindings = ["bindgen"] # generate fresh bindings
std = []
default = ["std"]

[dev-dependencies]
hex = "0.4.3"
Expand Down
2 changes: 1 addition & 1 deletion sys/hacl/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
//! # HACL Sys
//!
//! Bindings to HACL C code

#![cfg_attr(all(not(test), not(feature = "std")), no_std)]
#![allow(non_camel_case_types, non_snake_case, non_upper_case_globals)]

// #[cfg(not(target_arch = "wasm32"))]
Expand Down

0 comments on commit 847c890

Please sign in to comment.