blob: e3a96feb5ec1a47015810282ab762fcb68106f43 [file] [log] [blame]
Alice Wang9c40eca2023-02-03 13:10:24 +00001// Copyright 2023, 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 mirrors the content in open-dice/include/dice/android/bcc.h
16
Alice Wangf4bd1c62023-02-08 08:38:44 +000017use crate::dice::{Cdi, CdiValues, InputValues};
Alice Wang9c40eca2023-02-03 13:10:24 +000018use crate::error::{check_result, Result};
19use open_dice_bcc_bindgen::{
Alice Wangf4bd1c62023-02-08 08:38:44 +000020 BccConfigValues, BccFormatConfigDescriptor, BccMainFlow, BCC_INPUT_COMPONENT_NAME,
Alice Wang9c40eca2023-02-03 13:10:24 +000021 BCC_INPUT_COMPONENT_VERSION, BCC_INPUT_RESETTABLE,
22};
23use std::{ffi::CStr, ptr};
24
25/// Formats a configuration descriptor following the BCC's specification.
26/// See https://cs.android.com/android/platform/superproject/+/master:hardware/interfaces/security/rkp/aidl/android/hardware/security/keymint/ProtectedData.aidl
27pub fn bcc_format_config_descriptor(
28 name: Option<&CStr>,
29 version: Option<u64>,
30 resettable: bool,
31 buffer: &mut [u8],
32) -> Result<usize> {
33 let mut inputs = 0;
34 if name.is_some() {
35 inputs |= BCC_INPUT_COMPONENT_NAME;
36 }
37 if version.is_some() {
38 inputs |= BCC_INPUT_COMPONENT_VERSION;
39 }
40 if resettable {
41 inputs |= BCC_INPUT_RESETTABLE;
42 }
43
44 let values = BccConfigValues {
45 inputs,
46 component_name: name.map_or(ptr::null(), |p| p.as_ptr()),
47 component_version: version.unwrap_or(0),
48 };
49
50 let mut buffer_size = 0;
51 // SAFETY: The function writes to the buffer, within the given bounds, and only reads the
52 // input values. It writes its result to buffer_size.
53 check_result(unsafe {
54 BccFormatConfigDescriptor(&values, buffer.len(), buffer.as_mut_ptr(), &mut buffer_size)
55 })?;
56 Ok(buffer_size)
57}
Alice Wangf4bd1c62023-02-08 08:38:44 +000058
59/// Executes the main BCC flow.
60///
61/// Given a full set of input values along with the current BCC and CDI values,
62/// computes the next CDI values and matching updated BCC.
63pub fn bcc_main_flow(
64 current_cdi_attest: &Cdi,
65 current_cdi_seal: &Cdi,
66 current_bcc: &[u8],
67 input_values: &InputValues,
68 next_cdi_values: &mut CdiValues,
69 next_bcc: &mut [u8],
70) -> Result<usize> {
71 let mut next_bcc_size = 0;
72 // SAFETY: `BccMainFlow` only reads the current `bcc` and CDI values and writes
73 // to `next_bcc` and next CDI values within its bounds. It also reads
74 // `input_values` as a constant input and doesn't store any pointer.
75 // The first argument can be null and is not used in the current implementation.
76 check_result(unsafe {
77 BccMainFlow(
78 ptr::null_mut(), // context
79 current_cdi_attest.as_ptr(),
80 current_cdi_seal.as_ptr(),
81 current_bcc.as_ptr(),
82 current_bcc.len(),
83 input_values.as_ptr(),
84 next_bcc.len(),
85 next_bcc.as_mut_ptr(),
86 &mut next_bcc_size,
87 next_cdi_values.cdi_attest.as_mut_ptr(),
88 next_cdi_values.cdi_seal.as_mut_ptr(),
89 )
90 })?;
91 Ok(next_bcc_size)
92}