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