xref: /aosp_15_r20/build/soong/filesystem/vbmeta.go (revision 333d2b3687b3a337dbcca9d65000bca186795e39)
1*333d2b36SAndroid Build Coastguard Worker// Copyright (C) 2021 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"
22*333d2b36SAndroid Build Coastguard Worker	"github.com/google/blueprint/proptools"
23*333d2b36SAndroid Build Coastguard Worker
24*333d2b36SAndroid Build Coastguard Worker	"android/soong/android"
25*333d2b36SAndroid Build Coastguard Worker)
26*333d2b36SAndroid Build Coastguard Worker
27*333d2b36SAndroid Build Coastguard Workerfunc init() {
28*333d2b36SAndroid Build Coastguard Worker	android.RegisterModuleType("vbmeta", VbmetaFactory)
29*333d2b36SAndroid Build Coastguard Worker	pctx.HostBinToolVariable("avbtool", "avbtool")
30*333d2b36SAndroid Build Coastguard Worker}
31*333d2b36SAndroid Build Coastguard Worker
32*333d2b36SAndroid Build Coastguard Workervar (
33*333d2b36SAndroid Build Coastguard Worker	extractPublicKeyRule = pctx.AndroidStaticRule("avb_extract_public_key",
34*333d2b36SAndroid Build Coastguard Worker		blueprint.RuleParams{
35*333d2b36SAndroid Build Coastguard Worker			Command: `${avbtool} extract_public_key --key $in --output $out`,
36*333d2b36SAndroid Build Coastguard Worker			CommandDeps: []string{
37*333d2b36SAndroid Build Coastguard Worker				"${avbtool}",
38*333d2b36SAndroid Build Coastguard Worker			},
39*333d2b36SAndroid Build Coastguard Worker		})
40*333d2b36SAndroid Build Coastguard Worker)
41*333d2b36SAndroid Build Coastguard Worker
42*333d2b36SAndroid Build Coastguard Workertype vbmeta struct {
43*333d2b36SAndroid Build Coastguard Worker	android.ModuleBase
44*333d2b36SAndroid Build Coastguard Worker
45*333d2b36SAndroid Build Coastguard Worker	properties VbmetaProperties
46*333d2b36SAndroid Build Coastguard Worker
47*333d2b36SAndroid Build Coastguard Worker	output     android.Path
48*333d2b36SAndroid Build Coastguard Worker	installDir android.InstallPath
49*333d2b36SAndroid Build Coastguard Worker}
50*333d2b36SAndroid Build Coastguard Worker
51*333d2b36SAndroid Build Coastguard Workertype VbmetaProperties struct {
52*333d2b36SAndroid Build Coastguard Worker	// Name of the partition stored in vbmeta desc. Defaults to the name of this module.
53*333d2b36SAndroid Build Coastguard Worker	Partition_name *string
54*333d2b36SAndroid Build Coastguard Worker
55*333d2b36SAndroid Build Coastguard Worker	// Set the name of the output. Defaults to <module_name>.img.
56*333d2b36SAndroid Build Coastguard Worker	Stem *string
57*333d2b36SAndroid Build Coastguard Worker
58*333d2b36SAndroid Build Coastguard Worker	// Path to the private key that avbtool will use to sign this vbmeta image.
59*333d2b36SAndroid Build Coastguard Worker	Private_key *string `android:"path"`
60*333d2b36SAndroid Build Coastguard Worker
61*333d2b36SAndroid Build Coastguard Worker	// Algorithm that avbtool will use to sign this vbmeta image. Default is SHA256_RSA4096.
62*333d2b36SAndroid Build Coastguard Worker	Algorithm *string
63*333d2b36SAndroid Build Coastguard Worker
64*333d2b36SAndroid Build Coastguard Worker	// The rollback index. If unspecified, the rollback index is from PLATFORM_SECURITY_PATCH
65*333d2b36SAndroid Build Coastguard Worker	Rollback_index *int64
66*333d2b36SAndroid Build Coastguard Worker
67*333d2b36SAndroid Build Coastguard Worker	// Rollback index location of this vbmeta image. Must be 0, 1, 2, etc. Default is 0.
68*333d2b36SAndroid Build Coastguard Worker	Rollback_index_location *int64
69*333d2b36SAndroid Build Coastguard Worker
70*333d2b36SAndroid Build Coastguard Worker	// List of filesystem modules that this vbmeta has descriptors for. The filesystem modules
71*333d2b36SAndroid Build Coastguard Worker	// have to be signed (use_avb: true).
72*333d2b36SAndroid Build Coastguard Worker	Partitions proptools.Configurable[[]string]
73*333d2b36SAndroid Build Coastguard Worker
74*333d2b36SAndroid Build Coastguard Worker	// Metadata about the chained partitions that this vbmeta delegates the verification.
75*333d2b36SAndroid Build Coastguard Worker	// This is an alternative to chained_partitions, using chained_partitions instead is simpler
76*333d2b36SAndroid Build Coastguard Worker	// in most cases. However, this property allows building this vbmeta partition without
77*333d2b36SAndroid Build Coastguard Worker	// its chained partitions existing in this build.
78*333d2b36SAndroid Build Coastguard Worker	Chained_partition_metadata []ChainedPartitionProperties
79*333d2b36SAndroid Build Coastguard Worker
80*333d2b36SAndroid Build Coastguard Worker	// List of chained partitions that this vbmeta delegates the verification. They are the
81*333d2b36SAndroid Build Coastguard Worker	// names of other vbmeta modules.
82*333d2b36SAndroid Build Coastguard Worker	Chained_partitions []string
83*333d2b36SAndroid Build Coastguard Worker
84*333d2b36SAndroid Build Coastguard Worker	// List of key-value pair of avb properties
85*333d2b36SAndroid Build Coastguard Worker	Avb_properties []avbProperty
86*333d2b36SAndroid Build Coastguard Worker}
87*333d2b36SAndroid Build Coastguard Worker
88*333d2b36SAndroid Build Coastguard Workertype avbProperty struct {
89*333d2b36SAndroid Build Coastguard Worker	// Key of given avb property
90*333d2b36SAndroid Build Coastguard Worker	Key *string
91*333d2b36SAndroid Build Coastguard Worker
92*333d2b36SAndroid Build Coastguard Worker	// Value of given avb property
93*333d2b36SAndroid Build Coastguard Worker	Value *string
94*333d2b36SAndroid Build Coastguard Worker}
95*333d2b36SAndroid Build Coastguard Worker
96*333d2b36SAndroid Build Coastguard Workertype ChainedPartitionProperties struct {
97*333d2b36SAndroid Build Coastguard Worker	// Name of the chained partition
98*333d2b36SAndroid Build Coastguard Worker	Name *string
99*333d2b36SAndroid Build Coastguard Worker
100*333d2b36SAndroid Build Coastguard Worker	// Rollback index location of the chained partition. Must be 0, 1, 2, etc. Default is the
101*333d2b36SAndroid Build Coastguard Worker	// index of this partition in the list + 1.
102*333d2b36SAndroid Build Coastguard Worker	Rollback_index_location *int64
103*333d2b36SAndroid Build Coastguard Worker
104*333d2b36SAndroid Build Coastguard Worker	// Path to the public key that the chained partition is signed with. If this is specified,
105*333d2b36SAndroid Build Coastguard Worker	// private_key is ignored.
106*333d2b36SAndroid Build Coastguard Worker	Public_key *string `android:"path"`
107*333d2b36SAndroid Build Coastguard Worker
108*333d2b36SAndroid Build Coastguard Worker	// Path to the private key that the chained partition is signed with. If this is specified,
109*333d2b36SAndroid Build Coastguard Worker	// and public_key is not specified, a public key is extracted from this private key and
110*333d2b36SAndroid Build Coastguard Worker	// the extracted public key is embedded in the vbmeta image.
111*333d2b36SAndroid Build Coastguard Worker	Private_key *string `android:"path"`
112*333d2b36SAndroid Build Coastguard Worker}
113*333d2b36SAndroid Build Coastguard Worker
114*333d2b36SAndroid Build Coastguard Workertype vbmetaPartitionInfo struct {
115*333d2b36SAndroid Build Coastguard Worker	// Name of the partition
116*333d2b36SAndroid Build Coastguard Worker	Name string
117*333d2b36SAndroid Build Coastguard Worker
118*333d2b36SAndroid Build Coastguard Worker	// Rollback index location, non-negative int
119*333d2b36SAndroid Build Coastguard Worker	RollbackIndexLocation int
120*333d2b36SAndroid Build Coastguard Worker
121*333d2b36SAndroid Build Coastguard Worker	// The path to the public key of the private key used to sign this partition. Derived from
122*333d2b36SAndroid Build Coastguard Worker	// the private key.
123*333d2b36SAndroid Build Coastguard Worker	PublicKey android.Path
124*333d2b36SAndroid Build Coastguard Worker}
125*333d2b36SAndroid Build Coastguard Worker
126*333d2b36SAndroid Build Coastguard Workervar vbmetaPartitionProvider = blueprint.NewProvider[vbmetaPartitionInfo]()
127*333d2b36SAndroid Build Coastguard Worker
128*333d2b36SAndroid Build Coastguard Worker// vbmeta is the partition image that has the verification information for other partitions.
129*333d2b36SAndroid Build Coastguard Workerfunc VbmetaFactory() android.Module {
130*333d2b36SAndroid Build Coastguard Worker	module := &vbmeta{}
131*333d2b36SAndroid Build Coastguard Worker	module.AddProperties(&module.properties)
132*333d2b36SAndroid Build Coastguard Worker	android.InitAndroidArchModule(module, android.DeviceSupported, android.MultilibCommon)
133*333d2b36SAndroid Build Coastguard Worker	return module
134*333d2b36SAndroid Build Coastguard Worker}
135*333d2b36SAndroid Build Coastguard Worker
136*333d2b36SAndroid Build Coastguard Workertype vbmetaDep struct {
137*333d2b36SAndroid Build Coastguard Worker	blueprint.BaseDependencyTag
138*333d2b36SAndroid Build Coastguard Worker}
139*333d2b36SAndroid Build Coastguard Worker
140*333d2b36SAndroid Build Coastguard Workertype chainedPartitionDep struct {
141*333d2b36SAndroid Build Coastguard Worker	blueprint.BaseDependencyTag
142*333d2b36SAndroid Build Coastguard Worker}
143*333d2b36SAndroid Build Coastguard Worker
144*333d2b36SAndroid Build Coastguard Workervar vbmetaPartitionDep = vbmetaDep{}
145*333d2b36SAndroid Build Coastguard Workervar vbmetaChainedPartitionDep = chainedPartitionDep{}
146*333d2b36SAndroid Build Coastguard Worker
147*333d2b36SAndroid Build Coastguard Workerfunc (v *vbmeta) DepsMutator(ctx android.BottomUpMutatorContext) {
148*333d2b36SAndroid Build Coastguard Worker	ctx.AddDependency(ctx.Module(), vbmetaPartitionDep, v.properties.Partitions.GetOrDefault(ctx, nil)...)
149*333d2b36SAndroid Build Coastguard Worker	ctx.AddDependency(ctx.Module(), vbmetaChainedPartitionDep, v.properties.Chained_partitions...)
150*333d2b36SAndroid Build Coastguard Worker}
151*333d2b36SAndroid Build Coastguard Worker
152*333d2b36SAndroid Build Coastguard Workerfunc (v *vbmeta) installFileName() string {
153*333d2b36SAndroid Build Coastguard Worker	return proptools.StringDefault(v.properties.Stem, v.BaseModuleName()+".img")
154*333d2b36SAndroid Build Coastguard Worker}
155*333d2b36SAndroid Build Coastguard Worker
156*333d2b36SAndroid Build Coastguard Workerfunc (v *vbmeta) partitionName() string {
157*333d2b36SAndroid Build Coastguard Worker	return proptools.StringDefault(v.properties.Partition_name, v.BaseModuleName())
158*333d2b36SAndroid Build Coastguard Worker}
159*333d2b36SAndroid Build Coastguard Worker
160*333d2b36SAndroid Build Coastguard Worker// See external/avb/libavb/avb_slot_verify.c#VBMETA_MAX_SIZE
161*333d2b36SAndroid Build Coastguard Workerconst vbmetaMaxSize = 64 * 1024
162*333d2b36SAndroid Build Coastguard Worker
163*333d2b36SAndroid Build Coastguard Workerfunc (v *vbmeta) GenerateAndroidBuildActions(ctx android.ModuleContext) {
164*333d2b36SAndroid Build Coastguard Worker	builder := android.NewRuleBuilder(pctx, ctx)
165*333d2b36SAndroid Build Coastguard Worker	cmd := builder.Command().BuiltTool("avbtool").Text("make_vbmeta_image")
166*333d2b36SAndroid Build Coastguard Worker
167*333d2b36SAndroid Build Coastguard Worker	key := android.PathForModuleSrc(ctx, proptools.String(v.properties.Private_key))
168*333d2b36SAndroid Build Coastguard Worker	cmd.FlagWithInput("--key ", key)
169*333d2b36SAndroid Build Coastguard Worker
170*333d2b36SAndroid Build Coastguard Worker	algorithm := proptools.StringDefault(v.properties.Algorithm, "SHA256_RSA4096")
171*333d2b36SAndroid Build Coastguard Worker	cmd.FlagWithArg("--algorithm ", algorithm)
172*333d2b36SAndroid Build Coastguard Worker
173*333d2b36SAndroid Build Coastguard Worker	cmd.FlagWithArg("--rollback_index ", v.rollbackIndexCommand(ctx))
174*333d2b36SAndroid Build Coastguard Worker	ril := proptools.IntDefault(v.properties.Rollback_index_location, 0)
175*333d2b36SAndroid Build Coastguard Worker	if ril < 0 {
176*333d2b36SAndroid Build Coastguard Worker		ctx.PropertyErrorf("rollback_index_location", "must be 0, 1, 2, ...")
177*333d2b36SAndroid Build Coastguard Worker		return
178*333d2b36SAndroid Build Coastguard Worker	}
179*333d2b36SAndroid Build Coastguard Worker	cmd.FlagWithArg("--rollback_index_location ", strconv.Itoa(ril))
180*333d2b36SAndroid Build Coastguard Worker
181*333d2b36SAndroid Build Coastguard Worker	for _, avb_prop := range v.properties.Avb_properties {
182*333d2b36SAndroid Build Coastguard Worker		key := proptools.String(avb_prop.Key)
183*333d2b36SAndroid Build Coastguard Worker		if key == "" {
184*333d2b36SAndroid Build Coastguard Worker			ctx.PropertyErrorf("avb_properties", "key must be specified")
185*333d2b36SAndroid Build Coastguard Worker			continue
186*333d2b36SAndroid Build Coastguard Worker		}
187*333d2b36SAndroid Build Coastguard Worker		value := proptools.String(avb_prop.Value)
188*333d2b36SAndroid Build Coastguard Worker		if value == "" {
189*333d2b36SAndroid Build Coastguard Worker			ctx.PropertyErrorf("avb_properties", "value must be specified")
190*333d2b36SAndroid Build Coastguard Worker			continue
191*333d2b36SAndroid Build Coastguard Worker		}
192*333d2b36SAndroid Build Coastguard Worker		cmd.FlagWithArg("--prop ", key+":"+value)
193*333d2b36SAndroid Build Coastguard Worker	}
194*333d2b36SAndroid Build Coastguard Worker
195*333d2b36SAndroid Build Coastguard Worker	for _, p := range ctx.GetDirectDepsWithTag(vbmetaPartitionDep) {
196*333d2b36SAndroid Build Coastguard Worker		f, ok := p.(Filesystem)
197*333d2b36SAndroid Build Coastguard Worker		if !ok {
198*333d2b36SAndroid Build Coastguard Worker			ctx.PropertyErrorf("partitions", "%q(type: %s) is not supported",
199*333d2b36SAndroid Build Coastguard Worker				p.Name(), ctx.OtherModuleType(p))
200*333d2b36SAndroid Build Coastguard Worker			continue
201*333d2b36SAndroid Build Coastguard Worker		}
202*333d2b36SAndroid Build Coastguard Worker		signedImage := f.SignedOutputPath()
203*333d2b36SAndroid Build Coastguard Worker		if signedImage == nil {
204*333d2b36SAndroid Build Coastguard Worker			ctx.PropertyErrorf("partitions", "%q(type: %s) is not signed. Use `use_avb: true`",
205*333d2b36SAndroid Build Coastguard Worker				p.Name(), ctx.OtherModuleType(p))
206*333d2b36SAndroid Build Coastguard Worker			continue
207*333d2b36SAndroid Build Coastguard Worker		}
208*333d2b36SAndroid Build Coastguard Worker		cmd.FlagWithInput("--include_descriptors_from_image ", signedImage)
209*333d2b36SAndroid Build Coastguard Worker	}
210*333d2b36SAndroid Build Coastguard Worker
211*333d2b36SAndroid Build Coastguard Worker	seenRils := make(map[int]bool)
212*333d2b36SAndroid Build Coastguard Worker	for _, cp := range ctx.GetDirectDepsWithTag(vbmetaChainedPartitionDep) {
213*333d2b36SAndroid Build Coastguard Worker		info, ok := android.OtherModuleProvider(ctx, cp, vbmetaPartitionProvider)
214*333d2b36SAndroid Build Coastguard Worker		if !ok {
215*333d2b36SAndroid Build Coastguard Worker			ctx.PropertyErrorf("chained_partitions", "Expected all modules in chained_partitions to provide vbmetaPartitionProvider, but %s did not", cp.Name())
216*333d2b36SAndroid Build Coastguard Worker			continue
217*333d2b36SAndroid Build Coastguard Worker		}
218*333d2b36SAndroid Build Coastguard Worker		if info.Name == "" {
219*333d2b36SAndroid Build Coastguard Worker			ctx.PropertyErrorf("chained_partitions", "name must be specified")
220*333d2b36SAndroid Build Coastguard Worker			continue
221*333d2b36SAndroid Build Coastguard Worker		}
222*333d2b36SAndroid Build Coastguard Worker
223*333d2b36SAndroid Build Coastguard Worker		ril := info.RollbackIndexLocation
224*333d2b36SAndroid Build Coastguard Worker		if ril < 0 {
225*333d2b36SAndroid Build Coastguard Worker			ctx.PropertyErrorf("chained_partitions", "rollback index location must be 0, 1, 2, ...")
226*333d2b36SAndroid Build Coastguard Worker			continue
227*333d2b36SAndroid Build Coastguard Worker		} else if seenRils[ril] {
228*333d2b36SAndroid Build Coastguard Worker			ctx.PropertyErrorf("chained_partitions", "Multiple chained partitions with the same rollback index location %d", ril)
229*333d2b36SAndroid Build Coastguard Worker			continue
230*333d2b36SAndroid Build Coastguard Worker		}
231*333d2b36SAndroid Build Coastguard Worker		seenRils[ril] = true
232*333d2b36SAndroid Build Coastguard Worker
233*333d2b36SAndroid Build Coastguard Worker		publicKey := info.PublicKey
234*333d2b36SAndroid Build Coastguard Worker		cmd.FlagWithArg("--chain_partition ", fmt.Sprintf("%s:%d:%s", info.Name, ril, publicKey.String()))
235*333d2b36SAndroid Build Coastguard Worker		cmd.Implicit(publicKey)
236*333d2b36SAndroid Build Coastguard Worker	}
237*333d2b36SAndroid Build Coastguard Worker	for _, cpm := range v.properties.Chained_partition_metadata {
238*333d2b36SAndroid Build Coastguard Worker		name := proptools.String(cpm.Name)
239*333d2b36SAndroid Build Coastguard Worker		if name == "" {
240*333d2b36SAndroid Build Coastguard Worker			ctx.PropertyErrorf("chained_partitions", "name must be specified")
241*333d2b36SAndroid Build Coastguard Worker			continue
242*333d2b36SAndroid Build Coastguard Worker		}
243*333d2b36SAndroid Build Coastguard Worker
244*333d2b36SAndroid Build Coastguard Worker		ril := proptools.IntDefault(cpm.Rollback_index_location, -1)
245*333d2b36SAndroid Build Coastguard Worker		if ril < 0 {
246*333d2b36SAndroid Build Coastguard Worker			ctx.PropertyErrorf("chained_partition_metadata", "rollback index location must be 0, 1, 2, ...")
247*333d2b36SAndroid Build Coastguard Worker			continue
248*333d2b36SAndroid Build Coastguard Worker		} else if seenRils[ril] {
249*333d2b36SAndroid Build Coastguard Worker			ctx.PropertyErrorf("chained_partition_metadata", "Multiple chained partitions with the same rollback index location %d", ril)
250*333d2b36SAndroid Build Coastguard Worker			continue
251*333d2b36SAndroid Build Coastguard Worker		}
252*333d2b36SAndroid Build Coastguard Worker		seenRils[ril] = true
253*333d2b36SAndroid Build Coastguard Worker
254*333d2b36SAndroid Build Coastguard Worker		var publicKey android.Path
255*333d2b36SAndroid Build Coastguard Worker		if cpm.Public_key != nil {
256*333d2b36SAndroid Build Coastguard Worker			publicKey = android.PathForModuleSrc(ctx, *cpm.Public_key)
257*333d2b36SAndroid Build Coastguard Worker		} else if cpm.Private_key != nil {
258*333d2b36SAndroid Build Coastguard Worker			privateKey := android.PathForModuleSrc(ctx, *cpm.Private_key)
259*333d2b36SAndroid Build Coastguard Worker			extractedPublicKey := android.PathForModuleOut(ctx, "chained_metadata", name+".avbpubkey")
260*333d2b36SAndroid Build Coastguard Worker			ctx.Build(pctx, android.BuildParams{
261*333d2b36SAndroid Build Coastguard Worker				Rule:   extractPublicKeyRule,
262*333d2b36SAndroid Build Coastguard Worker				Input:  privateKey,
263*333d2b36SAndroid Build Coastguard Worker				Output: extractedPublicKey,
264*333d2b36SAndroid Build Coastguard Worker			})
265*333d2b36SAndroid Build Coastguard Worker			publicKey = extractedPublicKey
266*333d2b36SAndroid Build Coastguard Worker		} else {
267*333d2b36SAndroid Build Coastguard Worker			ctx.PropertyErrorf("public_key", "Either public_key or private_key must be specified")
268*333d2b36SAndroid Build Coastguard Worker			continue
269*333d2b36SAndroid Build Coastguard Worker		}
270*333d2b36SAndroid Build Coastguard Worker
271*333d2b36SAndroid Build Coastguard Worker		cmd.FlagWithArg("--chain_partition ", fmt.Sprintf("%s:%d:%s", name, ril, publicKey.String()))
272*333d2b36SAndroid Build Coastguard Worker		cmd.Implicit(publicKey)
273*333d2b36SAndroid Build Coastguard Worker	}
274*333d2b36SAndroid Build Coastguard Worker
275*333d2b36SAndroid Build Coastguard Worker	output := android.PathForModuleOut(ctx, v.installFileName())
276*333d2b36SAndroid Build Coastguard Worker	cmd.FlagWithOutput("--output ", output)
277*333d2b36SAndroid Build Coastguard Worker
278*333d2b36SAndroid Build Coastguard Worker	// libavb expects to be able to read the maximum vbmeta size, so we must provide a partition
279*333d2b36SAndroid Build Coastguard Worker	// which matches this or the read will fail.
280*333d2b36SAndroid Build Coastguard Worker	builder.Command().Text("truncate").
281*333d2b36SAndroid Build Coastguard Worker		FlagWithArg("-s ", strconv.Itoa(vbmetaMaxSize)).
282*333d2b36SAndroid Build Coastguard Worker		Output(output)
283*333d2b36SAndroid Build Coastguard Worker
284*333d2b36SAndroid Build Coastguard Worker	builder.Build("vbmeta", fmt.Sprintf("vbmeta %s", ctx.ModuleName()))
285*333d2b36SAndroid Build Coastguard Worker
286*333d2b36SAndroid Build Coastguard Worker	v.installDir = android.PathForModuleInstall(ctx, "etc")
287*333d2b36SAndroid Build Coastguard Worker	ctx.InstallFile(v.installDir, v.installFileName(), output)
288*333d2b36SAndroid Build Coastguard Worker
289*333d2b36SAndroid Build Coastguard Worker	extractedPublicKey := android.PathForModuleOut(ctx, v.partitionName()+".avbpubkey")
290*333d2b36SAndroid Build Coastguard Worker	ctx.Build(pctx, android.BuildParams{
291*333d2b36SAndroid Build Coastguard Worker		Rule:   extractPublicKeyRule,
292*333d2b36SAndroid Build Coastguard Worker		Input:  key,
293*333d2b36SAndroid Build Coastguard Worker		Output: extractedPublicKey,
294*333d2b36SAndroid Build Coastguard Worker	})
295*333d2b36SAndroid Build Coastguard Worker
296*333d2b36SAndroid Build Coastguard Worker	android.SetProvider(ctx, vbmetaPartitionProvider, vbmetaPartitionInfo{
297*333d2b36SAndroid Build Coastguard Worker		Name:                  v.partitionName(),
298*333d2b36SAndroid Build Coastguard Worker		RollbackIndexLocation: ril,
299*333d2b36SAndroid Build Coastguard Worker		PublicKey:             extractedPublicKey,
300*333d2b36SAndroid Build Coastguard Worker	})
301*333d2b36SAndroid Build Coastguard Worker
302*333d2b36SAndroid Build Coastguard Worker	ctx.SetOutputFiles([]android.Path{output}, "")
303*333d2b36SAndroid Build Coastguard Worker	v.output = output
304*333d2b36SAndroid Build Coastguard Worker}
305*333d2b36SAndroid Build Coastguard Worker
306*333d2b36SAndroid Build Coastguard Worker// Returns the embedded shell command that prints the rollback index
307*333d2b36SAndroid Build Coastguard Workerfunc (v *vbmeta) rollbackIndexCommand(ctx android.ModuleContext) string {
308*333d2b36SAndroid Build Coastguard Worker	if v.properties.Rollback_index != nil {
309*333d2b36SAndroid Build Coastguard Worker		return fmt.Sprintf("%d", *v.properties.Rollback_index)
310*333d2b36SAndroid Build Coastguard Worker	} else {
311*333d2b36SAndroid Build Coastguard Worker		// Take the first line and remove the newline char
312*333d2b36SAndroid Build Coastguard Worker		return "$(date -d 'TZ=\"GMT\" " + ctx.Config().PlatformSecurityPatch() + "' +%s | head -1 | tr -d '\n'" + ")"
313*333d2b36SAndroid Build Coastguard Worker	}
314*333d2b36SAndroid Build Coastguard Worker}
315*333d2b36SAndroid Build Coastguard Worker
316*333d2b36SAndroid Build Coastguard Workervar _ android.AndroidMkProviderInfoProducer = (*vbmeta)(nil)
317*333d2b36SAndroid Build Coastguard Worker
318*333d2b36SAndroid Build Coastguard Workerfunc (v *vbmeta) PrepareAndroidMKProviderInfo(config android.Config) *android.AndroidMkProviderInfo {
319*333d2b36SAndroid Build Coastguard Worker	providerData := android.AndroidMkProviderInfo{
320*333d2b36SAndroid Build Coastguard Worker		PrimaryInfo: android.AndroidMkInfo{
321*333d2b36SAndroid Build Coastguard Worker			Class:      "ETC",
322*333d2b36SAndroid Build Coastguard Worker			OutputFile: android.OptionalPathForPath(v.output),
323*333d2b36SAndroid Build Coastguard Worker			EntryMap:   make(map[string][]string),
324*333d2b36SAndroid Build Coastguard Worker		},
325*333d2b36SAndroid Build Coastguard Worker	}
326*333d2b36SAndroid Build Coastguard Worker	providerData.PrimaryInfo.SetString("LOCAL_MODULE_PATH", v.installDir.String())
327*333d2b36SAndroid Build Coastguard Worker	providerData.PrimaryInfo.SetString("LOCAL_INSTALLED_MODULE_STEM", v.installFileName())
328*333d2b36SAndroid Build Coastguard Worker	return &providerData
329*333d2b36SAndroid Build Coastguard Worker}
330*333d2b36SAndroid Build Coastguard Worker
331*333d2b36SAndroid Build Coastguard Workervar _ Filesystem = (*vbmeta)(nil)
332*333d2b36SAndroid Build Coastguard Worker
333*333d2b36SAndroid Build Coastguard Workerfunc (v *vbmeta) OutputPath() android.Path {
334*333d2b36SAndroid Build Coastguard Worker	return v.output
335*333d2b36SAndroid Build Coastguard Worker}
336*333d2b36SAndroid Build Coastguard Worker
337*333d2b36SAndroid Build Coastguard Workerfunc (v *vbmeta) SignedOutputPath() android.Path {
338*333d2b36SAndroid Build Coastguard Worker	return v.OutputPath() // vbmeta is always signed
339*333d2b36SAndroid Build Coastguard Worker}
340