Skip to main content

DhProvider

Trait DhProvider 

Source
pub trait DhProvider {
    type Algorithm: DhAlgorithm;
    type VisibleSecretKey: Sized + Into<Self::SecretKey>;
    type SecretKey: Sized;
    type PublicKey: Sized;
    type SharedSecret: Sized;

    // Required methods
    fn generate_visible(
        &mut self,
        alg: Self::Algorithm,
    ) -> Self::VisibleSecretKey;
    fn export_secretkey_bytes<'s>(
        &mut self,
        secretkey: &'s Self::VisibleSecretKey,
    ) -> impl AsRef<[u8]> + use<'s, Self>;
    fn import_secretkey_bytes(
        &mut self,
        alg: Self::Algorithm,
        secret: &[u8],
    ) -> Result<Self::VisibleSecretKey, ImportError>;
    fn export_publickey_bytes<'p>(
        &mut self,
        public: &'p Self::PublicKey,
    ) -> impl AsRef<[u8]> + use<'p, Self>;
    fn import_publickey_bytes(
        &mut self,
        alg: Self::Algorithm,
        data: &[u8],
    ) -> Result<Self::PublicKey, ImportError>;
    fn shared_secret(
        &mut self,
        private: &Self::SecretKey,
        public: &Self::PublicKey,
    ) -> Result<Self::SharedSecret, IncompatibleKeys>;
    fn public_key(&mut self, private: &Self::SecretKey) -> Self::PublicKey;
    fn raw_secret_bytes<'s>(
        &mut self,
        secret: &'s Self::SharedSecret,
    ) -> impl AsRef<[u8]> + use<'s, Self>;

    // Provided method
    fn generate(&mut self, alg: Self::Algorithm) -> Self::SecretKey { ... }
}
Expand description

Diffie-Hellman style key establishment.

This trait does not distinguish between prime factor DH and Elliptic Curve DH (ECDH); it describes the general interface, and many embedded systems likely only implement the latter.

This trait takes inspiration from the elliptic_curve crate, but does not use it directly because

  • embedded-cal passes around an exclusive reference to its engine,
  • its operation is cryptographically agile rather than monomorphized over algorithms,
  • only the user visible parts are modelled here (corresponding to SecretKey, PublicKey and a SharedSecret, and
  • it does not distinguish, on the type level, between an EphemeralSecret and a SecretKey, as some protocols such as Group OSCORE have legitimate use cases for static-static key derivations.

Importing and exporting public keys is a relatively verbose affair, as there is no consistent byte-like structure for all algorithms. Implementations are expected to provide imports and exports for every method that is defined for a given algorithm. For example, for P-256, both export and import in EC2-style format are expected, both with and without coordinate compression.

Required Associated Types§

Source

type Algorithm: DhAlgorithm

Source

type VisibleSecretKey: Sized + Into<Self::SecretKey>

A secret key that is intended to be exported.

It is recommended (but not required) that this is not just SecretKey but at least a newtype around it; otherwise, users with knowledge of the concrete Cal type (or who require that C::SecretKey is identical to or convertible from a C::VisibleSecretKey) could just swap them around.

§Rationale

Visible secret keys are a dedicated type here, compared to the AEAD and HMAC types where keys are merely loadable because secret keys have more diverse forms of serialization (eg. raw bytes, DER or COSE keys), and because key need generation (and not “just” a fixed number of uniformly random bytes that is trivial to generate once and store as part of it).

Source

type SecretKey: Sized

Source

type PublicKey: Sized

Source

type SharedSecret: Sized

Required Methods§

Source

fn generate_visible(&mut self, alg: Self::Algorithm) -> Self::VisibleSecretKey

Generates a secret key that is intended to be exported / shared (e.g. to be persisted across program executions).

Source

fn export_secretkey_bytes<'s>( &mut self, secretkey: &'s Self::VisibleSecretKey, ) -> impl AsRef<[u8]> + use<'s, Self>

Exposes a visible secret key’s secret.

Data is stored in the algorithm’s native format. For COSE ECDH, this is the d value.

If any algorithms are later added for which there is no straightforward [u8] representation, other methods may be added.

Source

fn import_secretkey_bytes( &mut self, alg: Self::Algorithm, secret: &[u8], ) -> Result<Self::VisibleSecretKey, ImportError>

Inverse operation of .export_secretkey_bytes().

Source

fn export_publickey_bytes<'p>( &mut self, public: &'p Self::PublicKey, ) -> impl AsRef<[u8]> + use<'p, Self>

Exposes a public key’s key data bytes.

For ECDH keys, this is defined as the compact representation.

Source

fn import_publickey_bytes( &mut self, alg: Self::Algorithm, data: &[u8], ) -> Result<Self::PublicKey, ImportError>

Imports a public key in the inverse operation of .export_publickey_bytes().

Source

fn shared_secret( &mut self, private: &Self::SecretKey, public: &Self::PublicKey, ) -> Result<Self::SharedSecret, IncompatibleKeys>

Derives a shared secret from a public and a private key.

§Errors

… are produced only if the private and the public key are for different algorithms.

Source

fn public_key(&mut self, private: &Self::SecretKey) -> Self::PublicKey

Produces the public key corresponding to a private key.

Source

fn raw_secret_bytes<'s>( &mut self, secret: &'s Self::SharedSecret, ) -> impl AsRef<[u8]> + use<'s, Self>

Produces the bytes of the shared secret, in the algorithm’s .output_length().

The SharedSecret itself is not AsRef itself because the implementation may want to not pass out this secret by default (expecting it to be used as input to a KDF).

Provided Methods§

Source

fn generate(&mut self, alg: Self::Algorithm) -> Self::SecretKey

Generates a secret key.

Dyn Compatibility§

This trait is not dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety".

Implementors§