Skip to content

Commit

Permalink
Decrypt CSS images on conversion
Browse files Browse the repository at this point in the history
  • Loading branch information
FakeShemp committed Jul 30, 2023
1 parent 1eb45e5 commit e7ede15
Show file tree
Hide file tree
Showing 7 changed files with 2,088 additions and 4,927 deletions.
4 changes: 2 additions & 2 deletions Aaru.Core/Devices/Dumping/Sbc/Data.cs
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,7 @@ void ReadSbcData(in ulong blocks, in uint maxBlocksToRead, in uint blockSize, Du
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);
}

Expand All @@ -203,7 +203,7 @@ void ReadSbcData(in ulong blocks, in uint maxBlocksToRead, in uint blockSize, Du
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);
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion Aaru.Core/Devices/Dumping/Sbc/Error.cs
Original file line number Diff line number Diff line change
Expand Up @@ -409,7 +409,7 @@ void RetryTitleKeys(DVDDecryption dvdDecrypt, byte[] discKey, ref double totalDu

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);
}

Expand Down
2 changes: 1 addition & 1 deletion Aaru.Decryption
3 changes: 0 additions & 3 deletions Aaru.Images/AaruFormat/Read.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1759,9 +1759,6 @@ public ErrorNumber ReadSectorsTag(ulong sectorAddress, uint length, SectorTagTyp
trk.EndSector == 0)
return ErrorNumber.SectorNotFound;

if(trk.Type == TrackType.Data)
return ErrorNumber.NotSupported;

switch(tag)
{
case SectorTagType.CdSectorEcc:
Expand Down
6,886 changes: 1,967 additions & 4,919 deletions Aaru.Localization/UI.Designer.cs

Large diffs are not rendered by default.

6 changes: 6 additions & 0 deletions Aaru.Localization/UI.resx
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand Down Expand Up @@ -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>
112 changes: 111 additions & 1 deletion Aaru/Commands/Image/Convert.cs
Original file line number Diff line number Diff line change
Expand Up @@ -47,13 +47,15 @@
using Aaru.Console;
using Aaru.Core;
using Aaru.Core.Media;
using Aaru.Decryption.DVD;
using Aaru.Devices;
using Aaru.Localization;
using Schemas;
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;
Expand Down Expand Up @@ -143,6 +145,11 @@ public ConvertImageCommand() : base("convert", UI.Image_Convert_Command_Descript
{
"--generate-subchannels"
}, () => false, UI.Generates_subchannels_help));

Add(new Option<bool>(new[]
{
"--decrypt"
}, () => false, UI.Decrypt_sectors_help));

Add(new Option<string>(new[]
{
Expand Down Expand Up @@ -173,7 +180,7 @@ public static int Invoke(bool verbose, bool debug, string cicmXml, string commen
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();

Expand Down Expand Up @@ -239,6 +246,7 @@ public static int Invoke(bool verbose, bool debug, string cicmXml, string commen
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);
Expand Down Expand Up @@ -765,13 +773,17 @@ outputFormat is IWritableOpticalImage outputOptical &&
}

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)
{
Expand Down Expand Up @@ -861,6 +873,104 @@ outputFormat is IWritableOpticalImage outputOptical &&
: 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,
Expand Down

0 comments on commit e7ede15

Please sign in to comment.