/*############################################################################ # Copyright 2016-2017 Intel Corporation # # 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 * \brief Join Request related unit tests. */ #include #include #include "epid/common-testhelper/epid_gtest-testhelper.h" #include "gtest/gtest.h" extern "C" { #include "epid/common/math/ecgroup.h" #include "epid/common/math/finitefield.h" #include "epid/common/src/epid2params.h" #include "epid/member/api.h" } #include "epid/common-testhelper/ecgroup_wrapper-testhelper.h" #include "epid/common-testhelper/ecpoint_wrapper-testhelper.h" #include "epid/common-testhelper/epid_params-testhelper.h" #include "epid/common-testhelper/errors-testhelper.h" #include "epid/common-testhelper/ffelement_wrapper-testhelper.h" #include "epid/common-testhelper/finite_field_wrapper-testhelper.h" #include "epid/common-testhelper/mem_params-testhelper.h" #include "epid/common-testhelper/prng-testhelper.h" #include "epid/member/src/context.h" #include "epid/member/unittests/member-testhelper.h" /// compares FpElemStr values bool operator==(FpElemStr const& lhs, FpElemStr const& rhs) { return 0 == std::memcmp(&lhs, &rhs, sizeof(lhs)); } /// compares JoinRequest values bool operator==(JoinRequest const& lhs, JoinRequest const& rhs) { return 0 == std::memcmp(&lhs, &rhs, sizeof(lhs)); } /// compares JoinRequest values for inequality bool operator!=(JoinRequest const& lhs, JoinRequest const& rhs) { return 0 != std::memcmp(&lhs, &rhs, sizeof(lhs)); } namespace { // local constant for Join Request tests. This can be hoisted later if needed // avoids cpplint warning about multiple includes. const GroupPubKey kPubKey = { #include "epid/common-testhelper/testdata/grp01/gpubkey.inc" }; const FpElemStr kFEps1 = {0x56, 0x57, 0xda, 0x39, 0x9f, 0x69, 0x17, 0x84, 0xac, 0xf9, 0xf6, 0xdf, 0xfe, 0xd2, 0x41, 0xe8, 0x02, 0x30, 0xf8, 0xd8, 0x72, 0x35, 0xd3, 0x0e, 0x76, 0x2e, 0xda, 0x4b, 0xf4, 0xc5, 0x31, 0x0f}; /// Validates join request. void ValidateJoinRequest(JoinRequest const& request, HashAlg hash_alg, GroupPubKey const& grp_public_key, FpElemStr const& f, IssuerNonce const& ni) { Epid2Params params_values = { #include "epid/common/src/epid2params_ate.inc" }; Epid20Params params; // h1^f ?= F EcPointObj F_expected(¶ms.G1, grp_public_key.h1); THROW_ON_EPIDERR(EcExp(params.G1, F_expected, (BigNumStr*)&f, F_expected)); ASSERT_EQ(*(G1ElemStr*)(F_expected.data().data()), request.F); // H(p|g1|g2|h1|h2|w|F|R|ni) ?= c, where R = h1^s * F^(-c) FfElementObj nc(¶ms.fp, request.c); THROW_ON_EPIDERR(FfNeg(params.fp, nc, nc)); EcPointObj a(¶ms.G1, grp_public_key.h1); EcPointObj b(¶ms.G1, request.F); THROW_ON_EPIDERR(EcExp(params.G1, a, (BigNumStr*)&request.s, a)); THROW_ON_EPIDERR(EcExp(params.G1, b, (BigNumStr*)nc.data().data(), b)); THROW_ON_EPIDERR(EcMul(params.G1, a, b, a)); #pragma pack(1) struct { BigNumStr p; // Intel(R) EPID 2.0 parameter p G1ElemStr g1; // Intel(R) EPID 2.0 parameter g1 G2ElemStr g2; // Intel(R) EPID 2.0 parameter g2 G1ElemStr h1; // Group public key value h1 G1ElemStr h2; // Group public key value h2 G2ElemStr w; // Group public key value w G1ElemStr F; // Variable F computed in algorithm G1ElemStr R; // Variable R computed in algorithm IssuerNonce NI; // Issuer Nonce } commitment_values = {params_values.p, params_values.g1, params_values.g2, grp_public_key.h1, grp_public_key.h2, grp_public_key.w, request.F, *(G1ElemStr*)(a.data().data()), ni}; #pragma pack() FfElementObj commitment(¶ms.fp); THROW_ON_EPIDERR(FfHash(params.fp, &commitment_values, sizeof commitment_values, hash_alg, commitment)); ASSERT_EQ(*(FpElemStr*)(commitment.data().data()), request.c); } TEST_F(EpidMemberTest, CreateJoinRequestFailsGivenNullParameters) { GroupPubKey pub_key = kPubKey; IssuerNonce ni; MemberParams params; Prng prng; JoinRequest join_request; SetMemberParams(Prng::Generate, &prng, nullptr, ¶ms); MemberCtxObj ctx(¶ms); THROW_ON_EPIDERR(EpidMemberSetHashAlg(ctx, kSha256)); EXPECT_EQ(kEpidBadArgErr, EpidCreateJoinRequest(nullptr, &pub_key, &ni, &join_request)); EXPECT_EQ(kEpidBadArgErr, EpidCreateJoinRequest(ctx, nullptr, &ni, &join_request)); EXPECT_EQ(kEpidBadArgErr, EpidCreateJoinRequest(ctx, &pub_key, nullptr, &join_request)); EXPECT_EQ(kEpidBadArgErr, EpidCreateJoinRequest(ctx, &pub_key, &ni, nullptr)); } TEST_F(EpidMemberTest, CreateJoinRequestFailsGivenInvalidGroupKey) { Prng prng; MemberParams params = {0}; GroupPubKey pub_key = kPubKey; FpElemStr f = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, }; IssuerNonce ni = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, }; pub_key.h1.x.data.data[15] = 0xff; Epid20Params epid_params; EcPointObj pt(&epid_params.G1); JoinRequest join_request; SetMemberParams(Prng::Generate, &prng, &f, ¶ms); MemberCtxObj member(¶ms); THROW_ON_EPIDERR(EpidMemberSetHashAlg(member, kSha256)); ASSERT_NE(kEpidNoErr, ReadEcPoint(epid_params.G1, (uint8_t*)&pub_key.h1, sizeof(pub_key.h1), pt)); EXPECT_EQ(kEpidBadArgErr, EpidCreateJoinRequest(member, &pub_key, &ni, &join_request)); } TEST_F(EpidMemberTest, CreateJoinRequestFailsGivenInvalidFValue) { Prng prng; MemberParams params = {0}; GroupPubKey pub_key = kPubKey; FpElemStr f = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, }; IssuerNonce ni = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, }; JoinRequest join_request; EpidStatus sts; SetMemberParams(Prng::Generate, &prng, &f, ¶ms); std::unique_ptr member; size_t context_size = 0; sts = EpidMemberGetSize(¶ms, &context_size); EXPECT_TRUE(kEpidNoErr == sts || kEpidBadArgErr == sts) << "Actual value " << sts; if (kEpidNoErr == sts) { member.reset(new uint8_t[context_size]()); sts = EpidMemberInit(¶ms, (MemberCtx*)member.get()); EXPECT_TRUE(kEpidNoErr == sts || kEpidBadArgErr == sts) << "Actual value " << sts; } if (kEpidNoErr == sts) { sts = EpidCreateJoinRequest((MemberCtx*)member.get(), &pub_key, &ni, &join_request); EXPECT_EQ(kEpidBadArgErr, sts); } EpidMemberDeinit((MemberCtx*)member.get()); } TEST_F(EpidMemberTest, CreateJoinRequestWorksGivenValidParameters) { Prng prng; MemberParams params = {0}; GroupPubKey pub_key = kPubKey; FpElemStr f = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, }; IssuerNonce ni = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, }; JoinRequest join_request; SetMemberParams(Prng::Generate, &prng, &f, ¶ms); MemberCtxObj member(¶ms); THROW_ON_EPIDERR(EpidMemberSetHashAlg(member, kSha256)); EXPECT_EQ(kEpidNoErr, EpidCreateJoinRequest(member, &pub_key, &ni, &join_request)); EXPECT_NO_FATAL_FAILURE( ValidateJoinRequest(join_request, kSha256, pub_key, f, ni)); } TEST_F(EpidMemberTest, PROTECTED_EPS1_CreateJoinRequestUsingWorksGivenValidParameters) { Prng prng; MemberParams params = {0}; GroupPubKey pub_key = kPubKey; IssuerNonce ni = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, }; JoinRequest join_request; SetMemberParams(Prng::Generate, &prng, nullptr, ¶ms); MemberCtxObj member(¶ms); THROW_ON_EPIDERR(EpidMemberSetHashAlg(member, kSha256)); EXPECT_EQ(kEpidNoErr, EpidCreateJoinRequest(member, &pub_key, &ni, &join_request)); EXPECT_NO_FATAL_FAILURE( ValidateJoinRequest(join_request, kSha256, pub_key, kFEps1, ni)); } TEST_F(EpidMemberTest, CreateJoinRequestGeneratesDiffJoinRequestsOnMultipleCalls) { Prng prng; MemberParams params = {0}; GroupPubKey pub_key = kPubKey; FpElemStr f = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, }; IssuerNonce ni = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, }; JoinRequest join_request1; JoinRequest join_request2; SetMemberParams(Prng::Generate, &prng, &f, ¶ms); MemberCtxObj member(¶ms); THROW_ON_EPIDERR(EpidMemberSetHashAlg(member, kSha256)); EXPECT_EQ(kEpidNoErr, EpidCreateJoinRequest(member, &pub_key, &ni, &join_request1)); EXPECT_NO_FATAL_FAILURE( ValidateJoinRequest(join_request1, kSha256, pub_key, f, ni)); EXPECT_EQ(kEpidNoErr, EpidCreateJoinRequest(member, &pub_key, &ni, &join_request2)); EXPECT_NO_FATAL_FAILURE( ValidateJoinRequest(join_request2, kSha256, pub_key, f, ni)); EXPECT_NE(join_request1, join_request2); } TEST_F( EpidMemberTest, PROTECTED_EPS1_CreateJoinRequestGeneratesDiffJoinRequestsOnMultipleCalls) { Prng prng; MemberParams params = {0}; GroupPubKey pub_key = kPubKey; IssuerNonce ni = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, }; JoinRequest join_request1; JoinRequest join_request2; SetMemberParams(Prng::Generate, &prng, nullptr, ¶ms); MemberCtxObj member(¶ms); THROW_ON_EPIDERR(EpidMemberSetHashAlg(member, kSha256)); EXPECT_EQ(kEpidNoErr, EpidCreateJoinRequest(member, &pub_key, &ni, &join_request1)); EXPECT_NO_FATAL_FAILURE( ValidateJoinRequest(join_request1, kSha256, pub_key, kFEps1, ni)); EXPECT_EQ(kEpidNoErr, EpidCreateJoinRequest(member, &pub_key, &ni, &join_request2)); EXPECT_NO_FATAL_FAILURE( ValidateJoinRequest(join_request2, kSha256, pub_key, kFEps1, ni)); EXPECT_NE(join_request1, join_request2); } TEST_F(EpidMemberTest, CreateJoinRequestGeneratesDiffJoinRequestsGivenDiffHashAlgs) { MemberParams params = {0}; GroupPubKey pub_key = kPubKey; FpElemStr f = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, }; IssuerNonce ni = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, }; JoinRequest join_request1; JoinRequest join_request2; // Ensure that two members created with equal seed and do not // interfere each other. Member1 is deleted by the time member2 // is created. { Prng prng; SetMemberParams(Prng::Generate, &prng, &f, ¶ms); MemberCtxObj member1(¶ms); THROW_ON_EPIDERR(EpidMemberSetHashAlg(member1, kSha256)); prng.set_seed(0x1234); EXPECT_EQ(kEpidNoErr, EpidCreateJoinRequest(member1, &pub_key, &ni, &join_request1)); EXPECT_NO_FATAL_FAILURE( ValidateJoinRequest(join_request1, kSha256, pub_key, f, ni)); } { Prng prng; SetMemberParams(Prng::Generate, &prng, &f, ¶ms); MemberCtxObj member2(¶ms); THROW_ON_EPIDERR(EpidMemberSetHashAlg(member2, kSha384)); prng.set_seed(0x1234); EXPECT_EQ(kEpidNoErr, EpidCreateJoinRequest(member2, &pub_key, &ni, &join_request2)); EXPECT_NO_FATAL_FAILURE( ValidateJoinRequest(join_request2, kSha384, pub_key, f, ni)); } EXPECT_NE(join_request1, join_request2); } TEST_F(EpidMemberTest, CreateJoinRequestWorksGivenValidParametersUsingIKGFData) { Prng prng; MemberParams params = {0}; const GroupPubKey* pub_key = reinterpret_cast( this->kGroupPublicKeyDataIkgf.data()); FpElemStr f = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, }; IssuerNonce ni = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, }; JoinRequest join_request; SetMemberParams(Prng::Generate, &prng, &f, ¶ms); MemberCtxObj member(¶ms); THROW_ON_EPIDERR(EpidMemberSetHashAlg(member, kSha256)); EXPECT_EQ(kEpidNoErr, EpidCreateJoinRequest(member, pub_key, &ni, &join_request)); EXPECT_NO_FATAL_FAILURE( ValidateJoinRequest(join_request, kSha256, *pub_key, f, ni)); } } // namespace