Alpha of CopperheadOS secure Android released
See the newer post about CopperheadOS Beta. It is no longer based on CyanogenMod and very little of this post is still applicable.
The alpha release of CopperheadOS is now available, with support for the Nexus 5 and Samsung Galaxy S4. It's currently based on the CyanogenMod 12.1 branch (Android 5.1.1). The ROMs are tested before being pushed out as over-the-air updates so you can expect more reliability than the automated CyanogenMod 12.1 nightlies.
The previous four blog posts provide a good overview of the changes, although most of the smaller features are not covered and more work has been done since these posts:
- The State of ASLR on Android Lollipop
- Integrating PaX into Android
- Separating Android's encryption and lockscreen passwords
- Hardening Android's Bionic libc
The site will have a full feature list soon, along with a list of the changes upstreamed into the Android Open Source Project.
Pre-built ROMs
Note that if you get stuck with these instructions, you can just follow any other instructions for installing CyanogenMod. Nothing about the process is different for CopperheadOS.
Installing the ROM
Recovery
Before installing the ROM, you'll need to replace the recovery image. For now, Team Win Recovery Project is the recommended option.
In the future, we'll only recommend using the CopperheadOS recovery image as it can be updated via over-the-air updates and provides signature validation. The CyanogenMod recovery project it's built from has buggy support for sideloading so it's not a great option right now. It is unable to sideload at all on the Galaxy S4 and it often fails to start on the Nexus 5 so it requires more than one attempt. Everything else does work fine as it comes from AOSP.
Nexus 5
The ROM zip file can be downloaded from the builds page.
- Boot into the bootloader. You can do this by turning off the device and then turning it on by holding both the Volume Down and Power buttons. Alternatively, you can use
adb reboot bootloader
. - Wipe the data partition and unlock the bootloader with
fastboot oem unlock
. - Flash a recovery with
fastboot flash recovery recovery.img
. - (OPTIONAL) If you're using our recovery image, you can relock the bootloader with
fastboot oem lock
. This will prevent it from being flashed via fastboot without wiping the data again. Note that this doesn't provide any real value once encryption is enabled. - Reboot into recovery from the bootloader.
- Tell the recovery to sideload a zip file (Advanced -> ADB sideload in TWRP, Apply update -> ADB sideload in our recovery image).
- Run
adb sideload rom.zip
. - Reboot in CopperheadOS from recovery.
- Don't enable encryption until a lockscreen password has been set, and don't remove the lockscreen password if you haven't set a separate encryption password. CyanogenMod currently doesn't support encryption with the internal default password.
Samsung Galaxy S4
The ROM zip file can be downloaded from the builds page.
- Boot into download mode. You can do this by turning off the device and then turning it on by holding the Volume Down, Home and Power buttons together. Alternatively, you can use
adb reboot download
. - Flash a recovery image with
heimdall flash --RECOVERY recovery.img --no-reboot
. - Manually power off once it's finished and hold Volume Up + Home + Power to boot into the recovery. Otherwise you'll have to start over as the OS will clobber the recovery image.
- Tell the recovery to sideload a zip file (Advanced -> ADB sideload in TWRP, Apply update -> ADB sideload in our recovery image).
- Run
adb sideload rom.zip
. - Reboot in CopperheadOS from recovery.
- Don't enable encryption until a lockscreen password has been set, and don't remove the lockscreen password if you haven't set a separate encryption password. CyanogenMod currently doesn't support encryption with the internal default password.
Google Play Services / Store
CopperheadOS is compatible with Google Play. One of the CyanogenMod developers maintains a repository on GitHub with zip files to sideload after the initial installation.
Note that the F-Droid app store is included by default and may have apps covering all of your needs. The default repository provides only entirely open source applications and has warnings for those with misfeatures like user tracking.
Reporting bugs
Bugs (or feature requests) should be reported to the issue tracker on the main repository. The other repositories all have the issue trackers disabled to keep things manageable.
At this stage, we're not going to be actively fixing bugs in AOSP or CyanogenMod.
PaX exceptions
Many apps need exceptions from the MPROTECT feature, mostly due to the JavaScript JIT compiler in the WebView widget. If you run into any issues, you can try turning on PaX's soft mode (i.e. userspace hardening features disabled) via the Settings -> Developer options -> PaX soft mode toggle. You need to enable the hidden Developer options menu by repeatedly touching the 'Build number' menu entry in Settings -> About phone.
If you do encounter an app requiring an exception, please report it to us so we can add it to the exception database. It would help us if you confirmed that toggling on soft mode resolves the issue, along with providing the relevant portion of the debug logs (adb logcat
) for the crash.
The long-term plan is to address the most common issues like the WebView via automated checks in the package manager. For now, even the most common issues need to be dealt with via the internal exception database. Thankfully, Android dropped text relocations on 64-bit and is in the process of killing them off on 32-bit so one of the most common problems is already being solved.
Building from source
CopperheadOS can be built with the same process as AOSP and CyanogenMod. The only significant difference is the integration of ROM signing into the build process to make it easier for users to sign their own builds. Replacing the default public AOSP test keys is highly recommend as Android's security model is based around the private keys actually being private.
Prerequisites
Building it has only been tested on Linux, but it should be possible to build it on OS X too. For more details on setting up a build environment with the required dependencies, see the Android documentation on this.
Downloading the sources requires upwards of 20GiB of bandwidth and the size of the source tree + build tree for one device will be ~50GiB. The minimum memory requirement is somewhere near 8GiB. A finished build (i.e. the ROM zip) is only ~250M.
Build
Android's source tree consists of hundreds of Git repositories, so it uses a meta-tool called Repo to make sense of it. Download the Repo tool from Google and put it in a directory in your $PATH
:
curl https://storage.googleapis.com/git-repo-downloads/repo > ~/.local/bin/repo
chmod +x ~/.local/bin/repo
export PATH="$PATH:$HOME/.local/bin"
Create a directory for the source tree and initialize it from Copperhead's main android repository:
mkdir ~/copperheados
cd ~/copperheados
repo init -u https://github.com/copperhead/android.git -b cm-12.1
Next, sync the repositories:
repo sync -j16
In either Bash or Zsh, set up the build environment by sourcing envsetup.sh:
source build/envsetup.sh
The environment then needs to be set up for the target device. Note that the same source tree can be reused for multiple target devices.
For the Nexus 5:
breakfast hammerhead
For the Samsung Galaxy S4:
breakfast jfltexx
You should now generate your own signing keys to avoid the public AOSP test keys:
mkdir ~/copperheados-signing-keys
cd ~/copperheados-signing-keys
~/copperheados/development/tools/make_key platform '/C=CA/ST=Ontario/L=Toronto/'
~/copperheados/development/tools/make_key media '/C=CA/ST=Ontario/L=Toronto/'
~/copperheados/development/tools/make_key shared '/C=CA/ST=Ontario/L=Toronto/'
~/copperheados/development/tools/make_key releasekey '/C=CA/ST=Ontario/L=Toronto/'
The following environment variables need to be set to use the keys:
export OTA_PACKAGE_SIGNING_KEY=~/copperheados-signing-keys/releasekey
export SIGNING_KEY_DIR=~/copperheados-signing-keys
Note that OTA_PACKAGE_SIGNING_KEY
is a convenience feature from CyanogenMod and SIGNING_KEY_DIR
is another convenience added by CopperheadOS. You would normally have to sign by hand after building.
At this point, the device-specific proprietary libraries need to be obtained from the relevant device. You can do this by flashing a CyanogenMod 12.1 ROM onto the device and running their extract-files.sh
script. There are other sources for these files, but CyanogenMod is likely the most trustworthy one.
For the Nexus 5:
device/lge/hammerhead/extract-files.sh
For the Samsung Galaxy S4:
device/samsung/jfltexx/extract-files.sh
Finally, run the build process for the target device.
For the Nexus 5:
brunch hammerhead
For the Samsung Galaxy S4:
brunch jfltexx
Assuming it succeeds, the ROM zip file will be placed in directory set by the scripts in your shell's $OUT
environment variable. The build process gives the zip file a name based on the date and another based on the build id. These are hard links to the same file and either can be used for either sideloading or over-the-air updates.
You can also flash the recovery.img (see above) to have a recovery with support for validating that any zip it installs is correctly signed with your key. The official CopperheadOS recovery won't work, since it expects our key.
Development model
If you're contributing or just building from source, you should keep in mind that the project is currently being developed in a strictly downstream model. All of the repositories are being regularly rebased onto the upstream CyanogenMod branches along with commits being reordered / rewritten to prepare work for submission to AOSP. This makes the project significantly easier to maintain, audit and port to new versions of Android, but it will make life very painful for anyone with clones. This will be changed if there are actually a significant amount of outside contributions coming in, which seems unlikely. The history is temporary even with merges used in place of rebases because the CyanogenMod branches are based on independent AOSP stable branches.
The Repo tool will happily clobber repositories in the source tree when they're rebased, but it doesn't like updates for the main android.git repository. If you don't want the download the sources again, you can rewind the history in .repo/manifests
to a known good commit with git reset --hard
and then sync.
I recommend contributing bug fixes and clear cut security improvements directly to AOSP or CyanogenMod as we'll benefit from anything implemented there. It makes sense to contribute directly if upstream isn't responsive and we may also want to backport changes. CopperheadOS targets a different niche so it will also be willing to make significant (but not extreme) sacrifices to improve security. For example, it uses OpenBSD malloc but it's not going to pay the enormous performance cost of something like Address Sanitizer. PaX's MPROTECT feature is a borderline reasonable compatibility sacrifice (especially since soft mode can be toggled on) but requiring other new permissions and managing exception databases for those too would be going too far.