Merge pull request #9594 from holtrop-wolfssl/rust-curve25519
Rust wrapper: add wolfssl_wolfcrypt::curve25519 module
This commit is contained in:
@@ -46,7 +46,7 @@ int wc_curve25519_make_key(WC_RNG* rng, int keysize, curve25519_key* key);
|
||||
|
||||
\brief This function computes 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 assigns the variable of the secret key to outlen. Only
|
||||
buffer out and assigns the length of the secret key to outlen. Only
|
||||
supports big endian.
|
||||
|
||||
\return 0 Returned on successfully computing a shared secret key.
|
||||
@@ -93,7 +93,7 @@ int wc_curve25519_shared_secret(curve25519_key* private_key,
|
||||
|
||||
\brief This function computes 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 assigns the variable of the secret key to outlen. Supports
|
||||
buffer out and assigns the length of the secret key to outlen. Supports
|
||||
both big and little endian.
|
||||
|
||||
\return 0 Returned on successfully computing a shared secret key.
|
||||
@@ -361,7 +361,7 @@ int wc_curve25519_import_private_raw_ex(const byte* priv, word32 privSz,
|
||||
\return 0 Returned on successfully exporting the private key from the
|
||||
curve25519_key structure.
|
||||
\return BAD_FUNC_ARG Returned if any input parameters are NULL.
|
||||
\return ECC_BAD_ARG_E Returned if wc_curve25519_size() is not equal to key.
|
||||
\return ECC_BAD_ARG_E Returned if *outLen is less than wc_curve25519_size().
|
||||
|
||||
\param [in] key Pointer to the structure from which to export the key.
|
||||
\param [out] out Pointer to the buffer in which to store the exported key.
|
||||
@@ -372,7 +372,7 @@ int wc_curve25519_import_private_raw_ex(const byte* priv, word32 privSz,
|
||||
\code
|
||||
int ret;
|
||||
byte priv[32];
|
||||
int privSz;
|
||||
word32 privSz;
|
||||
|
||||
curve25519_key key;
|
||||
// initialize and make key
|
||||
@@ -402,7 +402,7 @@ int wc_curve25519_export_private_raw(curve25519_key* key, byte* out,
|
||||
\return 0 Returned on successfully exporting the private key from the
|
||||
curve25519_key structure.
|
||||
\return BAD_FUNC_ARG Returned if any input parameters are NULL.
|
||||
\return ECC_BAD_ARG_E Returned if wc_curve25519_size() is not equal to key.
|
||||
\return ECC_BAD_ARG_E Returned if *outLen is less than wc_curve25519_size().
|
||||
|
||||
\param [in] key Pointer to the structure from which to export the key.
|
||||
\param [out] out Pointer to the buffer in which to store the exported key.
|
||||
@@ -416,7 +416,7 @@ int wc_curve25519_export_private_raw(curve25519_key* key, byte* out,
|
||||
int ret;
|
||||
|
||||
byte priv[32];
|
||||
int privSz;
|
||||
word32 privSz;
|
||||
curve25519_key key;
|
||||
// initialize and make key
|
||||
ret = wc_curve25519_export_private_raw_ex(&key, priv, &privSz,
|
||||
@@ -656,7 +656,7 @@ int wc_curve25519_export_public_ex(curve25519_key* key, byte* out,
|
||||
\return ECC_BAD_ARG_E Returned if privSz is less than CURVE25519_KEY_SIZE or
|
||||
pubSz is less than CURVE25519_PUB_KEY_SIZE.
|
||||
|
||||
\param [in] key Pointer to the curve448_key structure in from which to
|
||||
\param [in] key Pointer to the curve25519_key structure in from which to
|
||||
export the key pair.
|
||||
\param [out] priv Pointer to the buffer in which to store the private key.
|
||||
\param [in,out] privSz On in, is the size of the priv buffer in bytes.
|
||||
@@ -702,7 +702,7 @@ int wc_curve25519_export_key_raw(curve25519_key* key,
|
||||
\return ECC_BAD_ARG_E Returned if privSz is less than CURVE25519_KEY_SIZE or
|
||||
pubSz is less than CURVE25519_PUB_KEY_SIZE.
|
||||
|
||||
\param [in] key Pointer to the curve448_key structure in from which to
|
||||
\param [in] key Pointer to the curve25519_key structure in from which to
|
||||
export the key pair.
|
||||
\param [out] priv Pointer to the buffer in which to store the private key.
|
||||
\param [in,out] privSz On in, is the size of the priv buffer in bytes.
|
||||
@@ -725,7 +725,7 @@ int wc_curve25519_export_key_raw(curve25519_key* key,
|
||||
curve25519_key key;
|
||||
// initialize and make key
|
||||
|
||||
ret = wc_curve25519_export_key_raw_ex(&key,priv, &privSz, pub, &pubSz,
|
||||
ret = wc_curve25519_export_key_raw_ex(&key, priv, &privSz, pub, &pubSz,
|
||||
EC25519_BIG_ENDIAN);
|
||||
if (ret != 0) {
|
||||
// error exporting key
|
||||
|
||||
@@ -14,6 +14,7 @@ EXTRA_DIST += wrapper/rust/wolfssl-wolfcrypt/headers.h
|
||||
EXTRA_DIST += wrapper/rust/wolfssl-wolfcrypt/src/aes.rs
|
||||
EXTRA_DIST += wrapper/rust/wolfssl-wolfcrypt/src/blake2.rs
|
||||
EXTRA_DIST += wrapper/rust/wolfssl-wolfcrypt/src/cmac.rs
|
||||
EXTRA_DIST += wrapper/rust/wolfssl-wolfcrypt/src/curve25519.rs
|
||||
EXTRA_DIST += wrapper/rust/wolfssl-wolfcrypt/src/dh.rs
|
||||
EXTRA_DIST += wrapper/rust/wolfssl-wolfcrypt/src/ecc.rs
|
||||
EXTRA_DIST += wrapper/rust/wolfssl-wolfcrypt/src/ed25519.rs
|
||||
@@ -30,6 +31,7 @@ EXTRA_DIST += wrapper/rust/wolfssl-wolfcrypt/src/sys.rs
|
||||
EXTRA_DIST += wrapper/rust/wolfssl-wolfcrypt/tests/test_aes.rs
|
||||
EXTRA_DIST += wrapper/rust/wolfssl-wolfcrypt/tests/test_blake2.rs
|
||||
EXTRA_DIST += wrapper/rust/wolfssl-wolfcrypt/tests/test_cmac.rs
|
||||
EXTRA_DIST += wrapper/rust/wolfssl-wolfcrypt/tests/test_curve25519.rs
|
||||
EXTRA_DIST += wrapper/rust/wolfssl-wolfcrypt/tests/test_dh.rs
|
||||
EXTRA_DIST += wrapper/rust/wolfssl-wolfcrypt/tests/test_ecc.rs
|
||||
EXTRA_DIST += wrapper/rust/wolfssl-wolfcrypt/tests/test_ed25519.rs
|
||||
|
||||
@@ -133,6 +133,10 @@ fn scan_cfg() -> Result<()> {
|
||||
/* cmac */
|
||||
check_cfg(&binding, "wc_InitCmac", "cmac");
|
||||
|
||||
/* curve25519 */
|
||||
check_cfg(&binding, "wc_curve25519_make_pub", "curve25519");
|
||||
check_cfg(&binding, "wc_curve25519_make_pub_blind", "curve25519_blinding");
|
||||
|
||||
/* dh */
|
||||
check_cfg(&binding, "wc_InitDhKey", "dh");
|
||||
check_cfg(&binding, "wc_DhGenerateParams", "dh_keygen");
|
||||
|
||||
@@ -23,6 +23,8 @@ This module provides a Rust wrapper for the wolfCrypt library's BLAKE2
|
||||
functionality.
|
||||
*/
|
||||
|
||||
#![cfg(any(blake2b, blake2s))]
|
||||
|
||||
use crate::sys;
|
||||
use std::mem::MaybeUninit;
|
||||
|
||||
|
||||
668
wrapper/rust/wolfssl-wolfcrypt/src/curve25519.rs
Normal file
668
wrapper/rust/wolfssl-wolfcrypt/src/curve25519.rs
Normal file
@@ -0,0 +1,668 @@
|
||||
/*
|
||||
* Copyright (C) 2025 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
|
||||
*/
|
||||
|
||||
/*!
|
||||
This module provides a Rust wrapper for the wolfCrypt library's Curve25519
|
||||
functionality.
|
||||
*/
|
||||
|
||||
#![cfg(curve25519)]
|
||||
|
||||
#[cfg(random)]
|
||||
use crate::random::RNG;
|
||||
use crate::sys;
|
||||
use std::mem::MaybeUninit;
|
||||
|
||||
pub struct Curve25519Key {
|
||||
wc_key: sys::curve25519_key,
|
||||
}
|
||||
|
||||
impl Curve25519Key {
|
||||
/// Curve 25519 key size (32 bytes).
|
||||
pub const KEYSIZE: usize = sys::CURVE25519_KEYSIZE as usize;
|
||||
|
||||
/// Check that a public key buffer holds a valid Curve25519 key value
|
||||
/// given the endian ordering.
|
||||
///
|
||||
/// # Parameters
|
||||
///
|
||||
/// * `big_endian`: True for big-endian, false for little-endian.
|
||||
///
|
||||
/// # Returns
|
||||
///
|
||||
/// Returns either Ok(()) on success or Err(e) containing the wolfSSL
|
||||
/// library error code value.
|
||||
pub fn check_public(public: &[u8], big_endian: bool) -> Result<(), i32> {
|
||||
let public_size = public.len() as u32;
|
||||
let endian = if big_endian {sys::EC25519_BIG_ENDIAN} else {sys::EC25519_LITTLE_ENDIAN};
|
||||
let rc = unsafe {
|
||||
sys::wc_curve25519_check_public(public.as_ptr(), public_size,
|
||||
endian as i32)
|
||||
};
|
||||
if rc != 0 {
|
||||
return Err(rc);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Generate a new private key.
|
||||
///
|
||||
/// # Parameters
|
||||
///
|
||||
/// * `rng`: Random number generator struct to use for blinding operation.
|
||||
///
|
||||
/// # Returns
|
||||
///
|
||||
/// 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> {
|
||||
let mut wc_key: MaybeUninit<sys::curve25519_key> = MaybeUninit::uninit();
|
||||
let rc = unsafe {
|
||||
sys::wc_curve25519_init(wc_key.as_mut_ptr())
|
||||
};
|
||||
if rc != 0 {
|
||||
return Err(rc);
|
||||
}
|
||||
let wc_key = unsafe { wc_key.assume_init() };
|
||||
let mut curve25519key = Curve25519Key { wc_key };
|
||||
let rc = unsafe {
|
||||
sys::wc_curve25519_make_key(&mut rng.wc_rng, Self::KEYSIZE as i32,
|
||||
&mut curve25519key.wc_key)
|
||||
};
|
||||
if rc != 0 {
|
||||
return Err(rc);
|
||||
}
|
||||
Ok(curve25519key)
|
||||
}
|
||||
|
||||
/// Generate a new private key as a bare vector.
|
||||
///
|
||||
/// # Parameters
|
||||
///
|
||||
/// * `rng`: Random number generator struct to use for blinding operation.
|
||||
///
|
||||
/// # Returns
|
||||
///
|
||||
/// 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> {
|
||||
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())
|
||||
};
|
||||
if rc != 0 {
|
||||
return Err(rc);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Import a Curve25519 private key only (big-endian only).
|
||||
///
|
||||
/// # Parameters
|
||||
///
|
||||
/// * `private`: Buffer containing the Curve25519 private key.
|
||||
///
|
||||
/// # Returns
|
||||
///
|
||||
/// Returns either Ok(curve25519key) on success or Err(e) containing the
|
||||
/// wolfSSL library error code value.
|
||||
pub fn import_private(private: &[u8]) -> 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())
|
||||
};
|
||||
if rc != 0 {
|
||||
return Err(rc);
|
||||
}
|
||||
let wc_key = unsafe { wc_key.assume_init() };
|
||||
let mut curve25519key = Curve25519Key { wc_key };
|
||||
let private_size = private.len() as u32;
|
||||
let rc = unsafe {
|
||||
sys::wc_curve25519_import_private(private.as_ptr(), private_size,
|
||||
&mut curve25519key.wc_key)
|
||||
};
|
||||
if rc != 0 {
|
||||
return Err(rc);
|
||||
}
|
||||
Ok(curve25519key)
|
||||
}
|
||||
|
||||
/// Import a Curve25519 private key only (big or little endian).
|
||||
///
|
||||
/// # Parameters
|
||||
///
|
||||
/// * `private`: Buffer containing the Curve25519 private key.
|
||||
/// * `big_endian`: True for big-endian, false for little-endian.
|
||||
///
|
||||
/// # Returns
|
||||
///
|
||||
/// Returns either Ok(curve25519key) on success or Err(e) containing the
|
||||
/// wolfSSL library error code value.
|
||||
pub fn import_private_ex(private: &[u8], big_endian: bool) -> 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())
|
||||
};
|
||||
if rc != 0 {
|
||||
return Err(rc);
|
||||
}
|
||||
let wc_key = unsafe { wc_key.assume_init() };
|
||||
let mut curve25519key = Curve25519Key { wc_key };
|
||||
let private_size = private.len() as u32;
|
||||
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(),
|
||||
private_size, &mut curve25519key.wc_key, endian as i32)
|
||||
};
|
||||
if rc != 0 {
|
||||
return Err(rc);
|
||||
}
|
||||
Ok(curve25519key)
|
||||
}
|
||||
|
||||
/// Import a Curve25519 public/private key pair (big-endian only).
|
||||
///
|
||||
/// # Parameters
|
||||
///
|
||||
/// * `private`: Buffer containing the Curve25519 private key.
|
||||
/// * `public`: Buffer containing the Curve25519 public key.
|
||||
///
|
||||
/// # Returns
|
||||
///
|
||||
/// Returns either Ok(curve25519key) on success or Err(e) containing the
|
||||
/// wolfSSL library error code value.
|
||||
pub fn import_private_raw(private: &[u8], public: &[u8]) -> 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())
|
||||
};
|
||||
if rc != 0 {
|
||||
return Err(rc);
|
||||
}
|
||||
let wc_key = unsafe { wc_key.assume_init() };
|
||||
let mut curve25519key = Curve25519Key { wc_key };
|
||||
let private_size = private.len() as u32;
|
||||
let public_size = public.len() as u32;
|
||||
let rc = unsafe {
|
||||
sys::wc_curve25519_import_private_raw(private.as_ptr(),
|
||||
private_size, public.as_ptr(), public_size,
|
||||
&mut curve25519key.wc_key)
|
||||
};
|
||||
if rc != 0 {
|
||||
return Err(rc);
|
||||
}
|
||||
Ok(curve25519key)
|
||||
}
|
||||
|
||||
/// Import a Curve25519 public/private key pair (big or little endian).
|
||||
///
|
||||
/// # Parameters
|
||||
///
|
||||
/// * `private`: Buffer containing the Curve25519 private key.
|
||||
/// * `public`: Buffer containing the Curve25519 public key.
|
||||
/// * `big_endian`: True for big-endian, false for little-endian.
|
||||
///
|
||||
/// # Returns
|
||||
///
|
||||
/// Returns either Ok(curve25519key) on success or Err(e) containing the
|
||||
/// wolfSSL library error code value.
|
||||
pub fn import_private_raw_ex(private: &[u8], public: &[u8], big_endian: bool) -> 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())
|
||||
};
|
||||
if rc != 0 {
|
||||
return Err(rc);
|
||||
}
|
||||
let wc_key = unsafe { wc_key.assume_init() };
|
||||
let mut curve25519key = Curve25519Key { wc_key };
|
||||
let private_size = private.len() as u32;
|
||||
let public_size = public.len() as u32;
|
||||
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(),
|
||||
private_size, public.as_ptr(), public_size,
|
||||
&mut curve25519key.wc_key, endian as i32)
|
||||
};
|
||||
if rc != 0 {
|
||||
return Err(rc);
|
||||
}
|
||||
Ok(curve25519key)
|
||||
}
|
||||
|
||||
/// Import a Curve25519 public key (big-endian only).
|
||||
///
|
||||
/// # Parameters
|
||||
///
|
||||
/// * `public`: Buffer containing the Curve25519 public key.
|
||||
///
|
||||
/// # Returns
|
||||
///
|
||||
/// Returns either Ok(curve25519key) on success or Err(e) containing the
|
||||
/// wolfSSL library error code value.
|
||||
pub fn import_public(public: &[u8]) -> 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())
|
||||
};
|
||||
if rc != 0 {
|
||||
return Err(rc);
|
||||
}
|
||||
let wc_key = unsafe { wc_key.assume_init() };
|
||||
let mut curve25519key = Curve25519Key { wc_key };
|
||||
let public_size = public.len() as u32;
|
||||
let rc = unsafe {
|
||||
sys::wc_curve25519_import_public(public.as_ptr(), public_size,
|
||||
&mut curve25519key.wc_key)
|
||||
};
|
||||
if rc != 0 {
|
||||
return Err(rc);
|
||||
}
|
||||
Ok(curve25519key)
|
||||
}
|
||||
|
||||
/// Import a Curve25519 public key (big or little endian).
|
||||
///
|
||||
/// # Parameters
|
||||
///
|
||||
/// * `public`: Buffer containing the Curve25519 public key.
|
||||
/// * `big_endian`: True for big-endian, false for little-endian.
|
||||
///
|
||||
/// # Returns
|
||||
///
|
||||
/// Returns either Ok(curve25519key) on success or Err(e) containing the
|
||||
/// wolfSSL library error code value.
|
||||
pub fn import_public_ex(public: &[u8], big_endian: bool) -> 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())
|
||||
};
|
||||
if rc != 0 {
|
||||
return Err(rc);
|
||||
}
|
||||
let wc_key = unsafe { wc_key.assume_init() };
|
||||
let mut curve25519key = Curve25519Key { wc_key };
|
||||
let public_size = public.len() as u32;
|
||||
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,
|
||||
&mut curve25519key.wc_key, endian as i32)
|
||||
};
|
||||
if rc != 0 {
|
||||
return Err(rc);
|
||||
}
|
||||
Ok(curve25519key)
|
||||
}
|
||||
|
||||
/// Compute the public key from an existing private key using bare vectors.
|
||||
///
|
||||
/// # Parameters
|
||||
///
|
||||
/// * `private`: Private key (input).
|
||||
/// * `public`: Buffer in which to store the computed public key.
|
||||
///
|
||||
/// # Returns
|
||||
///
|
||||
/// Returns either Ok(()) on success or Err(e) containing the wolfSSL
|
||||
/// library error code value.
|
||||
pub fn make_pub(private: &[u8], public: &mut [u8]) -> Result<(), i32> {
|
||||
let private_size = private.len() as i32;
|
||||
let public_size = public.len() as i32;
|
||||
let rc = unsafe {
|
||||
sys::wc_curve25519_make_pub(public_size, public.as_mut_ptr(),
|
||||
private_size, private.as_ptr())
|
||||
};
|
||||
if rc != 0 {
|
||||
return Err(rc);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Compute the public key from an existing private key using bare vectors
|
||||
/// with blinding.
|
||||
///
|
||||
/// # Parameters
|
||||
///
|
||||
/// * `private`: Private key (input).
|
||||
/// * `public`: Buffer in which to store the computed public key.
|
||||
/// * `rng`: Random number generator struct to use for blinding operation.
|
||||
///
|
||||
/// # Returns
|
||||
///
|
||||
/// 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> {
|
||||
let private_size = private.len() as i32;
|
||||
let public_size = public.len() as i32;
|
||||
let rc = unsafe {
|
||||
sys::wc_curve25519_make_pub_blind(public_size, public.as_mut_ptr(),
|
||||
private_size, private.as_ptr(), &mut rng.wc_rng)
|
||||
};
|
||||
if rc != 0 {
|
||||
return Err(rc);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Compute the public key from an existing private key with supplied
|
||||
/// basepoint, using bare vectors.
|
||||
///
|
||||
/// # Parameters
|
||||
///
|
||||
/// * `private`: Private key (input).
|
||||
/// * `public`: Buffer in which to store the computed public key.
|
||||
/// * `basepoint`: Basepoint value to use.
|
||||
///
|
||||
/// # Returns
|
||||
///
|
||||
/// Returns either Ok(()) on success or Err(e) containing the wolfSSL
|
||||
/// library error code value.
|
||||
pub fn make_pub_generic(private: &[u8], public: &mut [u8], basepoint: &[u8]) -> Result<(), i32> {
|
||||
let private_size = private.len() as i32;
|
||||
let public_size = public.len() as i32;
|
||||
let basepoint_size = basepoint.len() as i32;
|
||||
let rc = unsafe {
|
||||
sys::wc_curve25519_generic(public_size, public.as_mut_ptr(),
|
||||
private_size, private.as_ptr(), basepoint_size, basepoint.as_ptr())
|
||||
};
|
||||
if rc != 0 {
|
||||
return Err(rc);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Compute the public key from an existing private key with supplied
|
||||
/// basepoint, using bare vectors.
|
||||
///
|
||||
/// # Parameters
|
||||
///
|
||||
/// * `private`: Private key (input).
|
||||
/// * `public`: Buffer in which to store the computed public key.
|
||||
/// * `basepoint`: Basepoint value to use.
|
||||
/// * `rng`: Random number generator struct to use for blinding operation.
|
||||
///
|
||||
/// # Returns
|
||||
///
|
||||
/// 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> {
|
||||
let private_size = private.len() as i32;
|
||||
let public_size = public.len() as i32;
|
||||
let basepoint_size = basepoint.len() as i32;
|
||||
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)
|
||||
};
|
||||
if rc != 0 {
|
||||
return Err(rc);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// 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. Only supports big endian.
|
||||
///
|
||||
/// # Parameters
|
||||
///
|
||||
/// * `private_key`: Curve25519Key struct holding the user's private key.
|
||||
/// * `public_key`: Curve25519Key struct holding the received public key.
|
||||
/// * `out`: Output buffer in which to store the generated secret key.
|
||||
///
|
||||
/// # Returns
|
||||
///
|
||||
/// Returns either Ok(size) containing the number of bytes written to `out`
|
||||
/// on success or Err(e) containing the wolfSSL library error code value.
|
||||
pub fn shared_secret(private_key: &mut Curve25519Key, public_key: &mut Curve25519Key, out: &mut [u8]) -> Result<usize, i32> {
|
||||
let mut outlen = out.len() as u32;
|
||||
let rc = unsafe {
|
||||
sys::wc_curve25519_shared_secret(&mut private_key.wc_key,
|
||||
&mut public_key.wc_key, out.as_mut_ptr(), &mut outlen)
|
||||
};
|
||||
if rc != 0 {
|
||||
return Err(rc);
|
||||
}
|
||||
Ok(outlen as usize)
|
||||
}
|
||||
|
||||
/// Associates a `RNG` instance with this `Curve25519Key` instance.
|
||||
///
|
||||
/// This is necessary when generating a shared secret if wolfSSL is built
|
||||
/// with the `WOLFSSL_CURVE25519_BLINDING` build option enabled.
|
||||
///
|
||||
/// # 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.
|
||||
///
|
||||
/// # 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> {
|
||||
let rc = unsafe {
|
||||
sys::wc_curve25519_set_rng(&mut self.wc_key, &mut rng.wc_rng)
|
||||
};
|
||||
if rc != 0 {
|
||||
return Err(rc);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// 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.
|
||||
///
|
||||
/// # Parameters
|
||||
///
|
||||
/// * `private_key`: Curve25519Key struct holding the user's private key.
|
||||
/// * `public_key`: Curve25519Key struct holding the received public key.
|
||||
/// * `out`: Output buffer in which to store the generated secret key.
|
||||
/// * `big_endian`: True for big-endian, false for little-endian.
|
||||
///
|
||||
/// # Returns
|
||||
///
|
||||
/// Returns either Ok(size) containing the number of bytes written to `out`
|
||||
/// on success or Err(e) containing the wolfSSL library error code value.
|
||||
pub fn shared_secret_ex(private_key: &mut Curve25519Key, public_key: &mut Curve25519Key, out: &mut [u8], big_endian: bool) -> Result<usize, i32> {
|
||||
let mut outlen = out.len() as u32;
|
||||
let endian = if big_endian {sys::EC25519_BIG_ENDIAN} else {sys::EC25519_LITTLE_ENDIAN};
|
||||
let rc = unsafe {
|
||||
sys::wc_curve25519_shared_secret_ex(&mut private_key.wc_key,
|
||||
&mut public_key.wc_key, out.as_mut_ptr(), &mut outlen, endian as i32)
|
||||
};
|
||||
if rc != 0 {
|
||||
return Err(rc);
|
||||
}
|
||||
Ok(outlen as usize)
|
||||
}
|
||||
|
||||
/// Export public and private keys from Curve25519Key struct to raw buffers
|
||||
/// (big-endian only).
|
||||
///
|
||||
/// # Parameters
|
||||
///
|
||||
/// * `private`: Buffer in which to store the raw private key.
|
||||
/// * `public`: Buffer in which to store the raw public key.
|
||||
///
|
||||
/// # Returns
|
||||
///
|
||||
/// Returns either Ok(()) on success or Err(e) containing the wolfSSL
|
||||
/// library error code value.
|
||||
pub fn export_key_raw(&mut self, private: &mut [u8], public: &mut [u8]) -> Result<(), i32> {
|
||||
let mut private_size = private.len() as u32;
|
||||
let mut public_size = public.len() as u32;
|
||||
let rc = unsafe {
|
||||
sys::wc_curve25519_export_key_raw(&mut self.wc_key,
|
||||
private.as_mut_ptr(), &mut private_size,
|
||||
public.as_mut_ptr(), &mut public_size)
|
||||
};
|
||||
if rc != 0 {
|
||||
return Err(rc);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Export public and private keys from Curve25519Key struct to raw buffers
|
||||
/// (big or little endian).
|
||||
///
|
||||
/// # Parameters
|
||||
///
|
||||
/// * `private`: Buffer in which to store the raw private key.
|
||||
/// * `public`: Buffer in which to store the raw public key.
|
||||
/// * `big_endian`: True for big-endian, false for little-endian.
|
||||
///
|
||||
/// # Returns
|
||||
///
|
||||
/// Returns either Ok(()) on success or Err(e) containing the wolfSSL
|
||||
/// library error code value.
|
||||
pub fn export_key_raw_ex(&mut self, private: &mut [u8], public: &mut [u8], big_endian: bool) -> Result<(), i32> {
|
||||
let mut private_size = private.len() as u32;
|
||||
let mut public_size = public.len() as u32;
|
||||
let endian = if big_endian {sys::EC25519_BIG_ENDIAN} else {sys::EC25519_LITTLE_ENDIAN};
|
||||
let rc = unsafe {
|
||||
sys::wc_curve25519_export_key_raw_ex(&mut self.wc_key,
|
||||
private.as_mut_ptr(), &mut private_size,
|
||||
public.as_mut_ptr(), &mut public_size, endian as i32)
|
||||
};
|
||||
if rc != 0 {
|
||||
return Err(rc);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Export private key from Curve25519Key struct to a raw buffer
|
||||
/// (big-endian only).
|
||||
///
|
||||
/// # Parameters
|
||||
///
|
||||
/// * `out`: Buffer in which to store the raw private key.
|
||||
///
|
||||
/// # Returns
|
||||
///
|
||||
/// Returns either Ok(size) containing the number of bytes written to `out`
|
||||
/// on success or Err(e) containing the wolfSSL library error code value.
|
||||
pub fn export_private_raw(&mut self, out: &mut [u8]) -> Result<usize, i32> {
|
||||
let mut outlen = out.len() as u32;
|
||||
let rc = unsafe {
|
||||
sys::wc_curve25519_export_private_raw(&mut self.wc_key,
|
||||
out.as_mut_ptr(), &mut outlen)
|
||||
};
|
||||
if rc != 0 {
|
||||
return Err(rc);
|
||||
}
|
||||
Ok(outlen as usize)
|
||||
}
|
||||
|
||||
/// Export private key from Curve25519Key struct to a raw buffer
|
||||
/// (big or little endian).
|
||||
///
|
||||
/// # Parameters
|
||||
///
|
||||
/// * `out`: Buffer in which to store the raw private key.
|
||||
/// * `big_endian`: True for big-endian, false for little-endian.
|
||||
///
|
||||
/// # Returns
|
||||
///
|
||||
/// Returns either Ok(size) containing the number of bytes written to `out`
|
||||
/// on success or Err(e) containing the wolfSSL library error code value.
|
||||
pub fn export_private_raw_ex(&mut self, out: &mut [u8], big_endian: bool) -> Result<usize, i32> {
|
||||
let mut outlen = out.len() as u32;
|
||||
let endian = if big_endian {sys::EC25519_BIG_ENDIAN} else {sys::EC25519_LITTLE_ENDIAN};
|
||||
let rc = unsafe {
|
||||
sys::wc_curve25519_export_private_raw_ex(&mut self.wc_key,
|
||||
out.as_mut_ptr(), &mut outlen, endian as i32)
|
||||
};
|
||||
if rc != 0 {
|
||||
return Err(rc);
|
||||
}
|
||||
Ok(outlen as usize)
|
||||
}
|
||||
|
||||
/// Export public key from Curve25519Key struct to a raw buffer
|
||||
/// (big-endian only).
|
||||
///
|
||||
/// # Parameters
|
||||
///
|
||||
/// * `out`: Buffer in which to store the raw public key.
|
||||
///
|
||||
/// # Returns
|
||||
///
|
||||
/// Returns either Ok(size) containing the number of bytes written to `out`
|
||||
/// on success or Err(e) containing the wolfSSL library error code value.
|
||||
pub fn export_public(&mut self, out: &mut [u8]) -> Result<usize, i32> {
|
||||
let mut outlen = out.len() as u32;
|
||||
let rc = unsafe {
|
||||
sys::wc_curve25519_export_public(&mut self.wc_key,
|
||||
out.as_mut_ptr(), &mut outlen)
|
||||
};
|
||||
if rc != 0 {
|
||||
return Err(rc);
|
||||
}
|
||||
Ok(outlen as usize)
|
||||
}
|
||||
|
||||
/// Export public key from Curve25519Key struct to a raw buffer
|
||||
/// (big or little endian).
|
||||
///
|
||||
/// # Parameters
|
||||
///
|
||||
/// * `out`: Buffer in which to store the raw public key.
|
||||
/// * `big_endian`: True for big-endian, false for little-endian.
|
||||
///
|
||||
/// # Returns
|
||||
///
|
||||
/// Returns either Ok(size) containing the number of bytes written to `out`
|
||||
/// on success or Err(e) containing the wolfSSL library error code value.
|
||||
pub fn export_public_ex(&mut self, out: &mut [u8], big_endian: bool) -> Result<usize, i32> {
|
||||
let mut outlen = out.len() as u32;
|
||||
let endian = if big_endian {sys::EC25519_BIG_ENDIAN} else {sys::EC25519_LITTLE_ENDIAN};
|
||||
let rc = unsafe {
|
||||
sys::wc_curve25519_export_public_ex(&mut self.wc_key,
|
||||
out.as_mut_ptr(), &mut outlen, endian as i32)
|
||||
};
|
||||
if rc != 0 {
|
||||
return Err(rc);
|
||||
}
|
||||
Ok(outlen as usize)
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for Curve25519Key {
|
||||
/// Safely free the underlying wolfSSL Curve25519Key context.
|
||||
///
|
||||
/// This calls the `wc_curve25519_free` wolfssl library function.
|
||||
///
|
||||
/// The Rust Drop trait guarantees that this method is called when the
|
||||
/// struct goes out of scope, automatically cleaning up resources and
|
||||
/// preventing memory leaks.
|
||||
fn drop(&mut self) {
|
||||
unsafe { sys::wc_curve25519_free(&mut self.wc_key); }
|
||||
}
|
||||
}
|
||||
@@ -24,6 +24,7 @@ pub mod sys;
|
||||
pub mod aes;
|
||||
pub mod blake2;
|
||||
pub mod cmac;
|
||||
pub mod curve25519;
|
||||
pub mod dh;
|
||||
pub mod ecc;
|
||||
pub mod ed25519;
|
||||
|
||||
146
wrapper/rust/wolfssl-wolfcrypt/tests/test_curve25519.rs
Normal file
146
wrapper/rust/wolfssl-wolfcrypt/tests/test_curve25519.rs
Normal file
@@ -0,0 +1,146 @@
|
||||
#![cfg(all(curve25519, random))]
|
||||
|
||||
use wolfssl_wolfcrypt::curve25519::*;
|
||||
use wolfssl_wolfcrypt::random::RNG;
|
||||
|
||||
#[test]
|
||||
fn test_check_pub() {
|
||||
let mut rng = RNG::new().expect("Error with new()");
|
||||
let mut private_buffer = [0u8; Curve25519Key::KEYSIZE];
|
||||
Curve25519Key::generate_priv(&mut rng, &mut private_buffer).expect("Error with generate_priv()");
|
||||
let mut public_buffer = [0u8; Curve25519Key::KEYSIZE];
|
||||
Curve25519Key::make_pub(&private_buffer, &mut public_buffer).expect("Error with make_pub()");
|
||||
Curve25519Key::check_public(&public_buffer, false).expect("Error with check_public()");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_generate_priv() {
|
||||
let mut rng = RNG::new().expect("Error with new()");
|
||||
let mut private_buffer = [0u8; Curve25519Key::KEYSIZE];
|
||||
Curve25519Key::generate_priv(&mut rng, &mut private_buffer).expect("Error with generate_priv()");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_import_export_private() {
|
||||
let mut rng = RNG::new().expect("Error with new()");
|
||||
let mut curve25519key = Curve25519Key::generate(&mut rng).expect("Error with generate()");
|
||||
let mut private_buffer = [0u8; Curve25519Key::KEYSIZE];
|
||||
curve25519key.export_private_raw(&mut private_buffer).expect("Error with export_private_raw()");
|
||||
Curve25519Key::import_private(&private_buffer).expect("Error with import_private()");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_import_export_private_ex() {
|
||||
let mut rng = RNG::new().expect("Error with new()");
|
||||
let mut curve25519key = Curve25519Key::generate(&mut rng).expect("Error with generate()");
|
||||
let mut private_buffer = [0u8; Curve25519Key::KEYSIZE];
|
||||
curve25519key.export_private_raw_ex(&mut private_buffer, false).expect("Error with export_private_raw_ex()");
|
||||
Curve25519Key::import_private_ex(&private_buffer, false).expect("Error with import_private_ex()");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_import_export_raw() {
|
||||
let mut rng = RNG::new().expect("Error with new()");
|
||||
let mut curve25519key = Curve25519Key::generate(&mut rng).expect("Error with generate()");
|
||||
let mut private_buffer = [0u8; Curve25519Key::KEYSIZE];
|
||||
let mut public_buffer = [0u8; Curve25519Key::KEYSIZE];
|
||||
curve25519key.export_key_raw(&mut private_buffer, &mut public_buffer).expect("Error with export_key_raw()");
|
||||
Curve25519Key::import_private_raw(&private_buffer, &public_buffer).expect("Error with import_private_raw()");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_import_export_raw_ex() {
|
||||
let mut rng = RNG::new().expect("Error with new()");
|
||||
let mut curve25519key = Curve25519Key::generate(&mut rng).expect("Error with generate()");
|
||||
let mut private_buffer = [0u8; Curve25519Key::KEYSIZE];
|
||||
let mut public_buffer = [0u8; Curve25519Key::KEYSIZE];
|
||||
curve25519key.export_key_raw_ex(&mut private_buffer, &mut public_buffer, false).expect("Error with export_key_raw_ex()");
|
||||
Curve25519Key::import_private_raw_ex(&private_buffer, &public_buffer, false).expect("Error with import_private_raw_ex()");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_import_export_public() {
|
||||
let mut rng = RNG::new().expect("Error with new()");
|
||||
let mut curve25519key = Curve25519Key::generate(&mut rng).expect("Error with generate()");
|
||||
let mut public_buffer = [0u8; Curve25519Key::KEYSIZE];
|
||||
curve25519key.export_public(&mut public_buffer).expect("Error with export_public()");
|
||||
Curve25519Key::import_public(&public_buffer).expect("Error with import_public()");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_import_export_public_ex() {
|
||||
let mut rng = RNG::new().expect("Error with new()");
|
||||
let mut curve25519key = Curve25519Key::generate(&mut rng).expect("Error with generate()");
|
||||
let mut public_buffer = [0u8; Curve25519Key::KEYSIZE];
|
||||
curve25519key.export_public_ex(&mut public_buffer, false).expect("Error with export_public_ex()");
|
||||
Curve25519Key::import_public_ex(&public_buffer, false).expect("Error with import_public_ex()");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_make_pub() {
|
||||
let mut rng = RNG::new().expect("Error with new()");
|
||||
let mut private_buffer = [0u8; Curve25519Key::KEYSIZE];
|
||||
Curve25519Key::generate_priv(&mut rng, &mut private_buffer).expect("Error with generate_priv()");
|
||||
let mut public_buffer = [0u8; Curve25519Key::KEYSIZE];
|
||||
Curve25519Key::make_pub(&private_buffer, &mut public_buffer).expect("Error with make_pub()");
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(curve25519_blinding)]
|
||||
fn test_make_pub_blind() {
|
||||
let mut rng = RNG::new().expect("Error with new()");
|
||||
let mut private_buffer = [0u8; Curve25519Key::KEYSIZE];
|
||||
Curve25519Key::generate_priv(&mut rng, &mut private_buffer).expect("Error with generate_priv()");
|
||||
let mut public_buffer = [0u8; Curve25519Key::KEYSIZE];
|
||||
Curve25519Key::make_pub_blind(&private_buffer, &mut public_buffer, &mut rng).expect("Error with 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)]
|
||||
key1.set_rng(&mut rng).expect("Error with set_rng()");
|
||||
#[cfg(curve25519_blinding)]
|
||||
key2.set_rng(&mut rng).expect("Error with set_rng()");
|
||||
|
||||
let mut public_buffer = [0u8; Curve25519Key::KEYSIZE];
|
||||
key1.export_public(&mut public_buffer).expect("Error with export_public()");
|
||||
let mut key1public = Curve25519Key::import_public(&public_buffer).expect("Error with import_public()");
|
||||
key2.export_public(&mut public_buffer).expect("Error with export_public()");
|
||||
let mut key2public = Curve25519Key::import_public(&public_buffer).expect("Error with import_public()");
|
||||
|
||||
let mut ss1 = [0u8; Curve25519Key::KEYSIZE];
|
||||
let mut ss2 = [0u8; Curve25519Key::KEYSIZE];
|
||||
Curve25519Key::shared_secret(&mut key1, &mut key2public, &mut ss1).expect("Error with shared_secret()");
|
||||
Curve25519Key::shared_secret(&mut key2, &mut key1public, &mut ss2).expect("Error with shared_secret()");
|
||||
|
||||
assert_eq!(ss1, ss2);
|
||||
}
|
||||
|
||||
#[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)]
|
||||
key1.set_rng(&mut rng).expect("Error with set_rng()");
|
||||
#[cfg(curve25519_blinding)]
|
||||
key2.set_rng(&mut rng).expect("Error with set_rng()");
|
||||
|
||||
let mut public_buffer = [0u8; Curve25519Key::KEYSIZE];
|
||||
key1.export_public(&mut public_buffer).expect("Error with export_public()");
|
||||
let mut key1public = Curve25519Key::import_public(&public_buffer).expect("Error with import_public()");
|
||||
key2.export_public(&mut public_buffer).expect("Error with export_public()");
|
||||
let mut key2public = Curve25519Key::import_public(&public_buffer).expect("Error with import_public()");
|
||||
|
||||
let mut ss1 = [0u8; Curve25519Key::KEYSIZE];
|
||||
let mut ss2 = [0u8; Curve25519Key::KEYSIZE];
|
||||
Curve25519Key::shared_secret_ex(&mut key1, &mut key2public, &mut ss1, false).expect("Error with shared_secret()");
|
||||
Curve25519Key::shared_secret_ex(&mut key2, &mut key1public, &mut ss2, false).expect("Error with shared_secret()");
|
||||
|
||||
assert_eq!(ss1, ss2);
|
||||
}
|
||||
Reference in New Issue
Block a user