xref: /aosp_15_r20/system/keymint/boringssl/src/err.rs (revision 9860b7637a5f185913c70aa0caabe3ecb78441e4)
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 //! Error mapping functionality.
16 
17 use bssl_sys as ffi;
18 use core::convert::TryFrom;
19 use kmr_wire::keymint::ErrorCode;
20 use log::error;
21 
22 /// Map an OpenSSL `Error` into a KeyMint `ErrorCode` value.
map_openssl_err(err: &openssl::error::Error) -> ErrorCode23 pub(crate) fn map_openssl_err(err: &openssl::error::Error) -> ErrorCode {
24     let code = err.code();
25     // Safety: no pointers involved.
26     let reason = unsafe { ffi::ERR_GET_REASON_RUST(code) };
27 
28     // Global error reasons.
29     match reason {
30         ffi::ERR_R_MALLOC_FAILURE => return ErrorCode::MemoryAllocationFailed,
31         ffi::ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED
32         | ffi::ERR_R_PASSED_NULL_PARAMETER
33         | ffi::ERR_R_INTERNAL_ERROR
34         | ffi::ERR_R_OVERFLOW => return ErrorCode::BoringSslError,
35         _ => {}
36     }
37 
38     // SAFETY: `ERR_GET_LIB` is safe for all inputs.
39     match unsafe { ffi::ERR_GET_LIB(code) as u32 } {
40         ffi::ERR_LIB_USER => ErrorCode::try_from(reason).unwrap_or(ErrorCode::BoringSslError),
41         ffi::ERR_LIB_EVP => translate_evp_error(reason),
42         ffi::ERR_LIB_ASN1 => translate_asn1_error(reason),
43         ffi::ERR_LIB_CIPHER => translate_cipher_error(reason),
44         ffi::ERR_LIB_PKCS8 => translate_pkcs8_error(reason),
45         ffi::ERR_LIB_X509V3 => translate_x509v3_error(reason),
46         ffi::ERR_LIB_RSA => translate_rsa_error(reason),
47         _ => {
48             error!("unknown BoringSSL error code {}", code);
49             ErrorCode::BoringSslError
50         }
51     }
52 }
53 
translate_evp_error(reason: i32) -> ErrorCode54 fn translate_evp_error(reason: i32) -> ErrorCode {
55     match reason {
56         ffi::EVP_R_UNSUPPORTED_ALGORITHM
57         | ffi::EVP_R_OPERATON_NOT_INITIALIZED // NOTYPO: upstream typo
58         | ffi::EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE => ErrorCode::UnsupportedAlgorithm,
59 
60         ffi::EVP_R_BUFFER_TOO_SMALL
61         | ffi::EVP_R_EXPECTING_AN_RSA_KEY
62         | ffi::EVP_R_EXPECTING_A_DSA_KEY
63         | ffi::EVP_R_MISSING_PARAMETERS => ErrorCode::InvalidKeyBlob,
64 
65         ffi::EVP_R_DIFFERENT_PARAMETERS | ffi::EVP_R_DECODE_ERROR => ErrorCode::InvalidArgument,
66 
67         ffi::EVP_R_DIFFERENT_KEY_TYPES => ErrorCode::IncompatibleAlgorithm,
68         _ => ErrorCode::BoringSslError,
69     }
70 }
71 
translate_asn1_error(reason: i32) -> ErrorCode72 fn translate_asn1_error(reason: i32) -> ErrorCode {
73     match reason {
74         ffi::ASN1_R_ENCODE_ERROR => ErrorCode::InvalidArgument,
75         _ => ErrorCode::BoringSslError,
76     }
77 }
78 
translate_cipher_error(reason: i32) -> ErrorCode79 fn translate_cipher_error(reason: i32) -> ErrorCode {
80     match reason {
81         ffi::CIPHER_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH
82         | ffi::CIPHER_R_WRONG_FINAL_BLOCK_LENGTH => ErrorCode::InvalidInputLength,
83 
84         ffi::CIPHER_R_UNSUPPORTED_KEY_SIZE | ffi::CIPHER_R_BAD_KEY_LENGTH => {
85             ErrorCode::UnsupportedKeySize
86         }
87 
88         ffi::CIPHER_R_BAD_DECRYPT => ErrorCode::InvalidArgument,
89 
90         ffi::CIPHER_R_INVALID_KEY_LENGTH => ErrorCode::InvalidKeyBlob,
91         _ => ErrorCode::BoringSslError,
92     }
93 }
translate_pkcs8_error(reason: i32) -> ErrorCode94 fn translate_pkcs8_error(reason: i32) -> ErrorCode {
95     match reason {
96         ffi::PKCS8_R_UNSUPPORTED_PRIVATE_KEY_ALGORITHM | ffi::PKCS8_R_UNKNOWN_CIPHER => {
97             ErrorCode::UnsupportedAlgorithm
98         }
99 
100         ffi::PKCS8_R_PRIVATE_KEY_ENCODE_ERROR | ffi::PKCS8_R_PRIVATE_KEY_DECODE_ERROR => {
101             ErrorCode::InvalidKeyBlob
102         }
103 
104         ffi::PKCS8_R_ENCODE_ERROR => ErrorCode::InvalidArgument,
105 
106         _ => ErrorCode::BoringSslError,
107     }
108 }
translate_x509v3_error(reason: i32) -> ErrorCode109 fn translate_x509v3_error(reason: i32) -> ErrorCode {
110     match reason {
111         ffi::X509V3_R_UNKNOWN_OPTION => ErrorCode::UnsupportedAlgorithm,
112 
113         _ => ErrorCode::BoringSslError,
114     }
115 }
translate_rsa_error(reason: i32) -> ErrorCode116 fn translate_rsa_error(reason: i32) -> ErrorCode {
117     match reason {
118         ffi::RSA_R_KEY_SIZE_TOO_SMALL => ErrorCode::IncompatiblePaddingMode,
119         ffi::RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE | ffi::RSA_R_DATA_TOO_SMALL_FOR_KEY_SIZE => {
120             ErrorCode::InvalidInputLength
121         }
122         ffi::RSA_R_DATA_TOO_LARGE_FOR_MODULUS | ffi::RSA_R_DATA_TOO_LARGE => {
123             ErrorCode::InvalidArgument
124         }
125         _ => ErrorCode::BoringSslError,
126     }
127 }
128