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
diff --git a/filesystem/bootimg.go b/filesystem/bootimg.go
index 2249506..90409b3 100644
--- a/filesystem/bootimg.go
+++ b/filesystem/bootimg.go
@@ -89,6 +89,10 @@
// 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 @@
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) 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) {
- output = b.signImage(ctx, unsignedOutput)
+ // 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 @@
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 @@
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)