Skip to content

Amazon builder script to compile custom bootloader for the FireTV 2nd gen Cube, with Amazon U-Boot & Fastboot restrictions removed

Notifications You must be signed in to change notification settings

Pro-me3us/raven_bootloader_builder

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

34 Commits
 
 
 
 
 
 
 
 

Repository files navigation

Raven Bootloader Builder

Modifications to Amazon script to compile a custom bootloader for the FireTV 2nd gen Cube, with U-Boot & Fastboot restrictions removed.

About

This bootloader compiler is a modification of the build script included with FireTVCubeGen2-7.2.0.4-20191004.tar.bz2 from Amazon's FireTV source code page.

Installation

Running the compilation script requires installing aarch64-none-elf & arm-none-eabi compiler Toolchains. Follow Odroid's Toolchain installation guide. Add the installed compiler paths to build_uboot_config.sh, and run build_uboot_config.sh to update the script paths.

Compiling the bootloader

To compile the bootloader run:

sudo ./build_uboot.sh platform.tar output_directory_name

Platform.tar is the compressed bootloader & kernel source from FireTVCubeGen2-7.2.0.4-20191004.tar.bz2. Merge the modified files provided here into your platform.tar to remove fastboot & U-Boot command restrictions from your build.

output_directory_name is the completed bootloader image destination.

The component images that make up the bootloader, including bl33.bin.enc can be found in:
tmp/tmp.randomstring/src/bootable/bootloader/uboot-amlogic/s922x/fip/_tmp/

Transplanting the patched U-Boot image into the signed bootloader

To insert the modified U-boot image (bl33.bin.enc) into the signed bootloader image obtained from the Amazon FireTV OTA update, overwriting the orginal U-Boot code.

  1. Decrypt the Bl33 portion of the signed bootloader with the AES key found at 0x00010EEC (within Bl30) of the signed bootloader. Note: this will require already having extracted the AES key located in the bootrom needed to decrypt Bl2 & Bl30
sudo openssl enc -aes-256-cbc -nopad -d -K 0000000000000000000000000000000000000000000000000000000000000000 -iv 00000000000000000000000000000000 -in u-boot.bin.signed -out bootloader.img
  1. The patched Bl33 image (bl33.bin.enc) and unmodified Bl33 within the decrypted bootloader (bootloader.img) are now aligned using the LZ4C magic to identify the beginning of the compression scheme used on U-Boot.
IN_OFFSET=`grep --byte-offset --only-matching --text LZ4C bl33.bin.enc | head -1 | cut -d: -f1`
OUT_OFFSET=`grep --byte-offset --only-matching --text LZ4C bootloader.img | head -1 | cut -d: -f1`
  1. Bl33.bin.enc is merged into bootloader.img, and the old Bl33 is overwritten
sudo dd if=bl33.bin.enc of=bootloader.img skip=$IN_OFFSET seek=$OUT_OFFSET bs=1 conv=notrunc
  1. Lastly, we re-encrypt the the end of bootloader.img using the same AES key from step 1).
sudo openssl enc -aes-256-cbc -nopad -e -K 0000000000000000000000000000000000000000000000000000000000000000 -iv 00000000000000000000000000000000 -in bootloader.img -out bootloader.img.enc

File modifications made

Build script

Minor modifications were made to the build script to disable the automatic cleanup following compilation completion. Deletion of the working folder is disabled to to make all the components of the bootloader accessible including bl33.bin.enc (patched U-Boot image).

[build_uboot.sh]
Disable deletion of the working folder
commented out line 48

#trap "rm -rf $WORKSPACE_DIR" EXIT

[mk_script.sh]
Disable deletion of the bootloader component images
commented out lines 140-144

function clean() {
	echo "Clean up"
#	cd ${UBOOT_SRC_FOLDER}
#	make distclean
#	cd ${MAIN_FOLDER}
#	rm ${FIP_BUILD_FOLDER} -rf
#	rm ${BUILD_FOLDER}/* -rf
	return
}

Removing Fastboot and U-Boot command restrictions

[amzn_lockdown.c] Original
Removing Amazon's U-Boot commandline restrictions

bool amzn_is_command_blocked(const char *cmd)
{
	int i = 0, found = 0;

	/* Are we in lock down? */
	if (lockdown_commands == false)
		return false;

	/* Is this an engineering device? */
	if (amzn_target_device_type() == AMZN_ENGINEERING_DEVICE)
		return false;

	/* Are we un-locked? */
	if (amzn_target_is_unlocked())
		return false;

	if (amzn_target_is_onetime_unlocked())
		return false;

	/* If command is on the white-list, allow */
	for (i = 0; i < ARRAY_SIZE(whitelisted_commands); i++)
		if (strcmp(whitelisted_commands[i], cmd) == 0)
			found = 1;

	/* Not on the white-list? Block */
	if (!found)
		return true;

	return false;
}

[amzn_lockdown.c] Modified
Edited down function and moved up to line 22

bool amzn_is_command_blocked(const char *cmd)
{
	return false;
}

===========================================

[amzn_fastboot_lockdown.c] Original
Removing Amazon's Fastboot command restrictions

__attribute__((weak)) int is_locked_production_device() {
#if defined(UFBL_FEATURE_SECURE_BOOT)
	return (AMZN_PRODUCTION_DEVICE == amzn_target_device_type()) && (1 != g_boot_arg->unlocked);
#else
	return 0;
#endif
}

#else /* UFBL_PROJ_ABC */

__attribute__((weak)) int is_locked_production_device() {
#if defined(UFBL_FEATURE_SECURE_BOOT) && defined(UFBL_FEATURE_UNLOCK)
	return (AMZN_PRODUCTION_DEVICE == amzn_target_device_type()
                        && (!amzn_target_is_unlocked())
#if defined(UFBL_FEATURE_TEMP_UNLOCK)
                        && (!amzn_target_is_temp_unlocked())
#endif
#if defined(UFBL_FEATURE_ONETIME_UNLOCK)
                        && (!amzn_target_is_onetime_unlocked())
#endif
			);
#else
	return 0;
#endif
}

#endif /* UFBL_PROJ_ABC */

[amzn_fastboot_lockdown.c] 1st Patch

__attribute__((weak)) int is_locked_production_device() {
    return 0;
}

[amzn_fastboot_lockdown.c] Original

	for (i = 0; i < sizeof(blacklist) / sizeof(blacklist[0]); ++i) {
		if (memcmp(buffer, blacklist[i], strlen(blacklist[i])) == 0) {
			return 1;
		}
	}

	amzn_extends_fastboot_blacklist(&list, &length);
	if (list != NULL && length > 0) {
		for (i = 0; i < length; ++i) {
			if (memcmp(buffer, list[i], strlen(list[i])) == 0) {
				return 1;
			}
		}
	}

	return 0;
}

[amzn_fastboot_lockdown.c] 2nd Patch

	for (i = 0; i < sizeof(blacklist) / sizeof(blacklist[0]); ++i) {
		if (memcmp(buffer, blacklist[i], strlen(blacklist[i])) == 0) {
			return 0;
		}
	}

	amzn_extends_fastboot_blacklist(&list, &length);
	if (list != NULL && length > 0) {
		for (i = 0; i < length; ++i) {
			if (memcmp(buffer, list[i], strlen(list[i])) == 0) {
				return 0;
			}
		}
	}

	return 0;
}

===========================================

[image_verify.c] Original
Remove the fastboot flash image verification check

int
amzn_image_verify(const void *image,
		  unsigned char *signature,
		  unsigned int image_size, meta_data_handler handler)
{
	int auth = 0;
	char *digest = NULL;

	if (!(digest = amzn_plat_alloc(SHA256_DIGEST_LENGTH))) {
		dprintf(CRITICAL, "ERROR: Unable to allocate image hash\n");
		goto cleanup;
	}

	memset(digest, 0, SHA256_DIGEST_LENGTH);

	/*
	 * Calculate hash of image for comparison
	 */
	amzn_target_sha256(image, image_size, digest);

	if (amzn_verify_image(AMZN_PRODUCTION_CERT, digest,
					signature, handler)) {
		if (amzn_target_device_type() == AMZN_PRODUCTION_DEVICE) {
			dprintf(ALWAYS,
				"Image FAILED AUTHENTICATION on PRODUCTION device\n");
			/* Failed verification */
			goto cleanup;
		} else {
		        dprintf(ALWAYS,
				"Authentication failed on engineering device with production certificate\n");
		}

		if (amzn_target_device_type() != AMZN_ENGINEERING_DEVICE) {
			dprintf(ALWAYS,
				"%s: Unknown device type!\n", UFBL_STR(__FUNCTION__));
			goto cleanup;
		}

		/* Engineering device */
		if (amzn_verify_image(AMZN_ENGINEERING_CERT, digest,
					signature, handler)) {
			dprintf(ALWAYS,
				"Image FAILED AUTHENTICATION on ENGINEERING device\n");
			goto cleanup;
		}
	} else {
		dprintf(ALWAYS,
			"Image AUTHENTICATED with PRODUCTION certificate\n");
	}

	auth = 1;

cleanup:
	if (digest)
		amzn_plat_free(digest);

	return auth;
}

[image_verify.c] Patched

int
amzn_image_verify(const void *image,
          unsigned char *signature,
          unsigned int image_size, meta_data_handler handler)
{
    return 1;
}

===========================================

[secure_boot.c] Original
Designate the Cube as an engineering device. This is a redundancy that should cover any restrictions that may have been missed.

int amzn_target_device_type(void)
{
	/* Is anti-rollback enabled? */
	if (query_efuse_status("ARB") == 1)
		return AMZN_PRODUCTION_DEVICE;
	else
		return AMZN_ENGINEERING_DEVICE;
}

[secure_boot.c] Patched

int amzn_target_device_type(void)
{
	/* Is anti-rollback enabled? */
	if (query_efuse_status("ARB") == 1)
		return AMZN_ENGINEERING_DEVICE;
	else
		return AMZN_ENGINEERING_DEVICE;
}

Setting the boot mode

The bootmode is set in [main.c]
To automatically boot to fastboot add the following two lines above autoboot_command(s); (lines 144-145):

#endif //#if defined(CONFIG_AML_UBOOT_AUTO_TEST)
	run_command("fastboot", 0);
	run_preboot_environment_command();

	autoboot_command(s);

To boot to Amlogic's burn mode:

#endif //#if defined(CONFIG_AML_UBOOT_AUTO_TEST)
	run_command("update", 0);
	run_preboot_environment_command();

	autoboot_command(s);

To automatically drop into the U-Boot console, simply comment out autoboot_command(s);

#endif //#if defined(CONFIG_AML_UBOOT_AUTO_TEST)

       // autoboot_command(s);

About

Amazon builder script to compile custom bootloader for the FireTV 2nd gen Cube, with Amazon U-Boot & Fastboot restrictions removed

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published