Allow saving exportable public keys in TZ 64/313164/9
authorAndrei Vakulich <a.vakulich@samsung.com>
Fri, 14 Jun 2024 13:13:40 +0000 (15:13 +0200)
committerKrzysztof Jackiewicz <k.jackiewicz@samsung.com>
Wed, 3 Jul 2024 07:11:19 +0000 (07:11 +0000)
Save RSA and ECDSA keys in TZ if only private key is unexportable.
Save DSA key pair in TZ if only both keys are unexportable.

Change-Id: I2cfd6a22386e265a1bb65b3d3e0dfe052f5b0aaa

src/manager/crypto/platform/decider.cpp
src/manager/crypto/platform/decider.h
src/manager/service/ckm-logic.cpp

index a1409d8..477122e 100644 (file)
@@ -89,28 +89,30 @@ GStore* Decider::tryBackend(CryptoBackend backend)
 }
 
 /*
- * operation encrypted type   extractable backend
- * ----------------------------------------------
- * import    FALSE     binary *           TZ/SW
- *                     skey   FALSE       TZ/SW
- *                     skey   TRUE        SW
- *                     akey   FALSE       TZ/SW
- *                     akey   TRUE        SW
- *                     cert   *           SW
- * ----------------------------------------------
- * import    TRUE      binary *           TZ
- *                     skey   FALSE       TZ
- *                     skey   TRUE        NONE
- *                     akey   FALSE       TZ
- *                     akey   TRUE        NONE
- *                     cert   *           NONE
- * ----------------------------------------------
- * generate  N/A       binary *           TZ/SW
- *                     skey   FALSE       TZ/SW
- *                     skey   TRUE        SW
- *                     akey   FALSE       TZ/SW
- *                     akey   TRUE        SW
- *                     cert   *           NONE
+ * operation encrypted type            extractable    backend
+ * ----------------------------------------------------------
+ * import    FALSE     binary          *              TZ/SW
+ *                     skey            FALSE          TZ/SW
+ *                     skey            TRUE           SW
+ *                     akey            FALSE          TZ/SW
+ *                     akey            TRUE           SW
+ *                     cert            *              SW
+ * ----------------------------------------------------------
+ * import    TRUE      binary          *              TZ
+ *                     skey            FALSE          TZ
+ *                     skey            TRUE           NONE
+ *                     akey            FALSE          TZ
+ *                     akey            TRUE           NONE
+ *                     cert            *              NONE
+ * ----------------------------------------------------------
+ * generate  N/A       binary          *              TZ/SW
+ *                     skey            FALSE          TZ/SW
+ *                     skey            TRUE           SW
+ *                     akey(DSA)       FALSE(PRV|PUB) TZ/SW
+ *                     akey(DSA)       TRUE(PRV|PUB)  SW
+ *                     akey(RSA,ECDSA) FALSE(PRV)     TZ/SW
+ *                     akey(RSA,ECDSA) TRUE(PRV)      SW
+ *                     cert            *              NONE
  */
 std::deque<CryptoBackend> Decider::getCompatibleBackends(DataType data,
                                                          const Policy &policy,
@@ -164,6 +166,23 @@ GStore &Decider::getStore(DataType data, const Policy &policy, bool import, bool
        ThrowErr(Exc::Crypto::InternalError, "Failed to connect to a compatible backend.");
 }
 
+GStore &Decider::getStore(DataType data,
+                                                 const Policy &policyPrivate,
+                                                 const Policy &policyPublic,
+                                                 bool import,
+                                                 bool encrypted)
+{
+       Policy resultPolicy = policyPrivate;
+
+       if (data == DataType::Type::KEY_DSA_PUBLIC ||
+               data == DataType::Type::KEY_DSA_PRIVATE)
+       {
+               resultPolicy.extractable |= policyPublic.extractable;
+       }
+
+       return getStore(data, resultPolicy, import, encrypted);
+}
+
 bool Decider::checkStore(CryptoBackend requestedBackend,
                          DataType data,
                          const Policy &policy,
index e4c24fe..89dea08 100644 (file)
@@ -47,6 +47,11 @@ public:
                         const Policy &policy,
                         bool import = true,
                         bool encrypted = false);
+       GStore &getStore(DataType data,
+                        const Policy &policyPrivate,
+                        const Policy &policyPublic,
+                        bool import = true,
+                        bool encrypted = false);
        bool checkStore(CryptoBackend id,
                        DataType data,
                        const Policy &policy,
index 2c9ff8e..dc67f76 100644 (file)
@@ -33,7 +33,9 @@
 #include <algorithm>
 #include <sw-backend/store.h>
 #include <generic-backend/exception.h>
+#include <generic-backend/algo-validation.h>
 #include <ss-migrate.h>
+#include <unordered_map>
 
 namespace {
 const char *const CERT_SYSTEM_DIR          = CA_CERTS_DIR;
@@ -1171,15 +1173,26 @@ RawBuffer CKMLogic::createKeyPair(
                if (policyPrv.backend != policyPub.backend)
                        ThrowErr(Exc::InputParam, "Error, key pair must be supported with the same backend.");
 
-               bool exportable = policyPrv.extractable || policyPub.extractable;
-               Policy lessRestricted(Password(), exportable, policyPrv.backend);
+               const std::unordered_map<AlgoType, DataType::Type> algoTypeToDataTypeConverter = {
+                       { AlgoType::RSA_GEN,    DataType::Type::KEY_RSA_PRIVATE },
+                       { AlgoType::DSA_GEN,    DataType::Type::KEY_DSA_PRIVATE },
+                       { AlgoType::ECDSA_GEN,  DataType::Type::KEY_ECDSA_PRIVATE }
+               };
+
+               const auto dataTypeIt = algoTypeToDataTypeConverter.find(
+                       CKM::Crypto::unpack<AlgoType>(keyGenParams, ParamName::ALGO_TYPE));
+
+               if (dataTypeIt == algoTypeToDataTypeConverter.cend())
+               {
+                       ThrowErr(Exc::InputParam, "Error, key pair must be RSA or DSA or ECDSA.");
+               }
 
-               // For now any asymmetric key will do. If necessary we can extract it from keyGenParams.
-               TokenPair keys = m_decider.getStore(DataType::DB_KEY_FIRST, policyPrv, false).generateAKey(
-                       keyGenParams,
-                       policyPrv.password,
-                       policyPub.password,
-                       digestPrv, digestPub);
+               TokenPair keys = m_decider.getStore(
+                       dataTypeIt->second, policyPrv, policyPub, false).generateAKey(
+                               keyGenParams,
+                               policyPrv.password,
+                               policyPub.password,
+                               digestPrv, digestPub);
 
                dbOpPrv.finalize(std::move(keys.first), policyPrv);
                dbOpPub.finalize(std::move(keys.second), policyPub);