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