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:
};
typedef std::vector<AliasInfo> AliasInfoVector;
+struct BackendInfo {
+ size_t maxChunkSize;
+};
+
enum class KeyType : int {
KEY_NONE = 0,
KEY_RSA_PUBLIC,
CKMC_BACKEND_TZ /**< TrustZone backend */
} ckmc_backend_id_e;
-struct __ckmc_backend_info_s;
-
/**
* @brief Backend information handle.
* @since_tizen 6.0
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
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
}
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
KEY_MANAGER_CAPI
void ckmc_backend_info_free(ckmc_backend_info_h info)
{
- free(info);
+ delete reinterpret_cast<CKM::BackendInfo*>(info);
}
int type;
ckmc_backend_id_e backend;
};
-
- struct __ckmc_backend_info_s {
- size_t max_chunk_size;
- };
}
namespace CKM {
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
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,
return m_impl->finalizeCipher(requestId, in, out);
}
+int Manager::getBackendInfo(BackendId backend, BackendInfo& info)
+{
+ return m_impl->getBackendInfo(backend, info);
+}
+
ManagerShPtr Manager::create()
{
try {
}
}
+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);
GET_PROTECTION_STATUS,
DERIVE,
IMPORT_WRAPPED_KEY,
- EXPORT_WRAPPED_KEY
+ EXPORT_WRAPPED_KEY,
+ GET_BACKEND_INFO
};
enum class EncryptionCommand : int {
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);
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:
{
}
-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)
{
class Decider final {
public:
Decider();
+ GStore *getStore(const CryptoBackend &backend);
GStore &getStore(const Token &token);
GStore &getStore(DataType data,
const Policy &policy,
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
};
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
const ClientId &keyOwner,
const Password &keyPassword);
+ RawBuffer getBackendInfo(
+ const int msgID,
+ BackendId backend);
+
int setPermissionHelper(
const Credentials &cred,
const Name &name,
keyPassword);
}
+ case LogicCommand::GET_BACKEND_INFO: {
+ BackendId backend;
+
+ buffer.Deserialize(backend);
+
+ return m_logic->getBackendInfo(msgId, backend);
+ }
+
default:
Throw(Exception::BrokenProtocol);
}
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()