Skip to content

Commit

Permalink
fix(HLS): Decrypt AES-encrypted segments separately
Browse files Browse the repository at this point in the history
We cannot merge all the encrypted AES-128-CBC (ClearKey) segments and then decrypt them in one go because each segment should be padded to a 16-byte boundary in CBC mode.

Since it uses PKCS#5 or #7 style (cant remember which) then the merged file has a 15 in 16 chance to fail the boundary check. And in the 1 in 16 odds that it passes the boundary check, it will not decrypt properly as each segment's padding will be treated as actual data, and not padding.
  • Loading branch information
rlaphoenix committed May 17, 2024
1 parent e57d755 commit 3426fc1
Showing 1 changed file with 21 additions and 9 deletions.
30 changes: 21 additions & 9 deletions devine/core/manifests/hls.py
Original file line number Diff line number Diff line change
Expand Up @@ -387,15 +387,27 @@ def decrypt(include_this_segment: bool) -> Path:
elif len(files) != range_len:
raise ValueError(f"Missing {range_len - len(files)} segment files for {segment_range}...")

merge(
to=merged_path,
via=files,
delete=True,
include_map_data=True
)

drm.decrypt(merged_path)
merged_path.rename(decrypted_path)
if isinstance(drm, Widevine):
# with widevine we can merge all segments and decrypt once
merge(
to=merged_path,
via=files,
delete=True,
include_map_data=True
)
drm.decrypt(merged_path)
merged_path.rename(decrypted_path)
else:
# with other drm we must decrypt separately and then merge them
# for aes this is because each segment likely has 16-byte padding
for file in files:
drm.decrypt(file)
merge(
to=merged_path,
via=files,
delete=True,
include_map_data=True
)

events.emit(
events.Types.TRACK_DECRYPTED,
Expand Down

0 comments on commit 3426fc1

Please sign in to comment.