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 dd91e99e6feac3e4caa3832ea86801c1f2f60fcc..245b3d1eca5fcc56ff1a0ef446047c8cb939cb1f 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 3bbbf030acbab18b155256fde4819cadd584705f..8653009328bbdea446786093c7d08a49279b5214 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 1d6d9ccbe85641beadd72b732f6bb043ca8eec0b..ef34a1df4a583b5df22be01998d79840ae13023a 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 326685edb6b81728e41db4377a06b592cabf75c9..601f9d1556721349f528d7209b45a75f27941393 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 bd8f5a88b1b5b168f82357e62ea9450155f995b5..f0a137aacb197caeb28205418ca9be0d5d8ad2f9 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 fee7183053bae01c31e062740d1f4eda62f4710a..3d6b1a96366e6a8415fb29b70d0542738125f046 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 adf67b67ef0153ed2a0140c6c7dcc36abfb52a04..4d6e59e49a34dfb004e76f177f4c71102c6d367a 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 e88894e4d98bc2baf337d4bad4961383e97f5403..fd5fcf7aa39106df41b40058400dad3f199215e6 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 46a822a3a313ddf83df5afdc81d9f209cf190540..1691037f7e3993db9d258d865c4961a68f380680 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 3e6503f9b1f57a46c719b83bb8b425715b733f0a..d402548e41ff9829de56ad8ebf56b233c3bd584b 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 b95354f76ab72e69eb6b56a5bab8193bfab98d7e..75c12cf90eae7bf7fc323101aed7391716b6648d 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 5d54c5ac0fe93425a8ec02abb6883dce596c690f..1348feaa2592d92067a8302ede57e3b8e1c0dbb8 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 ff67a1eefc0153cae82ddcee56c8a59783c6ae10..bdb976e223d370f74f3bbd69474d6c8723a21229 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 3315e764b049f3c704030e3ba62ed832d24168a3..47fb08d1d74e292c51d7621025e565ec523262de 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 d15fa09a9dab096b7e1bd83dd817213a4939ef25..439cec4f7a80c4581558feb2a9f41ad6f6c272e8 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 8b6261c0e8dbd4ff4358c3c56a6192af3c434856..98619e0dd77574e00374e26645cea7202de0cce5 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 f9a3cb59d9142d7b9bbd46d3d9891a5f87abcde9..a8fc1b7360caf9436f3f520b4fa7425965cb6fa8 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 511f271cf960523179d832e092fa27f599757435..7bfebbe56c7479452295bc7596ba46c9cead2aef 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 854bb255426e825b3065b09f6c6e129fcfa259b4..866e3ebe69fc8d3f35cb8dbf74feecab7c8dc57e 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()