private Stream GetDataStream(FirmwareHeader header) { // offset into the file past the header var substream = new SubStream(_stream, header.Offset + FirmwareHeader.HeaderLength, header.Length); var hasEncryptionKey = !header.KeyBlob.All(b => b == 0); if (hasEncryptionKey) { // Pull AES key from header, init AES decryptor, return stream var rawAesKey = _cipher.PublicDecrypt(header.KeyBlob); var aesKey = AESKey.Parse(rawAesKey); var aesAlg = new AesCryptoServiceProvider { Key = aesKey.Key, IV = aesKey.IV, Mode = CipherMode.CBC, Padding = PaddingMode.None // No reference to padding seen in binary, using default (PKCS7) always fails. }; var decryptor = aesAlg.CreateDecryptor(); var cryptoStream = new CryptoStream(substream, decryptor, CryptoStreamMode.Read, leaveOpen: true); return(cryptoStream); } else { return(new XorStream(substream, Constants.DataXOR)); } }
private FirmwareHeader ReadHeader(long offset) { Span <byte> buf = stackalloc byte[FirmwareHeader.HeaderLength]; _stream.Seek(offset, SeekOrigin.Begin); _stream.Read(buf); var header = FirmwareHeader.Parse(buf); if (header.Magic != Constants.FirmwareMagic) { throw new InvalidDataException($"read invalid header at {offset:X}, bad magic"); } header.Offset = offset; return(header); }