#include <string>
+#include <openssl/rand.h>
+#include <openssl/evp.h>
+
#include <boost_macros_wrapper.h>
#include <test_common.h>
#include <protocols.h>
#include <message-buffer.h>
#include <sw-backend/store.h>
+#include <sw-backend/internals.h>
+#ifdef TZ_BACKEND_ENABLED
+#include <tz-backend/store.h>
+#include <tz-backend/internals.h>
+#endif
+
+#include <generic-backend/crypto-params.h>
+#include <crypto-logic.h>
+
+#include <dpl/log/log.h>
using namespace CKM;
" should " << (success ? "succeed" : "fail"));
}
-// This function mimics the serialization on a 64-bit system prior to the fix
-RawBuffer pack64(const RawBuffer& data)
-{
- struct Writer64 : public IStream {
- explicit Writer64(uint64_t size) {
- m_buffer.reserve(sizeof(size) + size);
- Serialization::Serialize(*this, size);
+// This class is used to mimic the serialization on a 64-bit system prior to the fix
+class MessageSerializer64 {
+ struct Sizer64 : IStream {
+ void Read(size_t, void*)
+ {
+ ThrowErr(Exc::InternalError, "unexpected IStream::Read call in SerializeMessage64");
+ }
+ void Write(size_t num, const void*)
+ {
+ m_bytes += num;
}
- void Read(size_t, void*) override {
- BOOST_FAIL("Unexpected Read call in Writer.");
+ size_t m_bytes = 0;
+ };
+
+ struct Writer64 : IStream {
+ Writer64(size_t size)
+ {
+ if (size > std::numeric_limits<uint64_t>::max())
+ ThrowErr(Exc::InternalError, "Message too large for serialization");
+
+ uint64_t size64 = size;
+ m_buffer.reserve(sizeof(size64) + size64);
+ Serialization::Serialize(*this, size64);
}
- void Write(size_t num, const void* bytes) override {
- BOOST_REQUIRE(m_buffer.size() + num <= m_buffer.capacity());
+ void Read(size_t, void*)
+ {
+ ThrowErr(Exc::InternalError, "unexpected IStream::Read call in SerializeMessage64");
+ }
+ void Write(size_t num, const void* bytes)
+ {
+ assert(m_buffer.size() + num <= m_buffer.capacity());
m_buffer.resize(m_buffer.size() + num);
memcpy(&m_buffer[m_buffer.size() - num], bytes, num);
}
RawBuffer m_buffer;
};
+ MessageSerializer64() = delete;
+
+public:
+ template <typename... T>
+ static RawBuffer Run64(const T&... args)
+ {
+ Sizer64 sizer;
+ Serializer<T...>::Serialize(sizer, args...);
+ Writer64 writer(sizer.m_bytes);
+ Serializer<T...>::Serialize(writer, args...);
+ return std::move(writer.m_buffer);
+ }
+};
+
+template <typename... T>
+RawBuffer SerializeMessage64(const T&... args)
+{
+ return MessageSerializer64::Run64(args...);
+}
+
+RawBuffer pack64SW(const RawBuffer& data, const Password &pass)
+{
int scheme = 0;
- int dataSize = data.size();
- uint64_t size64 = sizeof(scheme) + sizeof(dataSize) + data.size();
- Writer64 writer(sizeof(size64) + size64);
- Serialization::Serialize(writer, scheme);
- Serialization::Serialize(writer, data);
- BOOST_REQUIRE(writer.m_buffer.size() == sizeof(size64) + size64);
-
- return writer.m_buffer;
+ RawBuffer packed = data;
+ if (!pass.empty()) {
+ RawBuffer iv;
+ std::pair<RawBuffer, RawBuffer> ret = Crypto::SW::Store::packPassword(scheme, packed, pass, iv);
+ // serialization exceptions will be catched as CKM::Exception and will cause
+ // CKM_API_ERROR_SERVER_ERROR
+ packed = SerializeMessage64(ret.first, iv, ret.second);
+ }
+ return SerializeMessage64(scheme, packed);
+}
+
+#ifdef TZ_BACKEND_ENABLED
+RawBuffer pack64TZ(const RawBuffer &keyId,
+ const Password &pwd,
+ const RawBuffer &iv,
+ const RawBuffer &tag)
+{
+ // determine whether the key is password protected and store schema info
+ // we don't need to additionally encrypt key ID
+ int scheme = pwd.empty() ? 0 : 1;
+ if (scheme) {
+ return SerializeMessage64(scheme, keyId, iv, tag);
+ } else {
+ return SerializeMessage64(scheme, keyId);
+ }
}
+#endif
} // namespace anonymous
BOOST_REQUIRE(o[1].backend == v[1].backend);
}
-POSITIVE_TEST_CASE(Serialization_32_vs_64_bit)
+POSITIVE_TEST_CASE(Serialization_32_vs_64_bit_SW)
{
using Crypto::SW::Store;
// pack 32 -> unpack
- auto packed = Store::pack(DATA, PASSWORD);
- auto unpacked = Store::unpack(packed, PASSWORD);
+ auto packed = Store::pack(DATA, "");
+ auto unpacked = Store::unpack(packed, "");
BOOST_REQUIRE(DATA == unpacked);
- packed = Store::pack(DATA, "");
- unpacked = Store::unpack(packed, "");
+ packed = Store::pack(DATA, PASSWORD);
+ unpacked = Store::unpack(packed, PASSWORD);
BOOST_REQUIRE(DATA == unpacked);
// pack 64 -> unpack
- packed = pack64(DATA);
+ packed = pack64SW(DATA, "");
unpacked = Store::unpack(packed, "");
BOOST_REQUIRE(DATA == unpacked);
+
+ packed = pack64SW(DATA, PASSWORD);
+ unpacked = Store::unpack(packed, PASSWORD);
+ BOOST_REQUIRE(DATA == unpacked);
}
-NEGATIVE_TEST_CASE(Serialization_32_vs_64_bit)
+NEGATIVE_TEST_CASE(Serialization_32_vs_64_bit_SW)
{
using Crypto::SW::Store;
// pack 32 -> unpack
- auto packed = Store::pack(DATA, PASSWORD);
+ auto packed = Store::pack(DATA, "");
+
+ BOOST_REQUIRE_THROW(Store::unpack(packed, PASSWORD), Exc::AuthenticationFailed);
+
+ packed = Store::pack(DATA, PASSWORD);
BOOST_REQUIRE_THROW(Store::unpack(packed, "wrong-password"), Exc::AuthenticationFailed);
BOOST_REQUIRE_THROW(Store::unpack(packed, ""), Exc::AuthenticationFailed);
- packed = Store::pack(DATA, "");
-
+ // pack 64 -> unpack
+ packed = pack64SW(DATA, "");
BOOST_REQUIRE_THROW(Store::unpack(packed, PASSWORD), Exc::AuthenticationFailed);
+ packed = pack64SW(DATA, PASSWORD);
+ BOOST_REQUIRE_THROW(Store::unpack(packed, "wrong-password"), Exc::AuthenticationFailed);
+ BOOST_REQUIRE_THROW(Store::unpack(packed, ""), Exc::AuthenticationFailed);
+}
+
+#ifdef TZ_BACKEND_ENABLED
+POSITIVE_TEST_CASE(Serialization_32_vs_64_bit_TZ)
+{
+ using Crypto::TZ::Store;
+
+ // pack 32 -> unpack
+ RawBuffer keyId(64, 0);
+ RawBuffer tag;
+ Password pass = "test-password";
+ RawBuffer ivNoPass;
+ RawBuffer ivPass = Crypto::TZ::Internals::generateIV();
+ RawBuffer keyIdRet, ivRet, tagRet;
+ int noPassScheme = 0;
+ int passScheme = 1;
+
+ auto packed = Store::pack(keyId, "", ivNoPass, tag);
+ Store::unpack(packed, "", noPassScheme, keyIdRet, ivRet, tagRet);
+ BOOST_REQUIRE(keyId == keyIdRet);
+ BOOST_REQUIRE(ivNoPass == ivRet);
+ BOOST_REQUIRE(tag == tagRet);
+
+ packed = Store::pack(keyId, pass, ivPass, tag);
+ Store::unpack(packed, pass, passScheme, keyIdRet, ivRet, tagRet);
+ BOOST_REQUIRE(keyId == keyIdRet);
+ BOOST_REQUIRE(ivPass == ivRet);
+ BOOST_REQUIRE(tag == tagRet);
+
// pack 64 -> unpack
- packed = pack64(DATA);
- BOOST_REQUIRE_THROW(Store::unpack(packed, PASSWORD), Exc::AuthenticationFailed);
+ RawBuffer keyId64(64, 0);
+ ivRet.clear();
+
+ packed = pack64TZ(keyId64, "", ivNoPass, tag);
+ Store::unpack(packed, "", noPassScheme, keyIdRet, ivRet, tagRet);
+ BOOST_REQUIRE(keyId == keyIdRet);
+ BOOST_REQUIRE(ivNoPass == ivRet);
+ BOOST_REQUIRE(tag == tagRet);
+
+ packed = pack64TZ(keyId64, pass, ivPass, tag);
+ Store::unpack(packed, pass, passScheme, keyIdRet, ivRet, tagRet);
+ BOOST_REQUIRE(keyId == keyIdRet);
+ BOOST_REQUIRE(ivPass == ivRet);
+ BOOST_REQUIRE(tag == tagRet);
+}
+
+NEGATIVE_TEST_CASE(Serialization_32_vs_64_bit_TZ)
+{
+ using Crypto::TZ::Store;
+
+ // pack 32 -> unpack
+ RawBuffer keyId(64, 0);
+ RawBuffer tag;
+ Password pass = "test-password";
+ RawBuffer iv = Crypto::TZ::Internals::generateIV();
+ RawBuffer keyIdRet, ivRet, tagRet;
+ int scheme = 1;
+
+ auto packed = Store::pack(keyId, pass, iv, tag);
+ BOOST_REQUIRE_THROW(Store::unpack(packed, "", scheme, keyIdRet, ivRet, tagRet),
+ Exc::AuthenticationFailed);
+
+ packed = Store::pack(keyId, "", iv, tag);
+ BOOST_REQUIRE_THROW(Store::unpack(packed, "wrong-password", scheme, keyIdRet, ivRet, tagRet),
+ Exc::AuthenticationFailed);
+
+ // pack 64 -> unpack
+ packed = pack64TZ(keyId, pass, iv, tag);
+ BOOST_REQUIRE_THROW(Store::unpack(packed, "", scheme, keyIdRet, ivRet, tagRet),
+ Exc::AuthenticationFailed);
+
+ packed = pack64TZ(keyId, "", iv, tag);
+ BOOST_REQUIRE_THROW(Store::unpack(packed, "wrong-password", scheme, keyIdRet, ivRet, tagRet),
+ Exc::AuthenticationFailed);
}
+#endif
BOOST_AUTO_TEST_SUITE_END()