private IContentKey FetchKey(IEnumerable <TLLVSlab> spcSlabs, IEnumerable <TLLVSlab> ckcSlabs, byte[] SK) { EncryptedCKPayload EncryptedContentKeyPayload = null; try { EncryptedContentKeyPayload = ckcSlabs.First(s => s.Tag.Same(TLLVTag.Id.EncryptedCK)).Payload <EncryptedCKPayload>(); } catch (FPException) { throw; } catch (Exception ex) { throw new FPInvalidContextException("EXC_2020", "Unable to process inspection. See 'innerException' for more information.", ex); } EncryptedCKParcel EncryptedContentKeyParcel = null; try { EncryptedContentKeyParcel = new EncryptedCKParcel(new ReadOnlyMemory <byte>(EncryptedContentKeyPayload.UnscrambledParcel(SK))); } catch (FPException) { throw; } catch (Exception ex) { throw new FPInvalidContextException("EXC_2021", "Unable to process inspection. See 'innerException' for more information.", ex); } byte[] IV = null; try { IV = EncryptedContentKeyPayload.IV; } catch (FPException) { throw; } catch (Exception ex) { throw new FPInvalidContextException("EXC_2022", "Unable to process inspection. See 'innerException' for more information.", ex); } byte[] CK = null; try { CK = EncryptedContentKeyParcel.Key; } catch (FPException) { throw; } catch (Exception ex) { throw new FPInvalidContextException("EXC_2023", "Unable to process inspection. See 'innerException' for more information.", ex); } return(new FPStaticKey(CK, IV)); }
public static byte[] UnscrambledParcel(this EncryptedCKPayload payload, byte[] key) { ArgumentThrow.IfNull(payload, $"Invalid {typeof(EncryptedCKPayload).Name} to unscramble. Payload can not be null.", nameof(payload)); ArgumentThrow.IfLengthNot(key, 16, "Invalid key to unscramble. Key buffer should be 16 bytes.", nameof(key)); using (var aes = Aes.Create()) { // aes.IV = null; aes.Key = key; aes.Mode = CipherMode.ECB; aes.Padding = PaddingMode.None; using (var decryptor = aes.CreateDecryptor()) using (var memoryStream = new MemoryStream()) using (var cryptoStream = new CryptoStream(memoryStream, decryptor, CryptoStreamMode.Write)) { cryptoStream.Write(payload.Parcel); 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); }