1 // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 2 // Copyright by contributors to this project. 3 // SPDX-License-Identifier: (Apache-2.0 OR MIT) 4 5 use crate::error::IntoAnyError; 6 use alloc::vec; 7 use alloc::vec::Vec; 8 use core::{ 9 fmt::{self, Debug}, 10 ops::Deref, 11 }; 12 use mls_rs_codec::{MlsDecode, MlsEncode, MlsSize}; 13 use zeroize::{ZeroizeOnDrop, Zeroizing}; 14 15 mod cipher_suite; 16 pub use self::cipher_suite::*; 17 18 #[cfg(feature = "test_suite")] 19 pub mod test_suite; 20 21 #[derive(Clone, PartialEq, Eq, MlsSize, MlsEncode, MlsDecode)] 22 #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))] 23 #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] 24 /// Ciphertext produced by [`CipherSuiteProvider::hpke_seal`] 25 pub struct HpkeCiphertext { 26 #[mls_codec(with = "mls_rs_codec::byte_vec")] 27 #[cfg_attr(feature = "serde", serde(with = "crate::vec_serde"))] 28 pub kem_output: Vec<u8>, 29 #[mls_codec(with = "mls_rs_codec::byte_vec")] 30 #[cfg_attr(feature = "serde", serde(with = "crate::vec_serde"))] 31 pub ciphertext: Vec<u8>, 32 } 33 34 impl Debug for HpkeCiphertext { fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result35 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 36 f.debug_struct("HpkeCiphertext") 37 .field("kem_output", &crate::debug::pretty_bytes(&self.kem_output)) 38 .field("ciphertext", &crate::debug::pretty_bytes(&self.ciphertext)) 39 .finish() 40 } 41 } 42 43 /// Byte representation of an HPKE public key. For ciphersuites using elliptic curves, 44 /// the public key should be represented in the uncompressed format. 45 #[derive(Clone, PartialEq, Eq, Hash, PartialOrd, Ord, MlsSize, MlsDecode, MlsEncode)] 46 #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))] 47 #[cfg_attr( 48 all(feature = "ffi", not(test)), 49 safer_ffi_gen::ffi_type(clone, opaque) 50 )] 51 #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] 52 pub struct HpkePublicKey( 53 #[mls_codec(with = "mls_rs_codec::byte_vec")] 54 #[cfg_attr(feature = "serde", serde(with = "crate::vec_serde"))] 55 Vec<u8>, 56 ); 57 58 impl Debug for HpkePublicKey { fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result59 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 60 crate::debug::pretty_bytes(&self.0) 61 .named("HpkePublicKey") 62 .fmt(f) 63 } 64 } 65 66 impl From<Vec<u8>> for HpkePublicKey { from(data: Vec<u8>) -> Self67 fn from(data: Vec<u8>) -> Self { 68 Self(data) 69 } 70 } 71 72 impl From<HpkePublicKey> for Vec<u8> { from(data: HpkePublicKey) -> Self73 fn from(data: HpkePublicKey) -> Self { 74 data.0 75 } 76 } 77 78 impl Deref for HpkePublicKey { 79 type Target = [u8]; 80 deref(&self) -> &Self::Target81 fn deref(&self) -> &Self::Target { 82 &self.0 83 } 84 } 85 86 impl AsRef<[u8]> for HpkePublicKey { as_ref(&self) -> &[u8]87 fn as_ref(&self) -> &[u8] { 88 &self.0 89 } 90 } 91 92 /// Byte representation of an HPKE secret key. 93 #[derive(Clone, PartialEq, Eq, MlsSize, MlsEncode, MlsDecode, ZeroizeOnDrop)] 94 #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))] 95 #[cfg_attr( 96 all(feature = "ffi", not(test)), 97 safer_ffi_gen::ffi_type(clone, opaque) 98 )] 99 #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] 100 pub struct HpkeSecretKey( 101 #[mls_codec(with = "mls_rs_codec::byte_vec")] 102 #[cfg_attr(feature = "serde", serde(with = "crate::vec_serde"))] 103 Vec<u8>, 104 ); 105 106 impl Debug for HpkeSecretKey { fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result107 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 108 crate::debug::pretty_bytes(&self.0) 109 .named("HpkeSecretKey") 110 .fmt(f) 111 } 112 } 113 114 impl From<Vec<u8>> for HpkeSecretKey { from(data: Vec<u8>) -> Self115 fn from(data: Vec<u8>) -> Self { 116 Self(data) 117 } 118 } 119 120 impl Deref for HpkeSecretKey { 121 type Target = [u8]; 122 deref(&self) -> &Self::Target123 fn deref(&self) -> &Self::Target { 124 &self.0 125 } 126 } 127 128 impl AsRef<[u8]> for HpkeSecretKey { as_ref(&self) -> &[u8]129 fn as_ref(&self) -> &[u8] { 130 &self.0 131 } 132 } 133 134 /// The HPKE context for sender outputted by [hpke_setup_s](CipherSuiteProvider::hpke_setup_s). 135 /// The context internally stores the secrets generated by [hpke_setup_s](CipherSuiteProvider::hpke_setup_s). 136 /// 137 /// This trait corresponds to ContextS from RFC 9180. 138 #[cfg_attr(not(mls_build_async), maybe_async::must_be_sync)] 139 #[cfg_attr(all(target_arch = "wasm32", mls_build_async), maybe_async::must_be_async(?Send))] 140 #[cfg_attr( 141 all(not(target_arch = "wasm32"), mls_build_async), 142 maybe_async::must_be_async 143 )] 144 pub trait HpkeContextS { 145 type Error: IntoAnyError; 146 147 /// Encrypt `data` using the cipher key of the context with optional `aad`. 148 /// This function should internally increment the sequence number. seal(&mut self, aad: Option<&[u8]>, data: &[u8]) -> Result<Vec<u8>, Self::Error>149 async fn seal(&mut self, aad: Option<&[u8]>, data: &[u8]) -> Result<Vec<u8>, Self::Error>; 150 151 /// Export a secret from the context for the given `exporter_context`. export(&self, exporter_context: &[u8], len: usize) -> Result<Vec<u8>, Self::Error>152 async fn export(&self, exporter_context: &[u8], len: usize) -> Result<Vec<u8>, Self::Error>; 153 } 154 155 /// The HPKE context for receiver outputted by [hpke_setup_r](CipherSuiteProvider::hpke_setup_r). 156 /// The context internally stores secrets received from the sender by [hpke_setup_r](CipherSuiteProvider::hpke_setup_r). 157 /// 158 /// This trait corresponds to ContextR from RFC 9180. 159 #[cfg_attr(not(mls_build_async), maybe_async::must_be_sync)] 160 #[cfg_attr(all(target_arch = "wasm32", mls_build_async), maybe_async::must_be_async(?Send))] 161 #[cfg_attr( 162 all(not(target_arch = "wasm32"), mls_build_async), 163 maybe_async::must_be_async 164 )] 165 pub trait HpkeContextR { 166 type Error: IntoAnyError; 167 168 /// Decrypt `ciphertext` using the cipher key of the context with optional `aad`. 169 /// This function should internally increment the sequence number. open(&mut self, aad: Option<&[u8]>, ciphertext: &[u8]) -> Result<Vec<u8>, Self::Error>170 async fn open(&mut self, aad: Option<&[u8]>, ciphertext: &[u8]) 171 -> Result<Vec<u8>, Self::Error>; 172 173 /// Export a secret from the context for the given `exporter_context`. export(&self, exporter_context: &[u8], len: usize) -> Result<Vec<u8>, Self::Error>174 async fn export(&self, exporter_context: &[u8], len: usize) -> Result<Vec<u8>, Self::Error>; 175 } 176 177 /// Byte representation of a signature public key. For ciphersuites using elliptic curves, 178 /// the public key should be represented in the uncompressed format. 179 #[derive(Clone, PartialEq, Eq, Hash, Ord, PartialOrd, MlsSize, MlsEncode, MlsDecode)] 180 #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))] 181 #[cfg_attr(all(feature = "ffi", not(test)), ::safer_ffi_gen::ffi_type(opaque))] 182 #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] 183 pub struct SignaturePublicKey( 184 #[mls_codec(with = "mls_rs_codec::byte_vec")] 185 #[cfg_attr(feature = "serde", serde(with = "crate::vec_serde"))] 186 Vec<u8>, 187 ); 188 189 impl Debug for SignaturePublicKey { fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result190 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 191 crate::debug::pretty_bytes(&self.0) 192 .named("SignaturePublicKey") 193 .fmt(f) 194 } 195 } 196 197 #[cfg_attr(all(feature = "ffi", not(test)), ::safer_ffi_gen::safer_ffi_gen)] 198 impl SignaturePublicKey { new(bytes: Vec<u8>) -> Self199 pub fn new(bytes: Vec<u8>) -> Self { 200 bytes.into() 201 } 202 new_slice(data: &[u8]) -> Self203 pub fn new_slice(data: &[u8]) -> Self { 204 Self(data.to_vec()) 205 } 206 as_bytes(&self) -> &[u8]207 pub fn as_bytes(&self) -> &[u8] { 208 &self.0 209 } 210 } 211 212 impl Deref for SignaturePublicKey { 213 type Target = [u8]; 214 deref(&self) -> &Self::Target215 fn deref(&self) -> &Self::Target { 216 &self.0 217 } 218 } 219 220 impl AsRef<[u8]> for SignaturePublicKey { as_ref(&self) -> &[u8]221 fn as_ref(&self) -> &[u8] { 222 &self.0 223 } 224 } 225 226 impl From<Vec<u8>> for SignaturePublicKey { from(data: Vec<u8>) -> Self227 fn from(data: Vec<u8>) -> Self { 228 SignaturePublicKey(data) 229 } 230 } 231 232 /// Byte representation of a signature key. 233 #[cfg_attr( 234 all(feature = "ffi", not(test)), 235 ::safer_ffi_gen::ffi_type(clone, opaque) 236 )] 237 #[derive(Clone, PartialEq, Eq, ZeroizeOnDrop, MlsSize, MlsEncode, MlsDecode)] 238 #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] 239 pub struct SignatureSecretKey { 240 #[mls_codec(with = "mls_rs_codec::byte_vec")] 241 #[cfg_attr(feature = "serde", serde(with = "crate::vec_serde"))] 242 bytes: Vec<u8>, 243 } 244 245 impl Debug for SignatureSecretKey { fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result246 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 247 crate::debug::pretty_bytes(&self.bytes) 248 .named("SignatureSecretKey") 249 .fmt(f) 250 } 251 } 252 253 #[cfg_attr(all(feature = "ffi", not(test)), ::safer_ffi_gen::safer_ffi_gen)] 254 impl SignatureSecretKey { new(bytes: Vec<u8>) -> Self255 pub fn new(bytes: Vec<u8>) -> Self { 256 bytes.into() 257 } 258 new_slice(data: &[u8]) -> Self259 pub fn new_slice(data: &[u8]) -> Self { 260 Self { 261 bytes: data.to_vec(), 262 } 263 } 264 as_bytes(&self) -> &[u8]265 pub fn as_bytes(&self) -> &[u8] { 266 &self.bytes 267 } 268 } 269 270 impl From<Vec<u8>> for SignatureSecretKey { from(bytes: Vec<u8>) -> Self271 fn from(bytes: Vec<u8>) -> Self { 272 Self { bytes } 273 } 274 } 275 276 impl Deref for SignatureSecretKey { 277 type Target = Vec<u8>; 278 deref(&self) -> &Self::Target279 fn deref(&self) -> &Self::Target { 280 &self.bytes 281 } 282 } 283 284 impl AsRef<[u8]> for SignatureSecretKey { as_ref(&self) -> &[u8]285 fn as_ref(&self) -> &[u8] { 286 &self.bytes 287 } 288 } 289 290 /// Provides implementations for several ciphersuites via [`CipherSuiteProvider`]. 291 pub trait CryptoProvider: Send + Sync { 292 type CipherSuiteProvider: CipherSuiteProvider + Clone; 293 294 /// Return the list of all supported ciphersuites. supported_cipher_suites(&self) -> Vec<CipherSuite>295 fn supported_cipher_suites(&self) -> Vec<CipherSuite>; 296 297 /// Generate a [CipherSuiteProvider] for the given `cipher_suite`. cipher_suite_provider(&self, cipher_suite: CipherSuite) -> Option<Self::CipherSuiteProvider>298 fn cipher_suite_provider(&self, cipher_suite: CipherSuite) 299 -> Option<Self::CipherSuiteProvider>; 300 } 301 302 /// Provides all cryptographic operations required by MLS for a given cipher suite. 303 #[cfg_attr(not(mls_build_async), maybe_async::must_be_sync)] 304 #[cfg_attr(all(target_arch = "wasm32", mls_build_async), maybe_async::must_be_async(?Send))] 305 #[cfg_attr( 306 all(not(target_arch = "wasm32"), mls_build_async), 307 maybe_async::must_be_async 308 )] 309 pub trait CipherSuiteProvider: Send + Sync { 310 type Error: IntoAnyError; 311 312 type HpkeContextS: HpkeContextS + Send + Sync; 313 type HpkeContextR: HpkeContextR + Send + Sync; 314 315 /// Return the implemented MLS [CipherSuite](CipherSuite). cipher_suite(&self) -> CipherSuite316 fn cipher_suite(&self) -> CipherSuite; 317 318 /// Compute the hash of `data`. hash(&self, data: &[u8]) -> Result<Vec<u8>, Self::Error>319 async fn hash(&self, data: &[u8]) -> Result<Vec<u8>, Self::Error>; 320 321 /// Compute the MAC tag of `data` using the `key` of length [kdf_extract_size](CipherSuiteProvider::kdf_extract_size). 322 /// Verifying a MAC tag of `data` using `key` is done by calling this function 323 /// and checking that the result matches the tag. mac(&self, key: &[u8], data: &[u8]) -> Result<Vec<u8>, Self::Error>324 async fn mac(&self, key: &[u8], data: &[u8]) -> Result<Vec<u8>, Self::Error>; 325 326 /// Encrypt `data` with public additional authenticated data `aad`, using additional `nonce` 327 /// (sometimes called the initialization vector, IV). The output should include 328 /// the authentication tag, if used by the given AEAD implementation (for example, 329 /// the tag can be appended to the ciphertext). aead_seal( &self, key: &[u8], data: &[u8], aad: Option<&[u8]>, nonce: &[u8], ) -> Result<Vec<u8>, Self::Error>330 async fn aead_seal( 331 &self, 332 key: &[u8], 333 data: &[u8], 334 aad: Option<&[u8]>, 335 nonce: &[u8], 336 ) -> Result<Vec<u8>, Self::Error>; 337 338 /// Decrypt the `ciphertext` generated by [aead_seal](CipherSuiteProvider::aead_seal). 339 /// This function should return an error if any of the inputs `key`, `aad` or `nonce` does not match 340 /// the corresponding input passed to [aead_seal](CipherSuiteProvider::aead_seal) to generate `ciphertext`. aead_open( &self, key: &[u8], ciphertext: &[u8], aad: Option<&[u8]>, nonce: &[u8], ) -> Result<Zeroizing<Vec<u8>>, Self::Error>341 async fn aead_open( 342 &self, 343 key: &[u8], 344 ciphertext: &[u8], 345 aad: Option<&[u8]>, 346 nonce: &[u8], 347 ) -> Result<Zeroizing<Vec<u8>>, Self::Error>; 348 349 /// Return the length of the secret key `key` passed to [aead_seal](CipherSuiteProvider::aead_seal) 350 /// and [aead_open](CipherSuiteProvider::aead_open). aead_key_size(&self) -> usize351 fn aead_key_size(&self) -> usize; 352 353 /// Return the length of the `nonce` passed to [aead_seal](CipherSuiteProvider::aead_seal) 354 /// and [aead_open](CipherSuiteProvider::aead_open). aead_nonce_size(&self) -> usize355 fn aead_nonce_size(&self) -> usize; 356 357 /// Generate a pseudo-random key `prk` extracted from the initial key 358 /// material `ikm`, using an optional random `salt`. The outputted `prk` should have 359 /// [kdf_extract_size](CipherSuiteProvider::kdf_extract_size) bytes. It can be used 360 /// as input to [kdf_expand](CipherSuiteProvider::kdf_expand). 361 /// 362 /// This function corresponds to the HKDF-Extract function from RFC 5869. kdf_extract(&self, salt: &[u8], ikm: &[u8]) -> Result<Zeroizing<Vec<u8>>, Self::Error>363 async fn kdf_extract(&self, salt: &[u8], ikm: &[u8]) 364 -> Result<Zeroizing<Vec<u8>>, Self::Error>; 365 366 /// Generate key material of the desired length `len` by expanding the given pseudo-random key 367 /// `prk` of length [kdf_extract_size](CipherSuiteProvider::kdf_extract_size). 368 /// The additional input `info` contains optional context data. 369 /// 370 /// This function corresponds to the HKDF-Expand function from RFC 5869. kdf_expand( &self, prk: &[u8], info: &[u8], len: usize, ) -> Result<Zeroizing<Vec<u8>>, Self::Error>371 async fn kdf_expand( 372 &self, 373 prk: &[u8], 374 info: &[u8], 375 len: usize, 376 ) -> Result<Zeroizing<Vec<u8>>, Self::Error>; 377 378 /// Return the size of pseudo-random key `prk` outputted by [kdf_extract](CipherSuiteProvider::kdf_extract) 379 /// and inputted to [kdf_expand](CipherSuiteProvider::kdf_expand). kdf_extract_size(&self) -> usize380 fn kdf_extract_size(&self) -> usize; 381 382 /// Encrypt the plaintext `pt` with optional public additional authenticated data `aad` to the 383 /// public key `remote_key` using additional context information `info` (which can be empty if 384 /// not needed). This function combines the action 385 /// of the [hpke_setup_s](CipherSuiteProvider::hpke_setup_s) and then calling [seal](HpkeContextS::seal) 386 /// on the resulting [HpkeContextS](self::HpkeContextS). 387 /// 388 /// This function corresponds to the one-shot API in base mode in RFC 9180. hpke_seal( &self, remote_key: &HpkePublicKey, info: &[u8], aad: Option<&[u8]>, pt: &[u8], ) -> Result<HpkeCiphertext, Self::Error>389 async fn hpke_seal( 390 &self, 391 remote_key: &HpkePublicKey, 392 info: &[u8], 393 aad: Option<&[u8]>, 394 pt: &[u8], 395 ) -> Result<HpkeCiphertext, Self::Error>; 396 397 /// Decrypt the `ciphertext` generated by [hpke_seal](CipherSuiteProvider::hpke_seal). 398 /// This function combines the action of the [hpke_setup_r](CipherSuiteProvider::hpke_setup_r) 399 /// and then calling [open](HpkeContextR::open) on the resulting [HpkeContextR](self::HpkeContextR). 400 /// 401 /// This function corresponds to the one-shot API in base mode in RFC 9180. hpke_open( &self, ciphertext: &HpkeCiphertext, local_secret: &HpkeSecretKey, local_public: &HpkePublicKey, info: &[u8], aad: Option<&[u8]>, ) -> Result<Vec<u8>, Self::Error>402 async fn hpke_open( 403 &self, 404 ciphertext: &HpkeCiphertext, 405 local_secret: &HpkeSecretKey, 406 local_public: &HpkePublicKey, 407 info: &[u8], 408 aad: Option<&[u8]>, 409 ) -> Result<Vec<u8>, Self::Error>; 410 411 /// Generate a tuple containing the ciphertext `kem_output` that can 412 /// be used as the input to [hpke_setup_r](CipherSuiteProvider::hpke_setup_r), 413 /// as well as the sender context [HpkeContextS](self::HpkeContextS) that can be 414 /// used to generate AEAD ciphertexts and export keys. 415 /// 416 /// The inputted `remote_key` will normally be generated using 417 /// [kem_derive](CipherSuiteProvider::kem_derive) or 418 /// [kem_generate](CipherSuiteProvider::kem_generate). However, the function 419 /// should return an error if the format is incorrect. 420 /// 421 /// This function corresponds to the SetupBaseS function from RFC 9180. hpke_setup_s( &self, remote_key: &HpkePublicKey, info: &[u8], ) -> Result<(Vec<u8>, Self::HpkeContextS), Self::Error>422 async fn hpke_setup_s( 423 &self, 424 remote_key: &HpkePublicKey, 425 info: &[u8], 426 ) -> Result<(Vec<u8>, Self::HpkeContextS), Self::Error>; 427 428 /// Receive the ciphertext `kem_output` generated by [hpke_setup_s](CipherSuiteProvider::hpke_setup_s) 429 /// and the `local_secret` corresponding to the `remote_key` used as input to 430 /// [hpke_setup_s](CipherSuiteProvider::hpke_setup_s). The ouput is the receiver context 431 /// [HpkeContextR](self::HpkeContextR) that can be used to decrypt AEAD ciphertexts 432 /// generated by the sender context [HpkeContextS](self::HpkeContextS) outputted by 433 /// [hpke_setup_r](CipherSuiteProvider::hpke_setup_r) 434 /// and export the same keys as that context. 435 /// 436 /// The inputted `local_secret` will normally be generated using 437 /// [kem_derive](CipherSuiteProvider::kem_derive) or 438 /// [kem_generate](CipherSuiteProvider::kem_generate). However, the function 439 /// should return an error if the format is incorrect. 440 /// 441 /// This function corresponds to the SetupBaseR function from RFC 9180. hpke_setup_r( &self, kem_output: &[u8], local_secret: &HpkeSecretKey, local_public: &HpkePublicKey, info: &[u8], ) -> Result<Self::HpkeContextR, Self::Error>442 async fn hpke_setup_r( 443 &self, 444 kem_output: &[u8], 445 local_secret: &HpkeSecretKey, 446 local_public: &HpkePublicKey, 447 448 info: &[u8], 449 ) -> Result<Self::HpkeContextR, Self::Error>; 450 451 /// Derive from the initial key material `ikm` the KEM keys used as inputs to 452 /// [hpke_setup_r](CipherSuiteProvider::hpke_setup_r), 453 /// [hpke_setup_s](CipherSuiteProvider::hpke_setup_s), [hpke_seal](CipherSuiteProvider::hpke_seal) 454 /// and [hpke_open](CipherSuiteProvider::hpke_open). kem_derive(&self, ikm: &[u8]) -> Result<(HpkeSecretKey, HpkePublicKey), Self::Error>455 async fn kem_derive(&self, ikm: &[u8]) -> Result<(HpkeSecretKey, HpkePublicKey), Self::Error>; 456 457 /// Generate fresh KEM keys to be used as inputs to [hpke_setup_r](CipherSuiteProvider::hpke_setup_r), 458 /// [hpke_setup_s](CipherSuiteProvider::hpke_setup_s), [hpke_seal](CipherSuiteProvider::hpke_seal) 459 /// and [hpke_open](CipherSuiteProvider::hpke_open). kem_generate(&self) -> Result<(HpkeSecretKey, HpkePublicKey), Self::Error>460 async fn kem_generate(&self) -> Result<(HpkeSecretKey, HpkePublicKey), Self::Error>; 461 462 /// Verify that the given byte vector `key` can be decoded as an HPKE public key. kem_public_key_validate(&self, key: &HpkePublicKey) -> Result<(), Self::Error>463 fn kem_public_key_validate(&self, key: &HpkePublicKey) -> Result<(), Self::Error>; 464 465 /// Fill `out` with random bytes. random_bytes(&self, out: &mut [u8]) -> Result<(), Self::Error>466 fn random_bytes(&self, out: &mut [u8]) -> Result<(), Self::Error>; 467 468 /// Generate `count` bytes of pseudorandom bytes as a vector. This is a shortcut for 469 /// creating a `Vec<u8>` of `count` bytes and calling [random_bytes](CipherSuiteProvider::random_bytes). random_bytes_vec(&self, count: usize) -> Result<Vec<u8>, Self::Error>470 fn random_bytes_vec(&self, count: usize) -> Result<Vec<u8>, Self::Error> { 471 let mut vec = vec![0u8; count]; 472 self.random_bytes(&mut vec)?; 473 474 Ok(vec) 475 } 476 477 /// Generate fresh signature keys to be used as inputs to [sign](CipherSuiteProvider::sign) 478 /// and [verify](CipherSuiteProvider::verify) signature_key_generate( &self, ) -> Result<(SignatureSecretKey, SignaturePublicKey), Self::Error>479 async fn signature_key_generate( 480 &self, 481 ) -> Result<(SignatureSecretKey, SignaturePublicKey), Self::Error>; 482 483 /// Output a public key corresponding to `secret_key`. signature_key_derive_public( &self, secret_key: &SignatureSecretKey, ) -> Result<SignaturePublicKey, Self::Error>484 async fn signature_key_derive_public( 485 &self, 486 secret_key: &SignatureSecretKey, 487 ) -> Result<SignaturePublicKey, Self::Error>; 488 489 /// Sign `data` using `secret_key`. sign( &self, secret_key: &SignatureSecretKey, data: &[u8], ) -> Result<Vec<u8>, Self::Error>490 async fn sign( 491 &self, 492 secret_key: &SignatureSecretKey, 493 data: &[u8], 494 ) -> Result<Vec<u8>, Self::Error>; 495 496 /// Verify that the secret key corresponding to `public_key` created the `signature` over `data`. verify( &self, public_key: &SignaturePublicKey, signature: &[u8], data: &[u8], ) -> Result<(), Self::Error>497 async fn verify( 498 &self, 499 public_key: &SignaturePublicKey, 500 signature: &[u8], 501 data: &[u8], 502 ) -> Result<(), Self::Error>; 503 } 504