@@ -536,7 +536,6 @@ verify_hashes_with_sei(signed_video_t *self, bu_list_item_t *sei)
536536 (!sei -> bu -> is_signed || (sei -> bu -> is_signed && sei -> verified_signature == 1 ));
537537 bool gop_hash_ok = verify_gop_hash (self );
538538 bool linked_hash_ok = verify_linked_hash (self , true);
539- self -> validation_flags .sei_in_sync |= linked_hash_ok ;
540539 // For complete and successful validation both the GOP hash and the linked hash have
541540 // to be correct (given that the signature could be verified successfully of course).
542541 // If the gop hash could not be verified correct, there is a second chance by
@@ -694,6 +693,7 @@ validate_authenticity(signed_video_t *self, bu_list_item_t *sei)
694693 gop_info_t * gop_info = self -> gop_info ;
695694 validation_flags_t * validation_flags = & (self -> validation_flags );
696695 signed_video_latest_validation_t * latest = self -> latest_validation ;
696+ size_t hash_size = self -> verify_data -> hash_size ;
697697
698698 SignedVideoAuthenticityResult valid = SV_AUTH_RESULT_NOT_OK ;
699699 // Initialize to "Unknown"
@@ -751,6 +751,29 @@ validate_authenticity(signed_video_t *self, bu_list_item_t *sei)
751751 valid = SV_AUTH_RESULT_OK_WITH_MISSING_INFO ;
752752 DEBUG_LOG ("Successful validation, but detected missing Bitstream Units" );
753753 }
754+
755+ // Determine if the SEIs are in sync.
756+ if (!validation_flags -> sei_in_sync ) {
757+ // If at least one BU could be validated successfully it is by definition also in
758+ // sync.
759+ validation_flags -> sei_in_sync |= has_valid_bu ;
760+ // If the computed and received link hashes are identical the SEI is in sync. There is
761+ // one exception though, and that is when the received SEI is the first of a stream.
762+ // In that case the computed linked hash AND the received one have all zeros.
763+ const uint8_t * received_linked_hash = self -> received_linked_hash ;
764+ bool is_start_of_stream = hash_is_empty (received_linked_hash , hash_size );
765+ if (!is_start_of_stream ) {
766+ // Comparing linked hashes is enough.
767+ validation_flags -> sei_in_sync |= verify_linked_hash (self , false);
768+ }
769+ // One special case is if the signature is not verified correctly, but the (partial)
770+ // GOP is correctly verified (GOP hashes match). If the SEI is not in sync it will
771+ // never get in sync and validation will never reach a verdict.
772+ if (validation_flags -> num_lost_seis == 0 ) {
773+ validation_flags -> sei_in_sync |= verify_success ;
774+ }
775+ }
776+
754777 // If we lose an entire GOP (part from the associated SEI) it will be seen as valid. Here we fix
755778 // it afterwards.
756779 // TODO: Move this inside the verify_hashes_ functions. We should not need to perform any special
@@ -793,10 +816,6 @@ validate_authenticity(signed_video_t *self, bu_list_item_t *sei)
793816 }
794817 if (latest -> public_key_has_changed ) valid = SV_AUTH_RESULT_NOT_OK ;
795818
796- if (valid == SV_AUTH_RESULT_OK ) {
797- validation_flags -> sei_in_sync = true;
798- }
799-
800819 // Update |latest_validation| with the validation result.
801820 if (latest -> authenticity <= SV_AUTH_RESULT_SIGNATURE_PRESENT ) {
802821 // Still either pending validation or video has no signature. Update with the current
@@ -815,12 +834,19 @@ validate_authenticity(signed_video_t *self, bu_list_item_t *sei)
815834 latest -> number_of_expected_picture_nalus += num_expected ;
816835 }
817836 // Update |current_partial_gop| and |num_lost_seis| w.r.t. if SEI is in sync.
818- if (validation_flags -> sei_in_sync ) {
819- gop_info -> current_partial_gop = gop_info -> next_partial_gop ;
820- validation_flags -> num_lost_seis = 0 ;
821- } else {
822- validation_flags -> num_lost_seis =
823- gop_info -> next_partial_gop - gop_info -> current_partial_gop - 1 ;
837+ // Only update if SEIs have not been reordered.
838+ if (validation_flags -> num_lost_seis >= 0 ) {
839+ if (validation_flags -> sei_in_sync && (validation_flags -> num_lost_seis < 2 )) {
840+ gop_info -> current_partial_gop = gop_info -> next_partial_gop ;
841+ validation_flags -> num_lost_seis = 0 ;
842+ } else {
843+ // Only update |num_lost_seis| if decreased. For example, if a validation was
844+ // performed with an "old" re-ordered SEI |next_partial_gop| is incorrect.
845+ int new_num_lost_seis = gop_info -> next_partial_gop - gop_info -> current_partial_gop - 1 ;
846+ if (new_num_lost_seis < validation_flags -> num_lost_seis ) {
847+ validation_flags -> num_lost_seis = new_num_lost_seis ;
848+ }
849+ }
824850 }
825851}
826852
0 commit comments