1 /*
2  *  Copyright (c) 2016, The OpenThread Authors.
3  *  All rights reserved.
4  *
5  *  Redistribution and use in source and binary forms, with or without
6  *  modification, are permitted provided that the following conditions are met:
7  *  1. Redistributions of source code must retain the above copyright
8  *     notice, this list of conditions and the following disclaimer.
9  *  2. Redistributions in binary form must reproduce the above copyright
10  *     notice, this list of conditions and the following disclaimer in the
11  *     documentation and/or other materials provided with the distribution.
12  *  3. Neither the name of the copyright holder nor the
13  *     names of its contributors may be used to endorse or promote products
14  *     derived from this software without specific prior written permission.
15  *
16  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17  *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18  *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19  *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
20  *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21  *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22  *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23  *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24  *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25  *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26  *  POSSIBILITY OF SUCH DAMAGE.
27  */
28 
29 /**
30  * @file
31  *   This file implements the use of mbedTLS.
32  */
33 
34 #include "mbedtls.hpp"
35 
36 #include <mbedtls/ctr_drbg.h>
37 #include <mbedtls/debug.h>
38 #include <mbedtls/entropy.h>
39 #include <mbedtls/platform.h>
40 #include <mbedtls/threading.h>
41 
42 #ifdef MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
43 #include <mbedtls/pem.h>
44 #endif
45 
46 #include "common/error.hpp"
47 #include "common/instance.hpp"
48 
49 namespace ot {
50 namespace Crypto {
51 
MbedTls(void)52 MbedTls::MbedTls(void)
53 {
54 #if OPENTHREAD_CONFIG_ENABLE_BUILTIN_MBEDTLS_MANAGEMENT
55 #ifdef MBEDTLS_DEBUG_C
56     // mbedTLS's debug level is almost the same as OpenThread's
57     mbedtls_debug_set_threshold(OPENTHREAD_CONFIG_LOG_LEVEL);
58 #endif
59     mbedtls_platform_set_calloc_free(Instance::HeapCAlloc, Instance::HeapFree);
60 #endif // OPENTHREAD_CONFIG_ENABLE_BUILTIN_MBEDTLS_MANAGEMENT
61 }
62 
MapError(int aMbedTlsError)63 Error MbedTls::MapError(int aMbedTlsError)
64 {
65     Error error = kErrorNone;
66 
67     switch (aMbedTlsError)
68     {
69 #if OPENTHREAD_CONFIG_ECDSA_ENABLE
70     case MBEDTLS_ERR_ECP_BAD_INPUT_DATA:
71     case MBEDTLS_ERR_MPI_BAD_INPUT_DATA:
72     case MBEDTLS_ERR_MPI_INVALID_CHARACTER:
73 #endif
74 #ifdef MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
75     case MBEDTLS_ERR_PK_TYPE_MISMATCH:
76     case MBEDTLS_ERR_PK_FILE_IO_ERROR:
77     case MBEDTLS_ERR_PK_KEY_INVALID_VERSION:
78     case MBEDTLS_ERR_PK_KEY_INVALID_FORMAT:
79     case MBEDTLS_ERR_PK_UNKNOWN_PK_ALG:
80     case MBEDTLS_ERR_PK_PASSWORD_REQUIRED:
81     case MBEDTLS_ERR_PK_PASSWORD_MISMATCH:
82     case MBEDTLS_ERR_PK_INVALID_PUBKEY:
83     case MBEDTLS_ERR_PK_INVALID_ALG:
84     case MBEDTLS_ERR_PK_UNKNOWN_NAMED_CURVE:
85     case MBEDTLS_ERR_PK_BAD_INPUT_DATA:
86     case MBEDTLS_ERR_X509_SIG_MISMATCH:
87     case MBEDTLS_ERR_X509_BAD_INPUT_DATA:
88     case MBEDTLS_ERR_X509_FILE_IO_ERROR:
89     case MBEDTLS_ERR_X509_CERT_UNKNOWN_FORMAT:
90     case MBEDTLS_ERR_X509_INVALID_VERSION:
91     case MBEDTLS_ERR_X509_UNKNOWN_SIG_ALG:
92     case MBEDTLS_ERR_X509_INVALID_SERIAL:
93     case MBEDTLS_ERR_X509_UNKNOWN_OID:
94     case MBEDTLS_ERR_X509_INVALID_FORMAT:
95     case MBEDTLS_ERR_X509_INVALID_ALG:
96     case MBEDTLS_ERR_X509_INVALID_NAME:
97     case MBEDTLS_ERR_X509_INVALID_DATE:
98     case MBEDTLS_ERR_X509_INVALID_SIGNATURE:
99     case MBEDTLS_ERR_X509_INVALID_EXTENSIONS:
100     case MBEDTLS_ERR_X509_UNKNOWN_VERSION:
101 #endif // MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
102     case MBEDTLS_ERR_SSL_BAD_INPUT_DATA:
103     case MBEDTLS_ERR_CTR_DRBG_REQUEST_TOO_BIG:
104     case MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG:
105         error = kErrorInvalidArgs;
106         break;
107 
108 #if OPENTHREAD_CONFIG_ECDSA_ENABLE
109     case MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL:
110     case MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL:
111     case MBEDTLS_ERR_MPI_ALLOC_FAILED:
112 #endif
113 #ifdef MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
114     case MBEDTLS_ERR_PEM_ALLOC_FAILED:
115     case MBEDTLS_ERR_PK_ALLOC_FAILED:
116     case MBEDTLS_ERR_X509_BUFFER_TOO_SMALL:
117     case MBEDTLS_ERR_X509_ALLOC_FAILED:
118 #endif
119     case MBEDTLS_ERR_SSL_ALLOC_FAILED:
120     case MBEDTLS_ERR_SSL_WANT_WRITE:
121     case MBEDTLS_ERR_ENTROPY_MAX_SOURCES:
122         error = kErrorNoBufs;
123         break;
124 
125 #ifdef MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
126     case MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE:
127     case MBEDTLS_ERR_PK_SIG_LEN_MISMATCH:
128     case MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE:
129     case MBEDTLS_ERR_X509_CERT_VERIFY_FAILED:
130 #endif // MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
131     case MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED:
132     case MBEDTLS_ERR_ENTROPY_SOURCE_FAILED:
133     case MBEDTLS_ERR_ENTROPY_NO_SOURCES_DEFINED:
134     case MBEDTLS_ERR_ENTROPY_NO_STRONG_SOURCE:
135     case MBEDTLS_ERR_SSL_PEER_VERIFY_FAILED:
136     case MBEDTLS_ERR_THREADING_BAD_INPUT_DATA:
137     case MBEDTLS_ERR_THREADING_MUTEX_ERROR:
138         error = kErrorSecurity;
139         break;
140 
141 #ifdef MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
142     case MBEDTLS_ERR_X509_FATAL_ERROR:
143         error = kErrorFailed;
144         break;
145 #endif
146     case MBEDTLS_ERR_SSL_TIMEOUT:
147     case MBEDTLS_ERR_SSL_WANT_READ:
148         error = kErrorBusy;
149         break;
150 
151 #if OPENTHREAD_CONFIG_ECDSA_ENABLE
152     case MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE:
153         error = kErrorNotCapable;
154         break;
155 #endif
156 
157     default:
158         if (aMbedTlsError < 0)
159         {
160             error = kErrorFailed;
161         }
162 
163         break;
164     }
165 
166     return error;
167 }
168 
169 } // namespace Crypto
170 } // namespace ot
171