Skip to main content

SharedSecret

Struct SharedSecret 

Source
pub struct SharedSecret(/* private fields */);
Expand description

The key-agreement shared secret, in big-endian order.

§Why there is one constructor and why it names the byte order

The spikes/tpm-ecdh spike discovered something easily overlooked: NCryptSecretAgreement with Microsoft Platform Crypto Provider returns the shared secret in little-endian order, whereas all pure P-256 implementations, including p256, use the big-endian X-coordinate representation, as prescribed by RFC 5903 (ECDH for IKE).

Byte order left to a comment is a bug waiting to happen: a reversed secret yields a different AEAD key; the slot will not open, appearing as “file corrupted”. The error would be found, but not at its actual source.

There is therefore exactly one constructor, and its name states the byte order. An implementation receiving NCrypt bytes must reverse them to invoke it truthfully; this cannot be silently forgotten, since the type has no other entry point.

Implementations§

Source§

impl SharedSecret

Source

pub fn from_be_bytes(bytes: [u8; 32]) -> Self

The only constructor. Bytes must be big-endian.

Source

pub fn ct_eq(&self, other: &Self) -> bool

Compare two secrets in constant time.

A named method rather than derived PartialEq: derivation would compare bytes conventionally, returning early at the first difference, which is a guessing oracle (I-13). A type for which == is unsafe should not provide it at all.

Needed externally: the hardware agreement implementation must be checked against the software implementation using identical keys, and comparing secrets is the only way to do that.

Trait Implementations§

Source§

impl Clone for SharedSecret

Source§

fn clone(&self) -> Self

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for SharedSecret

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.