How To Guide Guide to Lock Bootloader while using Rooted GrapheneOS (Magisk Root)

Search This thread

FireRattus

Senior Member
Feb 26, 2022
184
124
I did this on my pixel 7, shouldnt be a problem ig, but can't relock my bootloader with error message "FAILED (remote: 'invalid android images, skip locking')".
Anyone have any idea why this happens, because im able to boot into the system without any problems.
Update: found the error, forgot something ;)
What steps did you take exactly? it sounds like you didn't properly sign the OTA with AVBRoot, didn't flash the new AVB Key or didn't properly flash the new OTA
 

baraasoliman

Member
Mar 4, 2023
7
0
On a Pixel 4a5G. using the Graphene OS = factory-2023020200, ota_update-2023030400. Magisk = v25.2 (25200)

I got it working after much frustration. Thanks for your instructions.
What version of Magisk are you using? @FireRattus

I ran AVBroot in a virtual machine to get all the files I needed. Just follow steps 1-5,7 from https://github.com/chenxiaolong/avbroot

For whatever reason my environment variables didnt work out, so I used the local command invoke of fastboot and adb.


My process to help others:

First get to the fastboot menu by turning on the phone while holding the Vol down button.

.\fastboot flashing unlock

.\fastboot erase apdp_a
.\fastboot erase apdp_b
.\fastboot snapshot-update cancel

.\fastboot flash --slot=other bootloader .\Pixel_bramble\bramble-factory-2023020200\bootloader-bramble-b5-0.5-9150480.img
.\fastboot --set-active=other
.\fastboot reboot-bootloader
ping -n 5 127.0.0.1 >nul

.\fastboot flash --slot=other bootloader .\Pixel_bramble\bramble-factory-2023020200\bootloader-bramble-b5-0.5-9150480.img
.\fastboot --set-active=other
.\fastboot reboot-bootloader
ping -n 5 127.0.0.1 >nul

.\fastboot flash radio .\Pixel_bramble\bramble-factory-2023020200\radio-bramble-g7250-00220-221017-b-9183951.img
.\fastboot --set-active=other
.\fastboot reboot-bootloader
ping -n 5 127.0.0.1 >nul

.\fastboot flash radio .\Pixel_bramble\bramble-factory-2023020200\radio-bramble-g7250-00220-221017-b-9183951.img
.\fastboot --set-active=other
.\fastboot reboot-bootloader
ping -n 5 127.0.0.1 >nul

.\fastboot erase avb_custom_key
.\fastboot flash avb_custom_key .\Pixel_bramble\bramble-factory-2023020200\avb_pkmd.bin
.\fastboot reboot-bootloader
ping -n 5 127.0.0.1 >nul

.\fastboot oem uart disable
.\fastboot erase apdp_a
.\fastboot erase apdp_b
.\fastboot snapshot-update cancel

.\fastboot -w --skip-reboot update .\Pixel_bramble\bramble-factory-2023020200\image-bramble-2023020200.zip
.\fastboot reboot-bootloader
ping -n 5 127.0.0.1 >nul

echo Factory Image flashing complete
echo Press any key to continue...
pause >nul

.\fastboot flash --slot=other boot ".\Pixel_bramble\AVB Bramble\boot.img"
.\fastboot --set-active=other
.\fastboot reboot-bootloader
ping -n 5 127.0.0.1 >nul

.\fastboot flash --slot=other boot ".\Pixel_bramble\AVB Bramble\boot.img"
.\fastboot --set-active=other
.\fastboot reboot-bootloader
ping -n 5 127.0.0.1 >nul

.\fastboot flash --slot=other vbmeta ".\Pixel_bramble\AVB Bramble\vbmeta.img"
.\fastboot --set-active=other
.\fastboot reboot-bootloader
ping -n 5 127.0.0.1 >nul

.\fastboot flash --slot=other vbmeta ".\Pixel_bramble\AVB Bramble\vbmeta.img"
.\fastboot --set-active=other
.\fastboot reboot-bootloader
ping -n 5 127.0.0.1 >nul

.\fastboot flash --slot=other vendor_boot ".\Pixel_bramble\AVB Bramble\vendor_boot.img"
.\fastboot --set-active=other
.\fastboot reboot-bootloader
ping -n 5 127.0.0.1 >nul

.\fastboot flash --slot=other vendor_boot ".\Pixel_bramble\AVB Bramble\vendor_boot.img"
.\fastboot --set-active=other
.\fastboot reboot-bootloader
ping -n 5 127.0.0.1 >nul

.\fastboot erase avb_custom_key
.\fastboot flash avb_custom_key ".\Pixel_bramble\AVB Bramble\avb_pkmd.bin"
.\fastboot reboot-bootloader
ping -n 5 127.0.0.1 >nul

echo Custom Keys flashing complete
echo Enable sideloading in recovery mode using PWR + Volup
echo Press any key to continue...
pause >nul

Use the Vol up to select recovery, then use the PWR button to select.
After the Android man has his guts exposed, hit the PWR + Vol up to expose commands.
select apply update from ADB using Vol down and then PWR.

.\adb sideload ".\Pixel_bramble\bramble-GOS-ota_update-2023030400patched.zip"
.\fastboot reboot-bootloader

If the phone displays "Install from ADB completed with status 0" then it worked.
reboot the phone to fastboot again. then lock the bootloader.

.\fastboot flashing lock

After you boot into the phone, before connecting to wifi, disable auto system updates using developer mode, and disable app updates in the APPS app manager. Install the Magisk app, open the app, and hit OK to complete the setup.
If at that point you can reboot/boot into the OS you have a rooted phone with a locked bootloader.

PS: I took most of these commands from the Graphene OS installer flash-all.bat if you have a different phone.
how did you generate the key and were you on linux or windows thx
 

i_bl00dy

Member
Feb 7, 2023
13
6
Google Pixel 4a 5G
how did you generate the key and were you on linux or windows thx
I just made a new VM using ubuntu 22.04 @baraasoliman


Code:
sudo apt install openssl python3-lz4 python3-protobuf
sudo apt install adb fastboot
sudo usermod -aG plugdev $LOGNAME
reboot

mkdir AVB_dir
cd AVB_dir

openssl genrsa 4096 | openssl pkcs8 -topk8 -scrypt -out avb.key
openssl genrsa 4096 | openssl pkcs8 -topk8 -scrypt -out ota.key
git clone --recursive https://github.com/chenxiaolong/avbroot.git

python3 avbroot/external/avb/avbtool.py extract_public_key --key avb.key --output avb_pkmd.bin

openssl req -new -x509 -sha256 -key ota.key -out ota.crt -days 10000 -subj '/CN=OTA/'

python3 avbroot/avbroot.py \
    patch \
    --input bramble-ota_update-2023030400.zip \
    --privkey-avb avb.key \
    --privkey-ota ota.key \
    --cert-ota ota.crt \
    --magisk Magisk.apk

python3 avbroot/avbroot.py \
    extract \
    --input bramble-ota_update-2023030400.zip.patched \
    --directory extracted

move files and adapt as needed
see https://github.com/chenxiaolong/avbroot for details
 

EggZenBeanz

Senior Member
Jul 21, 2005
304
96
I've fallen at the first hurdle!

Struggling with the Python part. I have the dependencies installed and confirmed with running --version. Whenever I call the avbroot.py I get these errors.

Code:
Traceback (most recent call last):
  File "/home/marki/avbroot/avbroot.py", line 3, in <module>
    from avbroot import main
  File "/home/marki/avbroot/avbroot/main.py", line 13, in <module>
    from . import boot
  File "/home/marki/avbroot/avbroot/boot.py", line 14, in <module>
    from .formats import compression
  File "/home/marki/avbroot/avbroot/formats/compression.py", line 5, in <module>
    import lz4.block
  File "/usr/lib/python3/dist-packages/lz4/__init__.py", line 17, in <module>
    from ._version import (  # noqa: F401
ModuleNotFoundError: No module named 'lz4._version'

--versions:

Python 3.11.2

*** LZ4 command line interface 64-bits v1.9.2, by Yann Collet ***
 

FireRattus

Senior Member
Feb 26, 2022
184
124
I've fallen at the first hurdle!

Struggling with the Python part. I have the dependencies installed and confirmed with running --version. Whenever I call the avbroot.py I get these errors.

--versions:

Python 3.11.2

*** LZ4 command line interface 64-bits v1.9.2, by Yann Collet ***
Have you followed the instructions on the AVBRoot page? what command are you trying to run exactly?
 

EggZenBeanz

Senior Member
Jul 21, 2005
304
96
Have you followed the instructions on the AVBRoot page? what command are you trying to run exactly?

Thank you for the reply. I've scrubbed my system and python is working as expected.

I have a question regards RULESDEVICE=<ID>

I have run python3 avbroot.py magisk-info --image /home/marki/android/pixel3/magisk_patched-25200_nBkMT.img

The output is
Code:
KEEPVERITY=true
KEEPFORCEENCRYPT=true
PATCHVBMETAFLAG=false
RECOVERYMODE=false
SHA1=3d8bc4d2a114fc9f4d554420b00f99834f5919c4

But I do not see any RULESDEVICE=<ID> in the output
 
Last edited:

i_bl00dy

Member
Feb 7, 2023
13
6
Google Pixel 4a 5G
But I do not see any RULESDEVICE=<ID> in the output
from https://github.com/chenxiaolong/avbroot:
Magisk versions 25207 and newer require the device ID for a writable partition that is used to store custom SELinux rules. This can only be determined on a real device, so avbroot requires the device ID to be specified via --magisk-rules-device <ID>

The latest release of Magisk is 25200 (v25.2), so the 25207 version referenced is only a prerelease/beta. It will only become relevant if you want to use the latest version of Magisk whenever they release the next version.

I used Magisk 25200 (v25.2) and did not have to do anything with the device ID and root works as expected @EggZenBeanz
 
  • Like
Reactions: FireRattus

EggZenBeanz

Senior Member
Jul 21, 2005
304
96
from https://github.com/chenxiaolong/avbroot:


The latest release of Magisk is 25200 (v25.2), so the 25207 version referenced is only a prerelease/beta. It will only become relevant if you want to use the latest version of Magisk whenever they release the next version.

I used Magisk 25200 (v25.2) and did not have to do anything with the device ID and root works as expected @EggZenBeanz
Ah yes I see now, 25207. Thank you. I'm up and running with guide on a pixel 6a. Thank you @i_bl00dy and @FireRattus
 
  • Like
Reactions: FireRattus
Jan 19, 2023
6
7
UPDATED to latest and minimal release of Ubuntu (small footprint) and latest avbroot tool version (many bug-fixes and improvements)

I've made linux virtual machine for VirtualBox 7.0 in OVA format, so you may use tool on any host OS supported by VirtualBox and have guaranteed working environment without messing host system with all of these dependencies and complex development stuff.
[Download link]
Also I've written instruction how I've "built" this VM "from sources", so you may reproduce it and get trusted one. :)

Login credentials: user 'ubuntu' and password 'ubuntu' (may be connected by ssh via network - don't forget setup networking in VM settings and virtualbox/host).
It's based on Ubuntu 22.10 Minimal cloud image with avbroot tool sourced from git repository (commit 0fff7b77dd284e99da4282a5c12a8aab802480f0) and placed in ~/avbroot directory.

Follow instructions in avbroot README.md while skipping 'Installing dependencies' section, 'Usage' steps 2,3 and replacing python ... invokations with python3 .... To access host file system add VM shared folder (with auto-mount checked, empty mount point). Files in folder path are accessed with prefix /media/sf_<folder_name>/ from guest.

Example usage (when files are located at '/home/artem/Documents' directory on Linux host and shared folder with path '/home/artem' and name 'artem' added to VM):
Code:
cd ~/avbroot
python3 avbroot.py patch --input /media/sf_artem/Documents/bluejay-ota-tq1a.230105.001.a2-deb3f832.zip --privkey-avb /media/sf_artem/Documents/avb.key --privkey-ota /media/sf_artem/Documents/ota.key --cert-ota /media/sf_artem/Documents/ota.crt --magisk /media/sf_artem/Documents/Magisk-v25.2.apk

Notes:
  • I've did my best to achieve as small footprint as possible. Imported VM takes up ~1.0GB on hard drive right after importing. After full cycle of working with Google Pixel 6a stock OTA VM growed up to ~1.2GB due to temporary files created during process. Size may vary depending on OTA files used. (You may try to use separate VM shared folder to place guest temporary dir on host.)
  • Don't decrease VM RAM to 512MB. I've tried - it's a devil. Because it looks like everyting working ok, but you may not notice that some procedure within script executing failed (due to memory allocation error), but script didn't aborted and just resulted in wrong content in generated output, so you may face this problem later (to be found at very end after flashing, etc... - rooting not working or something like that).
  • You may change disk medium type to immutable (in virtualbox media manager) which makes VM to automatically reset to initial state and size on each power on (i.e. loosing all system changes you made and data inside VM since point, at which you changed type). Note, that it happens at power ON, not off! It's convenient as long as you keep all your data on host and using VM only as execution environment.
  • By default VM isn't connected to any network. You may enable network adapter in VM settings to access internet from guest or work via ssh. If you select NAT network, then it already contains port forwarding rule on 2222 tcp port for ssh'ing, but you may need to change guest IP in rule to match address, actually assigned by vbox to your VM instance in your setup (login to started guest, type ifconfig and find address of form '10.0.X.X' in command output). On linux host connect from terminal using command ssh -p 2222 [email protected].
 
Last edited:

holofractal

Senior Member
Jan 30, 2016
427
228
FYI you need to update avbroot and use flag

--magisk-preinit-device <name>

To get magisk to work with at least 2023-04 release.
 
  • Like
Reactions: FireRattus

FireRattus

Senior Member
Feb 26, 2022
184
124
FYI you need to update avbroot and use flag

--magisk-preinit-device <name>

To get magisk to work with at least 2023-04 release.
and the preinit device name for the Pixel 6 Pro, for GrapheneOS at least is metadata
If anyone could please share the correct preinit device name for the Pixel 6 that would be appreciated
I know when this was released initially one couldn't pass device integrity checks for Google. Is that still the case? Can we yet achieve both basic and CTS profile, at least?
This hasn't changed, it's mostly an issue that Graphene isn't going to fix
hopefully a solution like the universal safetynet fix will be updated to work with Graphene
 
  • Like
Reactions: rhetorician

i_bl00dy

Member
Feb 7, 2023
13
6
Google Pixel 4a 5G
I will post an update since I ran into a problem.

PSA: preinit device name for the Pixel 4a5g with Graphene OS is also "metadata".

I was originally on Slot a with GOS ota_update-2023030400 with Magisk 25200.
I tried to update to GOS ota_update-2023040400 with Magisk 26100 but the update initially failed (bootloop after Graphene logo but before where it should be optimizing apps) and rolled back to Slot a.
So I disabled all my Magisk Modules (Hosts for Adblock, DisableFlagSecure, Zygisk, and Enforce Deny List [USN 2.4.0 was disabled during all of this]), this enabled me to update Slot b to GOS ota_update-2023040400 with Magisk 26100 . and all was well...

Then I enabled all my module and got stuck in a bootloop. so this is where all my problems began.
With a locked bootloader, I couldnt just switch back to Slot a. so I tried to flash Slot a with GOS ota_update-2023030400 with Magisk 25200 to force the phone to boot from Slot a, but that was a no go since the GOS recovery considered it a downgrade and blocked the OTA.

OK, I thought this cant be an uncommon problem with modules causing a bootloop. So the next step was to somehow disable all the modules on load... Magisk disables module loading on next launch if the the phone enters SafeMode. Well turns out I dont think GOS has a safemode, cause the key combo doesnt seem to do anything, and I couldnt find any reference to Safe Mode on their website either.

What about just telling magisk to not load the modules manually...
well the ADB shell method was out because I hadnt enabled SU in the shell beforehand (and I dont know if I feel comfortable leaving shell with root access during normal use anyway).

Fine, I guess I need a way to enable USB debugging...
So I ended up flashing GOS ota_update-2023040400 without Magisk to Slot a (still self signed). This did boot, but without root obviously. I enabled USB debugging. Then I tried to update slot b with GOS ota_update-2023040400 with Magisk 26100 again. and run
Code:
./adb wait-for-device shell magisk --remove-modules
that just seemed to crash the phone faster... (after Google logo, before Graphene logo)

there does seem to be a small window where USB debugging is enabled before it crashes, I might try "./adb wait-for-device shell magisk --remove-modules" during that window manually...

The way I see it I have 4 possible routes left...
1. keep using the phone without root (not preferred)
2. somehow find a magisk apk that doesnt load modules (idk about this one, might feature request...)
3. build graphene OS from source (Target 2023030400 but change the number during build to 2023040400 to trick the recovery )
3a. see if there is a way to change the build number of the ota_update-2023030400 to ota_update-2023040400 to trick the recovery
4. nuke the phone and start over...

This is not my main phone, just an experiment, but this deadlock is annoying....

Im going to be busy for the next month, so I wont have time to play around with this for a while.
Any advice you guys could think of would be appreciated.
 

i_bl00dy

Member
Feb 7, 2023
13
6
Google Pixel 4a 5G
EDIT: I have misread the posts linked... I downloaded the apk from the post. I dont know if I will have time to try it before I leave for my vacation.

Try the modded Magisk from
This post

https://github.com/Magisk-Modules-Alt-Repo/HuskyDG_BootloopSaver

seems like the git repo is dead, any chance you have a copy squirreled away?

alternatively, seems like building a new Magisk APK would be the easiest solution compared to building GOS

https://github.com/topjohnwu/Magisk/issues/6301#issuecomment-1265164036

Code:
index 7a269336e..998fad6a5 100644
--- a/native/src/core/module.cpp
+++ b/native/src/core/module.cpp
@@ -587,6 +587,7 @@ void magic_mount() {
 
     char buf[4096];
     LOGI("* Loading modules\n");
+    /*
     for (const auto &m : *module_list) {
         const char *module = m.name.data();
         char *b = buf + sprintf(buf, "%s/" MODULEMNT "/%s/", MAGISKTMP.data(), module);
@@ -614,6 +615,7 @@ void magic_mount() {
         system->collect_files(module, fd);
         close(fd);
     }
+    */
     if (MAGISKTMP != "/sbin") {
         // Need to inject our binaries into /system/bin
         inject_magisk_bins(system);
diff --git a/native/src/zygisk/main.cpp b/native/src/zygisk/main.cpp
index 58200df3f..9398bf493 100644
--- a/native/src/zygisk/main.cpp
+++ b/native/src/zygisk/main.cpp
@@ -123,6 +123,7 @@ static void zygiskd(int socket) {
     // Load modules
     using comp_entry = void(*)(int);
     vector<comp_entry> modules;
+    /*
     {
         vector<int> module_fds = recv_fds(socket);
         for (int fd : module_fds) {
@@ -139,10 +140,11 @@ static void zygiskd(int socket) {
                     LOGW("Failed to dlopen zygisk module: %s\n", dlerror());
                 }
             }
-            modules.push_back(entry);
+            // modules.push_back(entry);
             close(fd);
         }
     }
+    */
 
     // ack
     write_int(socket, 0);
 
Last edited:

FireRattus

Senior Member
Feb 26, 2022
184
124
This is not my main phone, just an experiment, but this deadlock is annoying....

Im going to be busy for the next month, so I wont have time to play around with this for a while.
Any advice you guys could think of would be appreciated.
You could try patching the latest OTA update using AVBRoot but with the older Magisk 25.2
Or at least when Graphene releases a new build then that will have a greater build number
 

i_bl00dy

Member
Feb 7, 2023
13
6
Google Pixel 4a 5G
@FireRattus

I tried Flashing ota_update-2023040400 with Magisk 25200 before I disabled the Magisk Modules. The phone crashed after the Graphene logo during that attempt as well. so I suspect If I flash it again, now that I have reenabled the Magisk modules, that I will see the same behavior.

Or at least when Graphene releases a new build then that will have a greater build number

The Graphene OS Recovery doesnt seem to have a problem letting you flash (sideload) an equivalent OTA.
When I was on Slot b with ota_update-2023040400 with Magisk 26100 (bootlooping), it let me flash ota_update-2023040400 without Magisk. and then when I was on Slot a with ota_update-2023040400 without Magisk it let me flash ota_update-2023040400 with Magisk 26100 to Slot b (flashing an OTA is the only way I know of to force it to boot to the other slot)
 
  • Like
Reactions: FireRattus

i_bl00dy

Member
Feb 7, 2023
13
6
Google Pixel 4a 5G
Thanks @shoey63 for the link, the Magisk_NoMod (25203) worked like a charm.

Graphene OS does have a SafeMode, you have to press the Down Vol button after the Google logo, during the Graphene logo. I cant reproduce the bootloop at the moment to confirm that getting into safemode will disable the Magisk modules on next boot.

Comparing notes with @FireRattus, the module at fault was DisableFlagSecure. I disabled the module and booted with Magisk enabled no problem. After removing the module and reinstalling it, DisableFlagSecure works again, seems like the module recompiles a few system pieces on install, and that wasnt playing nice after an update.
 

Top Liked Posts

  • There are no posts matching your filters.
  • 4
    Thanks for the guide!

    I'm using an alternative method after building GrapheneOS from source, though. In fact you can simply use the following commands right after the build process:

    Bash:
    AVBROOT=/path/to/avbroot.py
    MAGISK=/path/to/Magisk-v26.1.apk
    MAGISK_PREINIT_DEVICE=persist
    cd $ANDROID_BUILD_TOP
    if [ ! -f keys/$TARGET_PRODUCT/releasekey.pem ] ; then openssl pkcs8 -topk8 -inform DER -in keys/$TARGET_PRODUCT/releasekey.pk8 -out keys/$TARGET_PRODUCT/releasekey.pem ; fi
    python $AVBROOT patch \
        --input out/release-$TARGET_PRODUCT-$BUILD_NUMBER/$TARGET_PRODUCT-ota_update-$BUILD_NUMBER.zip \
        --privkey-avb keys/$TARGET_PRODUCT/avb.pem \
        --privkey-ota keys/$TARGET_PRODUCT/releasekey.pem \
        --cert-ota keys/$TARGET_PRODUCT/releasekey.x509.pem \
        --magisk $MAGISK \
        --magisk-preinit-device=$MAGISK_PREINIT_DEVICE

    Just be sure to set valid values for AVBROOT, MAGISK and MAGISK_PREINIT_DEVICE. (See Magisk preinit device section for details on how to get the correct name of your preinit-device. For my Pixel 7 Pro it's "persist", but for your's it can be different).

    If you didn't just finish the build process, you need to set up your environment variables first (just set DEVICE to the codename of your device):
    Bash:
    DEVICE=cheetah
    cd /path/to/android-build-top
    source script/envsetup.sh
    choosecombo release $DEVICE user

    The big advantage of this method is, that no new keys need to be generated, but the build keys are used. That means you can switch between the original and rooted OTAs on the fly without having to unlock the bootloader. So you can even keep the bootloader locked (and thus avoid wiping your data) even if you never used Magisk before.
    1
    So is the preint device name different for each rom?

    Its not likely to be different from phone to phone using the same ROM, but different ROMs have the potential to use different values, so it must be checked on each phone individually. This is also because android phones have a large variety of hardware, and magisk aims to support as many of them as they can .

    I'm currently using this method on CalxysOS but unable to update to magisk 26 as I have no way to get the the preint deivce name with current 25.2 and locked bootloader.

    Read full documentation here on how to get it: avbroot#magisk-preinit-device

    TLDR:
    Extract boot.img from OTA update zip
    Copy boot.img from computer to phone
    Install Magisk V26.1.apk on phone (just runs as app, not root)
    Patch the boot.img from the magisk app on phone
    Copy the resulting magisk_patched-26100.img from phone to computer
    Run the command "python3 avbroot.py magisk-info --image magisk_patched-26100.img" to get the PREINITDEVICE=<name>

    Anybody get LSposed working on GRaphene OS yet?
    I got the module to install and run. I see the LSposed notification to install the manager, but clicking the notification does nothing. I manually installed the LSposed manager app, but it cant see the LSposed daemon running.

    I probably will wave to abandon the LSposed idea since Graphene OS is significantly different from regular AOSP ROMs, but I was hoping to mess with the Notification panel a bit.
    1
    I've recently patched Android Auto into my GrapheneOs build. Furthermore the patch bypasses a behaviour change of Android 13 that made Screen2Auto crash when starting some apps. Last but not least, my changes enable mirroring of Netflix and other media apps. It doesn't require root.
    This is what I did: https://gist.github.com/sn-00-x/9bd0b0143139c7efdae5507ad845ed86
    2
    @PiXinCreate do you run the official GrapheneOS images? Then you definitely have to unlock the bootloader and thus wipe your data.
    If you built the rom yourself, you could simply use your existing signing key to sign a patched init_boot image without having to wipe (but you'd have to do it like I described a few posts ago and not follow the thread's howto guide).
    Without root, you should be able to get a yellow state in PIA. I didn't try with root, yet or if USNF with MagiskHide work. It may, or may not, I don't know and didn't bothered trying, cause my goal is to patch everything I need directly into the rom without requiring Magisk and only flash a patched init_boot img in an emergency.
    What definitely doesn't work in GrapheneOS is LSPosed and therefor Shamiko can't be enabled.
    1
    The SafetyNet Patch 2.4.0-mod_1.2 by Displax allows my device (Pixel 4a5G) with graphene OS to pass the Safetynet BASIC, where without the patch even the BASIC would fail. The CTS profile match is still a fail (probably why citi doesnt work)


    Play Integrity on my Device doesn't work at all.

    Something to keep in mind is that Google is in the process of deprecating Safetynet. Timeline So I hope that the Custom Rom/Android Devs can come up with a way to at least pass PI MEETS_BASIC_INTEGRITY in the next year...

    Compare Safety Net vs Play Integrity
    Thanks

    I ran GrapheneOS for some time. It always passed basic and never device out of the box. Installing the displax module broke basic for me.

    The module needs to be adapted for GrapheneOS or you bake it in from source wit some tweaks.
  • 13
    This guide is intended to help people to achieve having a Pixel 6 Pro using GrapheneOS with Root (using Magisk) and a Locked Boot Loader
    Though it should be possible to do this with any device that GrapheneOS officially supports.

    Do not ever disable the OEM unlocking checkbox when using a locked bootloader with root. This is critically important. With root access, it is possible to corrupt the running system, for example by zeroing out the boot partition. In this scenario, if the checkbox is turned off, both the OS and recovery mode will be made unbootable and fastboot flashing unlock will not be allowed. This effectively renders the device hard bricked.

    I am not responsible for any harm you may do to your device, follow at your own risk etc etc, Rooting your device can potentially introduce security flaws, I am not claiming this to be secure.

    Simple method without building from source
    Although I highly recommend building Graphene yourself,
    All you really need to do is patch the official OTA released by graphene using AVBRoot
    Simply flash the official factory graphene build, then your patched OTA, then flash the avb_pkmd.bin you created following the instructions for AVBRoot and you can lock the bootloader, with patched rooted graphene.
    You will need to patch each new OTA to update and sideload the update as explained HERE Flash it to Both Slots
    Better Method, But requires more time and a decent computer
    Only Recommended for people with experience things building from source
    The first step is to build GrapheneOS from its sources or to use AVBRoot on official builds. I will include some of the information specific for Pixel 6 Pro to help with the build process

    Part one, follow this guide to build GrapheneOS from source

    You will want to build a Stable Release using the TAG_NAME
    Code:
    TP1A.221105.002.2022111000
    this an EXAMPLE Tag for the Pixel 6 Pro
    Find the Latest tag on the Releases page https://grapheneos.org/releases#raven-stable

    Build the Kernal for Raviole (6th generation Pixels) and follow all the instructions there

    When it comes to the step of "Extracting vendor files for Pixel devices"
    The DEVICE is
    Code:
    raven
    and an Example of the BUILD_ID is
    Code:
    tp1a.221105.002
    Check the TAG_NAME for the Latest BUILD_ID

    Continue to follow the guide until completion, creating your own Keys during the process
    I do recommend testing to Lock the Boot Loader, Just to see if you are able to
    In my experience if the pixel does not detect a valid signed boot etc, it will not allow you to lock the bootloader
    So if it brings up the screen on your phone where you can confirm the locking of the bootloader
    at this stage you can just select No / Do not lock

    To build with a specific BUILD_NUMBER use the command
    Code:
    export BUILD_NUMBER=2022112500
    Replacing the number with what matches the version you are attempting to build
    Remove the encryption from keys/raven/avb.pem that was created for Graphene so that you can use it with AVBRoot

    Use the script
    Code:
    script/decrypt_keys.sh
    https://grapheneos.org/build#encrypting-keys
    And set a copy of the key aside for the next steps.
    Use the following process to create the correct keys for AVBRoot & GrapheneOS

    Use the avb.pem you decrypted in the last step
    Convert the avb.pem to avb.key with the following command
    Code:
    openssl rsa -outform der -in avb.pem -out avb.key
    Then clone the avb.key and rename it to ota.key

    as it says "The boot-related components are signed with an AVB key and OTA-related components are signed with an OTA key. They can be the same RSA keypair, though the following steps show how to generate two separate keys."

    Convert the public key portion of the AVB signing key to the AVB public key metadata format. This is the format that the bootloader requires when setting the custom root of trust.
    Code:
    PATH/TO/avbroot/external/avb/avbtool.py extract_public_key --key avb.key --output avb_pkmd.bin
    Generate a self-signed certificate for the OTA signing key. This is used by recovery for verifying OTA updates.
    Code:
    openssl req -new -x509 -sha256 -key ota.key -out ota.crt -days 10000 -subj '/CN=OTA/'
    I also edit the "CN" to match what I used earlier when I generated the keys for Graphene

    I am not entirely certain what other of the keys I should use instead, I think this is the best approach for now
    as it creates all the keys it requires and this process works for me

    Copy the OTA (raven-ota_update-*.zip) from the folder where you have your own Factory Graphene Build and use this with AVBRoot
    Then you will have all the keys and files you need to continue the guide and use the AVBRoot script
    Now it's time to follow the instructions Here https://github.com/chenxiaolong/avbroot

    To create a full factory installer, Intall it and lock the bootloader.
    When you are done with AVBRoot and you have the boot.img, vbmeta.img and vendor_boot.img
    All patched and signed by AVBRoot, Take a factory image from your Graphene Build and Extract it anywhere
    Open the image-raven-*.zip with an Archive manager
    Delete the existing boot.img, vbmeta.img and vendor_boot.img files and replace them the patched ones
    also replace the avb_pkmd.bin with the one you have created in the previous steps for AVBRoot (might work without this step)

    Finally, you are able to run the flash-all.sh and then lock the bootloader
    Code:
    ./flash-all.sh
    Code:
    fastboot flashing lock
    Updating is very simple, Once you use AVBRoot to create the Patched OTA.zip
    you can reboot to recovery and flash the patched ota.zip with adb sideload
    Code:
    adb sideload raven-ota_update-*.zip.patched
    https://grapheneos.org/usage#updates-sideloading

    Creating the patched full factory installer is not required if you simply flash the avb custom key and the patched OTA zip before locking the bootloader, after flashing the unpatched full system install build

    This for me allowed me after much struggle to achieve a Rooted, Locked Boot Loader using GrapheneOS and Magisk
    Now though with this guide worked out, I think it should be quite easy for anyone with basic terminal knowledge to accomplish.

    Something to note is that GrapheneOS does Not Pass the CTS Profile integrity check
    and I do Not Pass the Play Integrity API Check currently, Neither the Basic or Strong check
    But I can pass the Basic attestation Safety Net test when using the patched SafetyNet Fix
    Further testing is needed and welcomed to try and pass SafetyNet and Play Integrity

    To Be Clear, Although it already should be, This is NOT Modifying the official Graphene OS Sources, it is simply using them as a SOURCE for a GUIDE, You build it using unmodified grapheneOS source code so it is an unnofficial build according to their website

    Sources: GrapheneOS, AVBRoot,
    Magisk

    PayPal Donation Link
    4
    Thanks for the guide!

    I'm using an alternative method after building GrapheneOS from source, though. In fact you can simply use the following commands right after the build process:

    Bash:
    AVBROOT=/path/to/avbroot.py
    MAGISK=/path/to/Magisk-v26.1.apk
    MAGISK_PREINIT_DEVICE=persist
    cd $ANDROID_BUILD_TOP
    if [ ! -f keys/$TARGET_PRODUCT/releasekey.pem ] ; then openssl pkcs8 -topk8 -inform DER -in keys/$TARGET_PRODUCT/releasekey.pk8 -out keys/$TARGET_PRODUCT/releasekey.pem ; fi
    python $AVBROOT patch \
        --input out/release-$TARGET_PRODUCT-$BUILD_NUMBER/$TARGET_PRODUCT-ota_update-$BUILD_NUMBER.zip \
        --privkey-avb keys/$TARGET_PRODUCT/avb.pem \
        --privkey-ota keys/$TARGET_PRODUCT/releasekey.pem \
        --cert-ota keys/$TARGET_PRODUCT/releasekey.x509.pem \
        --magisk $MAGISK \
        --magisk-preinit-device=$MAGISK_PREINIT_DEVICE

    Just be sure to set valid values for AVBROOT, MAGISK and MAGISK_PREINIT_DEVICE. (See Magisk preinit device section for details on how to get the correct name of your preinit-device. For my Pixel 7 Pro it's "persist", but for your's it can be different).

    If you didn't just finish the build process, you need to set up your environment variables first (just set DEVICE to the codename of your device):
    Bash:
    DEVICE=cheetah
    cd /path/to/android-build-top
    source script/envsetup.sh
    choosecombo release $DEVICE user

    The big advantage of this method is, that no new keys need to be generated, but the build keys are used. That means you can switch between the original and rooted OTAs on the fly without having to unlock the bootloader. So you can even keep the bootloader locked (and thus avoid wiping your data) even if you never used Magisk before.
    3
    Hey, thanks for the excellent guide, this is all about to be applicable to me :)

    I have run into a small issue though, when generating the avb.key, openssl gives me an unsupported error

    openssl rsa -outform der -in avb.pem -out avb.key

    routines:ssl_store_handle_load_result:unsupported:crypto/store/store_result.c:151:
    Unable to load certificate

    I am wondering if since I didn't put a password on the keys if that caused an issue. I tried encrypted/decrypted, same issue. It's a fresh arch linux install, so packages are up to date.

    Thanks!
    Thank you, I am glad that it has been helpful for you, I have not encountered that error myself but I did use a password initially for the steps to create the keys for Graphene, I don't think this should matter though
    If you don't mind and are able to, can you create another copy of the avb.pem, see if the problem still occurs and share it with me if it does, so I can test if I get the same error when I use your .pem

    Wouldn't rooting GrapheneOS decrease the security of the operating system, a key aspect that Graphene is designed to improve? Seems like that defeats the purpose of using it in the first place.
    I do clearly say in the first post
    > Rooting your device can potentially introduce security flaws, I am not claiming this to be secure.
    I don't believe just using magisk is really such an issue, you are able to deny root from any applications you don't want to use it
    it is possible there are unknown security vulnerabilities in magisk, but that's the same with anything.
    Even though it may introduce some potential security vulnerabilities that Graphene combats against
    I believe it should be everyones choice to use root and lock their boot loader if they choose to do so
    2
    I highly recommend using your own build that is signed with your own keys that you can keep secure!
    I make no promises to provide any updates to this rom at this time

    Here more as a proof of concept that it works and updates are possible
    Latest builds moved to: Unofficial GrapheneOS, Magisk Patched for Pixel 6 / 6 Pro
    2
    {Mod edit: Quoted post has been deleted. Oswald Boelcke}
    When locking or unlocking the bootloader it will trigger a wipe of all the user data but your phone will still be usable after, It does not turn it into a brick in my experience, you will need to have flashed a properly signed build signed with your own custom avb keys as instructed by AVBRoot