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 8559368
Show file tree
Hide file tree
Showing 5 changed files with 126 additions and 8 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
123 changes: 122 additions & 1 deletion Aaru/Commands/Image/Convert.cs
Original file line number Diff line number Diff line change
Expand Up @@ -44,16 +44,19 @@
using Aaru.CommonTypes.Enums;
using Aaru.CommonTypes.Interfaces;
using Aaru.CommonTypes.Metadata;
using Aaru.CommonTypes.Structs;
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 +146,11 @@ public ConvertImageCommand() : base("convert", UI.Image_Convert_Command_Descript
{
"--generate-subchannels"
}, () => false, UI.Generates_subchannels_help));

Add(new Option<bool>(new[]
{
"--decrypt"
}, () => false, "Try to decrypt encrypted sectors."));

Add(new Option<string>(new[]
{
Expand Down Expand Up @@ -173,7 +181,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 +247,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 +774,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 +874,114 @@ 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))
{
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))
{
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 8559368

Please sign in to comment.