1use core::{borrow::Borrow, fmt, result::Result};
6
7use aes_gcm::{
8 aead::{AeadInPlace, KeyInit, KeySizeUser},
9 A_MAX, C_MAX, P_MAX,
10};
11use crypto_common::BlockSizeUser;
12use ecdsa::{
13 der,
14 signature::{Signer as Signer_, Verifier},
15};
16use elliptic_curve::{
17 ecdh,
18 scalar::NonZeroScalar,
19 sec1::{EncodedPoint, FromEncodedPoint, ToEncodedPoint},
20 CurveArithmetic, FieldBytesSize,
21};
22use rand_core::{impls, CryptoRng, RngCore};
23use sha2::digest::OutputSizeUser;
24use subtle::{Choice, ConstantTimeEq};
25use typenum::{Unsigned, U12, U16};
26
27use crate::{
28 aead::{
29 check_open_in_place_params, check_seal_in_place_params, Aead, AeadKey, IndCca2, Lifetime,
30 OpenError, SealError,
31 },
32 block::BlockSize,
33 csprng::{Csprng, Random},
34 ec::{Curve, Secp256r1, Secp384r1},
35 hash::{Digest, Hash},
36 hex::{Hex, ToHex},
37 hkdf::hkdf_impl,
38 hmac::hmac_impl,
39 hpke::{AeadId, HpkeAead, KdfId, KemId},
40 import::{try_from_slice, ExportError, Import, ImportError},
41 kem::{dhkem_impl, DecapKey, Ecdh, EcdhError, EncapKey},
42 keys::{PublicKey, SecretKey, SecretKeyBytes},
43 oid::{
44 consts::{
45 AES_256_GCM, ECDSA_WITH_SHA2_256, ECDSA_WITH_SHA2_384, HKDF_WITH_SHA2_256,
46 HKDF_WITH_SHA2_384, HKDF_WITH_SHA2_512, HMAC_WITH_SHA2_256, HMAC_WITH_SHA2_384,
47 HMAC_WITH_SHA2_512, HMAC_WITH_SHA2_512_256, SECP256R1, SECP384R1, SHA2_256, SHA2_384,
48 SHA2_512, SHA2_512_256,
49 },
50 Identified, Oid,
51 },
52 signer::{Signature, Signer, SignerError, SigningKey, VerifyingKey},
53 zeroize::{is_zeroize_on_drop, Zeroize, ZeroizeOnDrop},
54};
55
56#[cfg_attr(feature = "clone-aead", derive(Clone))]
58pub struct Aes256Gcm(aes_gcm::Aes256Gcm);
59
60impl Aead for Aes256Gcm {
61 const LIFETIME: Lifetime = Lifetime::Messages(u32::MAX as u64);
63
64 type KeySize = <aes_gcm::Aes256Gcm as KeySizeUser>::KeySize;
65 type NonceSize = U12;
66 type Overhead = U16; const MAX_PLAINTEXT_SIZE: u64 = P_MAX;
69 const MAX_ADDITIONAL_DATA_SIZE: u64 = A_MAX;
70 const MAX_CIPHERTEXT_SIZE: u64 = C_MAX;
71
72 type Key = AeadKey<Self::KeySize>;
73
74 #[inline]
75 fn new(key: &Self::Key) -> Self {
76 let key: &[u8; 32] = key.as_array();
77 Self(aes_gcm::Aes256Gcm::new(key.into()))
78 }
79
80 fn seal_in_place(
81 &self,
82 nonce: &[u8],
83 data: &mut [u8],
84 tag: &mut [u8],
85 additional_data: &[u8],
86 ) -> Result<(), SealError> {
87 check_seal_in_place_params::<Self>(nonce, data, tag, additional_data)?;
88
89 let got_tag = self
90 .0
91 .encrypt_in_place_detached(
92 #[allow(clippy::unnecessary_fallible_conversions)]
94 nonce
95 .try_into()
96 .map_err(|_| SealError::InvalidNonceSize(InvalidNonceSize))?,
97 additional_data,
98 data,
99 )
100 .map_err(|_| SealError::Encryption)?;
101 tag.copy_from_slice(&got_tag[..]);
102
103 Ok(())
104 }
105
106 fn open_in_place(
107 &self,
108 nonce: &[u8],
109 data: &mut [u8],
110 tag: &[u8],
111 additional_data: &[u8],
112 ) -> Result<(), OpenError> {
113 check_open_in_place_params::<Self>(nonce, data, tag, additional_data)?;
114
115 self.0
116 .decrypt_in_place_detached(
117 #[allow(clippy::unnecessary_fallible_conversions)]
119 nonce
120 .try_into()
121 .map_err(|_| OpenError::InvalidNonceSize(InvalidNonceSize))?,
122 additional_data,
123 data,
124 #[allow(clippy::unnecessary_fallible_conversions)]
126 tag.try_into().map_err(|_| OpenError::InvalidOverheadSize)?,
127 )
128 .map_err(|_| OpenError::Authentication)
129 }
130}
131
132impl IndCca2 for Aes256Gcm {}
133
134impl Identified for Aes256Gcm {
135 const OID: &'static Oid = AES_256_GCM;
136}
137
138impl HpkeAead for Aes256Gcm {
139 const ID: AeadId = AeadId::Aes256Gcm;
140}
141
142impl fmt::Debug for Aes256Gcm {
143 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
144 f.debug_struct("Aes256Gcm").finish_non_exhaustive()
145 }
146}
147
148#[cfg(feature = "committing-aead")]
149mod committing {
150 use aes::cipher::{BlockEncrypt, BlockSizeUser, KeyInit};
151 use generic_array::GenericArray;
152 use typenum::{Unsigned, U32};
153
154 use super::{Aes256Gcm, Sha256};
155 use crate::{
156 aead::{AeadKey, BlockCipher},
157 oid::consts::{HTE_AES_256_GCM, UTC_AES_256_GCM},
158 };
159
160 #[doc(hidden)]
162 #[derive(Debug)]
163 pub struct Aes256(aes::Aes256);
164
165 impl BlockCipher for Aes256 {
166 type BlockSize = <aes::Aes256 as BlockSizeUser>::BlockSize;
167 const BLOCK_SIZE: usize = Self::BlockSize::USIZE;
168 type Key = AeadKey<U32>;
169
170 fn new(key: &Self::Key) -> Self {
171 let key: &[u8; 32] = key.as_array();
172 let cipher = <aes::Aes256 as KeyInit>::new(key.into());
173 Self(cipher)
174 }
175
176 fn encrypt_block(&self, block: &mut GenericArray<u8, Self::BlockSize>) {
177 let block: &mut [u8; 16] = block.as_mut();
179 self.0.encrypt_block(block.into())
180 }
181 }
182
183 crate::aead::utc_aead!(
184 Cmt1Aes256Gcm,
185 Aes256Gcm,
186 Aes256,
187 "CMT-1 AES-256-GCM.",
188 UTC_AES_256_GCM,
189 );
190 crate::aead::hte_aead!(
191 Cmt4Aes256Gcm,
192 Cmt1Aes256Gcm,
193 Sha256,
194 "CMT-4 AES-256-GCM.",
195 HTE_AES_256_GCM,
196 );
197}
198#[cfg(feature = "committing-aead")]
199#[cfg_attr(docsrs, doc(cfg(feature = "committing-aead")))]
200pub use committing::*;
201
202use crate::aead::InvalidNonceSize;
203
204macro_rules! curve_impl {
205 (
206 $name:ident,
207 $doc:expr,
208 $oid:expr,
209 $inner:ty,
210 $point:ident,
211 $curve:ident $(,)?
212 ) => {
213 #[doc = concat!($doc, ".")]
214 pub use $inner as $name;
215
216 impl Curve for $inner {
217 type ScalarSize = <$curve as Curve>::ScalarSize;
218 type CompressedSize = <$curve as Curve>::CompressedSize;
219 type UncompressedSize = <$curve as Curve>::UncompressedSize;
220 }
221
222 impl Identified for $inner {
223 const OID: &'static Oid = $oid;
224 }
225
226 #[doc = concat!("An encoded ", $doc, "point.")]
227 #[derive(Copy, Clone, Debug)]
228 pub struct $point(EncodedPoint<$inner>);
229
230 impl Borrow<[u8]> for $point {
231 fn borrow(&self) -> &[u8] {
232 self.0.as_bytes()
233 }
234 }
235
236 impl<'a> Import<&'a [u8]> for $point {
237 fn import(data: &'a [u8]) -> Result<Self, ImportError> {
238 let point = EncodedPoint::<$inner>::from_bytes(data)
239 .map_err(|_| ImportError::InvalidSyntax)?;
240 Ok(Self(point))
241 }
242 }
243
244 impl ToHex for &$point {
245 type Output = EncodedPoint<$inner>;
246
247 fn to_hex(self) -> Hex<Self::Output> {
248 Hex::new(self.0)
249 }
250 }
251 };
252}
253curve_impl!(
254 P256,
255 "NIST-P256",
256 SECP256R1,
257 p256::NistP256,
258 P256Point,
259 Secp256r1
260);
261curve_impl!(
262 P384,
263 "NIST-P256",
264 SECP384R1,
265 p384::NistP384,
266 P384Point,
267 Secp384r1
268);
269
270pub struct SharedSecret<C>(ecdh::SharedSecret<C>)
272where
273 C: CurveArithmetic;
274
275impl<C> Borrow<[u8]> for SharedSecret<C>
276where
277 C: CurveArithmetic,
278{
279 fn borrow(&self) -> &[u8] {
280 self.0.raw_secret_bytes().as_slice()
281 }
282}
283
284impl<C> fmt::Debug for SharedSecret<C>
285where
286 C: CurveArithmetic,
287{
288 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
289 f.debug_struct("SharedSecret").finish_non_exhaustive()
290 }
291}
292
293impl<C> ZeroizeOnDrop for SharedSecret<C> where C: CurveArithmetic {}
294impl<C> Drop for SharedSecret<C>
295where
296 C: CurveArithmetic,
297{
298 fn drop(&mut self) {
299 is_zeroize_on_drop(&self.0);
300 }
301}
302
303macro_rules! ecdh_impl {
304 (
305 $curve:ident,
306 $doc:expr,
307 $sk:ident,
308 $pk:ident,
309 $point:ident $(,)?
310 ) => {
311 #[doc = concat!($doc, " ECDH private key.")]
312 #[derive(Clone)]
313 pub struct $sk(NonZeroScalar<$curve>);
314
315 impl DecapKey for $sk {
316 type EncapKey = $pk;
317
318 #[inline]
319 fn public(&self) -> Result<$pk, $crate::signer::PkError> {
320 Ok($pk(elliptic_curve::PublicKey::from_secret_scalar(&self.0)))
321 }
322 }
323
324 impl SecretKey for $sk {
325 type Size = FieldBytesSize<$curve>;
326
327 #[inline]
328 fn try_export_secret(&self) -> Result<SecretKeyBytes<Self::Size>, ExportError> {
329 let secret: [u8; FieldBytesSize::<$curve>::USIZE] = self.0.to_bytes().into();
331 Ok(SecretKeyBytes::new(secret.into()))
332 }
333 }
334
335 impl Random for $sk {
336 #[inline]
337 fn random<R: Csprng>(rng: R) -> Self {
338 let sk = NonZeroScalar::random(&mut RngWrapper(rng));
339 Self(sk)
340 }
341 }
342
343 impl fmt::Debug for $sk {
344 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
345 f.debug_struct(stringify!($sk)).finish_non_exhaustive()
346 }
347 }
348
349 impl ConstantTimeEq for $sk {
350 fn ct_eq(&self, other: &Self) -> Choice {
351 self.0.ct_eq(&other.0)
352 }
353 }
354
355 impl<'a> Import<&'a [u8]> for $sk {
356 fn import(data: &'a [u8]) -> Result<Self, ImportError> {
357 let bytes = *try_from_slice(data)?;
358 let sk = Option::from(NonZeroScalar::from_repr(bytes.into()))
359 .ok_or(ImportError::InvalidSyntax)?;
360 Ok(Self(sk))
361 }
362 }
363
364 impl ZeroizeOnDrop for $sk {}
365 impl Drop for $sk {
366 fn drop(&mut self) {
367 self.0.zeroize();
368 }
369 }
370
371 #[doc = concat!($doc, " ECDH public key.")]
372 #[derive(Clone, Eq, PartialEq)]
373 pub struct $pk(elliptic_curve::PublicKey<$curve>);
374
375 impl EncapKey for $pk {}
376
377 impl PublicKey for $pk {
378 type Data = $point;
379
380 fn export(&self) -> Self::Data {
381 $point(self.0.to_encoded_point(false))
382 }
383 }
384
385 impl fmt::Debug for $pk {
386 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
387 f.debug_tuple(stringify!($pk))
388 .field(&self.export().to_hex())
389 .finish()
390 }
391 }
392
393 impl<'a> Import<&'a [u8]> for $pk {
394 fn import(data: &'a [u8]) -> Result<Self, ImportError> {
395 let point = EncodedPoint::<$curve>::from_bytes(data)
396 .map_err(|_| ImportError::InvalidSyntax)?;
397 let pk = Option::from(elliptic_curve::PublicKey::from_encoded_point(&point))
398 .ok_or(ImportError::InvalidSyntax)?;
399 Ok(Self(pk))
400 }
401 }
402
403 impl Ecdh for $curve {
404 const SCALAR_SIZE: usize = <$curve as Curve>::ScalarSize::USIZE;
405
406 type PrivateKey = $sk;
407 type PublicKey = $pk;
408 type SharedSecret = SharedSecret<$curve>;
409
410 fn ecdh(
411 local: &Self::PrivateKey,
412 remote: &Self::PublicKey,
413 ) -> Result<Self::SharedSecret, EcdhError> {
414 let secret = ecdh::diffie_hellman(&local.0, remote.0.as_affine());
415 Ok(SharedSecret(secret))
416 }
417 }
418 };
419}
420ecdh_impl!(P256, "P-256", P256PrivateKey, P256PublicKey, P256Point);
421ecdh_impl!(P384, "P-384", P384PrivateKey, P384PublicKey, P384Point);
422dhkem_impl!(
425 DhKemP256HkdfSha256,
426 "DHKEM(P256, HKDF-SHA256)",
427 KemId::DhKemP256HkdfSha256,
428 P256,
429 HkdfSha256,
430 P256PrivateKey,
431 P256PublicKey,
432);
433
434#[derive(Clone, Debug)]
436pub struct SigBytes<T>(T);
437
438impl<T> Borrow<[u8]> for SigBytes<T>
439where
440 T: AsRef<[u8]>,
441{
442 fn borrow(&self) -> &[u8] {
443 self.0.as_ref()
444 }
445}
446
447macro_rules! ecdsa_impl {
448 (
449 $curve:ident,
450 $doc:expr,
451 $sk:ident,
452 $pk:ident,
453 $sig:ident,
454 $point:ident,
455 $sig_oid:expr $(,)?
456 ) => {
457 #[doc = concat!($doc, " ECDSA private key.")]
458 #[derive(Clone)]
459 pub struct $sk(ecdsa::SigningKey<$curve>);
460
461 impl SigningKey<$curve> for $sk {
462 fn sign(&self, msg: &[u8]) -> Result<$sig, SignerError> {
463 let sig = self.0.sign(msg);
464 Ok($sig(sig))
465 }
466
467 #[inline]
468 fn public(&self) -> Result<$pk, $crate::signer::PkError> {
469 Ok($pk(ecdsa::VerifyingKey::from(&self.0)))
470 }
471 }
472
473 impl SecretKey for $sk {
474 type Size = FieldBytesSize<$curve>;
475
476 #[inline]
477 fn try_export_secret(&self) -> Result<SecretKeyBytes<Self::Size>, ExportError> {
478 let secret: [u8; FieldBytesSize::<$curve>::USIZE] = self.0.to_bytes().into();
480 Ok(SecretKeyBytes::new(secret.into()))
481 }
482 }
483
484 impl Random for $sk {
485 #[inline]
486 fn random<R: Csprng>(rng: R) -> Self {
487 let sk = ecdsa::SigningKey::random(&mut RngWrapper(rng));
488 Self(sk)
489 }
490 }
491
492 impl fmt::Debug for $sk {
493 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
494 f.debug_struct(stringify!($sk)).finish_non_exhaustive()
495 }
496 }
497
498 impl ConstantTimeEq for $sk {
499 fn ct_eq(&self, other: &Self) -> Choice {
500 self.0.ct_eq(&other.0)
501 }
502 }
503
504 impl<'a> Import<&'a [u8]> for $sk {
505 fn import(data: &'a [u8]) -> Result<Self, ImportError> {
506 let sk =
507 ecdsa::SigningKey::from_slice(data).map_err(|_| ImportError::InvalidSyntax)?;
508 Ok(Self(sk))
509 }
510 }
511
512 impl ZeroizeOnDrop for $sk {}
513 impl Drop for $sk {
514 #[inline]
515 fn drop(&mut self) {
516 is_zeroize_on_drop(&self.0);
517 }
518 }
519
520 #[doc = concat!($doc, " ECDSA public key.")]
521 #[derive(Clone, Eq, PartialEq)]
522 pub struct $pk(ecdsa::VerifyingKey<$curve>);
523
524 impl VerifyingKey<$curve> for $pk {
525 fn verify(&self, msg: &[u8], sig: &$sig) -> Result<(), SignerError> {
526 self.0
527 .verify(msg, &sig.0)
528 .map_err(|_| SignerError::Verification)
529 }
530 }
531
532 impl PublicKey for $pk {
533 type Data = $point;
534
535 fn export(&self) -> Self::Data {
536 $point(self.0.to_encoded_point(false))
537 }
538 }
539
540 impl fmt::Debug for $pk {
541 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
542 f.debug_struct(stringify!($pk))
543 .field("point", &self.export().to_hex())
544 .finish()
545 }
546 }
547
548 impl<'a> Import<&'a [u8]> for $pk {
549 fn import(data: &'a [u8]) -> Result<Self, ImportError> {
550 let point = EncodedPoint::<$curve>::from_bytes(data)
551 .map_err(|_| ImportError::InvalidSyntax)?;
552 let pk = ecdsa::VerifyingKey::from_encoded_point(&point)
553 .map_err(|_| ImportError::InvalidSyntax)?;
554 Ok(Self(pk))
555 }
556 }
557
558 #[doc = concat!($doc, " ECDSA signature.")]
559 #[derive(Clone, Debug)]
560 pub struct $sig(ecdsa::Signature<$curve>);
561
562 impl Signature<$curve> for $sig {
563 type Data = SigBytes<der::Signature<$curve>>;
564
565 fn export(&self) -> Self::Data {
566 SigBytes(self.0.to_der())
567 }
568 }
569
570 impl Identified for $sig {
571 const OID: &'static Oid = $sig_oid;
572 }
573
574 impl<'a> Import<&'a [u8]> for $sig {
575 fn import(data: &'a [u8]) -> Result<Self, ImportError> {
576 let sig =
577 ecdsa::Signature::from_der(data).map_err(|_| ImportError::InvalidSyntax)?;
578 Ok(Self(sig))
579 }
580 }
581
582 impl Signer for $curve {
583 type SigningKey = $sk;
584 type VerifyingKey = $pk;
585 type Signature = $sig;
586 }
587 };
588}
589ecdsa_impl!(
590 P256,
591 "P-256 with SHA2-256",
592 P256SigningKey,
593 P256VerifyingKey,
594 P256Signature,
595 P256Point,
596 ECDSA_WITH_SHA2_256,
597);
598ecdsa_impl!(
599 P384,
600 "P-384 with SHA2-384",
601 P384SigningKey,
602 P384VerifyingKey,
603 P384Signature,
604 P384Point,
605 ECDSA_WITH_SHA2_384,
606);
607
608macro_rules! hash_impl {
609 (
610 $name:ident,
611 $doc:expr,
612 $oid:expr $(,)?
613 ) => {
614 #[doc = concat!($doc, ".")]
615 #[derive(Clone, Debug, Default)]
616 pub struct $name(sha2::$name);
617
618 impl Hash for $name {
619 type DigestSize = <sha2::$name as OutputSizeUser>::OutputSize;
620 const DIGEST_SIZE: usize =
621 <<sha2::$name as OutputSizeUser>::OutputSize as Unsigned>::USIZE;
622
623 #[inline]
624 fn new() -> Self {
625 Self(<sha2::$name as sha2::Digest>::new())
626 }
627
628 #[inline]
629 fn update(&mut self, data: &[u8]) {
630 sha2::Digest::update(&mut self.0, data)
631 }
632
633 #[inline]
634 fn digest(self) -> Digest<Self::DigestSize> {
635 Digest::from_array(sha2::Digest::finalize(self.0).into())
636 }
637
638 #[inline]
639 fn hash(data: &[u8]) -> Digest<Self::DigestSize> {
640 Digest::from_array(<sha2::$name as sha2::Digest>::digest(data).into())
641 }
642 }
643
644 impl BlockSize for $name {
645 type BlockSize = <sha2::$name as BlockSizeUser>::BlockSize;
646 }
647
648 impl Identified for $name {
649 const OID: &'static Oid = $oid;
650 }
651 };
652}
653hash_impl!(Sha256, "SHA2-256", SHA2_256);
654hash_impl!(Sha384, "SHA2-384", SHA2_384);
655hash_impl!(Sha512, "SHA2-512", SHA2_512);
656hash_impl!(Sha512_256, "SHA2-512-256", SHA2_512_256);
657
658hkdf_impl!(
659 HkdfSha256,
660 "HKDF-SHA2-256",
661 Sha256,
662 oid = HKDF_WITH_SHA2_256,
663 kdf_id = KdfId::HkdfSha256,
664);
665hkdf_impl!(
666 HkdfSha384,
667 "HKDF-SHA2-384",
668 Sha384,
669 oid = HKDF_WITH_SHA2_384,
670 kdf_id = KdfId::HkdfSha384,
671);
672hkdf_impl!(
673 HkdfSha512,
674 "HKDF-SHA2-512",
675 Sha512,
676 oid = HKDF_WITH_SHA2_512,
677 kdf_id = KdfId::HkdfSha512,
678);
679
680hmac_impl!(HmacSha256, "HMAC-SHA2-256", Sha256, HMAC_WITH_SHA2_256);
681hmac_impl!(HmacSha384, "HMAC-SHA2-384", Sha384, HMAC_WITH_SHA2_384);
682hmac_impl!(HmacSha512, "HMAC-SHA2-512", Sha512, HMAC_WITH_SHA2_512);
683hmac_impl!(
684 HmacSha512_512,
685 "HMAC-SHA2-512_512",
686 Sha512,
687 HMAC_WITH_SHA2_512_256,
688);
689
690struct RngWrapper<R>(R);
692
693impl<R> CryptoRng for RngWrapper<R> {}
694
695impl<R: Csprng> RngCore for RngWrapper<R> {
696 fn next_u32(&mut self) -> u32 {
697 impls::next_u32_via_fill(self)
698 }
699
700 fn next_u64(&mut self) -> u64 {
701 impls::next_u64_via_fill(self)
702 }
703
704 fn fill_bytes(&mut self, dst: &mut [u8]) {
705 self.0.fill_bytes(dst)
706 }
707
708 fn try_fill_bytes(&mut self, dst: &mut [u8]) -> Result<(), rand_core::Error> {
709 self.fill_bytes(dst);
710 Ok(())
711 }
712}
713
714#[cfg(test)]
715mod tests {
716 use super::*;
717
718 mod aead_tests {
719 use super::*;
720 use crate::test_util::test_aead;
721
722 test_aead!(aes256gcm, Aes256Gcm, AeadTest::AesGcm);
723
724 #[cfg(feature = "committing-aead")]
725 mod committing {
726 use super::*;
727
728 test_aead!(cmd1_aead_aes256_gcm, Cmt1Aes256Gcm);
729 test_aead!(cmd4_aead_aes256_gcm, Cmt4Aes256Gcm);
730 }
731 }
732
733 mod ecdh_tests {
734 use super::*;
735 use crate::test_util::vectors::{test_ecdh, EcdhTest};
736
737 #[test]
738 fn test_ecdh_p256() {
739 test_ecdh::<P256>(EcdhTest::EcdhSecp256r1Ecpoint);
740 }
741
742 #[test]
743 fn test_ecdh_p384() {
744 test_ecdh::<P384>(EcdhTest::EcdhSecp384r1Ecpoint);
745 }
746 }
747
748 mod ecdsa_tests {
749 use super::*;
750 use crate::test_util::test_signer;
751
752 test_signer!(p256, P256, EcdsaTest::EcdsaSecp256r1Sha256);
753 test_signer!(p384, P384, EcdsaTest::EcdsaSecp384r1Sha384);
754 }
755
756 mod hkdf_tests {
757 use super::*;
758 use crate::test_util::test_kdf;
759
760 test_kdf!(test_hkdf_sha256, HkdfSha256, HkdfTest::HkdfSha256);
761 test_kdf!(test_hkdf_sha384, HkdfSha384, HkdfTest::HkdfSha384);
762 test_kdf!(test_hkdf_sha512, HkdfSha512, HkdfTest::HkdfSha512);
763 }
764
765 mod hmac_tests {
766 use super::*;
767 use crate::test_util::test_mac;
768
769 test_mac!(test_hmac_sha256, HmacSha256, MacTest::HmacSha256);
770 test_mac!(test_hmac_sha384, HmacSha384, MacTest::HmacSha384);
771 test_mac!(test_hmac_sha512, HmacSha512, MacTest::HmacSha512);
772 }
773
774 mod hpke_tests {
775 use super::*;
776 use crate::test_util::test_hpke;
777
778 test_hpke!(
779 sha256,
780 DhKemP256HkdfSha256,
781 HkdfSha256,
782 Aes256Gcm,
783 HpkeTest::HpkeDhKemP256HkdfSha256HkdfSha256Aes256Gcm,
784 );
785 test_hpke!(
786 sha512,
787 DhKemP256HkdfSha256,
788 HkdfSha512,
789 Aes256Gcm,
790 HpkeTest::HpkeDhKemP256HkdfSha256HkdfSha512Aes256Gcm,
791 );
792 }
793}