mirror of
https://github.com/aaru-dps/Aaru.git
synced 2025-12-16 19:24:25 +00:00
Decrypt CSS images on conversion
This commit is contained in:
@@ -181,7 +181,7 @@ partial class Dump
|
|||||||
outputFormat.WriteSectorTag(titleKey.Value.Key, i + j, SectorTagType.DvdTitleKey);
|
outputFormat.WriteSectorTag(titleKey.Value.Key, i + j, SectorTagType.DvdTitleKey);
|
||||||
_resume.MissingTitleKeys.Remove(i + j);
|
_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);
|
outputFormat.WriteSectorTag(tmpBuf, i + j, SectorTagType.DvdTitleKeyDecrypted);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -203,7 +203,7 @@ partial class Dump
|
|||||||
ErrorMessage?.
|
ErrorMessage?.
|
||||||
Invoke(string.Format(Localization.Core.Error_retrieving_title_key_for_sector_0, i));
|
Invoke(string.Format(Localization.Core.Error_retrieving_title_key_for_sector_0, i));
|
||||||
else
|
else
|
||||||
buffer = CSS.DecryptSector(buffer, cmi, titleKey, blocksToRead, blockSize);
|
buffer = CSS.DecryptSector(buffer, titleKey, cmi, blocksToRead, blockSize);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -409,7 +409,7 @@ partial class Dump
|
|||||||
|
|
||||||
if(discKey != null)
|
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);
|
outputFormat.WriteSectorTag(buffer, missingKey, SectorTagType.DvdTitleKeyDecrypted);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Submodule Aaru.Decryption updated: bc4497d676...d41607f900
@@ -1759,9 +1759,6 @@ public sealed partial class AaruFormat
|
|||||||
trk.EndSector == 0)
|
trk.EndSector == 0)
|
||||||
return ErrorNumber.SectorNotFound;
|
return ErrorNumber.SectorNotFound;
|
||||||
|
|
||||||
if(trk.Type == TrackType.Data)
|
|
||||||
return ErrorNumber.NotSupported;
|
|
||||||
|
|
||||||
switch(tag)
|
switch(tag)
|
||||||
{
|
{
|
||||||
case SectorTagType.CdSectorEcc:
|
case SectorTagType.CdSectorEcc:
|
||||||
|
|||||||
13528
Aaru.Localization/UI.Designer.cs
generated
13528
Aaru.Localization/UI.Designer.cs
generated
File diff suppressed because it is too large
Load Diff
@@ -959,6 +959,9 @@ In you are unsure, please press N to not continue.</value>
|
|||||||
<data name="Generates_subchannels_help" xml:space="preserve">
|
<data name="Generates_subchannels_help" xml:space="preserve">
|
||||||
<value>Generates missing subchannels.</value>
|
<value>Generates missing subchannels.</value>
|
||||||
</data>
|
</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">
|
<data name="Input_image_path" xml:space="preserve">
|
||||||
<value>Input image path</value>
|
<value>Input image path</value>
|
||||||
</data>
|
</data>
|
||||||
@@ -3012,4 +3015,7 @@ Do you want to continue?</value>
|
|||||||
<data name="Dump_graph_dimensions_argument_help" xml:space="preserve">
|
<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>
|
<value>Dimensions in pixels of the square that will contain the graph of dumped media.</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="Generating_decryption_keys" xml:space="preserve">
|
||||||
|
<value>Decryption keys not found. Trying to generate keys.</value>
|
||||||
|
</data>
|
||||||
</root>
|
</root>
|
||||||
@@ -47,6 +47,7 @@ using Aaru.CommonTypes.Metadata;
|
|||||||
using Aaru.Console;
|
using Aaru.Console;
|
||||||
using Aaru.Core;
|
using Aaru.Core;
|
||||||
using Aaru.Core.Media;
|
using Aaru.Core.Media;
|
||||||
|
using Aaru.Decryption.DVD;
|
||||||
using Aaru.Devices;
|
using Aaru.Devices;
|
||||||
using Aaru.Localization;
|
using Aaru.Localization;
|
||||||
using Schemas;
|
using Schemas;
|
||||||
@@ -54,6 +55,7 @@ using Spectre.Console;
|
|||||||
using File = System.IO.File;
|
using File = System.IO.File;
|
||||||
using ImageInfo = Aaru.CommonTypes.Structs.ImageInfo;
|
using ImageInfo = Aaru.CommonTypes.Structs.ImageInfo;
|
||||||
using MediaType = Aaru.CommonTypes.MediaType;
|
using MediaType = Aaru.CommonTypes.MediaType;
|
||||||
|
using Partition = Aaru.CommonTypes.Partition;
|
||||||
using TapeFile = Aaru.CommonTypes.Structs.TapeFile;
|
using TapeFile = Aaru.CommonTypes.Structs.TapeFile;
|
||||||
using TapePartition = Aaru.CommonTypes.Structs.TapePartition;
|
using TapePartition = Aaru.CommonTypes.Structs.TapePartition;
|
||||||
using Track = Aaru.CommonTypes.Structs.Track;
|
using Track = Aaru.CommonTypes.Structs.Track;
|
||||||
@@ -144,6 +146,11 @@ sealed class ConvertImageCommand : Command
|
|||||||
"--generate-subchannels"
|
"--generate-subchannels"
|
||||||
}, () => false, UI.Generates_subchannels_help));
|
}, () => false, UI.Generates_subchannels_help));
|
||||||
|
|
||||||
|
Add(new Option<bool>(new[]
|
||||||
|
{
|
||||||
|
"--decrypt"
|
||||||
|
}, () => false, UI.Decrypt_sectors_help));
|
||||||
|
|
||||||
Add(new Option<string>(new[]
|
Add(new Option<string>(new[]
|
||||||
{
|
{
|
||||||
"--aaru-metadata", "-m"
|
"--aaru-metadata", "-m"
|
||||||
@@ -173,7 +180,7 @@ sealed class ConvertImageCommand : Command
|
|||||||
int mediaSequence, string mediaSerialNumber, string mediaTitle, string outputPath,
|
int mediaSequence, string mediaSerialNumber, string mediaTitle, string outputPath,
|
||||||
string options, string resumeFile, string format, string geometry,
|
string options, string resumeFile, string format, string geometry,
|
||||||
bool fixSubchannelPosition, bool fixSubchannel, bool fixSubchannelCrc,
|
bool fixSubchannelPosition, bool fixSubchannel, bool fixSubchannelCrc,
|
||||||
bool generateSubchannels, string aaruMetadata)
|
bool generateSubchannels, bool decrypt, string aaruMetadata)
|
||||||
{
|
{
|
||||||
MainClass.PrintCopyright();
|
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={0}", fixSubchannel);
|
||||||
AaruConsole.DebugWriteLine("Image convert command", "--fix-subchannel-crc={0}", fixSubchannelCrc);
|
AaruConsole.DebugWriteLine("Image convert command", "--fix-subchannel-crc={0}", fixSubchannelCrc);
|
||||||
AaruConsole.DebugWriteLine("Image convert command", "--generate-subchannels={0}", generateSubchannels);
|
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);
|
AaruConsole.DebugWriteLine("Image convert command", "--aaru-metadata={0}", aaruMetadata);
|
||||||
|
|
||||||
Dictionary<string, string> parsedOptions = Core.Options.Parse(options);
|
Dictionary<string, string> parsedOptions = Core.Options.Parse(options);
|
||||||
@@ -766,12 +774,16 @@ sealed class ConvertImageCommand : Command
|
|||||||
|
|
||||||
ErrorNumber errno = ErrorNumber.NoError;
|
ErrorNumber errno = ErrorNumber.NoError;
|
||||||
|
|
||||||
|
if(decrypt)
|
||||||
|
AaruConsole.WriteLine("Decrypting encrypted sectors.");
|
||||||
|
|
||||||
AnsiConsole.Progress().AutoClear(true).HideCompleted(true).
|
AnsiConsole.Progress().AutoClear(true).HideCompleted(true).
|
||||||
Columns(new TaskDescriptionColumn(), new ProgressBarColumn(), new PercentageColumn()).
|
Columns(new TaskDescriptionColumn(), new ProgressBarColumn(), new PercentageColumn()).
|
||||||
Start(ctx =>
|
Start(ctx =>
|
||||||
{
|
{
|
||||||
ProgressTask discTask = ctx.AddTask(UI.Converting_disc);
|
ProgressTask discTask = ctx.AddTask(UI.Converting_disc);
|
||||||
discTask.MaxValue = inputOptical.Tracks.Count;
|
discTask.MaxValue = inputOptical.Tracks.Count;
|
||||||
|
byte[] generatedTitleKeys = null;
|
||||||
|
|
||||||
foreach(Track track in inputOptical.Tracks)
|
foreach(Track track in inputOptical.Tracks)
|
||||||
{
|
{
|
||||||
@@ -861,6 +873,104 @@ sealed class ConvertImageCommand : Command
|
|||||||
: inputOptical.ReadSectors(doneSectors + track.StartSector,
|
: inputOptical.ReadSectors(doneSectors + track.StartSector,
|
||||||
sectorsToDo, out sector);
|
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)
|
if(errno == ErrorNumber.NoError)
|
||||||
result = sectorsToDo == 1
|
result = sectorsToDo == 1
|
||||||
? outputOptical.WriteSector(sector,
|
? outputOptical.WriteSector(sector,
|
||||||
|
|||||||
Reference in New Issue
Block a user