-
Notifications
You must be signed in to change notification settings - Fork 45
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Implement FEC generation and validation #145
Comments
Also, once this is implemented, I plan on adding |
OK... I might only implement the read-whole-file-to-memory method. That runs in 5 seconds against the Pixel 7 Pro's stock The read + seek (well, EDIT: Some benchmarks.
EDIT 2: Reading 1-byte at a time is dumb. |
This commit adds initial support for the FEC (forward error correction) used by AVB hashtree descriptors. AVB FEC uses standard Reed-Solomon in the RS(255, 253) + Gf(256) + 0x11d configuration, but does not read data sequentially. Instead, it uses an interleaving pattern where each RS block covers bytes that span nearly the entire file. Due to the interleaving file access pattern, we're forced to use mmap or read the entire file into memory. Using seek = read when dealing with a large input file results in a ~500x increase in processing time. Reading one byte at a time non-sequentially is about the worst possible access pattern for seek + read. All of the processing is done multithreaded. Although the AOSP libfec implementation is also multithreaded, this implementation runs at ~5x the speed of AOSP libfec. Unfortunately, while the implementation is extremely fast, it required using `unsafe` blocks. Multiple threads need to write to disjoint, non-contiguous indices in a buffer, but there's no way to prove to the compiler that this is safe, so we're stuck with using raw pointers. Issue: #145 Signed-off-by: Andrew Gunnerson <accounts+github@chiller3.com>
This commit adds initial support for the FEC (forward error correction) used by AVB hashtree descriptors. AVB FEC uses standard Reed-Solomon in the RS(255, 253) + Gf(256) + 0x11d configuration, but does not read data sequentially. Instead, it uses an interleaving pattern where each RS block covers bytes that span nearly the entire file. Due to the interleaving file access pattern, we're forced to use mmap or read the entire file into memory. Using seek = read when dealing with a large input file results in a ~500x increase in processing time. Reading one byte at a time non-sequentially is about the worst possible access pattern for seek + read. All of the processing is done multithreaded. Although the AOSP libfec implementation is also multithreaded, this implementation runs at ~5x the speed of AOSP libfec. Unfortunately, while the implementation is extremely fast, it required using `unsafe` blocks. Multiple threads need to write to disjoint, non-contiguous indices in a buffer, but there's no way to prove to the compiler that this is safe, so we're stuck with using raw pointers. Issue: #145 Signed-off-by: Andrew Gunnerson <accounts+github@chiller3.com>
This commit adds initial support for the FEC (forward error correction) used by AVB hashtree descriptors. AVB FEC uses standard Reed-Solomon in the RS(255, 253) + Gf(256) + 0x11d configuration, but does not read data sequentially. Instead, it uses an interleaving pattern where each RS block covers bytes that span nearly the entire file. Due to the interleaving file access pattern, we're forced to use mmap or read the entire file into memory. Using seek = read when dealing with a large input file results in a ~500x increase in processing time. Reading one byte at a time non-sequentially is about the worst possible access pattern for seek + read. All of the processing is done multithreaded. Although the AOSP libfec implementation is also multithreaded, this implementation runs at ~5x the speed of AOSP libfec. Unfortunately, while the implementation is extremely fast, it required using `unsafe` blocks. Multiple threads need to write to disjoint, non-contiguous indices in a buffer, but there's no way to prove to the compiler that this is safe, so we're stuck with using raw pointers. Issue: #145 Signed-off-by: Andrew Gunnerson <accounts+github@chiller3.com>
This commit adds initial support for the FEC (forward error correction) used by AVB hashtree descriptors. AVB FEC uses standard Reed-Solomon in the RS(255, 253) + Gf(256) + 0x11d configuration, but does not read data sequentially. Instead, it uses an interleaving pattern where each RS block covers bytes that span nearly the entire file. Due to the interleaving file access pattern, we're forced to use mmap or read the entire file into memory. Using seek = read when dealing with a large input file results in a ~500x increase in processing time. Reading one byte at a time non-sequentially is about the worst possible access pattern for seek + read. All of the processing is done multithreaded. Although the AOSP libfec implementation is also multithreaded, this implementation runs at ~5x the speed of AOSP libfec. Unfortunately, while the implementation is extremely fast, it required using `unsafe` blocks. Multiple threads need to write to disjoint, non-contiguous indices in a buffer, but there's no way to prove to the compiler that this is safe, so we're stuck with using raw pointers. Issue: #145 Signed-off-by: Andrew Gunnerson <accounts+github@chiller3.com>
This commit adds initial support for the FEC (forward error correction) used by AVB hashtree descriptors. AVB FEC uses standard Reed-Solomon in the RS(255, 253) + GF(256) + 0x11d configuration, but does not read data sequentially. Instead, it uses an interleaving pattern where each RS block covers bytes that span nearly the entire file. Due to the interleaving file access pattern, we're forced to use mmap or read the entire file into memory. Using seek = read when dealing with a large input file results in a ~500x increase in processing time. Reading one byte at a time non-sequentially is about the worst possible access pattern for seek + read. All of the processing is done multithreaded. Although the AOSP libfec implementation is also multithreaded, this implementation runs at ~5x the speed of AOSP libfec. Unfortunately, while the implementation is extremely fast, it required using `unsafe` blocks. Multiple threads need to write to disjoint, non-contiguous indices in a buffer, but there's no way to prove to the compiler that this is safe, so we're stuck with using raw pointers. Issue: #145 Signed-off-by: Andrew Gunnerson <accounts+github@chiller3.com>
This commit adds initial support for the FEC (forward error correction) used by AVB hashtree descriptors. AVB FEC uses standard Reed-Solomon in the RS(255, 253) + GF(256) + 0x11d configuration, but does not read data sequentially. Instead, it uses an interleaving pattern where each RS block covers bytes that span nearly the entire file. Due to the interleaving file access pattern, we're forced to use mmap or read the entire file into memory. Using seek = read when dealing with a large input file results in a ~500x increase in processing time. Reading one byte at a time non-sequentially is about the worst possible access pattern for seek + read. All of the processing is done multithreaded. Although the AOSP libfec implementation is also multithreaded, this implementation runs at ~5x the speed of AOSP libfec. Unfortunately, while the implementation is extremely fast, it required using `unsafe` blocks. Multiple threads need to write to disjoint, non-contiguous indices in a buffer, but there's no way to prove to the compiler that this is safe, so we're stuck with using raw pointers. Issue: #145 Signed-off-by: Andrew Gunnerson <accounts+github@chiller3.com>
This commit adds initial support for the FEC (forward error correction) used by AVB hashtree descriptors. AVB FEC uses standard Reed-Solomon in the RS(255, 253) + GF(256) + 0x11d configuration, but does not read data sequentially. Instead, it uses an interleaving pattern where each RS block covers bytes that span nearly the entire file. Due to the interleaving file access pattern, we're forced to use mmap or read the entire file into memory. Using seek = read when dealing with a large input file results in a ~500x increase in processing time. Reading one byte at a time non-sequentially is about the worst possible access pattern for seek + read. All of the processing is done multithreaded. Although the AOSP libfec implementation is also multithreaded, this implementation runs at ~5x the speed of AOSP libfec. Unfortunately, while the implementation is extremely fast, it required using `unsafe` blocks. Multiple threads need to write to disjoint, non-contiguous indices in a buffer, but there's no way to prove to the compiler that this is safe, so we're stuck with using raw pointers. Issue: #145 Signed-off-by: Andrew Gunnerson <accounts+github@chiller3.com>
This commit adds initial support for the FEC (forward error correction) used by AVB hashtree descriptors. AVB FEC uses standard Reed-Solomon in the RS(255, 253) + GF(256) + 0x11d configuration, but does not read data sequentially. Instead, it uses an interleaving pattern where each RS block covers bytes that span nearly the entire file. Due to the interleaving file access pattern, we're forced to use mmap or read the entire file into memory. Using seek = read when dealing with a large input file results in a ~500x increase in processing time. Reading one byte at a time non-sequentially is about the worst possible access pattern for seek + read. All of the processing is done multithreaded. Although the AOSP libfec implementation is also multithreaded, this implementation runs at ~5x the speed of AOSP libfec. Unfortunately, while the implementation is extremely fast, it required using `unsafe` blocks. Multiple threads need to write to disjoint, non-contiguous indices in a buffer, but there's no way to prove to the compiler that this is safe, so we're stuck with using raw pointers. Issue: #145 Signed-off-by: Andrew Gunnerson <accounts+github@chiller3.com>
This commit adds initial support for the FEC (forward error correction) used by AVB hashtree descriptors. AVB FEC uses standard Reed-Solomon in the RS(255, 253) + GF(256) + 0x11d configuration, but does not read data sequentially. Instead, it uses an interleaving pattern where each RS block covers bytes that span nearly the entire file. Due to the interleaving file access pattern, we're forced to use mmap or read the entire file into memory. Using seek = read when dealing with a large input file results in a ~500x increase in processing time. Reading one byte at a time non-sequentially is about the worst possible access pattern for seek + read. All of the processing is done multithreaded. Although the AOSP libfec implementation is also multithreaded, this implementation runs at ~5x the speed of AOSP libfec. Unfortunately, while the implementation is extremely fast, it required using `unsafe` blocks. Multiple threads need to write to disjoint, non-contiguous indices in a buffer, but there's no way to prove to the compiler that this is safe, so we're stuck with using raw pointers. Issue: #145 Signed-off-by: Andrew Gunnerson <accounts+github@chiller3.com>
This commit adds initial support for the FEC (forward error correction) used by AVB hashtree descriptors. AVB FEC uses standard Reed-Solomon in the RS(255, 253) + GF(256) + 0x11d configuration, but does not read data sequentially. Instead, it uses an interleaving pattern where each RS block covers bytes that span nearly the entire file. Due to the interleaving file access pattern, we're forced to use mmap or read the entire file into memory. Using seek = read when dealing with a large input file results in a ~500x increase in processing time. Reading one byte at a time non-sequentially is about the worst possible access pattern for seek + read. All of the processing is done multithreaded. Although the AOSP libfec implementation is also multithreaded, this implementation runs at ~5x the speed of AOSP libfec. Unfortunately, while the implementation is extremely fast, it required using `unsafe` blocks. Multiple threads need to write to disjoint, non-contiguous indices in a buffer, but there's no way to prove to the compiler that this is safe, so we're stuck with using raw pointers. Issue: #145 Signed-off-by: Andrew Gunnerson <accounts+github@chiller3.com>
This commit adds initial support for the FEC (forward error correction) used by dm-verity. The new `avbroot fec` commands operate on FEC data stored in AOSP's standalone FEC file format. It is compatible with AOSP's `fec` tool. Issue: #145 Signed-off-by: Andrew Gunnerson <accounts+github@chiller3.com>
This commit adds initial support for the FEC (forward error correction) used by dm-verity. The new `avbroot fec` commands operate on FEC data stored in AOSP's standalone FEC file format. It is compatible with AOSP's `fec` tool. Issue: #145 Signed-off-by: Andrew Gunnerson <accounts+github@chiller3.com>
This also adds additional checks to ensure that there are no gaps between the image data and hash tree and between the hash tree and FEC data. Issue: #145 Signed-off-by: Andrew Gunnerson <accounts+github@chiller3.com>
This commit adds initial support for the FEC (forward error correction) used by dm-verity. The new `avbroot fec` commands operate on FEC data stored in AOSP's standalone FEC file format. It is compatible with AOSP's `fec` tool. Issue: #145 Signed-off-by: Andrew Gunnerson <accounts+github@chiller3.com>
This also fixes the wrong error being reported when the hash tree does not match and adds additional checks to ensure that there are no gaps between the image data, hash tree, and FEC data. Issue: #145 Signed-off-by: Andrew Gunnerson <accounts+github@chiller3.com>
Currently, avbroot's AVB logic can only verify and update the hash tree portion of hash tree descriptors. The FEC (forward error correction) data is left untouched. We currently don't modify dm-verity partitions, but if we need to in the future, broken/invalid FEC data could cause the user's device to crash or soft brick in the event of a bit flip that trips dm-verity.
(My original understanding of how things worked)
AVB FEC uses RS(255, 253) (Reed-Solomon codewords with 253 bytes of data and 2 bytes of parity) over GF(256) with the 0x11d primitive polynomial. The data fed into RS is not the raw data, but instead, an interleaving pattern. The interleaving is determined by 3 variables:
which is the only value avbroot will support (because the best Rust library for these calculations uses code generation that requires the K value at compile time).EDIT: avbroot will support everything in [231, 253] (everything allowed by dm-verity).It's undocumented in AOSP, but is equal toceil(file size / FEC block size / RS K value)
.Interleaving pattern:* Input offset 0 == output offset 0.* Each time the input offset is incremented by 1, the output offset is incremented by this value times the block size.~* Once the input offset cross a multiple of
rs_k
, the output offset "wraps around" and starts again at the beginning again.`For example, withfile_size=2048000
andrs_k=253
(and thus,rounds=2
):EDIT: Better documented in the implementation:
avbroot/avbroot/src/format/fec.rs
Lines 121 to 144 in f18a681
When calculating this FEC data, avbroot will probably default to reading everything into memory with an option to use mmap for memory-constrained systems. The access pattern is probably going to cause a whole lot of thrashing with mmap due to it needing to read one byte at a time all over the file.EDIT: avbroot now uses a much smarter way of doing the interleaved reads, inspired by cryptsetup'sveritysetup
.Once implemented (already have a working proof of concept),
avbroot avb verify
andavbroot ota verify
will be updated to check the validity of the FEC data.The text was updated successfully, but these errors were encountered: