Skip to content

Commit c0f6002

Browse files
authored
Get next SEI only once (#438)
The next available SEI is searched for in several places. It is only necessary to do it once, when preparing for validation. This commit passes that SEI on for further validation.
1 parent 2481d7e commit c0f6002

File tree

1 file changed

+38
-38
lines changed

1 file changed

+38
-38
lines changed

lib/src/sv_auth.c

Lines changed: 38 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ static void
5151
detect_lost_sei(signed_video_t *self);
5252
static bool
5353
verify_hashes_with_hash_list(signed_video_t *self,
54+
bu_list_item_t *sei,
5455
int *num_expected,
5556
int *num_received,
5657
bool order_ok);
@@ -61,9 +62,9 @@ set_validation_status_of_pending_items_used_in_gop_hash(signed_video_t *self,
6162
static bool
6263
verify_hashes_without_sei(signed_video_t *self, int num_skips);
6364
static void
64-
validate_authenticity(signed_video_t *self);
65+
validate_authenticity(signed_video_t *self, bu_list_item_t *sei);
6566
static svrc_t
66-
prepare_for_validation(signed_video_t *self);
67+
prepare_for_validation(signed_video_t *self, bu_list_item_t **sei);
6768
static bool
6869
is_recurrent_data_decoded(signed_video_t *self);
6970
static bool
@@ -341,11 +342,12 @@ extend_partial_gop(signed_video_t *self, const bu_list_item_t *sei)
341342
* Returns false if we failed verifying hashes. Otherwise, returns true. */
342343
static bool
343344
verify_hashes_with_hash_list(signed_video_t *self,
345+
bu_list_item_t *sei,
344346
int *num_expected,
345347
int *num_received,
346348
bool order_ok)
347349
{
348-
assert(self);
350+
assert(self && sei);
349351

350352
const size_t hash_size = self->verify_data->hash_size;
351353
assert(hash_size > 0);
@@ -361,12 +363,6 @@ verify_hashes_with_hash_list(signed_video_t *self,
361363

362364
bu_list_print(bu_list);
363365

364-
// Get the SEI associated with the oldest pending GOP.
365-
bu_list_item_t *sei = bu_list_get_next_sei_item(bu_list);
366-
// TODO: Investigate if we can end up without finding a SEI. If so, should we fail the validation
367-
// or call verify_hashes_without_sei()?
368-
if (!sei) return false;
369-
370366
// First of all we need to know if the SEI itself is authentic, that is, the SEI |document_hash|
371367
// has successfully been verified (= 1). If the document could not be verified sucessfully, that
372368
// is, the SEI is invalid, all BUs become invalid. Hence, verify_hashes_without_sei().
@@ -564,14 +560,16 @@ set_validation_status_of_pending_items_used_in_gop_hash(signed_video_t *self,
564560
* to reflect the total number of expected and received BUs.
565561
*/
566562
static bool
567-
verify_hashes_with_sei(signed_video_t *self, int *num_expected, int *num_received)
563+
verify_hashes_with_sei(signed_video_t *self,
564+
bu_list_item_t *sei,
565+
int *num_expected,
566+
int *num_received)
568567
{
569568
assert(self);
570569

571570
int num_expected_hashes = -1;
572571
int num_received_hashes = -1;
573572
char validation_status = 'P';
574-
bu_list_item_t *sei = bu_list_get_next_sei_item(self->bu_list);
575573

576574
bool gop_is_ok = verify_gop_hash(self);
577575
bool order_ok = verify_linked_hash(self);
@@ -588,7 +586,7 @@ verify_hashes_with_sei(signed_video_t *self, int *num_expected, int *num_receive
588586
if (validation_status != '.' && self->gop_info->list_idx > 0) {
589587
// Extend partial GOP with more items, since the failure can be due to added BUs.
590588
extend_partial_gop(self, sei);
591-
return verify_hashes_with_hash_list(self, num_expected, num_received, order_ok);
589+
return verify_hashes_with_hash_list(self, sei, num_expected, num_received, order_ok);
592590
}
593591
} else if (self->gop_info->verified_signature_hash == 0) {
594592
validation_status = 'N';
@@ -747,7 +745,7 @@ verify_hashes_without_sei(signed_video_t *self, int num_skips)
747745
* - Update |latest_validation| with the validation result.
748746
*/
749747
static void
750-
validate_authenticity(signed_video_t *self)
748+
validate_authenticity(signed_video_t *self, bu_list_item_t *sei)
751749
{
752750
assert(self);
753751

@@ -768,7 +766,7 @@ validate_authenticity(signed_video_t *self)
768766
// verify this GOP. Marking this GOP as not OK by verify_hashes_without_sei().
769767
verify_success = verify_hashes_without_sei(self, self->gop_info->num_sent);
770768
} else {
771-
verify_success = verify_hashes_with_sei(self, &num_expected, &num_received);
769+
verify_success = verify_hashes_with_sei(self, sei, &num_expected, &num_received);
772770
// Set |latest_validated_gop| to recived gop counter for the next validation.
773771
self->gop_info->latest_validated_gop = self->gop_info->current_partial_gop;
774772
}
@@ -921,7 +919,7 @@ prepare_golden_sei(signed_video_t *self, bu_list_item_t *sei)
921919
SV_THROW(hash_and_add_for_auth(self, sei));
922920
memcpy(verify_data->hash, sei->hash, verify_data->hash_size);
923921

924-
SV_THROW(prepare_for_validation(self));
922+
SV_THROW(prepare_for_validation(self, &sei));
925923
SV_CATCH()
926924
SV_DONE(status)
927925

@@ -938,7 +936,7 @@ prepare_golden_sei(signed_video_t *self, bu_list_item_t *sei)
938936
* 5) verify the associated hash using the signature.
939937
*/
940938
static svrc_t
941-
prepare_for_validation(signed_video_t *self)
939+
prepare_for_validation(signed_video_t *self, bu_list_item_t **sei)
942940
{
943941
assert(self);
944942

@@ -947,23 +945,26 @@ prepare_for_validation(signed_video_t *self)
947945
sign_or_verify_data_t *verify_data = self->verify_data;
948946
const size_t hash_size = verify_data->hash_size;
949947

948+
*sei = bu_list_get_next_sei_item(bu_list);
949+
if (!(*sei)) {
950+
// No reason to proceed with preparations if no pending SEI is found.
951+
return SV_OK;
952+
}
953+
950954
svrc_t status = SV_UNKNOWN_FAILURE;
951955
SV_TRY()
952-
bu_list_item_t *sei = bu_list_get_next_sei_item(bu_list);
953-
if (sei) {
954-
sei->in_validation = true;
955-
if (!sei->has_been_decoded) {
956-
// Decode the SEI and set signature->hash
957-
self->latest_validation->public_key_has_changed = false;
958-
const uint8_t *tlv_data = sei->bu->tlv_data;
959-
size_t tlv_size = sei->bu->tlv_size;
960-
SV_THROW(decode_sei_data(self, tlv_data, tlv_size));
961-
sei->has_been_decoded = true;
962-
memcpy(verify_data->hash, sei->hash, hash_size);
963-
}
964-
detect_lost_sei(self);
965-
SV_THROW(prepare_for_link_and_gop_hash_verification(self, sei));
956+
(*sei)->in_validation = true;
957+
if (!(*sei)->has_been_decoded) {
958+
// Decode the SEI and set signature->hash
959+
self->latest_validation->public_key_has_changed = false;
960+
const uint8_t *tlv_data = (*sei)->bu->tlv_data;
961+
size_t tlv_size = (*sei)->bu->tlv_size;
962+
SV_THROW(decode_sei_data(self, tlv_data, tlv_size));
963+
(*sei)->has_been_decoded = true;
964+
memcpy(verify_data->hash, (*sei)->hash, hash_size);
966965
}
966+
detect_lost_sei(self);
967+
SV_THROW(prepare_for_link_and_gop_hash_verification(self, *sei));
967968

968969
SV_THROW_IF_WITH_MSG(validation_flags->signing_present && !self->has_public_key,
969970
SV_NOT_SUPPORTED, "No public key present");
@@ -997,12 +998,10 @@ prepare_for_validation(signed_video_t *self)
997998
#endif
998999

9991000
// For SEIs, transfer the result of the signature verification.
1000-
if (sei) {
1001-
if (sei->bu->is_signed) {
1002-
self->gop_info->verified_signature_hash = sei->verified_signature;
1003-
} else {
1004-
self->gop_info->verified_signature_hash = 1;
1005-
}
1001+
if ((*sei)->bu->is_signed) {
1002+
self->gop_info->verified_signature_hash = (*sei)->verified_signature;
1003+
} else {
1004+
self->gop_info->verified_signature_hash = 1;
10061005
}
10071006

10081007
SV_CATCH()
@@ -1216,6 +1215,7 @@ maybe_validate_gop(signed_video_t *self, bu_info_t *bu)
12161215
// Keep validating as long as there are pending GOPs.
12171216
bool stop_validating = false;
12181217
while (has_pending_partial_gop(self) && !stop_validating) {
1218+
bu_list_item_t *sei = NULL;
12191219
// Initialize latest validation.
12201220
if (!self->validation_flags.has_auth_result || validation_flags->is_first_validation) {
12211221
latest->authenticity = SV_AUTH_RESULT_SIGNATURE_PRESENT;
@@ -1227,7 +1227,7 @@ maybe_validate_gop(signed_video_t *self, bu_info_t *bu)
12271227
update_sei_in_validation(self, true, NULL, NULL);
12281228
}
12291229

1230-
SV_THROW(prepare_for_validation(self));
1230+
SV_THROW(prepare_for_validation(self, &sei));
12311231
update_link_hash_for_auth(self);
12321232

12331233
if (!validation_flags->signing_present) {
@@ -1236,7 +1236,7 @@ maybe_validate_gop(signed_video_t *self, bu_info_t *bu)
12361236
// to avoid a dead lock.
12371237
stop_validating = true;
12381238
} else {
1239-
validate_authenticity(self);
1239+
validate_authenticity(self, sei);
12401240
}
12411241

12421242
if (validation_flags->is_first_validation && (latest->authenticity != SV_AUTH_RESULT_OK)) {

0 commit comments

Comments
 (0)