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); } }
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; } } }