49
49
//!
50
50
//! # Ok::<(), aws_lc_rs::error::Unspecified>(())
51
51
//! ```
52
+ mod ephemeral;
53
+
54
+ pub use ephemeral:: { agree_ephemeral, EphemeralPrivateKey } ;
55
+
52
56
use crate :: ec:: {
53
57
ec_group_from_nid, ec_point_from_bytes, evp_key_generate, evp_pkey_from_public_point,
54
58
} ;
55
59
use crate :: error:: Unspecified ;
56
60
use crate :: fips:: indicator_check;
57
61
use crate :: ptr:: LcPtr ;
58
- use crate :: rand:: SecureRandom ;
59
62
use crate :: { ec, hex} ;
60
63
use aws_lc:: {
61
64
EVP_PKEY_CTX_new , EVP_PKEY_CTX_new_id , EVP_PKEY_derive , EVP_PKEY_derive_init ,
@@ -165,10 +168,10 @@ enum KeyInner {
165
168
X25519 ( LcPtr < EVP_PKEY > ) ,
166
169
}
167
170
168
- /// An ephemeral private key for use (only) with `agree_ephemeral `. The
169
- /// signature of `agree_ephemeral` ensures that an `EphemeralPrivateKey` can be
170
- /// used for at most one key agreement.
171
- pub struct EphemeralPrivateKey {
171
+ /// A private key for use (only) with `agree `. The
172
+ /// signature of `agree` allows `PrivateKey` to be
173
+ /// used for more than one key agreement.
174
+ pub struct PrivateKey {
172
175
inner_key : KeyInner ,
173
176
}
174
177
@@ -184,31 +187,28 @@ impl KeyInner {
184
187
}
185
188
}
186
189
187
- unsafe impl Send for EphemeralPrivateKey { }
190
+ unsafe impl Send for PrivateKey { }
188
191
189
192
// https://github.com/awslabs/aws-lc/blob/main/include/openssl/ec_key.h#L88
190
193
// An |EC_KEY| object represents a public or private EC key. A given object may
191
194
// be used concurrently on multiple threads by non-mutating functions, provided
192
195
// no other thread is concurrently calling a mutating function. Unless otherwise
193
196
// documented, functions which take a |const| pointer are non-mutating and
194
197
// functions which take a non-|const| pointer are mutating.
195
- unsafe impl Sync for EphemeralPrivateKey { }
198
+ unsafe impl Sync for PrivateKey { }
196
199
197
- impl Debug for EphemeralPrivateKey {
200
+ impl Debug for PrivateKey {
198
201
fn fmt ( & self , f : & mut Formatter < ' _ > ) -> Result < ( ) , fmt:: Error > {
199
202
f. write_str ( & format ! (
200
- "EphemeralPrivateKey {{ algorithm: {:?} }}" ,
203
+ "PrivateKey {{ algorithm: {:?} }}" ,
201
204
self . inner_key. algorithm( )
202
205
) )
203
206
}
204
207
}
205
208
206
- impl EphemeralPrivateKey {
209
+ impl PrivateKey {
207
210
#[ inline]
208
- /// Generate a new ephemeral private key for the given algorithm.
209
- ///
210
- /// # *ring* Compatibility
211
- /// Our implementation ignores the `SecureRandom` parameter.
211
+ /// Generate a new private key for the given algorithm.
212
212
///
213
213
// # FIPS
214
214
// Use this function with one of the following algorithms:
@@ -218,29 +218,29 @@ impl EphemeralPrivateKey {
218
218
//
219
219
/// # Errors
220
220
/// `error::Unspecified` when operation fails due to internal error.
221
- pub fn generate ( alg : & ' static Algorithm , _rng : & dyn SecureRandom ) -> Result < Self , Unspecified > {
221
+ pub fn generate ( alg : & ' static Algorithm ) -> Result < Self , Unspecified > {
222
222
match alg. id {
223
223
AlgorithmID :: X25519 => {
224
224
let priv_key = generate_x25519 ( ) ?;
225
- Ok ( EphemeralPrivateKey {
225
+ Ok ( PrivateKey {
226
226
inner_key : KeyInner :: X25519 ( priv_key) ,
227
227
} )
228
228
}
229
229
AlgorithmID :: ECDH_P256 => {
230
230
let ec_key = evp_key_generate ( ECDH_P256 . id . nid ( ) ) ?;
231
- Ok ( EphemeralPrivateKey {
231
+ Ok ( PrivateKey {
232
232
inner_key : KeyInner :: ECDH_P256 ( ec_key) ,
233
233
} )
234
234
}
235
235
AlgorithmID :: ECDH_P384 => {
236
236
let ec_key = evp_key_generate ( ECDH_P384 . id . nid ( ) ) ?;
237
- Ok ( EphemeralPrivateKey {
237
+ Ok ( PrivateKey {
238
238
inner_key : KeyInner :: ECDH_P384 ( ec_key) ,
239
239
} )
240
240
}
241
241
AlgorithmID :: ECDH_P521 => {
242
242
let ec_key = evp_key_generate ( ECDH_P521 . id . nid ( ) ) ?;
243
- Ok ( EphemeralPrivateKey {
243
+ Ok ( PrivateKey {
244
244
inner_key : KeyInner :: ECDH_P521 ( ec_key) ,
245
245
} )
246
246
}
@@ -251,7 +251,7 @@ impl EphemeralPrivateKey {
251
251
#[ allow( clippy:: missing_errors_doc) ]
252
252
pub fn generate_for_test (
253
253
alg : & ' static Algorithm ,
254
- rng : & dyn SecureRandom ,
254
+ rng : & dyn crate :: rand :: SecureRandom ,
255
255
) -> Result < Self , Unspecified > {
256
256
match alg. id {
257
257
AlgorithmID :: X25519 => {
@@ -292,31 +292,31 @@ impl EphemeralPrivateKey {
292
292
)
293
293
} ) ?;
294
294
295
- Ok ( EphemeralPrivateKey {
295
+ Ok ( PrivateKey {
296
296
inner_key : KeyInner :: X25519 ( pkey) ,
297
297
} )
298
298
}
299
299
300
300
#[ cfg( test) ]
301
301
fn from_p256_private_key ( priv_key : & [ u8 ] ) -> Result < Self , Unspecified > {
302
302
let pkey = from_ec_private_key ( priv_key, ECDH_P256 . id . nid ( ) ) ?;
303
- Ok ( EphemeralPrivateKey {
303
+ Ok ( PrivateKey {
304
304
inner_key : KeyInner :: ECDH_P256 ( pkey) ,
305
305
} )
306
306
}
307
307
308
308
#[ cfg( test) ]
309
309
fn from_p384_private_key ( priv_key : & [ u8 ] ) -> Result < Self , Unspecified > {
310
310
let pkey = from_ec_private_key ( priv_key, ECDH_P384 . id . nid ( ) ) ?;
311
- Ok ( EphemeralPrivateKey {
311
+ Ok ( PrivateKey {
312
312
inner_key : KeyInner :: ECDH_P384 ( pkey) ,
313
313
} )
314
314
}
315
315
316
316
#[ cfg( test) ]
317
317
fn from_p521_private_key ( priv_key : & [ u8 ] ) -> Result < Self , Unspecified > {
318
318
let pkey = from_ec_private_key ( priv_key, ECDH_P521 . id . nid ( ) ) ?;
319
- Ok ( EphemeralPrivateKey {
319
+ Ok ( PrivateKey {
320
320
inner_key : KeyInner :: ECDH_P521 ( pkey) ,
321
321
} )
322
322
}
@@ -480,16 +480,14 @@ impl<B: AsRef<[u8]>> UnparsedPublicKey<B> {
480
480
}
481
481
}
482
482
483
- /// Performs a key agreement with an ephemeral private key and the given public
484
- /// key.
483
+ /// Performs a key agreement with a private key and the given public key.
485
484
///
486
- /// `my_private_key` is the ephemeral private key to use. Since it is moved, it
487
- /// will not be usable after calling `agree_ephemeral`, thus guaranteeing that
488
- /// the key is used for only one key agreement.
485
+ /// `my_private_key` is the private key to use. Only a reference to the key
486
+ /// is required, allowing the key to continue to be used.
489
487
///
490
- /// `peer_public_key` is the peer's public key. `agree_ephemeral ` will return
488
+ /// `peer_public_key` is the peer's public key. `agree ` will return
491
489
/// `Err(error_value)` if it does not match `my_private_key's` algorithm/curve.
492
- /// `agree_ephemeral ` verifies that it is encoded in the standard form for the
490
+ /// `agree ` verifies that it is encoded in the standard form for the
493
491
/// algorithm and that the key is *valid*; see the algorithm's documentation for
494
492
/// details on how keys are to be encoded and what constitutes a valid key for
495
493
/// that algorithm.
@@ -498,7 +496,7 @@ impl<B: AsRef<[u8]>> UnparsedPublicKey<B> {
498
496
/// called, e.g. when decoding of the peer's public key fails or when the public
499
497
/// key is otherwise invalid.
500
498
///
501
- /// After the key agreement is done, `agree_ephemeral ` calls `kdf` with the raw
499
+ /// After the key agreement is done, `agree ` calls `kdf` with the raw
502
500
/// key material from the key agreement operation and then returns what `kdf`
503
501
/// returns.
504
502
///
@@ -511,10 +509,9 @@ impl<B: AsRef<[u8]>> UnparsedPublicKey<B> {
511
509
/// # Errors
512
510
/// `error_value` on internal failure.
513
511
#[ inline]
514
- #[ allow( clippy:: needless_pass_by_value) ]
515
512
#[ allow( clippy:: missing_panics_doc) ]
516
- pub fn agree_ephemeral < B : AsRef < [ u8 ] > , F , R , E > (
517
- my_private_key : EphemeralPrivateKey ,
513
+ pub fn agree < B : AsRef < [ u8 ] > , F , R , E > (
514
+ my_private_key : & PrivateKey ,
518
515
peer_public_key : & UnparsedPublicKey < B > ,
519
516
error_value : E ,
520
517
kdf : F ,
@@ -703,7 +700,7 @@ mod tests {
703
700
704
701
let my_private = {
705
702
let rng = test:: rand:: FixedSliceRandom { bytes : & my_private } ;
706
- agreement:: EphemeralPrivateKey :: generate_for_test ( alg, & rng) . unwrap ( )
703
+ agreement:: PrivateKey :: generate_for_test ( alg, & rng) . unwrap ( )
707
704
} ;
708
705
709
706
let my_public = test:: from_dirty_hex (
@@ -720,11 +717,17 @@ mod tests {
720
717
721
718
assert_eq ! ( computed_public. algorithm( ) , alg) ;
722
719
723
- let result = agreement:: agree_ephemeral ( my_private, & peer_public, ( ) , |key_material| {
720
+ let result = agreement:: agree ( & my_private, & peer_public, ( ) , |key_material| {
724
721
assert_eq ! ( key_material, & output[ ..] ) ;
725
722
Ok ( ( ) )
726
723
} ) ;
727
724
assert_eq ! ( result, Ok ( ( ) ) ) ;
725
+
726
+ let result2 = agreement:: agree ( & my_private, & peer_public, ( ) , |key_material| {
727
+ assert_eq ! ( key_material, & output[ ..] ) ;
728
+ Ok ( ( ) )
729
+ } ) ;
730
+ assert_eq ! ( result2, Ok ( ( ) ) ) ;
728
731
}
729
732
730
733
#[ test]
@@ -857,13 +860,24 @@ mod tests {
857
860
858
861
let rng = rand:: SystemRandom :: new ( ) ;
859
862
let private_key =
863
+ agreement:: PrivateKey :: generate_for_test ( & agreement:: ECDH_P256 , & rng) . unwrap ( ) ;
864
+
865
+ test:: compile_time_assert_send :: < agreement:: PrivateKey > ( ) ;
866
+ test:: compile_time_assert_sync :: < agreement:: PrivateKey > ( ) ;
867
+
868
+ assert_eq ! (
869
+ format!( "{:?}" , & private_key) ,
870
+ "PrivateKey { algorithm: Algorithm { curve: P256 } }"
871
+ ) ;
872
+
873
+ let ephemeral_private_key =
860
874
agreement:: EphemeralPrivateKey :: generate_for_test ( & agreement:: ECDH_P256 , & rng) . unwrap ( ) ;
861
875
862
876
test:: compile_time_assert_send :: < agreement:: EphemeralPrivateKey > ( ) ;
863
- // test::compile_time_assert_sync::<agreement::EphemeralPrivateKey>();
877
+ test:: compile_time_assert_sync :: < agreement:: EphemeralPrivateKey > ( ) ;
864
878
865
879
assert_eq ! (
866
- format!( "{:?}" , & private_key ) ,
880
+ format!( "{:?}" , & ephemeral_private_key ) ,
867
881
"EphemeralPrivateKey { algorithm: Algorithm { curve: P256 } }"
868
882
) ;
869
883
0 commit comments