summaryrefslogtreecommitdiffstats
path: root/openssl_err.cpp
blob: df2920b0b7987fd6289d0fb6837653d89969248a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
/*
 * Copyright (C) 2014 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "openssl_err.h"

#include <openssl/err.h>
#include <openssl/evp.h>

#if defined(OPENSSL_IS_BORINGSSL)
#include <openssl/asn1.h>
#include <openssl/cipher.h>
#include <openssl/pkcs8.h>
#include <openssl/x509v3.h>
#endif

#include <hardware/keymaster_defs.h>
#include <keymaster/logger.h>

namespace keymaster {

static keymaster_error_t TranslateEvpError(int reason);
#if defined(OPENSSL_IS_BORINGSSL)
static keymaster_error_t TranslateASN1Error(int reason);
static keymaster_error_t TranslateCipherError(int reason);
static keymaster_error_t TranslatePKCS8Error(int reason);
static keymaster_error_t TranslateX509v3Error(int reason);
static keymaster_error_t TranslateRsaError(int reason);
#endif

keymaster_error_t TranslateLastOpenSslError(bool log_message) {
    unsigned long error = ERR_peek_last_error();

    if (log_message) {
        LOG_D("%s", ERR_error_string(error, NULL));
    }

    int reason = ERR_GET_REASON(error);
    switch (ERR_GET_LIB(error)) {
    case ERR_LIB_USER:
        return static_cast<keymaster_error_t>(reason);
    case ERR_LIB_EVP:
        return TranslateEvpError(reason);
#if defined(OPENSSL_IS_BORINGSSL)
    case ERR_LIB_ASN1:
        return TranslateASN1Error(reason);
    case ERR_LIB_CIPHER:
        return TranslateCipherError(reason);
    case ERR_LIB_PKCS8:
        return TranslatePKCS8Error(reason);
    case ERR_LIB_X509V3:
        return TranslateX509v3Error(reason);
    case ERR_LIB_RSA:
        return TranslateRsaError(reason);
#else
    case ERR_LIB_ASN1:
        LOG_E("ASN.1 parsing error %d", reason);
        return KM_ERROR_INVALID_ARGUMENT;
#endif
    }

    LOG_E("Openssl error %d, %d", ERR_GET_LIB(error), reason);
    return KM_ERROR_UNKNOWN_ERROR;
}

#if defined(OPENSSL_IS_BORINGSSL)

keymaster_error_t TranslatePKCS8Error(int reason) {
    switch (reason) {
    case PKCS8_R_UNSUPPORTED_PRIVATE_KEY_ALGORITHM:
    case PKCS8_R_UNKNOWN_CIPHER:
        return KM_ERROR_UNSUPPORTED_ALGORITHM;

    case PKCS8_R_PRIVATE_KEY_ENCODE_ERROR:
    case PKCS8_R_PRIVATE_KEY_DECODE_ERROR:
        return KM_ERROR_INVALID_KEY_BLOB;

    case PKCS8_R_ENCODE_ERROR:
        return KM_ERROR_INVALID_ARGUMENT;

    default:
        return KM_ERROR_UNKNOWN_ERROR;
    }
}

keymaster_error_t TranslateCipherError(int reason) {
    switch (reason) {
    case CIPHER_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH:
    case CIPHER_R_WRONG_FINAL_BLOCK_LENGTH:
        return KM_ERROR_INVALID_INPUT_LENGTH;

    case CIPHER_R_UNSUPPORTED_KEY_SIZE:
    case CIPHER_R_BAD_KEY_LENGTH:
        return KM_ERROR_UNSUPPORTED_KEY_SIZE;

    case CIPHER_R_BAD_DECRYPT:
        return KM_ERROR_INVALID_ARGUMENT;

    case CIPHER_R_INVALID_KEY_LENGTH:
        return KM_ERROR_INVALID_KEY_BLOB;

    default:
        return KM_ERROR_UNKNOWN_ERROR;
    }
}

keymaster_error_t TranslateASN1Error(int reason) {
    switch (reason) {
#if !defined(OPENSSL_IS_BORINGSSL)
    case ASN1_R_UNSUPPORTED_CIPHER:
        return KM_ERROR_UNSUPPORTED_ALGORITHM;

    case ASN1_R_ERROR_LOADING_SECTION:
        return KM_ERROR_INVALID_KEY_BLOB;
#endif

    case ASN1_R_ENCODE_ERROR:
        return KM_ERROR_INVALID_ARGUMENT;

    default:
        return KM_ERROR_UNKNOWN_ERROR;
    }
}

keymaster_error_t TranslateX509v3Error(int reason) {
    switch (reason) {
    case X509V3_R_UNKNOWN_OPTION:
        return KM_ERROR_UNSUPPORTED_ALGORITHM;

    default:
        return KM_ERROR_UNKNOWN_ERROR;
    }
}

keymaster_error_t TranslateRsaError(int reason) {
    switch (reason) {
    case RSA_R_KEY_SIZE_TOO_SMALL:
        LOG_W("RSA key is too small to use with selected padding/digest", 0);
        return KM_ERROR_INCOMPATIBLE_PADDING_MODE;
    case RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE:
    case RSA_R_DATA_TOO_SMALL_FOR_KEY_SIZE:
        return KM_ERROR_INVALID_INPUT_LENGTH;
    case RSA_R_DATA_TOO_LARGE_FOR_MODULUS:
        return KM_ERROR_INVALID_ARGUMENT;
    default:
        return KM_ERROR_UNKNOWN_ERROR;
    };
}

#endif  // OPENSSL_IS_BORINGSSL

keymaster_error_t TranslateEvpError(int reason) {
    switch (reason) {

    case EVP_R_UNKNOWN_DIGEST:
        return KM_ERROR_UNSUPPORTED_DIGEST;

#if !defined(OPENSSL_IS_BORINGSSL)
    case EVP_R_UNSUPPORTED_PRF:
    case EVP_R_UNSUPPORTED_PRIVATE_KEY_ALGORITHM:
    case EVP_R_UNSUPPORTED_KEY_DERIVATION_FUNCTION:
    case EVP_R_UNSUPPORTED_SALT_TYPE:
    case EVP_R_UNKNOWN_PBE_ALGORITHM:
    case EVP_R_UNSUPORTED_NUMBER_OF_ROUNDS:
    case EVP_R_UNSUPPORTED_CIPHER:
    case EVP_R_PKCS8_UNKNOWN_BROKEN_TYPE:
    case EVP_R_UNKNOWN_CIPHER:
#endif
    case EVP_R_UNSUPPORTED_ALGORITHM:
    case EVP_R_OPERATON_NOT_INITIALIZED:
    case EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE:
        return KM_ERROR_UNSUPPORTED_ALGORITHM;

#if !defined(OPENSSL_IS_BORINGSSL)
    case EVP_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH:
    case EVP_R_WRONG_FINAL_BLOCK_LENGTH:
        return KM_ERROR_INVALID_INPUT_LENGTH;

    case EVP_R_UNSUPPORTED_KEYLENGTH:
    case EVP_R_BAD_KEY_LENGTH:
        return KM_ERROR_UNSUPPORTED_KEY_SIZE;
#endif

#if !defined(OPENSSL_IS_BORINGSSL)
    case EVP_R_BAD_BLOCK_LENGTH:
    case EVP_R_BN_DECODE_ERROR:
    case EVP_R_BN_PUBKEY_ERROR:
    case EVP_R_CIPHER_PARAMETER_ERROR:
    case EVP_R_ERROR_LOADING_SECTION:
    case EVP_R_EXPECTING_A_ECDSA_KEY:
    case EVP_R_EXPECTING_A_EC_KEY:
    case EVP_R_INVALID_DIGEST:
    case EVP_R_INVALID_KEY_LENGTH:
    case EVP_R_NO_DSA_PARAMETERS:
    case EVP_R_PRIVATE_KEY_DECODE_ERROR:
    case EVP_R_PRIVATE_KEY_ENCODE_ERROR:
    case EVP_R_PUBLIC_KEY_NOT_RSA:
#endif
    case EVP_R_BUFFER_TOO_SMALL:
    case EVP_R_EXPECTING_AN_RSA_KEY:
    case EVP_R_EXPECTING_A_DH_KEY:
    case EVP_R_EXPECTING_A_DSA_KEY:
    case EVP_R_MISSING_PARAMETERS:
    case EVP_R_WRONG_PUBLIC_KEY_TYPE:
        return KM_ERROR_INVALID_KEY_BLOB;

#if !defined(OPENSSL_IS_BORINGSSL)
    case EVP_R_BAD_DECRYPT:
    case EVP_R_ENCODE_ERROR:
#endif
    case EVP_R_DIFFERENT_PARAMETERS:
    case EVP_R_DECODE_ERROR:
        return KM_ERROR_INVALID_ARGUMENT;

    case EVP_R_DIFFERENT_KEY_TYPES:
        return KM_ERROR_INCOMPATIBLE_ALGORITHM;
    }

    return KM_ERROR_UNKNOWN_ERROR;
}

}  // namespace keymaster