From 19ab8ce3b32ba271ba32ca4d68cd12d1e4bae2d2 Mon Sep 17 00:00:00 2001 From: Rebecca Wallander Date: Wed, 13 Jan 2021 23:37:05 +0100 Subject: [PATCH] Identify CSS, read and get disc key --- Aaru.CommonTypes | 2 +- Aaru.Core/Aaru.Core.csproj | 1 + Aaru.Core/Devices/Dumping/MMC.cs | 106 +++++++++++++++++++++++++++++++ Aaru.Devices/Enums.cs | 13 ++++ Aaru.sln | 10 +++ 5 files changed, 131 insertions(+), 1 deletion(-) diff --git a/Aaru.CommonTypes b/Aaru.CommonTypes index ec8e09f88..1e523e4a7 160000 --- a/Aaru.CommonTypes +++ b/Aaru.CommonTypes @@ -1 +1 @@ -Subproject commit ec8e09f8816938990be84237c6bd6471bb124a67 +Subproject commit 1e523e4a7a6095acbb8f21b925e7ca1f7de25c6b diff --git a/Aaru.Core/Aaru.Core.csproj b/Aaru.Core/Aaru.Core.csproj index 62af45dc6..c028c743f 100644 --- a/Aaru.Core/Aaru.Core.csproj +++ b/Aaru.Core/Aaru.Core.csproj @@ -149,6 +149,7 @@ Aaru.Console + {D7016DF2-5A5E-4524-B40D-BA2D59576688} diff --git a/Aaru.Core/Devices/Dumping/MMC.cs b/Aaru.Core/Devices/Dumping/MMC.cs index f62b9a1d1..973162196 100644 --- a/Aaru.Core/Devices/Dumping/MMC.cs +++ b/Aaru.Core/Devices/Dumping/MMC.cs @@ -39,12 +39,15 @@ using Aaru.Decoders.Bluray; using Aaru.Decoders.DVD; using Aaru.Decoders.SCSI; using Aaru.Decoders.SCSI.MMC; +using Aaru.Decryption; +using Aaru.Decryption.DVD; using Aaru.Devices; using Schemas; using DDS = Aaru.Decoders.DVD.DDS; using DMI = Aaru.Decoders.Xbox.DMI; using Inquiry = Aaru.CommonTypes.Structs.Devices.SCSI.Inquiry; using Spare = Aaru.Decoders.DVD.Spare; +using DVDDecryption = Aaru.Decryption.DVD.Dump; // ReSharper disable JoinDeclarationAndInitializer @@ -505,6 +508,109 @@ namespace Aaru.Core.Devices.Dumping tmpBuf = new byte[cmdBuf.Length - 4]; Array.Copy(cmdBuf, 4, tmpBuf, 0, cmdBuf.Length - 4); mediaTags.Add(MediaTagType.DVD_CMI, tmpBuf); + + CSS_CPRM.LeadInCopyright? cmi = CSS_CPRM.DecodeLeadInCopyright(cmdBuf); + + if(cmi!.Value.CopyrightType == CopyrightType.NoProtection) + { + UpdateStatus?.Invoke("Drive reports no copy protection on disc."); + } + else + { + if(!_decryption) + { + UpdateStatus?.Invoke("Drive reports the disc uses copy protection. " + + "The dump might be incorrect unless decryption is enabled."); + } + else + { + if(cmi!.Value.CopyrightType == CopyrightType.CSS) + { + UpdateStatus?.Invoke("Drive reports disc uses CSS copy protection."); + + var dvdDecrypt = new DVDDecryption(_dev); + + sense = dvdDecrypt.ReadBusKey(out cmdBuf, out _, + CSS_CPRM.DecodeLeadInCopyright(cmdBuf)!.Value. + CopyrightType, _dev.Timeout, out _); + + if(!sense) + { + byte[] busKey = cmdBuf; + + UpdateStatus?.Invoke("Reading disc key."); + sense = dvdDecrypt.ReadDiscKey(out cmdBuf, out _, _dev.Timeout, out _); + + if(!sense) + { + CSS_CPRM.DiscKey? decodedDiscKey = CSS.DecodeDiscKey(cmdBuf, busKey); + + sense = dvdDecrypt.ReadAsf(out cmdBuf, out _, + DvdCssKeyClass.DvdCssCppmOrCprm, _dev.Timeout, + out _); + + if(!sense) + { + if(cmdBuf[7] == 1) + { + UpdateStatus?.Invoke("Disc and drive authentication succeeded."); + + sense = dvdDecrypt.ReadRpc(out cmdBuf, out _, + DvdCssKeyClass.DvdCssCppmOrCprm, + _dev.Timeout, out _); + + if(!sense) + { + CSS_CPRM.RegionalPlaybackControlState? rpc = + CSS_CPRM.DecodeRegionalPlaybackControlState(cmdBuf); + + if(rpc.HasValue) + { + if(CSS.CheckRegion(rpc.Value, cmi.Value)) + { + UpdateStatus?.Invoke("Disc and drive regions match."); + } + else + { + UpdateStatus?. + Invoke("Disc and drive regions do not match. The dump might be incorrect"); + } + } + } + + if(decodedDiscKey.HasValue) + { + mediaTags.Add(MediaTagType.DVD_DiscKey, + decodedDiscKey.Value.Key); + + UpdateStatus?.Invoke("Decrypting disc key."); + + CSS.DecryptDiscKey(decodedDiscKey.Value.Key, + out byte[] discKey); + + if(discKey != null) + { + UpdateStatus?.Invoke("Decryption of disc key succeeded."); + mediaTags.Add(MediaTagType.DVD_DiscKey_Decrypted, discKey); + } + else + { + UpdateStatus?.Invoke("Decryption of disc key failed."); + } + } + } + } + } + } + } + else + { + UpdateStatus?. + Invoke($"Drive reports disc uses {CSS_CPRM.DecodeLeadInCopyright(cmdBuf)!.Value.CopyrightType.ToString()} copy protection. " + + "This is not yet supported and the dump might be incorrect."); + } + } + } } } #endregion DVD-ROM diff --git a/Aaru.Devices/Enums.cs b/Aaru.Devices/Enums.cs index 4dd7622f4..fa6a6e1bf 100644 --- a/Aaru.Devices/Enums.cs +++ b/Aaru.Devices/Enums.cs @@ -2885,4 +2885,17 @@ namespace Aaru.Devices { LogicalBlockAddress = 0, LogicalTrackNumber = 1, SessionNumber = 2 } + + public enum CssReportKeyFormat : byte + { + AgidForCssCppm = 0x00, ChallengeKey = 0x01, Key1 = 0x02, + TitleKey = 0x04, Asf = 0x05, RpcState = 0x08, + AgidForCprm = 0x11, InvalidateAgid = 0x3f + } + + public enum CssSendKeyFormat : byte + { + ChallengeKey = 0x01, Key2 = 0x03, RpcStructure = 0x06, + InvalidateAgid = 0x3f + } } \ No newline at end of file diff --git a/Aaru.sln b/Aaru.sln index 82fb91c74..352830551 100644 --- a/Aaru.sln +++ b/Aaru.sln @@ -44,6 +44,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Aaru.Tests.Devices", "Aaru. EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CUETools.Codecs.Flake", "cuetools.net\CUETools.Codecs.Flake\CUETools.Codecs.Flake.csproj", "{69FAC887-A3DE-4C23-84A5-9C5F64E4C3E1}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Aaru.Decryption", "Aaru.Decryption\Aaru.Decryption.csproj", "{B609D333-80C5-4503-BF46-8B9B91F04E97}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -220,6 +222,14 @@ Global {69FAC887-A3DE-4C23-84A5-9C5F64E4C3E1}.Release|Any CPU.Build.0 = Release|Any CPU {69FAC887-A3DE-4C23-84A5-9C5F64E4C3E1}.Release|x86.ActiveCfg = Release|Any CPU {69FAC887-A3DE-4C23-84A5-9C5F64E4C3E1}.Release|x86.Build.0 = Release|Any CPU + {B609D333-80C5-4503-BF46-8B9B91F04E97}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B609D333-80C5-4503-BF46-8B9B91F04E97}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B609D333-80C5-4503-BF46-8B9B91F04E97}.Debug|x86.ActiveCfg = Debug|Any CPU + {B609D333-80C5-4503-BF46-8B9B91F04E97}.Debug|x86.Build.0 = Debug|Any CPU + {B609D333-80C5-4503-BF46-8B9B91F04E97}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B609D333-80C5-4503-BF46-8B9B91F04E97}.Release|Any CPU.Build.0 = Release|Any CPU + {B609D333-80C5-4503-BF46-8B9B91F04E97}.Release|x86.ActiveCfg = Release|Any CPU + {B609D333-80C5-4503-BF46-8B9B91F04E97}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE