blob: b9a4026daa79ef2f682deba76dea9f41fbf6aeeb [file] [log] [blame]
Inseob Kim53391842024-03-29 17:44:07 +09001// Copyright (C) 2024 The Android Open Source Project
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15package filesystem
16
17import (
Spandan Dasd86882b2024-10-17 21:10:48 +000018 "fmt"
Inseob Kim53391842024-03-29 17:44:07 +090019 "path/filepath"
20 "strings"
21
22 "android/soong/android"
Inseob Kim5bda1032025-01-15 17:32:37 +090023
24 "github.com/google/blueprint/proptools"
Inseob Kim53391842024-03-29 17:44:07 +090025)
26
27type fsverityProperties struct {
28 // Patterns of files for fsverity metadata generation. For each matched file, a .fsv_meta file
29 // will be generated and included to the filesystem image.
30 // etc/security/fsverity/BuildManifest.apk will also be generated which contains information
31 // about generated .fsv_meta files.
Inseob Kim5bda1032025-01-15 17:32:37 +090032 Inputs proptools.Configurable[[]string]
Inseob Kim1e6afed2024-04-03 17:24:54 +090033
34 // APK libraries to link against, for etc/security/fsverity/BuildManifest.apk
Inseob Kim5bda1032025-01-15 17:32:37 +090035 Libs proptools.Configurable[[]string] `android:"path"`
Inseob Kim53391842024-03-29 17:44:07 +090036}
37
Cole Faust4e9f5922024-11-13 16:09:23 -080038func (f *filesystem) writeManifestGeneratorListFile(ctx android.ModuleContext, outputPath android.WritablePath, matchedSpecs []android.PackagingSpec, rebasedDir android.OutputPath) {
Inseob Kim53391842024-03-29 17:44:07 +090039 var buf strings.Builder
40 for _, spec := range matchedSpecs {
41 buf.WriteString(rebasedDir.Join(ctx, spec.RelPathInPackage()).String())
42 buf.WriteRune('\n')
43 }
44 android.WriteFileRuleVerbatim(ctx, outputPath, buf.String())
45}
46
47func (f *filesystem) buildFsverityMetadataFiles(ctx android.ModuleContext, builder *android.RuleBuilder, specs map[string]android.PackagingSpec, rootDir android.OutputPath, rebasedDir android.OutputPath) {
48 match := func(path string) bool {
Inseob Kim5bda1032025-01-15 17:32:37 +090049 for _, pattern := range f.properties.Fsverity.Inputs.GetOrDefault(ctx, nil) {
Inseob Kim53391842024-03-29 17:44:07 +090050 if matched, err := filepath.Match(pattern, path); matched {
51 return true
52 } else if err != nil {
53 ctx.PropertyErrorf("fsverity.inputs", "bad pattern %q", pattern)
54 return false
55 }
56 }
57 return false
58 }
59
60 var matchedSpecs []android.PackagingSpec
61 for _, relPath := range android.SortedKeys(specs) {
62 if match(relPath) {
63 matchedSpecs = append(matchedSpecs, specs[relPath])
64 }
65 }
66
67 if len(matchedSpecs) == 0 {
68 return
69 }
70
Inseob Kim53391842024-03-29 17:44:07 +090071 fsverityPath := ctx.Config().HostToolPath(ctx, "fsverity")
72
Inseob Kim53391842024-03-29 17:44:07 +090073 // STEP 1: generate .fsv_meta
74 var sb strings.Builder
75 sb.WriteString("set -e\n")
Inseob Kim53391842024-03-29 17:44:07 +090076 for _, spec := range matchedSpecs {
77 // srcPath is copied by CopySpecsToDir()
78 srcPath := rebasedDir.Join(ctx, spec.RelPathInPackage())
79 destPath := rebasedDir.Join(ctx, spec.RelPathInPackage()+".fsv_meta")
Cole Faustd7556eb2024-12-02 13:18:58 -080080 builder.Command().
81 BuiltTool("fsverity_metadata_generator").
82 FlagWithInput("--fsverity-path ", fsverityPath).
83 FlagWithArg("--signature ", "none").
84 FlagWithArg("--hash-alg ", "sha256").
85 FlagWithArg("--output ", destPath.String()).
86 Text(srcPath.String())
Kiyoung Kim99a954d2024-06-21 14:22:20 +090087 f.appendToEntry(ctx, destPath)
Inseob Kim53391842024-03-29 17:44:07 +090088 }
89
90 // STEP 2: generate signed BuildManifest.apk
91 // STEP 2-1: generate build_manifest.pb
Inseob Kim53391842024-03-29 17:44:07 +090092 manifestGeneratorListPath := android.PathForModuleOut(ctx, "fsverity_manifest.list")
Cole Faust4e9f5922024-11-13 16:09:23 -080093 f.writeManifestGeneratorListFile(ctx, manifestGeneratorListPath, matchedSpecs, rebasedDir)
Cole Faustd7556eb2024-12-02 13:18:58 -080094 assetsPath := android.PathForModuleOut(ctx, "fsverity_manifest/assets")
95 manifestPbPath := assetsPath.Join(ctx, "build_manifest.pb")
96 builder.Command().Text("rm -rf " + assetsPath.String())
97 builder.Command().Text("mkdir -p " + assetsPath.String())
98 builder.Command().
99 BuiltTool("fsverity_manifest_generator").
100 FlagWithInput("--fsverity-path ", fsverityPath).
101 FlagWithArg("--base-dir ", rootDir.String()).
102 FlagWithArg("--output ", manifestPbPath.String()).
103 FlagWithInput("@", manifestGeneratorListPath)
104
105 f.appendToEntry(ctx, manifestPbPath)
Cole Faust4e9f5922024-11-13 16:09:23 -0800106 f.appendToEntry(ctx, manifestGeneratorListPath)
Inseob Kim53391842024-03-29 17:44:07 +0900107
108 // STEP 2-2: generate BuildManifest.apk (unsigned)
Spandan Dasd86882b2024-10-17 21:10:48 +0000109 apkNameSuffix := ""
110 if f.PartitionType() == "system_ext" {
111 //https://source.corp.google.com/h/googleplex-android/platform/build/+/e392d2b486c2d4187b20a72b1c67cc737ecbcca5:core/Makefile;l=3410;drc=ea8f34bc1d6e63656b4ec32f2391e9d54b3ebb6b;bpv=1;bpt=0
112 apkNameSuffix = "SystemExt"
113 }
114 apkPath := rebasedDir.Join(ctx, "etc", "security", "fsverity", fmt.Sprintf("BuildManifest%s.apk", apkNameSuffix))
115 idsigPath := rebasedDir.Join(ctx, "etc", "security", "fsverity", fmt.Sprintf("BuildManifest%s.apk.idsig", apkNameSuffix))
Inseob Kim53391842024-03-29 17:44:07 +0900116 manifestTemplatePath := android.PathForSource(ctx, "system/security/fsverity/AndroidManifest.xml")
Inseob Kim5bda1032025-01-15 17:32:37 +0900117 libs := android.PathsForModuleSrc(ctx, f.properties.Fsverity.Libs.GetOrDefault(ctx, nil))
Inseob Kim53391842024-03-29 17:44:07 +0900118
Inseob Kim53391842024-03-29 17:44:07 +0900119 minSdkVersion := ctx.Config().PlatformSdkCodename()
120 if minSdkVersion == "REL" {
121 minSdkVersion = ctx.Config().PlatformSdkVersion().String()
122 }
Cole Faustd7556eb2024-12-02 13:18:58 -0800123
124 unsignedApkCommand := builder.Command().
125 BuiltTool("aapt2").
126 Text("link").
127 FlagWithOutput("-o ", apkPath).
128 FlagWithArg("-A ", assetsPath.String())
129 for _, lib := range libs {
130 unsignedApkCommand.FlagWithInput("-I ", lib)
131 }
132 unsignedApkCommand.
133 FlagWithArg("--min-sdk-version ", minSdkVersion).
134 FlagWithArg("--version-code ", ctx.Config().PlatformSdkVersion().String()).
135 FlagWithArg("--version-name ", ctx.Config().AppsDefaultVersionName()).
136 FlagWithInput("--manifest ", manifestTemplatePath).
137 Text(" --rename-manifest-package com.android.security.fsverity_metadata." + f.partitionName())
Inseob Kim53391842024-03-29 17:44:07 +0900138
Kiyoung Kim99a954d2024-06-21 14:22:20 +0900139 f.appendToEntry(ctx, apkPath)
140
Inseob Kim53391842024-03-29 17:44:07 +0900141 // STEP 2-3: sign BuildManifest.apk
Inseob Kim53391842024-03-29 17:44:07 +0900142 pemPath, keyPath := ctx.Config().DefaultAppCertificate(ctx)
Cole Faustd7556eb2024-12-02 13:18:58 -0800143 builder.Command().
144 BuiltTool("apksigner").
145 Text("sign").
146 FlagWithArg("--in ", apkPath.String()).
147 FlagWithInput("--cert ", pemPath).
148 FlagWithInput("--key ", keyPath).
149 ImplicitOutput(idsigPath)
Inseob Kim53391842024-03-29 17:44:07 +0900150
Kiyoung Kim99a954d2024-06-21 14:22:20 +0900151 f.appendToEntry(ctx, idsigPath)
Inseob Kim53391842024-03-29 17:44:07 +0900152}