1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
|
// Copyright 2023, The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//! GblOps trait that defines GBL callbacks.
//!
#[cfg(feature = "alloc")]
extern crate alloc;
#[cfg(test)]
extern crate static_assertions;
use crate::digest::{Algorithm, Context};
use crate::error::{Error, Result};
#[cfg(feature = "sw_digest")]
use crate::sw_digest::SwContext;
#[cfg(feature = "alloc")]
use alloc::ffi::CString;
use core::{fmt::Debug, ptr::NonNull};
use super::slots;
// https://stackoverflow.com/questions/41081240/idiomatic-callbacks-in-rust
// should we use traits for this? or optional/box FnMut?
//
/* TODO: b/312612203 - needed callbacks:
missing:
- validate_public_key_for_partition: None,
- key management => atx extension in callback => atx_ops: ptr::null_mut(), // support optional ATX.
*/
/// Trait that defines callbacks that can be provided to Gbl.
pub trait GblOps: Debug {
/// Digest context type
type Context: Context;
/// Create digest object to use for hash computations.
///
/// Context interface allows to update value adding more data to process.
/// # Arguments
///
/// * algorithm - algorithm to use for hash computation.
fn new_digest(&self, algorithm: Algorithm) -> Self::Context {
Context::new(algorithm)
}
/// Calculate digest of provided data with requested algorithm. Single use unlike [new_digest]
/// flow.
fn digest(&self, algorithm: Algorithm, data: &[u8]) -> <Self::Context as Context>::Digest {
let mut ctx = self.new_digest(algorithm);
ctx.update(data);
ctx.finish()
}
/// Callback for when fastboot mode is requested.
// Nevertype could be used here when it is stable https://github.com/serde-rs/serde/issues/812
fn do_fastboot<B: gbl_storage::AsBlockDevice>(
&self,
cursor: &mut slots::Cursor<B, impl slots::Manager>,
) -> Result<()> {
Err(Error::NotImplemented)
}
/// TODO: b/312607649 - placeholder interface for Gbl specific callbacks that uses alloc.
#[cfg(feature = "alloc")]
fn gbl_alloc_extra_action(&mut self, s: &str) -> Result<()> {
let _c_string = CString::new(s);
Err(Error::Error)
}
/// Load and initialize a slot manager and return a cursor over the manager on success.
fn load_slot_interface<B: gbl_storage::AsBlockDevice, M: slots::Manager>(
&mut self,
block_device: B,
boot_token: slots::BootToken,
) -> Result<slots::Cursor<B, M>> {
Err(Error::OperationProhibited)
}
}
/// Default [GblOps] implementation that returns errors and does nothing.
#[derive(Debug)]
pub struct DefaultGblOps {}
#[cfg(feature = "sw_digest")]
impl GblOps for DefaultGblOps {
type Context = SwContext;
}
#[cfg(test)]
static_assertions::const_assert_eq!(core::mem::size_of::<DefaultGblOps>(), 0);
impl DefaultGblOps {
/// Create new DefaultGblOps object
pub fn new() -> &'static mut Self {
let mut ptr: NonNull<Self> = NonNull::dangling();
// SAFETY: Self is a ZST, asserted above, and ptr is appropriately aligned and nonzero by
// NonNull::dangling()
unsafe { ptr.as_mut() }
}
}
|