X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=src%2Fmanager%2Fcrypto%2Fplatform%2Fdecider.cpp;h=9540509f8dbcfe4c28e45499858e4f4d29153cc8;hb=3c39dc62f2757e8edf55cf792f559b30a2558d48;hp=16255d9efe255597ebe4bc2acef69a63ed1cf71b;hpb=e8c312dd9465c28b900444121a9617fad64dbc40;p=platform%2Fcore%2Fsecurity%2Fkey-manager.git diff --git a/src/manager/crypto/platform/decider.cpp b/src/manager/crypto/platform/decider.cpp index 16255d9..9540509 100644 --- a/src/manager/crypto/platform/decider.cpp +++ b/src/manager/crypto/platform/decider.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved + * Copyright (c) 2015 - 2019 Samsung Electronics Co., Ltd All Rights Reserved * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,6 +16,7 @@ /* * @file decider.cpp * @author Bartłomiej Grzelewski (b.grzelewski@samsung.com) + * @author Lukasz Kostyra (l.kostyra@samsung.com) * @version 1.0 */ #include @@ -25,58 +26,141 @@ #include #include -#include -#include -namespace CKM { -namespace Crypto { +#ifdef TZ_BACKEND_ENABLED +#include -Decider::Decider() - : m_swStore(new SW::Store(CryptoBackend::OpenSSL)) - , m_tzStore(new TZ::Store(CryptoBackend::TrustZone)) -{} +#include +#include +#endif // TZ_BACKEND_ENABLED -GStore& Decider::getStore(const Token &token) { - return getStore(token.backendId); -}; +#include +#include +#include -GStore& Decider::getStore(CryptoBackend cryptoBackend) { - GStore *gStore = NULL; - if (cryptoBackend == CryptoBackend::OpenSSL) - gStore = m_swStore.get(); - if (cryptoBackend == CryptoBackend::TrustZone) - gStore = m_tzStore.get(); +namespace CKM { +namespace Crypto { - if (gStore) - return *gStore; +namespace { + +template +std::string ValueToString(const T& value) +{ + std::stringstream str; + // we need to re-cast because otherwise stringstream + // will write our value incorrectly + str << std::setfill('0') << std::setw(2 * sizeof(T)) << std::hex + << static_cast(value); + return str.str(); +} - ThrowErr(Exc::Crypto::InternalError, - "Backend not available. BackendId: ", (int)cryptoBackend); +CryptoBackend chooseCryptoBackend(const DataParams& params) +{ +#ifdef TZ_BACKEND_ENABLED + if (params.size() != 1 && params.size() != 2) { + ThrowErr(Exc::Crypto::InternalError, "Invalid number of key parameters provided to decider"); + } + + // user directly point proper backend - we will not discuss with it + if (params[0].policy.backend == CKM::PolicyBackend::FORCE_SOFTWARE) + return CryptoBackend::OpenSSL; + + // user directly point proper backend - we will not discuss with it + if (params[0].policy.backend == CKM::PolicyBackend::FORCE_HARDWARE) + return CryptoBackend::TrustZone; + + if (params.size() == 1) { + // For now only software backend supports device encyption key + // TODO tz-backend could support the master key, but it would require + // hardcoding a known key ID and querying TA whether the key is + // reachable + if (params[0].encrypted) { + return CryptoBackend::OpenSSL; + } + + // tz-backend allows only for data binary export + if (params[0].policy.extractable && !params[0].data.isBinaryData()) { + return CryptoBackend::OpenSSL; + } + + // Use TrustZone only with symmetric keys or unencrypted binary + // data until asymmetric cryptography is implemented + if (!params[0].data.isSKey() && !params[0].data.isBinaryData()) { + return CryptoBackend::OpenSSL; + } + } else if (params.size() == 2) { + // extractable private key can only be handled by OpenSSL + if (params[0].policy.extractable) { + return CryptoBackend::OpenSSL; + } + + // ECDSA algorithm is unsupported by GP API 1.0 + if (params[0].data.isEllipticCurve() || params[1].data.isEllipticCurve()) { + return CryptoBackend::OpenSSL; + } + } + + try { + LogDebug("Trying to open TA session..."); + TZ::Internals::TrustZoneContext::Instance(); + } catch (const Exc::Crypto::InternalError& e) { + LogDebug("...failed. Selecting SW backend."); + return CryptoBackend::OpenSSL; + } + + LogDebug("...succeeded. Selecting TZ backend."); + return CryptoBackend::TrustZone; + +#else // TZ_BACKEND_ENABLED + (void) params; + return CryptoBackend::OpenSSL; +#endif // TZ_BACKEND_ENABLED } -GStore& Decider::getStore(DataType data, bool exportable) { - return getStore(chooseCryptoBackend(data, exportable)); +} // namespace + +Decider::Decider() + : m_swStore(CryptoBackend::OpenSSL) +#ifdef TZ_BACKEND_ENABLED + , m_tzStore(CryptoBackend::TrustZone) +#endif +{ } -CryptoBackend Decider::chooseCryptoBackend(DataType dataType, bool exportable) const { -// The list of items that MUST be support by OpenSSL - if (dataType.isCertificate()) - return CryptoBackend::OpenSSL; +GStore &Decider::getStore(const Token &token) +{ + return getStore(token.backendId); +}; - if (dataType.isBinaryData()) - return CryptoBackend::OpenSSL; +GStore &Decider::getStore(CryptoBackend cryptoBackend) +{ + GStore *gStore = NULL; + + if (cryptoBackend == CryptoBackend::OpenSSL) + gStore = &m_swStore; +#ifdef TZ_BACKEND_ENABLED + if (cryptoBackend == CryptoBackend::TrustZone) + gStore = &m_tzStore; +#endif + if (gStore) + return *gStore; + + ThrowErr(Exc::Crypto::InternalError, + "Backend not available. BackendId: ", (int)cryptoBackend); +} - if (exportable) - return CryptoBackend::OpenSSL; +GStore &Decider::getStore(DataType data, const Policy &policy, bool encrypted) +{ + DataParams params{ + DataParam(data, policy, encrypted) + }; -// This is the place where we can use trust zone backend -// Examples: -// -// if (dataType.isKeyPrivate()) -// return CryptoBackend::TrustZone; + return getStore(chooseCryptoBackend(params)); +} -// This item does not met Trust Zone requirements. Let's use software backend - return CryptoBackend::OpenSSL; +GStore &Decider::getStore(const DataParams& params) +{ + return getStore(chooseCryptoBackend(params)); } } // namespace Crypto