Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions rustls-wolfcrypt-provider/src/hmac/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,23 +21,23 @@ impl WCShaHmac {

fn algorithm(&self) -> i32 {
match self {
WCShaHmac::Sha256 => WC_SHA256.try_into().unwrap(),
WCShaHmac::Sha384 => WC_SHA384.try_into().unwrap(),
WCShaHmac::Sha256 => wc_HashType_WC_HASH_TYPE_SHA256.try_into().unwrap(),
WCShaHmac::Sha384 => wc_HashType_WC_HASH_TYPE_SHA384.try_into().unwrap(),
}
}

pub fn new(hash_type: wc_HashType) -> Self {
match hash_type {
WC_SHA256 => WCShaHmac::Sha256,
WC_SHA384 => WCShaHmac::Sha384,
wolfcrypt_rs::wc_HashType_WC_HASH_TYPE_SHA256 => WCShaHmac::Sha256,
wolfcrypt_rs::wc_HashType_WC_HASH_TYPE_SHA384 => WCShaHmac::Sha384,
_ => panic!("Unsupported hash type"),
}
}

pub fn hash_type(&self) -> wc_HashType {
match self {
WCShaHmac::Sha256 => WC_SHA256,
WCShaHmac::Sha384 => WC_SHA384,
WCShaHmac::Sha256 => wc_HashType_WC_HASH_TYPE_SHA256,
WCShaHmac::Sha384 => wc_HashType_WC_HASH_TYPE_SHA384,
}
}

Expand Down
8 changes: 4 additions & 4 deletions rustls-wolfcrypt-provider/src/kx/sec256r1.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ impl KeyExchangeSecP256r1 {
key_object.init();
rng_object.init();

let key_size = unsafe { wc_ecc_get_curve_size_from_id(ecc_curve_id_ECC_SECP256R1) };
let key_size = unsafe { wc_ecc_get_curve_size_from_id(ecc_curve_ids_ECC_SECP256R1) };

let mut priv_key_raw = [0u8; 32];
let mut priv_key_raw_len: word32 = priv_key_raw.len() as word32;
Expand All @@ -45,7 +45,7 @@ impl KeyExchangeSecP256r1 {
rng_object.as_ptr(),
key_size,
key_object.as_ptr(),
ecc_curve_id_ECC_SECP256R1,
ecc_curve_ids_ECC_SECP256R1,
)
};
check_if_zero(ret)
Expand Down Expand Up @@ -112,7 +112,7 @@ impl KeyExchangeSecP256r1 {
ptr::null_mut(),
0,
priv_key_object.as_ptr(),
ecc_curve_id_ECC_SECP256R1,
ecc_curve_ids_ECC_SECP256R1,
)
};
check_if_zero(ret)
Expand All @@ -124,7 +124,7 @@ impl KeyExchangeSecP256r1 {
peer_pub_key[1..33].as_ptr(),
peer_pub_key[33..].as_ptr(),
ptr::null_mut(),
ecc_curve_id_ECC_SECP256R1,
ecc_curve_ids_ECC_SECP256R1,
)
};
check_if_zero(ret)
Expand Down
8 changes: 4 additions & 4 deletions rustls-wolfcrypt-provider/src/kx/sec384r1.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,14 +37,14 @@ impl KeyExchangeSecP384r1 {

rng_object.init();

let key_size = unsafe { wc_ecc_get_curve_size_from_id(ecc_curve_id_ECC_SECP384R1) };
let key_size = unsafe { wc_ecc_get_curve_size_from_id(ecc_curve_ids_ECC_SECP384R1) };

ret = unsafe {
wc_ecc_make_key_ex(
rng_object.as_ptr(),
key_size,
key_object.as_ptr(),
ecc_curve_id_ECC_SECP384R1,
ecc_curve_ids_ECC_SECP384R1,
)
};
check_if_zero(ret)
Expand Down Expand Up @@ -115,7 +115,7 @@ impl KeyExchangeSecP384r1 {
ptr::null_mut(),
0,
priv_key_object.as_ptr(),
ecc_curve_id_ECC_SECP384R1,
ecc_curve_ids_ECC_SECP384R1,
)
};
check_if_zero(ret)
Expand All @@ -131,7 +131,7 @@ impl KeyExchangeSecP384r1 {
peer_pub_key[1..49].as_ptr(),
peer_pub_key[49..].as_ptr(),
ptr::null_mut(),
ecc_curve_id_ECC_SECP384R1,
ecc_curve_ids_ECC_SECP384R1,
)
};
check_if_zero(ret)
Expand Down
8 changes: 4 additions & 4 deletions rustls-wolfcrypt-provider/src/kx/sec521r1.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,14 +38,14 @@ impl KeyExchangeSecP521r1 {
// We initiliaze the rng object.
rng_object.init();

let key_size = unsafe { wc_ecc_get_curve_size_from_id(ecc_curve_id_ECC_SECP521R1) };
let key_size = unsafe { wc_ecc_get_curve_size_from_id(ecc_curve_ids_ECC_SECP521R1) };

ret = unsafe {
wc_ecc_make_key_ex(
rng_object.as_ptr(),
key_size,
key_object.as_ptr(),
ecc_curve_id_ECC_SECP521R1,
ecc_curve_ids_ECC_SECP521R1,
)
};
check_if_zero(ret)
Expand Down Expand Up @@ -116,7 +116,7 @@ impl KeyExchangeSecP521r1 {
ptr::null_mut(),
0,
priv_key_object.as_ptr(),
ecc_curve_id_ECC_SECP521R1,
ecc_curve_ids_ECC_SECP521R1,
)
};
check_if_zero(ret)
Expand All @@ -132,7 +132,7 @@ impl KeyExchangeSecP521r1 {
peer_pub_key[1..67].as_ptr(),
peer_pub_key[67..].as_ptr(),
ptr::null_mut(),
ecc_curve_id_ECC_SECP521R1,
ecc_curve_ids_ECC_SECP521R1,
)
};
check_if_zero(ret)
Expand Down
19 changes: 18 additions & 1 deletion rustls-wolfcrypt-provider/src/kx/x25519.rs
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,21 @@ impl KeyExchangeX25519 {
rustls::Error::General("Failed to import Curve25519 private key".into())
})?;

// When wolfSSL is built with curve25519 blinding (pure-C builds, e.g.
// Apple Silicon where no asm backend is selected), the shared-secret
// scalar multiplication draws random values to blind the private
// scalar. An imported key has no RNG attached, so we must supply one;
// otherwise wc_curve25519_shared_secret_ex returns BAD_FUNC_ARG (-173).
// On non-blinding (asm) builds curve25519_set_rng is a no-op.
let mut rng: WC_RNG = unsafe { mem::zeroed() };
let rng_object = WCRngObject::new(&mut rng);
rng_object.init();

ret = unsafe { curve25519_set_rng(private_key_object.as_ptr(), rng_object.as_ptr()) };
check_if_zero(ret).map_err(|_| {
rustls::Error::General("Failed to set RNG on Curve25519 private key".into())
})?;

// This function computes a shared secret key given a secret private key and
// a received public key. Stores the generated secret in the buffer out.
ret = unsafe {
Expand All @@ -128,7 +143,9 @@ impl KeyExchangeX25519 {
)
};
check_if_zero(ret).map_err(|_| {
rustls::Error::General("Failed to compute Curve25519 shared secret".into())
rustls::Error::General(alloc::format!(
"Failed to compute Curve25519 shared secret (ret = {ret})"
))
})?;

Ok(Box::new(out))
Expand Down
8 changes: 4 additions & 4 deletions rustls-wolfcrypt-provider/src/sign/ecdsa.rs
Original file line number Diff line number Diff line change
Expand Up @@ -243,12 +243,12 @@ fn hash_message_for_scheme(
}
}

/// Converts a rustls `SignatureScheme` to the WolfSSL curve id (ecc_curve_id_ECC_...).
/// Converts a rustls `SignatureScheme` to the WolfSSL curve id (ecc_curve_ids_ECC_...).
fn scheme_to_curve_id(scheme: SignatureScheme) -> Result<i32, &'static str> {
match scheme {
SignatureScheme::ECDSA_NISTP256_SHA256 => Ok(ecc_curve_id_ECC_SECP256R1),
SignatureScheme::ECDSA_NISTP384_SHA384 => Ok(ecc_curve_id_ECC_SECP384R1),
SignatureScheme::ECDSA_NISTP521_SHA512 => Ok(ecc_curve_id_ECC_SECP521R1),
SignatureScheme::ECDSA_NISTP256_SHA256 => Ok(ecc_curve_ids_ECC_SECP256R1),
SignatureScheme::ECDSA_NISTP384_SHA384 => Ok(ecc_curve_ids_ECC_SECP384R1),
SignatureScheme::ECDSA_NISTP521_SHA512 => Ok(ecc_curve_ids_ECC_SECP521R1),
_ => Err("Not an ECDSA_NISTPxxx_SHAxxx scheme"),
}
}
136 changes: 64 additions & 72 deletions rustls-wolfcrypt-provider/src/sign/eddsa.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,81 +33,73 @@ impl fmt::Debug for Ed25519PrivateKey {
impl Ed25519PrivateKey {
/// Extract ED25519 private and if available public key values from a PKCS#8 DER formatted key
fn extract_key_pair(input_key: &[u8]) -> Result<([u8; 32], Option<[u8; 32]>), rustls::Error> {
let mut public_key_raw: [u8; 32] = [0; ED25519_PUB_KEY_SIZE as usize];
let mut private_key_raw: [u8; 32] = [0; ED25519_KEY_SIZE as usize];
let mut skip_bytes: usize;
let mut key_sub_slice = input_key;

const SHORT_FORM_LEN_MAX: u8 = 127;
const TAG_SEQUENCE: u8 = 0x30;
const TAG_OCTET_SEQUENCE: u8 = 0x04;
const TAG_OPTIONAL_SET_OF_ATTRIBUTES: u8 = 0x80; //Implicit, context-specific, and primitive underlying type (SET OF)
const TAG_OPTIONAL_PUBLIC_KEY_BIT_STRING: u8 = 0x81; //Implicit, context-specific, and primitive underlying type (BIT STRING)

// The input key is encoded in PKCS#8 DER format with a structure as in
// https://www.rfc-editor.org/rfc/rfc5958.html
let mut private_key_raw_len: word32 = private_key_raw.len() as word32;
// Scratch buffer for the optional embedded public key. DecodeAsymKey
// reports it either as the bare 32-byte key, or as the raw DER BIT STRING
// body (a leading 0x00 "unused bits" octet + the 32-byte key = 33 bytes),
// so 33 bytes is the largest form we ever need to hold here.
let mut public_key_scratch: [u8; ED25519_PUB_KEY_SIZE as usize + 1] =
[0; ED25519_PUB_KEY_SIZE as usize + 1];
let mut public_key_scratch_len: word32 = public_key_scratch.len() as word32;
let mut idx: word32 = 0;

// Parse the PKCS#8 structure with wolfSSL's own ASN parser. This is the
// same parser wc_Ed25519PrivateKeyDecode uses internally, but calling it
// directly lets us normalise the embedded public key before it is imported.
//
// AsymmetricKeyPackage ::= SEQUENCE SIZE (1..MAX) OF OneAsymmetricKey

// OneAsymmetricKey ::= SEQUENCE {
// version Version,
// privateKeyAlgorithm PrivateKeyAlgorithmIdentifier,
// privateKey PrivateKey,
// attributes [0] Attributes OPTIONAL,
// ...,
// [[2: publicKey [1] PublicKey OPTIONAL ]],
// ...
// }

// The key structure must begin with a SEQUENCE tag with at least 2 bytes length if short
// length format is used
if key_sub_slice[0] != TAG_SEQUENCE || key_sub_slice.len() < 2 {
return Err(rustls::Error::General(
"Faulty PKCS#8 ED25519 private key structure".into(),
));
}
// Check which length format and skip tag and length encoding bytes
if key_sub_slice[1] > SHORT_FORM_LEN_MAX {
skip_bytes = (2 + (key_sub_slice[1] & 0x7F)) as usize;
} else {
skip_bytes = 2;
}

// Skip version (3 bytes), algorithm ID sequence (0x30 + length encoding bytes + 5 ID bytes),
skip_bytes += 3 + 7;
key_sub_slice = input_key.get(skip_bytes..).unwrap();

// Check if next bytes are 0x04, 0x22, 0x04, 0x20
if !matches!(
key_sub_slice,
[TAG_OCTET_SEQUENCE, 0x22, TAG_OCTET_SEQUENCE, 0x20, ..]
) {
return Err(rustls::Error::General(
"Faulty PKCS#8 ED25519 private key structure".into(),
));
}

// Copy private key value
skip_bytes += 4;
key_sub_slice = input_key.get(skip_bytes..).unwrap();
private_key_raw.copy_from_slice(&key_sub_slice[..ED25519_KEY_SIZE as usize]);
skip_bytes += ED25519_KEY_SIZE as usize;
key_sub_slice = input_key.get(skip_bytes..).unwrap();

// Check if optional SET OF attributes exists and skip
if key_sub_slice.first() == Some(&TAG_OPTIONAL_SET_OF_ATTRIBUTES) {
skip_bytes += (2 + (key_sub_slice[1])) as usize;
key_sub_slice = input_key.get(skip_bytes..).unwrap();
}
// For an RFC 5958 (PKCS#8 v2) key that carries the optional public key,
// DecodeAsymKey hands back the [1] field as the raw DER BIT STRING body:
// a leading "unused bits" 0x00 octet followed by the 32-byte key (33 bytes
// total). wc_Ed25519PrivateKeyDecode passes that body verbatim to
// wc_ed25519_import_public_ex, which expects the key material itself,
// which is a bare 32-byte key (or a 0x40-prefixed 33-byte form).
// The 0x00-led 33-byte body matches neither, so it is rejected
// with BAD_FUNC_ARG (-173). So we strip the 0x00 octet here and
// hand on the bare 32-byte key instead.
let ret = unsafe {
DecodeAsymKey(
input_key.as_ptr(),
&mut idx,
input_key.len() as word32,
private_key_raw.as_mut_ptr(),
&mut private_key_raw_len,
public_key_scratch.as_mut_ptr(),
&mut public_key_scratch_len,
Key_Sum_ED25519k as i32,
)
};
check_if_zero(ret)
.map_err(|_| rustls::Error::General("DecodeAsymKey (ED25519) failed".into()))?;

// Normalise the optional public key based on the length the parser reported.
let pub_key: Option<[u8; 32]> = match public_key_scratch_len {
// No embedded public key; the caller derives it from the private seed.
0 => None,
// Bare 32-byte public key.
len if len == ED25519_PUB_KEY_SIZE => Some(
public_key_scratch[..ED25519_PUB_KEY_SIZE as usize]
.try_into()
.map_err(|_| {
rustls::Error::General("Unexpected ED25519 public key encoding".into())
})?,
),
// BIT STRING body: leading 0x00 "unused bits" octet + 32-byte key.
len if len == ED25519_PUB_KEY_SIZE + 1 && public_key_scratch[0] == 0x00 => Some(
public_key_scratch[1..1 + ED25519_PUB_KEY_SIZE as usize]
.try_into()
.map_err(|_| {
rustls::Error::General("Unexpected ED25519 public key encoding".into())
})?,
),
Comment thread
julek-wolfssl marked this conversation as resolved.
_ => {
return Err(rustls::Error::General(
"Unexpected ED25519 public key encoding".into(),
))
}
};

// Check if optional public key value exists. If exists, skip tag, length encoding byte,
// and bits-used byte
if key_sub_slice.first() == Some(&TAG_OPTIONAL_PUBLIC_KEY_BIT_STRING) {
public_key_raw.copy_from_slice(&key_sub_slice[3..(3 + ED25519_KEY_SIZE as usize)]);
Ok((private_key_raw, Some(public_key_raw)))
} else {
Ok((private_key_raw, None))
}
Ok((private_key_raw, pub_key))
}
}

Expand Down
2 changes: 1 addition & 1 deletion rustls-wolfcrypt-provider/src/sign/rsa.rs
Original file line number Diff line number Diff line change
Expand Up @@ -271,7 +271,7 @@ impl Signer for RsaSigner {
message.len() as u32,
sig_buf.as_mut_ptr(),
&mut sig_len,
rsa_key.as_ptr() as *const core::ffi::c_void,
rsa_key.as_ptr() as *mut core::ffi::c_void,
mem::size_of_val(&deref_rsa_key_c_type).try_into().unwrap(),
rng_object.as_ptr(),
)
Expand Down
6 changes: 3 additions & 3 deletions rustls-wolfcrypt-provider/src/verify/ecdsa.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,17 +70,17 @@ impl SignatureVerificationAlgorithm for EcdsaVerifier {
// Determine curve, how many bytes to skip from public_key, and which hash to use
let (curve_id, skip_len, wc_hash_type) = match self.scheme {
SignatureScheme::ECDSA_NISTP256_SHA256 => (
ecc_curve_id_ECC_SECP256R1,
ecc_curve_ids_ECC_SECP256R1,
32,
wc_HashType_WC_HASH_TYPE_SHA256,
),
SignatureScheme::ECDSA_NISTP384_SHA384 => (
ecc_curve_id_ECC_SECP384R1,
ecc_curve_ids_ECC_SECP384R1,
48,
wc_HashType_WC_HASH_TYPE_SHA384,
),
SignatureScheme::ECDSA_NISTP521_SHA512 => (
ecc_curve_id_ECC_SECP521R1,
ecc_curve_ids_ECC_SECP521R1,
66,
wc_HashType_WC_HASH_TYPE_SHA512,
),
Expand Down
6 changes: 3 additions & 3 deletions rustls-wolfcrypt-provider/src/verify/rsapkcs1.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ impl SignatureVerificationAlgorithm for RsaPkcs1Sha256Verify {
message.len() as word32,
signature.as_ptr(),
signature.len() as word32,
rsa_key_object.as_ptr() as *const c_void,
rsa_key_object.as_ptr() as *mut c_void,
Comment thread
holtrop-wolfssl marked this conversation as resolved.
mem::size_of_val(&derefenced_rsa_key_c_type)
.try_into()
.unwrap(),
Expand Down Expand Up @@ -128,7 +128,7 @@ impl SignatureVerificationAlgorithm for RsaPkcs1Sha384Verify {
message.len() as word32,
signature.as_ptr(),
signature.len() as word32,
rsa_key_object.as_ptr() as *const c_void,
rsa_key_object.as_ptr() as *mut c_void,
mem::size_of_val(&dereferenced_rsa_key_c_type)
.try_into()
.unwrap(),
Expand Down Expand Up @@ -194,7 +194,7 @@ impl SignatureVerificationAlgorithm for RsaPkcs1Sha512Verify {
message.len() as word32,
signature.as_ptr(),
signature.len() as word32,
rsa_key_object.as_ptr() as *const c_void,
rsa_key_object.as_ptr() as *mut c_void,
mem::size_of_val(&dereferenced_rsa_key_c_type)
.try_into()
.unwrap(),
Expand Down
Loading
Loading