1*9860b763SAndroid Build Coastguard Worker // Copyright 2022, The Android Open Source Project
2*9860b763SAndroid Build Coastguard Worker //
3*9860b763SAndroid Build Coastguard Worker // Licensed under the Apache License, Version 2.0 (the "License");
4*9860b763SAndroid Build Coastguard Worker // you may not use this file except in compliance with the License.
5*9860b763SAndroid Build Coastguard Worker // You may obtain a copy of the License at
6*9860b763SAndroid Build Coastguard Worker //
7*9860b763SAndroid Build Coastguard Worker // http://www.apache.org/licenses/LICENSE-2.0
8*9860b763SAndroid Build Coastguard Worker //
9*9860b763SAndroid Build Coastguard Worker // Unless required by applicable law or agreed to in writing, software
10*9860b763SAndroid Build Coastguard Worker // distributed under the License is distributed on an "AS IS" BASIS,
11*9860b763SAndroid Build Coastguard Worker // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12*9860b763SAndroid Build Coastguard Worker // See the License for the specific language governing permissions and
13*9860b763SAndroid Build Coastguard Worker // limitations under the License.
14*9860b763SAndroid Build Coastguard Worker
15*9860b763SAndroid Build Coastguard Worker //! Error mapping functionality.
16*9860b763SAndroid Build Coastguard Worker
17*9860b763SAndroid Build Coastguard Worker use bssl_sys as ffi;
18*9860b763SAndroid Build Coastguard Worker use core::convert::TryFrom;
19*9860b763SAndroid Build Coastguard Worker use kmr_wire::keymint::ErrorCode;
20*9860b763SAndroid Build Coastguard Worker use log::error;
21*9860b763SAndroid Build Coastguard Worker
22*9860b763SAndroid Build Coastguard Worker /// Map an OpenSSL `Error` into a KeyMint `ErrorCode` value.
map_openssl_err(err: &openssl::error::Error) -> ErrorCode23*9860b763SAndroid Build Coastguard Worker pub(crate) fn map_openssl_err(err: &openssl::error::Error) -> ErrorCode {
24*9860b763SAndroid Build Coastguard Worker let code = err.code();
25*9860b763SAndroid Build Coastguard Worker // Safety: no pointers involved.
26*9860b763SAndroid Build Coastguard Worker let reason = unsafe { ffi::ERR_GET_REASON_RUST(code) };
27*9860b763SAndroid Build Coastguard Worker
28*9860b763SAndroid Build Coastguard Worker // Global error reasons.
29*9860b763SAndroid Build Coastguard Worker match reason {
30*9860b763SAndroid Build Coastguard Worker ffi::ERR_R_MALLOC_FAILURE => return ErrorCode::MemoryAllocationFailed,
31*9860b763SAndroid Build Coastguard Worker ffi::ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED
32*9860b763SAndroid Build Coastguard Worker | ffi::ERR_R_PASSED_NULL_PARAMETER
33*9860b763SAndroid Build Coastguard Worker | ffi::ERR_R_INTERNAL_ERROR
34*9860b763SAndroid Build Coastguard Worker | ffi::ERR_R_OVERFLOW => return ErrorCode::BoringSslError,
35*9860b763SAndroid Build Coastguard Worker _ => {}
36*9860b763SAndroid Build Coastguard Worker }
37*9860b763SAndroid Build Coastguard Worker
38*9860b763SAndroid Build Coastguard Worker // SAFETY: `ERR_GET_LIB` is safe for all inputs.
39*9860b763SAndroid Build Coastguard Worker match unsafe { ffi::ERR_GET_LIB(code) as u32 } {
40*9860b763SAndroid Build Coastguard Worker ffi::ERR_LIB_USER => ErrorCode::try_from(reason).unwrap_or(ErrorCode::BoringSslError),
41*9860b763SAndroid Build Coastguard Worker ffi::ERR_LIB_EVP => translate_evp_error(reason),
42*9860b763SAndroid Build Coastguard Worker ffi::ERR_LIB_ASN1 => translate_asn1_error(reason),
43*9860b763SAndroid Build Coastguard Worker ffi::ERR_LIB_CIPHER => translate_cipher_error(reason),
44*9860b763SAndroid Build Coastguard Worker ffi::ERR_LIB_PKCS8 => translate_pkcs8_error(reason),
45*9860b763SAndroid Build Coastguard Worker ffi::ERR_LIB_X509V3 => translate_x509v3_error(reason),
46*9860b763SAndroid Build Coastguard Worker ffi::ERR_LIB_RSA => translate_rsa_error(reason),
47*9860b763SAndroid Build Coastguard Worker _ => {
48*9860b763SAndroid Build Coastguard Worker error!("unknown BoringSSL error code {}", code);
49*9860b763SAndroid Build Coastguard Worker ErrorCode::BoringSslError
50*9860b763SAndroid Build Coastguard Worker }
51*9860b763SAndroid Build Coastguard Worker }
52*9860b763SAndroid Build Coastguard Worker }
53*9860b763SAndroid Build Coastguard Worker
translate_evp_error(reason: i32) -> ErrorCode54*9860b763SAndroid Build Coastguard Worker fn translate_evp_error(reason: i32) -> ErrorCode {
55*9860b763SAndroid Build Coastguard Worker match reason {
56*9860b763SAndroid Build Coastguard Worker ffi::EVP_R_UNSUPPORTED_ALGORITHM
57*9860b763SAndroid Build Coastguard Worker | ffi::EVP_R_OPERATON_NOT_INITIALIZED // NOTYPO: upstream typo
58*9860b763SAndroid Build Coastguard Worker | ffi::EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE => ErrorCode::UnsupportedAlgorithm,
59*9860b763SAndroid Build Coastguard Worker
60*9860b763SAndroid Build Coastguard Worker ffi::EVP_R_BUFFER_TOO_SMALL
61*9860b763SAndroid Build Coastguard Worker | ffi::EVP_R_EXPECTING_AN_RSA_KEY
62*9860b763SAndroid Build Coastguard Worker | ffi::EVP_R_EXPECTING_A_DSA_KEY
63*9860b763SAndroid Build Coastguard Worker | ffi::EVP_R_MISSING_PARAMETERS => ErrorCode::InvalidKeyBlob,
64*9860b763SAndroid Build Coastguard Worker
65*9860b763SAndroid Build Coastguard Worker ffi::EVP_R_DIFFERENT_PARAMETERS | ffi::EVP_R_DECODE_ERROR => ErrorCode::InvalidArgument,
66*9860b763SAndroid Build Coastguard Worker
67*9860b763SAndroid Build Coastguard Worker ffi::EVP_R_DIFFERENT_KEY_TYPES => ErrorCode::IncompatibleAlgorithm,
68*9860b763SAndroid Build Coastguard Worker _ => ErrorCode::BoringSslError,
69*9860b763SAndroid Build Coastguard Worker }
70*9860b763SAndroid Build Coastguard Worker }
71*9860b763SAndroid Build Coastguard Worker
translate_asn1_error(reason: i32) -> ErrorCode72*9860b763SAndroid Build Coastguard Worker fn translate_asn1_error(reason: i32) -> ErrorCode {
73*9860b763SAndroid Build Coastguard Worker match reason {
74*9860b763SAndroid Build Coastguard Worker ffi::ASN1_R_ENCODE_ERROR => ErrorCode::InvalidArgument,
75*9860b763SAndroid Build Coastguard Worker _ => ErrorCode::BoringSslError,
76*9860b763SAndroid Build Coastguard Worker }
77*9860b763SAndroid Build Coastguard Worker }
78*9860b763SAndroid Build Coastguard Worker
translate_cipher_error(reason: i32) -> ErrorCode79*9860b763SAndroid Build Coastguard Worker fn translate_cipher_error(reason: i32) -> ErrorCode {
80*9860b763SAndroid Build Coastguard Worker match reason {
81*9860b763SAndroid Build Coastguard Worker ffi::CIPHER_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH
82*9860b763SAndroid Build Coastguard Worker | ffi::CIPHER_R_WRONG_FINAL_BLOCK_LENGTH => ErrorCode::InvalidInputLength,
83*9860b763SAndroid Build Coastguard Worker
84*9860b763SAndroid Build Coastguard Worker ffi::CIPHER_R_UNSUPPORTED_KEY_SIZE | ffi::CIPHER_R_BAD_KEY_LENGTH => {
85*9860b763SAndroid Build Coastguard Worker ErrorCode::UnsupportedKeySize
86*9860b763SAndroid Build Coastguard Worker }
87*9860b763SAndroid Build Coastguard Worker
88*9860b763SAndroid Build Coastguard Worker ffi::CIPHER_R_BAD_DECRYPT => ErrorCode::InvalidArgument,
89*9860b763SAndroid Build Coastguard Worker
90*9860b763SAndroid Build Coastguard Worker ffi::CIPHER_R_INVALID_KEY_LENGTH => ErrorCode::InvalidKeyBlob,
91*9860b763SAndroid Build Coastguard Worker _ => ErrorCode::BoringSslError,
92*9860b763SAndroid Build Coastguard Worker }
93*9860b763SAndroid Build Coastguard Worker }
translate_pkcs8_error(reason: i32) -> ErrorCode94*9860b763SAndroid Build Coastguard Worker fn translate_pkcs8_error(reason: i32) -> ErrorCode {
95*9860b763SAndroid Build Coastguard Worker match reason {
96*9860b763SAndroid Build Coastguard Worker ffi::PKCS8_R_UNSUPPORTED_PRIVATE_KEY_ALGORITHM | ffi::PKCS8_R_UNKNOWN_CIPHER => {
97*9860b763SAndroid Build Coastguard Worker ErrorCode::UnsupportedAlgorithm
98*9860b763SAndroid Build Coastguard Worker }
99*9860b763SAndroid Build Coastguard Worker
100*9860b763SAndroid Build Coastguard Worker ffi::PKCS8_R_PRIVATE_KEY_ENCODE_ERROR | ffi::PKCS8_R_PRIVATE_KEY_DECODE_ERROR => {
101*9860b763SAndroid Build Coastguard Worker ErrorCode::InvalidKeyBlob
102*9860b763SAndroid Build Coastguard Worker }
103*9860b763SAndroid Build Coastguard Worker
104*9860b763SAndroid Build Coastguard Worker ffi::PKCS8_R_ENCODE_ERROR => ErrorCode::InvalidArgument,
105*9860b763SAndroid Build Coastguard Worker
106*9860b763SAndroid Build Coastguard Worker _ => ErrorCode::BoringSslError,
107*9860b763SAndroid Build Coastguard Worker }
108*9860b763SAndroid Build Coastguard Worker }
translate_x509v3_error(reason: i32) -> ErrorCode109*9860b763SAndroid Build Coastguard Worker fn translate_x509v3_error(reason: i32) -> ErrorCode {
110*9860b763SAndroid Build Coastguard Worker match reason {
111*9860b763SAndroid Build Coastguard Worker ffi::X509V3_R_UNKNOWN_OPTION => ErrorCode::UnsupportedAlgorithm,
112*9860b763SAndroid Build Coastguard Worker
113*9860b763SAndroid Build Coastguard Worker _ => ErrorCode::BoringSslError,
114*9860b763SAndroid Build Coastguard Worker }
115*9860b763SAndroid Build Coastguard Worker }
translate_rsa_error(reason: i32) -> ErrorCode116*9860b763SAndroid Build Coastguard Worker fn translate_rsa_error(reason: i32) -> ErrorCode {
117*9860b763SAndroid Build Coastguard Worker match reason {
118*9860b763SAndroid Build Coastguard Worker ffi::RSA_R_KEY_SIZE_TOO_SMALL => ErrorCode::IncompatiblePaddingMode,
119*9860b763SAndroid Build Coastguard Worker ffi::RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE | ffi::RSA_R_DATA_TOO_SMALL_FOR_KEY_SIZE => {
120*9860b763SAndroid Build Coastguard Worker ErrorCode::InvalidInputLength
121*9860b763SAndroid Build Coastguard Worker }
122*9860b763SAndroid Build Coastguard Worker ffi::RSA_R_DATA_TOO_LARGE_FOR_MODULUS | ffi::RSA_R_DATA_TOO_LARGE => {
123*9860b763SAndroid Build Coastguard Worker ErrorCode::InvalidArgument
124*9860b763SAndroid Build Coastguard Worker }
125*9860b763SAndroid Build Coastguard Worker _ => ErrorCode::BoringSslError,
126*9860b763SAndroid Build Coastguard Worker }
127*9860b763SAndroid Build Coastguard Worker }
128