Turn backends into Decider members
[platform/core/security/key-manager.git] / src / manager / crypto / platform / decider.cpp
index 98bd69f..9540509 100644 (file)
@@ -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.
 #include <platform/decider.h>
 
 #include <generic-backend/exception.h>
-#include <sw-backend/store.h>
-#include <tz-backend/store.h>
+
+#ifdef TZ_BACKEND_ENABLED
+#include <tz-backend/tz-context.h>
 
 #include <tee_client_api.h>
 #include <km_ta_defines.h>
+#endif // TZ_BACKEND_ENABLED
 
 #include <sstream>
 #include <fstream>
@@ -41,8 +43,6 @@ namespace Crypto {
 
 namespace {
 
-const std::string TA_STORE_PATH = "/usr/lib/tastore";
-
 template <typename T>
 std::string ValueToString(const T& value)
 {
@@ -54,72 +54,94 @@ std::string ValueToString(const T& value)
        return str.str();
 }
 
-std::string convertTeecUUIDToString(TEEC_UUID uuid)
+CryptoBackend chooseCryptoBackend(const DataParams& params)
 {
-       std::string uuidStr;
-       uuidStr += ValueToString(uuid.timeLow);
-       uuidStr += ValueToString(uuid.timeMid);
-       uuidStr += ValueToString(uuid.timeHiAndVersion);
-       for (auto& c: uuid.clockSeqAndNode)
-               uuidStr += ValueToString(c);
-
-       return uuidStr;
-}
+#ifdef TZ_BACKEND_ENABLED
+       if (params.size() != 1 && params.size() != 2) {
+               ThrowErr(Exc::Crypto::InternalError, "Invalid number of key parameters provided to decider");
+       }
 
-CryptoBackend chooseCryptoBackend(DataType data, bool exportable,
-                                                                 bool encrypted)
-{
-       // 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 (encrypted)
+       // user directly point proper backend - we will not discuss with it
+       if (params[0].policy.backend == CKM::PolicyBackend::FORCE_SOFTWARE)
                return CryptoBackend::OpenSSL;
 
-       // Only software backend allows for key export
-       if (exportable)
-               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;
 
-       // Use TrustZone only with symmetric keys until asymmetric
-       // cryptography is implemented
-       if (!data.isSKey())
+       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;
+       }
 
-       // Check if key-manager TA exists
-       std::string taUUIDStr = convertTeecUUIDToString(KM_TA_UUID);
-
-       LogDebug("Checking for " << TA_STORE_PATH << "/" << taUUIDStr);
-       std::ifstream taFile(TA_STORE_PATH + "/" + taUUIDStr);
-       if (taFile)
-               return CryptoBackend::TrustZone;
+       LogDebug("...succeeded. Selecting TZ backend.");
+       return CryptoBackend::TrustZone;
 
-       // no TA available - fallback to OpenSSL
-       return CryptoBackend::OpenSSL;
+#else // TZ_BACKEND_ENABLED
+    (void) params;
+    return CryptoBackend::OpenSSL;
+#endif // TZ_BACKEND_ENABLED
 }
 
 } // namespace
 
 Decider::Decider()
-       : m_swStore(new SW::Store(CryptoBackend::OpenSSL))
-       , m_tzStore(new TZ::Store(CryptoBackend::TrustZone))
+       : m_swStore(CryptoBackend::OpenSSL)
+#ifdef TZ_BACKEND_ENABLED
+       , m_tzStore(CryptoBackend::TrustZone)
+#endif
 {
 }
 
-GStore &Decider::getStore(const Token &token) const
+GStore &Decider::getStore(const Token &token)
 {
        return getStore(token.backendId);
 };
 
-GStore &Decider::getStore(CryptoBackend cryptoBackend) const
+GStore &Decider::getStore(CryptoBackend cryptoBackend)
 {
        GStore *gStore = NULL;
 
        if (cryptoBackend == CryptoBackend::OpenSSL)
-               gStore = m_swStore.get();
-
+               gStore = &m_swStore;
+#ifdef TZ_BACKEND_ENABLED
        if (cryptoBackend == CryptoBackend::TrustZone)
-               gStore = m_tzStore.get();
-
+               gStore = &m_tzStore;
+#endif
        if (gStore)
                return *gStore;
 
@@ -127,9 +149,18 @@ GStore &Decider::getStore(CryptoBackend cryptoBackend) const
                         "Backend not available. BackendId: ", (int)cryptoBackend);
 }
 
-GStore &Decider::getStore(DataType data, bool exportable, bool encrypted) const
+GStore &Decider::getStore(DataType data, const Policy &policy, bool encrypted)
+{
+       DataParams params{
+               DataParam(data, policy, encrypted)
+       };
+
+       return getStore(chooseCryptoBackend(params));
+}
+
+GStore &Decider::getStore(const DataParams& params)
 {
-       return getStore(chooseCryptoBackend(data, exportable, encrypted));
+       return getStore(chooseCryptoBackend(params));
 }
 
 } // namespace Crypto