Simplify DB::Row/Token extraction 46/290346/6
authorKrzysztof Jackiewicz <k.jackiewicz@samsung.com>
Thu, 23 Mar 2023 08:19:41 +0000 (09:19 +0100)
committerKrzysztof Jackiewicz <k.jackiewicz@samsung.com>
Mon, 27 Mar 2023 12:40:40 +0000 (14:40 +0200)
For wrapped key export we need to pass 1 object to be wrapped by
another. GObjUPtr is insufficient as it loses information about the
specific type. We'll need that info in TZ backend.

The wrapping API can be then made look as follows:

RawBuffer GObj::wrap(const CryptoAlgorithm &params,
                     const Token &keyToWrap,
                     const Password &keyToWrapPass);

Change-Id: Ifeea08cbef43c6e86c067e37c68627d6b819bfcf

src/manager/service/ckm-logic.cpp
src/manager/service/ckm-logic.h
src/manager/service/crypto-logic.cpp
src/manager/service/crypto-logic.h
unit-tests/test_crypto-logic.cpp

index 54bf913bff50399e2877a4abcb21dcebb0976a3c..496b95b6e9d1d708a7a0d56ac8bca1a15db525c4 100644 (file)
@@ -625,25 +625,20 @@ int CKMLogic::checkDataPermissionsHelper(const Credentials &accessorCred,
        return m_accessControl.canRead(accessorCred, permission);
 }
 
-Crypto::GObjUPtr CKMLogic::rowToObject(
+void CKMLogic::decryptRow(
        UserData &handler,
-       DB::Row row,
+       DB::Row &row,
        const Password &password,
        const RawBuffer &hash)
 {
-       Crypto::GStore &store = m_decider.getStore(row);
-
-       Password pass = m_accessControl.isCCMode() ? "" : password;
-
-       // decrypt row
-       Crypto::GObjUPtr obj;
-
        if (CryptoLogic::getSchemeVersion(row.encryptionScheme) ==
                        CryptoLogic::ENCRYPTION_V2) {
                handler.crypto.decryptRow(Password(), row);
-
-               obj = store.getObject(row, pass);
        } else {
+               Crypto::GStore &store = m_decider.getStore(row);
+
+               Password pass = m_accessControl.isCCMode() ? "" : password;
+
                // decrypt entirely with old scheme: b64(pass(appkey(data))) -> data
                handler.crypto.decryptRow(pass, row);
                // destroy it in store
@@ -655,20 +650,26 @@ Crypto::GObjUPtr CKMLogic::rowToObject(
                                                                   Crypto::EncryptionParams(),
                                                                   hash);
 
-               // get it from the store (it can be different than the data we imported into store)
-               obj = store.getObject(token, pass);
-
                // update row with new token
                *static_cast<Token *>(&row) = std::move(token);
 
                // encrypt it with app key: pass(data) -> b64(appkey(pass(data))
-               handler.crypto.encryptRow(row);
+               auto encryptedRow = handler.crypto.encryptRow(row);
 
                // update it in db
-               handler.database.updateRow(row);
+               handler.database.updateRow(encryptedRow);
        }
+}
 
-       return obj;
+Crypto::GObjUPtr CKMLogic::rowToObject(
+       UserData &handler,
+       DB::Row row,
+       const Password &password,
+       const RawBuffer &hash)
+{
+       decryptRow(handler, row, password, hash);
+
+       return decryptedRowToObj(row, password);
 }
 
 int CKMLogic::readDataHelper(
@@ -740,21 +741,20 @@ int CKMLogic::readDataHelper(
                                                  password, obj, objDataType);
 }
 
-int CKMLogic::readDataHelper(
+int CKMLogic::readRowHelper(
        bool exportFlag,
        const Credentials &cred,
        DataType dataType,
        const Name &name,
        const ClientId &owner,
        const Password &password,
-       Crypto::GObjUPtr &obj,
+       DB::Row &row,
        DataType &objDataType)
 {
        auto [dbOp, permission, retCode] = beginAndGetPerm(cred, name, owner);
        if (retCode != CKM_API_SUCCESS)
                return retCode;
 
-       DB::Row row;
        retCode = readSingleRow(name, owner, dataType, dbOp.database(), row);
        if (CKM_API_SUCCESS != retCode)
                return retCode;
@@ -767,20 +767,49 @@ int CKMLogic::readDataHelper(
 
        // check access rights
        retCode = checkDataPermissionsHelper(cred, row, exportFlag, permission);
-       if (CKM_API_SUCCESS != retCode)
+       if (retCode != CKM_API_SUCCESS)
                return retCode;
 
        auto digest = CryptoLogic::makeHash(name, owner, cred.clientUid);
        if (digest.empty())
                return CKM_API_ERROR_HASH_ERROR;
 
-       obj = rowToObject(dbOp.handler(), std::move(row), password, digest);
-       // rowToObject may modify db
+       decryptRow(dbOp.handler(), row, password, digest);
+
+       // decryptRow may modify db
        dbOp.transaction().commit();
 
        return CKM_API_SUCCESS;
 }
 
+Crypto::GObjUPtr CKMLogic::decryptedRowToObj(const DB::Row& row, const Password &password)
+{
+       Crypto::GStore &store = m_decider.getStore(row);
+
+       Password pass = m_accessControl.isCCMode() ? "" : password;
+       return store.getObject(row, pass);
+}
+
+int CKMLogic::readDataHelper(
+       bool exportFlag,
+       const Credentials &cred,
+       DataType dataType,
+       const Name &name,
+       const ClientId &owner,
+       const Password &password,
+       Crypto::GObjUPtr &obj,
+       DataType &objDataType)
+{
+       DB::Row row;
+       int retCode = readRowHelper(exportFlag, cred, dataType, name, owner, password, row, objDataType);
+       if (retCode != CKM_API_SUCCESS)
+               return retCode;
+
+       obj = decryptedRowToObj(row, password);
+
+       return CKM_API_SUCCESS;
+}
+
 RawBuffer CKMLogic::getData(
        const Credentials &cred,
        int msgId,
index 58d07005c5b22b86bda66d3ddb41ececc01f491c..88296128bca201bc768e89042a484e203fe5cea1 100644 (file)
@@ -253,6 +253,12 @@ private:
                bool exportFlag,
                const PermissionMask& permission);
 
+       void decryptRow(
+               UserData &handler,
+               DB::Row &row,
+               const Password &password,
+               const RawBuffer &hash);
+
        Crypto::GObjUPtr rowToObject(
                UserData &handler,
                DB::Row row,
@@ -269,6 +275,18 @@ protected:
                Crypto::GObjUPtr &obj);
 
 private:
+       int readRowHelper(
+               bool exportFlag,
+               const Credentials &cred,
+               DataType dataType,
+               const Name &name,
+               const ClientId &owner,
+               const Password &password,
+               DB::Row &row,
+               DataType &objDataType);
+
+       Crypto::GObjUPtr decryptedRowToObj(const DB::Row& row, const Password &password);
+
        int readDataHelper(
                bool exportFlag,
                const Credentials &cred,
@@ -326,8 +344,7 @@ private:
 
                DB::Row encryptOne(Token&& token, const Policy& policy) {
                        DB::Row row(std::move(token), m_name, m_owner, static_cast<int>(policy.extractable));
-                       m_handler.crypto.encryptRow(row);
-                       return row;
+                       return m_handler.crypto.encryptRow(row);
                }
 
                void finalize(Token&& token, const Policy& policy) {
index bebdb7a64cf7326a14fe75816101f2f74dbfe763..a0dd9fbe738c8a308efdab7d72454a8cf6cb08ba 100644 (file)
@@ -121,7 +121,7 @@ RawBuffer CryptoLogic::generateRandIV() const
        return civ;
 }
 
-void CryptoLogic::encryptRow(DB::Row &row)
+DB::Row CryptoLogic::encryptRow(const DB::Row &row)
 {
        DB::Row crow = row;
        RawBuffer key;
@@ -132,14 +132,14 @@ void CryptoLogic::encryptRow(DB::Row &row)
        if (crow.dataSize <= 0)
                ThrowErr(Exc::InternalError, "Invalid dataSize.");
 
-       if (!haveKey(row.owner))
+       if (!haveKey(crow.owner))
                ThrowErr(Exc::InternalError, "Missing application key for ",
-                                row.owner, " client.");
+                                crow.owner, " client.");
 
        if (crow.iv.empty())
                crow.iv = generateRandIV();
 
-       key = m_keyMap[row.owner];
+       key = m_keyMap[crow.owner];
        CLEAR_FLAGS(crow.encryptionScheme);
        SET_FLAG(ENCR_APPKEY, crow.encryptionScheme);
 
@@ -160,7 +160,7 @@ void CryptoLogic::encryptRow(DB::Row &row)
 
        SET_ENCRYPTION_VERSION(ENCRYPTION_V2, crow.encryptionScheme);
 
-       row = std::move(crow);
+       return crow;
 }
 
 int CryptoLogic::getSchemeVersion(int encryptionScheme)
index 60543842ec5344a6f2437172eb6dc4f580c49a49..aec735224c03e3e778c521834f995c1c25b75538 100644 (file)
@@ -39,7 +39,7 @@ public:
        virtual ~CryptoLogic() {}
 
        void decryptRow(const Password &password, DB::Row &row);
-       void encryptRow(DB::Row &row);
+       DB::Row encryptRow(const DB::Row &row);
 
        static int getSchemeVersion(int encryptionScheme);
 
index b0b8c276c22267e73fe5fe5d48094a0949a37f1e..5c168a0baa8d233fcd874936b249535ecc55a03b 100644 (file)
@@ -141,9 +141,9 @@ POSITIVE_TEST_CASE(row_encryption)
 
        CryptoLogic logic;
 
-       DB::Row rowCopy = row;
+       DB::Row rowCopy;
        BOOST_REQUIRE_NO_THROW(logic.pushKey(TEST_CLIENT, TEST_KEY));
-       BOOST_REQUIRE_NO_THROW(logic.encryptRow(rowCopy));
+       BOOST_REQUIRE_NO_THROW(rowCopy = logic.encryptRow(row));
        BOOST_REQUIRE(rowCopy.algorithmType == DBCMAlgType::AES_GCM_256);
        BOOST_REQUIRE(rowCopy.dataSize == static_cast<int>(row.data.size()));
        BOOST_REQUIRE(!rowCopy.iv.empty());
@@ -191,64 +191,65 @@ NEGATIVE_TEST_CASE(row_encryption)
        row.iv.clear();
 
        // correct encryption
-       BOOST_REQUIRE_NO_THROW(logic.encryptRow(row));
+       DB::Row encryptedRow;
+       BOOST_REQUIRE_NO_THROW(encryptedRow = logic.encryptRow(row));
 
        // wrong algorithm
-       row.algorithmType = DBCMAlgType::NONE;
-       BOOST_REQUIRE_THROW(logic.decryptRow("", row), Exc::AuthenticationFailed);
-       row.algorithmType = DBCMAlgType::AES_GCM_256;
+       encryptedRow.algorithmType = DBCMAlgType::NONE;
+       BOOST_REQUIRE_THROW(logic.decryptRow("", encryptedRow), Exc::AuthenticationFailed);
+       encryptedRow.algorithmType = DBCMAlgType::AES_GCM_256;
 
        // unnecessary password
-       BOOST_REQUIRE_THROW(logic.decryptRow("unnecessary password", row),
+       BOOST_REQUIRE_THROW(logic.decryptRow("unnecessary password", encryptedRow),
                                                Exc::AuthenticationFailed);
 
        // no key
        BOOST_REQUIRE_NO_THROW(logic.removeKey(TEST_CLIENT));
-       BOOST_REQUIRE_THROW(logic.decryptRow("", row), Exc::AuthenticationFailed);
+       BOOST_REQUIRE_THROW(logic.decryptRow("", encryptedRow), Exc::AuthenticationFailed);
        BOOST_REQUIRE_NO_THROW(logic.pushKey(TEST_CLIENT, TEST_KEY));
 
        // wrong owner
-       ++row.owner[0];
-       BOOST_REQUIRE_THROW(logic.decryptRow("", row), Exc::AuthenticationFailed);
-       --row.owner[0];
+       ++encryptedRow.owner[0];
+       BOOST_REQUIRE_THROW(logic.decryptRow("", encryptedRow), Exc::AuthenticationFailed);
+       --encryptedRow.owner[0];
 
        // no iv
-       auto rowCopy = row;
+       auto rowCopy = encryptedRow;
        rowCopy.iv.clear();
        BOOST_REQUIRE_THROW(logic.decryptRow("", rowCopy), Exc::InternalError);
 
        // wrong iv (not base64)
-       rowCopy = row;
+       rowCopy = encryptedRow;
        rowCopy.iv[0] = 64;
        BOOST_REQUIRE_THROW(logic.decryptRow("", rowCopy), Exc::InternalError);
 
        // wrong iv
-       rowCopy = row;
+       rowCopy = encryptedRow;
        changeBase64(rowCopy.iv);
        BOOST_REQUIRE_THROW(logic.decryptRow("", rowCopy), Exc::AuthenticationFailed);
 
        // no ciphertext
-       rowCopy = row;
+       rowCopy = encryptedRow;
        rowCopy.data.clear();
        BOOST_REQUIRE_THROW(logic.decryptRow("", rowCopy),Exc::InternalError);
 
        // wrong ciphertext (not base64)
-       rowCopy = row;
+       rowCopy = encryptedRow;
        rowCopy.data[0] = 64;
        BOOST_REQUIRE_THROW(logic.decryptRow("", rowCopy), Exc::InternalError);
 
        // wrong ciphertext
-       rowCopy = row;
+       rowCopy = encryptedRow;
        changeBase64(rowCopy.data);
        BOOST_REQUIRE_THROW(logic.decryptRow("", rowCopy), Exc::AuthenticationFailed);
 
        // wrong tag
-       rowCopy = row;
+       rowCopy = encryptedRow;
        ++rowCopy.tag[0];
        BOOST_REQUIRE_THROW(logic.decryptRow("", rowCopy), Exc::AuthenticationFailed);
 
        // wrong dataSize
-       rowCopy = row;
+       rowCopy = encryptedRow;
        ++rowCopy.dataSize;
        BOOST_REQUIRE_THROW(logic.decryptRow("", rowCopy), Exc::AuthenticationFailed);
 }