Compare commits

...

20 Commits

Author SHA1 Message Date
Andrew Gunnerson 983e6c40a5 Version 3.9.0
Signed-off-by: Andrew Gunnerson <accounts+github@chiller3.com>
2024-11-11 20:04:59 -05:00
Andrew Gunnerson 8729854727 CHANGELOG.md: Add entry for PR #377
Signed-off-by: Andrew Gunnerson <accounts+github@chiller3.com>
2024-11-11 19:55:44 -05:00
Andrew Gunnerson 0d1beb7734 Update dependencies
Signed-off-by: Andrew Gunnerson <accounts+github@chiller3.com>
2024-11-11 19:54:50 -05:00
Andrew Gunnerson 2cd0d69238 CHANGELOG.md: Add entry for PR #376
Signed-off-by: Andrew Gunnerson <accounts+github@chiller3.com>
2024-11-11 19:43:50 -05:00
Andrew Gunnerson c0e65264e5 sparse: Allow parsing files with unknown fields
The official AOSP implementation does, so we should too. This allows
unpacking Samsung's sparse images, which have an extra 4 bytes in both
the file header and chunk headers.

Signed-off-by: Andrew Gunnerson <accounts+github@chiller3.com>
2024-11-11 19:41:27 -05:00
Andrew Gunnerson 37b15a2b6a CHANGELOG.md: Add entry for PR #374
Signed-off-by: Andrew Gunnerson <accounts+github@chiller3.com>
2024-11-08 17:38:56 -05:00
Andrew Gunnerson e4994fbe98 format/payload: Allow verifying signatures without an unpadded size
Older OTAs created before the payload metadata format supported EC
signatures will not have the `unpadded_signature_size` field set. In
this case, we'll just use the full length of `data`, which is what
update_engine also does.

Issue: #366

Signed-off-by: Andrew Gunnerson <accounts+github@chiller3.com>
2024-11-08 17:38:28 -05:00
Andrew Gunnerson cf1bacab30 CHANGELOG.md: Add entry for PR #373
Signed-off-by: Andrew Gunnerson <accounts+github@chiller3.com>
2024-11-08 17:27:24 -05:00
Andrew Gunnerson 4832121160 format/ota: Allow verifying OTAs without metadata.pb
While patched OTAs produced by avbroot always include the protobuf
version of the OTA metadata, the original OTA may not. Verifying those
with `avbroot ota verify` is a valid use case.

Issue: #366

Signed-off-by: Andrew Gunnerson <accounts+github@chiller3.com>
2024-11-08 17:25:00 -05:00
Andrew Gunnerson c614e61744 CHANGELOG.md: Add entry for PR #371
Signed-off-by: Andrew Gunnerson <accounts+github@chiller3.com>
2024-11-07 22:13:45 -05:00
Andrew Gunnerson 9ebce1666c Add option to skip verifying recovery's OTA cert too
Issue: #366

Signed-off-by: Andrew Gunnerson <accounts+github@chiller3.com>
2024-11-07 22:04:11 -05:00
Andrew Gunnerson fb34198ffc CHANGELOG.md: Add entry for PR #370
Signed-off-by: Andrew Gunnerson <accounts+github@chiller3.com>
2024-11-05 18:00:13 -05:00
Andrew Gunnerson 4a5eab4ba0 crypto: Fix minor clippy warning
Signed-off-by: Andrew Gunnerson <accounts+github@chiller3.com>
2024-11-05 17:59:26 -05:00
Andrew Gunnerson 1e1818ad8f CHANGELOG.md: Add entry for PR #369
Signed-off-by: Andrew Gunnerson <accounts+github@chiller3.com>
2024-11-05 17:58:59 -05:00
Andrew Gunnerson 3f25ad7c76 Add more context for avb::Header::set_algo_for_key() calls
Previously, it was not always obvious which key was problematic.

Issue: #366

Signed-off-by: Andrew Gunnerson <accounts+github@chiller3.com>
2024-11-05 17:53:01 -05:00
Andrew Gunnerson 37e28eb040 CHANGELOG.md: Add entry for PR #367
Signed-off-by: Andrew Gunnerson <accounts+github@chiller3.com>
2024-11-05 17:51:41 -05:00
Andrew Gunnerson ce87757fd1 patch/boot: Avoid loading boot images when there are no patchers
Signed-off-by: Andrew Gunnerson <accounts+github@chiller3.com>
2024-11-05 09:30:04 -05:00
Andrew Gunnerson 10c425dede Add option to skip inserting OTA cert into recovery image
Issue: #366

Signed-off-by: Andrew Gunnerson <accounts+github@chiller3.com>
2024-11-05 09:30:03 -05:00
Andrew Gunnerson 8a0d147993 CHANGELOG.md: Add entry for PR #368
Signed-off-by: Andrew Gunnerson <accounts+github@chiller3.com>
2024-11-04 18:54:23 -05:00
Andrew Gunnerson 062aa21485 Update dependencies
Signed-off-by: Andrew Gunnerson <accounts+github@chiller3.com>
2024-11-04 18:32:58 -05:00
14 changed files with 248 additions and 133 deletions
+20
View File
@@ -7,6 +7,16 @@
to update the actual links at the bottom of the file.
-->
### Version 3.9.0
* Update all dependencies ([PR #368], [PR #377])
* Add advanced option to skip replacing the OTA certificate in the recovery image ([Issue #366], [PR #367], [PR #371])
* Improve error message when an incompatible RSA key is used for AVB signing ([Issue #366], [PR #369])
* Fix clippy warnings ([PR #370])
* Allow `avbroot ota verify` to verify OTAs that lack `META-INF/com/android/metadata.pb` ([Issue #366], [PR #373])
* Allow `avbroot ota verify` to verify OTAs where the payload signature does not set `unpadded_signature_size` ([Issue #366], [PR #374])
* Allow `avbroot sparse` to parse sparse images with unknown fields (matches AOSP implementation) ([PR #376])
### Version 3.8.0
* Add `avbroot avb digest` subcommand for computing the special vbmeta digest ([PR #363])
@@ -265,6 +275,7 @@ Behind-the-scenes changes:
[Issue #328]: https://github.com/chenxiaolong/avbroot/issues/328
[Issue #332]: https://github.com/chenxiaolong/avbroot/issues/332
[Issue #356]: https://github.com/chenxiaolong/avbroot/issues/356
[Issue #366]: https://github.com/chenxiaolong/avbroot/issues/366
[PR #130]: https://github.com/chenxiaolong/avbroot/pull/130
[PR #132]: https://github.com/chenxiaolong/avbroot/pull/132
[PR #133]: https://github.com/chenxiaolong/avbroot/pull/133
@@ -376,3 +387,12 @@ Behind-the-scenes changes:
[PR #362]: https://github.com/chenxiaolong/avbroot/pull/362
[PR #363]: https://github.com/chenxiaolong/avbroot/pull/363
[PR #364]: https://github.com/chenxiaolong/avbroot/pull/364
[PR #367]: https://github.com/chenxiaolong/avbroot/pull/367
[PR #368]: https://github.com/chenxiaolong/avbroot/pull/368
[PR #369]: https://github.com/chenxiaolong/avbroot/pull/369
[PR #370]: https://github.com/chenxiaolong/avbroot/pull/370
[PR #371]: https://github.com/chenxiaolong/avbroot/pull/371
[PR #373]: https://github.com/chenxiaolong/avbroot/pull/373
[PR #374]: https://github.com/chenxiaolong/avbroot/pull/374
[PR #376]: https://github.com/chenxiaolong/avbroot/pull/376
[PR #377]: https://github.com/chenxiaolong/avbroot/pull/377
Generated
+123 -103
View File
@@ -36,9 +36,9 @@ checksum = "e9d4ee0d472d1cd2e28c97dfa124b3d8d992e10eb0a035f33f5d12e3a177ba3b"
[[package]]
name = "anstream"
version = "0.6.15"
version = "0.6.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "64e15c1ab1f89faffbf04a634d5e1962e9074f2741eef6d97f3c4e322426d526"
checksum = "8acc5369981196006228e28809f761875c0327210a891e941f4c683b3a99529b"
dependencies = [
"anstyle",
"anstyle-parse",
@@ -51,49 +51,49 @@ dependencies = [
[[package]]
name = "anstyle"
version = "1.0.8"
version = "1.0.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1bec1de6f59aedf83baf9ff929c98f2ad654b97c9510f4e70cf6f661d49fd5b1"
checksum = "55cc3b69f167a1ef2e161439aa98aed94e6028e5f9a59be9a6ffb47aef1651f9"
[[package]]
name = "anstyle-parse"
version = "0.2.5"
version = "0.2.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "eb47de1e80c2b463c735db5b217a0ddc39d612e7ac9e2e96a5aed1f57616c1cb"
checksum = "3b2d16507662817a6a20a9ea92df6652ee4f94f914589377d69f3b21bc5798a9"
dependencies = [
"utf8parse",
]
[[package]]
name = "anstyle-query"
version = "1.1.1"
version = "1.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6d36fc52c7f6c869915e99412912f22093507da8d9e942ceaf66fe4b7c14422a"
checksum = "79947af37f4177cfead1110013d678905c37501914fba0efea834c3fe9a8d60c"
dependencies = [
"windows-sys 0.52.0",
"windows-sys 0.59.0",
]
[[package]]
name = "anstyle-wincon"
version = "3.0.4"
version = "3.0.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5bf74e1b6e971609db8ca7a9ce79fd5768ab6ae46441c572e46cf596f59e57f8"
checksum = "2109dbce0e72be3ec00bed26e6a7479ca384ad226efdd66db8fa2e3a38c83125"
dependencies = [
"anstyle",
"windows-sys 0.52.0",
"windows-sys 0.59.0",
]
[[package]]
name = "anyhow"
version = "1.0.89"
version = "1.0.93"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "86fdf8605db99b54d3cd748a44c6d04df638eb5dafb219b135d0149bd0db01f6"
checksum = "4c95c10ba0b00a02636238b814946408b1322d5ac4760326e6fb8ec956d85775"
[[package]]
name = "arbitrary"
version = "1.3.2"
version = "1.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7d5a26814d8dcb93b0e5a0ff3c6d80a8843bafb21b39e8e18a6f05471870e110"
checksum = "dde20b3d026af13f561bdd0f15edf01fc734f0dafcedbaf42bba506a9517f223"
[[package]]
name = "assert_matches"
@@ -109,7 +109,7 @@ checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26"
[[package]]
name = "avbroot"
version = "3.8.0"
version = "3.9.0"
dependencies = [
"anyhow",
"assert_matches",
@@ -154,14 +154,14 @@ dependencies = [
"sha1",
"sha2",
"tempfile",
"thiserror",
"thiserror 2.0.3",
"toml_edit",
"topological-sort",
"tracing",
"tracing-subscriber",
"x509-cert",
"zerocopy 0.8.5",
"zerocopy-derive 0.8.5",
"zerocopy 0.8.9",
"zerocopy-derive 0.8.9",
"zip",
]
@@ -229,9 +229,9 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
[[package]]
name = "bytes"
version = "1.7.2"
version = "1.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "428d9aa8fbc0670b7b8d6030a7fadd0f86151cae55e4dbbece15f3780a3dfaf3"
checksum = "9ac0150caa2ae65ca5bd83f25c7de183dea78d4d366469f148435e2acfbad0da"
[[package]]
name = "bzip2"
@@ -254,9 +254,9 @@ dependencies = [
[[package]]
name = "cap-primitives"
version = "3.3.0"
version = "3.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ff5bcbaf57897c8f14098cc9ad48a78052930a9948119eea01b80ca224070fa6"
checksum = "82fa6c3f9773feab88d844aa50035a33fb6e7e7426105d2f4bb7aadc42a5f89a"
dependencies = [
"ambient-authority",
"fs-set-times",
@@ -271,9 +271,9 @@ dependencies = [
[[package]]
name = "cap-std"
version = "3.3.0"
version = "3.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e6cf1a22e6eab501e025a9953532b1e95efb8a18d6364bf8a4a7547b30c49186"
checksum = "7f71b70818556b4fe2a10c7c30baac3f5f45e973f49fc2673d7c75c39d0baf5b"
dependencies = [
"cap-primitives",
"io-extras",
@@ -283,9 +283,9 @@ dependencies = [
[[package]]
name = "cap-tempfile"
version = "3.3.0"
version = "3.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8563f37bd2d9ec79a08dc6b062b6733adc84f929d23f45388ba52025c7b32e26"
checksum = "200812b29d9de495a9ba97dee1737f7def8907de53a0962843b6a955df921e22"
dependencies = [
"cap-std",
"rand",
@@ -304,9 +304,9 @@ dependencies = [
[[package]]
name = "cc"
version = "1.1.30"
version = "1.1.37"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b16803a61b81d9eabb7eae2588776c4c1e584b738ede45fdbb4c972cec1e9945"
checksum = "40545c26d092346d8a8dab71ee48e7685a7a9cba76e634790c215b41a4a7b4cf"
dependencies = [
"jobserver",
"libc",
@@ -359,9 +359,9 @@ dependencies = [
[[package]]
name = "clap_complete"
version = "4.5.33"
version = "4.5.37"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9646e2e245bf62f45d39a0f3f36f1171ad1ea0d6967fd114bca72cb02a8fcdfb"
checksum = "11611dca53440593f38e6b25ec629de50b14cdfa63adc0fb856115a2c6d97595"
dependencies = [
"clap",
]
@@ -375,7 +375,7 @@ dependencies = [
"heck",
"proc-macro2",
"quote",
"syn 2.0.79",
"syn 2.0.87",
]
[[package]]
@@ -398,9 +398,9 @@ dependencies = [
[[package]]
name = "colorchoice"
version = "1.0.2"
version = "1.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d3fd119d74b830634cea2a0f58bbd0d54540518a14397557951e79340abc28c0"
checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990"
[[package]]
name = "const-oid"
@@ -436,9 +436,9 @@ checksum = "4938185353434999ef52c81753c8cca8955ed38042fc29913db3751916f3b7ab"
[[package]]
name = "cpufeatures"
version = "0.2.14"
version = "0.2.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "608697df725056feaccfa42cffdaeeec3fccc4ffc38358ecd19b243e716a78e0"
checksum = "0ca741a962e1b0bff6d724a1a0958b686406e853bb14061f218562e1896f95e6"
dependencies = [
"libc",
]
@@ -559,7 +559,7 @@ checksum = "8034092389675178f570469e6c3b0465d3d30b4505c294a6550db47f3c17ad18"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.79",
"syn 2.0.87",
]
[[package]]
@@ -585,7 +585,7 @@ dependencies = [
[[package]]
name = "e2e"
version = "3.8.0"
version = "3.9.0"
dependencies = [
"anyhow",
"avbroot",
@@ -634,9 +634,9 @@ checksum = "cfc25fd417983cc7f203394ebb89eba18e2df1b0ac1be2673091b5aca52b595f"
[[package]]
name = "fastrand"
version = "2.1.1"
version = "2.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e8c02a5121d4ea3eb16a80748c74f5549a5665e4c21333c6098f283870fbdea6"
checksum = "486f806e73c5707928240ddc295403b1b93c96a02038563881c4a2fd84b81ac4"
[[package]]
name = "fixedbitset"
@@ -679,7 +679,7 @@ dependencies = [
[[package]]
name = "fuzz"
version = "3.8.0"
version = "3.9.0"
dependencies = [
"avbroot",
"honggfuzz",
@@ -731,9 +731,9 @@ dependencies = [
[[package]]
name = "hashbrown"
version = "0.15.0"
version = "0.15.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e087f84d4f86bf4b218b927129862374b72199ae7d8657835f1e89000eea4fb"
checksum = "3a9bfc1af68b1726ea47d3d5109de126281def866b33970e10fbab11b5dafab3"
[[package]]
name = "heck"
@@ -799,9 +799,9 @@ dependencies = [
[[package]]
name = "io-extras"
version = "0.18.2"
version = "0.18.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c9f046b9af244f13b3bd939f55d16830ac3a201e8a9ba9661bfcb03e2be72b9b"
checksum = "7d45fd7584f9b67ac37bc041212d06bfac0700b36456b05890d36a3b626260eb"
dependencies = [
"io-lifetimes",
"windows-sys 0.52.0",
@@ -860,15 +860,15 @@ dependencies = [
[[package]]
name = "libc"
version = "0.2.159"
version = "0.2.162"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "561d97a539a36e26a9a5fad1ea11a3039a67714694aaa379433e580854bc3dc5"
checksum = "18d287de67fe55fd7e1581fe933d965a5a9477b38e949cfa9f8574ef01506398"
[[package]]
name = "liblzma"
version = "0.3.4"
version = "0.3.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a7c45fc6fcf5b527d3cf89c1dee8c327943984b0dc8bfcf6e100473b00969e63"
checksum = "603222e049bf0da71529325ada5d02dc3871cbd3679cf905429f7f0de93da87b"
dependencies = [
"liblzma-sys",
]
@@ -886,9 +886,9 @@ dependencies = [
[[package]]
name = "libm"
version = "0.2.8"
version = "0.2.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058"
checksum = "8355be11b20d696c8f18f6cc018c4e372165b1fa8126cef092399c9951984ffa"
[[package]]
name = "linux-raw-sys"
@@ -923,7 +923,7 @@ dependencies = [
"proc-macro2",
"quote",
"regex-syntax",
"syn 2.0.79",
"syn 2.0.87",
]
[[package]]
@@ -973,7 +973,7 @@ checksum = "4edc8853320c2a0dab800fbda86253c8938f6ea88510dc92c5f1ed20e794afc1"
dependencies = [
"cfg-if",
"miette-derive",
"thiserror",
"thiserror 1.0.69",
"unicode-width",
]
@@ -985,7 +985,7 @@ checksum = "dcf09caffaac8068c346b6df2a7fc27a177fd20b39421a39ce0a211bde679a6c"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.79",
"syn 2.0.87",
]
[[package]]
@@ -1087,9 +1087,9 @@ checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39"
[[package]]
name = "passterm"
version = "2.0.3"
version = "2.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "eea7e8981bca32c52230ca5f28b080dd5f28aed618a7bd12b5a382b234cd2b99"
checksum = "d1e7a4c22a6cce262e8c126b3052e6baf05d4dd5699ef23ed6dadd85c2a1194a"
dependencies = [
"libc",
]
@@ -1153,7 +1153,7 @@ dependencies = [
"phf_shared",
"proc-macro2",
"quote",
"syn 2.0.79",
"syn 2.0.87",
]
[[package]]
@@ -1167,9 +1167,9 @@ dependencies = [
[[package]]
name = "pin-project-lite"
version = "0.2.14"
version = "0.2.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02"
checksum = "915a1e146535de9163f3987b8944ed8cf49a18bb0056bcebcdcece385cece4ff"
[[package]]
name = "pkcs1"
@@ -1226,19 +1226,19 @@ dependencies = [
[[package]]
name = "prettyplease"
version = "0.2.22"
version = "0.2.25"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "479cf940fbbb3426c32c5d5176f62ad57549a0bb84773423ba8be9d089f5faba"
checksum = "64d1ec885c64d0457d564db4ec299b2dae3f9c02808b8ad9c3a089c591b18033"
dependencies = [
"proc-macro2",
"syn 2.0.79",
"syn 2.0.87",
]
[[package]]
name = "proc-macro2"
version = "1.0.87"
version = "1.0.89"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b3e4daa0dcf6feba26f985457cdf104d4b4256fc5a09547140f3631bb076b19a"
checksum = "f139b0662de085916d1fb67d2b4169d1addddda1919e696f3252b740b629986e"
dependencies = [
"unicode-ident",
]
@@ -1270,7 +1270,7 @@ dependencies = [
"prost",
"prost-types",
"regex",
"syn 2.0.79",
"syn 2.0.87",
"tempfile",
]
@@ -1284,7 +1284,7 @@ dependencies = [
"itertools",
"proc-macro2",
"quote",
"syn 2.0.79",
"syn 2.0.87",
]
[[package]]
@@ -1321,7 +1321,7 @@ dependencies = [
"prost-reflect",
"prost-types",
"protox-parse",
"thiserror",
"thiserror 1.0.69",
]
[[package]]
@@ -1333,7 +1333,7 @@ dependencies = [
"logos",
"miette",
"prost-types",
"thiserror",
"thiserror 1.0.69",
]
[[package]]
@@ -1397,9 +1397,9 @@ dependencies = [
[[package]]
name = "regex"
version = "1.11.0"
version = "1.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "38200e5ee88914975b69f657f0801b6f6dccafd44fd9326302a4aaeecfacb1d8"
checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191"
dependencies = [
"aho-corasick",
"memchr",
@@ -1409,9 +1409,9 @@ dependencies = [
[[package]]
name = "regex-automata"
version = "0.4.8"
version = "0.4.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "368758f23274712b504848e9d5a6f010445cc8b87a7cdb4d7cbee666c1288da3"
checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908"
dependencies = [
"aho-corasick",
"memchr",
@@ -1472,9 +1472,9 @@ dependencies = [
[[package]]
name = "rustix"
version = "0.38.37"
version = "0.38.40"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8acb788b847c24f28525660c4d7758620a7210875711f79e7f663cc152726811"
checksum = "99e4ea3e1cdc4b559b8e5650f9c8e5998e3e5c1343b4eaf034565f32318d63c0"
dependencies = [
"bitflags",
"errno",
@@ -1513,22 +1513,22 @@ checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b"
[[package]]
name = "serde"
version = "1.0.210"
version = "1.0.215"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c8e3592472072e6e22e0a54d5904d9febf8508f65fb8552499a1abc7d1078c3a"
checksum = "6513c1ad0b11a9376da888e3e0baa0077f1aed55c17f50e7b2397136129fb88f"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_derive"
version = "1.0.210"
version = "1.0.215"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "243902eda00fad750862fc144cea25caca5e20d615af0a81bee94ca738f1df1f"
checksum = "ad1e866f866923f252f05c889987993144fb74e722403468a4ebd70c3cd756c0"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.79",
"syn 2.0.87",
]
[[package]]
@@ -1652,9 +1652,9 @@ dependencies = [
[[package]]
name = "syn"
version = "2.0.79"
version = "2.0.87"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "89132cd0bf050864e1d38dc3bbc07a0eb8e7530af26344d3d2bbbef83499f590"
checksum = "25aa4ce346d03a6dcd68dd8b4010bcb74e54e62c90c573f394c46eae99aba32d"
dependencies = [
"proc-macro2",
"quote",
@@ -1663,9 +1663,9 @@ dependencies = [
[[package]]
name = "tempfile"
version = "3.13.0"
version = "3.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f0f2c9fc62d0beef6951ccffd757e241266a2c833136efbe35af6cd2567dca5b"
checksum = "28cce251fcbc87fac86a866eeb0d6c2d536fc16d06f184bb61aeae11aa4cee0c"
dependencies = [
"cfg-if",
"fastrand",
@@ -1676,22 +1676,42 @@ dependencies = [
[[package]]
name = "thiserror"
version = "1.0.64"
version = "1.0.69"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d50af8abc119fb8bb6dbabcfa89656f46f84aa0ac7688088608076ad2b459a84"
checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52"
dependencies = [
"thiserror-impl",
"thiserror-impl 1.0.69",
]
[[package]]
name = "thiserror"
version = "2.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c006c85c7651b3cf2ada4584faa36773bd07bac24acfb39f3c431b36d7e667aa"
dependencies = [
"thiserror-impl 2.0.3",
]
[[package]]
name = "thiserror-impl"
version = "1.0.64"
version = "1.0.69"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "08904e7672f5eb876eaaf87e0ce17857500934f4981c4a0ab2b4aa98baac7fc3"
checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.79",
"syn 2.0.87",
]
[[package]]
name = "thiserror-impl"
version = "2.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f077553d607adc1caf65430528a576c757a71ed73944b66ebb58ef2bbd243568"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.87",
]
[[package]]
@@ -1731,7 +1751,7 @@ checksum = "8d9ef545650e79f30233c0003bcc2504d7efac6dad25fca40744de773fe2049c"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.79",
"syn 2.0.87",
]
[[package]]
@@ -1781,7 +1801,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.79",
"syn 2.0.87",
]
[[package]]
@@ -1861,9 +1881,9 @@ checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821"
[[package]]
name = "uuid"
version = "1.10.0"
version = "1.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "81dfa00651efa65069b0b6b651f4aaa31ba9e3c3ce0137aaad053604ee7e0314"
checksum = "f8c5f0a0af699448548ad1a2fbf920fb4bee257eae39953ba95cb84891a0446a"
dependencies = [
"getrandom",
]
@@ -2025,7 +2045,7 @@ dependencies = [
[[package]]
name = "xtask"
version = "3.8.0"
version = "3.9.0"
dependencies = [
"anyhow",
"clap",
@@ -2045,11 +2065,11 @@ dependencies = [
[[package]]
name = "zerocopy"
version = "0.8.5"
version = "0.8.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6129d25825e874589a0e529175dd060c13dab4f3d960c6a0b711e5535b598bb2"
checksum = "f49e690f8f352f4a9ee8679a8c5921f42ffd0d6d6413a0a66b8e81cf524e109c"
dependencies = [
"zerocopy-derive 0.8.5",
"zerocopy-derive 0.8.9",
]
[[package]]
@@ -2060,18 +2080,18 @@ checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.79",
"syn 2.0.87",
]
[[package]]
name = "zerocopy-derive"
version = "0.8.5"
version = "0.8.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d917df3784b4e2f5deb708d14623b2c02833890e1aa7a5dd1088998e8e9402b1"
checksum = "fa732fcc881df7a6fbe8e3ed17baadece53b379ad58fe2633396b1a2b108a7b1"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.79",
"syn 2.0.87",
]
[[package]]
@@ -2091,7 +2111,7 @@ checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.79",
"syn 2.0.87",
]
[[package]]
+1 -1
View File
@@ -4,7 +4,7 @@ members = ["avbroot", "e2e", "fuzz", "xtask"]
resolver = "2"
[workspace.package]
version = "3.8.0"
version = "3.9.0"
license = "GPL-3.0-only"
edition = "2021"
repository = "https://github.com/chenxiaolong/avbroot"
+6
View File
@@ -385,6 +385,12 @@ Note that avbroot will validate that the prepatched image is compatible with the
avbroot can be used for just re-signing an OTA by specifying `--rootless` instead of `--magisk`/`--prepatched`. With this option, the patched OTA will not be rooted. The only modification applied is the replacement of the OTA verification certificate so that the OS can be upgraded with future (patched) OTAs.
### Skipping recovery OTA certificate patches
avbroot can skip modifying `otacerts.zip` in the recovery image with the `--skip-recovery-ota-cert` option. **Do not do this unless you have a good reason to do so.** (For example, if you've already manually inserted the OTA certificate into a boot image specified with `--prepatched` or `--replace`.) When this option is used with `--rootless` (and `--dsu` is not specified), then no modifications are performed on any boot image besides ensuring they are properly signed.
When manually adding the OTA certificate to a boot image, [verifying the patched OTA](#verifying-otas) afterwards is recommended to ensure that it was properly done.
### Replacing partitions
avbroot supports replacing entire partitions in the OTA, even partitions that are not boot images (eg. `vendor_dlkm`). A partition can be replaced by passing in `--replace <partition name> /path/to/partition.img`.
+1 -1
View File
@@ -49,7 +49,7 @@ serde = { version = "1.0.188", features = ["derive"] }
sha1 = "0.10.5"
sha2 = "0.10.7"
tempfile = "3.8.0"
thiserror = "1.0.47"
thiserror = "2.0.3"
toml_edit = { version = "0.22.9", features = ["serde"] }
topological-sort = "0.2.2"
tracing = "0.1.40"
+3 -1
View File
@@ -398,7 +398,9 @@ fn sign_or_clear(info: &mut AvbInfo, orig_header: &Header, key_group: &KeyGroup)
RsaSigningKey::Internal(private_key)
};
info.header.set_algo_for_key(&signing_key)?;
info.header
.set_algo_for_key(&signing_key)
.context("Failed to set signature algorithm")?;
info.header
.sign(&signing_key)
.context("Failed to sign new AVB header")?;
+33 -5
View File
@@ -201,7 +201,7 @@ fn patch_boot_images<'a, 'b: 'a>(
let boot_partitions = required_images.iter_boot().collect::<Vec<_>>();
info!(
"Patching boot images: {}",
"Candidate boot images: {}",
joined(sorted(boot_partitions.iter())),
);
@@ -593,7 +593,9 @@ fn update_vbmeta_headers(
// have no dependencies and are only being processed to ensure that the
// flags are set to a sane value.
if parent_header != &orig_parent_header {
parent_header.set_algo_for_key(key)?;
parent_header
.set_algo_for_key(key)
.with_context(|| format!("Failed to set signature algorithm: {name}"))?;
parent_header
.sign(key)
.with_context(|| format!("Failed to sign vbmeta header for image: {name}"))?;
@@ -1304,7 +1306,11 @@ pub fn patch_subcommand(cli: &PatchCli, cancel_signal: &AtomicBool) -> Result<()
assert!(cli.root.rootless);
};
boot_patchers.push(Box::new(OtaCertPatcher::new(cert_ota.clone())));
if cli.skip_recovery_ota_cert {
warn!("Not inserting OTA cert into recovery image; sideloading further updates may fail");
} else {
boot_patchers.push(Box::new(OtaCertPatcher::new(cert_ota.clone())));
}
if cli.dsu {
boot_patchers.push(Box::new(DsuPubKeyPatcher::new(key_avb.to_public_key())));
@@ -1684,9 +1690,11 @@ pub fn verify_subcommand(cli: &VerifyCli, cancel_signal: &AtomicBool) -> Result<
verify_partition_hashes(&temp_dir, &header, &unique_images, cancel_signal)?;
info!("Checking ramdisk's otacerts.zip");
if cli.skip_recovery_ota_cert {
warn!("Not verifying recovery ramdisk's otacerts.zip");
} else {
info!("Checking recovery ramdisk's otacerts.zip");
{
let required_images = RequiredImages::new(&header.manifest);
let boot_images =
boot::load_boot_images(&required_images.iter_boot().collect::<Vec<_>>(), |name| {
@@ -1922,6 +1930,17 @@ pub struct PatchCli {
)]
pub ignore_prepatched_compat: u8,
/// Skip adding OTA certificate to recovery image.
///
/// DO NOT USE THIS unless you've manually added the certificate to the
/// recovery image already. Otherwise, sideloading further updates will not
/// be possible.
///
/// When this option is used with --rootless, the boot images in the OTA
/// will not be modified.
#[arg(long, help_heading = HEADING_OTHER)]
pub skip_recovery_ota_cert: bool,
/// Add AVB public key to trusted keys for DSU.
#[arg(long, help_heading = HEADING_OTHER)]
pub dsu: bool,
@@ -2008,6 +2027,15 @@ pub struct VerifyCli {
/// valid, not that they are trusted.
#[arg(long, value_name = "FILE", value_parser)]
pub public_key_avb: Option<PathBuf>,
/// Skip verifying OTA certificate in recovery image.
///
/// This should not be used unless the OTA uses a special boot image format
/// that avbroot cannot parse. This certificate check ensures that the OTA
/// is configured properly to allow sideloading further OTAs signed by the
/// same key.
#[arg(long, help_heading = HEADING_OTHER)]
pub skip_recovery_ota_cert: bool,
}
#[allow(clippy::large_enum_variant)]
+1 -1
View File
@@ -176,7 +176,7 @@ impl PassphraseSource {
}
Self::EnvVar(v) => env::var(v).map_err(|e| Error::InvalidEnvVar(v.clone(), e))?,
Self::File(p) => fs::read_to_string(p)?
.trim_end_matches(&['\r', '\n'])
.trim_end_matches(['\r', '\n'])
.to_owned(),
};
+1 -1
View File
@@ -101,7 +101,7 @@ pub enum Error {
UnsupportedAlgorithm(AlgorithmType),
#[error("Hashing algorithm not supported: {0:?}")]
UnsupportedHashAlgorithm(String),
#[error("Incorrect key size ({}) for algorithm {1:?}", .0 * 8)]
#[error("Incorrect key size ({bytes}) for algorithm {1:?}", bytes = .0 * 8)]
IncorrectKeySize(usize, AlgorithmType),
#[error("RSA key size ({}) is not compatible with any AVB signing algorithm", .0 * 8)]
UnsupportedKey(usize),
+1 -1
View File
@@ -50,7 +50,7 @@ pub enum Error {
UnknownMagic([u8; 6]),
#[error("Hard links are not supported: {:?}", .0.as_bstr())]
HardLinksNotSupported(Vec<u8>),
#[error("Entry of type {0} should not have data: {:?}", .1.as_bstr())]
#[error("Entry of type {0} should not have data: {path:?}", path = .1.as_bstr())]
EntryHasData(CpioEntryType, Vec<u8>),
#[error("No inodes available for device {0:x},{1:x}")]
DeviceFull(u32, u32),
+27 -10
View File
@@ -300,6 +300,7 @@ fn compute_property_files(
pf_name: &str,
entries: &[ZipEntry],
max_length: Option<usize>,
want_pb: bool,
) -> Result<String> {
let compute = |path: &'static str| -> Result<String> {
let entry = entries
@@ -334,10 +335,14 @@ fn compute_property_files(
if max_length.is_none() {
tokens.push(format!("metadata:{}", " ".repeat(15)));
tokens.push(format!("metadata.pb:{}", " ".repeat(15)));
if want_pb {
tokens.push(format!("metadata.pb:{}", " ".repeat(15)));
}
} else {
tokens.push(compute(PATH_METADATA)?);
tokens.push(compute(PATH_METADATA_PB)?);
if want_pb {
tokens.push(compute(PATH_METADATA_PB)?);
}
}
let mut joined = tokens.join(",");
@@ -415,7 +420,7 @@ pub fn add_metadata(
for pf in [PF_NAME, PF_STREAMING_NAME] {
metadata.property_files.insert(
pf.to_owned(),
compute_property_files(pf, &zip_entries, None)?,
compute_property_files(pf, &zip_entries, None, true)?,
);
}
@@ -452,7 +457,7 @@ pub fn add_metadata(
// Compute the final property files using the offsets of the fake entries.
for (key, value) in &mut metadata.property_files {
*value = compute_property_files(key, &zip_entries, Some(value.len()))?;
*value = compute_property_files(key, &zip_entries, Some(value.len()), true)?;
}
// Add the final metadata files to the real zip.
@@ -494,8 +499,11 @@ pub fn verify_metadata(
add_payload_metadata_entry(&mut zip_entries, payload_metadata_size)?;
let metadata_pb = zip_entries.iter().find(|e| e.name == PATH_METADATA_PB);
for (key, value) in &metadata.property_files {
let new_value = compute_property_files(key, &zip_entries, Some(value.len()))?;
let new_value =
compute_property_files(key, &zip_entries, Some(value.len()), metadata_pb.is_some())?;
if *value != new_value {
return Err(Error::MismatchedPropertyFiles {
expected: value.clone(),
@@ -627,11 +635,20 @@ pub fn parse_zip_ota_info(
) -> Result<(OtaMetadata, Certificate, PayloadHeader, String)> {
let mut zip = ZipArchive::new(reader)?;
let metadata = {
let mut entry = zip.by_name(PATH_METADATA_PB)?;
let mut buf = Vec::new();
entry.read_to_end(&mut buf)?;
OtaMetadata::decode(buf.as_slice())?
let metadata = match zip.by_name(PATH_METADATA_PB) {
Ok(mut entry) => {
let mut buf = Vec::new();
entry.read_to_end(&mut buf)?;
parse_protobuf_metadata(&buf)?
}
e @ Err(ZipError::FileNotFound) => {
drop(e);
let mut entry = zip.by_name(PATH_METADATA)?;
let mut buf = String::new();
entry.read_to_string(&mut buf)?;
parse_legacy_metadata(&buf)?
}
Err(e) => return Err(e.into()),
};
let certificate = {
+4 -4
View File
@@ -206,10 +206,10 @@ fn verify_digest(digest: &[u8], signatures: &Signatures, cert: &Certificate) ->
let Some(data) = &signature.data else {
continue;
};
let Some(size) = signature.unpadded_signature_size else {
continue;
};
let without_padding = &data[..size as usize];
let size = signature
.unpadded_signature_size
.map_or(data.len(), |s| s as usize);
let without_padding = &data[..size];
match public_key.verify_sig(SignatureAlgorithm::Sha256WithRsa, digest, without_padding) {
Ok(_) => return Ok(()),
+22 -5
View File
@@ -14,6 +14,8 @@ use thiserror::Error;
use zerocopy::{byteorder::little_endian, FromZeros, IntoBytes};
use zerocopy_derive::{FromBytes, Immutable, IntoBytes, KnownLayout, Unaligned};
use crate::stream::ReadDiscardExt;
/// Magic value for [`RawHeader::magic`].
const HEADER_MAGIC: u32 = 0xed26ff3a;
@@ -108,15 +110,17 @@ impl RawHeader {
)));
}
if self.file_hdr_sz.get() != mem::size_of::<RawHeader>() as u16 {
if self.file_hdr_sz.get() < mem::size_of::<RawHeader>() as u16 {
return Err(Error::Header(format!(
"Invalid file header size: {}",
"Invalid file header size: {} < {}",
self.file_hdr_sz.get(),
mem::size_of::<RawHeader>(),
)));
} else if self.chunk_hdr_sz.get() != mem::size_of::<RawChunk>() as u16 {
} else if self.chunk_hdr_sz.get() < mem::size_of::<RawChunk>() as u16 {
return Err(Error::Header(format!(
"Invalid chunk header size: {}",
"Invalid chunk header size: {} < {}",
self.chunk_hdr_sz.get(),
mem::size_of::<RawChunk>(),
)));
}
@@ -129,6 +133,14 @@ impl RawHeader {
Ok(())
}
fn excess_raw_header_bytes(&self) -> u16 {
self.file_hdr_sz.get() - mem::size_of::<RawHeader>() as u16
}
fn excess_raw_chunk_bytes(&self) -> u16 {
self.chunk_hdr_sz.get() - mem::size_of::<RawChunk>() as u16
}
}
/// Raw on-disk layout for the chunk header.
@@ -180,7 +192,7 @@ impl RawChunk {
};
data_size
.checked_add(mem::size_of::<Self>() as u32)
.checked_add(header.chunk_hdr_sz.into())
.ok_or_else(|| Error::Chunk(index, format!("Data size too large: {data_size}")))
}
@@ -662,6 +674,8 @@ impl<R: Read> SparseReader<R> {
header.validate()?;
inner.read_discard(header.excess_raw_header_bytes().into())?;
Ok(Self {
inner,
seek: None,
@@ -724,6 +738,9 @@ impl<R: Read> SparseReader<R> {
raw_chunk.validate(self.chunk, &self.header, self.block)?;
self.inner
.read_discard(self.header.excess_raw_chunk_bytes().into())?;
let data: ChunkData;
match raw_chunk.chunk_type.get() {
+5
View File
@@ -1134,6 +1134,11 @@ pub fn patch_boot_images<'a>(
) -> Result<HashSet<&'a str>> {
let parent_span = Span::current();
if patchers.is_empty() {
debug!("Skip loading boot images; nothing to patch");
return Ok(HashSet::new());
}
// Preparse all images. Some patchers need to inspect every candidate.
let mut images = load_boot_images(names, open_input)?;