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