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