How Magisk Handles Boot Image Signing and Verification (AVB/VBMeta)

Magisk processes Android Verified Boot by distinguishing between two AVB generations: AVB 1.0 (legacy tail signatures) which it verifies and re-signs using RSA/ECDSA keys, and AVB 2.0 (VBMeta structures) which it preserves without re-signing while optionally disabling verification flags.

Magisk, the open-source rooting solution maintained by topjohnwu, must modify boot images while maintaining the cryptographic structures required by Android Verified Boot. The implementation in native/src/boot/sign.rs and native/src/boot/bootimg.cpp handles both legacy AVB 1.0 signatures and modern AVB 2.0 VBMeta containers to ensure patched images pass bootloader checks.

AVB 1.0 Legacy Signature Verification and Signing

Magisk detects AVB 1.0 through a specific footer magic and manages the complete lifecycle of signature verification and re-signing after payload modification.

Detecting AVB 1.0 Signatures

When parsing a boot image, BootImage::verify() inspects the image tail for the "AVB0" magic string. In sign.rs, the detection logic checks the tail bytes:

let tail = self.tail();
if tail.starts_with(b"AVB0") { return log_err!(); }

This detection triggers the AVB1_SIGNED_FLAG in the boot image structure, signaling that the payload requires cryptographic handling throughout the patching process.

Signature Verification Process

The verification routine decodes the tail as a DER-encoded BootSignature structure. Magisk recomputes the payload hash and validates it against the stored signature using the certificate's public key. According to the source code in sign.rs, the verify() function performs this cryptographic check between lines 48-64, ensuring image integrity before modifications proceed.

Re-signing Modified Boot Images

After injecting Magisk binaries into the payload, Magisk must re-sign the image to maintain verification compatibility. The sign_boot_image() function in sign.rs (lines 107-138) builds a new BootSignature structure, signs the payload plus authenticated attributes with a private key (defaulting to the bundled verity key), and appends the DER-encoded signature to the image tail.

In bootimg.cpp, the re-signing step triggers when the AVB1_SIGNED_FLAG is present:

if (boot.flags[AVB1_SIGNED_FLAG]) {
    byte_view payload(...);
    auto sig = sign_payload(payload);
    …
}

This ensures that devices enforcing AVB 1.0 will accept the modified image as properly signed.

AVB 2.0 VBMeta Structure Handling

Modern Android devices use AVB 2.0, which stores verification metadata in VBMeta structures referenced by a footer. Magisk handles these differently, preserving existing signatures rather than generating new ones.

Magisk examines the final 64 bytes of the boot image for the "AVBf" magic identifying an AvbFooter. In bootimg.cpp (lines 95-99), the detection logic locates the footer:

const void *footer = tail.data() + tail.size() - sizeof(AvbFooter);
if (BUFFER_MATCH(footer, AVB_FOOTER_MAGIC)) { … }

The footer contains the offset to the VBMeta image. Magisk validates the VBMeta header by checking for "AVB0" magic at the calculated offset (lines 100-103), setting the AVB_FLAG when valid VBMeta structures are found.

Preserving Verification Metadata During Repack

Unlike AVB 1.0, Magisk does not generate new VBMeta signatures because AVB 2.0 relies on the OEM-signed VBMeta image itself. Instead, the repack routine in bootimg.cpp (lines 16-26) copies the original AVB footer verbatim and updates size-dependent fields:

if (boot.flags[AVB_FLAG]) {
    memcpy(footer, boot.avb_footer, sizeof(AvbFooter));
    footer->original_image_size = __builtin_bswap64(aosp_img_size);
    footer->vbmeta_offset = __builtin_bswap64(off.vbmeta);
}

This preserves the original cryptographic signatures while adjusting for the new image geometry.

Disabling Verification with PATCHVBMETAFLAG

Magisk provides an optional bypass mechanism through the PATCHVBMETAFLAG environment variable. When set, Magisk patches the VBMeta flags to 3, which disables both the hash tree and verification checks. This allows modified images to boot on devices that would otherwise reject unsigned or modified boot partitions.

Complete Boot Image Processing Workflow

The full lifecycle for handling verified boot images follows this structured flow:

  1. Parse and detect → Identify AVB 1.0 (AVB1_SIGNED_FLAG) or AVB 2.0 (AVB_FLAG) signatures during initial boot image parsing
  2. Verify AVB 1.0 → Validate legacy signatures via BootSignature::verify() before allowing modifications
  3. Modify payload → Inject Magisk binaries and adjust image structures as needed
  4. Repack with metadata → Copy original AVB footers and VBMeta structures for AVB 2.0 images
  5. Re-sign if required → Generate new RSA/ECDSA signatures for AVB 1.0 images using sign_boot_image()
  6. Output final image → Write the patched image with all verification structures intact or updated

Summary

  • Magisk distinguishes AVB 1.0 (detected via "AVB0" tail magic) from AVB 2.0 (detected via "AVBf" footer magic) using logic in bootimg.cpp
  • AVB 1.0 images undergo full cryptographic verification and re-signing via sign.rs, using bundled or user-supplied keys
  • AVB 2.0 structures are preserved but not re-signed; Magisk updates original_image_size and vbmeta_offset while keeping OEM signatures intact
  • The PATCHVBMETAFLAG environment variable forces VBMeta flags to 3, disabling hash tree verification when required
  • Core implementation spans native/src/boot/sign.rs for cryptographic operations and native/src/boot/bootimg.cpp for image parsing and repacking

Frequently Asked Questions

What is the difference between AVB 1.0 and AVB 2.0 handling in Magisk?

AVB 1.0 uses tail-based RSA/ECDSA signatures that Magisk verifies and regenerates after modifications, while AVB 2.0 uses embedded VBMeta structures that Magisk preserves without re-signing. AVB 1.0 requires the AVB1_SIGNED_FLAG and calls sign_boot_image(), whereas AVB 2.0 only requires updating footer offsets and optionally patching flags.

Can I use custom keys to sign boot images with Magisk?

Yes. The sign_boot_image() function in sign.rs accepts custom private key parameters, defaulting to the bundled verity.pk8 test key only when no alternative is provided. You can supply your own keys during the signing process to match device-specific verification requirements.

What does the PATCHVBMETAFLAG environment variable do?

When PATCHVBMETAFLAG is set in the environment, Magisk modifies the VBMeta flags field to value 3 during repacking. This disables both the dm-verity hash tree and the verification process, allowing modified boot images to bypass strict AVB 2.0 checks on devices that enforce verified boot.

Why doesn't Magisk re-sign AVB 2.0 images?

AVB 2.0 relies on the VBMeta image itself being signed by the OEM's private keys, which Magisk does not possess. Instead of generating invalid signatures, Magisk preserves the original VBMeta structures and updates only the size-related metadata fields. This approach maintains the cryptographic chain of trust while allowing payload modifications.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →