Example #1
0
        private void WriteData(Stream stream)
        {
            Log("Writing data...");
            hdr.WriteToStream(stream);
            WriteInodes(stream);
            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);

            for (var x = 0; x < allNodes.Count; x++)
            {
                var f = allNodes[x];
                stream.Position = f.ino.StartBlock * hdr.BlockSize;
                WriteFSNode(stream, f);
            }
        }
Example #2
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;
                }
            }
        }