wolf_crypto/lib.rs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198
//! Safe bindings to wolfSSL's `wolfcrypt`
//!
//! This crate provides a well-tested, type-safe, zero-cost interface for wolfSSL's software
//! cryptographic module `wolfcrypt`. It leverages Rust's type system to ensure correct usage
//! of cryptographic primitives at compile-time.
//!
//! # Safety
//!
//! This crate uses Rust's type system and ownership model to prevent common cryptographic
//! mistakes. However, this library cannot ensure you use the provided cryptographic primitives
//! correctly in the broader context of your application to ensure overall security.
//!
//! # Performance
//!
//! The bindings are designed to be zero-cost, allowing direct use of the highly optimized
//! `wolfcrypt` implementations without additional runtime overhead.
//!
//! The majority of the future performance improvements will be in enabling further hardware
//! acceleration in the underlying `wolf-crypto-sys` crate.
//!
//! # Stability
//!
//! This library is currently in alpha. As such, there is no guarantee of API stability
//! across any update. This crate follows semantic versioning.
#![cfg_attr(docsrs, feature(doc_cfg))]
#![cfg_attr(not(any(test, feature = "std")), no_std)]
#![warn(
clippy::pedantic,
clippy::nursery,
clippy::all
)]
// requirements for lower level things, these are all checked, just not checked in the unsafe
// api.
#![allow(clippy::cast_possible_truncation)]
// stupid lint IMO
#![allow(clippy::module_name_repetitions)]
// always checked in safe api
#![allow(clippy::cast_possible_wrap)]
#![allow(clippy::cast_lossless)]
// this devalues things which actually require the must-use attribute
#![allow(clippy::must_use_candidate)]
// I am passing something which is 32 bits, so either half the size (more frequently) or the same
// size as the reference. This lint needs to be more context aware as this is just bad.
#![allow(clippy::needless_pass_by_value)]
// I don't care for the assertion in my panic API where I am checking if OK. This is just for
// more controlled error messages. Again, should be disabled
#![allow(clippy::manual_assert)]
// I don't need a linter lecturing me on performance
#![allow(clippy::inline_always)]
// I am doing constant time bitwise hacks
#![allow(clippy::cast_sign_loss)]
// for debug assertions
#![allow(clippy::used_underscore_binding)]
// why does clippy not look at the difference in size between variants or, just the impact
// one variant has on the total size? Like this lint is somewhat aimed at performance optimization,
// yet where it is giving me these warnings the size of Ok and Err are equivalent.
#![allow(clippy::result_large_err)]
// I may just want to be cautious.
#![allow(clippy::redundant_pub_crate)]
#![allow(clippy::similar_names)]
#![warn(missing_docs)]
#[cfg(any(test, feature = "alloc"))]
extern crate alloc;
#[cfg(test)]
extern crate std;
extern crate core;
#[macro_use]
mod macros;
mod ptr;
pub mod buf;
pub mod opaque_res;
mod sealed;
// TODO: FURTHER TESTING.
// pub mod random;
pub mod aes;
pub mod hash;
mod error;
non_fips! { // unfortunate
pub mod chacha;
}
pub mod aead;
pub mod mac;
pub(crate) mod ct;
pub mod kdf;
pub use ct::ct_eq;
pub mod hex {
//! Constant-Time Hex Encoding and Decoding
pub use super::ct::HexError;
pub use super::ct::hex_encode as encode_into;
pub use super::ct::hex_encode_str as encode_str;
pub use super::ct::hex_decode as decode_into;
alloc! {
pub use super::ct::hex_encode_alloc as encode;
pub use super::ct::hex_decode_alloc as decode;
}
}
pub use error::Unspecified;
pub use error::MakeOpaque;
#[cfg(not(target_pointer_width = "32"))]
#[inline]
#[must_use]
pub(crate) const fn const_can_cast_u32<const S: usize>() -> bool {
const_lte::<S, { u32::MAX }>()
}
#[cfg(not(target_pointer_width = "32"))]
#[inline]
#[must_use]
pub(crate) const fn can_cast_u32(len: usize) -> bool {
len <= (u32::MAX as usize)
}
#[cfg(target_pointer_width = "32")]
#[inline]
#[must_use]
pub(crate) const fn const_can_cast_u32<const S: usize>() -> bool {
true
}
#[cfg(target_pointer_width = "32")]
#[inline]
#[must_use]
pub(crate) const fn can_cast_u32(_len: usize) -> bool {
true
}
#[inline]
#[must_use]
pub(crate) const fn const_can_cast_i32<const S: usize>() -> bool {
const_lte::<S, { i32::MAX as u32 }>()
}
#[inline]
#[must_use]
pub(crate) const fn can_cast_i32(len: usize) -> bool {
len <= (i32::MAX as usize)
}
#[must_use]
pub(crate) const fn const_lte<const L: usize, const MAX: u32>() -> bool {
L <= (MAX as usize)
}
#[cfg_attr(not(feature = "allow-non-fips"), allow(dead_code))]
#[must_use]
pub(crate) const fn const_gte<const L: usize, const MIN: usize>() -> bool {
L >= MIN
}
#[allow(dead_code)]
#[inline]
#[must_use]
pub(crate) const fn lte<const MAX: usize>(value: usize) -> bool {
value <= MAX
}
#[cfg_attr(not(feature = "allow-non-fips"), allow(dead_code))]
#[inline]
#[must_use]
pub(crate) const fn gte<const MIN: usize>(value: usize) -> bool {
value >= MIN
}
#[cfg(not(target_pointer_width = "32"))]
#[inline]
#[must_use]
pub(crate) const fn to_u32(num: usize) -> Option<u32> {
if can_cast_u32(num) {
Some(num as u32)
} else {
None
}
}
#[cfg(target_pointer_width = "32")]
#[inline]
#[must_use]
pub(crate) const fn to_u32(num: usize) -> Option<u32> {
Some(num as u32)
}