Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 336b3ba2 authored by Cole Faust's avatar Cole Faust
Browse files

Avb sign boot images

The bootimg module had a very different implementation of avb signing
than what was in make. Add an alternate implemenation that is used
when avb_private_key is not set.

Bug: 377562951
Test: m nothing --no-skip-soong-tests
Change-Id: I253bcc8135f3d294eb6e09f39429c84c7c0fc037
parent ebf7c1f3
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -610,6 +610,8 @@ type PartitionVariables struct {
	ProductUseDynamicPartitionSize bool   `json:",omitempty"`
	CopyImagesForTargetFilesZip    bool   `json:",omitempty"`

	VendorSecurityPatch string `json:",omitempty"`

	// Boot image stuff
	BuildingRamdiskImage            bool   `json:",omitempty"`
	ProductBuildBootImage           bool   `json:",omitempty"`
@@ -623,6 +625,8 @@ type PartitionVariables struct {
	BoardBootHeaderVersion          string `json:",omitempty"`
	TargetKernelPath                string `json:",omitempty"`
	BoardUsesGenericKernelImage     bool   `json:",omitempty"`
	BootSecurityPatch               string `json:",omitempty"`
	InitBootSecurityPatch           string `json:",omitempty"`

	// Avb (android verified boot) stuff
	BoardAvbEnable          bool                                `json:",omitempty"`
+89 −15
Original line number Diff line number Diff line
@@ -89,6 +89,10 @@ type BootimgProperties struct {

	// Hash and signing algorithm for avbtool. Default is SHA256_RSA4096.
	Avb_algorithm *string

	// The security patch passed to as the com.android.build.<type>.security_patch avb property.
	// Replacement for the make variables BOOT_SECURITY_PATCH / INIT_BOOT_SECURITY_PATCH.
	Security_patch *string
}

type bootImageType int
@@ -114,6 +118,19 @@ func toBootImageType(ctx android.ModuleContext, bootImageType string) bootImageT
	return unsupported
}

func (b bootImageType) String() string {
	switch b {
	case boot:
		return "boot"
	case vendorBoot:
		return "vendor_boot"
	case initBoot:
		return "init_boot"
	default:
		panic("unknown boot image type")
	}
}

func (b bootImageType) isBoot() bool {
	return b == boot
}
@@ -158,11 +175,39 @@ func (b *bootimg) partitionName() string {

func (b *bootimg) GenerateAndroidBuildActions(ctx android.ModuleContext) {
	b.bootImageType = toBootImageType(ctx, proptools.StringDefault(b.properties.Boot_image_type, "boot"))
	unsignedOutput := b.buildBootImage(ctx)
	if b.bootImageType == unsupported {
		return
	}

	kernelProp := proptools.String(b.properties.Kernel_prebuilt)
	if b.bootImageType.isVendorBoot() && kernelProp != "" {
		ctx.PropertyErrorf("kernel_prebuilt", "vendor_boot partition can't have kernel")
		return
	}
	if b.bootImageType.isBoot() && kernelProp == "" {
		ctx.PropertyErrorf("kernel_prebuilt", "boot partition must have kernel")
		return
	}
	var kernel android.Path
	if kernelProp != "" {
		kernel = android.PathForModuleSrc(ctx, kernelProp)
	}

	unsignedOutput := b.buildBootImage(ctx, kernel)

	output := unsignedOutput
	if proptools.Bool(b.properties.Use_avb) {
		// This bootimg module supports 2 modes of avb signing, it picks between them based on
		// if the private key is specified or not. If there is a key, it does a signing process
		// similar to how the regular partitions (system, product, vendor, etc) are signed.
		// If the key is not provided, it will just add an avb footer to the image. The avb
		// footer only signing is how the make-built init_boot, boot, and vendor_boot images are
		// built.
		if proptools.String(b.properties.Avb_private_key) != "" {
			output = b.signImage(ctx, unsignedOutput)
		} else {
			output = b.addAvbFooter(ctx, unsignedOutput, kernel)
		}
	}

	b.installDir = android.PathForModuleInstall(ctx, "etc")
@@ -172,24 +217,14 @@ func (b *bootimg) GenerateAndroidBuildActions(ctx android.ModuleContext) {
	b.output = output
}

func (b *bootimg) buildBootImage(ctx android.ModuleContext) android.Path {
func (b *bootimg) buildBootImage(ctx android.ModuleContext, kernel android.Path) android.Path {
	output := android.PathForModuleOut(ctx, "unsigned", b.installFileName())

	builder := android.NewRuleBuilder(pctx, ctx)
	cmd := builder.Command().BuiltTool("mkbootimg")

	kernel := proptools.String(b.properties.Kernel_prebuilt)
	if b.bootImageType.isVendorBoot() && kernel != "" {
		ctx.PropertyErrorf("kernel_prebuilt", "vendor_boot partition can't have kernel")
		return output
	}

	if b.bootImageType.isBoot() && kernel == "" {
		ctx.PropertyErrorf("kernel_prebuilt", "boot partition must have kernel")
		return output
	}
	if kernel != "" {
		cmd.FlagWithInput("--kernel ", android.PathForModuleSrc(ctx, kernel))
	if kernel != nil {
		cmd.FlagWithInput("--kernel ", kernel)
	}

	// These arguments are passed for boot.img and init_boot.img generation
@@ -272,6 +307,45 @@ func (b *bootimg) buildBootImage(ctx android.ModuleContext) android.Path {
	return output
}

func (b *bootimg) addAvbFooter(ctx android.ModuleContext, unsignedImage android.Path, kernel android.Path) android.Path {
	output := android.PathForModuleOut(ctx, b.installFileName())
	builder := android.NewRuleBuilder(pctx, ctx)
	builder.Command().Text("cp").Input(unsignedImage).Output(output)
	cmd := builder.Command().BuiltTool("avbtool").
		Text("add_hash_footer").
		FlagWithInput("--image ", output)

	if b.properties.Partition_size != nil {
		cmd.FlagWithArg("--partition_size ", strconv.FormatInt(*b.properties.Partition_size, 10))
	} else {
		cmd.Flag("--dynamic_partition_size")
	}

	if kernel != nil {
		cmd.Textf(`--salt $(sha256sum "%s" | cut -d " " -f 1)`, kernel.String())
		cmd.Implicit(kernel)
	}

	cmd.FlagWithArg("--partition_name ", b.bootImageType.String())

	if !b.bootImageType.isVendorBoot() {
		cmd.FlagWithArg("--prop ", proptools.NinjaAndShellEscape(fmt.Sprintf(
			"com.android.build.%s.os_version:%s", b.bootImageType.String(), ctx.Config().PlatformVersionLastStable())))
	}

	fingerprintFile := ctx.Config().BuildFingerprintFile(ctx)
	cmd.FlagWithArg("--prop ", fmt.Sprintf("com.android.build.%s.fingerprint:%s", b.bootImageType.String(), fingerprintFile.String()))
	cmd.OrderOnly(fingerprintFile)

	if b.properties.Security_patch != nil {
		cmd.FlagWithArg("--prop ", proptools.NinjaAndShellEscape(fmt.Sprintf(
			"com.android.build.%s.security_patch:%s", b.bootImageType.String(), *b.properties.Security_patch)))
	}

	builder.Build("add_avb_footer", fmt.Sprintf("Adding avb footer to %s", b.BaseModuleName()))
	return output
}

func (b *bootimg) signImage(ctx android.ModuleContext, unsignedImage android.Path) android.Path {
	propFile, toolDeps := b.buildPropFile(ctx)

+17 −0
Original line number Diff line number Diff line
@@ -45,6 +45,11 @@ func createBootImage(ctx android.LoadHookContext) bool {
		partitionSize = &parsed
	}

	var securityPatch *string
	if partitionVariables.BootSecurityPatch != "" {
		securityPatch = &partitionVariables.BootSecurityPatch
	}

	bootImageName := generatedModuleNameForPartition(ctx.Config(), "boot")

	ctx.CreateModule(
@@ -53,6 +58,8 @@ func createBootImage(ctx android.LoadHookContext) bool {
			Kernel_prebuilt: proptools.StringPtr(":" + kernelFilegroupName),
			Header_version:  proptools.StringPtr(partitionVariables.BoardBootHeaderVersion),
			Partition_size:  partitionSize,
			Use_avb:         &partitionVariables.BoardAvbEnable,
			Security_patch:  securityPatch,
		},
		&struct {
			Name *string
@@ -74,6 +81,7 @@ func createVendorBootImage(ctx android.LoadHookContext) bool {
			Boot_image_type: proptools.StringPtr("vendor_boot"),
			Ramdisk_module:  proptools.StringPtr(generatedModuleNameForPartition(ctx.Config(), "vendor_ramdisk")),
			Header_version:  proptools.StringPtr(partitionVariables.BoardBootHeaderVersion),
			Use_avb:         &partitionVariables.BoardAvbEnable,
		},
		&struct {
			Name *string
@@ -89,12 +97,21 @@ func createInitBootImage(ctx android.LoadHookContext) bool {

	bootImageName := generatedModuleNameForPartition(ctx.Config(), "init_boot")

	var securityPatch *string
	if partitionVariables.InitBootSecurityPatch != "" {
		securityPatch = &partitionVariables.InitBootSecurityPatch
	} else if partitionVariables.BootSecurityPatch != "" {
		securityPatch = &partitionVariables.BootSecurityPatch
	}

	ctx.CreateModule(
		filesystem.BootimgFactory,
		&filesystem.BootimgProperties{
			Boot_image_type: proptools.StringPtr("init_boot"),
			Ramdisk_module:  proptools.StringPtr(generatedModuleNameForPartition(ctx.Config(), "ramdisk")),
			Header_version:  proptools.StringPtr(partitionVariables.BoardBootHeaderVersion),
			Use_avb:         &partitionVariables.BoardAvbEnable,
			Security_patch:  securityPatch,
		},
		&struct {
			Name *string