Skip to content

Commit 8f4ca78

Browse files
authored
Moves sv_update_hashable_data() into BU parser (#436)
Previously SEIs were postprocessed to update the hashable_data_size after parsing the BU. This is now done as part of the parsing. The function sv_update_hashable_data() has been removed.
1 parent 34f3f96 commit 8f4ca78

File tree

5 files changed

+21
-39
lines changed

5 files changed

+21
-39
lines changed

lib/src/sv_auth.c

Lines changed: 0 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1283,29 +1283,6 @@ maybe_validate_gop(signed_video_t *self, bu_info_t *bu)
12831283
return status;
12841284
}
12851285

1286-
/* This function updates the hashable part of the Bitstream Unit (BU) data. The default assumption
1287-
* is that all bytes from BU header to stop bit are hashed. This holds for all BU types but the
1288-
* Signed Video generated SEIs. For these, the last X bytes storing the signature are not hashed.
1289-
*
1290-
* In this function we update the bu_info_t member |hashable_data_size| w.r.t. that. The pointer
1291-
* to the start is still the same. */
1292-
void
1293-
sv_update_hashable_data(bu_info_t *bu)
1294-
{
1295-
assert(bu && (bu->is_valid > 0));
1296-
if (!bu->is_hashable || !bu->is_sv_sei) return;
1297-
1298-
// This is a Signed Video generated BU of type SEI. As payload it holds TLV data where the last
1299-
// chunk is supposed to be the signature. That part should not be hashed, hence we need to
1300-
// re-calculate hashable_data_size by subtracting the number of bytes (including potential
1301-
// emulation prevention bytes) coresponding to that tag. This is done by scanning the TLV for that
1302-
// tag.
1303-
const uint8_t *signature_tag_ptr =
1304-
sv_tlv_find_tag(bu->tlv_start_in_bu_data, bu->tlv_size, SIGNATURE_TAG, bu->with_epb);
1305-
1306-
if (signature_tag_ptr) bu->hashable_data_size = signature_tag_ptr - bu->hashable_data;
1307-
}
1308-
13091286
/* A valid BU is registered by hashing and adding to the |item|. */
13101287
static svrc_t
13111288
register_bu(signed_video_t *self, bu_list_item_t *item)
@@ -1316,7 +1293,6 @@ register_bu(signed_video_t *self, bu_list_item_t *item)
13161293
if (bu->is_valid == 0) return SV_OK;
13171294

13181295
extract_optional_info_from_sei(self, item);
1319-
sv_update_hashable_data(bu);
13201296

13211297
svrc_t status = SV_UNKNOWN_FAILURE;
13221298
SV_TRY()

lib/src/sv_common.c

Lines changed: 21 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -385,8 +385,20 @@ remove_epb_from_sei_payload(bu_info_t *bu)
385385
bu->with_epb = (bu->reserved_byte & 0x80); // Hash with emulation prevention bytes
386386
bu->is_golden_sei = (bu->reserved_byte & 0x40); // The BU is a golden SEI.
387387

388-
if (bu->emulation_prevention_bytes <= 0) return;
388+
// Check if the SEI is signed, i.e., a signature TLV tag exists. This is only possible
389+
// if TLV data size (computed from the payload size) fit within the total data size.
390+
const uint8_t *signature_ptr = NULL;
391+
if (bu->hashable_data_size > bu->tlv_size) {
392+
bool has_epb = bu->emulation_prevention_bytes > 0;
393+
signature_ptr = sv_tlv_find_tag(bu->tlv_data, bu->tlv_size, SIGNATURE_TAG, has_epb);
394+
}
395+
bu->is_signed = (signature_ptr != NULL);
396+
// If the SEI is signed the hashable part of the SEI ends at the signature tag.
397+
if (bu->is_signed) {
398+
bu->hashable_data_size = signature_ptr - bu->hashable_data;
399+
}
389400

401+
if (bu->emulation_prevention_bytes <= 0) return;
390402
// We need to read byte by byte to a new memory and remove any emulation prevention bytes.
391403
uint16_t last_two_bytes = LAST_TWO_BYTES_INIT_VALUE;
392404
// Complete data size including stop bit (byte). Note that |payload_size| excludes the final byte
@@ -407,10 +419,17 @@ remove_epb_from_sei_payload(bu_info_t *bu)
407419
// Point |tlv_data| to the first byte of the TLV part in |nalu_data_wo_epb|.
408420
bu->tlv_data = &bu->nalu_data_wo_epb[data_size - bu->payload_size + UUID_LEN];
409421
if (!bu->with_epb) {
422+
// Find the signature tag again, but now after emulation prevention has been
423+
// removed, to get the correct size of the hashable part.
424+
signature_ptr = sv_tlv_find_tag(bu->tlv_data, bu->tlv_size, SIGNATURE_TAG, false);
410425
// If the SEI was hashed before applying emulation prevention, update |hashable_data|.
411426
bu->hashable_data = bu->nalu_data_wo_epb;
412-
bu->hashable_data_size = data_size;
413427
bu->tlv_start_in_bu_data = bu->tlv_data;
428+
if (bu->is_signed) {
429+
bu->hashable_data_size = signature_ptr - bu->hashable_data;
430+
} else {
431+
bu->hashable_data_size = data_size;
432+
}
414433
}
415434
}
416435
}
@@ -560,14 +579,6 @@ parse_bu_info(const uint8_t *bu_data,
560579
}
561580

562581
remove_epb_from_sei_payload(&bu);
563-
if (bu.emulation_prevention_bytes >= 0 && (bu.hashable_data_size > bu.tlv_size)) {
564-
// Check if a signature TLV tag exists. If number of computed emulation prevention
565-
// bytes is negative, either the SEI is currupt or incomplete. Or if there is enough
566-
// TLV data.
567-
const uint8_t *signature_tag =
568-
sv_tlv_find_tag(bu.tlv_data, bu.tlv_size, SIGNATURE_TAG, false);
569-
bu.is_signed = (signature_tag != NULL);
570-
}
571582
// Update |is_hashable| w.r.t. signed or not.
572583
bu.is_hashable |= bu.is_sv_sei && !bu.is_signed;
573584
}

lib/src/sv_internal.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -397,9 +397,6 @@ parse_bu_info(const uint8_t *bu_data,
397397
void
398398
copy_bu_except_pointers(bu_info_t *dst_bu, const bu_info_t *src_bu);
399399

400-
void
401-
sv_update_hashable_data(bu_info_t *bu);
402-
403400
void
404401
sv_bytes_to_version_str(const int *arr, char *str);
405402

lib/src/sv_sign.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -445,7 +445,6 @@ complete_sei(signed_video_t *self)
445445
uint8_t test_hash[MAX_HASH_SIZE];
446446
bu_info_t test_bu_info =
447447
parse_bu_info(sei, sei_data->completed_sei_size, self->codec, false, true);
448-
sv_update_hashable_data(&test_bu_info);
449448
SV_THROW(sv_simply_hash(self, &test_bu_info, test_hash, self->sign_data->hash_size));
450449
free(test_bu_info.nalu_data_wo_epb);
451450
// Borrow hash and signature from |sign_data|.

tests/check/check_signed_video_sign.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -849,7 +849,6 @@ START_TEST(w_wo_emulation_prevention_bytes)
849849
ck_assert(seis[ii]);
850850
sei_sizes[ii] = sei_size;
851851
bu[ii] = parse_bu_info(seis[ii], sei_sizes[ii], codec, false, true);
852-
sv_update_hashable_data(&bu[ii]);
853852
signed_video_free(sv);
854853
sv = NULL;
855854
}

0 commit comments

Comments
 (0)