blob: 429c98036f7d8bdd985f077be6c1f1964f4ad42d [file] [log] [blame]
Alice Wang28cbcf12022-12-01 07:58:28 +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
15//! This module regroups methods related to AvbOps.
16
17#![warn(unsafe_op_in_unsafe_fn)]
18// TODO(b/256148034): Remove this when the feature is code complete.
19#![allow(dead_code)]
20#![allow(unused_imports)]
21
Alice Wang28cbcf12022-12-01 07:58:28 +000022use alloc::ffi::CString;
23use avb_bindgen::{
24 avb_slot_verify, AvbHashtreeErrorMode_AVB_HASHTREE_ERROR_MODE_EIO,
25 AvbSlotVerifyFlags_AVB_SLOT_VERIFY_FLAGS_NO_VBMETA_PARTITION,
26 AvbSlotVerifyResult_AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_ARGUMENT,
27 AvbSlotVerifyResult_AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_METADATA,
28 AvbSlotVerifyResult_AVB_SLOT_VERIFY_RESULT_ERROR_IO,
29 AvbSlotVerifyResult_AVB_SLOT_VERIFY_RESULT_ERROR_OOM,
30 AvbSlotVerifyResult_AVB_SLOT_VERIFY_RESULT_ERROR_PUBLIC_KEY_REJECTED,
31 AvbSlotVerifyResult_AVB_SLOT_VERIFY_RESULT_ERROR_ROLLBACK_INDEX,
32 AvbSlotVerifyResult_AVB_SLOT_VERIFY_RESULT_ERROR_UNSUPPORTED_VERSION,
33 AvbSlotVerifyResult_AVB_SLOT_VERIFY_RESULT_ERROR_VERIFICATION,
34 AvbSlotVerifyResult_AVB_SLOT_VERIFY_RESULT_OK,
35};
36use core::fmt;
37use log::debug;
38
39/// Error code from AVB image verification.
40#[derive(Clone, Copy, Debug)]
41pub enum AvbImageVerifyError {
42 /// AvbSlotVerifyResult_AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_ARGUMENT
43 InvalidArgument,
44 /// AvbSlotVerifyResult_AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_METADATA
45 InvalidMetadata,
46 /// AvbSlotVerifyResult_AVB_SLOT_VERIFY_RESULT_ERROR_IO
47 Io,
48 /// AvbSlotVerifyResult_AVB_SLOT_VERIFY_RESULT_ERROR_OOM
49 Oom,
50 /// AvbSlotVerifyResult_AVB_SLOT_VERIFY_RESULT_ERROR_PUBLIC_KEY_REJECTED
51 PublicKeyRejected,
52 /// AvbSlotVerifyResult_AVB_SLOT_VERIFY_RESULT_ERROR_ROLLBACK_INDEX
53 RollbackIndex,
54 /// AvbSlotVerifyResult_AVB_SLOT_VERIFY_RESULT_ERROR_UNSUPPORTED_VERSION
55 UnsupportedVersion,
56 /// AvbSlotVerifyResult_AVB_SLOT_VERIFY_RESULT_ERROR_VERIFICATION
57 Verification,
58 /// Unknown error.
59 Unknown(u32),
60}
61
62fn to_avb_verify_result(result: u32) -> Result<(), AvbImageVerifyError> {
63 #[allow(non_upper_case_globals)]
64 match result {
65 AvbSlotVerifyResult_AVB_SLOT_VERIFY_RESULT_OK => Ok(()),
66 AvbSlotVerifyResult_AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_ARGUMENT => {
67 Err(AvbImageVerifyError::InvalidArgument)
68 }
69 AvbSlotVerifyResult_AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_METADATA => {
70 Err(AvbImageVerifyError::InvalidMetadata)
71 }
72 AvbSlotVerifyResult_AVB_SLOT_VERIFY_RESULT_ERROR_IO => Err(AvbImageVerifyError::Io),
73 AvbSlotVerifyResult_AVB_SLOT_VERIFY_RESULT_ERROR_OOM => Err(AvbImageVerifyError::Oom),
74 AvbSlotVerifyResult_AVB_SLOT_VERIFY_RESULT_ERROR_PUBLIC_KEY_REJECTED => {
75 Err(AvbImageVerifyError::PublicKeyRejected)
76 }
77 AvbSlotVerifyResult_AVB_SLOT_VERIFY_RESULT_ERROR_ROLLBACK_INDEX => {
78 Err(AvbImageVerifyError::RollbackIndex)
79 }
80 AvbSlotVerifyResult_AVB_SLOT_VERIFY_RESULT_ERROR_UNSUPPORTED_VERSION => {
81 Err(AvbImageVerifyError::UnsupportedVersion)
82 }
83 AvbSlotVerifyResult_AVB_SLOT_VERIFY_RESULT_ERROR_VERIFICATION => {
84 Err(AvbImageVerifyError::Verification)
85 }
86 _ => Err(AvbImageVerifyError::Unknown(result)),
87 }
88}
89
90impl fmt::Display for AvbImageVerifyError {
91 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
92 match self {
93 Self::InvalidArgument => write!(f, "Invalid parameters."),
94 Self::InvalidMetadata => write!(f, "Invalid metadata."),
95 Self::Io => write!(f, "I/O error while trying to load data or get a rollback index."),
96 Self::Oom => write!(f, "Unable to allocate memory."),
97 Self::PublicKeyRejected => write!(
98 f,
99 "Everything is verified correctly out but the public key is not accepted. \
100 This includes the case where integrity data is not signed."
101 ),
102 Self::RollbackIndex => write!(f, "Rollback index is less than its stored value."),
103 Self::UnsupportedVersion => write!(
104 f,
105 "Some of the metadata requires a newer version of libavb than what is in use."
106 ),
107 Self::Verification => write!(f, "Data does not verify."),
108 Self::Unknown(e) => write!(f, "Unknown avb_slot_verify error '{e}'"),
109 }
110 }
111}
112
113/// Verifies that for the given image:
114/// - The given public key is acceptable.
115/// - The VBMeta struct is valid.
116/// - The partitions of the image match the descriptors of the verified VBMeta struct.
117/// Returns Ok if everything is verified correctly and the public key is accepted.
118pub fn verify_image(image: &[u8], public_key: &[u8]) -> Result<(), AvbImageVerifyError> {
119 AvbOps::new().verify_image(image, public_key)
120}
121
122/// TODO(b/256148034): Make AvbOps a rust wrapper of avb_bindgen::AvbOps using foreign_types.
123struct AvbOps {}
124
125impl AvbOps {
126 fn new() -> Self {
127 AvbOps {}
128 }
129
130 fn verify_image(&self, image: &[u8], public_key: &[u8]) -> Result<(), AvbImageVerifyError> {
131 debug!("AVB image: addr={:?}, size={:#x} ({1})", image.as_ptr(), image.len());
132 debug!(
133 "AVB public key: addr={:?}, size={:#x} ({1})",
134 public_key.as_ptr(),
135 public_key.len()
136 );
137 // TODO(b/256148034): Verify the kernel image with avb_slot_verify()
138 // let result = unsafe {
139 // avb_slot_verify(
140 // self.as_ptr(),
141 // requested_partitions.as_ptr(),
142 // ab_suffix.as_ptr(),
143 // AvbSlotVerifyFlags_AVB_SLOT_VERIFY_FLAGS_NO_VBMETA_PARTITION,
144 // AvbHashtreeErrorMode_AVB_HASHTREE_ERROR_MODE_EIO,
145 // &image.as_ptr(),
146 // )
147 // };
148 let result = AvbSlotVerifyResult_AVB_SLOT_VERIFY_RESULT_OK;
149 to_avb_verify_result(result)
150 }
151}