@@ -417,6 +417,7 @@ fn test_rekey() {
417417 h_i. rekey_outgoing ( ) ;
418418 let len = h_i. write_message ( b"hack the planet" , & mut buffer_msg) . unwrap ( ) ;
419419 assert ! ( h_r. read_message( & buffer_msg[ ..len] , & mut buffer_out) . is_err( ) ) ;
420+ h_r. set_receiving_nonce ( h_i. sending_nonce ( ) ) ;
420421
421422 // rekey incoming on responder
422423 h_r. rekey_incoming ( ) ;
@@ -428,6 +429,7 @@ fn test_rekey() {
428429 h_r. rekey_outgoing ( ) ;
429430 let len = h_r. write_message ( b"hack the planet" , & mut buffer_msg) . unwrap ( ) ;
430431 assert ! ( h_i. read_message( & buffer_msg[ ..len] , & mut buffer_out) . is_err( ) ) ;
432+ h_i. set_receiving_nonce ( h_r. sending_nonce ( ) ) ;
431433
432434 // rekey incoming on initiator
433435 h_i. rekey_incoming ( ) ;
@@ -444,37 +446,45 @@ fn test_rekey_manually() {
444446
445447 let mut buffer_msg = [ 0u8 ; 200 ] ;
446448 let mut buffer_out = [ 0u8 ; 200 ] ;
449+
450+ // Do a handshake, and transition to stateful transport mode.
447451 let len = h_i. write_message ( b"abc" , & mut buffer_msg) . unwrap ( ) ;
448452 h_r. read_message ( & buffer_msg[ ..len] , & mut buffer_out) . unwrap ( ) ;
449-
450453 let len = h_r. write_message ( b"defg" , & mut buffer_msg) . unwrap ( ) ;
451454 h_i. read_message ( & buffer_msg[ ..len] , & mut buffer_out) . unwrap ( ) ;
452-
453455 let mut h_i = h_i. into_transport_mode ( ) . unwrap ( ) ;
454456 let mut h_r = h_r. into_transport_mode ( ) . unwrap ( ) ;
455457
456- // test message initiator->responder before rekeying initiator
458+ // test sanity message initiator->responder before rekeying initiator
457459 let len = h_i. write_message ( b"hack the planet" , & mut buffer_msg) . unwrap ( ) ;
458460 let len = h_r. read_message ( & buffer_msg[ ..len] , & mut buffer_out) . unwrap ( ) ;
459461 assert_eq ! ( & buffer_out[ ..len] , b"hack the planet" ) ;
460462
461- // rekey initiator (on initiator)
463+ // rekey initiator-side initiator key to K1 without rekeying the responder,
464+ // expecting a decryption failure.
465+ //
466+ // The message *should* have failed to read, so we also force nonce re-sync.
462467 h_i. rekey_manually ( Some ( & [ 1u8 ; 32 ] ) , None ) ;
463468 let len = h_i. write_message ( b"hack the planet" , & mut buffer_msg) . unwrap ( ) ;
464469 assert ! ( h_r. read_message( & buffer_msg[ ..len] , & mut buffer_out) . is_err( ) ) ;
470+ h_r. set_receiving_nonce ( h_i. sending_nonce ( ) ) ;
465471
466- // rekey initiator (on responder)
472+ // rekey responder-side responder key to K1, expecting a successful decryption.
467473 h_r. rekey_manually ( Some ( & [ 1u8 ; 32 ] ) , None ) ;
468474 let len = h_i. write_message ( b"hack the planet" , & mut buffer_msg) . unwrap ( ) ;
469475 let len = h_r. read_message ( & buffer_msg[ ..len] , & mut buffer_out) . unwrap ( ) ;
470476 assert_eq ! ( & buffer_out[ ..len] , b"hack the planet" ) ;
471477
472- // rekey responder (on responder)
478+ // rekey responder-side responder key to K1 without rekeying the initiator,
479+ // expecting a decryption failure.
480+ //
481+ // The message *should* have failed to read, so we also force nonce re-sync.
473482 h_r. rekey_manually ( None , Some ( & [ 1u8 ; 32 ] ) ) ;
474483 let len = h_r. write_message ( b"hack the planet" , & mut buffer_msg) . unwrap ( ) ;
475484 assert ! ( h_i. read_message( & buffer_msg[ ..len] , & mut buffer_out) . is_err( ) ) ;
485+ h_i. set_receiving_nonce ( h_r. sending_nonce ( ) ) ;
476486
477- // rekey responder (on initiator)
487+ // rekey intiator-side responder key to K1, expecting a successful decryption.
478488 h_i. rekey_manually ( None , Some ( & [ 1u8 ; 32 ] ) ) ;
479489 let len = h_r. write_message ( b"hack the planet" , & mut buffer_msg) . unwrap ( ) ;
480490 let len = h_i. read_message ( & buffer_msg[ ..len] , & mut buffer_out) . unwrap ( ) ;
@@ -870,3 +880,36 @@ fn test_stateless_nonce_maximum_behavior() {
870880 Err ( snow:: Error :: State ( snow:: error:: StateProblem :: Exhausted ) )
871881 ) ) ;
872882}
883+
884+ #[ test]
885+ fn test_stateful_nonce_increment_behavior ( ) {
886+ let params: NoiseParams = "Noise_NN_25519_ChaChaPoly_SHA256" . parse ( ) . unwrap ( ) ;
887+ let mut h_i = Builder :: new ( params. clone ( ) ) . build_initiator ( ) . unwrap ( ) ;
888+ let mut h_r = Builder :: new ( params) . build_responder ( ) . unwrap ( ) ;
889+
890+ let mut buffer_msg = [ 0u8 ; 200 ] ;
891+ let mut buffer_out = [ 0u8 ; 200 ] ;
892+ let len = h_i. write_message ( b"abc" , & mut buffer_msg) . unwrap ( ) ;
893+ h_r. read_message ( & buffer_msg[ ..len] , & mut buffer_out) . unwrap ( ) ;
894+
895+ let len = h_r. write_message ( b"defg" , & mut buffer_msg) . unwrap ( ) ;
896+ h_i. read_message ( & buffer_msg[ ..len] , & mut buffer_out) . unwrap ( ) ;
897+
898+ let mut h_i = h_i. into_transport_mode ( ) . unwrap ( ) ;
899+ let mut h_r = h_r. into_transport_mode ( ) . unwrap ( ) ;
900+
901+ let len = h_i. write_message ( b"xyz" , & mut buffer_msg) . unwrap ( ) ;
902+
903+ // Corrupt the message by incrementing a byte in the payload
904+ let mut corrupted = buffer_msg[ ..len] . to_owned ( ) ;
905+ corrupted[ 0 ] = corrupted[ 0 ] . wrapping_add ( 1 ) ;
906+
907+ // This should result in an error, but should not change any internal state
908+ assert ! ( h_r. read_message( & corrupted, & mut buffer_out) . is_err( ) ) ;
909+
910+ // This should now succeed as the nonce counter should have remained the same
911+ h_r. read_message ( & buffer_msg[ ..len] , & mut buffer_out) . unwrap ( ) ;
912+
913+ // This should now fail again as the nonce counter should have incremented
914+ assert ! ( h_r. read_message( & buffer_msg[ ..len] , & mut buffer_out) . is_err( ) ) ;
915+ }
0 commit comments