blob: e3bc7a7d300110c7bb21c8fdefdd69b63b9404c8 [file] [log] [blame]
Alice Wange089a212022-07-18 11:24:03 +00001// Copyright 2022, 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
15use apexutil::to_hex_string;
16use serde::{Deserialize, Serialize};
17use std::fmt;
18
19/// An Avmd struct contains
20/// - A header with version information that allows rollback when needed.
21/// - A list of descriptors that describe different images.
22#[derive(Serialize, Deserialize, Debug, Clone)]
23pub struct Avmd {
24 header: Header,
25 descriptors: Vec<Descriptor>,
26}
27
28impl fmt::Display for Avmd {
29 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
30 writeln!(f, "Descriptors:")?;
31 for descriptor in &self.descriptors {
32 write!(f, "{}", descriptor)?;
33 }
34 Ok(())
35 }
36}
37
38impl Avmd {
39 /// Creates an instance of Avmd with a given list of descriptors.
40 pub fn new(descriptors: Vec<Descriptor>) -> Avmd {
41 Avmd { header: Header::default(), descriptors }
42 }
43}
44
45static AVMD_MAGIC: u32 = 0x444d5641;
46static AVMD_VERSION_MAJOR: u16 = 1;
47static AVMD_VERSION_MINOR: u16 = 0;
48
49/// Header information for AVMD.
50#[derive(Serialize, Deserialize, Debug, Clone)]
51struct Header {
52 magic: u32,
53 version_major: u16,
54 version_minor: u16,
55}
56
57impl Default for Header {
58 fn default() -> Self {
59 Header {
60 magic: AVMD_MAGIC,
61 version_major: AVMD_VERSION_MAJOR,
62 version_minor: AVMD_VERSION_MINOR,
63 }
64 }
65}
66
67/// AVMD descriptor.
68#[derive(Serialize, Deserialize, Debug, Clone)]
69pub enum Descriptor {
70 /// Descriptor type for the VBMeta images.
71 VbMeta(VbMetaDescriptor),
72 /// Descriptor type for APK.
73 Apk(ApkDescriptor),
74}
75
76impl fmt::Display for Descriptor {
77 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
78 match self {
79 Descriptor::VbMeta(descriptor) => write!(f, "{}", descriptor),
80 Descriptor::Apk(descriptor) => write!(f, "{}", descriptor),
81 }
82 }
83}
84
85/// VbMeta descriptor.
86#[derive(Serialize, Deserialize, Debug, Clone)]
87pub struct VbMetaDescriptor {
88 /// The identifier of this resource.
89 #[serde(flatten)]
90 pub resource: ResourceIdentifier,
91 /// The SHA-512 [VBMeta digest][] calculated from the top-level VBMeta image.
92 ///
93 /// [VBMeta digest]: https://android.googlesource.com/platform/external/avb/+/master/README.md#the-vbmeta-digest
94 pub vbmeta_digest: Vec<u8>,
95}
96
97impl fmt::Display for VbMetaDescriptor {
98 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
99 writeln!(f, " VBMeta descriptor:")?;
100 writeln!(f, " namespace: {}", self.resource.namespace)?;
101 writeln!(f, " name: {}", self.resource.name)?;
102 writeln!(f, " vbmeta digest: {}", to_hex_string(&self.vbmeta_digest))?;
103 Ok(())
104 }
105}
106
107/// APK descriptor.
108#[derive(Serialize, Deserialize, Debug, Clone)]
109pub struct ApkDescriptor {
110 /// The identifier of this resource.
111 #[serde(flatten)]
112 pub resource: ResourceIdentifier,
113 /// The ID of the algoithm used to sign the APK.
114 /// It should be one of the algorithms in the [list][].
115 ///
116 /// [list]: https://source.android.com/security/apksigning/v2#signature-algorithm-ids
117 pub signature_algorithm_id: u32,
118 /// Digest of the APK's v3 signing block. TODO: fix
119 pub apk_digest: Vec<u8>,
120}
121
122impl fmt::Display for ApkDescriptor {
123 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
124 writeln!(f, " APK descriptor:")?;
125 writeln!(f, " namespace: {}", self.resource.namespace)?;
126 writeln!(f, " name: {}", self.resource.name)?;
127 writeln!(f, " Signing algorithm ID: {:#x}", self.signature_algorithm_id)?;
128 writeln!(f, " APK digest: {}", to_hex_string(&self.apk_digest))?;
129 Ok(())
130 }
131}
132
133/// Resource identifier regroups information to identify resources.
134#[derive(Serialize, Deserialize, Debug, Clone)]
135pub struct ResourceIdentifier {
136 /// Namespace of the resource.
137 namespace: String,
138 /// Name of the resource.
139 name: String,
140}
141
142impl ResourceIdentifier {
143 /// Creates an instance of ResourceIdentifier with the given
144 /// namespace and name.
145 pub fn new(namespace: &str, name: &str) -> ResourceIdentifier {
146 ResourceIdentifier { namespace: namespace.to_string(), name: name.to_string() }
147 }
148}