2 * Copyright (c) 2015 - 2019 Samsung Electronics Co., Ltd All Rights Reserved
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License
18 * @author Bartłomiej Grzelewski (b.grzelewski@samsung.com)
19 * @author Lukasz Kostyra (l.kostyra@samsung.com)
22 #include <dpl/log/log.h>
24 #include <crypto-backend.h>
26 #include <platform/decider.h>
28 #include <generic-backend/exception.h>
30 #ifdef TZ_BACKEND_ENABLED
31 #include <tz-backend/tz-context.h>
33 #include <tee_client_api.h>
34 #include <km_ta_defines.h>
35 #endif // TZ_BACKEND_ENABLED
47 std::string ValueToString(const T& value)
49 std::stringstream str;
50 // we need to re-cast because otherwise stringstream
51 // will write our value incorrectly
52 str << std::setfill('0') << std::setw(2 * sizeof(T)) << std::hex
53 << static_cast<uint64_t>(value);
57 CryptoBackend chooseCryptoBackend(const DataParams& params)
59 #ifdef TZ_BACKEND_ENABLED
60 if (params.size() != 1 && params.size() != 2) {
61 ThrowErr(Exc::Crypto::InternalError, "Invalid number of key parameters provided to decider");
64 // user directly point proper backend - we will not discuss with it
65 if (params[0].policy.backend == CKM::PolicyBackend::FORCE_SOFTWARE)
66 return CryptoBackend::OpenSSL;
68 // user directly point proper backend - we will not discuss with it
69 if (params[0].policy.backend == CKM::PolicyBackend::FORCE_HARDWARE)
70 return CryptoBackend::TrustZone;
72 if (params.size() == 1) {
73 // For now only software backend supports device encyption key
74 // TODO tz-backend could support the master key, but it would require
75 // hardcoding a known key ID and querying TA whether the key is
77 if (params[0].encrypted) {
78 return CryptoBackend::OpenSSL;
81 // tz-backend allows only for data binary export
82 if (params[0].policy.extractable && !params[0].data.isBinaryData()) {
83 return CryptoBackend::OpenSSL;
86 // Use TrustZone only with symmetric keys or unencrypted binary
87 // data until asymmetric cryptography is implemented
88 if (!params[0].data.isSKey() && !params[0].data.isBinaryData()) {
89 return CryptoBackend::OpenSSL;
91 } else if (params.size() == 2) {
92 // extractable private key can only be handled by OpenSSL
93 if (params[0].policy.extractable) {
94 return CryptoBackend::OpenSSL;
97 // ECDSA algorithm is unsupported by GP API 1.0
98 if (params[0].data.isEllipticCurve() || params[1].data.isEllipticCurve()) {
99 return CryptoBackend::OpenSSL;
104 LogDebug("Trying to open TA session...");
105 TZ::Internals::TrustZoneContext::Instance();
106 } catch (const Exc::Crypto::InternalError& e) {
107 LogDebug("...failed. Selecting SW backend.");
108 return CryptoBackend::OpenSSL;
111 LogDebug("...succeeded. Selecting TZ backend.");
112 return CryptoBackend::TrustZone;
114 #else // TZ_BACKEND_ENABLED
116 return CryptoBackend::OpenSSL;
117 #endif // TZ_BACKEND_ENABLED
123 : m_swStore(CryptoBackend::OpenSSL)
124 #ifdef TZ_BACKEND_ENABLED
125 , m_tzStore(CryptoBackend::TrustZone)
130 GStore &Decider::getStore(const Token &token)
132 return getStore(token.backendId);
135 GStore &Decider::getStore(CryptoBackend cryptoBackend)
137 GStore *gStore = NULL;
139 if (cryptoBackend == CryptoBackend::OpenSSL)
141 #ifdef TZ_BACKEND_ENABLED
142 if (cryptoBackend == CryptoBackend::TrustZone)
148 ThrowErr(Exc::Crypto::InternalError,
149 "Backend not available. BackendId: ", (int)cryptoBackend);
152 GStore &Decider::getStore(DataType data, const Policy &policy, bool encrypted)
155 DataParam(data, policy, encrypted)
158 return getStore(chooseCryptoBackend(params));
161 GStore &Decider::getStore(const DataParams& params)
163 return getStore(chooseCryptoBackend(params));
166 } // namespace Crypto