Пример #1
0
        private static unsafe IntPtr MarshalSubsampleArray(EncryptedPacket packet)
        {
            var subsamplePointer = IntPtr.Zero;

            if (packet.Subsamples != null)
            {
                var subsamples = packet.Subsamples.Select(o => new MSD_SUBSAMPLE_INFO {
                    uBytesOfClearData = o.ClearData, uBytesOfEncryptedData = o.EncData
                }).ToArray();
                var totalSize = Marshal.SizeOf(typeof(MSD_SUBSAMPLE_INFO)) * subsamples.Length;
                var array     = Marshal.AllocHGlobal(totalSize);
                var pointer   = (MSD_SUBSAMPLE_INFO *)array.ToPointer();
                for (var i = 0; i < subsamples.Length; i++)
                {
                    pointer[i] = subsamples[i];
                }
                subsamplePointer = (IntPtr)pointer;
            }

            var subData = new MSD_FMP4_DATA
            {
                uSubSampleCount = (uint)(packet.Subsamples?.Length ?? 0),
                pSubSampleInfo  = subsamplePointer
            };
            var subdataPointer = Marshal.AllocHGlobal(Marshal.SizeOf(subData));

            Marshal.StructureToPtr(subData, subdataPointer, false);
            return(subdataPointer);
        }
Пример #2
0
        private unsafe eCDMReturnType CreateParamsAndDecryptData(EncryptedPacket packet, byte *data, int dataLen, ref HandleSize[] pHandleArray, CancellationToken token)
        {
            fixed(byte *iv = packet.Iv, kId = packet.KeyId)
            {
                var subdataPointer       = MarshalSubsampleArray(packet);
                var subsampleInfoPointer = ((MSD_FMP4_DATA *)subdataPointer.ToPointer())->pSubSampleInfo;

                try
                {
                    var param = new sMsdCipherParam
                    {
                        algorithm = eMsdCipherAlgorithm.MSD_AES128_CTR,
                        format    = eMsdMediaFormat.MSD_FORMAT_FMP4,
                        pdata     = data,
                        udatalen  = (uint)dataLen,
                        piv       = iv,
                        uivlen    = (uint)packet.Iv.Length,
                        pkid      = kId,
                        ukidlen   = (uint)packet.KeyId.Length,
                        psubdata  = subdataPointer
                    };
                    return(DecryptData(new[] { param }, ref pHandleArray, packet.StreamType, token));
                }
                finally
                {
                    if (subsampleInfoPointer != IntPtr.Zero)
                    {
                        Marshal.FreeHGlobal(subsampleInfoPointer);
                    }
                    Marshal.FreeHGlobal(subdataPointer);
                }
            }
        }
Пример #3
0
        private Packet DecryptPacketOnIemeThread(EncryptedPacket packet, CancellationToken token)
        {
            // Do padding only for Widevine with keys shorter then 16 bytes
            // Shorter keys need to be zero padded, not PCKS#7
            if (DrmType == EmeUtils.DrmType.Widevine && packet.Iv.Length < 16)
            {
                packet.Iv = PadIv(packet.Iv);
            }

            var pHandleArray = new HandleSize[1];
            var ret          = CreateParamsAndDecryptData(packet, ref pHandleArray, token);

            if (ret == eCDMReturnType.E_SUCCESS)
            {
                return(new DecryptedEMEPacket(thread)
                {
                    Dts = packet.Dts,
                    Pts = packet.Pts,
                    StreamType = packet.StreamType,
                    IsKeyFrame = packet.IsKeyFrame,
                    Duration = packet.Duration,
                    HandleSize = pHandleArray[0]
                });
            }

            Logger.Error($"Decryption failed: {packet.StreamType} - {ret}");
            throw new DrmException($"Decryption failed: {packet.StreamType} - {ret}");
        }
Пример #4
0
        private unsafe eCDMReturnType CreateParamsAndDecryptData(EncryptedPacket packet, ref HandleSize[] pHandleArray, CancellationToken token)
        {
            switch (packet.Storage)
            {
            case IManagedDataStorage managedStorage:
                fixed(byte *data = managedStorage.Data)
                return(CreateParamsAndDecryptData(packet, data, managedStorage.Data.Length, ref pHandleArray, token));

            case INativeDataStorage nativeStorage:
                return(CreateParamsAndDecryptData(packet, nativeStorage.Data, nativeStorage.Length, ref pHandleArray, token));

            default:
                throw new DrmException($"Unsupported packet storage: {packet.Storage?.GetType()}");
            }
        }
Пример #5
0
 public async Task <Packet> DecryptPacket(EncryptedPacket packet, CancellationToken token)
 {
     ThrowIfDisposed();
     return(await thread.Factory.Run(() => DecryptPacketOnIemeThread(packet, token)));
 }