1 // Copyright 2023 Google LLC 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 //! Cryptographic materials for v1 advertisement-format credentials. 16 17 use crate::credential::{protocol_version_seal, DiscoveryMetadataCryptoMaterial, ProtocolVersion}; 18 use crate::extended::V1IdentityToken; 19 use crypto_provider::{aead::Aead, aes, ed25519, CryptoProvider}; 20 use np_hkdf::{DerivedSectionKeys, NpKeySeedHkdf}; 21 22 /// Cryptographic information about a particular V1 discovery credential 23 /// necessary to match and decrypt encrypted V1 sections. 24 #[derive(Clone, Debug, PartialEq, Eq)] 25 pub struct V1DiscoveryCredential { 26 /// The 32-byte key-seed used for generating other key material. 27 pub key_seed: [u8; 32], 28 29 /// The MIC-short-salt variant of the HMAC of the identity token. 30 pub expected_mic_short_salt_identity_token_hmac: [u8; 32], 31 32 /// The MIC-extended-salt variant of the HMAC of the identity token. 33 pub expected_mic_extended_salt_identity_token_hmac: [u8; 32], 34 35 /// The signed-extended-salt variant of the HMAC of the identity token. 36 pub expected_signed_extended_salt_identity_token_hmac: [u8; 32], 37 38 /// The ed25519 public key used for verification of signed sections. 39 pub public_key: ed25519::PublicKey, 40 } 41 42 impl V1DiscoveryCredential { 43 /// Construct a V1 discovery credential from the provided identity data. new( key_seed: [u8; 32], expected_mic_short_salt_identity_token_hmac: [u8; 32], expected_mic_extended_salt_identity_token_hmac: [u8; 32], expected_signed_extended_salt_identity_token_hmac: [u8; 32], public_key: ed25519::PublicKey, ) -> Self44 pub fn new( 45 key_seed: [u8; 32], 46 expected_mic_short_salt_identity_token_hmac: [u8; 32], 47 expected_mic_extended_salt_identity_token_hmac: [u8; 32], 48 expected_signed_extended_salt_identity_token_hmac: [u8; 32], 49 public_key: ed25519::PublicKey, 50 ) -> Self { 51 Self { 52 key_seed, 53 expected_mic_short_salt_identity_token_hmac, 54 expected_mic_extended_salt_identity_token_hmac, 55 expected_signed_extended_salt_identity_token_hmac, 56 public_key, 57 } 58 } 59 60 /// Constructs pre-calculated crypto material from this discovery credential. to_precalculated<C: CryptoProvider>( &self, ) -> PrecalculatedV1DiscoveryCryptoMaterial61 pub(crate) fn to_precalculated<C: CryptoProvider>( 62 &self, 63 ) -> PrecalculatedV1DiscoveryCryptoMaterial { 64 PrecalculatedV1DiscoveryCryptoMaterial { 65 signed_identity_resolution_material: self.signed_identity_resolution_material::<C>(), 66 mic_short_salt_identity_resolution_material: self 67 .mic_short_salt_identity_resolution_material::<C>(), 68 mic_extended_salt_identity_resolution_material: self 69 .mic_extended_salt_identity_resolution_material::<C>(), 70 signed_verification_material: self.signed_verification_material::<C>(), 71 mic_short_salt_verification_material: self.mic_short_salt_verification_material::<C>(), 72 mic_extended_salt_verification_material: self 73 .mic_extended_salt_verification_material::<C>(), 74 metadata_nonce: self.metadata_nonce::<C>(), 75 } 76 } 77 } 78 79 impl DiscoveryMetadataCryptoMaterial<V1> for V1DiscoveryCredential { metadata_nonce<C: CryptoProvider>(&self) -> [u8; 12]80 fn metadata_nonce<C: CryptoProvider>(&self) -> [u8; 12] { 81 np_hkdf::NpKeySeedHkdf::<C>::new(&self.key_seed).v1_metadata_nonce() 82 } 83 } 84 85 impl V1DiscoveryCryptoMaterial for V1DiscoveryCredential { signed_identity_resolution_material<C: CryptoProvider>( &self, ) -> SignedSectionIdentityResolutionMaterial86 fn signed_identity_resolution_material<C: CryptoProvider>( 87 &self, 88 ) -> SignedSectionIdentityResolutionMaterial { 89 let hkdf = np_hkdf::NpKeySeedHkdf::<C>::new(&self.key_seed); 90 SignedSectionIdentityResolutionMaterial::from_hkdf_and_expected_identity_token_hmac( 91 &hkdf, 92 self.expected_signed_extended_salt_identity_token_hmac, 93 ) 94 } 95 mic_short_salt_identity_resolution_material<C: CryptoProvider>( &self, ) -> MicShortSaltSectionIdentityResolutionMaterial96 fn mic_short_salt_identity_resolution_material<C: CryptoProvider>( 97 &self, 98 ) -> MicShortSaltSectionIdentityResolutionMaterial { 99 let hkdf = np_hkdf::NpKeySeedHkdf::<C>::new(&self.key_seed); 100 MicShortSaltSectionIdentityResolutionMaterial::from_hkdf_and_expected_identity_token_hmac( 101 &hkdf, 102 self.expected_mic_short_salt_identity_token_hmac, 103 ) 104 } 105 mic_extended_salt_identity_resolution_material<C: CryptoProvider>( &self, ) -> MicExtendedSaltSectionIdentityResolutionMaterial106 fn mic_extended_salt_identity_resolution_material<C: CryptoProvider>( 107 &self, 108 ) -> MicExtendedSaltSectionIdentityResolutionMaterial { 109 let hkdf = np_hkdf::NpKeySeedHkdf::<C>::new(&self.key_seed); 110 MicExtendedSaltSectionIdentityResolutionMaterial::from_hkdf_and_expected_identity_token_hmac( 111 &hkdf, 112 self.expected_mic_extended_salt_identity_token_hmac, 113 ) 114 } 115 signed_verification_material<C: CryptoProvider>(&self) -> SignedSectionVerificationMaterial116 fn signed_verification_material<C: CryptoProvider>(&self) -> SignedSectionVerificationMaterial { 117 SignedSectionVerificationMaterial { public_key: self.public_key.clone() } 118 } 119 mic_short_salt_verification_material<C: CryptoProvider>( &self, ) -> MicShortSaltSectionVerificationMaterial120 fn mic_short_salt_verification_material<C: CryptoProvider>( 121 &self, 122 ) -> MicShortSaltSectionVerificationMaterial { 123 let hkdf = np_hkdf::NpKeySeedHkdf::<C>::new(&self.key_seed); 124 let mic_hmac_key = *hkdf.v1_mic_short_salt_keys().mic_hmac_key().as_bytes(); 125 MicShortSaltSectionVerificationMaterial { mic_hmac_key } 126 } 127 mic_extended_salt_verification_material<C: CryptoProvider>( &self, ) -> MicExtendedSaltSectionVerificationMaterial128 fn mic_extended_salt_verification_material<C: CryptoProvider>( 129 &self, 130 ) -> MicExtendedSaltSectionVerificationMaterial { 131 let hkdf = np_hkdf::NpKeySeedHkdf::<C>::new(&self.key_seed); 132 let mic_hmac_key = *hkdf.v1_mic_extended_salt_keys().mic_hmac_key().as_bytes(); 133 MicExtendedSaltSectionVerificationMaterial { mic_hmac_key } 134 } 135 } 136 137 /// Type-level identifier for the V1 protocol version. 138 #[derive(Debug, Clone)] 139 pub enum V1 {} 140 141 impl protocol_version_seal::ProtocolVersionSeal for V1 {} 142 143 impl ProtocolVersion for V1 { 144 type DiscoveryCredential = V1DiscoveryCredential; 145 type IdentityToken = V1IdentityToken; 146 metadata_nonce_from_key_seed<C: CryptoProvider>( hkdf: &NpKeySeedHkdf<C>, ) -> <C::Aes128Gcm as Aead>::Nonce147 fn metadata_nonce_from_key_seed<C: CryptoProvider>( 148 hkdf: &NpKeySeedHkdf<C>, 149 ) -> <C::Aes128Gcm as Aead>::Nonce { 150 hkdf.v1_metadata_nonce() 151 } 152 extract_metadata_key<C: CryptoProvider>( identity_token: Self::IdentityToken, ) -> aes::Aes128Key153 fn extract_metadata_key<C: CryptoProvider>( 154 identity_token: Self::IdentityToken, 155 ) -> aes::Aes128Key { 156 identity_token.into_bytes().into() 157 } 158 } 159 160 /// Trait which exists purely to be able to restrict the protocol 161 /// version of certain type-bounds to V1. 162 pub trait V1ProtocolVersion: ProtocolVersion {} 163 164 impl V1ProtocolVersion for V1 {} 165 166 /// Cryptographic materials necessary for determining whether or not 167 /// a given V1 advertisement section matches an identity. 168 /// Per the construction of the V1 specification, this is also 169 /// the information necessary to decrypt the raw byte contents 170 /// of an encrypted V1 section. 171 #[derive(Clone)] 172 pub(crate) struct SectionIdentityResolutionMaterial { 173 /// The AES key for decrypting section ciphertext 174 pub(crate) aes_key: aes::Aes128Key, 175 /// The identity token HMAC key for deriving and verifying the identity metadata 176 /// key HMAC against the expected value. 177 pub(crate) identity_token_hmac_key: [u8; 32], 178 /// The expected identity token HMAC to check against for an identity match. 179 pub(crate) expected_identity_token_hmac: [u8; 32], 180 } 181 182 /// Cryptographic materials necessary for determining whether or not 183 /// a given V1 signed advertisement section matches an identity. 184 #[derive(Clone)] 185 pub struct SignedSectionIdentityResolutionMaterial(SectionIdentityResolutionMaterial); 186 187 impl SignedSectionIdentityResolutionMaterial { 188 #[cfg(test)] from_raw(raw: SectionIdentityResolutionMaterial) -> Self189 pub(crate) fn from_raw(raw: SectionIdentityResolutionMaterial) -> Self { 190 Self(raw) 191 } 192 /// Extracts the underlying section-identity resolution material carried around 193 /// within this wrapper for resolution of signed sections. into_raw_resolution_material(self) -> SectionIdentityResolutionMaterial194 pub(crate) fn into_raw_resolution_material(self) -> SectionIdentityResolutionMaterial { 195 self.0 196 } 197 #[cfg(any(test, feature = "devtools"))] 198 /// Gets the underlying section-identity resolution material carried around 199 /// within this wrapper for resolution of signed sections. as_raw_resolution_material(&self) -> &SectionIdentityResolutionMaterial200 pub(crate) fn as_raw_resolution_material(&self) -> &SectionIdentityResolutionMaterial { 201 &self.0 202 } 203 204 /// Constructs identity-resolution material for a signed section whose 205 /// discovery credential leverages the provided HKDF and has the given 206 /// expected metadata-key HMAC. from_hkdf_and_expected_identity_token_hmac<C: CryptoProvider>( hkdf: &np_hkdf::NpKeySeedHkdf<C>, expected_identity_token_hmac: [u8; 32], ) -> Self207 pub(crate) fn from_hkdf_and_expected_identity_token_hmac<C: CryptoProvider>( 208 hkdf: &np_hkdf::NpKeySeedHkdf<C>, 209 expected_identity_token_hmac: [u8; 32], 210 ) -> Self { 211 Self(SectionIdentityResolutionMaterial { 212 aes_key: hkdf.v1_signature_keys().aes_key(), 213 identity_token_hmac_key: *hkdf.v1_signature_keys().identity_token_hmac_key().as_bytes(), 214 expected_identity_token_hmac, 215 }) 216 } 217 } 218 219 /// Cryptographic materials necessary for determining whether or not 220 /// a given V1 MIC extended salt advertisement section matches an identity. 221 #[derive(Clone)] 222 pub struct MicExtendedSaltSectionIdentityResolutionMaterial(SectionIdentityResolutionMaterial); 223 224 impl MicExtendedSaltSectionIdentityResolutionMaterial { 225 /// Extracts the underlying section-identity resolution material carried around 226 /// within this wrapper for resolution of MIC extended salt sections. into_raw_resolution_material(self) -> SectionIdentityResolutionMaterial227 pub(crate) fn into_raw_resolution_material(self) -> SectionIdentityResolutionMaterial { 228 self.0 229 } 230 /// Gets the underlying section-identity resolution material carried around 231 /// within this wrapper for resolution of MIC extended salt sections. 232 #[cfg(any(test, feature = "devtools"))] as_raw_resolution_material(&self) -> &SectionIdentityResolutionMaterial233 pub(crate) fn as_raw_resolution_material(&self) -> &SectionIdentityResolutionMaterial { 234 &self.0 235 } 236 #[cfg(test)] as_mut_raw_resolution_material( &mut self, ) -> &mut SectionIdentityResolutionMaterial237 pub(crate) fn as_mut_raw_resolution_material( 238 &mut self, 239 ) -> &mut SectionIdentityResolutionMaterial { 240 &mut self.0 241 } 242 /// Constructs identity-resolution material for an MIC extended salt section whose 243 /// discovery credential leverages the provided HKDF and has the given 244 /// expected metadata-key HMAC. from_hkdf_and_expected_identity_token_hmac<C: CryptoProvider>( hkdf: &np_hkdf::NpKeySeedHkdf<C>, expected_identity_token_hmac: [u8; 32], ) -> Self245 pub(crate) fn from_hkdf_and_expected_identity_token_hmac<C: CryptoProvider>( 246 hkdf: &np_hkdf::NpKeySeedHkdf<C>, 247 expected_identity_token_hmac: [u8; 32], 248 ) -> Self { 249 Self(SectionIdentityResolutionMaterial { 250 aes_key: hkdf.v1_mic_extended_salt_keys().aes_key(), 251 identity_token_hmac_key: *hkdf 252 .v1_mic_extended_salt_keys() 253 .identity_token_hmac_key() 254 .as_bytes(), 255 expected_identity_token_hmac, 256 }) 257 } 258 } 259 260 /// Cryptographic materials necessary for determining whether 261 /// a given V1 MIC short salt advertisement section matches an identity. 262 #[derive(Clone)] 263 pub struct MicShortSaltSectionIdentityResolutionMaterial(SectionIdentityResolutionMaterial); 264 265 impl MicShortSaltSectionIdentityResolutionMaterial { 266 /// Extracts the underlying section-identity resolution material carried around 267 /// within this wrapper for resolution of MIC short salt sections. into_raw_resolution_material(self) -> SectionIdentityResolutionMaterial268 pub(crate) fn into_raw_resolution_material(self) -> SectionIdentityResolutionMaterial { 269 self.0 270 } 271 /// Gets the underlying section-identity resolution material carried around 272 /// within this wrapper for resolution of MIC short salt sections. 273 #[cfg(any(test, feature = "devtools"))] as_raw_resolution_material(&self) -> &SectionIdentityResolutionMaterial274 pub(crate) fn as_raw_resolution_material(&self) -> &SectionIdentityResolutionMaterial { 275 &self.0 276 } 277 #[cfg(test)] as_mut_raw_resolution_material( &mut self, ) -> &mut SectionIdentityResolutionMaterial278 pub(crate) fn as_mut_raw_resolution_material( 279 &mut self, 280 ) -> &mut SectionIdentityResolutionMaterial { 281 &mut self.0 282 } 283 284 /// Constructs identity-resolution material for a MIC short salt section whose 285 /// discovery credential leverages the provided HKDF and has the given 286 /// expected metadata-key HMAC. from_hkdf_and_expected_identity_token_hmac<C: CryptoProvider>( hkdf: &np_hkdf::NpKeySeedHkdf<C>, expected_identity_token_hmac: [u8; 32], ) -> Self287 pub(crate) fn from_hkdf_and_expected_identity_token_hmac<C: CryptoProvider>( 288 hkdf: &np_hkdf::NpKeySeedHkdf<C>, 289 expected_identity_token_hmac: [u8; 32], 290 ) -> Self { 291 Self(SectionIdentityResolutionMaterial { 292 aes_key: hkdf.v1_mic_short_salt_keys().aes_key(), 293 identity_token_hmac_key: *hkdf 294 .v1_mic_short_salt_keys() 295 .identity_token_hmac_key() 296 .as_bytes(), 297 expected_identity_token_hmac, 298 }) 299 } 300 } 301 302 /// Crypto materials for V1 signed sections which are not employed in identity resolution, 303 /// but may be necessary to verify a signed section. 304 #[derive(Clone)] 305 pub struct SignedSectionVerificationMaterial { 306 /// The np_ed25519 public key to be 307 /// used for signature verification of signed sections. 308 pub(crate) public_key: ed25519::PublicKey, 309 } 310 311 impl SignedSectionVerificationMaterial { 312 /// Gets the np_ed25519 public key for the given identity, 313 /// used for signature verification of signed sections. signature_verification_public_key(&self) -> ed25519::PublicKey314 pub(crate) fn signature_verification_public_key(&self) -> ed25519::PublicKey { 315 self.public_key.clone() 316 } 317 } 318 319 /// Crypto materials for V1 MIC short salt sections which are not employed in identity resolution, 320 /// but may be necessary to fully decrypt a MIC short salt section. 321 #[derive(Clone)] 322 pub struct MicShortSaltSectionVerificationMaterial { 323 /// The MIC HMAC key for verifying the integrity of MIC short salt sections. 324 pub(crate) mic_hmac_key: [u8; 32], 325 } 326 327 impl MicSectionVerificationMaterial for MicShortSaltSectionVerificationMaterial { mic_hmac_key(&self) -> np_hkdf::NpHmacSha256Key328 fn mic_hmac_key(&self) -> np_hkdf::NpHmacSha256Key { 329 self.mic_hmac_key.into() 330 } 331 } 332 333 /// Crypto materials for V1 MIC extended salt sections which are not employed in identity 334 /// resolution, but may be necessary to fully decrypt a MIC extended salt section. 335 #[derive(Clone)] 336 pub struct MicExtendedSaltSectionVerificationMaterial { 337 /// The MIC HMAC key for verifying the integrity of MIC extended salt sections. 338 pub(crate) mic_hmac_key: [u8; 32], 339 } 340 341 impl MicSectionVerificationMaterial for MicExtendedSaltSectionVerificationMaterial { mic_hmac_key(&self) -> np_hkdf::NpHmacSha256Key342 fn mic_hmac_key(&self) -> np_hkdf::NpHmacSha256Key { 343 self.mic_hmac_key.into() 344 } 345 } 346 347 pub(crate) trait MicSectionVerificationMaterial { 348 /// Returns the HMAC key for calculating the MIC of the sections mic_hmac_key(&self) -> np_hkdf::NpHmacSha256Key349 fn mic_hmac_key(&self) -> np_hkdf::NpHmacSha256Key; 350 } 351 352 // Space-time tradeoffs: 353 // - Calculating an HKDF from the key seed costs about 2us on a gLinux laptop, and occupies 80b. 354 // - Calculating an AES (16b) or HMAC (32b) key from the HKDF costs about 700ns. 355 // The right tradeoff may also vary by use case. For frequently used identities we should 356 // probably pre-calculate everything. For occasionally used ones, or ones that are loaded from 357 // disk, used once, and discarded, we might want to precalculate on a separate thread or the 358 // like. 359 // The AES key and metadata key HMAC key are the most frequently used ones, as the MIC HMAC key 360 // is only used on the matching identity, not all identities. 361 362 /// Cryptographic material for an individual NP credential used to decrypt and verify v1 sections. 363 pub trait V1DiscoveryCryptoMaterial: DiscoveryMetadataCryptoMaterial<V1> { 364 /// Constructs or copies the identity resolution material for signed sections signed_identity_resolution_material<C: CryptoProvider>( &self, ) -> SignedSectionIdentityResolutionMaterial365 fn signed_identity_resolution_material<C: CryptoProvider>( 366 &self, 367 ) -> SignedSectionIdentityResolutionMaterial; 368 369 /// Constructs or copies the identity resolution material for MIC short salt sections mic_short_salt_identity_resolution_material<C: CryptoProvider>( &self, ) -> MicShortSaltSectionIdentityResolutionMaterial370 fn mic_short_salt_identity_resolution_material<C: CryptoProvider>( 371 &self, 372 ) -> MicShortSaltSectionIdentityResolutionMaterial; 373 374 /// Constructs or copies the identity resolution material for MIC extended salt sections mic_extended_salt_identity_resolution_material<C: CryptoProvider>( &self, ) -> MicExtendedSaltSectionIdentityResolutionMaterial375 fn mic_extended_salt_identity_resolution_material<C: CryptoProvider>( 376 &self, 377 ) -> MicExtendedSaltSectionIdentityResolutionMaterial; 378 379 /// Constructs or copies non-identity-resolution deserialization material for signed 380 /// sections. signed_verification_material<C: CryptoProvider>(&self) -> SignedSectionVerificationMaterial381 fn signed_verification_material<C: CryptoProvider>(&self) -> SignedSectionVerificationMaterial; 382 383 /// Constructs or copies non-identity-resolution deserialization material for MIC short salt 384 /// sections. mic_short_salt_verification_material<C: CryptoProvider>( &self, ) -> MicShortSaltSectionVerificationMaterial385 fn mic_short_salt_verification_material<C: CryptoProvider>( 386 &self, 387 ) -> MicShortSaltSectionVerificationMaterial; 388 389 /// Constructs or copies non-identity-resolution deserialization material for MIC extended salt 390 /// sections. mic_extended_salt_verification_material<C: CryptoProvider>( &self, ) -> MicExtendedSaltSectionVerificationMaterial391 fn mic_extended_salt_verification_material<C: CryptoProvider>( 392 &self, 393 ) -> MicExtendedSaltSectionVerificationMaterial; 394 } 395 396 /// [`V1DiscoveryCryptoMaterial`] that minimizes CPU time when providing key material at 397 /// the expense of occupied memory 398 pub struct PrecalculatedV1DiscoveryCryptoMaterial { 399 pub(crate) signed_identity_resolution_material: SignedSectionIdentityResolutionMaterial, 400 pub(crate) mic_short_salt_identity_resolution_material: 401 MicShortSaltSectionIdentityResolutionMaterial, 402 pub(crate) mic_extended_salt_identity_resolution_material: 403 MicExtendedSaltSectionIdentityResolutionMaterial, 404 pub(crate) signed_verification_material: SignedSectionVerificationMaterial, 405 pub(crate) mic_short_salt_verification_material: MicShortSaltSectionVerificationMaterial, 406 pub(crate) mic_extended_salt_verification_material: MicExtendedSaltSectionVerificationMaterial, 407 pub(crate) metadata_nonce: [u8; 12], 408 } 409 410 impl DiscoveryMetadataCryptoMaterial<V1> for PrecalculatedV1DiscoveryCryptoMaterial { metadata_nonce<C: CryptoProvider>(&self) -> [u8; 12]411 fn metadata_nonce<C: CryptoProvider>(&self) -> [u8; 12] { 412 self.metadata_nonce 413 } 414 } 415 416 impl V1DiscoveryCryptoMaterial for PrecalculatedV1DiscoveryCryptoMaterial { signed_identity_resolution_material<C: CryptoProvider>( &self, ) -> SignedSectionIdentityResolutionMaterial417 fn signed_identity_resolution_material<C: CryptoProvider>( 418 &self, 419 ) -> SignedSectionIdentityResolutionMaterial { 420 self.signed_identity_resolution_material.clone() 421 } 422 mic_short_salt_identity_resolution_material<C: CryptoProvider>( &self, ) -> MicShortSaltSectionIdentityResolutionMaterial423 fn mic_short_salt_identity_resolution_material<C: CryptoProvider>( 424 &self, 425 ) -> MicShortSaltSectionIdentityResolutionMaterial { 426 self.mic_short_salt_identity_resolution_material.clone() 427 } 428 mic_extended_salt_identity_resolution_material<C: CryptoProvider>( &self, ) -> MicExtendedSaltSectionIdentityResolutionMaterial429 fn mic_extended_salt_identity_resolution_material<C: CryptoProvider>( 430 &self, 431 ) -> MicExtendedSaltSectionIdentityResolutionMaterial { 432 self.mic_extended_salt_identity_resolution_material.clone() 433 } signed_verification_material<C: CryptoProvider>(&self) -> SignedSectionVerificationMaterial434 fn signed_verification_material<C: CryptoProvider>(&self) -> SignedSectionVerificationMaterial { 435 self.signed_verification_material.clone() 436 } 437 mic_short_salt_verification_material<C: CryptoProvider>( &self, ) -> MicShortSaltSectionVerificationMaterial438 fn mic_short_salt_verification_material<C: CryptoProvider>( 439 &self, 440 ) -> MicShortSaltSectionVerificationMaterial { 441 self.mic_short_salt_verification_material.clone() 442 } 443 mic_extended_salt_verification_material<C: CryptoProvider>( &self, ) -> MicExtendedSaltSectionVerificationMaterial444 fn mic_extended_salt_verification_material<C: CryptoProvider>( 445 &self, 446 ) -> MicExtendedSaltSectionVerificationMaterial { 447 self.mic_extended_salt_verification_material.clone() 448 } 449 } 450 451 // Implementations for reference types -- we don't provide a blanket impl for references 452 // due to the potential to conflict with downstream crates' implementations. 453 454 impl<'a> DiscoveryMetadataCryptoMaterial<V1> for &'a V1DiscoveryCredential { metadata_nonce<C: CryptoProvider>(&self) -> [u8; 12]455 fn metadata_nonce<C: CryptoProvider>(&self) -> [u8; 12] { 456 (*self).metadata_nonce::<C>() 457 } 458 } 459 460 impl<'a> V1DiscoveryCryptoMaterial for &'a V1DiscoveryCredential { signed_identity_resolution_material<C: CryptoProvider>( &self, ) -> SignedSectionIdentityResolutionMaterial461 fn signed_identity_resolution_material<C: CryptoProvider>( 462 &self, 463 ) -> SignedSectionIdentityResolutionMaterial { 464 (*self).signed_identity_resolution_material::<C>() 465 } 466 mic_short_salt_identity_resolution_material<C: CryptoProvider>( &self, ) -> MicShortSaltSectionIdentityResolutionMaterial467 fn mic_short_salt_identity_resolution_material<C: CryptoProvider>( 468 &self, 469 ) -> MicShortSaltSectionIdentityResolutionMaterial { 470 (*self).mic_short_salt_identity_resolution_material::<C>() 471 } 472 mic_extended_salt_identity_resolution_material<C: CryptoProvider>( &self, ) -> MicExtendedSaltSectionIdentityResolutionMaterial473 fn mic_extended_salt_identity_resolution_material<C: CryptoProvider>( 474 &self, 475 ) -> MicExtendedSaltSectionIdentityResolutionMaterial { 476 (*self).mic_extended_salt_identity_resolution_material::<C>() 477 } signed_verification_material<C: CryptoProvider>(&self) -> SignedSectionVerificationMaterial478 fn signed_verification_material<C: CryptoProvider>(&self) -> SignedSectionVerificationMaterial { 479 (*self).signed_verification_material::<C>() 480 } 481 mic_short_salt_verification_material<C: CryptoProvider>( &self, ) -> MicShortSaltSectionVerificationMaterial482 fn mic_short_salt_verification_material<C: CryptoProvider>( 483 &self, 484 ) -> MicShortSaltSectionVerificationMaterial { 485 (*self).mic_short_salt_verification_material::<C>() 486 } 487 mic_extended_salt_verification_material<C: CryptoProvider>( &self, ) -> MicExtendedSaltSectionVerificationMaterial488 fn mic_extended_salt_verification_material<C: CryptoProvider>( 489 &self, 490 ) -> MicExtendedSaltSectionVerificationMaterial { 491 (*self).mic_extended_salt_verification_material::<C>() 492 } 493 } 494 495 impl<'a> DiscoveryMetadataCryptoMaterial<V1> for &'a PrecalculatedV1DiscoveryCryptoMaterial { metadata_nonce<C: CryptoProvider>(&self) -> [u8; 12]496 fn metadata_nonce<C: CryptoProvider>(&self) -> [u8; 12] { 497 (*self).metadata_nonce::<C>() 498 } 499 } 500 501 impl<'a> V1DiscoveryCryptoMaterial for &'a PrecalculatedV1DiscoveryCryptoMaterial { signed_identity_resolution_material<C: CryptoProvider>( &self, ) -> SignedSectionIdentityResolutionMaterial502 fn signed_identity_resolution_material<C: CryptoProvider>( 503 &self, 504 ) -> SignedSectionIdentityResolutionMaterial { 505 (*self).signed_identity_resolution_material::<C>() 506 } 507 mic_short_salt_identity_resolution_material<C: CryptoProvider>( &self, ) -> MicShortSaltSectionIdentityResolutionMaterial508 fn mic_short_salt_identity_resolution_material<C: CryptoProvider>( 509 &self, 510 ) -> MicShortSaltSectionIdentityResolutionMaterial { 511 (*self).mic_short_salt_identity_resolution_material::<C>() 512 } 513 mic_extended_salt_identity_resolution_material<C: CryptoProvider>( &self, ) -> MicExtendedSaltSectionIdentityResolutionMaterial514 fn mic_extended_salt_identity_resolution_material<C: CryptoProvider>( 515 &self, 516 ) -> MicExtendedSaltSectionIdentityResolutionMaterial { 517 (*self).mic_extended_salt_identity_resolution_material::<C>() 518 } signed_verification_material<C: CryptoProvider>(&self) -> SignedSectionVerificationMaterial519 fn signed_verification_material<C: CryptoProvider>(&self) -> SignedSectionVerificationMaterial { 520 (*self).signed_verification_material::<C>() 521 } 522 mic_short_salt_verification_material<C: CryptoProvider>( &self, ) -> MicShortSaltSectionVerificationMaterial523 fn mic_short_salt_verification_material<C: CryptoProvider>( 524 &self, 525 ) -> MicShortSaltSectionVerificationMaterial { 526 (*self).mic_short_salt_verification_material::<C>() 527 } 528 mic_extended_salt_verification_material<C: CryptoProvider>( &self, ) -> MicExtendedSaltSectionVerificationMaterial529 fn mic_extended_salt_verification_material<C: CryptoProvider>( 530 &self, 531 ) -> MicExtendedSaltSectionVerificationMaterial { 532 (*self).mic_extended_salt_verification_material::<C>() 533 } 534 } 535 536 /// Crypto material for creating V1 sections. 537 #[derive(Clone)] 538 pub struct V1BroadcastCredential { 539 /// The 32-byte key-seed used for generating other key material. 540 pub key_seed: [u8; 32], 541 542 /// The 16-byte identity-token which identifies the sender. 543 pub identity_token: V1IdentityToken, 544 545 /// The ed25519 private key to be used for signing section contents. 546 pub private_key: ed25519::PrivateKey, 547 } 548 549 impl V1BroadcastCredential { 550 /// Builds some simple V1 signed broadcast crypto-materials out of 551 /// the provided key-seed, metadata-key, and ed25519 private key. new( key_seed: [u8; 32], identity_token: V1IdentityToken, private_key: ed25519::PrivateKey, ) -> Self552 pub fn new( 553 key_seed: [u8; 32], 554 identity_token: V1IdentityToken, 555 private_key: ed25519::PrivateKey, 556 ) -> Self { 557 Self { key_seed, identity_token, private_key } 558 } 559 560 /// Key seed from which other keys are derived. key_seed(&self) -> [u8; 32]561 pub(crate) fn key_seed(&self) -> [u8; 32] { 562 self.key_seed 563 } 564 565 /// Identity token that will be incorporated into encrypted advertisements. identity_token(&self) -> V1IdentityToken566 pub(crate) fn identity_token(&self) -> V1IdentityToken { 567 self.identity_token 568 } 569 570 /// Derive a discovery credential with the data necessary to discover advertisements produced 571 /// by this broadcast credential. derive_discovery_credential<C: CryptoProvider>(&self) -> V1DiscoveryCredential572 pub fn derive_discovery_credential<C: CryptoProvider>(&self) -> V1DiscoveryCredential { 573 let key_seed = self.key_seed(); 574 let hkdf = np_hkdf::NpKeySeedHkdf::<C>::new(&key_seed); 575 576 V1DiscoveryCredential::new( 577 key_seed, 578 hkdf.v1_mic_short_salt_keys() 579 .identity_token_hmac_key() 580 .calculate_hmac::<C>(self.identity_token.as_slice()), 581 hkdf.v1_mic_extended_salt_keys() 582 .identity_token_hmac_key() 583 .calculate_hmac::<C>(self.identity_token.as_slice()), 584 hkdf.v1_signature_keys() 585 .identity_token_hmac_key() 586 .calculate_hmac::<C>(self.identity_token.as_slice()), 587 self.signing_key().derive_public_key::<C::Ed25519>(), 588 ) 589 } 590 591 /// Key used for signature-protected sections signing_key(&self) -> ed25519::PrivateKey592 pub(crate) fn signing_key(&self) -> ed25519::PrivateKey { 593 self.private_key.clone() 594 } 595 } 596