Backend info API implementation 91/293891/6
authorKrzysztof Jackiewicz <k.jackiewicz@samsung.com>
Wed, 7 Jun 2023 11:19:02 +0000 (13:19 +0200)
committerKrzysztof Jackiewicz <k.jackiewicz@samsung.com>
Wed, 14 Jun 2023 07:59:17 +0000 (07:59 +0000)
Change-Id: Ib47c16bf5d2255c71d538b9e1009cb54b8f842ba

19 files changed:
src/include/ckm/ckm-manager.h
src/include/ckm/ckm-type.h
src/include/ckmc/ckmc-type.h
src/manager/client-capi/ckmc-manager.cpp
src/manager/client-capi/ckmc-type.cpp
src/manager/client/client-common.h
src/manager/client/client-manager-impl.cpp
src/manager/client/client-manager-impl.h
src/manager/client/client-manager.cpp
src/manager/common/protocols.cpp
src/manager/common/protocols.h
src/manager/crypto/generic-backend/gstore.h
src/manager/crypto/platform/decider.cpp
src/manager/crypto/platform/decider.h
src/manager/crypto/tz-backend/store.h
src/manager/service/ckm-logic.cpp
src/manager/service/ckm-logic.h
src/manager/service/ckm-service.cpp
unit-tests/test_sw-backend.cpp

index dd91e99..245b3d1 100644 (file)
@@ -200,6 +200,8 @@ public:
        int updateCipher(int requestId, const RawBuffer &in, RawBuffer &out);
        int finalizeCipher(int requestId, const RawBuffer &in, RawBuffer &out);
 
+       int getBackendInfo(BackendId backend, BackendInfo& info);
+
        static ManagerShPtr create();
 
 private:
index 3bbbf03..8653009 100644 (file)
@@ -80,6 +80,10 @@ struct AliasInfo {
 };
 typedef std::vector<AliasInfo> AliasInfoVector;
 
+struct BackendInfo {
+       size_t maxChunkSize;
+};
+
 enum class KeyType : int {
        KEY_NONE = 0,
        KEY_RSA_PUBLIC,
index 1d6d9cc..ef34a1d 100644 (file)
@@ -472,8 +472,6 @@ typedef enum __ckmc_backend_id {
        CKMC_BACKEND_TZ      /**< TrustZone backend */
 } ckmc_backend_id_e;
 
-struct __ckmc_backend_info_s;
-
 /**
  * @brief Backend information handle.
  * @since_tizen 6.0
@@ -1094,13 +1092,14 @@ void ckmc_param_list_free(ckmc_param_list_h params);
 int ckmc_generate_new_params(ckmc_algo_type_e type, ckmc_param_list_h *pparams);
 
 /**
- * @brief Retrieves maximum data chunk size that can be passed to given backend. This is the maximum
- *        size of data passed for encryption/decryption.
+ * @brief Retrieves maximum data chunk size in bytes that can be passed to given backend. This is
+ *        the maximum size of data passed as encryption/decryption input, AAD or IV.
  *
  * @since_tizen 6.0
  *
  * @param[in] info Backend info handle
- * @param[out] size Maximum chunk size
+ * @param[out] size Maximum chunk size. Equal to 0 if there's no backend specific limitation beside
+ *             available memory
  *
  * @return @c 0 on success, otherwise a negative error value
  * @retval #CKMC_ERROR_NONE Successful
index 326685e..601f9d1 100644 (file)
@@ -1119,14 +1119,17 @@ int ckmc_get_backend_info(ckmc_backend_id_e backend, ckmc_backend_info_h* ppinfo
        if (backend < CKMC_BACKEND_SW || backend > CKMC_BACKEND_TZ || ppinfo == nullptr)
                return CKMC_ERROR_INVALID_PARAMETER;
 
-       // TODO get it
-       auto _info = static_cast<ckmc_backend_info_h>(malloc(sizeof(__ckmc_backend_info_s)));
-       if (_info == nullptr)
-               return CKMC_ERROR_OUT_OF_MEMORY;
+       int ret = 0;
+       auto mgr = CKM::Manager::create();
+       auto info = new CKM::BackendInfo();
 
-       *ppinfo = _info;
+       ret = to_ckmc_error(mgr->getBackendInfo(static_cast<CKM::BackendId>(backend), *info));
+       if (ret != CKMC_ERROR_NONE)
+               return ret;
+
+       *ppinfo = reinterpret_cast<ckmc_backend_info_h>(info);
 
-       return CKMC_ERROR_SERVER_ERROR;
+       return CKMC_ERROR_NONE;
 
        EXCEPTION_GUARD_END
 }
index bd8f5a8..f0a137a 100644 (file)
@@ -881,7 +881,7 @@ int ckmc_backend_get_max_chunk_size(const ckmc_backend_info_h info, size_t* size
        if (info == nullptr || size == nullptr)
                return CKMC_ERROR_INVALID_PARAMETER;
 
-       *size = info->max_chunk_size;
+       *size = reinterpret_cast<CKM::BackendInfo*>(info)->maxChunkSize;
        return CKMC_ERROR_NONE;
 
        EXCEPTION_GUARD_END
@@ -890,5 +890,5 @@ int ckmc_backend_get_max_chunk_size(const ckmc_backend_info_h info, size_t* size
 KEY_MANAGER_CAPI
 void ckmc_backend_info_free(ckmc_backend_info_h info)
 {
-       free(info);
+       delete reinterpret_cast<CKM::BackendInfo*>(info);
 }
index fee7183..3d6b1a9 100644 (file)
@@ -48,10 +48,6 @@ extern "C" {
                int type;
                ckmc_backend_id_e backend;
        };
-
-       struct __ckmc_backend_info_s {
-               size_t max_chunk_size;
-       };
 }
 
 namespace CKM {
index adf67b6..4d6e59e 100644 (file)
@@ -858,4 +858,18 @@ int Manager::Impl::finalizeCipher(int requestId, const RawBuffer &in, RawBuffer
        EXCEPTION_GUARD_END
 }
 
+int Manager::Impl::getBackendInfo(BackendId backend, BackendInfo& info)
+{
+       EXCEPTION_GUARD_START_CPPAPI
+
+       BackendInfoSerializable bis(info);
+       return Request(*this,
+               LogicCommand::GET_BACKEND_INFO,
+               m_storageConnection,
+               backend
+       ).maybeDeserialize(bis);
+
+       EXCEPTION_GUARD_END
+}
+
 } // namespace CKM
index e88894e..fd5fcf7 100644 (file)
@@ -165,6 +165,8 @@ public:
        int updateCipher(int requestId, const RawBuffer &in, RawBuffer &out);
        int finalizeCipher(int requestId, const RawBuffer &in, RawBuffer &out);
 
+       int getBackendInfo(BackendId backend, BackendInfo& info);
+
 private:
        int saveBinaryData(
                const Alias &alias,
index 46a822a..1691037 100644 (file)
@@ -354,6 +354,11 @@ int Manager::finalizeCipher(int requestId, const RawBuffer &in, RawBuffer &out)
        return m_impl->finalizeCipher(requestId, in, out);
 }
 
+int Manager::getBackendInfo(BackendId backend, BackendInfo& info)
+{
+       return m_impl->getBackendInfo(backend, info);
+}
+
 ManagerShPtr Manager::create()
 {
        try {
index 3e6503f..d402548 100644 (file)
@@ -308,6 +308,20 @@ void AliasInfoSerializableVector::Serialize(IStream &stream) const
        }
 }
 
+BackendInfoSerializable::BackendInfoSerializable(BackendInfo &i) : backendInfo(i)
+{
+}
+
+void BackendInfoSerializable::Deserialize(IStream &stream)
+{
+       Deserialization::Deserialize(stream, backendInfo.maxChunkSize);
+}
+
+void BackendInfoSerializable::Serialize(IStream &stream) const
+{
+       Serialization::Serialize(stream, backendInfo.maxChunkSize);
+}
+
 AliasSupport::AliasSupport(const Alias &alias)
 {
        std::size_t separator_pos = alias.rfind(CKM::ALIAS_SEPARATOR);
index b95354f..75c12cf 100644 (file)
@@ -69,7 +69,8 @@ enum class LogicCommand : int {
        GET_PROTECTION_STATUS,
        DERIVE,
        IMPORT_WRAPPED_KEY,
-       EXPORT_WRAPPED_KEY
+       EXPORT_WRAPPED_KEY,
+       GET_BACKEND_INFO
 };
 
 enum class EncryptionCommand : int {
@@ -138,6 +139,14 @@ private:
        AliasInfoVector& aliasInfoVector;
 };
 
+struct COMMON_API BackendInfoSerializable : public ISerializable {
+       explicit BackendInfoSerializable(BackendInfo &);
+       void Serialize(IStream &) const override;
+       void Deserialize(IStream &) override;
+private:
+       BackendInfo& backendInfo;
+};
+
 class COMMON_API AliasSupport {
 public:
        explicit AliasSupport(const Alias &alias);
index 5d54c5a..1348fea 100644 (file)
@@ -54,6 +54,8 @@ public:
        virtual Token import(const Data &, const Password &, const EncryptionParams &,
                                                                   const RawBuffer &) = 0;
        virtual void destroy(const Token &) = 0;
+       virtual size_t maxChunkSize() const { return 0; }
+
        virtual ~GStore() {}
 
 protected:
index ff67a1e..bdb976e 100644 (file)
@@ -42,23 +42,29 @@ Decider::Decider()
 {
 }
 
-GStore &Decider::getStore(const Token &token)
+GStore* Decider::getStore(const CryptoBackend &backendId)
 {
-       GStore *gStore = NULL;
+       GStore *gStore = nullptr;
 
-       if (token.backendId == CryptoBackend::OpenSSL)
+       if (backendId == CryptoBackend::OpenSSL)
                gStore = &m_swStore;
 #ifdef TZ_BACKEND_ENABLED
-       if (token.backendId == CryptoBackend::TrustZone)
+       if (backendId == CryptoBackend::TrustZone)
                gStore = &m_tzStore;
 #endif
-       if (gStore)
-               return *gStore;
+       return gStore;
+}
+
+GStore &Decider::getStore(const Token &token)
+{
+       auto store = getStore(token.backendId);
+       if (store != nullptr)
+               return *store;
 
        ThrowErr(Exc::Crypto::InternalError,
                 "Backend not available. BackendId: ",
                 static_cast<int>(token.backendId));
-};
+}
 
 GStore* Decider::tryBackend(CryptoBackend backend)
 {
index 3315e76..47fb08d 100644 (file)
@@ -41,6 +41,7 @@ namespace Crypto {
 class Decider final {
 public:
        Decider();
+       GStore *getStore(const CryptoBackend &backend);
        GStore &getStore(const Token &token);
        GStore &getStore(DataType data,
                         const Policy &policy,
index d15fa09..439cec4 100644 (file)
@@ -55,6 +55,8 @@ public:
                                           RawBuffer &data,
                                           RawBuffer &iv,
                                           RawBuffer &tag);
+       size_t maxChunkSize() const override { return 4; } // TODO get it from somewhere
+
        // TODO device key ID is needed here to support importEncrypted
 };
 
index 8b6261c..98619e0 100644 (file)
@@ -1646,4 +1646,29 @@ RawBuffer CKMLogic::exportWrappedKey(
        return SerializeMessage(msgID, retCode, wrappedKeyType, wrappedKey);
 }
 
+RawBuffer CKMLogic::getBackendInfo(const int msgID, BackendId backend)
+{
+       BackendInfo info;
+       auto retCode = tryRet([&] {
+               CryptoBackend cryptoBackend;
+               if (backend == BackendId::SW)
+                       cryptoBackend = CryptoBackend::OpenSSL;
+               else if (backend == BackendId::TZ)
+                       cryptoBackend = CryptoBackend::TrustZone;
+               else
+                       return CKM_API_ERROR_INPUT_PARAM;
+
+               auto store = m_decider.getStore(cryptoBackend);
+               if (store == nullptr) {
+                       LogError("Required backend is unavailable");
+                       return CKM_API_ERROR_INPUT_PARAM;
+               }
+
+               info.maxChunkSize = store->maxChunkSize();
+               return CKM_API_SUCCESS;
+       });
+
+       return SerializeMessage(msgID, retCode, BackendInfoSerializable(info));
+}
+
 } // namespace CKM
index f9a3cb5..a8fc1b7 100644 (file)
@@ -226,6 +226,10 @@ public:
                const ClientId &keyOwner,
                const Password &keyPassword);
 
+       RawBuffer getBackendInfo(
+               const int msgID,
+               BackendId backend);
+
        int setPermissionHelper(
                const Credentials &cred,
                const Name &name,
index 511f271..7bfebbe 100644 (file)
@@ -520,6 +520,14 @@ RawBuffer CKMService::ProcessStorage(Credentials &cred, MessageBuffer &buffer)
                                        keyPassword);
        }
 
+       case LogicCommand::GET_BACKEND_INFO: {
+               BackendId backend;
+
+               buffer.Deserialize(backend);
+
+               return m_logic->getBackendInfo(msgId, backend);
+       }
+
        default:
                Throw(Exception::BrokenProtocol);
        }
index 854bb25..866e3eb 100644 (file)
@@ -1501,4 +1501,11 @@ POSITIVE_TEST_CASE(cipherAPI)
        BOOST_REQUIRE_NO_THROW(gcm->finalize(tag));
 }
 
+POSITIVE_TEST_CASE(backendInfo)
+{
+       size_t ret;
+       BOOST_REQUIRE_NO_THROW(ret = STORE.maxChunkSize());
+       BOOST_REQUIRE(ret == 0);
+}
+
 BOOST_AUTO_TEST_SUITE_END()