Skip to main content
This is unreleased documentation for the main (development) branch of crypto-glue.

crypto_glue/
lib.rs

1#![deny(warnings)]
2#![allow(dead_code)]
3#![warn(unused_extern_crates)]
4// Enable some groups of clippy lints.
5#![deny(clippy::suspicious)]
6#![deny(clippy::perf)]
7// Specific lints to enforce.
8#![deny(clippy::todo)]
9#![deny(clippy::unimplemented)]
10#![deny(clippy::unwrap_used)]
11#![deny(clippy::expect_used)]
12#![deny(clippy::panic)]
13#![deny(clippy::await_holding_lock)]
14#![deny(clippy::needless_pass_by_value)]
15#![deny(clippy::trivially_copy_pass_by_ref)]
16#![deny(clippy::disallowed_types)]
17#![deny(clippy::manual_let_else)]
18#![allow(clippy::unreachable)]
19
20pub use argon2;
21pub use cipher::block_padding;
22pub use der;
23pub use hex;
24pub use pbkdf2;
25pub use rand;
26pub use spki;
27pub use zeroize;
28
29pub mod prelude {}
30
31#[cfg(test)]
32mod test_ca;
33
34pub mod traits {
35    pub use aes_gcm::aead::AeadInOut;
36    pub use crypto_common::{Generate, KeyInit, OutputSizeUser};
37    pub use der::{
38        Decode as DecodeDer, DecodePem, Encode as EncodeDer, EncodePem,
39        pem::LineEnding as LineEndingPem, referenced::OwnedToRef,
40    };
41    pub use digest::FixedOutput;
42    pub use elliptic_curve::sec1::{FromSec1Point, ToSec1Point};
43    pub use hmac::{Hmac, Mac};
44    pub use pkcs8::{
45        DecodePrivateKey as Pkcs8DecodePrivateKey, EncodePrivateKey as Pkcs8EncodePrivateKey,
46    };
47    pub use rsa::pkcs1::{
48        DecodeRsaPrivateKey as Pkcs1DecodeRsaPrivateKey,
49        EncodeRsaPrivateKey as Pkcs1EncodeRsaPrivateKey,
50    };
51    pub use rsa::signature::{
52        DigestSigner, DigestVerifier, Keypair, RandomizedSigner, SignatureEncoding, Signer,
53        Verifier,
54    };
55    pub use rsa::traits::PublicKeyParts;
56    pub use sha2::Digest;
57    pub use spki::{
58        DecodePublicKey as SpkiDecodePublicKey, DynSignatureAlgorithmIdentifier,
59        EncodePublicKey as SpkiEncodePublicKey,
60    };
61    pub use zeroize::Zeroizing;
62    pub mod hazmat {
63        //! This is a “Hazardous Materials” module. You should ONLY use it if you’re 100% absolutely sure that you know what you’re doing because this module is full of land mines, dragons, and dinosaurs with laser guns.
64
65        pub use rsa::signature::hazmat::PrehashVerifier;
66    }
67    pub use x509_cert::ext::ToExtension;
68}
69
70pub mod x509;
71
72pub mod md5 {
73    pub use md5::*;
74}
75
76pub mod sha1 {
77    use hybrid_array::{Array, sizes::U20};
78
79    pub use sha1::Sha1;
80
81    pub type Sha1Output = Array<u8, U20>;
82}
83
84pub mod s256 {
85    use hybrid_array::{Array, sizes::U32};
86
87    pub use sha2::Sha256;
88
89    pub type Sha256Output = Array<u8, U32>;
90}
91
92pub mod s384 {
93    use hybrid_array::{Array, sizes::U48};
94
95    pub use sha2::Sha384;
96
97    pub type Sha384Output = Array<u8, U48>;
98}
99
100pub mod s512 {
101    use hybrid_array::{Array, sizes::U64};
102
103    pub use sha2::Sha512;
104
105    pub type Sha512Output = Array<u8, U64>;
106}
107
108pub mod hkdf_s256 {
109    use hkdf::Hkdf;
110    use sha2::Sha256;
111
112    pub type HkdfSha256 = Hkdf<Sha256>;
113}
114
115pub mod hmac_s1 {
116    use crypto_common::Key;
117    use crypto_common::Output;
118
119    use hmac::Hmac;
120    use hmac::Mac;
121    use sha1::Sha1;
122    use sha1::digest::CtOutput;
123    use zeroize::Zeroizing;
124
125    pub type HmacSha1 = Hmac<Sha1>;
126
127    pub type HmacSha1Key = Zeroizing<Key<Hmac<Sha1>>>;
128
129    pub type HmacSha1Output = CtOutput<HmacSha1>;
130
131    pub type HmacSha1Bytes = Output<HmacSha1>;
132
133    pub fn new_key() -> HmacSha1Key {
134        use crypto_common::Generate;
135        Key::<HmacSha1>::generate().into()
136    }
137
138    pub fn oneshot(key: &HmacSha1Key, data: &[u8]) -> HmacSha1Output {
139        use crypto_common::KeyInit;
140
141        let mut hmac = HmacSha1::new(key);
142        hmac.update(data);
143        hmac.finalize()
144    }
145
146    #[allow(clippy::needless_pass_by_value)]
147    pub fn key_from_vec(bytes: Vec<u8>) -> Option<HmacSha1Key> {
148        key_from_slice(&bytes)
149    }
150
151    pub fn key_from_slice(bytes: &[u8]) -> Option<HmacSha1Key> {
152        use crypto_common::KeySizeUser;
153        // Key too short - too long.
154        if bytes.len() < 16 || bytes.len() > Hmac::<Sha1>::key_size() {
155            None
156        } else {
157            let mut key = Key::<Hmac<Sha1>>::default();
158            let key_ref = &mut key.as_mut_slice()[..bytes.len()];
159            key_ref.copy_from_slice(bytes);
160            Some(key.into())
161        }
162    }
163
164    pub fn key_from_bytes(bytes: [u8; 64]) -> HmacSha1Key {
165        Key::<Hmac<Sha1>>::from(bytes).into()
166    }
167
168    pub fn key_size() -> usize {
169        use crypto_common::KeySizeUser;
170        Hmac::<Sha1>::key_size()
171    }
172}
173
174pub mod hmac_s256 {
175    use crypto_common::Key;
176    use crypto_common::Output;
177
178    use hmac::Hmac;
179    use hmac::Mac;
180    use sha2::Sha256;
181    use sha2::digest::CtOutput;
182    use zeroize::Zeroizing;
183
184    pub type HmacSha256 = Hmac<Sha256>;
185
186    pub type HmacSha256Key = Zeroizing<Key<Hmac<Sha256>>>;
187
188    pub type HmacSha256Output = CtOutput<HmacSha256>;
189
190    pub type HmacSha256Bytes = Output<HmacSha256>;
191
192    pub fn new_key() -> HmacSha256Key {
193        use crypto_common::Generate;
194        Key::<HmacSha256>::generate().into()
195    }
196
197    pub fn oneshot(key: &HmacSha256Key, data: &[u8]) -> HmacSha256Output {
198        use crypto_common::KeyInit;
199
200        let mut hmac = HmacSha256::new(key);
201        hmac.update(data);
202        hmac.finalize()
203    }
204
205    #[allow(clippy::needless_pass_by_value)]
206    pub fn key_from_vec(bytes: Vec<u8>) -> Option<HmacSha256Key> {
207        key_from_slice(&bytes)
208    }
209
210    pub fn key_from_slice(bytes: &[u8]) -> Option<HmacSha256Key> {
211        use crypto_common::KeySizeUser;
212        // Key too short - too long.
213        if bytes.len() < 16 || bytes.len() > Hmac::<Sha256>::key_size() {
214            None
215        } else {
216            let mut key = Key::<Hmac<Sha256>>::default();
217            let key_ref = &mut key.as_mut_slice()[..bytes.len()];
218            key_ref.copy_from_slice(bytes);
219            Some(key.into())
220        }
221    }
222
223    pub fn key_from_bytes(bytes: [u8; 64]) -> HmacSha256Key {
224        Key::<Hmac<Sha256>>::from(bytes).into()
225    }
226
227    pub fn key_size() -> usize {
228        use crypto_common::KeySizeUser;
229        Hmac::<Sha256>::key_size()
230    }
231}
232
233pub mod hmac_s512 {
234    use crypto_common::Key;
235    use crypto_common::Output;
236
237    use hmac::Hmac;
238    use sha2::Sha512;
239    use sha2::digest::CtOutput;
240    use zeroize::Zeroizing;
241
242    pub use hmac::Mac;
243
244    pub type HmacSha512 = Hmac<Sha512>;
245
246    pub type HmacSha512Key = Zeroizing<Key<Hmac<Sha512>>>;
247
248    pub type HmacSha512Output = CtOutput<HmacSha512>;
249
250    pub type HmacSha512Bytes = Output<HmacSha512>;
251
252    pub fn new_hmac_sha512_key() -> HmacSha512Key {
253        use crypto_common::Generate;
254        Key::<HmacSha512>::generate().into()
255    }
256
257    pub fn oneshot(key: &HmacSha512Key, data: &[u8]) -> HmacSha512Output {
258        use crypto_common::KeyInit;
259
260        let mut hmac = HmacSha512::new(key);
261        hmac.update(data);
262        hmac.finalize()
263    }
264
265    pub fn key_from_slice(bytes: &[u8]) -> Option<HmacSha512Key> {
266        use crypto_common::KeySizeUser;
267        // Key too short - too long.
268        if bytes.len() < 16 || bytes.len() > Hmac::<Sha512>::key_size() {
269            None
270        } else {
271            let mut key = Key::<Hmac<Sha512>>::default();
272            let key_ref = &mut key.as_mut_slice()[..bytes.len()];
273            key_ref.copy_from_slice(bytes);
274            Some(key.into())
275        }
276    }
277
278    pub fn key_size() -> usize {
279        use crypto_common::KeySizeUser;
280        Hmac::<Sha512>::key_size()
281    }
282}
283
284pub mod aes128 {
285    use aes;
286    use crypto_common::Key;
287    use zeroize::Zeroizing;
288
289    pub type Aes128Key = Zeroizing<Key<aes::Aes128>>;
290
291    pub fn key_size() -> usize {
292        use crypto_common::KeySizeUser;
293        aes::Aes128::key_size()
294    }
295
296    pub fn key_from_slice(bytes: &[u8]) -> Option<Aes128Key> {
297        Key::<aes::Aes128>::try_from(bytes)
298            .ok()
299            .map(|key| key.into())
300    }
301
302    pub fn key_from_bytes(bytes: [u8; 16]) -> Aes128Key {
303        Key::<aes::Aes128>::from(bytes).into()
304    }
305
306    pub fn new_key() -> Aes128Key {
307        use crypto_common::Generate;
308        Key::<aes::Aes128>::generate().into()
309    }
310}
311
312pub mod aes128gcm {
313    use aes::cipher::consts::{U12, U16};
314
315    pub use aes_gcm::aead::{Aead, AeadInOut, Payload};
316    pub use crypto_common::KeyInit;
317
318    pub use crate::aes128::Aes128Key;
319
320    pub type Aes128Gcm = aes_gcm::Aes128Gcm;
321
322    pub type Aes128GcmNonce = aes_gcm::Nonce<U12>;
323    pub type Aes128GcmTag = aes_gcm::Tag<U16>;
324
325    pub fn new_nonce() -> Aes128GcmNonce {
326        use crypto_common::Generate;
327        Aes128GcmNonce::generate()
328    }
329}
330
331pub mod aes128kw {
332    use hybrid_array::{Array, sizes::U24};
333
334    pub use crypto_common::KeyInit;
335
336    pub type Aes128Kw = aes_kw::KwAes128;
337
338    pub type Aes128KwWrapped = Array<u8, U24>;
339}
340
341pub mod aes256 {
342    use aes;
343    use aes::cipher::Array;
344    use crypto_common::Key;
345    use zeroize::Zeroizing;
346
347    pub use aes::Aes256;
348    pub use aes::cipher::{BlockCipherDecrypt, BlockCipherEncrypt};
349
350    pub type Aes256Key = Zeroizing<Key<aes::Aes256>>;
351    pub type Aes256BlockSize = <aes::Aes256 as aes::cipher::BlockSizeUser>::BlockSize;
352    pub type Aes256Block = Array<u8, <aes::Aes256 as aes::cipher::BlockSizeUser>::BlockSize>;
353
354    pub fn key_size() -> usize {
355        use crypto_common::KeySizeUser;
356        aes::Aes256::key_size()
357    }
358
359    pub fn key_from_slice(bytes: &[u8]) -> Option<Aes256Key> {
360        Key::<aes::Aes256>::try_from(bytes)
361            .ok()
362            .map(|key| key.into())
363    }
364
365    pub fn key_from_bytes(bytes: [u8; 32]) -> Aes256Key {
366        Key::<aes::Aes256>::from(bytes).into()
367    }
368
369    pub fn new_key() -> Aes256Key {
370        use crypto_common::Generate;
371        Key::<aes::Aes256>::generate().into()
372    }
373}
374
375pub mod aes256gcm {
376    use aes::Aes256;
377    use aes::cipher::consts::{U12, U16};
378    use aes_gcm::AesGcm;
379
380    pub use aes_gcm::aead::{Aead, AeadInOut, Payload};
381    pub use crypto_common::KeyInit;
382
383    pub use crate::aes256::Aes256Key;
384
385    // Same as  AesGcm<Aes256, U12, U16>;
386    pub type Aes256Gcm = aes_gcm::Aes256Gcm;
387
388    pub type Aes256GcmN16 = AesGcm<Aes256, U16, U16>;
389    pub type Aes256GcmNonce16 = aes_gcm::Nonce<U16>;
390
391    pub type Aes256GcmNonce = aes_gcm::Nonce<U12>;
392    pub type Aes256GcmTag = aes_gcm::Tag<U16>;
393
394    pub fn new_nonce() -> Aes256GcmNonce {
395        use crypto_common::Generate;
396        Aes256GcmNonce::generate()
397    }
398}
399
400pub mod aes256cts {
401    use aes::cipher::Array;
402    use aes::cipher::consts::U16;
403
404    pub use crate::aes256::Aes256Key;
405    pub use aes::cipher::{BlockModeDecrypt, BlockModeEncrypt, InnerIvInit, KeyIvInit};
406
407    pub use cts::Decrypt as CtsDecrypt;
408    pub use cts::Encrypt as CtsEncrypt;
409
410    pub type Aes256CtsEnc = cts::CbcCs3<aes::Aes256>;
411    pub type Aes256CtsDec = cts::CbcCs3<aes::Aes256>;
412
413    pub type Aes256CtsIv = Array<u8, U16>;
414
415    pub fn new_iv() -> Aes256CtsIv {
416        use crypto_common::Generate;
417        Aes256CtsIv::generate()
418    }
419}
420
421pub mod aes256cbc {
422    use crate::hmac_s256::HmacSha256;
423    use crate::hmac_s256::HmacSha256Output;
424    use aes::cipher::Array;
425    use aes::cipher::consts::U16;
426
427    pub use crate::aes256::Aes256Key;
428
429    pub use aes::cipher::{BlockModeDecrypt, BlockModeEncrypt, KeyIvInit, block_padding};
430
431    pub type Aes256CbcEnc = cbc::Encryptor<aes::Aes256>;
432    pub type Aes256CbcDec = cbc::Decryptor<aes::Aes256>;
433
434    pub type Aes256CbcIv = Array<u8, U16>;
435
436    pub fn new_iv() -> Aes256CbcIv {
437        use crypto_common::Generate;
438        Aes256CbcIv::generate()
439    }
440
441    pub fn enc<P>(
442        key: &Aes256Key,
443        data: &[u8],
444    ) -> Result<(HmacSha256Output, Aes256CbcIv, Vec<u8>), crypto_common::InvalidLength>
445    where
446        P: block_padding::Padding,
447    {
448        use cipher::BlockModeEncrypt;
449        use cipher::KeyInit;
450        use hmac::Mac;
451
452        let iv = new_iv();
453        let enc = Aes256CbcEnc::new(key, &iv);
454
455        let ciphertext = enc.encrypt_padded_vec::<P>(data);
456
457        let mut hmac = HmacSha256::new_from_slice(key.as_slice())?;
458        hmac.update(&ciphertext);
459        let mac = hmac.finalize();
460
461        Ok((mac, iv, ciphertext))
462    }
463
464    pub fn dec<P>(
465        key: &Aes256Key,
466        mac: &HmacSha256Output,
467        iv: &Aes256CbcIv,
468        ciphertext: &[u8],
469    ) -> Option<Vec<u8>>
470    where
471        P: block_padding::Padding,
472    {
473        use cipher::BlockModeDecrypt;
474        use cipher::KeyInit;
475        use hmac::Mac;
476
477        let mut hmac = HmacSha256::new_from_slice(key.as_slice()).ok()?;
478        hmac.update(ciphertext);
479        let check_mac = hmac.finalize();
480
481        if check_mac != *mac {
482            return None;
483        }
484
485        let dec = Aes256CbcDec::new(key, iv);
486
487        let plaintext = dec.decrypt_padded_vec::<P>(ciphertext).ok()?;
488
489        Some(plaintext)
490    }
491}
492
493pub mod aes256kw {
494    use hybrid_array::{Array, sizes::U40};
495
496    pub use crypto_common::KeyInit;
497
498    pub type Aes256Kw = aes_kw::KwAes256;
499
500    pub type Aes256KwWrapped = Array<u8, U40>;
501}
502
503pub mod rsa {
504    use rsa::pkcs1v15::{Signature, SigningKey, VerifyingKey};
505    use rsa::{RsaPrivateKey, RsaPublicKey};
506
507    pub use rand;
508    pub use rsa::BoxedUint as BigUint;
509    pub use rsa::{Oaep, pkcs1v15};
510    pub use sha2::{Sha256, Sha384};
511
512    pub const MIN_BITS: usize = 2048;
513
514    pub type RS256PrivateKey = RsaPrivateKey;
515    pub type RS256PublicKey = RsaPublicKey;
516    pub type RS256Signature = Signature;
517    pub type RS256Digest = Sha256;
518    pub type RS256VerifyingKey = VerifyingKey<Sha256>;
519    pub type RS256SigningKey = SigningKey<Sha256>;
520
521    pub type RS384Digest = Sha384;
522    pub type RS384VerifyingKey = VerifyingKey<Sha384>;
523    pub type RS384SigningKey = SigningKey<Sha384>;
524
525    pub fn new_key(bits: usize) -> rsa::errors::Result<RsaPrivateKey> {
526        let bits = std::cmp::max(bits, MIN_BITS);
527        let mut rng = rand::rng();
528        RsaPrivateKey::new(&mut rng, bits)
529    }
530
531    pub fn oaep_sha256_encrypt(
532        public_key: &RsaPublicKey,
533        data: &[u8],
534    ) -> rsa::errors::Result<Vec<u8>> {
535        let mut rng = rand::rng();
536        let padding = Oaep::<Sha256>::new();
537        public_key.encrypt(&mut rng, padding, data)
538    }
539
540    pub fn oaep_sha256_decrypt(
541        private_key: &RsaPrivateKey,
542        ciphertext: &[u8],
543    ) -> rsa::errors::Result<Vec<u8>> {
544        let padding = Oaep::<Sha256>::new();
545        private_key.decrypt(padding, ciphertext)
546    }
547}
548
549pub mod ec {
550    pub use sec1::EcPrivateKey;
551}
552
553pub mod ecdh {
554    pub use elliptic_curve::ecdh::diffie_hellman;
555}
556
557pub mod ecdh_p256 {
558    use elliptic_curve::ecdh::{EphemeralSecret, SharedSecret};
559    use elliptic_curve::sec1::Sec1Point;
560    use elliptic_curve::{FieldBytes, PublicKey};
561    use hkdf::Hkdf;
562    use p256::NistP256;
563    use sha2::Sha256;
564
565    pub type EcdhP256EphemeralSecret = EphemeralSecret<NistP256>;
566    pub type EcdhP256SharedSecret = SharedSecret<NistP256>;
567    pub type EcdhP256PublicKey = PublicKey<NistP256>;
568    pub type EcdhP256PublicSec1Point = Sec1Point<NistP256>;
569    pub type EcdhP256FieldBytes = FieldBytes<NistP256>;
570
571    pub type EcdhP256Hkdf = Hkdf<Sha256>;
572
573    pub type EcdhP256Digest = Sha256;
574
575    pub fn new_secret() -> EcdhP256EphemeralSecret {
576        use crypto_common::Generate;
577        EcdhP256EphemeralSecret::generate()
578    }
579}
580
581pub mod ecdsa_p256 {
582    use ecdsa::DigestAlgorithm;
583    use ecdsa::{Signature, SignatureBytes, SigningKey, VerifyingKey};
584    use elliptic_curve::point::AffinePoint;
585    use elliptic_curve::scalar::NonZeroScalar;
586    use elliptic_curve::sec1::FromSec1Point;
587    use elliptic_curve::sec1::Sec1Point;
588    use elliptic_curve::{FieldBytes, PublicKey, SecretKey};
589    use hybrid_array::{Array, sizes::U32};
590    use p256::{NistP256, ecdsa::DerSignature};
591
592    pub type EcdsaP256Digest = <NistP256 as DigestAlgorithm>::Digest;
593
594    pub type EcdsaP256PrivateKey = SecretKey<NistP256>;
595    pub type EcdsaP256NonZeroScalar = NonZeroScalar<NistP256>;
596
597    pub type EcdsaP256FieldBytes = FieldBytes<NistP256>;
598    pub type EcdsaP256AffinePoint = AffinePoint<NistP256>;
599
600    pub type EcdsaP256PublicKey = PublicKey<NistP256>;
601
602    pub type EcdsaP256PublicCoordinate = Array<u8, U32>;
603    pub type EcdsaP256PublicSec1Point = Sec1Point<NistP256>;
604
605    pub type EcdsaP256SigningKey = SigningKey<NistP256>;
606    pub type EcdsaP256VerifyingKey = VerifyingKey<NistP256>;
607
608    pub type EcdsaP256Signature = Signature<NistP256>;
609    pub type EcdsaP256DerSignature = DerSignature;
610    pub type EcdsaP256SignatureBytes = SignatureBytes<NistP256>;
611
612    pub fn new_key() -> EcdsaP256PrivateKey {
613        use crypto_common::Generate;
614
615        EcdsaP256PrivateKey::generate()
616    }
617
618    pub fn from_coords_raw(x: &[u8], y: &[u8]) -> Option<EcdsaP256PublicKey> {
619        let mut field_x = EcdsaP256FieldBytes::default();
620        if x.len() != field_x.len() {
621            return None;
622        }
623
624        let mut field_y = EcdsaP256FieldBytes::default();
625        if y.len() != field_y.len() {
626            return None;
627        }
628
629        field_x.copy_from_slice(x);
630        field_y.copy_from_slice(y);
631
632        let ep = EcdsaP256PublicSec1Point::from_affine_coordinates(&field_x, &field_y, false);
633
634        EcdsaP256PublicKey::from_sec1_point(&ep).into_option()
635    }
636}
637
638pub mod ecdsa_p384 {
639    use ecdsa::DigestAlgorithm;
640    use ecdsa::{Signature, SignatureBytes, SigningKey, VerifyingKey};
641    use elliptic_curve::point::AffinePoint;
642    use elliptic_curve::sec1::FromSec1Point;
643    use elliptic_curve::sec1::Sec1Point;
644    use elliptic_curve::{FieldBytes, PublicKey, SecretKey};
645    use p384::{NistP384, ecdsa::DerSignature};
646    // use sha2::digest::consts::U32;
647
648    pub type EcdsaP384Digest = <NistP384 as DigestAlgorithm>::Digest;
649
650    pub type EcdsaP384PrivateKey = SecretKey<NistP384>;
651
652    pub type EcdsaP384FieldBytes = FieldBytes<NistP384>;
653    pub type EcdsaP384AffinePoint = AffinePoint<NistP384>;
654
655    pub type EcdsaP384PublicKey = PublicKey<NistP384>;
656
657    // pub type EcdsaP384PublicCoordinate = GenericArray<u8, U32>;
658    pub type EcdsaP384PublicSec1Point = Sec1Point<NistP384>;
659
660    pub type EcdsaP384SigningKey = SigningKey<NistP384>;
661    pub type EcdsaP384VerifyingKey = VerifyingKey<NistP384>;
662
663    pub type EcdsaP384Signature = Signature<NistP384>;
664    pub type EcdsaP384DerSignature = DerSignature;
665    pub type EcdsaP384SignatureBytes = SignatureBytes<NistP384>;
666
667    pub fn new_key() -> EcdsaP384PrivateKey {
668        use crypto_common::Generate;
669        EcdsaP384PrivateKey::generate()
670    }
671
672    pub fn from_coords_raw(x: &[u8], y: &[u8]) -> Option<EcdsaP384PublicKey> {
673        let mut field_x = EcdsaP384FieldBytes::default();
674        if x.len() != field_x.len() {
675            return None;
676        }
677
678        let mut field_y = EcdsaP384FieldBytes::default();
679        if y.len() != field_y.len() {
680            return None;
681        }
682
683        field_x.copy_from_slice(x);
684        field_y.copy_from_slice(y);
685
686        let ep = EcdsaP384PublicSec1Point::from_affine_coordinates(&field_x, &field_y, false);
687
688        EcdsaP384PublicKey::from_sec1_point(&ep).into_option()
689    }
690}
691
692pub mod ecdsa_p521 {
693    use ecdsa::DigestAlgorithm;
694    use ecdsa::{Signature, SignatureBytes, SigningKey, VerifyingKey};
695    use elliptic_curve::point::AffinePoint;
696    use elliptic_curve::sec1::FromSec1Point;
697    use elliptic_curve::sec1::Sec1Point;
698    use elliptic_curve::{FieldBytes, PublicKey, SecretKey};
699    use p521::{NistP521, ecdsa::DerSignature};
700
701    pub type EcdsaP521Digest = <NistP521 as DigestAlgorithm>::Digest;
702
703    pub type EcdsaP521PrivateKey = SecretKey<NistP521>;
704
705    pub type EcdsaP521FieldBytes = FieldBytes<NistP521>;
706    pub type EcdsaP521AffinePoint = AffinePoint<NistP521>;
707
708    pub type EcdsaP521PublicKey = PublicKey<NistP521>;
709
710    // pub type EcdsaP521PublicCoordinate = GenericArray<u8, U32>;
711    pub type EcdsaP521PublicSec1Point = Sec1Point<NistP521>;
712
713    pub type EcdsaP521SigningKey = SigningKey<NistP521>;
714    pub type EcdsaP521VerifyingKey = VerifyingKey<NistP521>;
715
716    pub type EcdsaP521Signature = Signature<NistP521>;
717    pub type EcdsaP521DerSignature = DerSignature;
718    pub type EcdsaP521SignatureBytes = SignatureBytes<NistP521>;
719
720    pub fn new_key() -> EcdsaP521PrivateKey {
721        use crypto_common::Generate;
722        EcdsaP521PrivateKey::generate()
723    }
724
725    pub fn from_coords_raw(x: &[u8], y: &[u8]) -> Option<EcdsaP521PublicKey> {
726        let mut field_x = EcdsaP521FieldBytes::default();
727        if x.len() != field_x.len() {
728            return None;
729        }
730
731        let mut field_y = EcdsaP521FieldBytes::default();
732        if y.len() != field_y.len() {
733            return None;
734        }
735
736        field_x.copy_from_slice(x);
737        field_y.copy_from_slice(y);
738
739        let ep = EcdsaP521PublicSec1Point::from_affine_coordinates(&field_x, &field_y, false);
740
741        EcdsaP521PublicKey::from_sec1_point(&ep).into_option()
742    }
743}
744
745pub mod nist_sp800_108_kdf_hmac_sha256 {
746    use crate::traits::Zeroizing;
747    use crypto_common::KeySizeUser;
748    use digest::consts::*;
749    use hmac::Hmac;
750    use kbkdf::{Counter, Kbkdf, Params};
751    use sha2::Sha256;
752
753    struct MockOutput;
754
755    impl KeySizeUser for MockOutput {
756        type KeySize = U32;
757    }
758
759    type HmacSha256 = Hmac<Sha256>;
760
761    pub fn derive_key_aes256(
762        key_in: &[u8],
763        label: &[u8],
764        context: &[u8],
765    ) -> Option<Zeroizing<Vec<u8>>> {
766        let counter = Counter::<HmacSha256, MockOutput>::default();
767        let params = Params::builder(key_in)
768            .with_label(label)
769            .with_context(context)
770            .use_l(true)
771            .use_separator(true)
772            .use_counter(true)
773            .build();
774        let key = counter.derive(params).ok()?;
775
776        let mut output = Zeroizing::new(vec![0; MockOutput::key_size()]);
777        output.copy_from_slice(key.as_slice());
778        Some(output)
779    }
780}
781
782pub mod pkcs8 {
783    pub use pkcs8::PrivateKeyInfo;
784}
785
786#[cfg(test)]
787mod tests {
788    #[cfg(all(target_arch = "wasm32", any(target_os = "unknown", target_os = "none")))]
789    use wasm_bindgen_test::*;
790    #[cfg(all(target_arch = "wasm32", any(target_os = "unknown", target_os = "none")))]
791    wasm_bindgen_test_configure!(run_in_browser);
792
793    #[test]
794    #[cfg_attr(
795        all(target_arch = "wasm32", any(target_os = "unknown", target_os = "none")),
796        wasm_bindgen_test
797    )]
798    fn sha256_basic() {
799        use crate::s256::*;
800        use crate::traits::*;
801
802        let mut hasher = Sha256::new();
803        hasher.update([0, 1, 2, 3]);
804        let out: Sha256Output = hasher.finalize();
805
806        eprintln!("{:?}", out.as_slice());
807    }
808
809    #[test]
810    #[cfg_attr(
811        all(target_arch = "wasm32", any(target_os = "unknown", target_os = "none")),
812        wasm_bindgen_test
813    )]
814    fn hmac_256_basic() {
815        use crate::hmac_s256::*;
816        use crate::traits::{KeyInit, Mac};
817
818        let hmac_key = new_key();
819
820        let mut hmac = HmacSha256::new(&hmac_key);
821        hmac.update(&[0, 1, 2, 3]);
822        let out = hmac.finalize();
823
824        eprintln!("{:?}", out.into_bytes());
825    }
826
827    #[test]
828    #[cfg_attr(
829        all(target_arch = "wasm32", any(target_os = "unknown", target_os = "none")),
830        wasm_bindgen_test
831    )]
832    fn hmac_512_basic() {
833        use crate::hmac_s512::*;
834        use cipher::KeyInit;
835
836        let hmac_key = new_hmac_sha512_key();
837
838        let mut hmac = HmacSha512::new(&hmac_key);
839        hmac.update(&[0, 1, 2, 3]);
840        let out = hmac.finalize();
841
842        eprintln!("{:?}", out.into_bytes());
843    }
844
845    #[test]
846    #[cfg_attr(
847        all(target_arch = "wasm32", any(target_os = "unknown", target_os = "none")),
848        wasm_bindgen_test
849    )]
850    fn aes256gcm_basic() {
851        use crate::aes256;
852        use crate::aes256gcm::*;
853
854        let aes256gcm_key = aes256::new_key();
855
856        let cipher = Aes256Gcm::new(&aes256gcm_key);
857
858        let nonce = new_nonce();
859
860        // These are the "basic" encrypt/decrypt which postfixs a tag.
861        let ciphertext = cipher
862            .encrypt(&nonce, b"plaintext message".as_ref())
863            .expect("Failed to encrypt message");
864        let plaintext = cipher
865            .decrypt(&nonce, ciphertext.as_ref())
866            .expect("Failed to decrypt message");
867
868        assert_eq!(&plaintext, b"plaintext message");
869
870        // For control of the tag, the following is used.
871
872        // Never re-use nonces
873        let nonce = new_nonce();
874
875        let mut buffer = Vec::from(b"test message, super cool");
876
877        // Same as "None"
878        let associated_data = b"";
879
880        let tag = cipher
881            .encrypt_inout_detached(&nonce, associated_data, buffer.as_mut_slice().into())
882            .expect("Failed to encrypt message");
883
884        cipher
885            .decrypt_inout_detached(&nonce, associated_data, buffer.as_mut_slice().into(), &tag)
886            .expect("Failed to decrypt message");
887
888        assert_eq!(buffer, b"test message, super cool");
889    }
890
891    #[test]
892    fn aes256cts_basic() {
893        use crate::aes256;
894        use crate::aes256cts::{self, *};
895        use crate::traits::Generate;
896
897        let key = aes256::new_key();
898        let iv = Aes256CtsIv::generate();
899
900        let enc = aes256cts::Aes256CtsEnc::new(&key, &iv);
901
902        let original_buffer = b"plaintext message";
903        let mut buffer = *original_buffer;
904
905        enc.encrypt(&mut buffer).expect("encryption failed");
906
907        assert_ne!(&buffer, original_buffer);
908
909        let dec = aes256cts::Aes256CtsDec::new(&key, &iv);
910
911        dec.decrypt(&mut buffer).expect("decryption failed");
912
913        assert_eq!(&buffer, original_buffer);
914    }
915
916    #[test]
917    #[cfg_attr(
918        all(target_arch = "wasm32", any(target_os = "unknown", target_os = "none")),
919        wasm_bindgen_test
920    )]
921    fn aes256cbc_basic() {
922        use crate::aes256;
923        use crate::aes256cbc::{self, *};
924
925        let key = aes256::new_key();
926        let iv = aes256cbc::new_iv();
927
928        let enc = aes256cbc::Aes256CbcEnc::new(&key, &iv);
929
930        let ciphertext = enc.encrypt_padded_vec::<block_padding::Pkcs7>(b"plaintext message");
931
932        let dec = aes256cbc::Aes256CbcDec::new(&key, &iv);
933
934        let plaintext = dec
935            .decrypt_padded_vec::<block_padding::Pkcs7>(&ciphertext)
936            .expect("Unpadding Failed");
937
938        assert_eq!(plaintext, b"plaintext message");
939    }
940
941    #[test]
942    #[cfg_attr(
943        all(target_arch = "wasm32", any(target_os = "unknown", target_os = "none")),
944        wasm_bindgen_test
945    )]
946    fn aes256cbc_hmac_basic() {
947        use crate::aes256;
948        use crate::aes256cbc::{self, block_padding};
949
950        let key = aes256::new_key();
951
952        let (mac, iv, ciphertext) =
953            aes256cbc::enc::<block_padding::Pkcs7>(&key, b"plaintext message")
954                .expect("Failed to encrypt message");
955
956        let plaintext = aes256cbc::dec::<block_padding::Pkcs7>(&key, &mac, &iv, &ciphertext)
957            .expect("Failed to decrypt message");
958
959        assert_eq!(plaintext, b"plaintext message");
960    }
961
962    #[test]
963    #[cfg_attr(
964        all(target_arch = "wasm32", any(target_os = "unknown", target_os = "none")),
965        wasm_bindgen_test
966    )]
967    fn aes256kw_basic() {
968        use crate::aes256;
969        use crate::aes256kw::*;
970
971        let key_wrap_key = aes256::new_key();
972        let key_wrap = Aes256Kw::new(&key_wrap_key);
973
974        let key_to_wrap = aes256::new_key();
975        let mut wrapped_key = Aes256KwWrapped::default();
976
977        // Wrap it.
978        key_wrap
979            .wrap_key(&key_to_wrap, &mut wrapped_key)
980            .expect("Failed to wrap key");
981        // Reverse the process
982
983        let mut key_unwrapped = aes256::Aes256Key::default();
984
985        key_wrap
986            .unwrap_key(&wrapped_key, &mut key_unwrapped)
987            .expect("Failed to unwrap key");
988
989        assert_eq!(key_to_wrap, key_unwrapped);
990    }
991
992    #[test]
993    #[cfg_attr(
994        all(target_arch = "wasm32", any(target_os = "unknown", target_os = "none")),
995        wasm_bindgen_test
996    )]
997    fn rsa_basic() {
998        use crate::rsa::*;
999        use crate::traits::*;
1000
1001        let pkey = new_key(MIN_BITS).expect("Failed to generate RSA key");
1002
1003        let pubkey = RS256PublicKey::from(&pkey);
1004
1005        // OAEP
1006
1007        let ciphertext =
1008            oaep_sha256_encrypt(&pubkey, b"this is a message").expect("Failed to encrypt message");
1009
1010        let plaintext = oaep_sha256_decrypt(&pkey, &ciphertext).expect("Failed to decrypt message");
1011
1012        assert_eq!(plaintext, b"this is a message");
1013
1014        // PKCS1.5 Sig
1015        let signing_key = RS256SigningKey::new(pkey);
1016        let verifying_key = RS256VerifyingKey::new(pubkey);
1017
1018        let mut rng = rand::rng();
1019
1020        let data = b"Fully sick data to sign mate.";
1021
1022        let signature = signing_key.sign_with_rng(&mut rng, data);
1023        assert!(verifying_key.verify(data, &signature).is_ok());
1024
1025        let signature = signing_key.sign(data);
1026        assert!(verifying_key.verify(data, &signature).is_ok());
1027    }
1028
1029    #[test]
1030    #[cfg_attr(
1031        all(target_arch = "wasm32", any(target_os = "unknown", target_os = "none")),
1032        wasm_bindgen_test
1033    )]
1034    fn ecdsa_p256_basic() {
1035        use crate::ecdsa_p256::*;
1036        use crate::traits::*;
1037
1038        let priv_key = new_key();
1039
1040        let pub_key = priv_key.public_key();
1041
1042        let signer = EcdsaP256SigningKey::from(&priv_key);
1043        let verifier = EcdsaP256VerifyingKey::from(&pub_key);
1044
1045        // Can either sign data directly, using the correct associated hash type.
1046        let data = [0, 1, 2, 3, 4, 5, 6, 7];
1047
1048        let sig: EcdsaP256Signature = signer.try_sign(&data).expect("Failed to sign data");
1049
1050        assert!(verifier.verify(&data, &sig).is_ok());
1051
1052        // Or you can build the digest content directly, based on the type of the C::Digest value.
1053        let sig: EcdsaP256Signature = signer
1054            .try_sign_digest(|digest: &mut EcdsaP256Digest| {
1055                digest.update(data);
1056                Ok(())
1057            })
1058            .expect("Failed to sign digest");
1059        assert!(verifier.verify(&data, &sig).is_ok());
1060    }
1061
1062    #[test]
1063    #[cfg_attr(
1064        all(target_arch = "wasm32", any(target_os = "unknown", target_os = "none")),
1065        wasm_bindgen_test
1066    )]
1067    fn ecdh_p256_basic() {
1068        use crate::ecdh_p256::*;
1069
1070        let secret_a = new_secret();
1071        let secret_b = new_secret();
1072
1073        let public_a = secret_a.public_key();
1074        let public_b = secret_b.public_key();
1075
1076        let derived_secret_a = secret_a.diffie_hellman(&public_b);
1077        let derived_secret_b = secret_b.diffie_hellman(&public_a);
1078
1079        assert_eq!(
1080            derived_secret_a.raw_secret_bytes(),
1081            derived_secret_b.raw_secret_bytes()
1082        );
1083    }
1084
1085    #[test]
1086    #[cfg_attr(
1087        all(target_arch = "wasm32", any(target_os = "unknown", target_os = "none")),
1088        wasm_bindgen_test
1089    )]
1090    fn pkcs8_handling_test() {
1091        use crate::ecdsa_p256;
1092        use crate::traits::Pkcs8EncodePrivateKey;
1093
1094        use pkcs8::PrivateKeyInfoRef;
1095
1096        let ecdsa_priv_key = ecdsa_p256::new_key();
1097        let ecdsa_priv_key_der = ecdsa_priv_key
1098            .to_pkcs8_der()
1099            .expect("Failed to encode ECDSA private key");
1100
1101        let priv_key_info = PrivateKeyInfoRef::try_from(ecdsa_priv_key_der.as_bytes())
1102            .expect("Failed to parse private key info");
1103
1104        eprintln!("{priv_key_info:?}");
1105    }
1106
1107    #[cfg(any(unix, windows))]
1108    #[test]
1109    fn rustls_mtls_basic() {
1110        use crate::test_ca::*;
1111        use crate::x509::X509Display;
1112        use elliptic_curve::SecretKey;
1113        use rustls::{
1114            self, RootCertStore,
1115            client::{ClientConfig, ClientConnection},
1116            pki_types::{CertificateDer, PrivateKeyDer, PrivatePkcs8KeyDer, ServerName},
1117            server::{ServerConfig, ServerConnection},
1118        };
1119        use std::io::Read;
1120        use std::io::Write;
1121        #[cfg(unix)]
1122        use std::os::unix::net::UnixStream;
1123        use std::str::FromStr;
1124        use std::sync::Arc;
1125        use std::sync::atomic::{AtomicU16, Ordering};
1126        use std::time::Duration;
1127        #[cfg(windows)]
1128        use uds_windows::UnixStream;
1129        use x509_cert::der::Encode;
1130        use x509_cert::name::Name;
1131        use x509_cert::time::Time;
1132
1133        // ========================
1134        // CA SETUP
1135
1136        let now = now();
1137        let not_before = Time::try_from(now).expect("Failed to convert system time to X509 time");
1138        let not_after = Time::try_from(now + Duration::new(3600, 0))
1139            .expect("Failed to convert system time to X509 time");
1140
1141        let (root_signing_key, root_ca_cert) = build_test_ca_root(not_before, not_after);
1142
1143        eprintln!("{}", X509Display::from(&root_ca_cert));
1144
1145        let subject = Name::from_str("CN=localhost").expect("Failed to parse subject name");
1146
1147        let (server_key, server_csr) = build_test_csr(&subject);
1148
1149        let server_cert = test_ca_sign_server_csr(
1150            not_before,
1151            not_after,
1152            &server_csr,
1153            &root_signing_key,
1154            &root_ca_cert,
1155        );
1156
1157        eprintln!("{}", X509Display::from(&server_cert));
1158
1159        // ========================
1160        use p384::pkcs8::EncodePrivateKey;
1161        let server_private_key_pkcs8_der = SecretKey::from(server_key)
1162            .to_pkcs8_der()
1163            .expect("Failed to encode server private key");
1164
1165        let root_ca_cert_der = root_ca_cert
1166            .to_der()
1167            .expect("Failed to encode root CA certificate");
1168        let server_cert_der = server_cert
1169            .to_der()
1170            .expect("Failed to encode server certificate");
1171
1172        let mut ca_roots = RootCertStore::empty();
1173
1174        ca_roots
1175            .add(CertificateDer::from(root_ca_cert_der.clone()))
1176            .expect("Failed to add root CA certificate");
1177
1178        let server_chain = vec![
1179            CertificateDer::from(server_cert_der),
1180            CertificateDer::from(root_ca_cert_der),
1181        ];
1182
1183        let server_private_key: PrivateKeyDer =
1184            PrivatePkcs8KeyDer::from(server_private_key_pkcs8_der.as_bytes().to_vec()).into();
1185
1186        // let provider = Arc::new(rustls_rustcrypto::provider());
1187        let provider = Arc::new(rustls::crypto::aws_lc_rs::default_provider());
1188
1189        let client_tls_config: Arc<_> = ClientConfig::builder_with_provider(provider.clone())
1190            .with_safe_default_protocol_versions()
1191            .expect("invalid protocol versions")
1192            .with_root_certificates(ca_roots)
1193            .with_no_client_auth()
1194            .into();
1195
1196        let server_tls_config: Arc<_> = ServerConfig::builder_with_provider(provider)
1197            .with_safe_default_protocol_versions()
1198            .expect("invalid protocol versions")
1199            .with_no_client_auth()
1200            .with_single_cert(server_chain, server_private_key)
1201            .map(Arc::new)
1202            .expect("bad certificate/key");
1203
1204        let server_name = ServerName::try_from("localhost").expect("invalid DNS name");
1205
1206        let (mut server_unix_stream, mut client_unix_stream) =
1207            UnixStream::pair().expect("Failed to create UnixStream pair");
1208
1209        let atomic = Arc::new(AtomicU16::new(0));
1210
1211        let atomic_t = atomic.clone();
1212
1213        let handle = std::thread::spawn(move || {
1214            let mut client_connection = ClientConnection::new(client_tls_config, server_name)
1215                .expect("Failed to create client connection");
1216
1217            let mut client = rustls::Stream::new(&mut client_connection, &mut client_unix_stream);
1218
1219            client.write_all(b"hello").expect("Failed to write data");
1220
1221            while atomic_t.load(Ordering::Relaxed) != 1 {
1222                std::thread::sleep(std::time::Duration::from_millis(1));
1223            }
1224
1225            println!("THREAD DONE");
1226        });
1227
1228        let mut server_connection =
1229            ServerConnection::new(server_tls_config).expect("Failed to create server connection");
1230
1231        server_connection
1232            .complete_io(&mut server_unix_stream)
1233            .expect("Failed to complete TLS handshake");
1234
1235        server_connection
1236            .complete_io(&mut server_unix_stream)
1237            .expect("Failed to complete TLS handshake");
1238
1239        let mut buf: [u8; 5] = [0; 5];
1240        server_connection
1241            .reader()
1242            .read_exact(&mut buf)
1243            .expect("Failed to read data");
1244
1245        assert_eq!(&buf, b"hello");
1246
1247        atomic.store(1, Ordering::Relaxed);
1248
1249        // If the thread paniced, this will panic.
1250        handle.join().expect("Thread panicked");
1251    }
1252}