xref: /aosp_15_r20/build/soong/filesystem/fsverity_metadata.go (revision 333d2b3687b3a337dbcca9d65000bca186795e39)
1*333d2b36SAndroid Build Coastguard Worker// Copyright (C) 2024 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	"path/filepath"
20*333d2b36SAndroid Build Coastguard Worker	"strings"
21*333d2b36SAndroid Build Coastguard Worker
22*333d2b36SAndroid Build Coastguard Worker	"android/soong/android"
23*333d2b36SAndroid Build Coastguard Worker)
24*333d2b36SAndroid Build Coastguard Worker
25*333d2b36SAndroid Build Coastguard Workertype fsverityProperties struct {
26*333d2b36SAndroid Build Coastguard Worker	// Patterns of files for fsverity metadata generation.  For each matched file, a .fsv_meta file
27*333d2b36SAndroid Build Coastguard Worker	// will be generated and included to the filesystem image.
28*333d2b36SAndroid Build Coastguard Worker	// etc/security/fsverity/BuildManifest.apk will also be generated which contains information
29*333d2b36SAndroid Build Coastguard Worker	// about generated .fsv_meta files.
30*333d2b36SAndroid Build Coastguard Worker	Inputs []string
31*333d2b36SAndroid Build Coastguard Worker
32*333d2b36SAndroid Build Coastguard Worker	// APK libraries to link against, for etc/security/fsverity/BuildManifest.apk
33*333d2b36SAndroid Build Coastguard Worker	Libs []string `android:"path"`
34*333d2b36SAndroid Build Coastguard Worker}
35*333d2b36SAndroid Build Coastguard Worker
36*333d2b36SAndroid Build Coastguard Workerfunc (f *filesystem) writeManifestGeneratorListFile(ctx android.ModuleContext, outputPath android.WritablePath, matchedSpecs []android.PackagingSpec, rebasedDir android.OutputPath) {
37*333d2b36SAndroid Build Coastguard Worker	var buf strings.Builder
38*333d2b36SAndroid Build Coastguard Worker	for _, spec := range matchedSpecs {
39*333d2b36SAndroid Build Coastguard Worker		buf.WriteString(rebasedDir.Join(ctx, spec.RelPathInPackage()).String())
40*333d2b36SAndroid Build Coastguard Worker		buf.WriteRune('\n')
41*333d2b36SAndroid Build Coastguard Worker	}
42*333d2b36SAndroid Build Coastguard Worker	android.WriteFileRuleVerbatim(ctx, outputPath, buf.String())
43*333d2b36SAndroid Build Coastguard Worker}
44*333d2b36SAndroid Build Coastguard Worker
45*333d2b36SAndroid Build Coastguard Workerfunc (f *filesystem) buildFsverityMetadataFiles(ctx android.ModuleContext, builder *android.RuleBuilder, specs map[string]android.PackagingSpec, rootDir android.OutputPath, rebasedDir android.OutputPath) {
46*333d2b36SAndroid Build Coastguard Worker	match := func(path string) bool {
47*333d2b36SAndroid Build Coastguard Worker		for _, pattern := range f.properties.Fsverity.Inputs {
48*333d2b36SAndroid Build Coastguard Worker			if matched, err := filepath.Match(pattern, path); matched {
49*333d2b36SAndroid Build Coastguard Worker				return true
50*333d2b36SAndroid Build Coastguard Worker			} else if err != nil {
51*333d2b36SAndroid Build Coastguard Worker				ctx.PropertyErrorf("fsverity.inputs", "bad pattern %q", pattern)
52*333d2b36SAndroid Build Coastguard Worker				return false
53*333d2b36SAndroid Build Coastguard Worker			}
54*333d2b36SAndroid Build Coastguard Worker		}
55*333d2b36SAndroid Build Coastguard Worker		return false
56*333d2b36SAndroid Build Coastguard Worker	}
57*333d2b36SAndroid Build Coastguard Worker
58*333d2b36SAndroid Build Coastguard Worker	var matchedSpecs []android.PackagingSpec
59*333d2b36SAndroid Build Coastguard Worker	for _, relPath := range android.SortedKeys(specs) {
60*333d2b36SAndroid Build Coastguard Worker		if match(relPath) {
61*333d2b36SAndroid Build Coastguard Worker			matchedSpecs = append(matchedSpecs, specs[relPath])
62*333d2b36SAndroid Build Coastguard Worker		}
63*333d2b36SAndroid Build Coastguard Worker	}
64*333d2b36SAndroid Build Coastguard Worker
65*333d2b36SAndroid Build Coastguard Worker	if len(matchedSpecs) == 0 {
66*333d2b36SAndroid Build Coastguard Worker		return
67*333d2b36SAndroid Build Coastguard Worker	}
68*333d2b36SAndroid Build Coastguard Worker
69*333d2b36SAndroid Build Coastguard Worker	fsverityPath := ctx.Config().HostToolPath(ctx, "fsverity")
70*333d2b36SAndroid Build Coastguard Worker
71*333d2b36SAndroid Build Coastguard Worker	// STEP 1: generate .fsv_meta
72*333d2b36SAndroid Build Coastguard Worker	var sb strings.Builder
73*333d2b36SAndroid Build Coastguard Worker	sb.WriteString("set -e\n")
74*333d2b36SAndroid Build Coastguard Worker	for _, spec := range matchedSpecs {
75*333d2b36SAndroid Build Coastguard Worker		// srcPath is copied by CopySpecsToDir()
76*333d2b36SAndroid Build Coastguard Worker		srcPath := rebasedDir.Join(ctx, spec.RelPathInPackage())
77*333d2b36SAndroid Build Coastguard Worker		destPath := rebasedDir.Join(ctx, spec.RelPathInPackage()+".fsv_meta")
78*333d2b36SAndroid Build Coastguard Worker		builder.Command().
79*333d2b36SAndroid Build Coastguard Worker			BuiltTool("fsverity_metadata_generator").
80*333d2b36SAndroid Build Coastguard Worker			FlagWithInput("--fsverity-path ", fsverityPath).
81*333d2b36SAndroid Build Coastguard Worker			FlagWithArg("--signature ", "none").
82*333d2b36SAndroid Build Coastguard Worker			FlagWithArg("--hash-alg ", "sha256").
83*333d2b36SAndroid Build Coastguard Worker			FlagWithArg("--output ", destPath.String()).
84*333d2b36SAndroid Build Coastguard Worker			Text(srcPath.String())
85*333d2b36SAndroid Build Coastguard Worker		f.appendToEntry(ctx, destPath)
86*333d2b36SAndroid Build Coastguard Worker	}
87*333d2b36SAndroid Build Coastguard Worker
88*333d2b36SAndroid Build Coastguard Worker	// STEP 2: generate signed BuildManifest.apk
89*333d2b36SAndroid Build Coastguard Worker	// STEP 2-1: generate build_manifest.pb
90*333d2b36SAndroid Build Coastguard Worker	manifestGeneratorListPath := android.PathForModuleOut(ctx, "fsverity_manifest.list")
91*333d2b36SAndroid Build Coastguard Worker	f.writeManifestGeneratorListFile(ctx, manifestGeneratorListPath, matchedSpecs, rebasedDir)
92*333d2b36SAndroid Build Coastguard Worker	assetsPath := android.PathForModuleOut(ctx, "fsverity_manifest/assets")
93*333d2b36SAndroid Build Coastguard Worker	manifestPbPath := assetsPath.Join(ctx, "build_manifest.pb")
94*333d2b36SAndroid Build Coastguard Worker	builder.Command().Text("rm -rf " + assetsPath.String())
95*333d2b36SAndroid Build Coastguard Worker	builder.Command().Text("mkdir -p " + assetsPath.String())
96*333d2b36SAndroid Build Coastguard Worker	builder.Command().
97*333d2b36SAndroid Build Coastguard Worker		BuiltTool("fsverity_manifest_generator").
98*333d2b36SAndroid Build Coastguard Worker		FlagWithInput("--fsverity-path ", fsverityPath).
99*333d2b36SAndroid Build Coastguard Worker		FlagWithArg("--base-dir ", rootDir.String()).
100*333d2b36SAndroid Build Coastguard Worker		FlagWithArg("--output ", manifestPbPath.String()).
101*333d2b36SAndroid Build Coastguard Worker		FlagWithInput("@", manifestGeneratorListPath)
102*333d2b36SAndroid Build Coastguard Worker
103*333d2b36SAndroid Build Coastguard Worker	f.appendToEntry(ctx, manifestPbPath)
104*333d2b36SAndroid Build Coastguard Worker	f.appendToEntry(ctx, manifestGeneratorListPath)
105*333d2b36SAndroid Build Coastguard Worker
106*333d2b36SAndroid Build Coastguard Worker	// STEP 2-2: generate BuildManifest.apk (unsigned)
107*333d2b36SAndroid Build Coastguard Worker	apkNameSuffix := ""
108*333d2b36SAndroid Build Coastguard Worker	if f.PartitionType() == "system_ext" {
109*333d2b36SAndroid Build Coastguard Worker		//https://source.corp.google.com/h/googleplex-android/platform/build/+/e392d2b486c2d4187b20a72b1c67cc737ecbcca5:core/Makefile;l=3410;drc=ea8f34bc1d6e63656b4ec32f2391e9d54b3ebb6b;bpv=1;bpt=0
110*333d2b36SAndroid Build Coastguard Worker		apkNameSuffix = "SystemExt"
111*333d2b36SAndroid Build Coastguard Worker	}
112*333d2b36SAndroid Build Coastguard Worker	apkPath := rebasedDir.Join(ctx, "etc", "security", "fsverity", fmt.Sprintf("BuildManifest%s.apk", apkNameSuffix))
113*333d2b36SAndroid Build Coastguard Worker	idsigPath := rebasedDir.Join(ctx, "etc", "security", "fsverity", fmt.Sprintf("BuildManifest%s.apk.idsig", apkNameSuffix))
114*333d2b36SAndroid Build Coastguard Worker	manifestTemplatePath := android.PathForSource(ctx, "system/security/fsverity/AndroidManifest.xml")
115*333d2b36SAndroid Build Coastguard Worker	libs := android.PathsForModuleSrc(ctx, f.properties.Fsverity.Libs)
116*333d2b36SAndroid Build Coastguard Worker
117*333d2b36SAndroid Build Coastguard Worker	minSdkVersion := ctx.Config().PlatformSdkCodename()
118*333d2b36SAndroid Build Coastguard Worker	if minSdkVersion == "REL" {
119*333d2b36SAndroid Build Coastguard Worker		minSdkVersion = ctx.Config().PlatformSdkVersion().String()
120*333d2b36SAndroid Build Coastguard Worker	}
121*333d2b36SAndroid Build Coastguard Worker
122*333d2b36SAndroid Build Coastguard Worker	unsignedApkCommand := builder.Command().
123*333d2b36SAndroid Build Coastguard Worker		BuiltTool("aapt2").
124*333d2b36SAndroid Build Coastguard Worker		Text("link").
125*333d2b36SAndroid Build Coastguard Worker		FlagWithOutput("-o ", apkPath).
126*333d2b36SAndroid Build Coastguard Worker		FlagWithArg("-A ", assetsPath.String())
127*333d2b36SAndroid Build Coastguard Worker	for _, lib := range libs {
128*333d2b36SAndroid Build Coastguard Worker		unsignedApkCommand.FlagWithInput("-I ", lib)
129*333d2b36SAndroid Build Coastguard Worker	}
130*333d2b36SAndroid Build Coastguard Worker	unsignedApkCommand.
131*333d2b36SAndroid Build Coastguard Worker		FlagWithArg("--min-sdk-version ", minSdkVersion).
132*333d2b36SAndroid Build Coastguard Worker		FlagWithArg("--version-code ", ctx.Config().PlatformSdkVersion().String()).
133*333d2b36SAndroid Build Coastguard Worker		FlagWithArg("--version-name ", ctx.Config().AppsDefaultVersionName()).
134*333d2b36SAndroid Build Coastguard Worker		FlagWithInput("--manifest ", manifestTemplatePath).
135*333d2b36SAndroid Build Coastguard Worker		Text(" --rename-manifest-package com.android.security.fsverity_metadata." + f.partitionName())
136*333d2b36SAndroid Build Coastguard Worker
137*333d2b36SAndroid Build Coastguard Worker	f.appendToEntry(ctx, apkPath)
138*333d2b36SAndroid Build Coastguard Worker
139*333d2b36SAndroid Build Coastguard Worker	// STEP 2-3: sign BuildManifest.apk
140*333d2b36SAndroid Build Coastguard Worker	pemPath, keyPath := ctx.Config().DefaultAppCertificate(ctx)
141*333d2b36SAndroid Build Coastguard Worker	builder.Command().
142*333d2b36SAndroid Build Coastguard Worker		BuiltTool("apksigner").
143*333d2b36SAndroid Build Coastguard Worker		Text("sign").
144*333d2b36SAndroid Build Coastguard Worker		FlagWithArg("--in ", apkPath.String()).
145*333d2b36SAndroid Build Coastguard Worker		FlagWithInput("--cert ", pemPath).
146*333d2b36SAndroid Build Coastguard Worker		FlagWithInput("--key ", keyPath).
147*333d2b36SAndroid Build Coastguard Worker		ImplicitOutput(idsigPath)
148*333d2b36SAndroid Build Coastguard Worker
149*333d2b36SAndroid Build Coastguard Worker	f.appendToEntry(ctx, idsigPath)
150*333d2b36SAndroid Build Coastguard Worker}
151