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
31pub mod traits {
32    pub use aes_gcm::aead::AeadInOut;
33    pub use crypto_common::{Generate, KeyInit, OutputSizeUser};
34    pub use der::{
35        Decode as DecodeDer, DecodePem, Encode as EncodeDer, EncodePem,
36        pem::LineEnding as LineEndingPem, referenced::OwnedToRef,
37    };
38    pub use digest::FixedOutput;
39    pub use elliptic_curve::sec1::{FromSec1Point, ToSec1Point};
40    pub use hmac::{Hmac, Mac};
41    pub use pkcs8::{
42        DecodePrivateKey as Pkcs8DecodePrivateKey, EncodePrivateKey as Pkcs8EncodePrivateKey,
43    };
44    pub use rsa::pkcs1::{
45        DecodeRsaPrivateKey as Pkcs1DecodeRsaPrivateKey,
46        EncodeRsaPrivateKey as Pkcs1EncodeRsaPrivateKey,
47    };
48    pub use rsa::signature::{
49        DigestSigner, DigestVerifier, Keypair, RandomizedSigner, SignatureEncoding, Signer,
50        Verifier,
51    };
52    pub use rsa::traits::PublicKeyParts;
53    pub use sha2::Digest;
54    pub use spki::{
55        DecodePublicKey as SpkiDecodePublicKey, DynSignatureAlgorithmIdentifier,
56        EncodePublicKey as SpkiEncodePublicKey,
57    };
58    pub use zeroize::Zeroizing;
59    pub mod hazmat {
60        //! 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.
61
62        pub use rsa::signature::hazmat::PrehashVerifier;
63    }
64    pub use x509_cert::ext::ToExtension;
65}
66
67pub mod x509;
68
69pub mod md5 {
70    pub use md5::*;
71}
72
73pub mod sha1 {
74    use hybrid_array::{Array, sizes::U20};
75
76    pub use sha1::Sha1;
77
78    pub type Sha1Output = Array<u8, U20>;
79}
80
81pub mod s256 {
82    use hybrid_array::{Array, sizes::U32};
83
84    pub use sha2::Sha256;
85
86    pub type Sha256Output = Array<u8, U32>;
87}
88
89pub mod s384 {
90    use hybrid_array::{Array, sizes::U48};
91
92    pub use sha2::Sha384;
93
94    pub type Sha384Output = Array<u8, U48>;
95}
96
97pub mod s512 {
98    use hybrid_array::{Array, sizes::U64};
99
100    pub use sha2::Sha512;
101
102    pub type Sha512Output = Array<u8, U64>;
103}
104
105pub mod hkdf_s256 {
106    use hkdf::Hkdf;
107    use sha2::Sha256;
108
109    pub type HkdfSha256 = Hkdf<Sha256>;
110}
111
112pub mod hmac_s1 {
113    use crypto_common::Key;
114    use crypto_common::Output;
115
116    use hmac::Hmac;
117    use hmac::Mac;
118    use sha1::Sha1;
119    use sha1::digest::CtOutput;
120    use zeroize::Zeroizing;
121
122    pub type HmacSha1 = Hmac<Sha1>;
123
124    pub type HmacSha1Key = Zeroizing<Key<Hmac<Sha1>>>;
125
126    pub type HmacSha1Output = CtOutput<HmacSha1>;
127
128    pub type HmacSha1Bytes = Output<HmacSha1>;
129
130    pub fn new_key() -> HmacSha1Key {
131        use crypto_common::Generate;
132        Key::<HmacSha1>::generate().into()
133    }
134
135    pub fn oneshot(key: &HmacSha1Key, data: &[u8]) -> HmacSha1Output {
136        use crypto_common::KeyInit;
137
138        let mut hmac = HmacSha1::new(key);
139        hmac.update(data);
140        hmac.finalize()
141    }
142
143    #[allow(clippy::needless_pass_by_value)]
144    pub fn key_from_vec(bytes: Vec<u8>) -> Option<HmacSha1Key> {
145        key_from_slice(&bytes)
146    }
147
148    pub fn key_from_slice(bytes: &[u8]) -> Option<HmacSha1Key> {
149        use crypto_common::KeySizeUser;
150        // Key too short - too long.
151        if bytes.len() < 16 || bytes.len() > Hmac::<Sha1>::key_size() {
152            None
153        } else {
154            let mut key = Key::<Hmac<Sha1>>::default();
155            let key_ref = &mut key.as_mut_slice()[..bytes.len()];
156            key_ref.copy_from_slice(bytes);
157            Some(key.into())
158        }
159    }
160
161    pub fn key_from_bytes(bytes: [u8; 64]) -> HmacSha1Key {
162        Key::<Hmac<Sha1>>::from(bytes).into()
163    }
164
165    pub fn key_size() -> usize {
166        use crypto_common::KeySizeUser;
167        Hmac::<Sha1>::key_size()
168    }
169}
170
171pub mod hmac_s256 {
172    use crypto_common::Key;
173    use crypto_common::Output;
174
175    use hmac::Hmac;
176    use hmac::Mac;
177    use sha2::Sha256;
178    use sha2::digest::CtOutput;
179    use zeroize::Zeroizing;
180
181    pub type HmacSha256 = Hmac<Sha256>;
182
183    pub type HmacSha256Key = Zeroizing<Key<Hmac<Sha256>>>;
184
185    pub type HmacSha256Output = CtOutput<HmacSha256>;
186
187    pub type HmacSha256Bytes = Output<HmacSha256>;
188
189    pub fn new_key() -> HmacSha256Key {
190        use crypto_common::Generate;
191        Key::<HmacSha256>::generate().into()
192    }
193
194    pub fn oneshot(key: &HmacSha256Key, data: &[u8]) -> HmacSha256Output {
195        use crypto_common::KeyInit;
196
197        let mut hmac = HmacSha256::new(key);
198        hmac.update(data);
199        hmac.finalize()
200    }
201
202    #[allow(clippy::needless_pass_by_value)]
203    pub fn key_from_vec(bytes: Vec<u8>) -> Option<HmacSha256Key> {
204        key_from_slice(&bytes)
205    }
206
207    pub fn key_from_slice(bytes: &[u8]) -> Option<HmacSha256Key> {
208        use crypto_common::KeySizeUser;
209        // Key too short - too long.
210        if bytes.len() < 16 || bytes.len() > Hmac::<Sha256>::key_size() {
211            None
212        } else {
213            let mut key = Key::<Hmac<Sha256>>::default();
214            let key_ref = &mut key.as_mut_slice()[..bytes.len()];
215            key_ref.copy_from_slice(bytes);
216            Some(key.into())
217        }
218    }
219
220    pub fn key_from_bytes(bytes: [u8; 64]) -> HmacSha256Key {
221        Key::<Hmac<Sha256>>::from(bytes).into()
222    }
223
224    pub fn key_size() -> usize {
225        use crypto_common::KeySizeUser;
226        Hmac::<Sha256>::key_size()
227    }
228}
229
230pub mod hmac_s512 {
231    use crypto_common::Key;
232    use crypto_common::Output;
233
234    use hmac::Hmac;
235    use sha2::Sha512;
236    use sha2::digest::CtOutput;
237    use zeroize::Zeroizing;
238
239    pub use hmac::Mac;
240
241    pub type HmacSha512 = Hmac<Sha512>;
242
243    pub type HmacSha512Key = Zeroizing<Key<Hmac<Sha512>>>;
244
245    pub type HmacSha512Output = CtOutput<HmacSha512>;
246
247    pub type HmacSha512Bytes = Output<HmacSha512>;
248
249    pub fn new_hmac_sha512_key() -> HmacSha512Key {
250        use crypto_common::Generate;
251        Key::<HmacSha512>::generate().into()
252    }
253
254    pub fn oneshot(key: &HmacSha512Key, data: &[u8]) -> HmacSha512Output {
255        use crypto_common::KeyInit;
256
257        let mut hmac = HmacSha512::new(key);
258        hmac.update(data);
259        hmac.finalize()
260    }
261
262    pub fn key_from_slice(bytes: &[u8]) -> Option<HmacSha512Key> {
263        use crypto_common::KeySizeUser;
264        // Key too short - too long.
265        if bytes.len() < 16 || bytes.len() > Hmac::<Sha512>::key_size() {
266            None
267        } else {
268            let mut key = Key::<Hmac<Sha512>>::default();
269            let key_ref = &mut key.as_mut_slice()[..bytes.len()];
270            key_ref.copy_from_slice(bytes);
271            Some(key.into())
272        }
273    }
274
275    pub fn key_size() -> usize {
276        use crypto_common::KeySizeUser;
277        Hmac::<Sha512>::key_size()
278    }
279}
280
281pub mod aes128 {
282    use aes;
283    use crypto_common::Key;
284    use zeroize::Zeroizing;
285
286    pub type Aes128Key = Zeroizing<Key<aes::Aes128>>;
287
288    pub fn key_size() -> usize {
289        use crypto_common::KeySizeUser;
290        aes::Aes128::key_size()
291    }
292
293    pub fn key_from_slice(bytes: &[u8]) -> Option<Aes128Key> {
294        Key::<aes::Aes128>::try_from(bytes)
295            .ok()
296            .map(|key| key.into())
297    }
298
299    pub fn key_from_bytes(bytes: [u8; 16]) -> Aes128Key {
300        Key::<aes::Aes128>::from(bytes).into()
301    }
302
303    pub fn new_key() -> Aes128Key {
304        use crypto_common::Generate;
305        Key::<aes::Aes128>::generate().into()
306    }
307}
308
309pub mod aes128gcm {
310    use aes::cipher::consts::{U12, U16};
311
312    pub use aes_gcm::aead::{Aead, AeadInOut, Payload};
313    pub use crypto_common::KeyInit;
314
315    pub use crate::aes128::Aes128Key;
316
317    pub type Aes128Gcm = aes_gcm::Aes128Gcm;
318
319    pub type Aes128GcmNonce = aes_gcm::Nonce<U12>;
320    pub type Aes128GcmTag = aes_gcm::Tag<U16>;
321
322    pub fn new_nonce() -> Aes128GcmNonce {
323        use crypto_common::Generate;
324        Aes128GcmNonce::generate()
325    }
326}
327
328pub mod aes128kw {
329    use hybrid_array::{Array, sizes::U24};
330
331    pub use crypto_common::KeyInit;
332
333    pub type Aes128Kw = aes_kw::KwAes128;
334
335    pub type Aes128KwWrapped = Array<u8, U24>;
336}
337
338pub mod aes256 {
339    use aes;
340    use aes::cipher::Array;
341    use crypto_common::Key;
342    use zeroize::Zeroizing;
343
344    pub use aes::Aes256;
345    pub use aes::cipher::{BlockCipherDecrypt, BlockCipherEncrypt};
346
347    pub type Aes256Key = Zeroizing<Key<aes::Aes256>>;
348    pub type Aes256BlockSize = <aes::Aes256 as aes::cipher::BlockSizeUser>::BlockSize;
349    pub type Aes256Block = Array<u8, <aes::Aes256 as aes::cipher::BlockSizeUser>::BlockSize>;
350
351    pub fn key_size() -> usize {
352        use crypto_common::KeySizeUser;
353        aes::Aes256::key_size()
354    }
355
356    pub fn key_from_slice(bytes: &[u8]) -> Option<Aes256Key> {
357        Key::<aes::Aes256>::try_from(bytes)
358            .ok()
359            .map(|key| key.into())
360    }
361
362    pub fn key_from_bytes(bytes: [u8; 32]) -> Aes256Key {
363        Key::<aes::Aes256>::from(bytes).into()
364    }
365
366    pub fn new_key() -> Aes256Key {
367        use crypto_common::Generate;
368        Key::<aes::Aes256>::generate().into()
369    }
370}
371
372pub mod aes256gcm {
373    use aes::Aes256;
374    use aes::cipher::consts::{U12, U16};
375    use aes_gcm::AesGcm;
376
377    pub use aes_gcm::aead::{Aead, AeadInOut, Payload};
378    pub use crypto_common::KeyInit;
379
380    pub use crate::aes256::Aes256Key;
381
382    // Same as  AesGcm<Aes256, U12, U16>;
383    pub type Aes256Gcm = aes_gcm::Aes256Gcm;
384
385    pub type Aes256GcmN16 = AesGcm<Aes256, U16, U16>;
386    pub type Aes256GcmNonce16 = aes_gcm::Nonce<U16>;
387
388    pub type Aes256GcmNonce = aes_gcm::Nonce<U12>;
389    pub type Aes256GcmTag = aes_gcm::Tag<U16>;
390
391    pub fn new_nonce() -> Aes256GcmNonce {
392        use crypto_common::Generate;
393        Aes256GcmNonce::generate()
394    }
395}
396
397pub mod aes256cts {
398    use aes::cipher::Array;
399    use aes::cipher::consts::U16;
400
401    pub use crate::aes256::Aes256Key;
402    pub use aes::cipher::{BlockModeDecrypt, BlockModeEncrypt, InnerIvInit, KeyIvInit};
403
404    pub use cts::Decrypt as CtsDecrypt;
405    pub use cts::Encrypt as CtsEncrypt;
406
407    pub type Aes256CtsEnc = cts::CbcCs3<aes::Aes256>;
408    pub type Aes256CtsDec = cts::CbcCs3<aes::Aes256>;
409
410    pub type Aes256CtsIv = Array<u8, U16>;
411
412    pub fn new_iv() -> Aes256CtsIv {
413        use crypto_common::Generate;
414        Aes256CtsIv::generate()
415    }
416}
417
418pub mod aes256cbc {
419    use crate::hmac_s256::HmacSha256;
420    use crate::hmac_s256::HmacSha256Output;
421    use aes::cipher::Array;
422    use aes::cipher::consts::U16;
423
424    pub use crate::aes256::Aes256Key;
425
426    pub use aes::cipher::{BlockModeDecrypt, BlockModeEncrypt, KeyIvInit, block_padding};
427
428    pub type Aes256CbcEnc = cbc::Encryptor<aes::Aes256>;
429    pub type Aes256CbcDec = cbc::Decryptor<aes::Aes256>;
430
431    pub type Aes256CbcIv = Array<u8, U16>;
432
433    pub fn new_iv() -> Aes256CbcIv {
434        use crypto_common::Generate;
435        Aes256CbcIv::generate()
436    }
437
438    pub fn enc<P>(
439        key: &Aes256Key,
440        data: &[u8],
441    ) -> Result<(HmacSha256Output, Aes256CbcIv, Vec<u8>), crypto_common::InvalidLength>
442    where
443        P: block_padding::Padding,
444    {
445        use cipher::BlockModeEncrypt;
446        use cipher::KeyInit;
447        use hmac::Mac;
448
449        let iv = new_iv();
450        let enc = Aes256CbcEnc::new(key, &iv);
451
452        let ciphertext = enc.encrypt_padded_vec::<P>(data);
453
454        let mut hmac = HmacSha256::new_from_slice(key.as_slice())?;
455        hmac.update(&ciphertext);
456        let mac = hmac.finalize();
457
458        Ok((mac, iv, ciphertext))
459    }
460
461    pub fn dec<P>(
462        key: &Aes256Key,
463        mac: &HmacSha256Output,
464        iv: &Aes256CbcIv,
465        ciphertext: &[u8],
466    ) -> Option<Vec<u8>>
467    where
468        P: block_padding::Padding,
469    {
470        use cipher::BlockModeDecrypt;
471        use cipher::KeyInit;
472        use hmac::Mac;
473
474        let mut hmac = HmacSha256::new_from_slice(key.as_slice()).ok()?;
475        hmac.update(ciphertext);
476        let check_mac = hmac.finalize();
477
478        if check_mac != *mac {
479            return None;
480        }
481
482        let dec = Aes256CbcDec::new(key, iv);
483
484        let plaintext = dec.decrypt_padded_vec::<P>(ciphertext).ok()?;
485
486        Some(plaintext)
487    }
488}
489
490pub mod aes256kw {
491    use hybrid_array::{Array, sizes::U40};
492
493    pub use crypto_common::KeyInit;
494
495    pub type Aes256Kw = aes_kw::KwAes256;
496
497    pub type Aes256KwWrapped = Array<u8, U40>;
498}
499
500pub mod rsa {
501    use rsa::pkcs1v15::{Signature, SigningKey, VerifyingKey};
502    use rsa::{RsaPrivateKey, RsaPublicKey};
503
504    pub use rand;
505    pub use rsa::BoxedUint as BigUint;
506    pub use rsa::{Oaep, pkcs1v15};
507    pub use sha2::{Sha256, Sha384};
508
509    pub const MIN_BITS: usize = 2048;
510
511    pub type RS256PrivateKey = RsaPrivateKey;
512    pub type RS256PublicKey = RsaPublicKey;
513    pub type RS256Signature = Signature;
514    pub type RS256Digest = Sha256;
515    pub type RS256VerifyingKey = VerifyingKey<Sha256>;
516    pub type RS256SigningKey = SigningKey<Sha256>;
517
518    pub type RS384Digest = Sha384;
519    pub type RS384VerifyingKey = VerifyingKey<Sha384>;
520    pub type RS384SigningKey = SigningKey<Sha384>;
521
522    pub fn new_key(bits: usize) -> rsa::errors::Result<RsaPrivateKey> {
523        let bits = std::cmp::max(bits, MIN_BITS);
524        let mut rng = rand::rng();
525        RsaPrivateKey::new(&mut rng, bits)
526    }
527
528    pub fn oaep_sha256_encrypt(
529        public_key: &RsaPublicKey,
530        data: &[u8],
531    ) -> rsa::errors::Result<Vec<u8>> {
532        let mut rng = rand::rng();
533        let padding = Oaep::<Sha256>::new();
534        public_key.encrypt(&mut rng, padding, data)
535    }
536
537    pub fn oaep_sha256_decrypt(
538        private_key: &RsaPrivateKey,
539        ciphertext: &[u8],
540    ) -> rsa::errors::Result<Vec<u8>> {
541        let padding = Oaep::<Sha256>::new();
542        private_key.decrypt(padding, ciphertext)
543    }
544}
545
546pub mod ec {
547    pub use sec1::EcPrivateKey;
548}
549
550pub mod ecdh {
551    pub use elliptic_curve::ecdh::diffie_hellman;
552}
553
554pub mod ecdh_p256 {
555    use elliptic_curve::ecdh::{EphemeralSecret, SharedSecret};
556    use elliptic_curve::sec1::Sec1Point;
557    use elliptic_curve::{FieldBytes, PublicKey};
558    use hkdf::Hkdf;
559    use p256::NistP256;
560    use sha2::Sha256;
561
562    pub type EcdhP256EphemeralSecret = EphemeralSecret<NistP256>;
563    pub type EcdhP256SharedSecret = SharedSecret<NistP256>;
564    pub type EcdhP256PublicKey = PublicKey<NistP256>;
565    pub type EcdhP256PublicSec1Point = Sec1Point<NistP256>;
566    pub type EcdhP256FieldBytes = FieldBytes<NistP256>;
567
568    pub type EcdhP256Hkdf = Hkdf<Sha256>;
569
570    pub type EcdhP256Digest = Sha256;
571
572    pub fn new_secret() -> EcdhP256EphemeralSecret {
573        use crypto_common::Generate;
574        EcdhP256EphemeralSecret::generate()
575    }
576}
577
578pub mod ecdsa_p256 {
579    use ecdsa::DigestAlgorithm;
580    use ecdsa::{Signature, SignatureBytes, SigningKey, VerifyingKey};
581    use elliptic_curve::point::AffinePoint;
582    use elliptic_curve::scalar::NonZeroScalar;
583    use elliptic_curve::sec1::FromSec1Point;
584    use elliptic_curve::sec1::Sec1Point;
585    use elliptic_curve::{FieldBytes, PublicKey, SecretKey};
586    use hybrid_array::{Array, sizes::U32};
587    use p256::{NistP256, ecdsa::DerSignature};
588
589    pub type EcdsaP256Digest = <NistP256 as DigestAlgorithm>::Digest;
590
591    pub type EcdsaP256PrivateKey = SecretKey<NistP256>;
592    pub type EcdsaP256NonZeroScalar = NonZeroScalar<NistP256>;
593
594    pub type EcdsaP256FieldBytes = FieldBytes<NistP256>;
595    pub type EcdsaP256AffinePoint = AffinePoint<NistP256>;
596
597    pub type EcdsaP256PublicKey = PublicKey<NistP256>;
598
599    pub type EcdsaP256PublicCoordinate = Array<u8, U32>;
600    pub type EcdsaP256PublicSec1Point = Sec1Point<NistP256>;
601
602    pub type EcdsaP256SigningKey = SigningKey<NistP256>;
603    pub type EcdsaP256VerifyingKey = VerifyingKey<NistP256>;
604
605    pub type EcdsaP256Signature = Signature<NistP256>;
606    pub type EcdsaP256DerSignature = DerSignature;
607    pub type EcdsaP256SignatureBytes = SignatureBytes<NistP256>;
608
609    pub fn new_key() -> EcdsaP256PrivateKey {
610        use crypto_common::Generate;
611
612        EcdsaP256PrivateKey::generate()
613    }
614
615    pub fn from_coords_raw(x: &[u8], y: &[u8]) -> Option<EcdsaP256PublicKey> {
616        let mut field_x = EcdsaP256FieldBytes::default();
617        if x.len() != field_x.len() {
618            return None;
619        }
620
621        let mut field_y = EcdsaP256FieldBytes::default();
622        if y.len() != field_y.len() {
623            return None;
624        }
625
626        field_x.copy_from_slice(x);
627        field_y.copy_from_slice(y);
628
629        let ep = EcdsaP256PublicSec1Point::from_affine_coordinates(&field_x, &field_y, false);
630
631        EcdsaP256PublicKey::from_sec1_point(&ep).into_option()
632    }
633}
634
635pub mod ecdsa_p384 {
636    use ecdsa::DigestAlgorithm;
637    use ecdsa::{Signature, SignatureBytes, SigningKey, VerifyingKey};
638    use elliptic_curve::point::AffinePoint;
639    use elliptic_curve::sec1::FromSec1Point;
640    use elliptic_curve::sec1::Sec1Point;
641    use elliptic_curve::{FieldBytes, PublicKey, SecretKey};
642    use p384::{NistP384, ecdsa::DerSignature};
643    // use sha2::digest::consts::U32;
644
645    pub type EcdsaP384Digest = <NistP384 as DigestAlgorithm>::Digest;
646
647    pub type EcdsaP384PrivateKey = SecretKey<NistP384>;
648
649    pub type EcdsaP384FieldBytes = FieldBytes<NistP384>;
650    pub type EcdsaP384AffinePoint = AffinePoint<NistP384>;
651
652    pub type EcdsaP384PublicKey = PublicKey<NistP384>;
653
654    // pub type EcdsaP384PublicCoordinate = GenericArray<u8, U32>;
655    pub type EcdsaP384PublicSec1Point = Sec1Point<NistP384>;
656
657    pub type EcdsaP384SigningKey = SigningKey<NistP384>;
658    pub type EcdsaP384VerifyingKey = VerifyingKey<NistP384>;
659
660    pub type EcdsaP384Signature = Signature<NistP384>;
661    pub type EcdsaP384DerSignature = DerSignature;
662    pub type EcdsaP384SignatureBytes = SignatureBytes<NistP384>;
663
664    pub fn new_key() -> EcdsaP384PrivateKey {
665        use crypto_common::Generate;
666        EcdsaP384PrivateKey::generate()
667    }
668
669    pub fn from_coords_raw(x: &[u8], y: &[u8]) -> Option<EcdsaP384PublicKey> {
670        let mut field_x = EcdsaP384FieldBytes::default();
671        if x.len() != field_x.len() {
672            return None;
673        }
674
675        let mut field_y = EcdsaP384FieldBytes::default();
676        if y.len() != field_y.len() {
677            return None;
678        }
679
680        field_x.copy_from_slice(x);
681        field_y.copy_from_slice(y);
682
683        let ep = EcdsaP384PublicSec1Point::from_affine_coordinates(&field_x, &field_y, false);
684
685        EcdsaP384PublicKey::from_sec1_point(&ep).into_option()
686    }
687}
688
689pub mod ecdsa_p521 {
690    use ecdsa::DigestAlgorithm;
691    use ecdsa::{Signature, SignatureBytes, SigningKey, VerifyingKey};
692    use elliptic_curve::point::AffinePoint;
693    use elliptic_curve::sec1::FromSec1Point;
694    use elliptic_curve::sec1::Sec1Point;
695    use elliptic_curve::{FieldBytes, PublicKey, SecretKey};
696    use p521::{NistP521, ecdsa::DerSignature};
697
698    pub type EcdsaP521Digest = <NistP521 as DigestAlgorithm>::Digest;
699
700    pub type EcdsaP521PrivateKey = SecretKey<NistP521>;
701
702    pub type EcdsaP521FieldBytes = FieldBytes<NistP521>;
703    pub type EcdsaP521AffinePoint = AffinePoint<NistP521>;
704
705    pub type EcdsaP521PublicKey = PublicKey<NistP521>;
706
707    // pub type EcdsaP521PublicCoordinate = GenericArray<u8, U32>;
708    pub type EcdsaP521PublicSec1Point = Sec1Point<NistP521>;
709
710    pub type EcdsaP521SigningKey = SigningKey<NistP521>;
711    pub type EcdsaP521VerifyingKey = VerifyingKey<NistP521>;
712
713    pub type EcdsaP521Signature = Signature<NistP521>;
714    pub type EcdsaP521DerSignature = DerSignature;
715    pub type EcdsaP521SignatureBytes = SignatureBytes<NistP521>;
716
717    pub fn new_key() -> EcdsaP521PrivateKey {
718        use crypto_common::Generate;
719        EcdsaP521PrivateKey::generate()
720    }
721
722    pub fn from_coords_raw(x: &[u8], y: &[u8]) -> Option<EcdsaP521PublicKey> {
723        let mut field_x = EcdsaP521FieldBytes::default();
724        if x.len() != field_x.len() {
725            return None;
726        }
727
728        let mut field_y = EcdsaP521FieldBytes::default();
729        if y.len() != field_y.len() {
730            return None;
731        }
732
733        field_x.copy_from_slice(x);
734        field_y.copy_from_slice(y);
735
736        let ep = EcdsaP521PublicSec1Point::from_affine_coordinates(&field_x, &field_y, false);
737
738        EcdsaP521PublicKey::from_sec1_point(&ep).into_option()
739    }
740}
741
742pub mod nist_sp800_108_kdf_hmac_sha256 {
743    use crate::traits::Zeroizing;
744    use crypto_common::KeySizeUser;
745    use digest::consts::*;
746    use hmac::Hmac;
747    use kbkdf::{Counter, Kbkdf, Params};
748    use sha2::Sha256;
749
750    struct MockOutput;
751
752    impl KeySizeUser for MockOutput {
753        type KeySize = U32;
754    }
755
756    type HmacSha256 = Hmac<Sha256>;
757
758    pub fn derive_key_aes256(
759        key_in: &[u8],
760        label: &[u8],
761        context: &[u8],
762    ) -> Option<Zeroizing<Vec<u8>>> {
763        let counter = Counter::<HmacSha256, MockOutput>::default();
764        let params = Params::builder(key_in)
765            .with_label(label)
766            .with_context(context)
767            .use_l(true)
768            .use_separator(true)
769            .use_counter(true)
770            .build();
771        let key = counter.derive(params).ok()?;
772
773        let mut output = Zeroizing::new(vec![0; MockOutput::key_size()]);
774        output.copy_from_slice(key.as_slice());
775        Some(output)
776    }
777}
778
779pub mod pkcs8 {
780    pub use pkcs8::PrivateKeyInfo;
781}