xref: /aosp_15_r20/build/soong/filesystem/avb_add_hash_footer.go (revision 333d2b3687b3a337dbcca9d65000bca186795e39)
1*333d2b36SAndroid Build Coastguard Worker// Copyright (C) 2022 The Android Open Source Project
2*333d2b36SAndroid Build Coastguard Worker//
3*333d2b36SAndroid Build Coastguard Worker// Licensed under the Apache License, Version 2.0 (the "License");
4*333d2b36SAndroid Build Coastguard Worker// you may not use this file except in compliance with the License.
5*333d2b36SAndroid Build Coastguard Worker// You may obtain a copy of the License at
6*333d2b36SAndroid Build Coastguard Worker//
7*333d2b36SAndroid Build Coastguard Worker//     http://www.apache.org/licenses/LICENSE-2.0
8*333d2b36SAndroid Build Coastguard Worker//
9*333d2b36SAndroid Build Coastguard Worker// Unless required by applicable law or agreed to in writing, software
10*333d2b36SAndroid Build Coastguard Worker// distributed under the License is distributed on an "AS IS" BASIS,
11*333d2b36SAndroid Build Coastguard Worker// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12*333d2b36SAndroid Build Coastguard Worker// See the License for the specific language governing permissions and
13*333d2b36SAndroid Build Coastguard Worker// limitations under the License.
14*333d2b36SAndroid Build Coastguard Worker
15*333d2b36SAndroid Build Coastguard Workerpackage filesystem
16*333d2b36SAndroid Build Coastguard Worker
17*333d2b36SAndroid Build Coastguard Workerimport (
18*333d2b36SAndroid Build Coastguard Worker	"fmt"
19*333d2b36SAndroid Build Coastguard Worker	"strconv"
20*333d2b36SAndroid Build Coastguard Worker
21*333d2b36SAndroid Build Coastguard Worker	"github.com/google/blueprint/proptools"
22*333d2b36SAndroid Build Coastguard Worker
23*333d2b36SAndroid Build Coastguard Worker	"android/soong/android"
24*333d2b36SAndroid Build Coastguard Worker)
25*333d2b36SAndroid Build Coastguard Worker
26*333d2b36SAndroid Build Coastguard Workertype avbAddHashFooter struct {
27*333d2b36SAndroid Build Coastguard Worker	android.ModuleBase
28*333d2b36SAndroid Build Coastguard Worker	android.DefaultableModuleBase
29*333d2b36SAndroid Build Coastguard Worker
30*333d2b36SAndroid Build Coastguard Worker	properties avbAddHashFooterProperties
31*333d2b36SAndroid Build Coastguard Worker
32*333d2b36SAndroid Build Coastguard Worker	output     android.Path
33*333d2b36SAndroid Build Coastguard Worker	installDir android.InstallPath
34*333d2b36SAndroid Build Coastguard Worker}
35*333d2b36SAndroid Build Coastguard Worker
36*333d2b36SAndroid Build Coastguard Workertype avbProp struct {
37*333d2b36SAndroid Build Coastguard Worker	// Name of a property
38*333d2b36SAndroid Build Coastguard Worker	Name *string
39*333d2b36SAndroid Build Coastguard Worker
40*333d2b36SAndroid Build Coastguard Worker	// Value of a property. Can't be used together with `file`.
41*333d2b36SAndroid Build Coastguard Worker	Value *string
42*333d2b36SAndroid Build Coastguard Worker
43*333d2b36SAndroid Build Coastguard Worker	// File from which the value of the prop is read from. Can't be used together with `value`.
44*333d2b36SAndroid Build Coastguard Worker	File *string `android:"path,arch_variant"`
45*333d2b36SAndroid Build Coastguard Worker}
46*333d2b36SAndroid Build Coastguard Worker
47*333d2b36SAndroid Build Coastguard Workertype avbAddHashFooterProperties struct {
48*333d2b36SAndroid Build Coastguard Worker	// Source file of this image. Can reference a genrule type module with the ":module" syntax.
49*333d2b36SAndroid Build Coastguard Worker	Src *string `android:"path,arch_variant"`
50*333d2b36SAndroid Build Coastguard Worker
51*333d2b36SAndroid Build Coastguard Worker	// Set the name of the output. Defaults to <module_name>.img.
52*333d2b36SAndroid Build Coastguard Worker	Filename *string
53*333d2b36SAndroid Build Coastguard Worker
54*333d2b36SAndroid Build Coastguard Worker	// Name of the image partition. Defaults to the name of this module.
55*333d2b36SAndroid Build Coastguard Worker	Partition_name *string
56*333d2b36SAndroid Build Coastguard Worker
57*333d2b36SAndroid Build Coastguard Worker	// Size of the partition. Defaults to dynamically calculating the size.
58*333d2b36SAndroid Build Coastguard Worker	Partition_size *int64
59*333d2b36SAndroid Build Coastguard Worker
60*333d2b36SAndroid Build Coastguard Worker	// Path to the private key that avbtool will use to sign this image.
61*333d2b36SAndroid Build Coastguard Worker	Private_key *string `android:"path"`
62*333d2b36SAndroid Build Coastguard Worker
63*333d2b36SAndroid Build Coastguard Worker	// Algorithm that avbtool will use to sign this image. Default is SHA256_RSA4096.
64*333d2b36SAndroid Build Coastguard Worker	Algorithm *string
65*333d2b36SAndroid Build Coastguard Worker
66*333d2b36SAndroid Build Coastguard Worker	// The salt in hex. Required for reproducible builds.
67*333d2b36SAndroid Build Coastguard Worker	Salt *string
68*333d2b36SAndroid Build Coastguard Worker
69*333d2b36SAndroid Build Coastguard Worker	// List of properties to add to the footer
70*333d2b36SAndroid Build Coastguard Worker	Props []avbProp
71*333d2b36SAndroid Build Coastguard Worker
72*333d2b36SAndroid Build Coastguard Worker	// The index used to prevent rollback of the image on device.
73*333d2b36SAndroid Build Coastguard Worker	Rollback_index *int64
74*333d2b36SAndroid Build Coastguard Worker
75*333d2b36SAndroid Build Coastguard Worker	// Include descriptors from images
76*333d2b36SAndroid Build Coastguard Worker	Include_descriptors_from_images []string `android:"path,arch_variant"`
77*333d2b36SAndroid Build Coastguard Worker}
78*333d2b36SAndroid Build Coastguard Worker
79*333d2b36SAndroid Build Coastguard Worker// The AVB footer adds verification information to the image.
80*333d2b36SAndroid Build Coastguard Workerfunc avbAddHashFooterFactory() android.Module {
81*333d2b36SAndroid Build Coastguard Worker	module := &avbAddHashFooter{}
82*333d2b36SAndroid Build Coastguard Worker	module.AddProperties(&module.properties)
83*333d2b36SAndroid Build Coastguard Worker	android.InitAndroidArchModule(module, android.DeviceSupported, android.MultilibFirst)
84*333d2b36SAndroid Build Coastguard Worker	android.InitDefaultableModule(module)
85*333d2b36SAndroid Build Coastguard Worker	return module
86*333d2b36SAndroid Build Coastguard Worker}
87*333d2b36SAndroid Build Coastguard Worker
88*333d2b36SAndroid Build Coastguard Workerfunc (a *avbAddHashFooter) installFileName() string {
89*333d2b36SAndroid Build Coastguard Worker	return proptools.StringDefault(a.properties.Filename, a.BaseModuleName()+".img")
90*333d2b36SAndroid Build Coastguard Worker}
91*333d2b36SAndroid Build Coastguard Worker
92*333d2b36SAndroid Build Coastguard Workerfunc (a *avbAddHashFooter) GenerateAndroidBuildActions(ctx android.ModuleContext) {
93*333d2b36SAndroid Build Coastguard Worker	builder := android.NewRuleBuilder(pctx, ctx)
94*333d2b36SAndroid Build Coastguard Worker
95*333d2b36SAndroid Build Coastguard Worker	if a.properties.Src == nil {
96*333d2b36SAndroid Build Coastguard Worker		ctx.PropertyErrorf("src", "missing source file")
97*333d2b36SAndroid Build Coastguard Worker		return
98*333d2b36SAndroid Build Coastguard Worker	}
99*333d2b36SAndroid Build Coastguard Worker	input := android.PathForModuleSrc(ctx, proptools.String(a.properties.Src))
100*333d2b36SAndroid Build Coastguard Worker	output := android.PathForModuleOut(ctx, a.installFileName())
101*333d2b36SAndroid Build Coastguard Worker	builder.Command().Text("cp").Input(input).Output(output)
102*333d2b36SAndroid Build Coastguard Worker
103*333d2b36SAndroid Build Coastguard Worker	cmd := builder.Command().BuiltTool("avbtool").Text("add_hash_footer")
104*333d2b36SAndroid Build Coastguard Worker
105*333d2b36SAndroid Build Coastguard Worker	partition_name := proptools.StringDefault(a.properties.Partition_name, a.BaseModuleName())
106*333d2b36SAndroid Build Coastguard Worker	cmd.FlagWithArg("--partition_name ", partition_name)
107*333d2b36SAndroid Build Coastguard Worker
108*333d2b36SAndroid Build Coastguard Worker	if a.properties.Partition_size == nil {
109*333d2b36SAndroid Build Coastguard Worker		cmd.Flag("--dynamic_partition_size")
110*333d2b36SAndroid Build Coastguard Worker	} else {
111*333d2b36SAndroid Build Coastguard Worker		partition_size := proptools.Int(a.properties.Partition_size)
112*333d2b36SAndroid Build Coastguard Worker		cmd.FlagWithArg("--partition_size ", strconv.Itoa(partition_size))
113*333d2b36SAndroid Build Coastguard Worker	}
114*333d2b36SAndroid Build Coastguard Worker
115*333d2b36SAndroid Build Coastguard Worker	key := android.PathForModuleSrc(ctx, proptools.String(a.properties.Private_key))
116*333d2b36SAndroid Build Coastguard Worker	cmd.FlagWithInput("--key ", key)
117*333d2b36SAndroid Build Coastguard Worker
118*333d2b36SAndroid Build Coastguard Worker	algorithm := proptools.StringDefault(a.properties.Algorithm, "SHA256_RSA4096")
119*333d2b36SAndroid Build Coastguard Worker	cmd.FlagWithArg("--algorithm ", algorithm)
120*333d2b36SAndroid Build Coastguard Worker
121*333d2b36SAndroid Build Coastguard Worker	if a.properties.Salt == nil {
122*333d2b36SAndroid Build Coastguard Worker		ctx.PropertyErrorf("salt", "missing salt value")
123*333d2b36SAndroid Build Coastguard Worker		return
124*333d2b36SAndroid Build Coastguard Worker	}
125*333d2b36SAndroid Build Coastguard Worker	cmd.FlagWithArg("--salt ", proptools.String(a.properties.Salt))
126*333d2b36SAndroid Build Coastguard Worker
127*333d2b36SAndroid Build Coastguard Worker	imagePaths := android.PathsForModuleSrc(ctx, a.properties.Include_descriptors_from_images)
128*333d2b36SAndroid Build Coastguard Worker	for _, imagePath := range imagePaths {
129*333d2b36SAndroid Build Coastguard Worker		cmd.FlagWithInput("--include_descriptors_from_image ", imagePath)
130*333d2b36SAndroid Build Coastguard Worker	}
131*333d2b36SAndroid Build Coastguard Worker
132*333d2b36SAndroid Build Coastguard Worker	for _, prop := range a.properties.Props {
133*333d2b36SAndroid Build Coastguard Worker		addAvbProp(ctx, cmd, prop)
134*333d2b36SAndroid Build Coastguard Worker	}
135*333d2b36SAndroid Build Coastguard Worker
136*333d2b36SAndroid Build Coastguard Worker	if a.properties.Rollback_index != nil {
137*333d2b36SAndroid Build Coastguard Worker		rollbackIndex := proptools.Int(a.properties.Rollback_index)
138*333d2b36SAndroid Build Coastguard Worker		if rollbackIndex < 0 {
139*333d2b36SAndroid Build Coastguard Worker			ctx.PropertyErrorf("rollback_index", "Rollback index must be non-negative")
140*333d2b36SAndroid Build Coastguard Worker		}
141*333d2b36SAndroid Build Coastguard Worker		cmd.Flag(fmt.Sprintf(" --rollback_index %d", rollbackIndex))
142*333d2b36SAndroid Build Coastguard Worker	}
143*333d2b36SAndroid Build Coastguard Worker
144*333d2b36SAndroid Build Coastguard Worker	cmd.FlagWithOutput("--image ", output)
145*333d2b36SAndroid Build Coastguard Worker
146*333d2b36SAndroid Build Coastguard Worker	builder.Build("avbAddHashFooter", fmt.Sprintf("avbAddHashFooter %s", ctx.ModuleName()))
147*333d2b36SAndroid Build Coastguard Worker
148*333d2b36SAndroid Build Coastguard Worker	a.installDir = android.PathForModuleInstall(ctx, "etc")
149*333d2b36SAndroid Build Coastguard Worker	ctx.InstallFile(a.installDir, a.installFileName(), output)
150*333d2b36SAndroid Build Coastguard Worker	a.output = output
151*333d2b36SAndroid Build Coastguard Worker}
152*333d2b36SAndroid Build Coastguard Worker
153*333d2b36SAndroid Build Coastguard Workerfunc addAvbProp(ctx android.ModuleContext, cmd *android.RuleBuilderCommand, prop avbProp) {
154*333d2b36SAndroid Build Coastguard Worker	name := proptools.String(prop.Name)
155*333d2b36SAndroid Build Coastguard Worker	value := proptools.String(prop.Value)
156*333d2b36SAndroid Build Coastguard Worker	file := proptools.String(prop.File)
157*333d2b36SAndroid Build Coastguard Worker	if name == "" {
158*333d2b36SAndroid Build Coastguard Worker		ctx.PropertyErrorf("name", "can't be empty")
159*333d2b36SAndroid Build Coastguard Worker		return
160*333d2b36SAndroid Build Coastguard Worker	}
161*333d2b36SAndroid Build Coastguard Worker	if value == "" && file == "" {
162*333d2b36SAndroid Build Coastguard Worker		ctx.PropertyErrorf("value", "either value or file should be set")
163*333d2b36SAndroid Build Coastguard Worker		return
164*333d2b36SAndroid Build Coastguard Worker	}
165*333d2b36SAndroid Build Coastguard Worker	if value != "" && file != "" {
166*333d2b36SAndroid Build Coastguard Worker		ctx.PropertyErrorf("value", "value and file can't be set at the same time")
167*333d2b36SAndroid Build Coastguard Worker		return
168*333d2b36SAndroid Build Coastguard Worker	}
169*333d2b36SAndroid Build Coastguard Worker
170*333d2b36SAndroid Build Coastguard Worker	if value != "" {
171*333d2b36SAndroid Build Coastguard Worker		cmd.FlagWithArg("--prop ", proptools.ShellEscape(fmt.Sprintf("%s:%s", name, value)))
172*333d2b36SAndroid Build Coastguard Worker	} else {
173*333d2b36SAndroid Build Coastguard Worker		p := android.PathForModuleSrc(ctx, file)
174*333d2b36SAndroid Build Coastguard Worker		cmd.Implicit(p)
175*333d2b36SAndroid Build Coastguard Worker		cmd.FlagWithArg("--prop_from_file ", proptools.ShellEscape(fmt.Sprintf("%s:%s", name, cmd.PathForInput(p))))
176*333d2b36SAndroid Build Coastguard Worker	}
177*333d2b36SAndroid Build Coastguard Worker}
178*333d2b36SAndroid Build Coastguard Worker
179*333d2b36SAndroid Build Coastguard Workervar _ android.AndroidMkEntriesProvider = (*avbAddHashFooter)(nil)
180*333d2b36SAndroid Build Coastguard Worker
181*333d2b36SAndroid Build Coastguard Worker// Implements android.AndroidMkEntriesProvider
182*333d2b36SAndroid Build Coastguard Workerfunc (a *avbAddHashFooter) AndroidMkEntries() []android.AndroidMkEntries {
183*333d2b36SAndroid Build Coastguard Worker	return []android.AndroidMkEntries{android.AndroidMkEntries{
184*333d2b36SAndroid Build Coastguard Worker		Class:      "ETC",
185*333d2b36SAndroid Build Coastguard Worker		OutputFile: android.OptionalPathForPath(a.output),
186*333d2b36SAndroid Build Coastguard Worker		ExtraEntries: []android.AndroidMkExtraEntriesFunc{
187*333d2b36SAndroid Build Coastguard Worker			func(ctx android.AndroidMkExtraEntriesContext, entries *android.AndroidMkEntries) {
188*333d2b36SAndroid Build Coastguard Worker				entries.SetString("LOCAL_MODULE_PATH", a.installDir.String())
189*333d2b36SAndroid Build Coastguard Worker				entries.SetString("LOCAL_INSTALLED_MODULE_STEM", a.installFileName())
190*333d2b36SAndroid Build Coastguard Worker			},
191*333d2b36SAndroid Build Coastguard Worker		},
192*333d2b36SAndroid Build Coastguard Worker	}}
193*333d2b36SAndroid Build Coastguard Worker}
194*333d2b36SAndroid Build Coastguard Worker
195*333d2b36SAndroid Build Coastguard Workervar _ Filesystem = (*avbAddHashFooter)(nil)
196*333d2b36SAndroid Build Coastguard Worker
197*333d2b36SAndroid Build Coastguard Workerfunc (a *avbAddHashFooter) OutputPath() android.Path {
198*333d2b36SAndroid Build Coastguard Worker	return a.output
199*333d2b36SAndroid Build Coastguard Worker}
200*333d2b36SAndroid Build Coastguard Worker
201*333d2b36SAndroid Build Coastguard Workerfunc (a *avbAddHashFooter) SignedOutputPath() android.Path {
202*333d2b36SAndroid Build Coastguard Worker	return a.OutputPath() // always signed
203*333d2b36SAndroid Build Coastguard Worker}
204*333d2b36SAndroid Build Coastguard Worker
205*333d2b36SAndroid Build Coastguard Worker// TODO(b/185115783): remove when not needed as input to a prebuilt_etc rule
206*333d2b36SAndroid Build Coastguard Workervar _ android.SourceFileProducer = (*avbAddHashFooter)(nil)
207*333d2b36SAndroid Build Coastguard Worker
208*333d2b36SAndroid Build Coastguard Worker// Implements android.SourceFileProducer
209*333d2b36SAndroid Build Coastguard Workerfunc (a *avbAddHashFooter) Srcs() android.Paths {
210*333d2b36SAndroid Build Coastguard Worker	return append(android.Paths{}, a.output)
211*333d2b36SAndroid Build Coastguard Worker}
212*333d2b36SAndroid Build Coastguard Worker
213*333d2b36SAndroid Build Coastguard Workertype avbAddHashFooterDefaults struct {
214*333d2b36SAndroid Build Coastguard Worker	android.ModuleBase
215*333d2b36SAndroid Build Coastguard Worker	android.DefaultsModuleBase
216*333d2b36SAndroid Build Coastguard Worker}
217*333d2b36SAndroid Build Coastguard Worker
218*333d2b36SAndroid Build Coastguard Worker// avb_add_hash_footer_defaults provides a set of properties that can be inherited by other
219*333d2b36SAndroid Build Coastguard Worker// avb_add_hash_footer modules. A module can use the properties from an avb_add_hash_footer_defaults
220*333d2b36SAndroid Build Coastguard Worker// using `defaults: ["<:default_module_name>"]`. Properties of both modules are erged (when
221*333d2b36SAndroid Build Coastguard Worker// possible) by prepending the default module's values to the depending module's values.
222*333d2b36SAndroid Build Coastguard Workerfunc avbAddHashFooterDefaultsFactory() android.Module {
223*333d2b36SAndroid Build Coastguard Worker	module := &avbAddHashFooterDefaults{}
224*333d2b36SAndroid Build Coastguard Worker	module.AddProperties(&avbAddHashFooterProperties{})
225*333d2b36SAndroid Build Coastguard Worker	android.InitDefaultsModule(module)
226*333d2b36SAndroid Build Coastguard Worker	return module
227*333d2b36SAndroid Build Coastguard Worker}
228