mirror of
https://github.com/wolfSSL/wolfssl.git
synced 2026-07-05 22:50:50 +02:00
Merge pull request #10402 from holtrop-wolfssl/rust-crate-updates-2026-05-05
Rust wrapper: ensure memory safety for C RNG struct
This commit is contained in:
@@ -11,7 +11,7 @@ categories = ["cryptography", "security", "api-bindings"]
|
||||
readme = "README.md"
|
||||
|
||||
[features]
|
||||
std = []
|
||||
alloc = []
|
||||
rand_core = ["dep:rand_core"]
|
||||
aead = ["dep:aead"]
|
||||
cipher = ["dep:cipher"]
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
FEATURES := rand_core,aead,cipher,digest,mac,signature,password-hash,kem
|
||||
FEATURES := alloc,rand_core,aead,cipher,digest,mac,signature,password-hash,kem
|
||||
CARGO_FEATURE_FLAGS := --features $(FEATURES)
|
||||
|
||||
.PHONY: all
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
The `wolfssl-wolfcrypt` crate is a Rust wrapper for the wolfCrypt cryptographic
|
||||
algorithms portion of the wolfSSL C library.
|
||||
|
||||
This crate requires wolfSSL version 5.9.0 or newer.
|
||||
|
||||
## Installation
|
||||
|
||||
The `wolfssl` C library must be installed to be used by the Rust crate.
|
||||
|
||||
@@ -371,6 +371,9 @@ fn scan_cfg() -> Result<()> {
|
||||
check_cfg(&binding, "wc_Dh_ffdhe6144_Get", "dh_ffdhe_6144");
|
||||
check_cfg(&binding, "wc_Dh_ffdhe8192_Get", "dh_ffdhe_8192");
|
||||
|
||||
/* crypto callback */
|
||||
check_cfg(&binding, "wc_CryptoCb_RegisterDevice", "wolf_crypto_cb");
|
||||
|
||||
/* ecc */
|
||||
check_cfg(&binding, "wc_ecc_init", "ecc");
|
||||
check_cfg(&binding, "wc_ecc_export_point_der_compressed", "ecc_comp_key");
|
||||
|
||||
@@ -33,13 +33,10 @@ use zeroize::{Zeroize, ZeroizeOnDrop};
|
||||
use aead::{AeadCore, AeadInPlace, KeyInit, KeySizeUser};
|
||||
|
||||
#[cfg(feature = "aead")]
|
||||
use aead::generic_array::typenum::{U0, U12, U16, U32};
|
||||
use aead::generic_array::typenum::{U0, U12, U16, U24, U32};
|
||||
|
||||
#[cfg(all(feature = "cipher", not(feature = "aead")))]
|
||||
use cipher::typenum::consts::{U16, U32};
|
||||
|
||||
#[cfg(feature = "cipher")]
|
||||
use cipher::typenum::consts::U24;
|
||||
use cipher::typenum::consts::{U16, U24, U32};
|
||||
|
||||
#[cfg(feature = "cipher")]
|
||||
use cipher::{
|
||||
@@ -557,6 +554,58 @@ impl AeadInPlace for Aes128Ccm {
|
||||
}
|
||||
}
|
||||
|
||||
/// AES-192-CCM authenticated encryption (12-byte nonce, 16-byte tag).
|
||||
#[cfg(all(aes_ccm, feature = "aead"))]
|
||||
#[derive(Zeroize, ZeroizeOnDrop)]
|
||||
pub struct Aes192Ccm {
|
||||
key: [u8; 24],
|
||||
}
|
||||
|
||||
#[cfg(all(aes_ccm, feature = "aead"))]
|
||||
impl KeySizeUser for Aes192Ccm {
|
||||
type KeySize = U24;
|
||||
}
|
||||
|
||||
#[cfg(all(aes_ccm, feature = "aead"))]
|
||||
impl AeadCore for Aes192Ccm {
|
||||
type NonceSize = U12;
|
||||
type TagSize = U16;
|
||||
type CiphertextOverhead = U0;
|
||||
}
|
||||
|
||||
#[cfg(all(aes_ccm, feature = "aead"))]
|
||||
impl KeyInit for Aes192Ccm {
|
||||
fn new(key: &aead::Key<Self>) -> Self {
|
||||
let mut k = [0u8; 24];
|
||||
k.copy_from_slice(key.as_ref());
|
||||
Aes192Ccm { key: k }
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(all(aes_ccm, feature = "aead"))]
|
||||
impl AeadInPlace for Aes192Ccm {
|
||||
fn encrypt_in_place_detached(
|
||||
&self,
|
||||
nonce: &aead::Nonce<Self>,
|
||||
associated_data: &[u8],
|
||||
buffer: &mut [u8],
|
||||
) -> Result<aead::Tag<Self>, aead::Error> {
|
||||
let mut tag = aead::Tag::<Self>::default();
|
||||
ccm_encrypt_in_place(&self.key, nonce.as_ref(), associated_data, buffer, tag.as_mut())?;
|
||||
Ok(tag)
|
||||
}
|
||||
|
||||
fn decrypt_in_place_detached(
|
||||
&self,
|
||||
nonce: &aead::Nonce<Self>,
|
||||
associated_data: &[u8],
|
||||
buffer: &mut [u8],
|
||||
tag: &aead::Tag<Self>,
|
||||
) -> Result<(), aead::Error> {
|
||||
ccm_decrypt_in_place(&self.key, nonce.as_ref(), associated_data, buffer, tag.as_ref())
|
||||
}
|
||||
}
|
||||
|
||||
/// AES-256-CCM authenticated encryption (12-byte nonce, 16-byte tag).
|
||||
#[cfg(all(aes_ccm, feature = "aead"))]
|
||||
#[derive(Zeroize, ZeroizeOnDrop)]
|
||||
@@ -1713,6 +1762,58 @@ impl AeadInPlace for Aes128Gcm {
|
||||
}
|
||||
}
|
||||
|
||||
/// AES-192-GCM authenticated encryption (12-byte nonce, 16-byte tag).
|
||||
#[cfg(all(aes_gcm, feature = "aead"))]
|
||||
#[derive(Zeroize, ZeroizeOnDrop)]
|
||||
pub struct Aes192Gcm {
|
||||
key: [u8; 24],
|
||||
}
|
||||
|
||||
#[cfg(all(aes_gcm, feature = "aead"))]
|
||||
impl KeySizeUser for Aes192Gcm {
|
||||
type KeySize = U24;
|
||||
}
|
||||
|
||||
#[cfg(all(aes_gcm, feature = "aead"))]
|
||||
impl AeadCore for Aes192Gcm {
|
||||
type NonceSize = U12;
|
||||
type TagSize = U16;
|
||||
type CiphertextOverhead = U0;
|
||||
}
|
||||
|
||||
#[cfg(all(aes_gcm, feature = "aead"))]
|
||||
impl KeyInit for Aes192Gcm {
|
||||
fn new(key: &aead::Key<Self>) -> Self {
|
||||
let mut k = [0u8; 24];
|
||||
k.copy_from_slice(key.as_ref());
|
||||
Aes192Gcm { key: k }
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(all(aes_gcm, feature = "aead"))]
|
||||
impl AeadInPlace for Aes192Gcm {
|
||||
fn encrypt_in_place_detached(
|
||||
&self,
|
||||
nonce: &aead::Nonce<Self>,
|
||||
associated_data: &[u8],
|
||||
buffer: &mut [u8],
|
||||
) -> Result<aead::Tag<Self>, aead::Error> {
|
||||
let mut tag = aead::Tag::<Self>::default();
|
||||
gcm_encrypt_in_place(&self.key, nonce.as_ref(), associated_data, buffer, tag.as_mut())?;
|
||||
Ok(tag)
|
||||
}
|
||||
|
||||
fn decrypt_in_place_detached(
|
||||
&self,
|
||||
nonce: &aead::Nonce<Self>,
|
||||
associated_data: &[u8],
|
||||
buffer: &mut [u8],
|
||||
tag: &aead::Tag<Self>,
|
||||
) -> Result<(), aead::Error> {
|
||||
gcm_decrypt_in_place(&self.key, nonce.as_ref(), associated_data, buffer, tag.as_ref())
|
||||
}
|
||||
}
|
||||
|
||||
/// AES-256-GCM authenticated encryption (12-byte nonce, 16-byte tag).
|
||||
#[cfg(all(aes_gcm, feature = "aead"))]
|
||||
#[derive(Zeroize, ZeroizeOnDrop)]
|
||||
|
||||
@@ -0,0 +1,169 @@
|
||||
/*
|
||||
* Copyright (C) 2006-2026 wolfSSL Inc.
|
||||
*
|
||||
* This file is part of wolfSSL.
|
||||
*
|
||||
* wolfSSL is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* wolfSSL is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
|
||||
*/
|
||||
|
||||
/*!
|
||||
RustCrypto `digest` trait implementations for the wolfCrypt BLAKE2 hash
|
||||
types.
|
||||
|
||||
Because BLAKE2b and BLAKE2s have variable digest sizes, this module exposes
|
||||
typed wrappers that pin the digest size of an underlying [`crate::blake2`]
|
||||
instance to a specific value, matching the typed aliases provided by the
|
||||
RustCrypto `blake2` crate (`Blake2b512`, `Blake2b256`, `Blake2s256`, etc.).
|
||||
|
||||
Each typed wrapper implements the traits from the `digest` crate
|
||||
(`HashMarker`, `OutputSizeUser`, `BlockSizeUser`, `Update`, `Reset`,
|
||||
`FixedOutput`, and `FixedOutputReset`). With these implementations the
|
||||
`digest::Digest` trait becomes available via its blanket implementation,
|
||||
allowing these hashers to be used anywhere a RustCrypto `Digest` is
|
||||
accepted.
|
||||
|
||||
Any failure returned by the underlying wolfCrypt call in a trait method
|
||||
will result in a panic, matching the infallible signatures required by the
|
||||
RustCrypto traits.
|
||||
*/
|
||||
|
||||
use digest::consts::{U16, U24, U32, U48, U64, U128};
|
||||
|
||||
macro_rules! impl_blake2_digest {
|
||||
(
|
||||
$(#[$attr:meta])*
|
||||
$name:ident,
|
||||
wc_ty = $wc_ty:path,
|
||||
digest_size = $digest_size:literal,
|
||||
out = $out_size:ty,
|
||||
block = $block_size:ty
|
||||
) => {
|
||||
$(#[$attr])*
|
||||
pub struct $name {
|
||||
blake2: $wc_ty,
|
||||
}
|
||||
|
||||
$(#[$attr])*
|
||||
impl Default for $name {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
blake2: <$wc_ty>::new($digest_size)
|
||||
.expect("wolfCrypt BLAKE2 init failed"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$(#[$attr])*
|
||||
impl digest::HashMarker for $name {}
|
||||
|
||||
$(#[$attr])*
|
||||
impl digest::OutputSizeUser for $name {
|
||||
type OutputSize = $out_size;
|
||||
}
|
||||
|
||||
$(#[$attr])*
|
||||
impl digest::block_api::BlockSizeUser for $name {
|
||||
type BlockSize = $block_size;
|
||||
}
|
||||
|
||||
$(#[$attr])*
|
||||
impl digest::Update for $name {
|
||||
fn update(&mut self, data: &[u8]) {
|
||||
<$wc_ty>::update(&mut self.blake2, data)
|
||||
.expect("wolfCrypt BLAKE2 update failed");
|
||||
}
|
||||
}
|
||||
|
||||
$(#[$attr])*
|
||||
impl digest::Reset for $name {
|
||||
fn reset(&mut self) {
|
||||
self.blake2 = <$wc_ty>::new($digest_size)
|
||||
.expect("wolfCrypt BLAKE2 init failed");
|
||||
}
|
||||
}
|
||||
|
||||
$(#[$attr])*
|
||||
impl digest::FixedOutput for $name {
|
||||
fn finalize_into(mut self, out: &mut digest::Output<Self>) {
|
||||
<$wc_ty>::finalize(&mut self.blake2, out.as_mut_slice())
|
||||
.expect("wolfCrypt BLAKE2 finalize failed");
|
||||
}
|
||||
}
|
||||
|
||||
$(#[$attr])*
|
||||
impl digest::FixedOutputReset for $name {
|
||||
fn finalize_into_reset(&mut self, out: &mut digest::Output<Self>) {
|
||||
<$wc_ty>::finalize(&mut self.blake2, out.as_mut_slice())
|
||||
.expect("wolfCrypt BLAKE2 finalize failed");
|
||||
self.blake2 = <$wc_ty>::new($digest_size)
|
||||
.expect("wolfCrypt BLAKE2 init failed");
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
impl_blake2_digest! {
|
||||
#[cfg(blake2b)]
|
||||
Blake2b256,
|
||||
wc_ty = crate::blake2::BLAKE2b,
|
||||
digest_size = 32,
|
||||
out = U32,
|
||||
block = U128
|
||||
}
|
||||
|
||||
impl_blake2_digest! {
|
||||
#[cfg(blake2b)]
|
||||
Blake2b384,
|
||||
wc_ty = crate::blake2::BLAKE2b,
|
||||
digest_size = 48,
|
||||
out = U48,
|
||||
block = U128
|
||||
}
|
||||
|
||||
impl_blake2_digest! {
|
||||
#[cfg(blake2b)]
|
||||
Blake2b512,
|
||||
wc_ty = crate::blake2::BLAKE2b,
|
||||
digest_size = 64,
|
||||
out = U64,
|
||||
block = U128
|
||||
}
|
||||
|
||||
impl_blake2_digest! {
|
||||
#[cfg(blake2s)]
|
||||
Blake2s128,
|
||||
wc_ty = crate::blake2::BLAKE2s,
|
||||
digest_size = 16,
|
||||
out = U16,
|
||||
block = U64
|
||||
}
|
||||
|
||||
impl_blake2_digest! {
|
||||
#[cfg(blake2s)]
|
||||
Blake2s192,
|
||||
wc_ty = crate::blake2::BLAKE2s,
|
||||
digest_size = 24,
|
||||
out = U24,
|
||||
block = U64
|
||||
}
|
||||
|
||||
impl_blake2_digest! {
|
||||
#[cfg(blake2s)]
|
||||
Blake2s256,
|
||||
wc_ty = crate::blake2::BLAKE2s,
|
||||
digest_size = 32,
|
||||
out = U32,
|
||||
block = U64
|
||||
}
|
||||
@@ -0,0 +1,163 @@
|
||||
/*
|
||||
* Copyright (C) 2006-2026 wolfSSL Inc.
|
||||
*
|
||||
* This file is part of wolfSSL.
|
||||
*
|
||||
* wolfSSL is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* wolfSSL is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
|
||||
*/
|
||||
|
||||
/*!
|
||||
RustCrypto `digest::Mac` trait implementations for the wolfCrypt keyed
|
||||
BLAKE2 types.
|
||||
|
||||
These wrappers cover keyed BLAKE2 (the construction exposed by RustCrypto's
|
||||
`blake2` crate as `Blake2bMac` / `Blake2sMac`), not the wolfCrypt-specific
|
||||
HMAC-BLAKE2 construction. With these implementations the `digest::Mac`
|
||||
trait becomes available via its blanket implementation, allowing these
|
||||
types to be used anywhere a RustCrypto `Mac` is accepted.
|
||||
|
||||
Each typed wrapper pins the digest size and the maximum key size to a
|
||||
specific algorithm parameterization. The `Blake2sMac128`, `Blake2sMac192`,
|
||||
and `Blake2sMac256` wrappers all accept keys of any length up to 32 bytes
|
||||
(the BLAKE2s maximum), and the `Blake2bMac512` wrapper accepts keys of any
|
||||
length up to 64 bytes (the BLAKE2b maximum), matching the variable-length
|
||||
key behavior of the RustCrypto `blake2` crate's `Blake2sMac` / `Blake2bMac`
|
||||
types.
|
||||
|
||||
Any failure returned by the underlying wolfCrypt call in a trait method
|
||||
will result in a panic, matching the infallible signatures required by the
|
||||
RustCrypto traits.
|
||||
*/
|
||||
|
||||
use digest::consts::{U16, U24, U32, U48, U64};
|
||||
|
||||
macro_rules! impl_blake2_mac {
|
||||
(
|
||||
$(#[$attr:meta])*
|
||||
$name:ident,
|
||||
wc_ty = $wc_ty:path,
|
||||
digest_size = $digest_size:literal,
|
||||
out = $out_size:ty,
|
||||
key = $key_size:ty
|
||||
) => {
|
||||
$(#[$attr])*
|
||||
pub struct $name {
|
||||
blake2: $wc_ty,
|
||||
}
|
||||
|
||||
$(#[$attr])*
|
||||
impl digest::MacMarker for $name {}
|
||||
|
||||
$(#[$attr])*
|
||||
impl digest::OutputSizeUser for $name {
|
||||
type OutputSize = $out_size;
|
||||
}
|
||||
|
||||
$(#[$attr])*
|
||||
impl digest::common::KeySizeUser for $name {
|
||||
type KeySize = $key_size;
|
||||
}
|
||||
|
||||
$(#[$attr])*
|
||||
impl digest::KeyInit for $name {
|
||||
fn new(key: &digest::Key<Self>) -> Self {
|
||||
Self {
|
||||
blake2: <$wc_ty>::new_with_key($digest_size, key.as_slice())
|
||||
.expect("wolfCrypt BLAKE2 init failed"),
|
||||
}
|
||||
}
|
||||
|
||||
fn new_from_slice(key: &[u8]) -> Result<Self, digest::InvalidLength> {
|
||||
if key.len() > <Self as digest::common::KeySizeUser>::key_size() {
|
||||
return Err(digest::InvalidLength);
|
||||
}
|
||||
Ok(Self {
|
||||
blake2: <$wc_ty>::new_with_key($digest_size, key)
|
||||
.map_err(|_| digest::InvalidLength)?,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
$(#[$attr])*
|
||||
impl digest::Update for $name {
|
||||
fn update(&mut self, data: &[u8]) {
|
||||
<$wc_ty>::update(&mut self.blake2, data)
|
||||
.expect("wolfCrypt BLAKE2 update failed");
|
||||
}
|
||||
}
|
||||
|
||||
$(#[$attr])*
|
||||
impl digest::FixedOutput for $name {
|
||||
fn finalize_into(mut self, out: &mut digest::Output<Self>) {
|
||||
<$wc_ty>::finalize(&mut self.blake2, out.as_mut_slice())
|
||||
.expect("wolfCrypt BLAKE2 finalize failed");
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
impl_blake2_mac! {
|
||||
#[cfg(blake2b)]
|
||||
Blake2bMac256,
|
||||
wc_ty = crate::blake2::BLAKE2b,
|
||||
digest_size = 32,
|
||||
out = U32,
|
||||
key = U64
|
||||
}
|
||||
|
||||
impl_blake2_mac! {
|
||||
#[cfg(blake2b)]
|
||||
Blake2bMac384,
|
||||
wc_ty = crate::blake2::BLAKE2b,
|
||||
digest_size = 48,
|
||||
out = U48,
|
||||
key = U64
|
||||
}
|
||||
|
||||
impl_blake2_mac! {
|
||||
#[cfg(blake2b)]
|
||||
Blake2bMac512,
|
||||
wc_ty = crate::blake2::BLAKE2b,
|
||||
digest_size = 64,
|
||||
out = U64,
|
||||
key = U64
|
||||
}
|
||||
|
||||
impl_blake2_mac! {
|
||||
#[cfg(blake2s)]
|
||||
Blake2sMac128,
|
||||
wc_ty = crate::blake2::BLAKE2s,
|
||||
digest_size = 16,
|
||||
out = U16,
|
||||
key = U32
|
||||
}
|
||||
|
||||
impl_blake2_mac! {
|
||||
#[cfg(blake2s)]
|
||||
Blake2sMac192,
|
||||
wc_ty = crate::blake2::BLAKE2s,
|
||||
digest_size = 24,
|
||||
out = U24,
|
||||
key = U32
|
||||
}
|
||||
|
||||
impl_blake2_mac! {
|
||||
#[cfg(blake2s)]
|
||||
Blake2sMac256,
|
||||
wc_ty = crate::blake2::BLAKE2s,
|
||||
digest_size = 32,
|
||||
out = U32,
|
||||
key = U32
|
||||
}
|
||||
@@ -26,12 +26,15 @@ functionality.
|
||||
#![cfg(curve25519)]
|
||||
|
||||
#[cfg(random)]
|
||||
use crate::random::RNG;
|
||||
use crate::random::{RNG, RngHandle};
|
||||
use crate::sys;
|
||||
use core::mem::MaybeUninit;
|
||||
|
||||
pub struct Curve25519Key {
|
||||
wc_key: sys::curve25519_key,
|
||||
/// RNG bound via `set_rng`, kept alive while the C struct holds its pointer.
|
||||
#[cfg(random)]
|
||||
rng: Option<RngHandle>,
|
||||
}
|
||||
|
||||
impl Curve25519Key {
|
||||
@@ -73,7 +76,7 @@ impl Curve25519Key {
|
||||
/// Returns either Ok(curve25519key) on success or Err(e) containing the
|
||||
/// wolfSSL library error code value.
|
||||
#[cfg(random)]
|
||||
pub fn generate(rng: &mut RNG) -> Result<Self, i32> {
|
||||
pub fn generate(rng: &RNG) -> Result<Self, i32> {
|
||||
let mut wc_key: MaybeUninit<sys::curve25519_key> = MaybeUninit::uninit();
|
||||
let rc = unsafe {
|
||||
sys::wc_curve25519_init(wc_key.as_mut_ptr())
|
||||
@@ -82,9 +85,13 @@ impl Curve25519Key {
|
||||
return Err(rc);
|
||||
}
|
||||
let wc_key = unsafe { wc_key.assume_init() };
|
||||
let mut curve25519key = Curve25519Key { wc_key };
|
||||
let mut curve25519key = Curve25519Key {
|
||||
wc_key,
|
||||
#[cfg(random)]
|
||||
rng: None,
|
||||
};
|
||||
let rc = unsafe {
|
||||
sys::wc_curve25519_make_key(&mut rng.wc_rng, Self::KEYSIZE as i32,
|
||||
sys::wc_curve25519_make_key(rng.wc_rng, Self::KEYSIZE as i32,
|
||||
&mut curve25519key.wc_key)
|
||||
};
|
||||
if rc != 0 {
|
||||
@@ -104,12 +111,12 @@ impl Curve25519Key {
|
||||
/// Returns either Ok(()) on success or Err(e) containing the wolfSSL
|
||||
/// library error code value.
|
||||
#[cfg(random)]
|
||||
pub fn generate_priv(rng: &mut RNG, out: &mut [u8]) -> Result<(), i32> {
|
||||
pub fn generate_priv(rng: &RNG, out: &mut [u8]) -> Result<(), i32> {
|
||||
if out.len() != Self::KEYSIZE {
|
||||
return Err(sys::wolfCrypt_ErrorCodes_BUFFER_E);
|
||||
}
|
||||
let rc = unsafe {
|
||||
sys::wc_curve25519_make_priv(&mut rng.wc_rng, Self::KEYSIZE as i32, out.as_mut_ptr())
|
||||
sys::wc_curve25519_make_priv(rng.wc_rng, Self::KEYSIZE as i32, out.as_mut_ptr())
|
||||
};
|
||||
if rc != 0 {
|
||||
return Err(rc);
|
||||
@@ -137,7 +144,11 @@ impl Curve25519Key {
|
||||
return Err(rc);
|
||||
}
|
||||
let wc_key = unsafe { wc_key.assume_init() };
|
||||
let mut curve25519key = Curve25519Key { wc_key };
|
||||
let mut curve25519key = Curve25519Key {
|
||||
wc_key,
|
||||
#[cfg(random)]
|
||||
rng: None,
|
||||
};
|
||||
let rc = unsafe {
|
||||
sys::wc_curve25519_import_private(private.as_ptr(), private_size,
|
||||
&mut curve25519key.wc_key)
|
||||
@@ -169,7 +180,11 @@ impl Curve25519Key {
|
||||
return Err(rc);
|
||||
}
|
||||
let wc_key = unsafe { wc_key.assume_init() };
|
||||
let mut curve25519key = Curve25519Key { wc_key };
|
||||
let mut curve25519key = Curve25519Key {
|
||||
wc_key,
|
||||
#[cfg(random)]
|
||||
rng: None,
|
||||
};
|
||||
let endian = if big_endian {sys::EC25519_BIG_ENDIAN} else {sys::EC25519_LITTLE_ENDIAN};
|
||||
let rc = unsafe {
|
||||
sys::wc_curve25519_import_private_ex(private.as_ptr(),
|
||||
@@ -203,7 +218,11 @@ impl Curve25519Key {
|
||||
return Err(rc);
|
||||
}
|
||||
let wc_key = unsafe { wc_key.assume_init() };
|
||||
let mut curve25519key = Curve25519Key { wc_key };
|
||||
let mut curve25519key = Curve25519Key {
|
||||
wc_key,
|
||||
#[cfg(random)]
|
||||
rng: None,
|
||||
};
|
||||
let rc = unsafe {
|
||||
sys::wc_curve25519_import_private_raw(private.as_ptr(),
|
||||
private_size, public.as_ptr(), public_size,
|
||||
@@ -238,7 +257,11 @@ impl Curve25519Key {
|
||||
return Err(rc);
|
||||
}
|
||||
let wc_key = unsafe { wc_key.assume_init() };
|
||||
let mut curve25519key = Curve25519Key { wc_key };
|
||||
let mut curve25519key = Curve25519Key {
|
||||
wc_key,
|
||||
#[cfg(random)]
|
||||
rng: None,
|
||||
};
|
||||
let endian = if big_endian {sys::EC25519_BIG_ENDIAN} else {sys::EC25519_LITTLE_ENDIAN};
|
||||
let rc = unsafe {
|
||||
sys::wc_curve25519_import_private_raw_ex(private.as_ptr(),
|
||||
@@ -271,7 +294,11 @@ impl Curve25519Key {
|
||||
return Err(rc);
|
||||
}
|
||||
let wc_key = unsafe { wc_key.assume_init() };
|
||||
let mut curve25519key = Curve25519Key { wc_key };
|
||||
let mut curve25519key = Curve25519Key {
|
||||
wc_key,
|
||||
#[cfg(random)]
|
||||
rng: None,
|
||||
};
|
||||
let rc = unsafe {
|
||||
sys::wc_curve25519_import_public(public.as_ptr(), public_size,
|
||||
&mut curve25519key.wc_key)
|
||||
@@ -303,7 +330,11 @@ impl Curve25519Key {
|
||||
return Err(rc);
|
||||
}
|
||||
let wc_key = unsafe { wc_key.assume_init() };
|
||||
let mut curve25519key = Curve25519Key { wc_key };
|
||||
let mut curve25519key = Curve25519Key {
|
||||
wc_key,
|
||||
#[cfg(random)]
|
||||
rng: None,
|
||||
};
|
||||
let endian = if big_endian {sys::EC25519_BIG_ENDIAN} else {sys::EC25519_LITTLE_ENDIAN};
|
||||
let rc = unsafe {
|
||||
sys::wc_curve25519_import_public_ex(public.as_ptr(), public_size,
|
||||
@@ -353,12 +384,12 @@ impl Curve25519Key {
|
||||
/// Returns either Ok(()) on success or Err(e) containing the wolfSSL
|
||||
/// library error code value.
|
||||
#[cfg(all(curve25519_blinding, random))]
|
||||
pub fn make_pub_blind(private: &[u8], public: &mut [u8], rng: &mut RNG) -> Result<(), i32> {
|
||||
pub fn make_pub_blind(private: &[u8], public: &mut [u8], rng: &RNG) -> Result<(), i32> {
|
||||
let private_size = crate::buffer_len_to_i32(private.len())?;
|
||||
let public_size = crate::buffer_len_to_i32(public.len())?;
|
||||
let rc = unsafe {
|
||||
sys::wc_curve25519_make_pub_blind(public_size, public.as_mut_ptr(),
|
||||
private_size, private.as_ptr(), &mut rng.wc_rng)
|
||||
private_size, private.as_ptr(), rng.wc_rng)
|
||||
};
|
||||
if rc != 0 {
|
||||
return Err(rc);
|
||||
@@ -408,14 +439,14 @@ impl Curve25519Key {
|
||||
/// Returns either Ok(()) on success or Err(e) containing the wolfSSL
|
||||
/// library error code value.
|
||||
#[cfg(all(curve25519_blinding, random))]
|
||||
pub fn make_pub_generic_blind(private: &[u8], public: &mut [u8], basepoint: &[u8], rng: &mut RNG) -> Result<(), i32> {
|
||||
pub fn make_pub_generic_blind(private: &[u8], public: &mut [u8], basepoint: &[u8], rng: &RNG) -> Result<(), i32> {
|
||||
let private_size = crate::buffer_len_to_i32(private.len())?;
|
||||
let public_size = crate::buffer_len_to_i32(public.len())?;
|
||||
let basepoint_size = crate::buffer_len_to_i32(basepoint.len())?;
|
||||
let rc = unsafe {
|
||||
sys::wc_curve25519_generic_blind(public_size, public.as_mut_ptr(),
|
||||
private_size, private.as_ptr(), basepoint_size, basepoint.as_ptr(),
|
||||
&mut rng.wc_rng)
|
||||
rng.wc_rng)
|
||||
};
|
||||
if rc != 0 {
|
||||
return Err(rc);
|
||||
@@ -454,27 +485,57 @@ impl Curve25519Key {
|
||||
/// This is necessary when generating a shared secret if wolfSSL is built
|
||||
/// with the `WOLFSSL_CURVE25519_BLINDING` build option enabled.
|
||||
///
|
||||
/// The key takes ownership of the RNG, so the underlying `WC_RNG` is
|
||||
/// guaranteed to outlive this key.
|
||||
///
|
||||
/// # Parameters
|
||||
///
|
||||
/// * `rng`: The `RNG` struct instance to associate with this
|
||||
/// `Curve25519Key` instance. The `RNG` struct should not be moved in
|
||||
/// memory after calling this method.
|
||||
/// `Curve25519Key` instance.
|
||||
///
|
||||
/// # Returns
|
||||
///
|
||||
/// Returns Ok(()) on success or Err(e) containing the wolfSSL library
|
||||
/// error code value.
|
||||
#[cfg(all(curve25519_blinding, random))]
|
||||
pub fn set_rng(&mut self, rng: &mut RNG) -> Result<(), i32> {
|
||||
pub fn set_rng(&mut self, rng: RNG) -> Result<(), i32> {
|
||||
let wc_rng = rng.wc_rng;
|
||||
let rc = unsafe {
|
||||
sys::wc_curve25519_set_rng(&mut self.wc_key, &mut rng.wc_rng)
|
||||
sys::wc_curve25519_set_rng(&mut self.wc_key, wc_rng)
|
||||
};
|
||||
if rc != 0 {
|
||||
return Err(rc);
|
||||
}
|
||||
self.rng = Some(RngHandle::Owned(rng));
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Bind a shared `RNG` to this key. Available when the `alloc` feature
|
||||
/// is enabled.
|
||||
#[cfg(all(curve25519_blinding, random, feature = "alloc"))]
|
||||
pub fn set_shared_rng(&mut self, rng: alloc::rc::Rc<RNG>) -> Result<(), i32> {
|
||||
let wc_rng = rng.wc_rng;
|
||||
let rc = unsafe {
|
||||
sys::wc_curve25519_set_rng(&mut self.wc_key, wc_rng)
|
||||
};
|
||||
if rc != 0 {
|
||||
return Err(rc);
|
||||
}
|
||||
self.rng = Some(RngHandle::Shared(rng));
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Borrow the RNG previously bound via `set_rng` or `set_shared_rng`.
|
||||
#[cfg(random)]
|
||||
pub fn rng(&self) -> Option<&RNG> {
|
||||
match &self.rng {
|
||||
Some(RngHandle::Owned(rng)) => Some(rng),
|
||||
#[cfg(feature = "alloc")]
|
||||
Some(RngHandle::Shared(rng)) => Some(rng),
|
||||
None => None,
|
||||
}
|
||||
}
|
||||
|
||||
/// Compute a shared secret key given a secret private key and a received
|
||||
/// public key. It stores the generated secret key in the buffer out and
|
||||
/// returns the generated key size. Supports big or little endian.
|
||||
|
||||
@@ -194,7 +194,7 @@ impl DH {
|
||||
/// }
|
||||
/// ```
|
||||
#[cfg(all(dh_keygen, random))]
|
||||
pub fn generate(rng: &mut RNG, modulus_size: i32) -> Result<Self, i32> {
|
||||
pub fn generate(rng: &RNG, modulus_size: i32) -> Result<Self, i32> {
|
||||
Self::generate_ex(rng, modulus_size, None, None)
|
||||
}
|
||||
|
||||
@@ -225,7 +225,7 @@ impl DH {
|
||||
/// }
|
||||
/// ```
|
||||
#[cfg(all(dh_keygen, random))]
|
||||
pub fn generate_ex(rng: &mut RNG, modulus_size: i32, heap: Option<*mut core::ffi::c_void>, dev_id: Option<i32>) -> Result<Self, i32> {
|
||||
pub fn generate_ex(rng: &RNG, modulus_size: i32, heap: Option<*mut core::ffi::c_void>, dev_id: Option<i32>) -> Result<Self, i32> {
|
||||
let mut wc_dhkey: MaybeUninit<sys::DhKey> = MaybeUninit::uninit();
|
||||
let heap = match heap {
|
||||
Some(heap) => heap,
|
||||
@@ -242,7 +242,7 @@ impl DH {
|
||||
let wc_dhkey = unsafe { wc_dhkey.assume_init() };
|
||||
let mut dh = DH { wc_dhkey };
|
||||
let rc = unsafe {
|
||||
sys::wc_DhGenerateParams(&mut rng.wc_rng, modulus_size, &mut dh.wc_dhkey)
|
||||
sys::wc_DhGenerateParams(rng.wc_rng, modulus_size, &mut dh.wc_dhkey)
|
||||
};
|
||||
if rc != 0 {
|
||||
return Err(rc);
|
||||
@@ -921,7 +921,7 @@ impl DH {
|
||||
/// }
|
||||
/// ```
|
||||
#[cfg(random)]
|
||||
pub fn new_from_pgq_with_check(p: &[u8], g: &[u8], q: &[u8], trusted: i32, rng: &mut RNG) -> Result<Self, i32> {
|
||||
pub fn new_from_pgq_with_check(p: &[u8], g: &[u8], q: &[u8], trusted: i32, rng: &RNG) -> Result<Self, i32> {
|
||||
Self::new_from_pgq_with_check_ex(p, g, q, trusted, rng, None, None)
|
||||
}
|
||||
|
||||
@@ -1030,7 +1030,7 @@ impl DH {
|
||||
/// }
|
||||
/// ```
|
||||
#[cfg(random)]
|
||||
pub fn new_from_pgq_with_check_ex(p: &[u8], g: &[u8], q: &[u8], trusted: i32, rng: &mut RNG, heap: Option<*mut core::ffi::c_void>, dev_id: Option<i32>) -> Result<Self, i32> {
|
||||
pub fn new_from_pgq_with_check_ex(p: &[u8], g: &[u8], q: &[u8], trusted: i32, rng: &RNG, heap: Option<*mut core::ffi::c_void>, dev_id: Option<i32>) -> Result<Self, i32> {
|
||||
let p_size = crate::buffer_len_to_u32(p.len())?;
|
||||
let g_size = crate::buffer_len_to_u32(g.len())?;
|
||||
let q_size = crate::buffer_len_to_u32(q.len())?;
|
||||
@@ -1050,7 +1050,7 @@ impl DH {
|
||||
let wc_dhkey = unsafe { wc_dhkey.assume_init() };
|
||||
let mut dh = DH { wc_dhkey };
|
||||
let rc = unsafe {
|
||||
sys::wc_DhSetCheckKey(&mut dh.wc_dhkey, p.as_ptr(), p_size, g.as_ptr(), g_size, q.as_ptr(), q_size, trusted, &mut rng.wc_rng)
|
||||
sys::wc_DhSetCheckKey(&mut dh.wc_dhkey, p.as_ptr(), p_size, g.as_ptr(), g_size, q.as_ptr(), q_size, trusted, rng.wc_rng)
|
||||
};
|
||||
if rc != 0 {
|
||||
return Err(rc);
|
||||
@@ -1509,13 +1509,13 @@ impl DH {
|
||||
/// }
|
||||
/// ```
|
||||
#[cfg(random)]
|
||||
pub fn generate_key_pair(&mut self, rng: &mut RNG,
|
||||
pub fn generate_key_pair(&mut self, rng: &RNG,
|
||||
private: &mut [u8], private_size: &mut u32,
|
||||
public: &mut [u8], public_size: &mut u32) -> Result<(), i32> {
|
||||
*private_size = crate::buffer_len_to_u32(private.len())?;
|
||||
*public_size = crate::buffer_len_to_u32(public.len())?;
|
||||
let rc = unsafe {
|
||||
sys::wc_DhGenerateKeyPair(&mut self.wc_dhkey, &mut rng.wc_rng,
|
||||
sys::wc_DhGenerateKeyPair(&mut self.wc_dhkey, rng.wc_rng,
|
||||
private.as_mut_ptr(), private_size,
|
||||
public.as_mut_ptr(), public_size)
|
||||
};
|
||||
|
||||
@@ -159,7 +159,7 @@ impl Dilithium {
|
||||
/// }
|
||||
/// ```
|
||||
#[cfg(all(dilithium_make_key, random))]
|
||||
pub fn generate(level: u8, rng: &mut RNG) -> Result<Self, i32> {
|
||||
pub fn generate(level: u8, rng: &RNG) -> Result<Self, i32> {
|
||||
Self::generate_ex(level, rng, None, None)
|
||||
}
|
||||
|
||||
@@ -193,7 +193,7 @@ impl Dilithium {
|
||||
#[cfg(all(dilithium_make_key, random))]
|
||||
pub fn generate_ex(
|
||||
level: u8,
|
||||
rng: &mut RNG,
|
||||
rng: &RNG,
|
||||
heap: Option<*mut core::ffi::c_void>,
|
||||
dev_id: Option<i32>,
|
||||
) -> Result<Self, i32> {
|
||||
@@ -202,7 +202,7 @@ impl Dilithium {
|
||||
if rc != 0 {
|
||||
return Err(rc);
|
||||
}
|
||||
let rc = unsafe { sys::wc_dilithium_make_key(&mut key.ws_key, &mut rng.wc_rng) };
|
||||
let rc = unsafe { sys::wc_dilithium_make_key(&mut key.ws_key, rng.wc_rng) };
|
||||
if rc != 0 {
|
||||
return Err(rc);
|
||||
}
|
||||
@@ -859,7 +859,7 @@ impl Dilithium {
|
||||
&mut self,
|
||||
msg: &[u8],
|
||||
sig: &mut [u8],
|
||||
rng: &mut RNG,
|
||||
rng: &RNG,
|
||||
) -> Result<usize, i32> {
|
||||
let msg_len = crate::buffer_len_to_u32(msg.len())?;
|
||||
let mut sig_len = crate::buffer_len_to_u32(sig.len())?;
|
||||
@@ -869,7 +869,7 @@ impl Dilithium {
|
||||
msg.as_ptr(), msg_len,
|
||||
sig.as_mut_ptr(), &mut sig_len,
|
||||
&mut self.ws_key,
|
||||
&mut rng.wc_rng,
|
||||
rng.wc_rng,
|
||||
)
|
||||
};
|
||||
if rc != 0 {
|
||||
@@ -917,7 +917,7 @@ impl Dilithium {
|
||||
ctx: &[u8],
|
||||
msg: &[u8],
|
||||
sig: &mut [u8],
|
||||
rng: &mut RNG,
|
||||
rng: &RNG,
|
||||
) -> Result<usize, i32> {
|
||||
if ctx.len() > 255 {
|
||||
return Err(sys::wolfCrypt_ErrorCodes_BUFFER_E);
|
||||
@@ -931,7 +931,7 @@ impl Dilithium {
|
||||
msg.as_ptr(), msg_len,
|
||||
sig.as_mut_ptr(), &mut sig_len,
|
||||
&mut self.ws_key,
|
||||
&mut rng.wc_rng,
|
||||
rng.wc_rng,
|
||||
)
|
||||
};
|
||||
if rc != 0 {
|
||||
@@ -966,7 +966,7 @@ impl Dilithium {
|
||||
hash_alg: i32,
|
||||
hash: &[u8],
|
||||
sig: &mut [u8],
|
||||
rng: &mut RNG,
|
||||
rng: &RNG,
|
||||
) -> Result<usize, i32> {
|
||||
if ctx.len() > 255 {
|
||||
return Err(sys::wolfCrypt_ErrorCodes_BUFFER_E);
|
||||
@@ -981,7 +981,7 @@ impl Dilithium {
|
||||
hash.as_ptr(), hash_len,
|
||||
sig.as_mut_ptr(), &mut sig_len,
|
||||
&mut self.ws_key,
|
||||
&mut rng.wc_rng,
|
||||
rng.wc_rng,
|
||||
)
|
||||
};
|
||||
if rc != 0 {
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -252,9 +252,9 @@ macro_rules! define_ecdsa_curve {
|
||||
sys::wc_SignatureType_WC_SIGNATURE_TYPE_ECC,
|
||||
msg.as_ptr(), msg_len,
|
||||
der.as_mut_ptr(), &mut der_len,
|
||||
&mut self.inner.wc_ecc_key as *mut _ as *mut c_void,
|
||||
self.inner.wc_ecc_key as *mut c_void,
|
||||
size_of::<sys::ecc_key>() as u32,
|
||||
&mut self.rng.wc_rng,
|
||||
self.rng.wc_rng,
|
||||
)
|
||||
};
|
||||
if rc != 0 {
|
||||
@@ -313,7 +313,7 @@ macro_rules! define_ecdsa_curve {
|
||||
fn verify(&self, msg: &[u8], sig: &$signature) -> Result<(), Error> {
|
||||
let mut der = [0u8; $der_max];
|
||||
let der_len = rs_to_der::<$field_size>(&sig.0, &mut der)?;
|
||||
let mut key = ECC::import_x963_ex(&self.pub_bytes, $curve_id, None, None)
|
||||
let key = ECC::import_x963_ex(&self.pub_bytes, $curve_id, None, None)
|
||||
.map_err(|_| Error::new())?;
|
||||
let msg_len: u32 = msg.len().try_into().map_err(|_| Error::new())?;
|
||||
let rc = unsafe {
|
||||
@@ -322,7 +322,7 @@ macro_rules! define_ecdsa_curve {
|
||||
sys::wc_SignatureType_WC_SIGNATURE_TYPE_ECC,
|
||||
msg.as_ptr(), msg_len,
|
||||
der.as_ptr(), der_len as u32,
|
||||
&mut key.wc_ecc_key as *mut _ as *mut c_void,
|
||||
key.wc_ecc_key as *mut c_void,
|
||||
size_of::<sys::ecc_key>() as u32,
|
||||
)
|
||||
};
|
||||
|
||||
@@ -72,7 +72,7 @@ impl Ed25519 {
|
||||
/// let mut rng = RNG::new().expect("Error creating RNG");
|
||||
/// let ed = Ed25519::generate(&mut rng).expect("Error with generate()");
|
||||
/// ```
|
||||
pub fn generate(rng: &mut RNG) -> Result<Self, i32> {
|
||||
pub fn generate(rng: &RNG) -> Result<Self, i32> {
|
||||
Self::generate_ex(rng, None, None)
|
||||
}
|
||||
|
||||
@@ -97,7 +97,7 @@ impl Ed25519 {
|
||||
/// let mut rng = RNG::new().expect("Error creating RNG");
|
||||
/// let ed = Ed25519::generate_ex(&mut rng, None, None).expect("Error with generate_ex()");
|
||||
/// ```
|
||||
pub fn generate_ex(rng: &mut RNG, heap: Option<*mut core::ffi::c_void>, dev_id: Option<i32>) -> Result<Self, i32> {
|
||||
pub fn generate_ex(rng: &RNG, heap: Option<*mut core::ffi::c_void>, dev_id: Option<i32>) -> Result<Self, i32> {
|
||||
let mut ws_key: MaybeUninit<sys::ed25519_key> = MaybeUninit::uninit();
|
||||
let heap = match heap {
|
||||
Some(heap) => heap,
|
||||
@@ -114,7 +114,7 @@ impl Ed25519 {
|
||||
let ws_key = unsafe { ws_key.assume_init() };
|
||||
let mut ed25519 = Ed25519 { ws_key };
|
||||
let rc = unsafe {
|
||||
sys::wc_ed25519_make_key(&mut rng.wc_rng,
|
||||
sys::wc_ed25519_make_key(rng.wc_rng,
|
||||
sys::ED25519_KEY_SIZE as i32, &mut ed25519.ws_key)
|
||||
};
|
||||
if rc != 0 {
|
||||
|
||||
@@ -71,7 +71,7 @@ impl Ed448 {
|
||||
/// let mut rng = RNG::new().expect("Error creating RNG");
|
||||
/// let ed = Ed448::generate(&mut rng).expect("Error with generate()");
|
||||
/// ```
|
||||
pub fn generate(rng: &mut RNG) -> Result<Self, i32> {
|
||||
pub fn generate(rng: &RNG) -> Result<Self, i32> {
|
||||
Self::generate_ex(rng, None, None)
|
||||
}
|
||||
|
||||
@@ -96,7 +96,7 @@ impl Ed448 {
|
||||
/// let mut rng = RNG::new().expect("Error creating RNG");
|
||||
/// let ed = Ed448::generate_ex(&mut rng, None, None).expect("Error with generate_ex()");
|
||||
/// ```
|
||||
pub fn generate_ex(rng: &mut RNG, heap: Option<*mut core::ffi::c_void>, dev_id: Option<i32>) -> Result<Self, i32> {
|
||||
pub fn generate_ex(rng: &RNG, heap: Option<*mut core::ffi::c_void>, dev_id: Option<i32>) -> Result<Self, i32> {
|
||||
let mut ws_key: MaybeUninit<sys::ed448_key> = MaybeUninit::uninit();
|
||||
let heap = match heap {
|
||||
Some(heap) => heap,
|
||||
@@ -113,7 +113,7 @@ impl Ed448 {
|
||||
let ws_key = unsafe { ws_key.assume_init() };
|
||||
let mut ed448 = Ed448 { ws_key };
|
||||
let rc = unsafe {
|
||||
sys::wc_ed448_make_key(&mut rng.wc_rng,
|
||||
sys::wc_ed448_make_key(rng.wc_rng,
|
||||
sys::ED448_KEY_SIZE as i32, &mut ed448.ws_key)
|
||||
};
|
||||
if rc != 0 {
|
||||
|
||||
@@ -330,6 +330,24 @@ impl HMAC {
|
||||
}
|
||||
}
|
||||
|
||||
impl Clone for HMAC {
|
||||
/// Deep-copy the HMAC state via `wc_HmacCopy()`.
|
||||
///
|
||||
/// Panics if the underlying wolfSSL copy fails.
|
||||
fn clone(&self) -> Self {
|
||||
let mut wc_hmac: MaybeUninit<sys::Hmac> = MaybeUninit::uninit();
|
||||
let rc = unsafe {
|
||||
sys::wc_HmacCopy(&self.wc_hmac as *const _ as *mut _,
|
||||
wc_hmac.as_mut_ptr())
|
||||
};
|
||||
if rc != 0 {
|
||||
panic!("wc_HmacCopy() failed: {}", rc);
|
||||
}
|
||||
let wc_hmac = unsafe { wc_hmac.assume_init() };
|
||||
HMAC { wc_hmac }
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for HMAC {
|
||||
/// Safely free the underlying wolfSSL Hmac context.
|
||||
///
|
||||
|
||||
@@ -42,6 +42,7 @@ macro_rules! impl_hmac_mac {
|
||||
$name:ident, hmac_type = $hmac_type:expr, key = $key_size:ty, out = $out_size:ty
|
||||
) => {
|
||||
$(#[$attr])*
|
||||
#[derive(Clone)]
|
||||
pub struct $name {
|
||||
hmac: crate::hmac::HMAC,
|
||||
}
|
||||
|
||||
@@ -20,6 +20,9 @@
|
||||
|
||||
#![no_std]
|
||||
|
||||
#[cfg(feature = "alloc")]
|
||||
extern crate alloc;
|
||||
|
||||
/* bindgen-generated bindings to the C library */
|
||||
pub mod sys;
|
||||
|
||||
@@ -42,6 +45,10 @@ pub(crate) unsafe fn zeroize_raw<T>(val: &mut T) {
|
||||
|
||||
pub mod aes;
|
||||
pub mod blake2;
|
||||
#[cfg(all(any(blake2b, blake2s), feature = "digest"))]
|
||||
pub mod blake2_digest;
|
||||
#[cfg(all(any(blake2b, blake2s), feature = "mac"))]
|
||||
pub mod blake2_mac;
|
||||
pub mod chacha20_poly1305;
|
||||
pub mod cmac;
|
||||
#[cfg(all(cmac, feature = "mac"))]
|
||||
|
||||
@@ -442,8 +442,8 @@ impl Lms {
|
||||
/// }
|
||||
/// ```
|
||||
#[cfg(all(lms_make_key, random))]
|
||||
pub fn make_key(&mut self, rng: &mut RNG) -> Result<(), i32> {
|
||||
let rc = unsafe { sys::wc_LmsKey_MakeKey(&mut self.ws_key, &mut rng.wc_rng) };
|
||||
pub fn make_key(&mut self, rng: &RNG) -> Result<(), i32> {
|
||||
let rc = unsafe { sys::wc_LmsKey_MakeKey(&mut self.ws_key, rng.wc_rng) };
|
||||
if rc != 0 {
|
||||
return Err(rc);
|
||||
}
|
||||
|
||||
@@ -123,7 +123,7 @@ impl MlKem {
|
||||
/// }
|
||||
/// ```
|
||||
#[cfg(random)]
|
||||
pub fn generate(key_type: i32, rng: &mut RNG) -> Result<Self, i32> {
|
||||
pub fn generate(key_type: i32, rng: &RNG) -> Result<Self, i32> {
|
||||
Self::generate_ex(key_type, rng, None, None)
|
||||
}
|
||||
|
||||
@@ -157,12 +157,12 @@ impl MlKem {
|
||||
#[cfg(random)]
|
||||
pub fn generate_ex(
|
||||
key_type: i32,
|
||||
rng: &mut RNG,
|
||||
rng: &RNG,
|
||||
heap: Option<*mut core::ffi::c_void>,
|
||||
dev_id: Option<i32>,
|
||||
) -> Result<Self, i32> {
|
||||
let key = Self::new_ex(key_type, heap, dev_id)?;
|
||||
let rc = unsafe { sys::wc_MlKemKey_MakeKey(key.ws_key, &mut rng.wc_rng) };
|
||||
let rc = unsafe { sys::wc_MlKemKey_MakeKey(key.ws_key, rng.wc_rng) };
|
||||
if rc != 0 {
|
||||
return Err(rc);
|
||||
}
|
||||
@@ -472,7 +472,7 @@ impl MlKem {
|
||||
&mut self,
|
||||
ct: &mut [u8],
|
||||
ss: &mut [u8],
|
||||
rng: &mut RNG,
|
||||
rng: &RNG,
|
||||
) -> Result<(), i32> {
|
||||
// Verify the cipher text length is as expected based on the parameter
|
||||
// set (key type) in use.
|
||||
@@ -489,7 +489,7 @@ impl MlKem {
|
||||
self.ws_key,
|
||||
ct.as_mut_ptr(),
|
||||
ss.as_mut_ptr(),
|
||||
&mut rng.wc_rng,
|
||||
rng.wc_rng,
|
||||
)
|
||||
};
|
||||
if rc != 0 {
|
||||
|
||||
@@ -31,7 +31,7 @@ wolfSSL `WC_RNG` object. It ensures proper initialization and deallocation.
|
||||
use wolfssl_wolfcrypt::random::RNG;
|
||||
|
||||
// Create a RNG instance.
|
||||
let mut rng = RNG::new().expect("Failed to create RNG");
|
||||
let rng = RNG::new().expect("Failed to create RNG");
|
||||
|
||||
// Generate a single random byte value.
|
||||
let byte = rng.generate_byte().expect("Failed to generate a single byte");
|
||||
@@ -45,18 +45,42 @@ rng.generate_block(&mut buffer).expect("Failed to generate a block");
|
||||
#![cfg(random)]
|
||||
|
||||
use crate::sys;
|
||||
use core::mem::{size_of_val, MaybeUninit};
|
||||
use core::mem::size_of_val;
|
||||
use num_traits::PrimInt;
|
||||
|
||||
/// A cryptographically secure random number generator based on the wolfSSL
|
||||
/// library.
|
||||
///
|
||||
/// This struct wraps the wolfssl `WC_RNG` type, providing a high-level API
|
||||
/// for generating random bytes and blocks of data. The `Drop` implementation
|
||||
/// ensures that the underlying wolfSSL RNG context is correctly freed when the
|
||||
/// `RNG` struct goes out of scope, preventing memory leaks.
|
||||
/// This struct wraps a pointer to a wolfssl `WC_RNG` allocated on the C heap,
|
||||
/// providing a high-level API for generating random bytes and blocks of data.
|
||||
/// The `Drop` implementation ensures that the underlying wolfSSL RNG context is
|
||||
/// correctly freed when the `RNG` struct goes out of scope, preventing memory
|
||||
/// leaks.
|
||||
///
|
||||
/// All generation methods take `&self`. The actual mutation of the DRBG state
|
||||
/// happens through the raw pointer in the C library; the `RNG` struct itself
|
||||
/// is logically immutable after construction.
|
||||
pub struct RNG {
|
||||
pub(crate) wc_rng: sys::WC_RNG,
|
||||
pub(crate) wc_rng: *mut sys::WC_RNG,
|
||||
}
|
||||
|
||||
// Safety: the only field of `RNG` is a non-null pointer to a `WC_RNG` that
|
||||
// lives on the C heap and is never reassigned after construction. Moving the
|
||||
// struct between threads is sound.
|
||||
unsafe impl Send for RNG {}
|
||||
|
||||
// Note: `RNG` is intentionally not `Sync`. The underlying C `WC_RNG` state is
|
||||
// mutated by every call to a generation routine, with no internal locking.
|
||||
// Callers that need cross-thread sharing of a single RNG struct must implement
|
||||
// their own locking.
|
||||
|
||||
/// Storage for an RNG that a consumer (e.g. `RSA`, `ECC`) has been bound to
|
||||
/// via `set_rng`. The consumer keeps the `RngHandle` alive for as long as the
|
||||
/// C struct holds its pointer, ensuring the `WC_RNG` outlives the consumer.
|
||||
pub(crate) enum RngHandle {
|
||||
Owned(RNG),
|
||||
#[cfg(feature = "alloc")]
|
||||
Shared(alloc::rc::Rc<RNG>),
|
||||
}
|
||||
|
||||
impl RNG {
|
||||
@@ -97,7 +121,7 @@ impl RNG {
|
||||
return Err(rc);
|
||||
}
|
||||
}
|
||||
let mut wc_rng: MaybeUninit<sys::WC_RNG> = MaybeUninit::uninit();
|
||||
let mut wc_rng: *mut sys::WC_RNG = core::ptr::null_mut();
|
||||
let heap = match heap {
|
||||
Some(heap) => heap,
|
||||
None => core::ptr::null_mut(),
|
||||
@@ -107,12 +131,10 @@ impl RNG {
|
||||
None => sys::INVALID_DEVID,
|
||||
};
|
||||
let rc = unsafe {
|
||||
sys::wc_InitRng_ex(wc_rng.as_mut_ptr(), heap, dev_id)
|
||||
sys::wc_rng_new_ex(&mut wc_rng, core::ptr::null_mut(), 0, heap, dev_id)
|
||||
};
|
||||
if rc == 0 {
|
||||
let wc_rng = unsafe { wc_rng.assume_init() };
|
||||
let rng = RNG {wc_rng};
|
||||
Ok(rng)
|
||||
Ok(RNG {wc_rng})
|
||||
} else {
|
||||
Err(rc)
|
||||
}
|
||||
@@ -159,7 +181,7 @@ impl RNG {
|
||||
}
|
||||
let ptr = nonce.as_mut_ptr() as *mut u8;
|
||||
let size = crate::buffer_len_to_u32(size_of_val(nonce))?;
|
||||
let mut wc_rng: MaybeUninit<sys::WC_RNG> = MaybeUninit::uninit();
|
||||
let mut wc_rng: *mut sys::WC_RNG = core::ptr::null_mut();
|
||||
let heap = match heap {
|
||||
Some(heap) => heap,
|
||||
None => core::ptr::null_mut(),
|
||||
@@ -169,12 +191,10 @@ impl RNG {
|
||||
None => sys::INVALID_DEVID,
|
||||
};
|
||||
let rc = unsafe {
|
||||
sys::wc_InitRngNonce_ex(wc_rng.as_mut_ptr(), ptr, size, heap, dev_id)
|
||||
sys::wc_rng_new_ex(&mut wc_rng, ptr, size, heap, dev_id)
|
||||
};
|
||||
if rc == 0 {
|
||||
let wc_rng = unsafe { wc_rng.assume_init() };
|
||||
let rng = RNG {wc_rng};
|
||||
Ok(rng)
|
||||
Ok(RNG {wc_rng})
|
||||
} else {
|
||||
Err(rc)
|
||||
}
|
||||
@@ -315,9 +335,9 @@ impl RNG {
|
||||
///
|
||||
/// A `Result` which is `Ok(u8)` containing the random byte on success or
|
||||
/// an `Err` with the wolfssl library return code on failure.
|
||||
pub fn generate_byte(&mut self) -> Result<u8, i32> {
|
||||
pub fn generate_byte(&self) -> Result<u8, i32> {
|
||||
let mut b: u8 = 0;
|
||||
let rc = unsafe { sys::wc_RNG_GenerateByte(&mut self.wc_rng, &mut b) };
|
||||
let rc = unsafe { sys::wc_RNG_GenerateByte(self.wc_rng, &mut b) };
|
||||
if rc == 0 {
|
||||
Ok(b)
|
||||
} else {
|
||||
@@ -339,10 +359,10 @@ impl RNG {
|
||||
///
|
||||
/// A `Result` which is `Ok(())` on success or an `Err` with the wolfssl
|
||||
/// library return code on failure.
|
||||
pub fn generate_block<T: PrimInt>(&mut self, buf: &mut [T]) -> Result<(), i32> {
|
||||
pub fn generate_block<T: PrimInt>(&self, buf: &mut [T]) -> Result<(), i32> {
|
||||
let ptr = buf.as_mut_ptr() as *mut u8;
|
||||
let size = crate::buffer_len_to_u32(size_of_val(buf))?;
|
||||
let rc = unsafe { sys::wc_RNG_GenerateBlock(&mut self.wc_rng, ptr, size) };
|
||||
let rc = unsafe { sys::wc_RNG_GenerateBlock(self.wc_rng, ptr, size) };
|
||||
if rc == 0 {
|
||||
Ok(())
|
||||
} else {
|
||||
@@ -371,10 +391,10 @@ impl RNG {
|
||||
/// rng.reseed(&seed).expect("Error with reseed()");
|
||||
/// ```
|
||||
#[cfg(random_hashdrbg)]
|
||||
pub fn reseed(&mut self, seed: &[u8]) -> Result<(), i32> {
|
||||
pub fn reseed(&self, seed: &[u8]) -> Result<(), i32> {
|
||||
let seed_size = crate::buffer_len_to_u32(seed.len())?;
|
||||
let rc = unsafe {
|
||||
sys::wc_RNG_DRBG_Reseed(&mut self.wc_rng, seed.as_ptr(), seed_size)
|
||||
sys::wc_RNG_DRBG_Reseed(self.wc_rng, seed.as_ptr(), seed_size)
|
||||
};
|
||||
if rc != 0 {
|
||||
return Err(rc);
|
||||
@@ -411,22 +431,16 @@ impl rand_core::TryRng for RNG {
|
||||
#[cfg(feature = "rand_core")]
|
||||
impl rand_core::TryCryptoRng for RNG {}
|
||||
|
||||
impl RNG {
|
||||
fn zeroize(&mut self) {
|
||||
unsafe { crate::zeroize_raw(&mut self.wc_rng); }
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for RNG {
|
||||
/// Safely free the underlying wolfSSL RNG context.
|
||||
///
|
||||
/// This calls the `wc_FreeRng` wolfssl library function.
|
||||
/// This calls the `wc_rng_free` wolfssl library function, which frees the
|
||||
/// C-heap-allocated `WC_RNG` object.
|
||||
///
|
||||
/// The Rust Drop trait guarantees that this method is called when the RNG
|
||||
/// struct goes out of scope, automatically cleaning up resources and
|
||||
/// preventing memory leaks.
|
||||
fn drop(&mut self) {
|
||||
unsafe { sys::wc_FreeRng(&mut self.wc_rng); }
|
||||
self.zeroize();
|
||||
unsafe { sys::wc_rng_free(self.wc_rng); }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,26 +29,26 @@ wolfSSL `RsaKey` object. It ensures proper initialization and deallocation.
|
||||
|
||||
```rust
|
||||
# extern crate std;
|
||||
#[cfg(random)]
|
||||
#[cfg(all(random, feature = "alloc"))]
|
||||
{
|
||||
use std::fs;
|
||||
use wolfssl_wolfcrypt::random::RNG;
|
||||
use wolfssl_wolfcrypt::rsa::RSA;
|
||||
|
||||
let mut rng = RNG::new().expect("Error creating RNG");
|
||||
let rng = std::rc::Rc::new(RNG::new().expect("Error creating RNG"));
|
||||
let key_path = "../../../certs/client-keyPub.der";
|
||||
let der: Vec<u8> = fs::read(key_path).expect("Error reading key file");
|
||||
let mut rsa = RSA::new_public_from_der(&der).expect("Error with new_public_from_der()");
|
||||
rsa.set_rng(&mut rng).expect("Error with set_rng()");
|
||||
rsa.set_shared_rng(std::rc::Rc::clone(&rng)).expect("Error with set_shared_rng()");
|
||||
let plain: &[u8] = b"Test message";
|
||||
let mut enc: [u8; 512] = [0; 512];
|
||||
let enc_len = rsa.public_encrypt(plain, &mut enc, &mut rng).expect("Error with public_encrypt()");
|
||||
let enc_len = rsa.public_encrypt(plain, &mut enc, &rng).expect("Error with public_encrypt()");
|
||||
assert!(enc_len > 0 && enc_len <= 512);
|
||||
|
||||
let key_path = "../../../certs/client-key.der";
|
||||
let der: Vec<u8> = fs::read(key_path).expect("Error reading key file");
|
||||
let mut rsa = RSA::new_from_der(&der).expect("Error with new_from_der()");
|
||||
rsa.set_rng(&mut rng).expect("Error with set_rng()");
|
||||
rsa.set_shared_rng(std::rc::Rc::clone(&rng)).expect("Error with set_shared_rng()");
|
||||
let mut plain_out: [u8; 512] = [0; 512];
|
||||
let dec_len = rsa.private_decrypt(&enc[0..enc_len], &mut plain_out).expect("Error with private_decrypt()");
|
||||
assert!(dec_len as usize == plain.len());
|
||||
@@ -61,7 +61,7 @@ assert_eq!(plain_out[0..dec_len], *plain);
|
||||
|
||||
use crate::sys;
|
||||
#[cfg(random)]
|
||||
use crate::random::RNG;
|
||||
use crate::random::{RNG, RngHandle};
|
||||
use core::mem::{MaybeUninit};
|
||||
|
||||
/// The `RSA` struct manages the lifecycle of a wolfSSL `RsaKey` object.
|
||||
@@ -72,6 +72,10 @@ use core::mem::{MaybeUninit};
|
||||
/// or `generate()`.
|
||||
pub struct RSA {
|
||||
pub(crate) wc_rsakey: sys::RsaKey,
|
||||
/// RNG bound to this key via `set_rng`. Kept alive here so the C struct's
|
||||
/// internal `WC_RNG` pointer remains valid for as long as the key exists.
|
||||
#[cfg(random)]
|
||||
rng: Option<RngHandle>,
|
||||
}
|
||||
|
||||
impl RSA {
|
||||
@@ -143,26 +147,26 @@ impl RSA {
|
||||
///
|
||||
/// ```rust
|
||||
/// # extern crate std;
|
||||
/// #[cfg(random)]
|
||||
/// #[cfg(all(random, feature = "alloc"))]
|
||||
/// {
|
||||
/// use std::fs;
|
||||
/// use wolfssl_wolfcrypt::random::RNG;
|
||||
/// use wolfssl_wolfcrypt::rsa::RSA;
|
||||
///
|
||||
/// let mut rng = RNG::new().expect("Error creating RNG");
|
||||
/// let rng = std::rc::Rc::new(RNG::new().expect("Error creating RNG"));
|
||||
/// let key_path = "../../../certs/client-keyPub.der";
|
||||
/// let der: Vec<u8> = fs::read(key_path).expect("Error reading key file");
|
||||
/// let mut rsa = RSA::new_public_from_der(&der).expect("Error with new_public_from_der()");
|
||||
/// rsa.set_rng(&mut rng).expect("Error with set_rng()");
|
||||
/// rsa.set_shared_rng(std::rc::Rc::clone(&rng)).expect("Error with set_shared_rng()");
|
||||
/// let plain: &[u8] = b"Test message";
|
||||
/// let mut enc: [u8; 512] = [0; 512];
|
||||
/// let enc_len = rsa.public_encrypt(plain, &mut enc, &mut rng).expect("Error with public_encrypt()");
|
||||
/// let enc_len = rsa.public_encrypt(plain, &mut enc, &rng).expect("Error with public_encrypt()");
|
||||
/// assert!(enc_len > 0 && enc_len <= 512);
|
||||
///
|
||||
/// let key_path = "../../../certs/client-key.der";
|
||||
/// let der: Vec<u8> = fs::read(key_path).expect("Error reading key file");
|
||||
/// let mut rsa = RSA::new_from_der(&der).expect("Error with new_from_der()");
|
||||
/// rsa.set_rng(&mut rng).expect("Error with set_rng()");
|
||||
/// rsa.set_shared_rng(std::rc::Rc::clone(&rng)).expect("Error with set_shared_rng()");
|
||||
/// let mut plain_out: [u8; 512] = [0; 512];
|
||||
/// let dec_len = rsa.private_decrypt(&enc[0..enc_len], &mut plain_out).expect("Error with private_decrypt()");
|
||||
/// assert!(dec_len as usize == plain.len());
|
||||
@@ -191,26 +195,26 @@ impl RSA {
|
||||
///
|
||||
/// ```rust
|
||||
/// # extern crate std;
|
||||
/// #[cfg(random)]
|
||||
/// #[cfg(all(random, feature = "alloc"))]
|
||||
/// {
|
||||
/// use std::fs;
|
||||
/// use wolfssl_wolfcrypt::random::RNG;
|
||||
/// use wolfssl_wolfcrypt::rsa::RSA;
|
||||
///
|
||||
/// let mut rng = RNG::new().expect("Error creating RNG");
|
||||
/// let rng = std::rc::Rc::new(RNG::new().expect("Error creating RNG"));
|
||||
/// let key_path = "../../../certs/client-keyPub.der";
|
||||
/// let der: Vec<u8> = fs::read(key_path).expect("Error reading key file");
|
||||
/// let mut rsa = RSA::new_public_from_der(&der).expect("Error with new_public_from_der()");
|
||||
/// rsa.set_rng(&mut rng).expect("Error with set_rng()");
|
||||
/// rsa.set_shared_rng(std::rc::Rc::clone(&rng)).expect("Error with set_shared_rng()");
|
||||
/// let plain: &[u8] = b"Test message";
|
||||
/// let mut enc: [u8; 512] = [0; 512];
|
||||
/// let enc_len = rsa.public_encrypt(plain, &mut enc, &mut rng).expect("Error with public_encrypt()");
|
||||
/// let enc_len = rsa.public_encrypt(plain, &mut enc, &rng).expect("Error with public_encrypt()");
|
||||
/// assert!(enc_len > 0 && enc_len <= 512);
|
||||
///
|
||||
/// let key_path = "../../../certs/client-key.der";
|
||||
/// let der: Vec<u8> = fs::read(key_path).expect("Error reading key file");
|
||||
/// let mut rsa = RSA::new_from_der_ex(&der, None, None).expect("Error with new_from_der_ex()");
|
||||
/// rsa.set_rng(&mut rng).expect("Error with set_rng()");
|
||||
/// rsa.set_shared_rng(std::rc::Rc::clone(&rng)).expect("Error with set_shared_rng()");
|
||||
/// let mut plain_out: [u8; 512] = [0; 512];
|
||||
/// let dec_len = rsa.private_decrypt(&enc[0..enc_len], &mut plain_out).expect("Error with private_decrypt()");
|
||||
/// assert!(dec_len as usize == plain.len());
|
||||
@@ -241,7 +245,11 @@ impl RSA {
|
||||
unsafe { sys::wc_FreeRsaKey(&mut wc_rsakey); }
|
||||
return Err(rc);
|
||||
}
|
||||
let rsa = RSA { wc_rsakey };
|
||||
let rsa = RSA {
|
||||
wc_rsakey,
|
||||
#[cfg(random)]
|
||||
rng: None,
|
||||
};
|
||||
Ok(rsa)
|
||||
}
|
||||
|
||||
@@ -260,26 +268,26 @@ impl RSA {
|
||||
///
|
||||
/// ```rust
|
||||
/// # extern crate std;
|
||||
/// #[cfg(random)]
|
||||
/// #[cfg(all(random, feature = "alloc"))]
|
||||
/// {
|
||||
/// use std::fs;
|
||||
/// use wolfssl_wolfcrypt::random::RNG;
|
||||
/// use wolfssl_wolfcrypt::rsa::RSA;
|
||||
///
|
||||
/// let mut rng = RNG::new().expect("Error creating RNG");
|
||||
/// let rng = std::rc::Rc::new(RNG::new().expect("Error creating RNG"));
|
||||
/// let key_path = "../../../certs/client-keyPub.der";
|
||||
/// let der: Vec<u8> = fs::read(key_path).expect("Error reading key file");
|
||||
/// let mut rsa = RSA::new_public_from_der(&der).expect("Error with new_public_from_der()");
|
||||
/// rsa.set_rng(&mut rng).expect("Error with set_rng()");
|
||||
/// rsa.set_shared_rng(std::rc::Rc::clone(&rng)).expect("Error with set_shared_rng()");
|
||||
/// let plain: &[u8] = b"Test message";
|
||||
/// let mut enc: [u8; 512] = [0; 512];
|
||||
/// let enc_len = rsa.public_encrypt(plain, &mut enc, &mut rng).expect("Error with public_encrypt()");
|
||||
/// let enc_len = rsa.public_encrypt(plain, &mut enc, &rng).expect("Error with public_encrypt()");
|
||||
/// assert!(enc_len > 0 && enc_len <= 512);
|
||||
///
|
||||
/// let key_path = "../../../certs/client-key.der";
|
||||
/// let der: Vec<u8> = fs::read(key_path).expect("Error reading key file");
|
||||
/// let mut rsa = RSA::new_from_der(&der).expect("Error with new_from_der()");
|
||||
/// rsa.set_rng(&mut rng).expect("Error with set_rng()");
|
||||
/// rsa.set_shared_rng(std::rc::Rc::clone(&rng)).expect("Error with set_shared_rng()");
|
||||
/// let mut plain_out: [u8; 512] = [0; 512];
|
||||
/// let dec_len = rsa.private_decrypt(&enc[0..enc_len], &mut plain_out).expect("Error with private_decrypt()");
|
||||
/// assert!(dec_len as usize == plain.len());
|
||||
@@ -308,26 +316,26 @@ impl RSA {
|
||||
///
|
||||
/// ```rust
|
||||
/// # extern crate std;
|
||||
/// #[cfg(random)]
|
||||
/// #[cfg(all(random, feature = "alloc"))]
|
||||
/// {
|
||||
/// use std::fs;
|
||||
/// use wolfssl_wolfcrypt::random::RNG;
|
||||
/// use wolfssl_wolfcrypt::rsa::RSA;
|
||||
///
|
||||
/// let mut rng = RNG::new().expect("Error creating RNG");
|
||||
/// let rng = std::rc::Rc::new(RNG::new().expect("Error creating RNG"));
|
||||
/// let key_path = "../../../certs/client-keyPub.der";
|
||||
/// let der: Vec<u8> = fs::read(key_path).expect("Error reading key file");
|
||||
/// let mut rsa = RSA::new_public_from_der_ex(&der, None, None).expect("Error with new_public_from_der_ex()");
|
||||
/// rsa.set_rng(&mut rng).expect("Error with set_rng()");
|
||||
/// rsa.set_shared_rng(std::rc::Rc::clone(&rng)).expect("Error with set_shared_rng()");
|
||||
/// let plain: &[u8] = b"Test message";
|
||||
/// let mut enc: [u8; 512] = [0; 512];
|
||||
/// let enc_len = rsa.public_encrypt(plain, &mut enc, &mut rng).expect("Error with public_encrypt()");
|
||||
/// let enc_len = rsa.public_encrypt(plain, &mut enc, &rng).expect("Error with public_encrypt()");
|
||||
/// assert!(enc_len > 0 && enc_len <= 512);
|
||||
///
|
||||
/// let key_path = "../../../certs/client-key.der";
|
||||
/// let der: Vec<u8> = fs::read(key_path).expect("Error reading key file");
|
||||
/// let mut rsa = RSA::new_from_der(&der).expect("Error with new_from_der()");
|
||||
/// rsa.set_rng(&mut rng).expect("Error with set_rng()");
|
||||
/// rsa.set_shared_rng(std::rc::Rc::clone(&rng)).expect("Error with set_shared_rng()");
|
||||
/// let mut plain_out: [u8; 512] = [0; 512];
|
||||
/// let dec_len = rsa.private_decrypt(&enc[0..enc_len], &mut plain_out).expect("Error with private_decrypt()");
|
||||
/// assert!(dec_len as usize == plain.len());
|
||||
@@ -358,7 +366,11 @@ impl RSA {
|
||||
unsafe { sys::wc_FreeRsaKey(&mut wc_rsakey); }
|
||||
return Err(rc);
|
||||
}
|
||||
let rsa = RSA { wc_rsakey };
|
||||
let rsa = RSA {
|
||||
wc_rsakey,
|
||||
#[cfg(random)]
|
||||
rng: None,
|
||||
};
|
||||
Ok(rsa)
|
||||
}
|
||||
|
||||
@@ -411,7 +423,11 @@ impl RSA {
|
||||
unsafe { sys::wc_FreeRsaKey(&mut wc_rsakey); }
|
||||
return Err(rc);
|
||||
}
|
||||
Ok(RSA { wc_rsakey })
|
||||
Ok(RSA {
|
||||
wc_rsakey,
|
||||
#[cfg(random)]
|
||||
rng: None,
|
||||
})
|
||||
}
|
||||
|
||||
/// Generate a new RSA key using the given size and exponent.
|
||||
@@ -446,15 +462,15 @@ impl RSA {
|
||||
/// use wolfssl_wolfcrypt::random::RNG;
|
||||
/// use wolfssl_wolfcrypt::rsa::RSA;
|
||||
///
|
||||
/// let mut rng = RNG::new().expect("Error creating RNG");
|
||||
/// let mut rsa = RSA::generate(2048, 65537, &mut rng).expect("Error with generate()");
|
||||
/// let rng = RNG::new().expect("Error creating RNG");
|
||||
/// let mut rsa = RSA::generate(2048, 65537, &rng).expect("Error with generate()");
|
||||
/// rsa.check().expect("Error with check()");
|
||||
/// let encrypt_size = rsa.get_encrypt_size().expect("Error with get_encrypt_size()");
|
||||
/// assert_eq!(encrypt_size, 256);
|
||||
/// }
|
||||
/// ```
|
||||
#[cfg(all(random, rsa_keygen))]
|
||||
pub fn generate(size: i32, e: i32, rng: &mut RNG) -> Result<Self, i32> {
|
||||
pub fn generate(size: i32, e: i32, rng: &RNG) -> Result<Self, i32> {
|
||||
Self::generate_ex(size, e, rng, None, None)
|
||||
}
|
||||
|
||||
@@ -493,15 +509,15 @@ impl RSA {
|
||||
/// use wolfssl_wolfcrypt::random::RNG;
|
||||
/// use wolfssl_wolfcrypt::rsa::RSA;
|
||||
///
|
||||
/// let mut rng = RNG::new().expect("Error creating RNG");
|
||||
/// let mut rsa = RSA::generate_ex(2048, 65537, &mut rng, None, None).expect("Error with generate_ex()");
|
||||
/// let rng = RNG::new().expect("Error creating RNG");
|
||||
/// let mut rsa = RSA::generate_ex(2048, 65537, &rng, None, None).expect("Error with generate_ex()");
|
||||
/// rsa.check().expect("Error with check()");
|
||||
/// let encrypt_size = rsa.get_encrypt_size().expect("Error with get_encrypt_size()");
|
||||
/// assert_eq!(encrypt_size, 256);
|
||||
/// }
|
||||
/// ```
|
||||
#[cfg(all(random, rsa_keygen))]
|
||||
pub fn generate_ex(size: i32, e: i32, rng: &mut RNG, heap: Option<*mut core::ffi::c_void>, dev_id: Option<i32>) -> Result<Self, i32> {
|
||||
pub fn generate_ex(size: i32, e: i32, rng: &RNG, heap: Option<*mut core::ffi::c_void>, dev_id: Option<i32>) -> Result<Self, i32> {
|
||||
let mut wc_rsakey: MaybeUninit<sys::RsaKey> = MaybeUninit::uninit();
|
||||
let heap = match heap {
|
||||
Some(heap) => heap,
|
||||
@@ -518,13 +534,17 @@ impl RSA {
|
||||
let mut wc_rsakey = unsafe { wc_rsakey.assume_init() };
|
||||
let e = e as core::ffi::c_long;
|
||||
let rc = unsafe {
|
||||
sys::wc_MakeRsaKey(&mut wc_rsakey, size, e, &mut rng.wc_rng)
|
||||
sys::wc_MakeRsaKey(&mut wc_rsakey, size, e, rng.wc_rng)
|
||||
};
|
||||
if rc != 0 {
|
||||
unsafe { sys::wc_FreeRsaKey(&mut wc_rsakey); }
|
||||
return Err(rc);
|
||||
}
|
||||
let rsa = RSA { wc_rsakey };
|
||||
let rsa = RSA {
|
||||
wc_rsakey,
|
||||
#[cfg(random)]
|
||||
rng: None,
|
||||
};
|
||||
Ok(rsa)
|
||||
}
|
||||
|
||||
@@ -556,8 +576,8 @@ impl RSA {
|
||||
/// use wolfssl_wolfcrypt::random::RNG;
|
||||
/// use wolfssl_wolfcrypt::rsa::RSA;
|
||||
///
|
||||
/// let mut rng = RNG::new().expect("Error creating RNG");
|
||||
/// let mut rsa = RSA::generate(2048, 65537, &mut rng).expect("Error with generate()");
|
||||
/// let rng = RNG::new().expect("Error creating RNG");
|
||||
/// let mut rsa = RSA::generate(2048, 65537, &rng).expect("Error with generate()");
|
||||
/// let mut e: [u8; 256] = [0; 256];
|
||||
/// let mut e_size: u32 = 0;
|
||||
/// let mut n: [u8; 256] = [0; 256];
|
||||
@@ -624,8 +644,8 @@ impl RSA {
|
||||
/// use wolfssl_wolfcrypt::random::RNG;
|
||||
/// use wolfssl_wolfcrypt::rsa::RSA;
|
||||
///
|
||||
/// let mut rng = RNG::new().expect("Error creating RNG");
|
||||
/// let mut rsa = RSA::generate(2048, 65537, &mut rng).expect("Error with generate()");
|
||||
/// let rng = RNG::new().expect("Error creating RNG");
|
||||
/// let mut rsa = RSA::generate(2048, 65537, &rng).expect("Error with generate()");
|
||||
/// let mut e: [u8; 256] = [0; 256];
|
||||
/// let mut e_size: u32 = 0;
|
||||
/// let mut n: [u8; 256] = [0; 256];
|
||||
@@ -667,8 +687,8 @@ impl RSA {
|
||||
/// use wolfssl_wolfcrypt::random::RNG;
|
||||
/// use wolfssl_wolfcrypt::rsa::RSA;
|
||||
///
|
||||
/// let mut rng = RNG::new().expect("Error creating RNG");
|
||||
/// let mut rsa = RSA::generate(2048, 65537, &mut rng).expect("Error with generate()");
|
||||
/// let rng = RNG::new().expect("Error creating RNG");
|
||||
/// let mut rsa = RSA::generate(2048, 65537, &rng).expect("Error with generate()");
|
||||
/// let encrypt_size = rsa.get_encrypt_size().expect("Error with get_encrypt_size()");
|
||||
/// assert_eq!(encrypt_size, 256);
|
||||
/// }
|
||||
@@ -696,8 +716,8 @@ impl RSA {
|
||||
/// use wolfssl_wolfcrypt::random::RNG;
|
||||
/// use wolfssl_wolfcrypt::rsa::RSA;
|
||||
///
|
||||
/// let mut rng = RNG::new().expect("Error creating RNG");
|
||||
/// let mut rsa = RSA::generate(2048, 65537, &mut rng).expect("Error with generate()");
|
||||
/// let rng = RNG::new().expect("Error creating RNG");
|
||||
/// let mut rsa = RSA::generate(2048, 65537, &rng).expect("Error with generate()");
|
||||
/// rsa.check().expect("Error with check()");
|
||||
/// }
|
||||
/// ```
|
||||
@@ -729,26 +749,26 @@ impl RSA {
|
||||
///
|
||||
/// ```rust
|
||||
/// # extern crate std;
|
||||
/// #[cfg(random)]
|
||||
/// #[cfg(all(random, feature = "alloc"))]
|
||||
/// {
|
||||
/// use std::fs;
|
||||
/// use wolfssl_wolfcrypt::random::RNG;
|
||||
/// use wolfssl_wolfcrypt::rsa::RSA;
|
||||
///
|
||||
/// let mut rng = RNG::new().expect("Error creating RNG");
|
||||
/// let rng = std::rc::Rc::new(RNG::new().expect("Error creating RNG"));
|
||||
/// let key_path = "../../../certs/client-keyPub.der";
|
||||
/// let der: Vec<u8> = fs::read(key_path).expect("Error reading key file");
|
||||
/// let mut rsa = RSA::new_public_from_der(&der).expect("Error with new_public_from_der()");
|
||||
/// rsa.set_rng(&mut rng).expect("Error with set_rng()");
|
||||
/// rsa.set_shared_rng(std::rc::Rc::clone(&rng)).expect("Error with set_shared_rng()");
|
||||
/// let plain: &[u8] = b"Test message";
|
||||
/// let mut enc: [u8; 512] = [0; 512];
|
||||
/// let enc_len = rsa.public_encrypt(plain, &mut enc, &mut rng).expect("Error with public_encrypt()");
|
||||
/// let enc_len = rsa.public_encrypt(plain, &mut enc, &rng).expect("Error with public_encrypt()");
|
||||
/// assert!(enc_len > 0 && enc_len <= 512);
|
||||
///
|
||||
/// let key_path = "../../../certs/client-key.der";
|
||||
/// let der: Vec<u8> = fs::read(key_path).expect("Error reading key file");
|
||||
/// let mut rsa = RSA::new_from_der(&der).expect("Error with new_from_der()");
|
||||
/// rsa.set_rng(&mut rng).expect("Error with set_rng()");
|
||||
/// rsa.set_shared_rng(std::rc::Rc::clone(&rng)).expect("Error with set_shared_rng()");
|
||||
/// let mut plain_out: [u8; 512] = [0; 512];
|
||||
/// let dec_len = rsa.private_decrypt(&enc[0..enc_len], &mut plain_out).expect("Error with private_decrypt()");
|
||||
/// assert!(dec_len as usize == plain.len());
|
||||
@@ -756,13 +776,13 @@ impl RSA {
|
||||
/// }
|
||||
/// ```
|
||||
#[cfg(random)]
|
||||
pub fn public_encrypt(&mut self, din: &[u8], dout: &mut [u8], rng: &mut RNG) -> Result<usize, i32> {
|
||||
pub fn public_encrypt(&mut self, din: &[u8], dout: &mut [u8], rng: &RNG) -> Result<usize, i32> {
|
||||
let din_size = crate::buffer_len_to_u32(din.len())?;
|
||||
let dout_size = crate::buffer_len_to_u32(dout.len())?;
|
||||
let rc = unsafe {
|
||||
sys::wc_RsaPublicEncrypt(din.as_ptr(), din_size,
|
||||
dout.as_mut_ptr(), dout_size, &mut self.wc_rsakey,
|
||||
&mut rng.wc_rng)
|
||||
rng.wc_rng)
|
||||
};
|
||||
if rc < 0 {
|
||||
return Err(rc);
|
||||
@@ -788,26 +808,26 @@ impl RSA {
|
||||
///
|
||||
/// ```rust
|
||||
/// # extern crate std;
|
||||
/// #[cfg(random)]
|
||||
/// #[cfg(all(random, feature = "alloc"))]
|
||||
/// {
|
||||
/// use std::fs;
|
||||
/// use wolfssl_wolfcrypt::random::RNG;
|
||||
/// use wolfssl_wolfcrypt::rsa::RSA;
|
||||
///
|
||||
/// let mut rng = RNG::new().expect("Error creating RNG");
|
||||
/// let rng = std::rc::Rc::new(RNG::new().expect("Error creating RNG"));
|
||||
/// let key_path = "../../../certs/client-keyPub.der";
|
||||
/// let der: Vec<u8> = fs::read(key_path).expect("Error reading key file");
|
||||
/// let mut rsa = RSA::new_public_from_der(&der).expect("Error with new_public_from_der()");
|
||||
/// rsa.set_rng(&mut rng).expect("Error with set_rng()");
|
||||
/// rsa.set_shared_rng(std::rc::Rc::clone(&rng)).expect("Error with set_shared_rng()");
|
||||
/// let plain: &[u8] = b"Test message";
|
||||
/// let mut enc: [u8; 512] = [0; 512];
|
||||
/// let enc_len = rsa.public_encrypt(plain, &mut enc, &mut rng).expect("Error with public_encrypt()");
|
||||
/// let enc_len = rsa.public_encrypt(plain, &mut enc, &rng).expect("Error with public_encrypt()");
|
||||
/// assert!(enc_len > 0 && enc_len <= 512);
|
||||
///
|
||||
/// let key_path = "../../../certs/client-key.der";
|
||||
/// let der: Vec<u8> = fs::read(key_path).expect("Error reading key file");
|
||||
/// let mut rsa = RSA::new_from_der(&der).expect("Error with new_from_der()");
|
||||
/// rsa.set_rng(&mut rng).expect("Error with set_rng()");
|
||||
/// rsa.set_shared_rng(std::rc::Rc::clone(&rng)).expect("Error with set_shared_rng()");
|
||||
/// let mut plain_out: [u8; 512] = [0; 512];
|
||||
/// let dec_len = rsa.private_decrypt(&enc[0..enc_len], &mut plain_out).expect("Error with private_decrypt()");
|
||||
/// assert!(dec_len as usize == plain.len());
|
||||
@@ -849,26 +869,26 @@ impl RSA {
|
||||
/// # Example
|
||||
///
|
||||
/// ```rust
|
||||
/// #[cfg(all(random, rsa_pss))]
|
||||
/// #[cfg(all(random, rsa_pss, feature = "alloc"))]
|
||||
/// {
|
||||
/// use std::fs;
|
||||
/// use wolfssl_wolfcrypt::random::RNG;
|
||||
/// use wolfssl_wolfcrypt::rsa::RSA;
|
||||
///
|
||||
/// let mut rng = RNG::new().expect("Error creating RNG");
|
||||
/// let rng = std::rc::Rc::new(RNG::new().expect("Error creating RNG"));
|
||||
///
|
||||
/// let key_path = "../../../certs/client-key.der";
|
||||
/// let der: Vec<u8> = fs::read(key_path).expect("Error reading key file");
|
||||
/// let mut rsa = RSA::new_from_der(&der).expect("Error with new_from_der()");
|
||||
/// let msg: &[u8] = b"This is the string to be signed!";
|
||||
/// let mut signature: [u8; 512] = [0; 512];
|
||||
/// let sig_len = rsa.pss_sign(msg, &mut signature, RSA::HASH_TYPE_SHA256, RSA::MGF1SHA256, &mut rng).expect("Error with pss_sign()");
|
||||
/// let sig_len = rsa.pss_sign(msg, &mut signature, RSA::HASH_TYPE_SHA256, RSA::MGF1SHA256, &rng).expect("Error with pss_sign()");
|
||||
/// assert!(sig_len > 0 && sig_len <= 512);
|
||||
///
|
||||
/// let key_path = "../../../certs/client-keyPub.der";
|
||||
/// let der: Vec<u8> = fs::read(key_path).expect("Error reading key file");
|
||||
/// let mut rsa = RSA::new_public_from_der(&der).expect("Error with new_public_from_der()");
|
||||
/// rsa.set_rng(&mut rng).expect("Error with set_rng()");
|
||||
/// rsa.set_shared_rng(std::rc::Rc::clone(&rng)).expect("Error with set_shared_rng()");
|
||||
/// let signature = &signature[0..sig_len];
|
||||
/// let mut verify_out: [u8; 512] = [0; 512];
|
||||
/// let verify_out_size = rsa.pss_verify(signature, &mut verify_out, RSA::HASH_TYPE_SHA256, RSA::MGF1SHA256).expect("Error with pss_verify()");
|
||||
@@ -880,12 +900,12 @@ impl RSA {
|
||||
/// }
|
||||
/// ```
|
||||
#[cfg(all(random, rsa_pss))]
|
||||
pub fn pss_sign(&mut self, din: &[u8], dout: &mut [u8], hash_algo: u32, mgf: i32, rng: &mut RNG) -> Result<usize, i32> {
|
||||
pub fn pss_sign(&mut self, din: &[u8], dout: &mut [u8], hash_algo: u32, mgf: i32, rng: &RNG) -> Result<usize, i32> {
|
||||
let din_size = crate::buffer_len_to_u32(din.len())?;
|
||||
let dout_size = crate::buffer_len_to_u32(dout.len())?;
|
||||
let rc = unsafe {
|
||||
sys::wc_RsaPSS_Sign(din.as_ptr(), din_size, dout.as_mut_ptr(), dout_size,
|
||||
hash_algo, mgf, &mut self.wc_rsakey, &mut rng.wc_rng)
|
||||
hash_algo, mgf, &mut self.wc_rsakey, rng.wc_rng)
|
||||
};
|
||||
if rc < 0 {
|
||||
return Err(rc);
|
||||
@@ -912,26 +932,26 @@ impl RSA {
|
||||
/// # Example
|
||||
///
|
||||
/// ```rust
|
||||
/// #[cfg(all(random, rsa_pss, rsa_const_api))]
|
||||
/// #[cfg(all(random, rsa_pss, rsa_const_api, feature = "alloc"))]
|
||||
/// {
|
||||
/// use std::fs;
|
||||
/// use wolfssl_wolfcrypt::random::RNG;
|
||||
/// use wolfssl_wolfcrypt::rsa::RSA;
|
||||
///
|
||||
/// let mut rng = RNG::new().expect("Error creating RNG");
|
||||
/// let rng = std::rc::Rc::new(RNG::new().expect("Error creating RNG"));
|
||||
///
|
||||
/// let key_path = "../../../certs/client-key.der";
|
||||
/// let der: Vec<u8> = fs::read(key_path).expect("Error reading key file");
|
||||
/// let mut rsa = RSA::new_from_der(&der).expect("Error with new_from_der()");
|
||||
/// let msg: &[u8] = b"This is the string to be signed!";
|
||||
/// let mut signature: [u8; 512] = [0; 512];
|
||||
/// let sig_len = rsa.pss_sign(msg, &mut signature, RSA::HASH_TYPE_SHA256, RSA::MGF1SHA256, &mut rng).expect("Error with pss_sign()");
|
||||
/// let sig_len = rsa.pss_sign(msg, &mut signature, RSA::HASH_TYPE_SHA256, RSA::MGF1SHA256, &rng).expect("Error with pss_sign()");
|
||||
/// assert!(sig_len > 0 && sig_len <= 512);
|
||||
///
|
||||
/// let key_path = "../../../certs/client-keyPub.der";
|
||||
/// let der: Vec<u8> = fs::read(key_path).expect("Error reading key file");
|
||||
/// let mut rsa = RSA::new_public_from_der(&der).expect("Error with new_public_from_der()");
|
||||
/// rsa.set_rng(&mut rng).expect("Error with set_rng()");
|
||||
/// rsa.set_shared_rng(std::rc::Rc::clone(&rng)).expect("Error with set_shared_rng()");
|
||||
/// let signature = &signature[0..sig_len];
|
||||
/// let mut verify_out: [u8; 512] = [0; 512];
|
||||
/// let verify_out_size = rsa.pss_verify(signature, &mut verify_out, RSA::HASH_TYPE_SHA256, RSA::MGF1SHA256).expect("Error with pss_verify()");
|
||||
@@ -978,26 +998,26 @@ impl RSA {
|
||||
/// # Example
|
||||
///
|
||||
/// ```rust
|
||||
/// #[cfg(all(random, rsa_pss, rsa_const_api))]
|
||||
/// #[cfg(all(random, rsa_pss, rsa_const_api, feature = "alloc"))]
|
||||
/// {
|
||||
/// use std::fs;
|
||||
/// use wolfssl_wolfcrypt::random::RNG;
|
||||
/// use wolfssl_wolfcrypt::rsa::RSA;
|
||||
///
|
||||
/// let mut rng = RNG::new().expect("Error creating RNG");
|
||||
/// let rng = std::rc::Rc::new(RNG::new().expect("Error creating RNG"));
|
||||
///
|
||||
/// let key_path = "../../../certs/client-key.der";
|
||||
/// let der: Vec<u8> = fs::read(key_path).expect("Error reading key file");
|
||||
/// let mut rsa = RSA::new_from_der(&der).expect("Error with new_from_der()");
|
||||
/// let msg: &[u8] = b"This is the string to be signed!";
|
||||
/// let mut signature: [u8; 512] = [0; 512];
|
||||
/// let sig_len = rsa.pss_sign(msg, &mut signature, RSA::HASH_TYPE_SHA256, RSA::MGF1SHA256, &mut rng).expect("Error with pss_sign()");
|
||||
/// let sig_len = rsa.pss_sign(msg, &mut signature, RSA::HASH_TYPE_SHA256, RSA::MGF1SHA256, &rng).expect("Error with pss_sign()");
|
||||
/// assert!(sig_len > 0 && sig_len <= 512);
|
||||
///
|
||||
/// let key_path = "../../../certs/client-keyPub.der";
|
||||
/// let der: Vec<u8> = fs::read(key_path).expect("Error reading key file");
|
||||
/// let mut rsa = RSA::new_public_from_der(&der).expect("Error with new_public_from_der()");
|
||||
/// rsa.set_rng(&mut rng).expect("Error with set_rng()");
|
||||
/// rsa.set_shared_rng(std::rc::Rc::clone(&rng)).expect("Error with set_shared_rng()");
|
||||
/// let signature = &signature[0..sig_len];
|
||||
/// let mut verify_out: [u8; 512] = [0; 512];
|
||||
/// let verify_out_size = rsa.pss_verify(signature, &mut verify_out, RSA::HASH_TYPE_SHA256, RSA::MGF1SHA256).expect("Error with pss_verify()");
|
||||
@@ -1049,26 +1069,26 @@ impl RSA {
|
||||
/// # Example
|
||||
///
|
||||
/// ```rust
|
||||
/// #[cfg(all(random, rsa_pss, rsa_const_api))]
|
||||
/// #[cfg(all(random, rsa_pss, rsa_const_api, feature = "alloc"))]
|
||||
/// {
|
||||
/// use std::fs;
|
||||
/// use wolfssl_wolfcrypt::random::RNG;
|
||||
/// use wolfssl_wolfcrypt::rsa::RSA;
|
||||
///
|
||||
/// let mut rng = RNG::new().expect("Error creating RNG");
|
||||
/// let rng = std::rc::Rc::new(RNG::new().expect("Error creating RNG"));
|
||||
///
|
||||
/// let key_path = "../../../certs/client-key.der";
|
||||
/// let der: Vec<u8> = fs::read(key_path).expect("Error reading key file");
|
||||
/// let mut rsa = RSA::new_from_der(&der).expect("Error with new_from_der()");
|
||||
/// let msg: &[u8] = b"This is the string to be signed!";
|
||||
/// let mut signature: [u8; 512] = [0; 512];
|
||||
/// let sig_len = rsa.pss_sign(msg, &mut signature, RSA::HASH_TYPE_SHA256, RSA::MGF1SHA256, &mut rng).expect("Error with pss_sign()");
|
||||
/// let sig_len = rsa.pss_sign(msg, &mut signature, RSA::HASH_TYPE_SHA256, RSA::MGF1SHA256, &rng).expect("Error with pss_sign()");
|
||||
/// assert!(sig_len > 0 && sig_len <= 512);
|
||||
///
|
||||
/// let key_path = "../../../certs/client-keyPub.der";
|
||||
/// let der: Vec<u8> = fs::read(key_path).expect("Error reading key file");
|
||||
/// let mut rsa = RSA::new_public_from_der(&der).expect("Error with new_public_from_der()");
|
||||
/// rsa.set_rng(&mut rng).expect("Error with set_rng()");
|
||||
/// rsa.set_shared_rng(std::rc::Rc::clone(&rng)).expect("Error with set_shared_rng()");
|
||||
/// let signature = &signature[0..sig_len];
|
||||
/// let mut verify_out: [u8; 512] = [0; 512];
|
||||
/// let verify_out_size = rsa.pss_verify(signature, &mut verify_out, RSA::HASH_TYPE_SHA256, RSA::MGF1SHA256).expect("Error with pss_verify()");
|
||||
@@ -1125,7 +1145,7 @@ impl RSA {
|
||||
/// use wolfssl_wolfcrypt::random::RNG;
|
||||
/// use wolfssl_wolfcrypt::rsa::RSA;
|
||||
///
|
||||
/// let mut rng = RNG::new().expect("Error creating RNG");
|
||||
/// let rng = RNG::new().expect("Error creating RNG");
|
||||
///
|
||||
/// let key_path = "../../../certs/client-key.der";
|
||||
/// let der: Vec<u8> = fs::read(key_path).expect("Error reading key file");
|
||||
@@ -1134,22 +1154,22 @@ impl RSA {
|
||||
/// let mut plain = [0u8; 256];
|
||||
/// plain[..msg.len()].copy_from_slice(msg);
|
||||
/// let mut enc = [0u8; 256];
|
||||
/// let enc_len = rsa.rsa_direct(&plain, &mut enc, RSA::PRIVATE_ENCRYPT, &mut rng).expect("Error with rsa_direct()");
|
||||
/// let enc_len = rsa.rsa_direct(&plain, &mut enc, RSA::PRIVATE_ENCRYPT, &rng).expect("Error with rsa_direct()");
|
||||
/// assert_eq!(enc_len, 256);
|
||||
/// let mut plain_out = [0u8; 256];
|
||||
/// let dec_len = rsa.rsa_direct(&enc, &mut plain_out, RSA::PUBLIC_DECRYPT, &mut rng).expect("Error with rsa_direct()");
|
||||
/// let dec_len = rsa.rsa_direct(&enc, &mut plain_out, RSA::PUBLIC_DECRYPT, &rng).expect("Error with rsa_direct()");
|
||||
/// assert_eq!(dec_len, 256);
|
||||
/// assert_eq!(plain_out, plain);
|
||||
/// }
|
||||
/// ```
|
||||
#[cfg(all(rsa_direct, rsa_const_api))]
|
||||
pub fn rsa_direct(&mut self, din: &[u8], dout: &mut [u8], typ: i32, rng: &mut RNG) -> Result<usize, i32> {
|
||||
pub fn rsa_direct(&mut self, din: &[u8], dout: &mut [u8], typ: i32, rng: &RNG) -> Result<usize, i32> {
|
||||
let din_size = crate::buffer_len_to_u32(din.len())?;
|
||||
let mut dout_size = crate::buffer_len_to_u32(dout.len())?;
|
||||
let rc = unsafe {
|
||||
sys::wc_RsaDirect(din.as_ptr(), din_size,
|
||||
dout.as_mut_ptr(), &mut dout_size,
|
||||
&mut self.wc_rsakey, typ, &mut rng.wc_rng)
|
||||
&mut self.wc_rsakey, typ, rng.wc_rng)
|
||||
};
|
||||
if rc < 0 {
|
||||
return Err(rc);
|
||||
@@ -1165,8 +1185,7 @@ impl RSA {
|
||||
/// # Parameters
|
||||
///
|
||||
/// * `rng`: The `RNG` struct instance to associate with this `RSA`
|
||||
/// instance. The `RNG` struct should not be moved in memory after
|
||||
/// calling this method.
|
||||
/// instance.
|
||||
///
|
||||
/// # Returns
|
||||
///
|
||||
@@ -1183,19 +1202,19 @@ impl RSA {
|
||||
/// use wolfssl_wolfcrypt::random::RNG;
|
||||
/// use wolfssl_wolfcrypt::rsa::RSA;
|
||||
///
|
||||
/// let mut rng = RNG::new().expect("Error creating RNG");
|
||||
/// let key_path = "../../../certs/client-keyPub.der";
|
||||
/// let der: Vec<u8> = fs::read(key_path).expect("Error reading key file");
|
||||
/// let mut rsa = RSA::new_public_from_der(&der).expect("Error with new_public_from_der()");
|
||||
/// rsa.set_rng(&mut rng).expect("Error with set_rng()");
|
||||
/// rsa.set_rng(RNG::new().expect("Error creating RNG")).expect("Error with set_rng()");
|
||||
/// let plain: &[u8] = b"Test message";
|
||||
/// let mut enc: [u8; 512] = [0; 512];
|
||||
/// let enc_len = rsa.public_encrypt(plain, &mut enc, &mut rng).expect("Error with public_encrypt()");
|
||||
/// let enc_rng = RNG::new().expect("Error creating RNG");
|
||||
/// let enc_len = rsa.public_encrypt(plain, &mut enc, &enc_rng).expect("Error with public_encrypt()");
|
||||
/// assert!(enc_len > 0 && enc_len <= 512);
|
||||
/// let key_path = "../../../certs/client-key.der";
|
||||
/// let der: Vec<u8> = fs::read(key_path).expect("Error reading key file");
|
||||
/// let mut rsa = RSA::new_from_der(&der).expect("Error with new_from_der()");
|
||||
/// rsa.set_rng(&mut rng).expect("Error with set_rng()");
|
||||
/// rsa.set_rng(RNG::new().expect("Error creating RNG")).expect("Error with set_rng()");
|
||||
/// let mut plain_out: [u8; 512] = [0; 512];
|
||||
/// let dec_len = rsa.private_decrypt(&enc[0..enc_len], &mut plain_out).expect("Error with private_decrypt()");
|
||||
/// assert!(dec_len as usize == plain.len());
|
||||
@@ -1203,16 +1222,47 @@ impl RSA {
|
||||
/// }
|
||||
/// ```
|
||||
#[cfg(random)]
|
||||
pub fn set_rng(&mut self, rng: &mut RNG) -> Result<(), i32> {
|
||||
pub fn set_rng(&mut self, rng: RNG) -> Result<(), i32> {
|
||||
let wc_rng = rng.wc_rng;
|
||||
let rc = unsafe {
|
||||
sys::wc_RsaSetRNG(&mut self.wc_rsakey, &mut rng.wc_rng)
|
||||
sys::wc_RsaSetRNG(&mut self.wc_rsakey, wc_rng)
|
||||
};
|
||||
if rc != 0 {
|
||||
return Err(rc);
|
||||
}
|
||||
self.rng = Some(RngHandle::Owned(rng));
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Bind a shared `RNG` to this key for blinding during private operations.
|
||||
///
|
||||
/// Like `set_rng`, but takes an `Rc<RNG>` so the same RNG can be shared
|
||||
/// among multiple consumers and used directly by the caller. Available
|
||||
/// when the `alloc` feature is enabled.
|
||||
#[cfg(all(random, feature = "alloc"))]
|
||||
pub fn set_shared_rng(&mut self, rng: alloc::rc::Rc<RNG>) -> Result<(), i32> {
|
||||
let wc_rng = rng.wc_rng;
|
||||
let rc = unsafe {
|
||||
sys::wc_RsaSetRNG(&mut self.wc_rsakey, wc_rng)
|
||||
};
|
||||
if rc != 0 {
|
||||
return Err(rc);
|
||||
}
|
||||
self.rng = Some(RngHandle::Shared(rng));
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Borrow the RNG previously bound via `set_rng` or `set_shared_rng`.
|
||||
#[cfg(random)]
|
||||
pub fn rng(&self) -> Option<&RNG> {
|
||||
match &self.rng {
|
||||
Some(RngHandle::Owned(rng)) => Some(rng),
|
||||
#[cfg(feature = "alloc")]
|
||||
Some(RngHandle::Shared(rng)) => Some(rng),
|
||||
None => None,
|
||||
}
|
||||
}
|
||||
|
||||
/// Sign the provided data with the private key.
|
||||
///
|
||||
/// # Parameters
|
||||
@@ -1233,26 +1283,26 @@ impl RSA {
|
||||
///
|
||||
/// ```rust
|
||||
/// # extern crate std;
|
||||
/// #[cfg(random)]
|
||||
/// #[cfg(all(random, feature = "alloc"))]
|
||||
/// {
|
||||
/// use std::fs;
|
||||
/// use wolfssl_wolfcrypt::random::RNG;
|
||||
/// use wolfssl_wolfcrypt::rsa::RSA;
|
||||
///
|
||||
/// let mut rng = RNG::new().expect("Error creating RNG");
|
||||
/// let rng = std::rc::Rc::new(RNG::new().expect("Error creating RNG"));
|
||||
///
|
||||
/// let key_path = "../../../certs/client-key.der";
|
||||
/// let der: Vec<u8> = fs::read(key_path).expect("Error reading key file");
|
||||
/// let mut rsa = RSA::new_from_der(&der).expect("Error with new_from_der()");
|
||||
/// let msg: &[u8] = b"This is the string to be signed!";
|
||||
/// let mut signature: [u8; 512] = [0; 512];
|
||||
/// let sig_len = rsa.ssl_sign(msg, &mut signature, &mut rng).expect("Error with ssl_sign()");
|
||||
/// let sig_len = rsa.ssl_sign(msg, &mut signature, &rng).expect("Error with ssl_sign()");
|
||||
/// assert!(sig_len > 0 && sig_len <= 512);
|
||||
///
|
||||
/// let key_path = "../../../certs/client-keyPub.der";
|
||||
/// let der: Vec<u8> = fs::read(key_path).expect("Error reading key file");
|
||||
/// let mut rsa = RSA::new_public_from_der(&der).expect("Error with new_public_from_der()");
|
||||
/// rsa.set_rng(&mut rng).expect("Error with set_rng()");
|
||||
/// rsa.set_shared_rng(std::rc::Rc::clone(&rng)).expect("Error with set_shared_rng()");
|
||||
/// let signature = &signature[0..sig_len];
|
||||
/// let mut verify_out: [u8; 512] = [0; 512];
|
||||
/// let verify_out_size = rsa.ssl_verify(signature, &mut verify_out).expect("Error with ssl_verify()");
|
||||
@@ -1260,13 +1310,13 @@ impl RSA {
|
||||
/// }
|
||||
/// ```
|
||||
#[cfg(random)]
|
||||
pub fn ssl_sign(&mut self, din: &[u8], dout: &mut [u8], rng: &mut RNG) -> Result<usize, i32> {
|
||||
pub fn ssl_sign(&mut self, din: &[u8], dout: &mut [u8], rng: &RNG) -> Result<usize, i32> {
|
||||
let din_size = crate::buffer_len_to_u32(din.len())?;
|
||||
let dout_size = crate::buffer_len_to_u32(dout.len())?;
|
||||
let rc = unsafe {
|
||||
sys::wc_RsaSSL_Sign(din.as_ptr(), din_size,
|
||||
dout.as_mut_ptr(), dout_size,
|
||||
&mut self.wc_rsakey, &mut rng.wc_rng)
|
||||
&mut self.wc_rsakey, rng.wc_rng)
|
||||
};
|
||||
if rc < 0 {
|
||||
return Err(rc);
|
||||
@@ -1295,26 +1345,26 @@ impl RSA {
|
||||
///
|
||||
/// ```rust
|
||||
/// # extern crate std;
|
||||
/// #[cfg(random)]
|
||||
/// #[cfg(all(random, feature = "alloc"))]
|
||||
/// {
|
||||
/// use std::fs;
|
||||
/// use wolfssl_wolfcrypt::random::RNG;
|
||||
/// use wolfssl_wolfcrypt::rsa::RSA;
|
||||
///
|
||||
/// let mut rng = RNG::new().expect("Error creating RNG");
|
||||
/// let rng = std::rc::Rc::new(RNG::new().expect("Error creating RNG"));
|
||||
///
|
||||
/// let key_path = "../../../certs/client-key.der";
|
||||
/// let der: Vec<u8> = fs::read(key_path).expect("Error reading key file");
|
||||
/// let mut rsa = RSA::new_from_der(&der).expect("Error with new_from_der()");
|
||||
/// let msg: &[u8] = b"This is the string to be signed!";
|
||||
/// let mut signature: [u8; 512] = [0; 512];
|
||||
/// let sig_len = rsa.ssl_sign(msg, &mut signature, &mut rng).expect("Error with ssl_sign()");
|
||||
/// let sig_len = rsa.ssl_sign(msg, &mut signature, &rng).expect("Error with ssl_sign()");
|
||||
/// assert!(sig_len > 0 && sig_len <= 512);
|
||||
///
|
||||
/// let key_path = "../../../certs/client-keyPub.der";
|
||||
/// let der: Vec<u8> = fs::read(key_path).expect("Error reading key file");
|
||||
/// let mut rsa = RSA::new_public_from_der(&der).expect("Error with new_public_from_der()");
|
||||
/// rsa.set_rng(&mut rng).expect("Error with set_rng()");
|
||||
/// rsa.set_shared_rng(std::rc::Rc::clone(&rng)).expect("Error with set_shared_rng()");
|
||||
/// let signature = &signature[0..sig_len];
|
||||
/// let mut verify_out: [u8; 512] = [0; 512];
|
||||
/// let verify_out_size = rsa.ssl_verify(signature, &mut verify_out).expect("Error with ssl_verify()");
|
||||
|
||||
@@ -149,9 +149,9 @@ pub struct SigningKey<H: Hash, const N: usize> {
|
||||
impl<H: Hash, const N: usize> SigningKey<H, N> {
|
||||
/// Generate a fresh `N * 8`-bit RSA key with public exponent 65537.
|
||||
#[cfg(rsa_keygen)]
|
||||
pub fn generate(mut rng: RNG) -> Result<Self, i32> {
|
||||
pub fn generate(rng: RNG) -> Result<Self, i32> {
|
||||
let bits: i32 = (N * 8).try_into().map_err(|_| sys::wolfCrypt_ErrorCodes_BAD_FUNC_ARG)?;
|
||||
let rsa = RSA::generate(bits, 65537, &mut rng)?;
|
||||
let rsa = RSA::generate(bits, 65537, &rng)?;
|
||||
Ok(Self { inner: rsa, rng, _hash: PhantomData })
|
||||
}
|
||||
|
||||
@@ -186,7 +186,7 @@ impl<H: Hash, const N: usize> SignerMut<Signature<N>> for SigningKey<H, N> {
|
||||
sig.as_mut_ptr(), &mut sig_len,
|
||||
&mut self.inner.wc_rsakey as *mut _ as *mut c_void,
|
||||
size_of::<sys::RsaKey>() as u32,
|
||||
&mut self.rng.wc_rng,
|
||||
self.rng.wc_rng,
|
||||
)
|
||||
};
|
||||
if rc != 0 || sig_len as usize != N {
|
||||
|
||||
@@ -1030,6 +1030,29 @@ fn test_aes256gcm_nist_tc14_encrypt() {
|
||||
assert_eq!(&tag[..], &expected_tag);
|
||||
}
|
||||
|
||||
/// Roundtrip test for AES-192-GCM using `aead::Aead`.
|
||||
#[test]
|
||||
#[cfg(all(feature = "aead", aes_gcm))]
|
||||
fn test_aes192gcm_aead_roundtrip() {
|
||||
let key = [0x77u8; 24];
|
||||
let nonce_bytes = [0x88u8; 12];
|
||||
let aad = b"aes-192-gcm test";
|
||||
let plaintext = b"AES-192-GCM roundtrip test";
|
||||
|
||||
let cipher = Aes192Gcm::new_from_slice(&key).unwrap();
|
||||
let nonce: aead::Nonce<Aes192Gcm> = nonce_bytes.into();
|
||||
|
||||
let ciphertext = cipher
|
||||
.encrypt(&nonce, Payload { msg: plaintext, aad })
|
||||
.expect("AES-192-GCM encrypt failed");
|
||||
|
||||
let recovered = cipher
|
||||
.decrypt(&nonce, Payload { msg: &ciphertext, aad })
|
||||
.expect("AES-192-GCM decrypt failed");
|
||||
|
||||
assert_eq!(recovered, plaintext);
|
||||
}
|
||||
|
||||
/// Roundtrip test for AES-256-GCM using `aead::Aead`.
|
||||
#[test]
|
||||
#[cfg(all(feature = "aead", aes_gcm))]
|
||||
@@ -1092,6 +1115,29 @@ fn test_aes128ccm_reject_tampered() {
|
||||
assert!(cipher.decrypt(&nonce, ct.as_slice()).is_err());
|
||||
}
|
||||
|
||||
/// Roundtrip test for AES-192-CCM using `aead::Aead`.
|
||||
#[test]
|
||||
#[cfg(all(feature = "aead", aes_ccm))]
|
||||
fn test_aes192ccm_aead_roundtrip() {
|
||||
let key = [0x33u8; 24];
|
||||
let nonce_bytes = [0x44u8; 12];
|
||||
let aad = b"aes-192-ccm test";
|
||||
let plaintext = b"AES-192-CCM plaintext data";
|
||||
|
||||
let cipher = Aes192Ccm::new_from_slice(&key).unwrap();
|
||||
let nonce: aead::Nonce<Aes192Ccm> = nonce_bytes.into();
|
||||
|
||||
let ciphertext = cipher
|
||||
.encrypt(&nonce, Payload { msg: plaintext, aad })
|
||||
.expect("AES-192-CCM encrypt failed");
|
||||
|
||||
let recovered = cipher
|
||||
.decrypt(&nonce, Payload { msg: &ciphertext, aad })
|
||||
.expect("AES-192-CCM decrypt failed");
|
||||
|
||||
assert_eq!(recovered, plaintext);
|
||||
}
|
||||
|
||||
/// Roundtrip test for AES-256-CCM using `aead::Aead`.
|
||||
#[test]
|
||||
#[cfg(all(feature = "aead", aes_ccm))]
|
||||
|
||||
@@ -0,0 +1,126 @@
|
||||
#![cfg(all(any(blake2b, blake2s), feature = "digest"))]
|
||||
|
||||
use digest::{Digest, FixedOutputReset};
|
||||
use digest::block_api::BlockSizeUser;
|
||||
|
||||
mod common;
|
||||
|
||||
fn check_digest<D: Digest + BlockSizeUser + FixedOutputReset + Default>(
|
||||
input: &[u8],
|
||||
expected: &[u8],
|
||||
expected_block_size: usize,
|
||||
) {
|
||||
assert_eq!(<D as Digest>::output_size(), expected.len());
|
||||
assert_eq!(<D as BlockSizeUser>::block_size(), expected_block_size);
|
||||
|
||||
/* One-shot digest via associated function. */
|
||||
let out = D::digest(input);
|
||||
assert_eq!(out.as_slice(), expected);
|
||||
|
||||
/* Streaming via Digest::update and finalize. */
|
||||
let mut hasher = D::new();
|
||||
Digest::update(&mut hasher, input);
|
||||
let out = hasher.finalize();
|
||||
assert_eq!(out.as_slice(), expected);
|
||||
|
||||
/* Split update via Default + Update + FixedOutputReset::finalize_reset. */
|
||||
let mut hasher = D::default();
|
||||
if input.len() >= 2 {
|
||||
let mid = input.len() / 2;
|
||||
Digest::update(&mut hasher, &input[..mid]);
|
||||
Digest::update(&mut hasher, &input[mid..]);
|
||||
} else {
|
||||
Digest::update(&mut hasher, input);
|
||||
}
|
||||
let out = hasher.finalize_reset();
|
||||
assert_eq!(out.as_slice(), expected);
|
||||
|
||||
/* After reset, the same hasher should produce the same result. */
|
||||
Digest::update(&mut hasher, input);
|
||||
let out = hasher.finalize();
|
||||
assert_eq!(out.as_slice(), expected);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(blake2b)]
|
||||
fn test_digest_blake2b_512() {
|
||||
use wolfssl_wolfcrypt::blake2_digest::Blake2b512;
|
||||
common::setup();
|
||||
check_digest::<Blake2b512>(
|
||||
b"abc",
|
||||
b"\xBA\x80\xA5\x3F\x98\x1C\x4D\x0D\x6A\x27\x97\xB6\x9F\x12\xF6\xE9\x4C\x21\x2F\x14\x68\x5A\xC4\xB7\x4B\x12\xBB\x6F\xDB\xFF\xA2\xD1\x7D\x87\xC5\x39\x2A\xAB\x79\x2D\xC2\x52\xD5\xDE\x45\x33\xCC\x95\x18\xD3\x8A\xA8\xDB\xF1\x92\x5A\xB9\x23\x86\xED\xD4\x00\x99\x23",
|
||||
128,
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(blake2b)]
|
||||
fn test_digest_blake2b_384() {
|
||||
use wolfssl_wolfcrypt::blake2::BLAKE2b;
|
||||
use wolfssl_wolfcrypt::blake2_digest::Blake2b384;
|
||||
common::setup();
|
||||
|
||||
let mut reference = BLAKE2b::new(48).expect("Error with new()");
|
||||
reference.update(b"abc").expect("Error with update()");
|
||||
let mut expected = [0u8; 48];
|
||||
reference.finalize(&mut expected).expect("Error with finalize()");
|
||||
|
||||
check_digest::<Blake2b384>(b"abc", &expected, 128);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(blake2b)]
|
||||
fn test_digest_blake2b_256() {
|
||||
use wolfssl_wolfcrypt::blake2::BLAKE2b;
|
||||
use wolfssl_wolfcrypt::blake2_digest::Blake2b256;
|
||||
common::setup();
|
||||
|
||||
let mut reference = BLAKE2b::new(32).expect("Error with new()");
|
||||
reference.update(b"abc").expect("Error with update()");
|
||||
let mut expected = [0u8; 32];
|
||||
reference.finalize(&mut expected).expect("Error with finalize()");
|
||||
|
||||
check_digest::<Blake2b256>(b"abc", &expected, 128);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(blake2s)]
|
||||
fn test_digest_blake2s_256() {
|
||||
use wolfssl_wolfcrypt::blake2_digest::Blake2s256;
|
||||
common::setup();
|
||||
check_digest::<Blake2s256>(
|
||||
b"abc",
|
||||
b"\x50\x8C\x5E\x8C\x32\x7C\x14\xE2\xE1\xA7\x2B\xA3\x4E\xEB\x45\x2F\x37\x45\x8B\x20\x9E\xD6\x3A\x29\x4D\x99\x9B\x4C\x86\x67\x59\x82",
|
||||
64,
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(blake2s)]
|
||||
fn test_digest_blake2s_192() {
|
||||
use wolfssl_wolfcrypt::blake2::BLAKE2s;
|
||||
use wolfssl_wolfcrypt::blake2_digest::Blake2s192;
|
||||
common::setup();
|
||||
|
||||
let mut reference = BLAKE2s::new(24).expect("Error with new()");
|
||||
reference.update(b"abc").expect("Error with update()");
|
||||
let mut expected = [0u8; 24];
|
||||
reference.finalize(&mut expected).expect("Error with finalize()");
|
||||
|
||||
check_digest::<Blake2s192>(b"abc", &expected, 64);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(blake2s)]
|
||||
fn test_digest_blake2s_128() {
|
||||
use wolfssl_wolfcrypt::blake2::BLAKE2s;
|
||||
use wolfssl_wolfcrypt::blake2_digest::Blake2s128;
|
||||
common::setup();
|
||||
|
||||
let mut reference = BLAKE2s::new(16).expect("Error with new()");
|
||||
reference.update(b"abc").expect("Error with update()");
|
||||
let mut expected = [0u8; 16];
|
||||
reference.finalize(&mut expected).expect("Error with finalize()");
|
||||
|
||||
check_digest::<Blake2s128>(b"abc", &expected, 64);
|
||||
}
|
||||
@@ -0,0 +1,181 @@
|
||||
#![cfg(all(any(blake2b, blake2s), feature = "mac"))]
|
||||
|
||||
use digest::{KeyInit, Mac};
|
||||
|
||||
#[test]
|
||||
#[cfg(blake2b)]
|
||||
fn test_blake2b_mac_512() {
|
||||
use wolfssl_wolfcrypt::blake2::BLAKE2b;
|
||||
use wolfssl_wolfcrypt::blake2_mac::Blake2bMac512;
|
||||
|
||||
let key = [0x42u8; 64];
|
||||
let input = b"The quick brown fox jumps over the lazy dog";
|
||||
|
||||
let mut reference = BLAKE2b::new_with_key(64, &key)
|
||||
.expect("Error with new_with_key()");
|
||||
reference.update(input).expect("Error with update()");
|
||||
let mut expected = [0u8; 64];
|
||||
reference.finalize(&mut expected)
|
||||
.expect("Error with finalize()");
|
||||
|
||||
let mut mac = Blake2bMac512::new_from_slice(&key)
|
||||
.expect("Blake2bMac512 init failed");
|
||||
mac.update(input);
|
||||
let tag = mac.finalize();
|
||||
assert_eq!(tag.into_bytes().as_slice(), &expected);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(blake2b)]
|
||||
fn test_blake2b_mac_256() {
|
||||
use wolfssl_wolfcrypt::blake2::BLAKE2b;
|
||||
use wolfssl_wolfcrypt::blake2_mac::Blake2bMac256;
|
||||
|
||||
let key = [0x33u8; 64];
|
||||
let input = b"libsodium crypto_generichash analog";
|
||||
|
||||
let mut reference = BLAKE2b::new_with_key(32, &key)
|
||||
.expect("Error with new_with_key()");
|
||||
reference.update(input).expect("Error with update()");
|
||||
let mut expected = [0u8; 32];
|
||||
reference.finalize(&mut expected)
|
||||
.expect("Error with finalize()");
|
||||
|
||||
let mut mac = Blake2bMac256::new_from_slice(&key)
|
||||
.expect("Blake2bMac256 init failed");
|
||||
mac.update(input);
|
||||
let tag = mac.finalize();
|
||||
assert_eq!(tag.into_bytes().as_slice(), &expected);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(blake2b)]
|
||||
fn test_blake2b_mac_384() {
|
||||
use wolfssl_wolfcrypt::blake2::BLAKE2b;
|
||||
use wolfssl_wolfcrypt::blake2_mac::Blake2bMac384;
|
||||
|
||||
let key = [0x77u8; 64];
|
||||
let input = b"sha-384 sized blake2b mac";
|
||||
|
||||
let mut reference = BLAKE2b::new_with_key(48, &key)
|
||||
.expect("Error with new_with_key()");
|
||||
reference.update(input).expect("Error with update()");
|
||||
let mut expected = [0u8; 48];
|
||||
reference.finalize(&mut expected)
|
||||
.expect("Error with finalize()");
|
||||
|
||||
let mut mac = Blake2bMac384::new_from_slice(&key)
|
||||
.expect("Blake2bMac384 init failed");
|
||||
mac.update(input);
|
||||
let tag = mac.finalize();
|
||||
assert_eq!(tag.into_bytes().as_slice(), &expected);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(blake2b)]
|
||||
fn test_blake2b_mac_512_chunked() {
|
||||
use wolfssl_wolfcrypt::blake2::BLAKE2b;
|
||||
use wolfssl_wolfcrypt::blake2_mac::Blake2bMac512;
|
||||
|
||||
let key = [0xA5u8; 64];
|
||||
let input: Vec<u8> = (0u8..200).collect();
|
||||
|
||||
let mut reference = BLAKE2b::new_with_key(64, &key)
|
||||
.expect("Error with new_with_key()");
|
||||
reference.update(&input).expect("Error with update()");
|
||||
let mut expected = [0u8; 64];
|
||||
reference.finalize(&mut expected)
|
||||
.expect("Error with finalize()");
|
||||
|
||||
let mut mac = Blake2bMac512::new_from_slice(&key)
|
||||
.expect("Blake2bMac512 init failed");
|
||||
for chunk in input.chunks(17) {
|
||||
mac.update(chunk);
|
||||
}
|
||||
mac.verify_slice(&expected)
|
||||
.expect("Blake2bMac512 verify failed");
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(blake2s)]
|
||||
fn test_blake2s_mac_128() {
|
||||
use wolfssl_wolfcrypt::blake2::BLAKE2s;
|
||||
use wolfssl_wolfcrypt::blake2_mac::Blake2sMac128;
|
||||
|
||||
let key = [0x55u8; 32];
|
||||
let input = b"short blake2s mac";
|
||||
|
||||
let mut reference = BLAKE2s::new_with_key(16, &key)
|
||||
.expect("Error with new_with_key()");
|
||||
reference.update(input).expect("Error with update()");
|
||||
let mut expected = [0u8; 16];
|
||||
reference.finalize(&mut expected)
|
||||
.expect("Error with finalize()");
|
||||
|
||||
let mut mac = Blake2sMac128::new_from_slice(&key)
|
||||
.expect("Blake2sMac128 init failed");
|
||||
mac.update(input);
|
||||
let tag = mac.finalize();
|
||||
assert_eq!(tag.into_bytes().as_slice(), &expected);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(blake2s)]
|
||||
fn test_blake2s_mac_192() {
|
||||
use wolfssl_wolfcrypt::blake2::BLAKE2s;
|
||||
use wolfssl_wolfcrypt::blake2_mac::Blake2sMac192;
|
||||
|
||||
let key = [0x99u8; 32];
|
||||
let input = b"medium blake2s mac";
|
||||
|
||||
let mut reference = BLAKE2s::new_with_key(24, &key)
|
||||
.expect("Error with new_with_key()");
|
||||
reference.update(input).expect("Error with update()");
|
||||
let mut expected = [0u8; 24];
|
||||
reference.finalize(&mut expected)
|
||||
.expect("Error with finalize()");
|
||||
|
||||
let mut mac = Blake2sMac192::new_from_slice(&key)
|
||||
.expect("Blake2sMac192 init failed");
|
||||
mac.update(input);
|
||||
let tag = mac.finalize();
|
||||
assert_eq!(tag.into_bytes().as_slice(), &expected);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(blake2s)]
|
||||
fn test_blake2s_mac_256() {
|
||||
use wolfssl_wolfcrypt::blake2::BLAKE2s;
|
||||
use wolfssl_wolfcrypt::blake2_mac::Blake2sMac256;
|
||||
|
||||
let key = [0x42u8; 32];
|
||||
let input = b"The quick brown fox jumps over the lazy dog";
|
||||
|
||||
let mut reference = BLAKE2s::new_with_key(32, &key)
|
||||
.expect("Error with new_with_key()");
|
||||
reference.update(input).expect("Error with update()");
|
||||
let mut expected = [0u8; 32];
|
||||
reference.finalize(&mut expected)
|
||||
.expect("Error with finalize()");
|
||||
|
||||
let mut mac = Blake2sMac256::new_from_slice(&key)
|
||||
.expect("Blake2sMac256 init failed");
|
||||
mac.update(input);
|
||||
let tag = mac.finalize();
|
||||
assert_eq!(tag.into_bytes().as_slice(), &expected);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(blake2s)]
|
||||
fn test_blake2s_mac_256_verify_fail() {
|
||||
use wolfssl_wolfcrypt::blake2_mac::Blake2sMac256;
|
||||
|
||||
let key = [0x0Bu8; 32];
|
||||
let input = b"hello";
|
||||
let wrong_tag = [0u8; 32];
|
||||
|
||||
let mut mac = Blake2sMac256::new_from_slice(&key)
|
||||
.expect("Blake2sMac256 init failed");
|
||||
mac.update(input);
|
||||
assert!(mac.verify_slice(&wrong_tag).is_err());
|
||||
}
|
||||
@@ -1,5 +1,7 @@
|
||||
#![cfg(all(curve25519, random))]
|
||||
|
||||
#[cfg(curve25519_blinding)]
|
||||
use std::rc::Rc;
|
||||
use wolfssl_wolfcrypt::curve25519::*;
|
||||
use wolfssl_wolfcrypt::random::RNG;
|
||||
|
||||
@@ -97,14 +99,17 @@ fn test_make_pub_blind() {
|
||||
|
||||
#[test]
|
||||
fn test_shared_secret() {
|
||||
let mut rng = RNG::new().expect("Error with new()");
|
||||
let mut key1 = Curve25519Key::generate(&mut rng).expect("Error with generate()");
|
||||
let mut key2 = Curve25519Key::generate(&mut rng).expect("Error with generate()");
|
||||
#[cfg(curve25519_blinding)]
|
||||
let rng = Rc::new(RNG::new().expect("Error with new()"));
|
||||
#[cfg(not(curve25519_blinding))]
|
||||
let rng = RNG::new().expect("Error with new()");
|
||||
let mut key1 = Curve25519Key::generate(&rng).expect("Error with generate()");
|
||||
let mut key2 = Curve25519Key::generate(&rng).expect("Error with generate()");
|
||||
|
||||
#[cfg(curve25519_blinding)]
|
||||
key1.set_rng(&mut rng).expect("Error with set_rng()");
|
||||
key1.set_shared_rng(Rc::clone(&rng)).expect("Error with set_shared_rng()");
|
||||
#[cfg(curve25519_blinding)]
|
||||
key2.set_rng(&mut rng).expect("Error with set_rng()");
|
||||
key2.set_shared_rng(Rc::clone(&rng)).expect("Error with set_shared_rng()");
|
||||
|
||||
let mut public_buffer = [0u8; Curve25519Key::KEYSIZE];
|
||||
key1.export_public(&mut public_buffer).expect("Error with export_public()");
|
||||
@@ -122,14 +127,17 @@ fn test_shared_secret() {
|
||||
|
||||
#[test]
|
||||
fn test_shared_secret_ex() {
|
||||
let mut rng = RNG::new().expect("Error with new()");
|
||||
let mut key1 = Curve25519Key::generate(&mut rng).expect("Error with generate()");
|
||||
let mut key2 = Curve25519Key::generate(&mut rng).expect("Error with generate()");
|
||||
#[cfg(curve25519_blinding)]
|
||||
let rng = Rc::new(RNG::new().expect("Error with new()"));
|
||||
#[cfg(not(curve25519_blinding))]
|
||||
let rng = RNG::new().expect("Error with new()");
|
||||
let mut key1 = Curve25519Key::generate(&rng).expect("Error with generate()");
|
||||
let mut key2 = Curve25519Key::generate(&rng).expect("Error with generate()");
|
||||
|
||||
#[cfg(curve25519_blinding)]
|
||||
key1.set_rng(&mut rng).expect("Error with set_rng()");
|
||||
key1.set_shared_rng(Rc::clone(&rng)).expect("Error with set_shared_rng()");
|
||||
#[cfg(curve25519_blinding)]
|
||||
key2.set_rng(&mut rng).expect("Error with set_rng()");
|
||||
key2.set_shared_rng(Rc::clone(&rng)).expect("Error with set_shared_rng()");
|
||||
|
||||
let mut public_buffer = [0u8; Curve25519Key::KEYSIZE];
|
||||
key1.export_public(&mut public_buffer).expect("Error with export_public()");
|
||||
|
||||
@@ -4,9 +4,13 @@ mod common;
|
||||
|
||||
#[cfg(any(all(ecc_import, ecc_export, ecc_sign, ecc_verify, random), random))]
|
||||
use std::fs;
|
||||
#[cfg(all(ecc_dh, random))]
|
||||
use std::rc::Rc;
|
||||
use wolfssl_wolfcrypt::ecc::*;
|
||||
#[cfg(random)]
|
||||
use wolfssl_wolfcrypt::random::RNG;
|
||||
#[cfg(ecc_import)]
|
||||
use wolfssl_wolfcrypt::sys;
|
||||
|
||||
#[test]
|
||||
#[cfg(random)]
|
||||
@@ -134,7 +138,7 @@ fn test_ecc_import_export_sign_verify() {
|
||||
let valid = ecc.verify_hash(&signature, &hash).expect("Error with verify_hash()");
|
||||
assert_eq!(valid, false);
|
||||
|
||||
ecc.set_rng(&mut rng).expect("Error with set_rng()");
|
||||
ecc.set_rng(rng).expect("Error with set_rng()");
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -142,13 +146,13 @@ fn test_ecc_import_export_sign_verify() {
|
||||
fn test_ecc_shared_secret() {
|
||||
common::setup();
|
||||
|
||||
let mut rng = RNG::new().expect("Failed to create RNG");
|
||||
let mut ecc0 = ECC::generate(32, &mut rng, None, None).expect("Error with generate()");
|
||||
let mut ecc1 = ECC::generate(32, &mut rng, None, None).expect("Error with generate()");
|
||||
let rng = Rc::new(RNG::new().expect("Failed to create RNG"));
|
||||
let mut ecc0 = ECC::generate(32, &rng, None, None).expect("Error with generate()");
|
||||
let mut ecc1 = ECC::generate(32, &rng, None, None).expect("Error with generate()");
|
||||
let mut ss0 = [0u8; 128];
|
||||
let mut ss1 = [0u8; 128];
|
||||
ecc0.set_rng(&mut rng).expect("Error with set_rng()");
|
||||
ecc1.set_rng(&mut rng).expect("Error with set_rng()");
|
||||
ecc0.set_shared_rng(Rc::clone(&rng)).expect("Error with set_shared_rng()");
|
||||
ecc1.set_shared_rng(Rc::clone(&rng)).expect("Error with set_shared_rng()");
|
||||
let ss0_size = ecc0.shared_secret(&mut ecc1, &mut ss0).expect("Error with shared_secret()");
|
||||
let ss1_size = ecc1.shared_secret(&mut ecc0, &mut ss1).expect("Error with shared_secret()");
|
||||
assert_eq!(ss0_size, ss1_size);
|
||||
@@ -290,6 +294,33 @@ fn test_ecc_import_unsigned() {
|
||||
assert_eq!(valid, true);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(ecc_import)]
|
||||
fn test_ecc_import_unsigned_short_slices() {
|
||||
common::setup();
|
||||
|
||||
let curve_id = ECC::SECP256R1;
|
||||
let qx = [0u8; 32];
|
||||
let qy = [0u8; 32];
|
||||
let d = [0u8; 32];
|
||||
let empty: [u8; 0] = [];
|
||||
|
||||
let cases: [(&[u8], &[u8], &[u8]); 6] = [
|
||||
(&qx[..31], &qy, &d ),
|
||||
(&qx, &qy[..31], &d ),
|
||||
(&qx, &qy, &d[..31] ),
|
||||
(&empty, &qy, &d ),
|
||||
(&qx, &empty, &d ),
|
||||
(&qx, &qy, &empty ),
|
||||
];
|
||||
for (qx, qy, d) in cases {
|
||||
match ECC::import_unsigned(qx, qy, d, curve_id, None, None) {
|
||||
Ok(_) => panic!("import_unsigned() should fail with short slice"),
|
||||
Err(rc) => assert_eq!(rc, sys::wolfCrypt_ErrorCodes_BAD_FUNC_ARG),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(random)]
|
||||
fn test_ecc_make_pub() {
|
||||
@@ -365,6 +396,38 @@ fn test_ecc_import() {
|
||||
ECC::import_raw_ex(qx, qy, d, ECC::SECP256R1, None, None).expect("Error with import_raw_ex()");
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(ecc_import)]
|
||||
fn test_ecc_import_raw_not_null_terminated() {
|
||||
common::setup();
|
||||
|
||||
let qx = b"7a4e287890a1a47ad3457e52f2f76a83ce46cbc947616d0cbaa82323818a793d\0";
|
||||
let qy = b"eec4084f5b29ebf29c44cce3b3059610922f8b30ea6e8811742ac7238fe87308\0";
|
||||
let d = b"8c14b793cb19137e323a6d2e2a870bca2e7a493ec1153b3a95feb8a4873f8d08\0";
|
||||
let qx_no_nul: &[u8] = &qx[..qx.len() - 1];
|
||||
let qy_no_nul: &[u8] = &qy[..qy.len() - 1];
|
||||
let d_no_nul: &[u8] = &d[..d.len() - 1];
|
||||
let curve_name = b"SECP256R1\0";
|
||||
let curve_name_no_nul: &[u8] = b"SECP256R1";
|
||||
let empty: &[u8] = b"";
|
||||
|
||||
assert!(ECC::import_raw(qx_no_nul, qy, d, curve_name, None, None).is_err());
|
||||
assert!(ECC::import_raw(qx, qy_no_nul, d, curve_name, None, None).is_err());
|
||||
assert!(ECC::import_raw(qx, qy, d_no_nul, curve_name, None, None).is_err());
|
||||
assert!(ECC::import_raw(qx, qy, d, curve_name_no_nul, None, None).is_err());
|
||||
assert!(ECC::import_raw(empty, qy, d, curve_name, None, None).is_err());
|
||||
assert!(ECC::import_raw(qx, empty, d, curve_name, None, None).is_err());
|
||||
assert!(ECC::import_raw(qx, qy, empty, curve_name, None, None).is_err());
|
||||
assert!(ECC::import_raw(qx, qy, d, empty, None, None).is_err());
|
||||
|
||||
assert!(ECC::import_raw_ex(qx_no_nul, qy, d, ECC::SECP256R1, None, None).is_err());
|
||||
assert!(ECC::import_raw_ex(qx, qy_no_nul, d, ECC::SECP256R1, None, None).is_err());
|
||||
assert!(ECC::import_raw_ex(qx, qy, d_no_nul, ECC::SECP256R1, None, None).is_err());
|
||||
assert!(ECC::import_raw_ex(empty, qy, d, ECC::SECP256R1, None, None).is_err());
|
||||
assert!(ECC::import_raw_ex(qx, empty, d, ECC::SECP256R1, None, None).is_err());
|
||||
assert!(ECC::import_raw_ex(qx, qy, empty, ECC::SECP256R1, None, None).is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_ecc_rs_hex_to_sig_not_null_terminated() {
|
||||
common::setup();
|
||||
|
||||
@@ -40,6 +40,27 @@ fn test_hmac_sha256_mac_finalize() {
|
||||
assert_eq!(result.as_bytes().as_slice(), expected);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_hmac_sha256_mac_clone() {
|
||||
let key = b"\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b";
|
||||
let prefix = b"Hi ";
|
||||
let suffix = b"There";
|
||||
let expected = b"\xb0\x34\x4c\x61\xd8\xdb\x38\x53\x5c\xa8\xaf\xce\xaf\x0b\xf1\x2b\x88\x1d\xc2\x00\xc9\x83\x3d\xa7\x26\xe9\x37\x6c\x2e\x32\xcf\xf7";
|
||||
|
||||
let mut mac = HmacSha256::new_from_slice(key)
|
||||
.expect("HMAC init failed");
|
||||
mac.update(prefix);
|
||||
|
||||
let mut forked = mac.clone();
|
||||
forked.update(suffix);
|
||||
let forked_tag = forked.finalize();
|
||||
assert_eq!(forked_tag.as_bytes().as_slice(), expected);
|
||||
|
||||
mac.update(suffix);
|
||||
let original_tag = mac.finalize();
|
||||
assert_eq!(original_tag.as_bytes().as_slice(), expected);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_hmac_sha256_mac_verify_fail() {
|
||||
let key = b"\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b";
|
||||
|
||||
@@ -52,7 +52,7 @@ fn test_test_seed() {
|
||||
fn test_rng_generate_byte() {
|
||||
// Since a single 0x00 or 0xFF could occur occasionally, we'll combine four
|
||||
// bytes into a u32 and make sure they aren't all 0x00 or all 0xFF.
|
||||
let mut rng = RNG::new().expect("Failed to create RNG");
|
||||
let rng = RNG::new().expect("Failed to create RNG");
|
||||
let mut v: u32 = 0;
|
||||
for _i in 0..4 {
|
||||
let byte = rng.generate_byte().expect("Failed to generate a single byte");
|
||||
@@ -65,7 +65,7 @@ fn test_rng_generate_byte() {
|
||||
// Test that generate_block works for a slice of u8.
|
||||
#[test]
|
||||
fn test_rng_generate_block_u8() {
|
||||
let mut rng = RNG::new().expect("Failed to create RNG");
|
||||
let rng = RNG::new().expect("Failed to create RNG");
|
||||
let mut buffer = [0u8; 32];
|
||||
rng.generate_block(&mut buffer).expect("Failed to generate a block of bytes");
|
||||
|
||||
@@ -77,7 +77,7 @@ fn test_rng_generate_block_u8() {
|
||||
// Test that generate_block works for a slice of u32.
|
||||
#[test]
|
||||
fn test_rng_generate_block_u32() {
|
||||
let mut rng = RNG::new().expect("Failed to create RNG");
|
||||
let rng = RNG::new().expect("Failed to create RNG");
|
||||
let mut buffer = [0u32; 8];
|
||||
rng.generate_block(&mut buffer).expect("Failed to generate a block of u32");
|
||||
|
||||
@@ -93,7 +93,7 @@ fn test_rng_generate_block_u32() {
|
||||
#[test]
|
||||
#[cfg(random_hashdrbg)]
|
||||
fn test_rng_reseed() {
|
||||
let mut rng = RNG::new().expect("Failed to create RNG");
|
||||
let rng = RNG::new().expect("Failed to create RNG");
|
||||
let seed = [1u8, 2, 3, 4];
|
||||
rng.reseed(&seed).expect("Error with reseed()");
|
||||
}
|
||||
|
||||
@@ -5,6 +5,8 @@ mod common;
|
||||
#[cfg(any(all(sha256, random, rsa_pss), random, rsa_direct))]
|
||||
use std::fs;
|
||||
#[cfg(random)]
|
||||
use std::rc::Rc;
|
||||
#[cfg(random)]
|
||||
use wolfssl_wolfcrypt::random::RNG;
|
||||
#[cfg(any(random, rsa_direct, rsa_keygen))]
|
||||
use wolfssl_wolfcrypt::rsa::*;
|
||||
@@ -14,8 +16,8 @@ use wolfssl_wolfcrypt::rsa::*;
|
||||
fn test_rsa_generate() {
|
||||
common::setup();
|
||||
|
||||
let mut rng = RNG::new().expect("Error creating RNG");
|
||||
let mut rsa = RSA::generate(2048, 65537, &mut rng).expect("Error with generate()");
|
||||
let rng = RNG::new().expect("Error creating RNG");
|
||||
let mut rsa = RSA::generate(2048, 65537, &rng).expect("Error with generate()");
|
||||
rsa.check().expect("Error with check()");
|
||||
|
||||
let encrypt_size = rsa.get_encrypt_size().expect("Error with get_encrypt_size()");
|
||||
@@ -58,20 +60,20 @@ fn test_rsa_generate() {
|
||||
#[test]
|
||||
#[cfg(random)]
|
||||
fn test_rsa_encrypt_decrypt() {
|
||||
let mut rng = RNG::new().expect("Error creating RNG");
|
||||
let rng = Rc::new(RNG::new().expect("Error creating RNG"));
|
||||
let key_path = "../../../certs/client-keyPub.der";
|
||||
let der: Vec<u8> = fs::read(key_path).expect("Error reading key file");
|
||||
let mut rsa = RSA::new_public_from_der(&der).expect("Error with new_public_from_der()");
|
||||
rsa.set_rng(&mut rng).expect("Error with set_rng()");
|
||||
rsa.set_shared_rng(Rc::clone(&rng)).expect("Error with set_shared_rng()");
|
||||
let plain: &[u8] = b"Test message";
|
||||
let mut enc: [u8; 512] = [0; 512];
|
||||
let enc_len = rsa.public_encrypt(plain, &mut enc, &mut rng).expect("Error with public_encrypt()");
|
||||
let enc_len = rsa.public_encrypt(plain, &mut enc, &rng).expect("Error with public_encrypt()");
|
||||
assert!(enc_len > 0 && enc_len <= 512);
|
||||
|
||||
let key_path = "../../../certs/client-key.der";
|
||||
let der: Vec<u8> = fs::read(key_path).expect("Error reading key file");
|
||||
let mut rsa = RSA::new_from_der(&der).expect("Error with new_from_der()");
|
||||
rsa.set_rng(&mut rng).expect("Error with set_rng()");
|
||||
rsa.set_shared_rng(Rc::clone(&rng)).expect("Error with set_shared_rng()");
|
||||
let mut plain_out: [u8; 512] = [0; 512];
|
||||
let dec_len = rsa.private_decrypt(&enc[0..enc_len], &mut plain_out).expect("Error with private_decrypt()");
|
||||
assert!(dec_len as usize == plain.len());
|
||||
@@ -81,20 +83,20 @@ fn test_rsa_encrypt_decrypt() {
|
||||
#[test]
|
||||
#[cfg(all(sha256, random, rsa_pss))]
|
||||
fn test_rsa_pss() {
|
||||
let mut rng = RNG::new().expect("Error creating RNG");
|
||||
let rng = Rc::new(RNG::new().expect("Error creating RNG"));
|
||||
|
||||
let key_path = "../../../certs/client-key.der";
|
||||
let der: Vec<u8> = fs::read(key_path).expect("Error reading key file");
|
||||
let mut rsa = RSA::new_from_der(&der).expect("Error with new_from_der()");
|
||||
let msg: &[u8] = b"This is the string to be signed!";
|
||||
let mut signature: [u8; 512] = [0; 512];
|
||||
let sig_len = rsa.pss_sign(msg, &mut signature, RSA::HASH_TYPE_SHA256, RSA::MGF1SHA256, &mut rng).expect("Error with pss_sign()");
|
||||
let sig_len = rsa.pss_sign(msg, &mut signature, RSA::HASH_TYPE_SHA256, RSA::MGF1SHA256, &rng).expect("Error with pss_sign()");
|
||||
assert!(sig_len > 0 && sig_len <= 512);
|
||||
|
||||
let key_path = "../../../certs/client-keyPub.der";
|
||||
let der: Vec<u8> = fs::read(key_path).expect("Error reading key file");
|
||||
let mut rsa = RSA::new_public_from_der(&der).expect("Error with new_public_from_der()");
|
||||
rsa.set_rng(&mut rng).expect("Error with set_rng()");
|
||||
rsa.set_shared_rng(Rc::clone(&rng)).expect("Error with set_shared_rng()");
|
||||
let signature = &signature[0..sig_len];
|
||||
let mut verify_out: [u8; 512] = [0; 512];
|
||||
let verify_out_size = rsa.pss_verify(signature, &mut verify_out, RSA::HASH_TYPE_SHA256, RSA::MGF1SHA256).expect("Error with pss_verify()");
|
||||
@@ -108,7 +110,7 @@ fn test_rsa_pss() {
|
||||
#[test]
|
||||
#[cfg(rsa_direct)]
|
||||
fn test_rsa_direct() {
|
||||
let mut rng = RNG::new().expect("Error creating RNG");
|
||||
let rng = RNG::new().expect("Error creating RNG");
|
||||
|
||||
let key_path = "../../../certs/client-key.der";
|
||||
let der: Vec<u8> = fs::read(key_path).expect("Error reading key file");
|
||||
@@ -117,10 +119,10 @@ fn test_rsa_direct() {
|
||||
let mut plain = [0u8; 256];
|
||||
plain[..msg.len()].copy_from_slice(msg);
|
||||
let mut enc = [0u8; 256];
|
||||
let enc_len = rsa.rsa_direct(&plain, &mut enc, RSA::PRIVATE_ENCRYPT, &mut rng).expect("Error with rsa_direct()");
|
||||
let enc_len = rsa.rsa_direct(&plain, &mut enc, RSA::PRIVATE_ENCRYPT, &rng).expect("Error with rsa_direct()");
|
||||
assert_eq!(enc_len, 256);
|
||||
let mut plain_out = [0u8; 256];
|
||||
let dec_len = rsa.rsa_direct(&enc, &mut plain_out, RSA::PUBLIC_DECRYPT, &mut rng).expect("Error with rsa_direct()");
|
||||
let dec_len = rsa.rsa_direct(&enc, &mut plain_out, RSA::PUBLIC_DECRYPT, &rng).expect("Error with rsa_direct()");
|
||||
assert_eq!(dec_len, 256);
|
||||
assert_eq!(plain_out, plain);
|
||||
}
|
||||
@@ -128,20 +130,20 @@ fn test_rsa_direct() {
|
||||
#[test]
|
||||
#[cfg(random)]
|
||||
fn test_rsa_ssl() {
|
||||
let mut rng = RNG::new().expect("Error creating RNG");
|
||||
let rng = Rc::new(RNG::new().expect("Error creating RNG"));
|
||||
|
||||
let key_path = "../../../certs/client-key.der";
|
||||
let der: Vec<u8> = fs::read(key_path).expect("Error reading key file");
|
||||
let mut rsa = RSA::new_from_der(&der).expect("Error with new_from_der()");
|
||||
let msg: &[u8] = b"This is the string to be signed!";
|
||||
let mut signature: [u8; 512] = [0; 512];
|
||||
let sig_len = rsa.ssl_sign(msg, &mut signature, &mut rng).expect("Error with ssl_sign()");
|
||||
let sig_len = rsa.ssl_sign(msg, &mut signature, &rng).expect("Error with ssl_sign()");
|
||||
assert!(sig_len > 0 && sig_len <= 512);
|
||||
|
||||
let key_path = "../../../certs/client-keyPub.der";
|
||||
let der: Vec<u8> = fs::read(key_path).expect("Error reading key file");
|
||||
let mut rsa = RSA::new_public_from_der(&der).expect("Error with new_public_from_der()");
|
||||
rsa.set_rng(&mut rng).expect("Error with set_rng()");
|
||||
rsa.set_shared_rng(Rc::clone(&rng)).expect("Error with set_shared_rng()");
|
||||
let signature = &signature[0..sig_len];
|
||||
let mut verify_out: [u8; 512] = [0; 512];
|
||||
let verify_out_size = rsa.ssl_verify(signature, &mut verify_out).expect("Error with ssl_verify()");
|
||||
|
||||
Reference in New Issue
Block a user