/*
- * Copyright (c) 2017 - 2018 Samsung Electronics Co., Ltd All Rights Reserved
+ * Copyright (c) 2017 - 2019 Samsung Electronics Co., Ltd All Rights Reserved
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
#include <tz-backend/tz-context.h>
#include <tz-backend/tz-memory.h>
+#include <tz-backend/tz-serializer.h>
#include <generic-backend/exception.h>
#include <generic-backend/crypto-params.h>
#include <generic-backend/encryption-params.h>
// [2].memref - reference to serialized buffer:
// KM_BinaryData with data id
// KM_BinaryData with tag id (optional, if password was provided)
- uint32_t inMemorySize = 0;
- // place for dataType
- inMemorySize += KM_SizeOfFlag();
-
- KM_BinaryData ta_data;
- ta_data.data_size = static_cast<uint32_t>(data.size());
- ta_data.data = const_cast<unsigned char *>(data.data());
- inMemorySize += KM_SizeOfBinaryData(&ta_data);
-
- uint32_t keySizeBits_flags = static_cast<uint32_t>(keySizeBits);
- inMemorySize += KM_SizeOfFlag();
-
- KM_BinaryData ta_data_enc_iv;
- ta_data_enc_iv.data_size = static_cast<uint32_t>(encData.iv.size());
- ta_data_enc_iv.data = const_cast<unsigned char *>(encData.iv.data());
- inMemorySize += KM_SizeOfBinaryData(&ta_data_enc_iv);
-
- KM_BinaryData ta_data_enc_tag;
- ta_data_enc_tag.data_size = static_cast<uint32_t>(encData.tag.size());
- ta_data_enc_tag.data = const_cast<unsigned char *>(encData.tag.data());
- inMemorySize += KM_SizeOfBinaryData(&ta_data_enc_tag);
+ TZSerializer sIn;
+ sIn.Push(new TZSerializableFlag(dataType));
+ sIn.Push(new TZSerializableBinary(data));
+ sIn.Push(new TZSerializableFlag(keySizeBits));
+ sIn.Push(new TZSerializableBinary(encData.iv));
+ sIn.Push(new TZSerializableBinary(encData.tag));
uint32_t pwd_flag = pwd.empty() ? 0 : 1;
- inMemorySize += KM_SizeOfFlag();
-
- KM_PwdData kmPwdData;
- if (pwd_flag) {
- memset(&kmPwdData, 0, sizeof(KM_PwdData));
- kmPwdData.pwd = const_cast<unsigned char *>(pwd.data());
- kmPwdData.pwd_size = pwd.size();
- kmPwdData.iv = const_cast<unsigned char *>(iv.data());
- kmPwdData.iv_size = iv.size();
- kmPwdData.tag = NULL;
- kmPwdData.tag_size = 0;
- kmPwdData.derive_len_bits = Params::DERIVED_KEY_LENGTH_BITS;
- kmPwdData.it_count = Params::DERIVED_KEY_ITERATIONS;
- kmPwdData.tag_len_bits = pwdTagSizeBits;
-
- inMemorySize += KM_SizeOfPwdData(&kmPwdData);
- }
-
- TrustZoneMemory inMemory(m_Context, inMemorySize, TEEC_MEM_INPUT);
- void *inMemoryPtr = inMemory.Get()->buffer;
-
- int ret = KM_SerializeFlag(&inMemoryPtr, &inMemorySize, dataType);
- if (ret){
- ThrowErr(Exc::Crypto::InternalError, "Failed to serialize data, ret: ", ret);
- }
-
- ret = KM_SerializeBinaryData(&inMemoryPtr, &inMemorySize, &ta_data);
- if (ret) {
- ThrowErr(Exc::Crypto::InternalError, "Failed to serialize data, ret: ", ret);
- }
-
- ret = KM_SerializeFlag(&inMemoryPtr, &inMemorySize, keySizeBits_flags);
- if (ret) {
- ThrowErr(Exc::Crypto::InternalError, "Failed to serialize data, ret: ", ret);
- }
-
- ret = KM_SerializeBinaryData(&inMemoryPtr, &inMemorySize, &ta_data_enc_iv);
- if (ret) {
- ThrowErr(Exc::Crypto::InternalError, "Failed to serialize data, ret: ", ret);
- }
+ sIn.Push(new TZSerializableFlag(pwd_flag));
+ if (pwd_flag)
+ sIn.Push(new TZSerializablePwdData(pwd, iv, pwdTagSizeBits));
- ret = KM_SerializeBinaryData(&inMemoryPtr, &inMemorySize, &ta_data_enc_tag);
- if (ret) {
- ThrowErr(Exc::Crypto::InternalError, "Failed to serialize data, ret: ", ret);
- }
-
- ret = KM_SerializeFlag(&inMemoryPtr, &inMemorySize, pwd_flag);
- if (ret) {
- ThrowErr(Exc::Crypto::InternalError, "Failed to serialize data, ret: ", ret);
- }
+ TrustZoneMemory inMemory(m_Context, sIn.GetSize(), TEEC_MEM_INPUT);
+ sIn.Serialize(inMemory);
- if (pwd_flag) {
- ret = KM_SerializePwdData(&inMemoryPtr, &inMemorySize, &kmPwdData);
- if (ret) {
- ThrowErr(Exc::Crypto::InternalError, "Failed to serialize data, ret: ", ret);
- }
- }
- KM_BinaryData kmDataId;
- KM_BinaryData kmTag;
- memset(&kmDataId, 0, sizeof(KM_BinaryData));
- memset(&kmTag, 0, sizeof(KM_BinaryData));
- kmDataId.data_size = KM_DATA_ID_SIZE;
- uint32_t outMemorySize = KM_SizeOfBinaryData(&kmDataId);
+ TZSerializer sOut;
+ sOut.Push(new TZSerializableBinary(KM_DATA_ID_SIZE));
if (pwd_flag) {
- kmTag.data_size = pwdTagSizeBits / 8;
- outMemorySize += KM_SizeOfBinaryData(&kmTag);
+ sOut.Push(new TZSerializableBinary(pwdTagSizeBits / 8));
}
- TrustZoneMemory outMemory(m_Context, outMemorySize, TEEC_MEM_OUTPUT);
- void *outMemoryPtr = outMemory.Get()->buffer;
+ TrustZoneMemory outMemory(m_Context, sOut.GetSize(), TEEC_MEM_OUTPUT);
TEEC_Operation op;
op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INOUT, TEEC_MEMREF_WHOLE,
Execute(CMD_IMPORT_DATA, &op);
- ret = KM_DeserializeBinaryData(&outMemoryPtr, &outMemorySize, &kmDataId);
- if (ret) {
- ThrowErr(Exc::Crypto::InternalError, "Failed to deserialize data, ret: ", ret);
- }
- dataId.resize(kmDataId.data_size);
- memcpy(dataId.data(), kmDataId.data, kmDataId.data_size);
+ sOut.Deserialize(outMemory);
+ sOut.Pull(dataId);
if (pwd_flag) {
- ret = KM_DeserializeBinaryData(&outMemoryPtr, &outMemorySize, &kmTag);
- if (ret) {
- ThrowErr(Exc::Crypto::InternalError, "Failed to deserialize data, ret: ", ret);
- }
- pwdTag.resize(kmTag.data_size);
- memcpy(pwdTag.data(), kmTag.data, kmTag.data_size);
+ sOut.Pull(pwdTag);
}
LogDebug("Imported object ID is (hex): " << rawToHexString(dataId));
// [0].value.a - return code
// [0].value.b - size of buffer to be passed from CA
LogDebug("Object ID (passed to CMD_GET_DATA_SIZE) is (hex): " << rawToHexString(dataId));
- KM_BinaryData kmDataId;
- kmDataId.data_size = static_cast<uint32_t>(dataId.size());
- kmDataId.data = const_cast<unsigned char *>(dataId.data());
- uint32_t inMemorySize = KM_SizeOfBinaryData(&kmDataId);
- TrustZoneMemory inMemory(m_Context, inMemorySize, TEEC_MEM_INPUT);
- void *inMemoryPtr = inMemory.Get()->buffer;
- int ret = KM_SerializeBinaryData(&inMemoryPtr, &inMemorySize, &kmDataId);
- if (ret) {
- ThrowErr(Exc::Crypto::InternalError, "Failed to deserialize data, ret: ", ret);
- }
+
+ TZSerializer sIn;
+ sIn.Push(new TZSerializableBinary(dataId));
+
+ TrustZoneMemory inMemory(m_Context, sIn.GetSize(), TEEC_MEM_INPUT);
+ sIn.Serialize(inMemory);
+
TEEC_Operation op;
op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_OUTPUT, TEEC_MEMREF_WHOLE,
TEEC_NONE, TEEC_NONE);
// [2].memref - reference to serialized buffer:
// KM_BinaryData with binary data
LogDebug("Object ID (passed to CMD_GET_DATA) is (hex): " << rawToHexString(dataId));
- uint32_t data_size = 0;
- GetDataSize(dataId, data_size);
- KM_BinaryData kmDataId;
- kmDataId.data_size = static_cast<uint32_t>(dataId.size());
- kmDataId.data = const_cast<unsigned char *>(dataId.data());
- uint32_t inMemorySize = KM_SizeOfBinaryData(&kmDataId) + KM_SizeOfFlag();
- uint32_t pwd_flag = pwd.getPassword().empty() ? 0 : 1;
- uint32_t pwdTagSizeBits = Params::DEFAULT_AES_GCM_TAG_LEN_BITS;
-
- KM_PwdData kmPwdData;
- if (pwd_flag) {
- memset(&kmPwdData, 0, sizeof(KM_PwdData));
- kmPwdData.pwd = const_cast<unsigned char *>(pwd.getPassword().data());
- kmPwdData.pwd_size = pwd.getPassword().size();
- kmPwdData.iv = const_cast<unsigned char *>(pwd.getIV().data());
- kmPwdData.iv_size = pwd.getIV().size();
- kmPwdData.tag = const_cast<unsigned char *>(pwd.getTag().data());
- kmPwdData.tag_size = pwd.getTag().size();
- kmPwdData.derive_len_bits = Params::DERIVED_KEY_LENGTH_BITS;
- kmPwdData.it_count = Params::DERIVED_KEY_ITERATIONS;
- kmPwdData.tag_len_bits = pwdTagSizeBits;
-
- inMemorySize += KM_SizeOfPwdData(&kmPwdData);
- }
+ TZSerializer sIn;
+ sIn.Push(new TZSerializableBinary(dataId));
- TrustZoneMemory inMemory(m_Context, inMemorySize, TEEC_MEM_INPUT);
- void *inMemoryPtr = inMemory.Get()->buffer;
+ uint32_t pwd_flag = pwd.getPassword().empty() ? 0 : 1;
+ sIn.Push(new TZSerializableFlag(pwd_flag));
- int ret = KM_SerializeBinaryData(&inMemoryPtr, &inMemorySize, &kmDataId);
- if (ret) {
- ThrowErr(Exc::Crypto::InternalError, "Failed to serialize data, ret: ", ret);
- }
- ret = KM_SerializeFlag(&inMemoryPtr, &inMemorySize, pwd_flag);
- if (ret) {
- ThrowErr(Exc::Crypto::InternalError, "Failed to serialize data, ret: ", ret);
- }
if (pwd_flag) {
- ret = KM_SerializePwdData(&inMemoryPtr, &inMemorySize, &kmPwdData);
- if (ret) {
- ThrowErr(Exc::Crypto::InternalError, "Failed to serialize data, ret: ", ret);
- }
+ sIn.Push(new TZSerializablePwdData(pwd.getPassword(),
+ pwd.getIV(),
+ Params::DEFAULT_AES_GCM_TAG_LEN_BITS,
+ pwd.getTag()));
}
- KM_BinaryData kmExtractedData;
- memset(&kmExtractedData, 0, sizeof(KM_BinaryData));
- kmExtractedData.data_size = data_size;
-
- uint32_t outMemorySize = KM_SizeOfBinaryData(&kmExtractedData);
- uint32_t outMemorySize2 = outMemorySize;
+ TrustZoneMemory inMemory(m_Context, sIn.GetSize(), TEEC_MEM_INPUT);
+ sIn.Serialize(inMemory);
- TrustZoneMemory outMemory(m_Context, outMemorySize, TEEC_MEM_OUTPUT);
- void *outMemoryPtr = outMemory.Get()->buffer;
- void *outMemoryPtr2 = outMemory.Get()->buffer;
+ uint32_t data_size = 0;
+ GetDataSize(dataId, data_size);
- // requesting size is saved in this buffer
- ret = KM_SerializeBinaryData(&outMemoryPtr2, &outMemorySize2, &kmExtractedData);
- if (ret) {
- ThrowErr(Exc::Crypto::InternalError, "Failed to serialize data, ret: ", ret);
- }
+ TZSerializer sOut;
+ sOut.Push(new TZSerializableBinary(data_size));
+ TrustZoneMemory outMemory(m_Context, sOut.GetSize(), TEEC_MEM_OUTPUT);
+ sOut.Serialize(outMemory);
TEEC_Operation op;
op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INOUT, TEEC_MEMREF_WHOLE,
Execute(CMD_GET_DATA, &op);
- ret = KM_DeserializeBinaryData(&outMemoryPtr, &outMemorySize, &kmExtractedData);
- if (ret) {
- ThrowErr(Exc::Crypto::InternalError, "Failed to serialize data, ret: ", ret);
- }
-
- data.resize(kmExtractedData.data_size);
- memcpy(data.data(), kmExtractedData.data, kmExtractedData.data_size);
+ sOut.Deserialize(outMemory);
+ sOut.Pull(data);
}
// output:
// [0].value.a - return code
LogDebug("Object ID (passed to CMD_GET_DATA) is (hex): " << rawToHexString(dataId));
- KM_BinaryData kmDataId;
- kmDataId.data_size = static_cast<uint32_t>(dataId.size());
- kmDataId.data = const_cast<unsigned char *>(dataId.data());
- uint32_t inMemorySize = KM_SizeOfBinaryData(&kmDataId);
- TrustZoneMemory inMemory(m_Context, inMemorySize, TEEC_MEM_INPUT);
- void *inMemoryPtr = inMemory.Get()->buffer;
-
- int ret = KM_SerializeBinaryData(&inMemoryPtr, &inMemorySize, &kmDataId);
+ TZSerializer sIn;
+ sIn.Push(new TZSerializableBinary(dataId));
- if (ret) {
- ThrowErr(Exc::Crypto::InternalError, "Failed to serialize data, ret: ", ret);
- }
+ TrustZoneMemory inMemory(m_Context, sIn.GetSize(), TEEC_MEM_INPUT);
+ sIn.Serialize(inMemory);
TEEC_Operation op;
op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_OUTPUT, TEEC_MEMREF_WHOLE,
--- /dev/null
+/*
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+/*
+ * @file tz-serializer.cpp
+ * @author Krzysztof Jackiewicz (k.jackiewicz@samsung.com)
+ * @version 1.0
+ * @brief
+ */
+#include "tz-serializer.h"
+
+#include <string.h>
+
+#include <generic-backend/crypto-params.h>
+
+namespace CKM {
+namespace Crypto {
+namespace TZ {
+namespace Internals {
+
+// TZSerializable
+void TZSerializable::Pull(RawBuffer &) const
+{
+ ThrowErr(Exc::Crypto::InternalError,
+ "This serializable does not support conversion to RawBuffer");
+}
+
+void TZSerializable::Pull(uint32_t &) const
+{
+ ThrowErr(Exc::Crypto::InternalError,
+ "This serializable does not support conversion to uint32_t");
+}
+
+
+// TZSerializableBinary
+TZSerializableBinary::TZSerializableBinary(uint32_t data_size)
+{
+ m_data.data = nullptr;
+ m_data.data_size = data_size;
+}
+
+TZSerializableBinary::TZSerializableBinary(const RawBuffer &data)
+{
+ m_data.data = data.empty() ? nullptr : const_cast<unsigned char *>(data.data());
+ m_data.data_size = data.size();
+}
+
+uint32_t TZSerializableBinary::GetSize() const
+{
+ return KM_SizeOfBinaryData(const_cast<KM_BinaryData*>(&m_data));
+}
+
+int TZSerializableBinary::Serialize(void **buffer, uint32_t *size_guard) const
+{
+ return KM_SerializeBinaryData(buffer, size_guard, const_cast<KM_BinaryData*>(&m_data));
+}
+
+int TZSerializableBinary::Deserialize(void **buffer, uint32_t *size_guard)
+{
+ return KM_DeserializeBinaryData(buffer, size_guard, &m_data);
+}
+
+void TZSerializableBinary::Pull(RawBuffer &buffer) const
+{
+ buffer.resize(m_data.data_size);
+ memcpy(buffer.data(), m_data.data, m_data.data_size);
+}
+
+
+// TZSerializablePwdData
+TZSerializablePwdData::TZSerializablePwdData(const RawBuffer &pwd,
+ const RawBuffer &iv,
+ uint32_t tagSizeBits,
+ const RawBuffer &tag)
+{
+ memset(&m_data, 0, sizeof(KM_PwdData));
+ m_data.pwd = pwd.empty() ? nullptr : const_cast<unsigned char *>(pwd.data());
+ m_data.pwd_size = pwd.size();
+ m_data.iv = iv.empty() ? nullptr : const_cast<unsigned char *>(iv.data());
+ m_data.iv_size = iv.size();
+ m_data.tag = tag.empty() ? nullptr : const_cast<unsigned char *>(tag.data());
+ m_data.tag_size = tag.size();
+ m_data.derive_len_bits = Params::DERIVED_KEY_LENGTH_BITS;
+ m_data.it_count = Params::DERIVED_KEY_ITERATIONS;
+ m_data.tag_len_bits = tagSizeBits;
+}
+
+uint32_t TZSerializablePwdData::GetSize() const
+{
+ return KM_SizeOfPwdData(const_cast<KM_PwdData*>(&m_data));
+}
+
+int TZSerializablePwdData::Serialize(void **buffer, uint32_t *size_guard) const
+{
+ return KM_SerializePwdData(buffer, size_guard, const_cast<KM_PwdData*>(&m_data));
+}
+
+int TZSerializablePwdData::Deserialize(void **buffer, uint32_t *size_guard)
+{
+ return KM_DeserializePwdData(buffer, size_guard, &m_data);
+}
+
+// TZSerializableFlag
+uint32_t TZSerializableFlag::GetSize() const
+{
+ return KM_SizeOfFlag();
+}
+
+int TZSerializableFlag::Serialize(void **buffer, uint32_t *size_guard) const
+{
+ return KM_SerializeFlag(buffer, size_guard, m_flag);
+}
+
+int TZSerializableFlag::Deserialize(void **buffer, uint32_t *size_guard)
+{
+ return KM_DeserializeFlag(buffer, size_guard, &m_flag);
+}
+
+void TZSerializableFlag::Pull(uint32_t &flag) const
+{
+ flag = m_flag;
+}
+
+
+// TZSerializer
+void TZSerializer::Push(TZSerializable *serializable)
+{
+ m_serializables.emplace_back(serializable);
+ m_memorySize += serializable->GetSize();
+}
+
+void TZSerializer::Serialize(TrustZoneMemory &memory) const
+{
+ void *inBuffer = memory.Get()->buffer;
+ uint32_t inBufferGuard = m_memorySize;
+
+ for (const auto& s : m_serializables) {
+ int ret = s->Serialize(&inBuffer, &inBufferGuard);
+ if (ret) {
+ ThrowErr(Exc::Crypto::InternalError, "Failed to serialize data, ret: ", ret);
+ }
+ }
+}
+
+void TZSerializer::Deserialize(const TrustZoneMemory &memory)
+{
+ void *outBuffer = memory.Get()->buffer;
+ uint32_t outBufferGuard = m_memorySize;
+
+ for (const auto& s : m_serializables) {
+ int ret = s->Deserialize(&outBuffer, &outBufferGuard);
+ if (ret) {
+ ThrowErr(Exc::Crypto::InternalError, "Failed to deserialize data, ret: ", ret);
+ }
+ }
+}
+
+} // namespace Internals
+} // namespace TZ
+} // namespace Crypto
+} // namespace CKM
--- /dev/null
+/*
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+/*
+ * @file tz-serializer.h
+ * @author Krzysztof Jackiewicz (k.jackiewicz@samsung.com)
+ * @version 1.0
+ * @brief
+ */
+
+#pragma once
+
+#include <cstdint>
+#include <list>
+#include <memory>
+
+#include <tee_client_api.h>
+#include <km_serialization.h>
+
+#include <tz-backend/tz-memory.h>
+#include <generic-backend/exception.h>
+#include <dpl/raw-buffer.h>
+
+namespace CKM {
+namespace Crypto {
+namespace TZ {
+namespace Internals {
+
+class TZSerializable {
+public:
+ TZSerializable() {}
+ virtual ~TZSerializable() {}
+ TZSerializable(const TZSerializable&) = delete;
+ TZSerializable& operator=(const TZSerializable&) = delete;
+
+ virtual uint32_t GetSize() const = 0;
+ virtual int Serialize(void **buffer, uint32_t *size_guard) const = 0;
+ virtual int Deserialize(void **buffer, uint32_t *size_guard) = 0;
+ virtual void Pull(RawBuffer &buffer) const;
+ virtual void Pull(uint32_t &flag) const;
+};
+
+
+class TZSerializableBinary : public TZSerializable {
+public:
+ explicit TZSerializableBinary(uint32_t data_size);
+ explicit TZSerializableBinary(const RawBuffer &data);
+ uint32_t GetSize() const override;
+ int Serialize(void **buffer, uint32_t *size_guard) const override;
+ int Deserialize(void **buffer, uint32_t *size_guard) override;
+ void Pull(RawBuffer &buffer) const override;
+private:
+ KM_BinaryData m_data;
+};
+
+
+class TZSerializablePwdData : public TZSerializable {
+public:
+ TZSerializablePwdData(const RawBuffer &pwd,
+ const RawBuffer &iv,
+ uint32_t tagSizeBits,
+ const RawBuffer &tag = RawBuffer());
+ uint32_t GetSize() const override;
+ int Serialize(void **buffer, uint32_t *size_guard) const override;
+ int Deserialize(void **buffer, uint32_t *size_guard) override;
+private:
+ KM_PwdData m_data;
+};
+
+
+class TZSerializableFlag : public TZSerializable {
+public:
+ TZSerializableFlag() : m_flag(0) {}
+ explicit TZSerializableFlag(uint32_t flag) : m_flag(flag) {}
+ uint32_t GetSize() const override;
+ int Serialize(void **buffer, uint32_t *size_guard) const override;
+ int Deserialize(void **buffer, uint32_t *size_guard) override;
+ void Pull(uint32_t &flag) const override;
+private:
+ uint32_t m_flag;
+};
+
+
+class TZSerializer {
+public:
+ TZSerializer() : m_memorySize(0) {}
+ ~TZSerializer() {}
+ TZSerializer(const TZSerializer&) = delete;
+ TZSerializer& operator=(const TZSerializer&) = delete;
+
+ void Push(TZSerializable *serializable);
+
+ template <typename T>
+ void Pull(T &buffer);
+ uint32_t GetSize() const { return m_memorySize; }
+ void Serialize(TrustZoneMemory &memory) const;
+ void Deserialize(const TrustZoneMemory &memory);
+
+private:
+ std::list<std::unique_ptr<TZSerializable>> m_serializables;
+ uint32_t m_memorySize;
+};
+
+template <typename T>
+void TZSerializer::Pull(T &data)
+{
+ if (m_serializables.empty()) {
+ ThrowErr(Exc::Crypto::InternalError, "No more serializables to extract");
+ }
+
+ m_serializables.front()->Pull(data);
+ m_serializables.pop_front();
+}
+
+} // namespace Internals
+} // namespace TZ
+} // namespace Crypto
+} // namespace CKM