Decrypt CSS images on conversion

This commit is contained in:
Rebecca Wallander
2023-07-29 23:50:37 +02:00
parent 1eb45e5cac
commit e7ede15234
7 changed files with 5409 additions and 8248 deletions

View File

@@ -181,7 +181,7 @@ partial class Dump
outputFormat.WriteSectorTag(titleKey.Value.Key, i + j, SectorTagType.DvdTitleKey);
_resume.MissingTitleKeys.Remove(i + j);
CSS.DecryptTitleKey(0, discKey, titleKey.Value.Key, out tmpBuf);
CSS.DecryptTitleKey(discKey, titleKey.Value.Key, out tmpBuf);
outputFormat.WriteSectorTag(tmpBuf, i + j, SectorTagType.DvdTitleKeyDecrypted);
}
@@ -203,7 +203,7 @@ partial class Dump
ErrorMessage?.
Invoke(string.Format(Localization.Core.Error_retrieving_title_key_for_sector_0, i));
else
buffer = CSS.DecryptSector(buffer, cmi, titleKey, blocksToRead, blockSize);
buffer = CSS.DecryptSector(buffer, titleKey, cmi, blocksToRead, blockSize);
}
}
}

View File

@@ -409,7 +409,7 @@ partial class Dump
if(discKey != null)
{
CSS.DecryptTitleKey(0, discKey, titleKey.Value.Key, out buffer);
CSS.DecryptTitleKey(discKey, titleKey.Value.Key, out buffer);
outputFormat.WriteSectorTag(buffer, missingKey, SectorTagType.DvdTitleKeyDecrypted);
}

View File

@@ -1759,9 +1759,6 @@ public sealed partial class AaruFormat
trk.EndSector == 0)
return ErrorNumber.SectorNotFound;
if(trk.Type == TrackType.Data)
return ErrorNumber.NotSupported;
switch(tag)
{
case SectorTagType.CdSectorEcc:

File diff suppressed because it is too large Load Diff

View File

@@ -959,6 +959,9 @@ In you are unsure, please press N to not continue.</value>
<data name="Generates_subchannels_help" xml:space="preserve">
<value>Generates missing subchannels.</value>
</data>
<data name="Decrypt_sectors_help" xml:space="preserve">
<value>Try to decrypt encrypted sectors.</value>
</data>
<data name="Input_image_path" xml:space="preserve">
<value>Input image path</value>
</data>
@@ -3012,4 +3015,7 @@ Do you want to continue?</value>
<data name="Dump_graph_dimensions_argument_help" xml:space="preserve">
<value>Dimensions in pixels of the square that will contain the graph of dumped media.</value>
</data>
<data name="Generating_decryption_keys" xml:space="preserve">
<value>Decryption keys not found. Trying to generate keys.</value>
</data>
</root>

View File

@@ -47,6 +47,7 @@ using Aaru.CommonTypes.Metadata;
using Aaru.Console;
using Aaru.Core;
using Aaru.Core.Media;
using Aaru.Decryption.DVD;
using Aaru.Devices;
using Aaru.Localization;
using Schemas;
@@ -54,6 +55,7 @@ using Spectre.Console;
using File = System.IO.File;
using ImageInfo = Aaru.CommonTypes.Structs.ImageInfo;
using MediaType = Aaru.CommonTypes.MediaType;
using Partition = Aaru.CommonTypes.Partition;
using TapeFile = Aaru.CommonTypes.Structs.TapeFile;
using TapePartition = Aaru.CommonTypes.Structs.TapePartition;
using Track = Aaru.CommonTypes.Structs.Track;
@@ -144,6 +146,11 @@ sealed class ConvertImageCommand : Command
"--generate-subchannels"
}, () => false, UI.Generates_subchannels_help));
Add(new Option<bool>(new[]
{
"--decrypt"
}, () => false, UI.Decrypt_sectors_help));
Add(new Option<string>(new[]
{
"--aaru-metadata", "-m"
@@ -173,7 +180,7 @@ sealed class ConvertImageCommand : Command
int mediaSequence, string mediaSerialNumber, string mediaTitle, string outputPath,
string options, string resumeFile, string format, string geometry,
bool fixSubchannelPosition, bool fixSubchannel, bool fixSubchannelCrc,
bool generateSubchannels, string aaruMetadata)
bool generateSubchannels, bool decrypt, string aaruMetadata)
{
MainClass.PrintCopyright();
@@ -239,6 +246,7 @@ sealed class ConvertImageCommand : Command
AaruConsole.DebugWriteLine("Image convert command", "--fix-subchannel={0}", fixSubchannel);
AaruConsole.DebugWriteLine("Image convert command", "--fix-subchannel-crc={0}", fixSubchannelCrc);
AaruConsole.DebugWriteLine("Image convert command", "--generate-subchannels={0}", generateSubchannels);
AaruConsole.DebugWriteLine("Image convert command", "--decrypt={0}", decrypt);
AaruConsole.DebugWriteLine("Image convert command", "--aaru-metadata={0}", aaruMetadata);
Dictionary<string, string> parsedOptions = Core.Options.Parse(options);
@@ -766,12 +774,16 @@ sealed class ConvertImageCommand : Command
ErrorNumber errno = ErrorNumber.NoError;
if(decrypt)
AaruConsole.WriteLine("Decrypting encrypted sectors.");
AnsiConsole.Progress().AutoClear(true).HideCompleted(true).
Columns(new TaskDescriptionColumn(), new ProgressBarColumn(), new PercentageColumn()).
Start(ctx =>
{
ProgressTask discTask = ctx.AddTask(UI.Converting_disc);
discTask.MaxValue = inputOptical.Tracks.Count;
byte[] generatedTitleKeys = null;
foreach(Track track in inputOptical.Tracks)
{
@@ -861,6 +873,104 @@ sealed class ConvertImageCommand : Command
: inputOptical.ReadSectors(doneSectors + track.StartSector,
sectorsToDo, out sector);
// TODO: Move to generic place when anything but CSS DVDs can be decrypted
if(inputOptical.Info.MediaType is MediaType.DVDROM or MediaType.DVDR
or MediaType.DVDRDL or MediaType.DVDPR or MediaType.DVDPRDL && decrypt)
{
// Only sectors which are MPEG packets can be encrypted.
if(MPEG.ContainsMpegPackets(sector, sectorsToDo))
{
byte[] cmi, titleKey;
if(sectorsToDo == 1)
{
if(inputOptical.ReadSectorTag(doneSectors + track.StartSector,
SectorTagType.DvdCmi, out cmi) == ErrorNumber.NoError &&
inputOptical.ReadSectorTag(doneSectors + track.StartSector,
SectorTagType.DvdTitleKeyDecrypted, out titleKey) ==
ErrorNumber.NoError)
sector = CSS.DecryptSector(sector, titleKey, cmi);
else
{
if(generatedTitleKeys == null)
{
List<Partition> partitions =
Aaru.Core.Partitions.GetAll(inputOptical);
partitions = partitions.FindAll(p =>
{
Core.Filesystems.Identify(inputOptical,
out List<string> idPlugins, p);
return idPlugins.Contains("iso9660 filesystem");
});
if(plugins.ReadOnlyFilesystems.
TryGetValue("iso9660 filesystem",
out Type pluginType))
{
AaruConsole.DebugWriteLine("Convert-image command",
UI.Generating_decryption_keys);
generatedTitleKeys = CSS.GenerateTitleKeys(inputOptical,
partitions, trackSectors, pluginType);
}
}
if(generatedTitleKeys != null)
sector = CSS.DecryptSector(sector,
generatedTitleKeys.
Skip((int)(5 * (doneSectors + track.StartSector))).
Take(5).ToArray(), null);
}
}
else
{
if(inputOptical.ReadSectorsTag(doneSectors + track.StartSector,
sectorsToDo, SectorTagType.DvdCmi, out cmi) ==
ErrorNumber.NoError &&
inputOptical.ReadSectorsTag(doneSectors + track.StartSector,
sectorsToDo, SectorTagType.DvdTitleKeyDecrypted,
out titleKey) == ErrorNumber.NoError)
sector = CSS.DecryptSector(sector, titleKey, cmi, sectorsToDo);
else
{
if(generatedTitleKeys == null)
{
List<Partition> partitions =
Aaru.Core.Partitions.GetAll(inputOptical);
partitions = partitions.FindAll(p =>
{
Core.Filesystems.Identify(inputOptical,
out List<string> idPlugins, p);
return idPlugins.Contains("iso9660 filesystem");
});
if(plugins.ReadOnlyFilesystems.
TryGetValue("iso9660 filesystem",
out Type pluginType))
{
AaruConsole.DebugWriteLine("Convert-image command",
UI.Generating_decryption_keys);
generatedTitleKeys = CSS.GenerateTitleKeys(inputOptical,
partitions, trackSectors, pluginType);
}
}
if(generatedTitleKeys != null)
sector = CSS.DecryptSector(sector,
generatedTitleKeys.
Skip((int)(5 * (doneSectors + track.StartSector))).
Take((int)(5 * sectorsToDo)).ToArray(), null,
sectorsToDo);
}
}
}
}
if(errno == ErrorNumber.NoError)
result = sectorsToDo == 1
? outputOptical.WriteSector(sector,