mirror of
https://github.com/wolfSSL/wolfssl.git
synced 2026-01-26 09:32:43 +01:00
Rust wrapper: add wolfssl::wolfcrypt::ecc module
This commit is contained in:
@@ -122,7 +122,7 @@ int wc_ecc_make_key_ex(WC_RNG* rng, int keysize, ecc_key* key, int curve_id);
|
||||
slot.
|
||||
|
||||
\return 0 Returned on success.
|
||||
\return ECC_BAD_ARG_E Returned if rng or key evaluate to NULL
|
||||
\return ECC_BAD_ARG_E Returned if key is NULL
|
||||
\return BAD_FUNC_ARG Returned if the supplied key is not a valid ecc_key.
|
||||
\return MEMORY_E Returned if there is an error allocating memory while
|
||||
computing the public key
|
||||
@@ -172,11 +172,10 @@ int wc_ecc_make_pub(ecc_key* key, ecc_point* pubOut);
|
||||
an existing private component. If pubOut is supplied, the computed public
|
||||
key is stored there, else it is stored in the supplied ecc_key public
|
||||
component slot. The supplied rng, if non-NULL, is used to blind the private
|
||||
key value used in the computation. If rng is NULL, an ephemeral rng is
|
||||
instantiated internally.
|
||||
key value used in the computation.
|
||||
|
||||
\return 0 Returned on success.
|
||||
\return ECC_BAD_ARG_E Returned if rng or key evaluate to NULL
|
||||
\return ECC_BAD_ARG_E Returned if key is NULL
|
||||
\return BAD_FUNC_ARG Returned if the supplied key is not a valid ecc_key.
|
||||
\return MEMORY_E Returned if there is an error allocating memory while
|
||||
computing the public key
|
||||
|
||||
@@ -4083,7 +4083,9 @@ int wc_ecc_mulmod(const mp_int* k, ecc_point *G, ecc_point *R, mp_int* a,
|
||||
/**
|
||||
* Allocate a new ECC point (if one not provided)
|
||||
* use a heap hint when creating new ecc_point
|
||||
* return an allocated point on success or NULL on failure
|
||||
* @return 0 on success
|
||||
* @return BAD_FUNC_ARG for invalid arguments
|
||||
* @return MEMORY_E on failure to allocate memory
|
||||
*/
|
||||
static int wc_ecc_new_point_ex(ecc_point** point, void* heap)
|
||||
{
|
||||
@@ -11811,15 +11813,14 @@ static int wc_ecc_import_raw_private(ecc_key* key, const char* qx,
|
||||
qy y component of the public key, as ASCII hex string
|
||||
d private key, as ASCII hex string, optional if importing public
|
||||
key only
|
||||
dp Custom ecc_set_type
|
||||
return MP_OKAY on success
|
||||
curve_id The id of the curve.
|
||||
@return MP_OKAY on success
|
||||
*/
|
||||
int wc_ecc_import_raw_ex(ecc_key* key, const char* qx, const char* qy,
|
||||
const char* d, int curve_id)
|
||||
{
|
||||
return wc_ecc_import_raw_private(key, qx, qy, d, curve_id,
|
||||
WC_TYPE_HEX_STR);
|
||||
|
||||
}
|
||||
|
||||
/* Import x, y and optional private (d) as unsigned binary */
|
||||
|
||||
@@ -17,8 +17,10 @@ EXTRA_DIST += wrapper/rust/wolfssl/build.rs
|
||||
EXTRA_DIST += wrapper/rust/wolfssl/src/lib.rs
|
||||
EXTRA_DIST += wrapper/rust/wolfssl/src/wolfcrypt.rs
|
||||
EXTRA_DIST += wrapper/rust/wolfssl/src/wolfcrypt/aes.rs
|
||||
EXTRA_DIST += wrapper/rust/wolfssl/src/wolfcrypt/ecc.rs
|
||||
EXTRA_DIST += wrapper/rust/wolfssl/src/wolfcrypt/random.rs
|
||||
EXTRA_DIST += wrapper/rust/wolfssl/src/wolfcrypt/rsa.rs
|
||||
EXTRA_DIST += wrapper/rust/wolfssl/tests/test_aes.rs
|
||||
EXTRA_DIST += wrapper/rust/wolfssl/tests/test_ecc.rs
|
||||
EXTRA_DIST += wrapper/rust/wolfssl/tests/test_random.rs
|
||||
EXTRA_DIST += wrapper/rust/wolfssl/tests/test_rsa.rs
|
||||
|
||||
@@ -19,5 +19,6 @@
|
||||
*/
|
||||
|
||||
pub mod aes;
|
||||
pub mod ecc;
|
||||
pub mod random;
|
||||
pub mod rsa;
|
||||
|
||||
1613
wrapper/rust/wolfssl/src/wolfcrypt/ecc.rs
Normal file
1613
wrapper/rust/wolfssl/src/wolfcrypt/ecc.rs
Normal file
File diff suppressed because it is too large
Load Diff
267
wrapper/rust/wolfssl/tests/test_ecc.rs
Normal file
267
wrapper/rust/wolfssl/tests/test_ecc.rs
Normal file
@@ -0,0 +1,267 @@
|
||||
use std::fs;
|
||||
use wolfssl::wolfcrypt::ecc::*;
|
||||
use wolfssl::wolfcrypt::random::RNG;
|
||||
|
||||
#[test]
|
||||
fn test_ecc_generate() {
|
||||
let mut rng = RNG::new().expect("Failed to create RNG");
|
||||
let mut ecc = ECC::generate(32, &mut rng).expect("Error with generate()");
|
||||
ecc.check().expect("Error with check()");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_ecc_generate_ex() {
|
||||
let mut rng = RNG::new().expect("Failed to create RNG");
|
||||
let curve_id = ECC::SECP256R1;
|
||||
let curve_size = ECC::get_curve_size_from_id(curve_id).expect("Error with get_curve_size_from_id()");
|
||||
assert_eq!(curve_size, 32);
|
||||
let mut ecc = ECC::generate_ex(curve_size, &mut rng, curve_id).expect("Error with generate_ex()");
|
||||
ecc.check().expect("Error with check()");
|
||||
|
||||
let mut x963 = [0u8; 128];
|
||||
let x963_size = ecc.export_x963(&mut x963).expect("Error with export_x963()");
|
||||
let x963 = &x963[0..x963_size];
|
||||
let mut ecc = ECC::import_x963_ex(x963, ECC::SECP256R1).expect("Error with import_x963_ex");
|
||||
ecc.check().expect("Error with check()");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_ecc_generate_ex2() {
|
||||
let mut rng = RNG::new().expect("Failed to create RNG");
|
||||
let curve_id = ECC::SECP256R1;
|
||||
let curve_size = ECC::get_curve_size_from_id(curve_id).expect("Error with get_curve_size_from_id()");
|
||||
assert_eq!(curve_size, 32);
|
||||
let mut ecc = ECC::generate_ex2(curve_size, &mut rng, curve_id, ECC::FLAG_COFACTOR).expect("Error with generate_ex2()");
|
||||
ecc.check().expect("Error with check()");
|
||||
}
|
||||
|
||||
fn bytes_to_asciiz_hex_string(bytes: &[u8]) -> String {
|
||||
let mut hex_string = String::with_capacity(bytes.len() * 2 + 1);
|
||||
for byte in bytes {
|
||||
hex_string.push_str(&format!("{:02X}", byte));
|
||||
}
|
||||
hex_string.push('\0');
|
||||
hex_string
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_ecc_import_export_sign_verify() {
|
||||
let mut rng = RNG::new().expect("Failed to create RNG");
|
||||
let key_path = "../../../certs/ecc-client-key.der";
|
||||
let der: Vec<u8> = fs::read(key_path).expect("Error reading key file");
|
||||
let mut ecc = ECC::import_der(&der).expect("Error with import_der()");
|
||||
let hash = [0x42u8; 32];
|
||||
let mut signature = [0u8; 128];
|
||||
let signature_length = ecc.sign_hash(&hash, &mut signature, &mut rng).expect("Error with sign_hash()");
|
||||
assert!(signature_length > 0 && signature_length <= signature.len());
|
||||
|
||||
let signature = &mut signature[0..signature_length];
|
||||
let key_path = "../../../certs/ecc-client-keyPub.der";
|
||||
let der: Vec<u8> = fs::read(key_path).expect("Error reading key file");
|
||||
let mut ecc = ECC::import_public_der(&der).expect("Error with import_public_der()");
|
||||
let valid = ecc.verify_hash(&signature, &hash).expect("Error with verify_hash()");
|
||||
assert_eq!(valid, true);
|
||||
|
||||
let mut x963 = [0u8; 128];
|
||||
let x963_size = ecc.export_x963(&mut x963).expect("Error with export_x963()");
|
||||
let x963 = &x963[0..x963_size];
|
||||
let mut ecc = ECC::import_x963(x963).expect("Error with import_x963");
|
||||
let valid = ecc.verify_hash(&signature, &hash).expect("Error with verify_hash()");
|
||||
assert_eq!(valid, true);
|
||||
|
||||
let mut x963 = [0u8; 128];
|
||||
let x963_size = ecc.export_x963_compressed(&mut x963).expect("Error with export_x963_compressed()");
|
||||
let x963 = &x963[0..x963_size];
|
||||
let mut ecc = ECC::import_x963(x963).expect("Error with import_x963");
|
||||
let valid = ecc.verify_hash(&signature, &hash).expect("Error with verify_hash()");
|
||||
assert_eq!(valid, true);
|
||||
|
||||
let mut r = [0u8; 32];
|
||||
let mut r_size = 0u32;
|
||||
let mut s = [0u8; 32];
|
||||
let mut s_size = 0u32;
|
||||
ECC::sig_to_rs(signature, &mut r, &mut r_size, &mut s, &mut s_size).expect("Error with sig_to_rs()");
|
||||
assert_eq!(r_size, 32);
|
||||
assert_eq!(s_size, 32);
|
||||
let r = &r[0..r_size as usize];
|
||||
let s = &s[0..s_size as usize];
|
||||
let mut sig_out = [0u8; 128];
|
||||
let sig_out_size = ECC::rs_bin_to_sig(r, s, &mut sig_out).expect("Error with rs_bin_to_sig()");
|
||||
assert_eq!(*signature, *&sig_out[0..sig_out_size]);
|
||||
|
||||
let r_hex_string = bytes_to_asciiz_hex_string(r);
|
||||
let s_hex_string = bytes_to_asciiz_hex_string(s);
|
||||
let mut sig_out = [0u8; 128];
|
||||
let sig_out_size = ECC::rs_hex_to_sig(&r_hex_string[0..r_hex_string.len()].as_bytes(), &s_hex_string[0..s_hex_string.len()].as_bytes(), &mut sig_out).expect("Error with rs_hex_to_sig()");
|
||||
assert_eq!(*signature, *&sig_out[0..sig_out_size]);
|
||||
|
||||
signature[signature.len() - 2] = 0xDEu8;
|
||||
signature[signature.len() - 1] = 0xADu8;
|
||||
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()");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_ecc_shared_secret() {
|
||||
let mut rng = RNG::new().expect("Failed to create RNG");
|
||||
let mut ecc0 = ECC::generate(32, &mut rng).expect("Error with generate()");
|
||||
let mut ecc1 = ECC::generate(32, &mut rng).expect("Error with generate()");
|
||||
let mut ss0 = [0u8; 128];
|
||||
let mut ss1 = [0u8; 128];
|
||||
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);
|
||||
let ss0 = &ss0[0..ss0_size];
|
||||
let ss1 = &ss1[0..ss1_size];
|
||||
assert_eq!(*ss0, *ss1);
|
||||
|
||||
let mut ss0 = [0u8; 128];
|
||||
let ecc_point = ecc1.make_pub_to_point(None).expect("Error with make_pub_to_point()");
|
||||
let ss0_size = ecc0.shared_secret_ex(&ecc_point, &mut ss0).expect("Error with shared_secret_ex()");
|
||||
let ss0 = &ss0[0..ss0_size];
|
||||
assert_eq!(*ss0, *ss1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_ecc_export() {
|
||||
let mut rng = RNG::new().expect("Failed to create RNG");
|
||||
let mut ecc = ECC::generate(32, &mut rng).expect("Error with generate()");
|
||||
let mut qx = [0u8; 32];
|
||||
let mut qx_len = 0u32;
|
||||
let mut qy = [0u8; 32];
|
||||
let mut qy_len = 0u32;
|
||||
let mut d = [0u8; 32];
|
||||
let mut d_len = 0u32;
|
||||
ecc.export(&mut qx, &mut qx_len, &mut qy, &mut qy_len, &mut d, &mut d_len).expect("Error with export()");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_ecc_export_ex() {
|
||||
let mut rng = RNG::new().expect("Failed to create RNG");
|
||||
let mut ecc = ECC::generate(32, &mut rng).expect("Error with generate()");
|
||||
let mut qx = [0u8; 32];
|
||||
let mut qx_len = 0u32;
|
||||
let mut qy = [0u8; 32];
|
||||
let mut qy_len = 0u32;
|
||||
let mut d = [0u8; 32];
|
||||
let mut d_len = 0u32;
|
||||
ecc.export_ex(&mut qx, &mut qx_len, &mut qy, &mut qy_len, &mut d, &mut d_len, false).expect("Error with export_ex()");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_ecc_import_export_private() {
|
||||
let mut rng = RNG::new().expect("Failed to create RNG");
|
||||
let mut ecc = ECC::generate(32, &mut rng).expect("Error with generate()");
|
||||
let hash = [0x42u8; 32];
|
||||
let mut signature = [0u8; 128];
|
||||
let signature_length = ecc.sign_hash(&hash, &mut signature, &mut rng).expect("Error with sign_hash()");
|
||||
let signature = &signature[0..signature_length];
|
||||
|
||||
let mut d = [0u8; 32];
|
||||
let d_size = ecc.export_private(&mut d).expect("Error with export_private()");
|
||||
assert_eq!(d_size, 32);
|
||||
let mut x963 = [0u8; 128];
|
||||
let x963_size = ecc.export_x963(&mut x963).expect("Error with export_x963()");
|
||||
let x963 = &x963[0..x963_size];
|
||||
|
||||
let mut ecc2 = ECC::import_private_key(&d, x963).expect("Error with import_private_key()");
|
||||
let valid = ecc2.verify_hash(&signature, &hash).expect("Error with verify_hash()");
|
||||
assert_eq!(valid, true);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_ecc_import_export_private_ex() {
|
||||
let mut rng = RNG::new().expect("Failed to create RNG");
|
||||
let curve_id = ECC::SECP256R1;
|
||||
let curve_size = ECC::get_curve_size_from_id(curve_id).expect("Error with get_curve_size_from_id()");
|
||||
let mut ecc = ECC::generate_ex(curve_size, &mut rng, curve_id).expect("Error with generate_ex()");
|
||||
let hash = [0x42u8; 32];
|
||||
let mut signature = [0u8; 128];
|
||||
let signature_length = ecc.sign_hash(&hash, &mut signature, &mut rng).expect("Error with sign_hash()");
|
||||
let signature = &signature[0..signature_length];
|
||||
|
||||
let mut d = [0u8; 32];
|
||||
let d_size = ecc.export_private(&mut d).expect("Error with export_private()");
|
||||
assert_eq!(d_size, 32);
|
||||
let mut x963 = [0u8; 128];
|
||||
let x963_size = ecc.export_x963(&mut x963).expect("Error with export_x963()");
|
||||
let x963 = &x963[0..x963_size];
|
||||
|
||||
let mut ecc2 = ECC::import_private_key_ex(&d, x963, curve_id).expect("Error with import_private_key_ex()");
|
||||
let valid = ecc2.verify_hash(&signature, &hash).expect("Error with verify_hash()");
|
||||
assert_eq!(valid, true);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_ecc_export_public() {
|
||||
let mut rng = RNG::new().expect("Failed to create RNG");
|
||||
let mut ecc = ECC::generate(32, &mut rng).expect("Error with generate()");
|
||||
let mut qx = [0u8; 32];
|
||||
let mut qx_len = 0u32;
|
||||
let mut qy = [0u8; 32];
|
||||
let mut qy_len = 0u32;
|
||||
ecc.export_public(&mut qx, &mut qx_len, &mut qy, &mut qy_len).expect("Error with export_public()");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_ecc_import_unsigned() {
|
||||
let mut rng = RNG::new().expect("Failed to create RNG");
|
||||
let curve_id = ECC::SECP256R1;
|
||||
let curve_size = ECC::get_curve_size_from_id(curve_id).expect("Error with get_curve_size_from_id()");
|
||||
let mut ecc = ECC::generate_ex(curve_size, &mut rng, curve_id).expect("Error with generate()");
|
||||
let mut qx = [0u8; 32];
|
||||
let mut qx_len = 0u32;
|
||||
let mut qy = [0u8; 32];
|
||||
let mut qy_len = 0u32;
|
||||
let mut d = [0u8; 32];
|
||||
let mut d_len = 0u32;
|
||||
ecc.export_ex(&mut qx, &mut qx_len, &mut qy, &mut qy_len, &mut d, &mut d_len, false).expect("Error with export_ex()");
|
||||
|
||||
let mut ecc2 = ECC::import_unsigned(&qx, &qy, &d, curve_id).expect("Error with import_unsigned()");
|
||||
|
||||
let hash = [0x42u8; 32];
|
||||
let mut signature = [0u8; 128];
|
||||
let signature_length = ecc.sign_hash(&hash, &mut signature, &mut rng).expect("Error with sign_hash()");
|
||||
let signature = &signature[0..signature_length];
|
||||
let valid = ecc2.verify_hash(signature, &hash).expect("Error with verify_hash()");
|
||||
assert_eq!(valid, true);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_ecc_make_pub() {
|
||||
let mut rng = RNG::new().expect("Failed to create RNG");
|
||||
let key_path = "../../../certs/ecc-client-key.der";
|
||||
let der: Vec<u8> = fs::read(key_path).expect("Error reading key file");
|
||||
let mut ecc = ECC::import_der(&der).expect("Error with import_der()");
|
||||
ecc.make_pub(Some(&mut rng)).expect("Error with make_pub()");
|
||||
ecc.make_pub(None).expect("Error with make_pub()");
|
||||
ecc.make_pub_to_point(Some(&mut rng)).expect("Error with make_pub_to_point()");
|
||||
ecc.make_pub_to_point(None).expect("Error with make_pub_to_point()");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_ecc_point() {
|
||||
let mut rng = RNG::new().expect("Failed to create RNG");
|
||||
let curve_id = ECC::SECP256R1;
|
||||
let curve_size = ECC::get_curve_size_from_id(curve_id).expect("Error with get_curve_size_from_id()");
|
||||
let mut ecc = ECC::generate_ex(curve_size, &mut rng, curve_id).expect("Error with generate()");
|
||||
let ecc_point = ecc.make_pub_to_point(Some(&mut rng)).expect("Error with make_pub_to_point()");
|
||||
let mut der = [0u8; 128];
|
||||
let size = ecc_point.export_der(&mut der, curve_id).expect("Error with export_der()");
|
||||
assert!(size > 0 && size <= der.len());
|
||||
ECCPoint::import_der(&der[0..size], curve_id).expect("Error with import_der()");
|
||||
let size = ecc_point.export_der_compressed(&mut der, curve_id).expect("Error with export_der_compressed()");
|
||||
ECCPoint::import_der_ex(&der[0..size], curve_id, 1).expect("Error with import_der_ex()");
|
||||
ecc_point.forcezero();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_ecc_import() {
|
||||
let qx = b"7a4e287890a1a47ad3457e52f2f76a83ce46cbc947616d0cbaa82323818a793d\0";
|
||||
let qy = b"eec4084f5b29ebf29c44cce3b3059610922f8b30ea6e8811742ac7238fe87308\0";
|
||||
let d = b"8c14b793cb19137e323a6d2e2a870bca2e7a493ec1153b3a95feb8a4873f8d08\0";
|
||||
ECC::import_raw(qx, qy, d, b"SECP256R1\0").expect("Error with import_raw()");
|
||||
ECC::import_raw_ex(qx, qy, d, ECC::SECP256R1).expect("Error with import_raw_ex()");
|
||||
}
|
||||
Reference in New Issue
Block a user