5151//! See [do_hazardous_operations] for documentation and sample code.
5252
5353use crate :: errors:: { KeyMaterialError , SuspendableError } ;
54- use crate :: traits:: { RNG , Secret , SecurityStrength } ;
55- use bouncycastle_utils:: { ct, min} ;
54+ use crate :: traits:: { RNG , SecurityStrength } ;
55+ use bouncycastle_utils:: { ct, min, secret :: Secret } ;
5656
5757use core:: cmp:: { Ordering , PartialOrd } ;
5858use core:: fmt;
@@ -215,15 +215,13 @@ pub trait KeyMaterialTrait: KeyMaterialInternalTrait {
215215/// The capacity of the internal buffer can be set at compile-time via the <KEY_LEN> param.
216216#[ derive( Clone ) ]
217217pub struct KeyMaterial < const KEY_LEN : usize > {
218- buf : [ u8 ; KEY_LEN ] ,
219- key_len : usize ,
218+ buf : Secret < [ u8 ; KEY_LEN ] > ,
219+ key_len : Secret < usize > ,
220220 key_type : KeyType ,
221221 security_strength : SecurityStrength ,
222222 allow_hazardous_operations : bool ,
223223}
224224
225- impl < const KEY_LEN : usize > Secret for KeyMaterial < KEY_LEN > { }
226-
227225// The explicit `#[repr(u8)]` discriminants are the stable on-the-wire encoding used by
228226// `SerializableState` implementations (see the `TryFrom<u8>` impl below). Pin each value to its
229227// variant name: reordering variants is fine, but never reuse or renumber an existing discriminant,
@@ -287,8 +285,8 @@ impl<const KEY_LEN: usize> KeyMaterial<KEY_LEN> {
287285 /// If you want a properly populated instance, use [KeyMaterial::from_rng].
288286 pub fn new ( ) -> Self {
289287 Self {
290- buf : [ 0u8 ; KEY_LEN ] ,
291- key_len : 0 ,
288+ buf : Secret :: new ( ) ,
289+ key_len : Secret :: new ( ) ,
292290 key_type : KeyType :: Zeroized ,
293291 security_strength : SecurityStrength :: None ,
294292 allow_hazardous_operations : false ,
@@ -305,7 +303,7 @@ impl<const KEY_LEN: usize> KeyMaterial<KEY_LEN> {
305303 Ok ( ( ) )
306304 } ) ?;
307305
308- key. key_len = KEY_LEN ;
306+ * key. key_len = KEY_LEN ;
309307 key. key_type = KeyType :: CryptographicRandom ;
310308 key. security_strength = rng. security_strength ( ) ;
311309 Ok ( key)
@@ -347,14 +345,11 @@ impl<const KEY_LEN: usize> KeyMaterial<KEY_LEN> {
347345 return Err ( KeyMaterialError :: InputDataLongerThanKeyCapacity ) ;
348346 }
349347
350- let mut key = Self {
351- buf : [ 0u8 ; KEY_LEN ] ,
352- key_len : other. key_len ( ) ,
353- key_type : other. key_type ( ) ,
354- security_strength : SecurityStrength :: None ,
355- allow_hazardous_operations : false ,
356- } ;
348+ let mut key = Self :: new ( ) ;
357349 key. buf [ ..other. key_len ( ) ] . copy_from_slice ( other. ref_to_bytes ( ) ) ;
350+ * key. key_len = other. key_len ( ) ;
351+ key. key_type = other. key_type ( ) ;
352+ key. security_strength = other. security_strength ( ) ;
358353 Ok ( key)
359354 }
360355}
@@ -378,7 +373,7 @@ impl<const KEY_LEN: usize> KeyMaterialTrait for KeyMaterial<KEY_LEN> {
378373 } ;
379374
380375 self . buf [ ..source. len ( ) ] . copy_from_slice ( source) ;
381- self . key_len = source. len ( ) ;
376+ * self . key_len = source. len ( ) ;
382377 self . key_type = new_key_type;
383378
384379 do_hazardous_operations ( self , |s| {
@@ -399,22 +394,22 @@ impl<const KEY_LEN: usize> KeyMaterialTrait for KeyMaterial<KEY_LEN> {
399394 }
400395
401396 fn ref_to_bytes ( & self ) -> & [ u8 ] {
402- & self . buf [ ..self . key_len ]
397+ & self . buf [ ..* self . key_len ]
403398 }
404399
405400 fn ref_to_bytes_mut ( & mut self ) -> Result < & mut [ u8 ] , KeyMaterialError > {
406401 if !self . allow_hazardous_operations {
407402 return Err ( KeyMaterialError :: HazardousOperationNotPermitted ) ;
408403 }
409- Ok ( & mut self . buf )
404+ Ok ( self . buf . as_mut ( ) )
410405 }
411406
412407 fn capacity ( & self ) -> usize {
413408 KEY_LEN
414409 }
415410
416411 fn key_len ( & self ) -> usize {
417- self . key_len
412+ * self . key_len
418413 }
419414
420415 fn set_key_len ( & mut self , key_len : usize ) -> Result < ( ) , KeyMaterialError > {
@@ -423,7 +418,7 @@ impl<const KEY_LEN: usize> KeyMaterialTrait for KeyMaterial<KEY_LEN> {
423418 }
424419
425420 // are we extending the key length, or truncating?
426- if key_len <= self . key_len {
421+ if key_len <= * self . key_len {
427422 // truncation is always allowed (not hazardous)
428423
429424 self . security_strength =
@@ -433,14 +428,14 @@ impl<const KEY_LEN: usize> KeyMaterialTrait for KeyMaterial<KEY_LEN> {
433428 self . key_type = KeyType :: Zeroized ;
434429 }
435430
436- self . key_len = key_len;
431+ * self . key_len = key_len;
437432
438433 Ok ( ( ) )
439434 } else {
440435 if !self . allow_hazardous_operations {
441436 return Err ( KeyMaterialError :: HazardousOperationNotPermitted ) ;
442437 }
443- self . key_len = key_len;
438+ * self . key_len = key_len;
444439 Ok ( ( ) )
445440 }
446441 }
@@ -557,8 +552,8 @@ impl<const KEY_LEN: usize> KeyMaterialTrait for KeyMaterial<KEY_LEN> {
557552 }
558553
559554 fn zeroize ( & mut self ) {
560- self . buf . fill ( 0u8 ) ;
561- self . key_len = 0 ;
555+ self . buf . zeroize ( ) ;
556+ self . key_len . zeroize ( ) ;
562557 self . key_type = KeyType :: Zeroized ;
563558 }
564559
@@ -579,7 +574,7 @@ impl<const KEY_LEN: usize> PartialEq for KeyMaterial<KEY_LEN> {
579574 if self . key_len != other. key_len {
580575 return false ;
581576 }
582- ct:: ct_eq_bytes ( & self . buf [ ..self . key_len ] , & other. buf [ ..self . key_len ] )
577+ ct:: ct_eq_bytes ( & self . buf [ ..* self . key_len ] , & other. buf [ ..* self . key_len ] )
583578 }
584579}
585580impl < const KEY_LEN : usize > Eq for KeyMaterial < KEY_LEN > { }
@@ -618,32 +613,27 @@ impl PartialOrd for KeyType {
618613/// Block accidental logging of the internal key material buffer.
619614impl < const KEY_LEN : usize > fmt:: Display for KeyMaterial < KEY_LEN > {
620615 fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
616+ // deref the key_len explicitly so that Secret doesn't render it as "<redacted>"
621617 write ! (
622618 f,
623- "KeyMaterial {{ len: {}, key_type: {:?}, security_strength: {:?} }}" ,
624- self . key_len, self . key_type, self . security_strength
619+ "KeyMaterial<{}> {{ len: {}, key_type: {:?}, security_strength: {:?} }}" ,
620+ KEY_LEN , * self . key_len, self . key_type, self . security_strength
625621 )
626622 }
627623}
628624
629625/// Block accidental logging of the internal key material buffer.
630626impl < const KEY_LEN : usize > fmt:: Debug for KeyMaterial < KEY_LEN > {
631627 fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
628+ // deref the key_len explicitly so that Secret doesn't render it as "<redacted>"
632629 write ! (
633630 f,
634- "KeyMaterial {{ len: {}, key_type: {:?}, security_strength: {:?} }}" ,
635- self . key_len, self . key_type, self . security_strength
631+ "KeyMaterial<{}> {{ len: {}, key_type: {:?}, security_strength: {:?} }}" ,
632+ KEY_LEN , * self . key_len, self . key_type, self . security_strength
636633 )
637634 }
638635}
639636
640- /// Zeroize the key material on drop.
641- impl < const KEY_LEN : usize > Drop for KeyMaterial < KEY_LEN > {
642- fn drop ( & mut self ) {
643- self . zeroize ( )
644- }
645- }
646-
647637/* Hazardous Operations Runner */
648638
649639/// Internal-use trait holding the low-level hazardous-operations guard toggle.
0 commit comments