From f0b497cf78b5783ee4870b1323db2be497549be3 Mon Sep 17 00:00:00 2001 From: Rebecca Wallander Date: Thu, 14 Jan 2021 00:03:37 +0100 Subject: [PATCH] Add dumping of title keys --- Aaru.Core/Devices/Dumping/MMC.cs | 17 ++--- Aaru.Core/Devices/Dumping/Sbc/Data.cs | 93 ++++++++++++++++++++++++++- Aaru.Core/Devices/Dumping/Sbc/Dump.cs | 7 +- 3 files changed, 106 insertions(+), 11 deletions(-) diff --git a/Aaru.Core/Devices/Dumping/MMC.cs b/Aaru.Core/Devices/Dumping/MMC.cs index 973162196..ef66a02bd 100644 --- a/Aaru.Core/Devices/Dumping/MMC.cs +++ b/Aaru.Core/Devices/Dumping/MMC.cs @@ -59,12 +59,13 @@ namespace Aaru.Core.Devices.Dumping /// Dumps an optical disc void Mmc() { - MediaType dskType = MediaType.Unknown; - bool sense; - byte[] tmpBuf; - bool compactDisc = true; - bool gotConfiguration = false; - bool isXbox = false; + MediaType dskType = MediaType.Unknown; + bool sense; + byte[] tmpBuf; + bool compactDisc = true; + bool gotConfiguration = false; + bool isXbox = false; + DVDDecryption dvdDecrypt = null; _speedMultiplier = 1; // TODO: Log not only what is it reading, but if it was read correctly or not. @@ -528,7 +529,7 @@ namespace Aaru.Core.Devices.Dumping { UpdateStatus?.Invoke("Drive reports disc uses CSS copy protection."); - var dvdDecrypt = new DVDDecryption(_dev); + dvdDecrypt = new DVDDecryption(_dev); sense = dvdDecrypt.ReadBusKey(out cmdBuf, out _, CSS_CPRM.DecodeLeadInCopyright(cmdBuf)!.Value. @@ -866,7 +867,7 @@ namespace Aaru.Core.Devices.Dumping return; } - Sbc(mediaTags, dskType, true); + Sbc(mediaTags, dskType, true, dvdDecrypt); } static void AddMediaTagToSidecar(string outputPath, KeyValuePair tag, diff --git a/Aaru.Core/Devices/Dumping/Sbc/Data.cs b/Aaru.Core/Devices/Dumping/Sbc/Data.cs index b938010c0..9d6493935 100644 --- a/Aaru.Core/Devices/Dumping/Sbc/Data.cs +++ b/Aaru.Core/Devices/Dumping/Sbc/Data.cs @@ -26,9 +26,14 @@ using System; using System.Linq; +using Aaru.CommonTypes.Enums; using Aaru.CommonTypes.Extents; using Aaru.Core.Logging; +using Aaru.Decoders.DVD; +using Aaru.Decryption; +using Aaru.Decryption.DVD; using Schemas; +using DVDDecryption = Aaru.Decryption.DVD.Dump; // ReSharper disable JoinDeclarationAndInitializer // ReSharper disable InlineOutVariableDeclaration @@ -53,10 +58,12 @@ namespace Aaru.Core.Devices.Dumping /// ImgBurn log /// Total time spent writing to image /// Set if we need to start a trim + /// DVD CSS decryption module + /// The DVD disc key void ReadSbcData(in ulong blocks, in uint maxBlocksToRead, in uint blockSize, DumpHardwareType currentTry, ExtentsULong extents, ref double currentSpeed, ref double minSpeed, ref double maxSpeed, ref double totalDuration, Reader scsiReader, MhddLog mhddLog, IbgLog ibgLog, - ref double imageWriteDuration, ref bool newTrim) + ref double imageWriteDuration, ref bool newTrim, DVDDecryption dvdDecrypt, byte[] discKey) { ulong sectorSpeedStart = 0; bool sense; @@ -97,6 +104,90 @@ namespace Aaru.Core.Devices.Dumping if(!sense && !_dev.Error) { + if(_decryption) + { + if(_titleKeys && discKey != null) + { + for(ulong j = 0; j < blocksToRead; j++) + { + if(_aborted) + { + break; + } + + if(!_resume.MissingTitleKeys.Contains(i + j)) + { + // Key is already dumped. + continue; + } + + byte[] tmpBuf; + + bool tmpSense = dvdDecrypt.ReadTitleKey(out tmpBuf, out _, + DvdCssKeyClass.DvdCssCppmOrCprm, i + j, + _dev.Timeout, out _); + + if(!tmpSense) + { + CSS_CPRM.TitleKey? titleKey = CSS.DecodeTitleKey(tmpBuf, dvdDecrypt.BusKey); + + if(titleKey.HasValue) + { + _outputPlugin.WriteSectorTag(new[] + { + titleKey.Value.CMI + }, i + j, SectorTagType.DvdCmi); + } + else + continue; + + if((titleKey.Value.CMI & 0x80) >> 7 == 0) + { + // The CMI indicates this sector is not encrypted. + _outputPlugin.WriteSectorTag(new byte[] + { + 0, 0, 0, 0, 0 + }, i + j, SectorTagType.DvdTitleKey); + + _outputPlugin.WriteSectorTag(new byte[] + { + 0, 0, 0, 0, 0 + }, i + j, SectorTagType.DvdTitleKeyDecrypted); + + _resume.MissingTitleKeys.Remove(i + j); + + continue; + } + + if(titleKey.Value.Key.All(k => k == 0)) + { + // According to libdvdcss, if the key is all zeroes, the sector is actually + // not encrypted even if the CMI says it is. + _outputPlugin.WriteSectorTag(new byte[] + { + 0, 0, 0, 0, 0 + }, i + j, SectorTagType.DvdTitleKey); + + _outputPlugin.WriteSectorTag(new byte[] + { + 0, 0, 0, 0, 0 + }, i + j, SectorTagType.DvdTitleKeyDecrypted); + + _resume.MissingTitleKeys.Remove(i + j); + + continue; + } + + _outputPlugin.WriteSectorTag(titleKey.Value.Key, i + j, SectorTagType.DvdTitleKey); + _resume.MissingTitleKeys.Remove(i + j); + + CSS.DecryptTitleKey(0, discKey, titleKey.Value.Key, out tmpBuf); + _outputPlugin.WriteSectorTag(tmpBuf, i + j, SectorTagType.DvdTitleKeyDecrypted); + } + } + } + } + mhddLog.Write(i, cmdDuration); ibgLog.Write(i, currentSpeed * 1024); DateTime writeStart = DateTime.Now; diff --git a/Aaru.Core/Devices/Dumping/Sbc/Dump.cs b/Aaru.Core/Devices/Dumping/Sbc/Dump.cs index 0f99a3699..008249e57 100644 --- a/Aaru.Core/Devices/Dumping/Sbc/Dump.cs +++ b/Aaru.Core/Devices/Dumping/Sbc/Dump.cs @@ -53,6 +53,7 @@ using DeviceReport = Aaru.Core.Devices.Report.DeviceReport; using MediaType = Aaru.CommonTypes.MediaType; using TrackType = Aaru.CommonTypes.Enums.TrackType; using Version = Aaru.CommonTypes.Interop.Version; +using DVDDecryption = Aaru.Decryption.DVD.Dump; // ReSharper disable JoinDeclarationAndInitializer @@ -65,7 +66,9 @@ namespace Aaru.Core.Devices.Dumping /// If device contains an optical disc (e.g. DVD or BD) /// Media tags as retrieved in MMC layer /// Disc type as detected in SCSI or MMC layer - void Sbc(Dictionary mediaTags, MediaType dskType, bool opticalDisc) + /// DVD CSS decryption module + void Sbc(Dictionary mediaTags, MediaType dskType, bool opticalDisc, + DVDDecryption dvdDecrypt = null) { bool sense; byte scsiMediumType = 0; @@ -671,7 +674,7 @@ namespace Aaru.Core.Devices.Dumping else ReadSbcData(blocks, blocksToRead, blockSize, currentTry, extents, ref currentSpeed, ref minSpeed, ref maxSpeed, ref totalDuration, scsiReader, mhddLog, ibgLog, ref imageWriteDuration, - ref newTrim); + ref newTrim, dvdDecrypt, mediaTags[MediaTagType.DVD_DiscKey_Decrypted]); end = DateTime.UtcNow; mhddLog.Close();