decider: Allow multiple policies for more complex logic 44/199144/9
authorLukasz Kostyra <l.kostyra@samsung.com>
Tue, 5 Feb 2019 11:13:56 +0000 (12:13 +0100)
committerTomasz Swierczek <t.swierczek@samsung.com>
Mon, 20 May 2019 09:06:53 +0000 (11:06 +0200)
When generating asymmetric keys, ckm-logic selected less restrictive
policy out of two provided and selected key store this way. Now, both
policies are supplied to Decider, which will allow for more complex
backend selection logic.

Change-Id: Id2b845326cae7bbf5d90bb575645c8af36c20d0f

src/manager/common/data-type.cpp
src/manager/common/data-type.h
src/manager/crypto/platform/decider.cpp
src/manager/crypto/platform/decider.h
src/manager/crypto/tz-backend/internals.cpp
src/manager/service/ckm-logic.cpp
tests/test_data-type.cpp

index 9049d1b..0bcf74f 100644 (file)
@@ -1,5 +1,5 @@
 /*
- *  Copyright (c) 2000 - 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *  Copyright (c) 2000 - 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.
@@ -76,40 +76,6 @@ DataType::DataType(KeyType key)
        }
 }
 
-DataType::DataType(AlgoType algorithmType)
-{
-       switch (algorithmType) {
-       case AlgoType::AES_CTR:
-       case AlgoType::AES_CBC:
-       case AlgoType::AES_GCM:
-       case AlgoType::AES_CFB:
-       case AlgoType::AES_GEN:
-               m_dataType = DataType::KEY_AES;
-               break;
-
-       case AlgoType::RSA_SV:
-       case AlgoType::RSA_OAEP:
-       case AlgoType::RSA_GEN:
-               m_dataType = DataType::KEY_RSA_PUBLIC;
-               break;
-
-       case AlgoType::DSA_SV:
-       case AlgoType::DSA_GEN:
-               m_dataType = DataType::KEY_DSA_PUBLIC;
-               break;
-
-       case AlgoType::ECDSA_SV:
-       case AlgoType::ECDSA_GEN:
-               m_dataType = DataType::KEY_ECDSA_PUBLIC;
-               break;
-
-       default:
-               ThrowErr(Exc::InputParam,
-                                "Invalid conversion from AlgoType=", static_cast<int>(algorithmType),
-                                " to DBDataType");
-       }
-}
-
 DataType::DataType(int data) :
        m_dataType(static_cast<Type>(data))
 {
index ba3c4fd..30829e1 100644 (file)
@@ -1,5 +1,5 @@
 /*
- *  Copyright (c) 2000 - 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *  Copyright (c) 2000 - 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.
@@ -70,7 +70,6 @@ public:
        DataType(Type data);
        explicit DataType(int data);
        explicit DataType(KeyType key);
-       explicit DataType(AlgoType algorithmType);
        DataType(const DataType &) = default;
        DataType &operator=(const DataType &) = default;
 
index a7e6b32..e14e9b6 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.
@@ -56,34 +56,41 @@ std::string ValueToString(const T& value)
        return str.str();
 }
 
-CryptoBackend chooseCryptoBackend(DataType data,
-                                  const Policy &policy,
-                                  bool encrypted)
+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 (policy.backend == CKM::PolicyBackend::FORCE_SOFTWARE)
+       if (params[0].policy.backend == CKM::PolicyBackend::FORCE_SOFTWARE)
                return CryptoBackend::OpenSSL;
 
        // user directly point proper backend - we will not discuss with it
-       if (policy.backend == CKM::PolicyBackend::FORCE_HARDWARE)
+       if (params[0].policy.backend == CKM::PolicyBackend::FORCE_HARDWARE)
                return CryptoBackend::TrustZone;
 
-       // 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)
-               return CryptoBackend::OpenSSL;
-
-       // tz-backend allows only for data binary export
-       if (policy.extractable && !data.isBinaryData())
-               return CryptoBackend::OpenSSL;
-
-       // Use TrustZone only with symmetric keys or unencrypted binary
-       // data until asymmetric cryptography is implemented
-       if (!data.isSKey() && !data.isBinaryData())
+       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) {
+               LogDebug("2 keys - asymmetric encryption not yet supported, selecting OpenSSL");
                return CryptoBackend::OpenSSL;
+       }
 
        try {
                LogDebug("Trying to open TA session...");
@@ -95,10 +102,9 @@ CryptoBackend chooseCryptoBackend(DataType data,
 
        LogDebug("...succeeded. Selecting TZ backend.");
        return CryptoBackend::TrustZone;
+
 #else // TZ_BACKEND_ENABLED
-    (void) data;
-    (void) policy;
-    (void) encrypted;
+    (void) params;
     return CryptoBackend::OpenSSL;
 #endif // TZ_BACKEND_ENABLED
 }
@@ -137,7 +143,16 @@ GStore &Decider::getStore(CryptoBackend cryptoBackend) const
 
 GStore &Decider::getStore(DataType data, const Policy &policy, bool encrypted) const
 {
-       return getStore(chooseCryptoBackend(data, policy, encrypted));
+       DataParams params{
+               DataParam(data, policy, encrypted)
+       };
+
+       return getStore(chooseCryptoBackend(params));
+}
+
+GStore &Decider::getStore(const DataParams& params) const
+{
+       return getStore(chooseCryptoBackend(params));
 }
 
 } // namespace Crypto
index ef0522c..14d1071 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.
@@ -21,6 +21,7 @@
 #pragma once
 
 #include <memory>
+#include <vector>
 
 #include <ckm/ckm-type.h>
 
 namespace CKM {
 namespace Crypto {
 
+struct DataParam {
+       DataParam() = delete;
+       DataParam(const DataType &d, const Policy &pol, bool enc = false)
+               : data(d)
+               , policy(pol)
+               , encrypted(enc)
+       {
+       }
+
+       DataType data;
+       Policy policy;
+       bool encrypted;
+};
+
+using DataParams = std::vector<DataParam>;
+
 class Decider {
 public:
        Decider();
        GStore &getStore(const Token &token) const;
        GStore &getStore(DataType data, const Policy &policy, bool encrypted = false) const;
+       GStore &getStore(const DataParams& params) const;
 
        virtual ~Decider() {}
 
@@ -49,4 +67,3 @@ protected:
 
 } // Crypto
 } // CKM
-
index 317a775..71038e0 100644 (file)
@@ -1,5 +1,5 @@
 /*
- *  Copyright (c) 2017 - 2018 Samsung Electronics Co., Ltd All Rights Reserved
+ *  Copyright (c) 2017 - 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.
@@ -86,7 +86,7 @@ Data generateSKey(const CryptoAlgorithm &alg,
        int keyBits = unpack<int>(alg, ParamName::GEN_KEY_LEN);
 
        Data keyData;
-       keyData.type = DataType(keyType);
+       keyData.type = DataType(KeyType::KEY_AES);
 
        if (!pwd.empty()) {
                if (iv.empty()) {
index c54b9a4..aedf064 100644 (file)
@@ -55,6 +55,16 @@ bool isNameValid(const CKM::Name &name)
        return true;
 }
 
+// keypair data type, having private key data type and public key data type
+// private is assumed to be .first, public .second
+using DataTypePair = std::pair<CKM::DataType, CKM::DataType>;
+
+const std::map<CKM::AlgoType, DataTypePair> ALGO_TYPE_TO_DATA_TYPE_PAIR_MAP = {
+       { CKM::AlgoType::RSA_GEN,       { CKM::DataType(CKM::KeyType::KEY_RSA_PRIVATE), CKM::DataType(CKM::KeyType::KEY_RSA_PUBLIC) } },
+       { CKM::AlgoType::DSA_GEN,       { CKM::DataType(CKM::KeyType::KEY_DSA_PRIVATE), CKM::DataType(CKM::KeyType::KEY_DSA_PUBLIC) } },
+       { CKM::AlgoType::ECDSA_GEN,     { CKM::DataType(CKM::KeyType::KEY_ECDSA_PRIVATE), CKM::DataType(CKM::KeyType::KEY_ECDSA_PUBLIC) } },
+};
+
 } // anonymous namespace
 
 namespace CKM {
@@ -1391,10 +1401,10 @@ int CKMLogic::createKeyPairHelper(
        if (!keyGenParams.getParam(ParamName::ALGO_TYPE, keyType))
                ThrowErr(Exc::InputParam, "Error, parameter ALGO_TYPE not found.");
 
-       DataType dt(keyType);
-
-       if (!dt.isKey())
+       const auto dtIt = ALGO_TYPE_TO_DATA_TYPE_PAIR_MAP.find(keyType);
+       if (dtIt == ALGO_TYPE_TO_DATA_TYPE_PAIR_MAP.end())
                ThrowErr(Exc::InputParam, "Error, parameter ALGO_TYPE with wrong value.");
+       const DataTypePair& dt = dtIt->second;
 
        if (policyPrivate.backend != policyPublic.backend)
                ThrowErr(Exc::InputParam, "Error, key pair must be supported with the same backend.");
@@ -1417,7 +1427,12 @@ int CKMLogic::createKeyPairHelper(
        bool exportable = policyPrivate.extractable || policyPublic.extractable;
        Policy lessRestricted(Password(), exportable, policyPrivate.backend);
 
-       TokenPair keys = m_decider.getStore(dt, lessRestricted).generateAKey(keyGenParams,
+       Crypto::DataParams params{
+               Crypto::DataParam(dt.first, policyPrivate),
+               Crypto::DataParam(dt.second, policyPublic),
+       };
+
+       TokenPair keys = m_decider.getStore(params).generateAKey(keyGenParams,
                                         policyPrivate.password,
                                         policyPublic.password);
 
index 3598273..c147541 100644 (file)
@@ -1,5 +1,5 @@
 /*
- *  Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *  Copyright (c) 2016 - 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.
@@ -37,48 +37,6 @@ BOOST_AUTO_TEST_CASE(CONSTRUCTOR)
                                                CKM::Exc::InputParam);
        BOOST_REQUIRE_THROW(DataType(static_cast<KeyType>(999)),
                                                CKM::Exc::InputParam);
-
-       std::vector<DataType> types;
-
-       types.emplace_back(AlgoType::AES_CTR);
-       types.emplace_back(AlgoType::AES_CBC);
-       types.emplace_back(AlgoType::AES_GCM);
-       types.emplace_back(AlgoType::AES_CFB);
-       types.emplace_back(AlgoType::AES_GEN);
-
-       for (auto &type : types)
-               BOOST_REQUIRE(type == DataType(DataType::KEY_AES));
-
-       types.clear();
-
-       types.emplace_back(AlgoType::RSA_SV);
-       types.emplace_back(AlgoType::RSA_OAEP);
-       types.emplace_back(AlgoType::RSA_GEN);
-
-       for (auto &type : types)
-               BOOST_REQUIRE(type == DataType(DataType::KEY_RSA_PUBLIC));
-
-       types.clear();
-
-       types.emplace_back(AlgoType::DSA_SV);
-       types.emplace_back(AlgoType::DSA_GEN);
-
-       for (auto &type : types)
-               BOOST_REQUIRE(type == DataType(DataType::KEY_DSA_PUBLIC));
-
-       types.clear();
-
-       types.emplace_back(AlgoType::ECDSA_SV);
-       types.emplace_back(AlgoType::ECDSA_GEN);
-
-       for (auto &type : types)
-               BOOST_REQUIRE(type == DataType(DataType::KEY_ECDSA_PUBLIC));
-
-       types.clear();
-
-       BOOST_REQUIRE_THROW(
-               DataType(static_cast<AlgoType>(-1)),
-               CKM::Exc::InputParam);
 }
 
 BOOST_AUTO_TEST_CASE(KEY_TYPE_CASTING)