public static byte[] ScrambledParcel(this SKR1Parcel parcel, byte[] iv, byte[] key) { ArgumentThrow.IfNull(parcel, $"Invalid {typeof(SKR1Parcel).Name} to scramble. Parcel can not be null.", nameof(parcel)); ArgumentThrow.IfLengthNot(iv, 16, "Invalid iv to scramble. IV buffer should be 16 bytes.", nameof(iv)); ArgumentThrow.IfLengthNot(key, 16, "Invalid key to scramble. Key buffer should be 16 bytes.", nameof(key)); using (var aes = Aes.Create()) { aes.IV = iv; aes.Key = key; aes.Mode = CipherMode.CBC; aes.Padding = PaddingMode.None; using (var encryptor = aes.CreateEncryptor()) using (var memoryStream = new MemoryStream()) using (var cryptoStream = new CryptoStream(memoryStream, encryptor, CryptoStreamMode.Write)) { cryptoStream.Write(parcel.Binary); return(memoryStream.ToArray()); } } }
private async Task <IEnumerable <TLLVSlab> > GenerateCKC(DFunction derivator, IEnumerable <TLLVSlab> spcSlabs, object info) { var ckcSlabs = new List <TLLVSlab>(); byte[] DASk = null; try { DASk = derivator.DeriveBytes(spcSlabs.First(p => p.Tag.Same(TLLVTag.Id.R2)).Payload <R2Payload>().R2); } catch (FPException) { throw; } catch (Exception ex) { throw new FPInvalidContextException("EXC_0014", "Unable to process SPC. See 'innerException' for more information.", ex); } SKR1Payload SessionRandom1Payload = null; try { SessionRandom1Payload = spcSlabs.First(p => p.Tag.Same(TLLVTag.Id.SKR1)).Payload <SKR1Payload>(); } catch (FPException) { throw; } catch (Exception ex) { throw new FPInvalidContextException("EXC_0015", "Unable to process SPC. See 'innerException' for more information.", ex); } SKR1IntegrityPayload SessionRandom1IntegrityPayload = null; try { SessionRandom1IntegrityPayload = spcSlabs.First(p => p.Tag.Same(TLLVTag.Id.SKR1Integrity)).Payload <SKR1IntegrityPayload>(); } catch (FPException) { throw; } catch (Exception ex) { throw new FPInvalidContextException("EXC_0016", "Unable to process SPC. See 'innerException' for more information.", ex); } SKR1Parcel SessionRandom1Parcel = null; try { SessionRandom1Parcel = new SKR1Parcel(new ReadOnlyMemory <byte>(SessionRandom1Payload.UnscrambledParcel(DASk))); } catch (FPException) { throw; } catch (Exception ex) { throw new FPInvalidContextException("EXC_0017", "Unable to process SPC. See 'innerException' for more information.", ex); } if (Enumerable.SequenceEqual(SessionRandom1Parcel.Integrity, SessionRandom1IntegrityPayload.Integrity) == false) { throw new FPContextIntegrityViolatedException("EXC_0034", "Unable to process SPC. SPC integrity violated."); } TRRPayload TagReturnRequestPayload = null; try { TagReturnRequestPayload = spcSlabs.First(p => p.Tag.Same(TLLVTag.Id.TRR)).Payload <TRRPayload>(); } catch (FPException) { throw; } catch (Exception ex) { throw new FPInvalidContextException("EXC_0018", "Unable to process SPC. See 'innerException' for more information.", ex); } ckcSlabs.AddRange(spcSlabs.Where(slab => TagReturnRequestPayload.TRR.Select(tag => tag.Code).Contains(slab.Tag.Code))); AssetPayload AssetIdentifierPayload = null; try { AssetIdentifierPayload = spcSlabs.First(p => p.Tag.Same(TLLVTag.Id.Asset)).Payload <AssetPayload>(); } catch (FPException) { throw; } catch (Exception ex) { throw new FPInvalidContextException("EXC_0019", "Unable to process SPC. See 'innerException' for more information.", ex); } IContentKey ContentKey = null; try { ContentKey = await this.Locator.FetchContentKey(AssetIdentifierPayload.Identifier, info); } catch (FPException) { throw; } catch (Exception ex) { throw new FPKeyLocatorException("EXC_0020", "Unable to fetch content key from key locator. See 'innerException' for more information.", ex); } if (ContentKey.IV == null || ContentKey.IV.Length != 16) { throw new FPInvalidKeyException("EXC_0035", "Invalid IV fetched from key locator. IV can not be null and should be 16 bytes length."); } if (ContentKey.Key == null || ContentKey.Key.Length != 16) { throw new FPInvalidKeyException("EXC_0036", "Invalid key fetched from key locator. Key can not be null and should be 16 bytes length."); } EncryptedCKParcel EncryptedContentKeyParcel = null; try { EncryptedContentKeyParcel = new EncryptedCKParcel(ContentKey.Key); } catch (FPException) { throw; } catch (Exception ex) { throw new FPInvalidContextException("EXC_0021", "Unable to process SPC. See 'innerException' for more information.", ex); } EncryptedCKPayload EncryptedContentKeyPayload = null; try { EncryptedContentKeyPayload = new EncryptedCKPayload(ContentKey.IV, EncryptedContentKeyParcel.ScrambledParcel(SessionRandom1Parcel.SK)); } catch (FPException) { throw; } catch (Exception ex) { throw new FPInvalidContextException("EXC_0022", "Unable to process SPC. See 'innerException' for more information.", ex); } TLLVSlab EncryptedContentKeySlab = null; try { EncryptedContentKeySlab = new TLLVSlab(TLLVTag.Id.EncryptedCK, EncryptedContentKeyPayload.Binary); } catch (FPException) { throw; } catch (Exception ex) { throw new FPInvalidContextException("EXC_0023", "Unable to process SPC. See 'innerException' for more information.", ex); } ckcSlabs.Add(EncryptedContentKeySlab); R1Payload Random1Payload = null; try { Random1Payload = new R1Payload(SessionRandom1Parcel.R1); } catch (FPException) { throw; } catch (Exception ex) { throw new FPInvalidContextException("EXC_0024", "Unable to process SPC. See 'innerException' for more information.", ex); } TLLVSlab Random1Slab = null; try { Random1Slab = new TLLVSlab(TLLVTag.Id.R1, Random1Payload.Binary); } catch (FPException) { throw; } catch (Exception ex) { throw new FPInvalidContextException("EXC_0025", "Unable to process SPC. See 'innerException' for more information.", ex); } ckcSlabs.Add(Random1Slab); TLLVSlab MediaPlaybackSlab = null; try { MediaPlaybackSlab = spcSlabs.FirstOrDefault(p => p.Tag.Same(TLLVTag.Id.MediaPlayback)); } catch (FPException) { throw; } catch (Exception ex) { throw new FPInvalidContextException("EXC_0026", "Unable to process SPC. See 'innerException' for more information.", ex); } if (MediaPlaybackSlab != null) { MediaPlaybackPayload MediaPlaybackPayload = null; try { MediaPlaybackPayload = MediaPlaybackSlab.Payload <MediaPlaybackPayload>(); } catch (FPException) { throw; } catch (Exception ex) { throw new FPInvalidContextException("EXC_0027", "Unable to process SPC. See 'innerException' for more information.", ex); } if (MediaPlaybackPayload.CreationDate < DateTime.UtcNow.AddHours(-6)) { throw new FPContextDateViolatedException("EXC_0036", "Unable to process SPC. Date range violated."); } if (MediaPlaybackPayload.CreationDate > DateTime.UtcNow.AddHours(6)) { throw new FPContextDateViolatedException("EXC_0037", "Unable to process SPC. Date range violated."); } DurationCKPayload DurationContentKeyPayload = null; try { DurationContentKeyPayload = new DurationCKPayload((UInt32)this.LicenseDuration, 0, DurationCKType.Rental); } catch (FPException) { throw; } catch (Exception ex) { throw new FPInvalidContextException("EXC_0028", "Unable to process SPC. See 'innerException' for more information.", ex); } TLLVSlab DurationContentKeySlab = null; try { DurationContentKeySlab = new TLLVSlab(TLLVTag.Id.DurationCK, DurationContentKeyPayload.Binary); } catch (FPException) { throw; } catch (Exception ex) { throw new FPInvalidContextException("EXC_0029", "Unable to process SPC. See 'innerException' for more information.", ex); } ckcSlabs.Add(DurationContentKeySlab); } TLLVSlab CapabilitiesSlab = null; try { CapabilitiesSlab = spcSlabs.FirstOrDefault(p => p.Tag.Same(TLLVTag.Id.Capabilities)); } catch (FPException) { throw; } catch (Exception ex) { throw new FPInvalidContextException("EXC_0030", "Unable to process SPC. See 'innerException' for more information.", ex); } if (CapabilitiesSlab != null) { // Send HDCPEnforcementSlab CapabilitiesPayload CapabilitiesPayload = null; try { CapabilitiesPayload = CapabilitiesSlab.Payload <CapabilitiesPayload>(); } catch (FPException) { throw; } catch (Exception ex) { throw new FPInvalidContextException("EXC_0031", "Unable to process SPC. See 'innerException' for more information.", ex); } if (CapabilitiesPayload.HasCapability(LowCapabilities.HDCPEnforcement)) { HDCPEnforcementPayload HDCPEnforcementPayload = null; try { HDCPEnforcementPayload = new HDCPEnforcementPayload(HDCPTypeRequierement.HDCPType0Required); } catch (FPException) { throw; } catch (Exception ex) { throw new FPInvalidContextException("EXC_0032", "Unable to process SPC. See 'innerException' for more information.", ex); } TLLVSlab HDCPEnforcementSlab = null; try { HDCPEnforcementSlab = new TLLVSlab(TLLVTag.Id.HDCPEnforcement, HDCPEnforcementPayload.Binary); } catch (FPException) { throw; } catch (Exception ex) { throw new FPInvalidContextException("EXC_0033", "Unable to process SPC. See 'innerException' for more information.", ex); } ckcSlabs.Add(HDCPEnforcementSlab); } } return(ckcSlabs); }
private IContentKey FetchKey(FPProvider provider, SPCMessage spc, CKCMessage ckc) { IEnumerable <TLLVSlab> spcSlabs = null; try { spcSlabs = TLLVSlab.FromBuffer(spc.UnscrambledPayload(provider.RSAKey)); } catch (FPException) { throw; } catch (Exception ex) { throw new FPInvalidContextException("EXC_2010", "Unable to process inspection. See 'innerException' for more information.", ex); } byte[] DASk = null; try { DASk = new DFunction(provider.ASKey).DeriveBytes(spcSlabs.First(p => p.Tag.Same(TLLVTag.Id.R2)).Payload <R2Payload>().R2); } catch (FPException) { throw; } catch (Exception ex) { throw new FPInvalidContextException("EXC_2011", "Unable to process inspection. See 'innerException' for more information.", ex); } SKR1Payload SessionRandom1Payload = null; try { SessionRandom1Payload = spcSlabs.First(p => p.Tag.Same(TLLVTag.Id.SKR1)).Payload <SKR1Payload>(); } catch (FPException) { throw; } catch (Exception ex) { throw new FPInvalidContextException("EXC_2012", "Unable to process inspection. See 'innerException' for more information.", ex); } SKR1IntegrityPayload SessionRandom1IntegrityPayload = null; try { SessionRandom1IntegrityPayload = spcSlabs.First(p => p.Tag.Same(TLLVTag.Id.SKR1Integrity)).Payload <SKR1IntegrityPayload>(); } catch (FPException) { throw; } catch (Exception ex) { throw new FPInvalidContextException("EXC_2013", "Unable to process inspection. See 'innerException' for more information.", ex); } SKR1Parcel SessionRandom1Parcel = null; try { SessionRandom1Parcel = new SKR1Parcel(new ReadOnlyMemory <byte>(SessionRandom1Payload.UnscrambledParcel(DASk))); } catch (FPException) { throw; } catch (Exception ex) { throw new FPInvalidContextException("EXC_2014", "Unable to process inspection. See 'innerException' for more information.", ex); } if (Enumerable.SequenceEqual(SessionRandom1Parcel.Integrity, SessionRandom1IntegrityPayload.Integrity) == false) { throw new FPContextIntegrityViolatedException("EXC_0034", "Unable to process SPC. SPC integrity violated."); } byte[] seed = null; try { seed = spcSlabs.First(s => s.Tag.Same(TLLVTag.Id.AR)).Payload <ARPayload>().Seed; } catch (FPException) { throw; } catch (Exception ex) { throw new FPInvalidContextException("EXC_2015", "Unable to process inspection. See 'innerException' for more information.", ex); } byte[] random = null; try { random = SessionRandom1Parcel.R1; } catch (FPException) { throw; } catch (Exception ex) { throw new FPInvalidContextException("EXC_2016", "Unable to process inspection. See 'innerException' for more information.", ex); } byte[] key = null; try { using (var sha = SHA1.Create()) using (var aes = Aes.Create()) { // aes.IV = new byte[16]; aes.Key = sha.ComputeHash(random).Take(16).ToArray(); aes.Mode = CipherMode.ECB; aes.Padding = PaddingMode.None; using (var encryptor = aes.CreateEncryptor()) using (var memoryStream = new MemoryStream()) using (var cryptoStream = new CryptoStream(memoryStream, encryptor, CryptoStreamMode.Write)) { cryptoStream.Write(seed); key = memoryStream.ToArray(); } } } catch (FPException) { throw; } catch (Exception ex) { throw new FPInvalidContextException("EXC_2017", "Unable to process inspection. See 'innerException' for more information.", ex); } IEnumerable <TLLVSlab> ckcSlabs = null; try { ckcSlabs = TLLVSlab.FromBuffer(ckc.UnscrambledPayload(key)); } catch (FPException) { throw; } catch (Exception ex) { throw new FPInvalidContextException("EXC_2018", "Unable to process inspection. See 'innerException' for more information.", ex); } byte[] SK = null; try { SK = SessionRandom1Parcel.SK; } catch (FPException) { throw; } catch (Exception ex) { throw new FPInvalidContextException("EXC_2019", "Unable to process inspection. See 'innerException' for more information.", ex); } return(FetchKey(spcSlabs, ckcSlabs, SK)); }