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