Add backend field in policy 17/162217/1 accepted/tizen/unified/20171205.155557 submit/tizen/20171204.124944 submit/tizen/20180312.095815
authorBartlomiej Grzelewski <b.grzelewski@samsung.com>
Wed, 29 Nov 2017 15:32:28 +0000 (16:32 +0100)
committerBartlomiej Grzelewski <b.grzelewski@samsung.com>
Wed, 29 Nov 2017 16:22:12 +0000 (17:22 +0100)
New field will allow user to force usage of software/hardwere backend
during runtime.

Change-Id: I6f3c575fa979807f456a32a70b278942cdb28b04

src/include/ckm/ckm-type.h
src/manager/common/protocols.h
src/manager/crypto/platform/decider.cpp
src/manager/crypto/platform/decider.h
src/manager/service/ckm-logic.cpp
tests/test_crypto-logic.cpp

index e534384..5a07a3d 100644 (file)
@@ -70,12 +70,22 @@ enum class CertificateFieldId : int {
        SUBJECT
 };
 
+enum class PolicyBackend : int {
+       DEFAULT = 0,
+       FORCE_SOFTWARE = 1,
+       FORCE_HARDWARE = 2,
+};
+
 struct Policy {
-       Policy(const Password &pass = Password(), bool extract = true) :
-               password(pass), extractable(extract) {}
+       Policy(const Password &pass = Password(), bool extract = true, PolicyBackend policyBackend = PolicyBackend::DEFAULT)
+         : password(pass)
+         , extractable(extract)
+         , backend(policyBackend)
+       {}
        virtual ~Policy() {}
        Password password;  // byte array used to encrypt data inside CKM
        bool extractable;   // if true key may be extracted from storage
+       PolicyBackend backend;
 };
 
 enum class HashAlgorithm : int {
index 6141a84..e8be62b 100644 (file)
@@ -89,14 +89,18 @@ struct COMMON_API PolicySerializable : public Policy, ISerializable {
 
        explicit PolicySerializable(IStream &stream)
        {
+               int policyBackend;
                Deserialization::Deserialize(stream, password);
                Deserialization::Deserialize(stream, extractable);
+               Deserialization::Deserialize(stream, policyBackend);
+               backend = static_cast<PolicyBackend>(policyBackend);
        }
 
        void Serialize(IStream &stream) const
        {
                Serialization::Serialize(stream, password);
                Serialization::Serialize(stream, extractable);
+               Serialization::Serialize(stream, static_cast<int>(backend));
        }
 };
 
index 98bd69f..d5a5506 100644 (file)
@@ -66,9 +66,18 @@ std::string convertTeecUUIDToString(TEEC_UUID uuid)
        return uuidStr;
 }
 
-CryptoBackend chooseCryptoBackend(DataType data, bool exportable,
-                                                                 bool encrypted)
+CryptoBackend chooseCryptoBackend(DataType data,
+                                  const Policy &policy,
+                                  bool encrypted)
 {
+       // user directly point proper backend - we will not discuss with it
+       if (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)
+               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
@@ -77,7 +86,7 @@ CryptoBackend chooseCryptoBackend(DataType data, bool exportable,
                return CryptoBackend::OpenSSL;
 
        // Only software backend allows for key export
-       if (exportable)
+       if (policy.extractable)
                return CryptoBackend::OpenSSL;
 
        // Use TrustZone only with symmetric keys until asymmetric
@@ -127,9 +136,9 @@ 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) const
 {
-       return getStore(chooseCryptoBackend(data, exportable, encrypted));
+       return getStore(chooseCryptoBackend(data, policy, encrypted));
 }
 
 } // namespace Crypto
index 184f698..ef0522c 100644 (file)
@@ -36,7 +36,7 @@ class Decider {
 public:
        Decider();
        GStore &getStore(const Token &token) const;
-       GStore &getStore(DataType data, bool exportable, bool encrypted = false) const;
+       GStore &getStore(DataType data, const Policy &policy, bool encrypted = false) const;
 
        virtual ~Decider() {}
 
index 2da2070..7d976a9 100644 (file)
@@ -401,7 +401,7 @@ DB::Row CKMLogic::createEncryptedRow(
        const Crypto::Data &data,
        const Policy &policy) const
 {
-       Crypto::GStore &store = m_decider.getStore(data.type, policy.extractable);
+       Crypto::GStore &store = m_decider.getStore(data.type, policy);
 
        // do not encrypt data with password during cc_mode on
        Token token = store.import(data,
@@ -1176,8 +1176,7 @@ int CKMLogic::importInitialData(
                if (retCode != CKM_API_SUCCESS)
                        return retCode;
 
-               Crypto::GStore &store =
-                       m_decider.getStore(data.type, policy.extractable, !enc.encryptedKey.empty());
+               Crypto::GStore &store = m_decider.getStore(data.type, policy, !enc.encryptedKey.empty());
 
                Token token;
 
@@ -1313,7 +1312,7 @@ int CKMLogic::createKeyAESHelper(
        keyGenAlgorithm.setParam(ParamName::ALGO_TYPE, AlgoType::AES_GEN);
        keyGenAlgorithm.setParam(ParamName::GEN_KEY_LEN, size);
        Token key = m_decider.getStore(DataType::KEY_AES,
-                                                                  policy.extractable).generateSKey(keyGenAlgorithm, policy.password);
+                                      policy).generateSKey(keyGenAlgorithm, policy.password);
 
        // save the data
        DB::Row row(std::move(key), name, ownerLabel,
@@ -1349,6 +1348,9 @@ int CKMLogic::createKeyPairHelper(
        if (!dt.isKey())
                ThrowErr(Exc::InputParam, "Error, parameter ALGO_TYPE with wrong value.");
 
+       if (policyPrivate.backend != policyPublic.backend)
+               ThrowErr(Exc::InputParam, "Error, key pair must be supported with the same backend.");
+
        // use client label if not explicitly provided
        const Label &ownerLabelPrv = labelPrivate.empty() ? cred.smackLabel :
                                                                 labelPrivate;
@@ -1365,7 +1367,9 @@ int CKMLogic::createKeyPairHelper(
                return CKM_API_ERROR_INPUT_PARAM;
 
        bool exportable = policyPrivate.extractable || policyPublic.extractable;
-       TokenPair keys = m_decider.getStore(dt, exportable).generateAKey(keyGenParams,
+       Policy lessRestricted(Password(), exportable, policyPrivate.backend);
+
+       TokenPair keys = m_decider.getStore(dt, lessRestricted).generateAKey(keyGenParams,
                                         policyPrivate.password,
                                         policyPublic.password);
 
index ffe67ff..6bb84cd 100644 (file)
@@ -90,7 +90,7 @@ BOOST_AUTO_TEST_CASE(row_encryption)
        Policy policy(Password(), true);
        Crypto::Data data(DataType(DataType::Type::BINARY_DATA), createRandom(10));
        Crypto::Decider decider;
-       Crypto::GStore &store = decider.getStore(data.type, true);
+       Crypto::GStore &store = decider.getStore(data.type, policy);
        Token token = store.import(data, policy.password);
 
        Name name = "test_data";
@@ -112,7 +112,7 @@ BOOST_AUTO_TEST_CASE(row_encryption_negatives)
        Policy policy(Password(), true);
        Crypto::Data data(DataType(DataType::Type::BINARY_DATA), createRandom(10));
        Crypto::Decider decider;
-       Crypto::GStore &store = decider.getStore(data.type, true);
+       Crypto::GStore &store = decider.getStore(data.type, policy);
        Token token = store.import(data, policy.password);
 
        Name name = "test_data";