xref: /aosp_15_r20/system/security/keystore2/test_utils/ffi_test_utils.rs (revision e1997b9af69e3155ead6e072d106a0077849ffba)
1 // 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 implements helper methods to access the functionalities implemented in CPP.
16 
17 use crate::key_generations::Error;
18 use android_hardware_security_keymint::aidl::android::hardware::security::keymint::{
19     SecurityLevel::SecurityLevel, Tag::Tag,
20 };
21 
22 #[cxx::bridge]
23 mod ffi {
24     struct CxxResult {
25         data: Vec<u8>,
26         error: bool,
27     }
28 
29     unsafe extern "C++" {
30         include!("ffi_test_utils.hpp");
validateCertChain(cert_buf: Vec<u8>, cert_len: u32, strict_issuer_check: bool) -> bool31         fn validateCertChain(cert_buf: Vec<u8>, cert_len: u32, strict_issuer_check: bool) -> bool;
createWrappedKey( encrypted_secure_key: Vec<u8>, encrypted_transport_key: Vec<u8>, iv: Vec<u8>, tag: Vec<u8>, ) -> CxxResult32         fn createWrappedKey(
33             encrypted_secure_key: Vec<u8>,
34             encrypted_transport_key: Vec<u8>,
35             iv: Vec<u8>,
36             tag: Vec<u8>,
37         ) -> CxxResult;
buildAsn1DerEncodedWrappedKeyDescription() -> CxxResult38         fn buildAsn1DerEncodedWrappedKeyDescription() -> CxxResult;
performCryptoOpUsingKeystoreEngine(grant_id: i64) -> bool39         fn performCryptoOpUsingKeystoreEngine(grant_id: i64) -> bool;
getValueFromAttestRecord( cert_buf: Vec<u8>, tag: i32, expected_sec_level: i32, ) -> CxxResult40         fn getValueFromAttestRecord(
41             cert_buf: Vec<u8>,
42             tag: i32,
43             expected_sec_level: i32,
44         ) -> CxxResult;
getOsVersion() -> u3245         fn getOsVersion() -> u32;
getOsPatchlevel() -> u3246         fn getOsPatchlevel() -> u32;
getVendorPatchlevel() -> u3247         fn getVendorPatchlevel() -> u32;
48     }
49 }
50 
51 /// Validate given certificate chain.
validate_certchain(cert_buf: &[u8]) -> Result<bool, Error>52 pub fn validate_certchain(cert_buf: &[u8]) -> Result<bool, Error> {
53     validate_certchain_with_strict_issuer_check(cert_buf, true)
54 }
55 
56 /// Validate given certificate chain with an option to validate the issuer.
validate_certchain_with_strict_issuer_check( cert_buf: &[u8], strict_issuer_check: bool, ) -> Result<bool, Error>57 pub fn validate_certchain_with_strict_issuer_check(
58     cert_buf: &[u8],
59     strict_issuer_check: bool,
60 ) -> Result<bool, Error> {
61     if ffi::validateCertChain(
62         cert_buf.to_vec(),
63         cert_buf.len().try_into().unwrap(),
64         strict_issuer_check,
65     ) {
66         return Ok(true);
67     }
68 
69     Err(Error::ValidateCertChainFailed)
70 }
71 
72 /// Collect the result from CxxResult into a Rust supported structure.
get_result(result: ffi::CxxResult) -> Result<Vec<u8>, Error>73 fn get_result(result: ffi::CxxResult) -> Result<Vec<u8>, Error> {
74     if !result.error && !result.data.is_empty() {
75         Ok(result.data)
76     } else {
77         Err(Error::DerEncodeFailed)
78     }
79 }
80 
81 /// Creates wrapped key material to import in ASN.1 DER-encoded data corresponding to
82 /// `SecureKeyWrapper`. See `IKeyMintDevice.aidl` for documentation of the `SecureKeyWrapper`
83 /// schema.
create_wrapped_key( encrypted_secure_key: &[u8], encrypted_transport_key: &[u8], iv: &[u8], tag: &[u8], ) -> Result<Vec<u8>, Error>84 pub fn create_wrapped_key(
85     encrypted_secure_key: &[u8],
86     encrypted_transport_key: &[u8],
87     iv: &[u8],
88     tag: &[u8],
89 ) -> Result<Vec<u8>, Error> {
90     get_result(ffi::createWrappedKey(
91         encrypted_secure_key.to_vec(),
92         encrypted_transport_key.to_vec(),
93         iv.to_vec(),
94         tag.to_vec(),
95     ))
96 }
97 
98 /// Creates ASN.1 DER-encoded data corresponding to `KeyDescription` schema.
99 /// See `IKeyMintDevice.aidl` for documentation of the `KeyDescription` schema.
100 /// Below mentioned key parameters are used -
101 ///     Algorithm: AES-256
102 ///     Padding: PKCS7
103 ///     Blockmode: ECB
104 ///     Purpose: Encrypt, Decrypt
create_wrapped_key_additional_auth_data() -> Result<Vec<u8>, Error>105 pub fn create_wrapped_key_additional_auth_data() -> Result<Vec<u8>, Error> {
106     get_result(ffi::buildAsn1DerEncodedWrappedKeyDescription())
107 }
108 
109 /// Performs crypto operation using Keystore-Engine APIs.
perform_crypto_op_using_keystore_engine(grant_id: i64) -> Result<bool, Error>110 pub fn perform_crypto_op_using_keystore_engine(grant_id: i64) -> Result<bool, Error> {
111     if ffi::performCryptoOpUsingKeystoreEngine(grant_id) {
112         return Ok(true);
113     }
114 
115     Err(Error::Keystore2EngineOpFailed)
116 }
117 
118 /// Get the value of the given `Tag` from attestation record.
get_value_from_attest_record( cert_buf: &[u8], tag: Tag, expected_sec_level: SecurityLevel, ) -> Result<Vec<u8>, Error>119 pub fn get_value_from_attest_record(
120     cert_buf: &[u8],
121     tag: Tag,
122     expected_sec_level: SecurityLevel,
123 ) -> Result<Vec<u8>, Error> {
124     let result = ffi::getValueFromAttestRecord(cert_buf.to_vec(), tag.0, expected_sec_level.0);
125     if !result.error && !result.data.is_empty() {
126         return Ok(result.data);
127     }
128     Err(Error::AttestRecordGetValueFailed)
129 }
130 
131 /// Get OS Version
get_os_version() -> u32132 pub fn get_os_version() -> u32 {
133     ffi::getOsVersion()
134 }
135 
136 /// Get OS Patch Level
get_os_patchlevel() -> u32137 pub fn get_os_patchlevel() -> u32 {
138     ffi::getOsPatchlevel()
139 }
140 
141 /// Get vendor Patch Level
get_vendor_patchlevel() -> u32142 pub fn get_vendor_patchlevel() -> u32 {
143     ffi::getVendorPatchlevel()
144 }
145