Example #1
0
        /// <summary>
        /// Writes the PFS image to the given stream
        /// </summary>
        public void WriteImage(Stream stream)
        {
            WriteData(stream);

            if (hdr.Mode.HasFlag(PfsMode.Signed))
            {
                Log("Signing...");
                var signKey = Crypto.PfsGenSignKey(properties.EKPFS, hdr.Seed);
                foreach (var sig in data_sigs.Concat(final_sigs))
                {
                    var sig_buffer = new byte[sig.Size];
                    stream.Position = sig.Block * properties.BlockSize;
                    stream.Read(sig_buffer, 0, sig.Size);
                    stream.Position = sig.SigOffset;
                    stream.Write(Crypto.HmacSha256(signKey, sig_buffer), 0, 32);
                    stream.WriteLE((int)sig.Block);
                }
            }

            if (hdr.Mode.HasFlag(PfsMode.Encrypted))
            {
                Log("Encrypting...");
                var(tweakKey, dataKey) = Crypto.PfsGenEncKey(properties.EKPFS, hdr.Seed);
                var    transformer  = new XtsBlockTransform(dataKey, tweakKey);
                byte[] sectorBuffer = new byte[xtsSectorSize];
                foreach (var xtsSector in XtsSectorGen())
                {
                    stream.Position = xtsSector * xtsSectorSize;
                    stream.Read(sectorBuffer, 0, xtsSectorSize);
                    transformer.EncryptSector(sectorBuffer, (ulong)xtsSector);
                    stream.Position = xtsSector * xtsSectorSize;
                    stream.Write(sectorBuffer, 0, xtsSectorSize);
                }
            }
        }
Example #2
0
        public void TestRoundTrip()
        {
            byte[] dataKey     = new byte[16];
            byte[] tweakKey    = new byte[16];
            var    transformer = new XtsBlockTransform(dataKey, tweakKey);

            byte[] data = new byte[]
            {
                0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xA, 0xB, 0xC, 0xD, 0xE, 0xF,
                0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
            };
            byte[] expected = data.ToArray();
            transformer.EncryptSector(data, 0);
            CollectionAssert.AreNotEqual(expected, data);
            transformer.DecryptSector(data, 0);
            CollectionAssert.AreEqual(expected, data);


            transformer.EncryptSector(data, 1);
            CollectionAssert.AreNotEqual(expected, data);
            transformer.DecryptSector(data, 1);
            CollectionAssert.AreEqual(expected, data);
        }
Example #3
0
        public void WriteImage(Stream stream)
        {
            Log("Writing header...");
            hdr.WriteToStream(stream);
            Log("Writing inodes...");
            WriteInodes(stream);
            Log("Writing superroot dirents");
            WriteSuperrootDirents(stream);

            var fpt_file = new FSFile(s => fpt.WriteToStream(s), "flat_path_table", fpt.Size);

            fpt_file.ino = fpt_ino;
            allNodes.Insert(0, fpt_file);

            Log("Writing data blocks...");
            for (var x = 0; x < allNodes.Count; x++)
            {
                var f = allNodes[x];
                stream.Position = f.ino.StartBlock * hdr.BlockSize;
                WriteFSNode(stream, f);
            }
            stream.SetLength(hdr.Ndblock * hdr.BlockSize);

            if (hdr.Mode.HasFlag(PfsMode.Signed))
            {
                Log("Signing...");
                var signKey = Crypto.PfsGenSignKey(properties.EKPFS, hdr.Seed);
                foreach (var sig in sig_order)
                {
                    var sig_buffer = new byte[sig.Size];
                    stream.Position = sig.Block * properties.BlockSize;
                    stream.Read(sig_buffer, 0, sig.Size);
                    stream.Position = sig.SigOffset;
                    stream.Write(Crypto.HmacSha256(signKey, sig_buffer), 0, 32);
                    stream.WriteLE((int)sig.Block);
                }
            }

            if (hdr.Mode.HasFlag(PfsMode.Encrypted))
            {
                Log("Encrypting...");
                var encKey   = Crypto.PfsGenEncKey(properties.EKPFS, hdr.Seed);
                var dataKey  = new byte[16];
                var tweakKey = new byte[16];
                Buffer.BlockCopy(encKey, 0, tweakKey, 0, 16);
                Buffer.BlockCopy(encKey, 16, dataKey, 0, 16);
                stream.Position = hdr.BlockSize;
                var       transformer  = new XtsBlockTransform(dataKey, tweakKey);
                const int sectorSize   = 0x1000;
                long      xtsSector    = 16;
                long      totalSectors = (stream.Length + 0xFFF) / sectorSize;
                byte[]    sectorBuffer = new byte[sectorSize];
                while (xtsSector < totalSectors)
                {
                    if (xtsSector / 0x10 == emptyBlock)
                    {
                        xtsSector += 16;
                    }
                    stream.Position = xtsSector * sectorSize;
                    stream.Read(sectorBuffer, 0, sectorSize);
                    transformer.EncryptSector(sectorBuffer, (ulong)xtsSector);
                    stream.Position = xtsSector * sectorSize;
                    stream.Write(sectorBuffer, 0, sectorSize);
                    xtsSector += 1;
                }
            }
        }