1 /*############################################################################
2 # Copyright 2016-2017 Intel Corporation
3 #
4 # Licensed under the Apache License, Version 2.0 (the "License");
5 # you may not use this file except in compliance with the License.
6 # You may obtain a copy of the License at
7 #
8 # http://www.apache.org/licenses/LICENSE-2.0
9 #
10 # Unless required by applicable law or agreed to in writing, software
11 # distributed under the License is distributed on an "AS IS" BASIS,
12 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 # See the License for the specific language governing permissions and
14 # limitations under the License.
15 ############################################################################*/
16
17 /*!
18 * \file
19 * \brief Join Request related unit tests.
20 */
21
22 #include <cstring>
23 #include <memory>
24 #include "epid/common-testhelper/epid_gtest-testhelper.h"
25 #include "gtest/gtest.h"
26
27 extern "C" {
28 #include "epid/common/math/ecgroup.h"
29 #include "epid/common/math/finitefield.h"
30 #include "epid/common/src/epid2params.h"
31 #include "epid/member/api.h"
32 }
33
34 #include "epid/common-testhelper/ecgroup_wrapper-testhelper.h"
35 #include "epid/common-testhelper/ecpoint_wrapper-testhelper.h"
36 #include "epid/common-testhelper/epid_params-testhelper.h"
37 #include "epid/common-testhelper/errors-testhelper.h"
38 #include "epid/common-testhelper/ffelement_wrapper-testhelper.h"
39 #include "epid/common-testhelper/finite_field_wrapper-testhelper.h"
40 #include "epid/common-testhelper/mem_params-testhelper.h"
41 #include "epid/common-testhelper/prng-testhelper.h"
42 #include "epid/member/tiny/unittests/member-testhelper.h"
43
44 /// compares FpElemStr values
operator ==(FpElemStr const & lhs,FpElemStr const & rhs)45 bool operator==(FpElemStr const& lhs, FpElemStr const& rhs) {
46 return 0 == std::memcmp(&lhs, &rhs, sizeof(lhs));
47 }
48
49 /// compares JoinRequest values
operator ==(JoinRequest const & lhs,JoinRequest const & rhs)50 bool operator==(JoinRequest const& lhs, JoinRequest const& rhs) {
51 return 0 == std::memcmp(&lhs, &rhs, sizeof(lhs));
52 }
53
54 /// compares JoinRequest values for inequality
operator !=(JoinRequest const & lhs,JoinRequest const & rhs)55 bool operator!=(JoinRequest const& lhs, JoinRequest const& rhs) {
56 return 0 != std::memcmp(&lhs, &rhs, sizeof(lhs));
57 }
58
59 namespace {
60
61 // local constant for Join Request tests. This can be hoisted later if needed
62 // avoids cpplint warning about multiple includes.
63 const GroupPubKey kPubKey = {
64 #include "epid/common-testhelper/testdata/grp01/gpubkey.inc"
65 };
66
67 const FpElemStr kFEps1 = {0x56, 0x57, 0xda, 0x39, 0x9f, 0x69, 0x17, 0x84,
68 0xac, 0xf9, 0xf6, 0xdf, 0xfe, 0xd2, 0x41, 0xe8,
69 0x02, 0x30, 0xf8, 0xd8, 0x72, 0x35, 0xd3, 0x0e,
70 0x76, 0x2e, 0xda, 0x4b, 0xf4, 0xc5, 0x31, 0x0f};
71 /// Validates join request.
ValidateJoinRequest(JoinRequest const & request,HashAlg hash_alg,GroupPubKey const & grp_public_key,FpElemStr const & f,IssuerNonce const & ni)72 void ValidateJoinRequest(JoinRequest const& request, HashAlg hash_alg,
73 GroupPubKey const& grp_public_key, FpElemStr const& f,
74 IssuerNonce const& ni) {
75 Epid2Params params_values = {
76 #include "epid/common/src/epid2params_ate.inc"
77 };
78
79 Epid20Params params;
80
81 // h1^f ?= F
82 EcPointObj F_expected(¶ms.G1, grp_public_key.h1);
83 THROW_ON_EPIDERR(EcExp(params.G1, F_expected, (BigNumStr*)&f, F_expected));
84 ASSERT_EQ(*(G1ElemStr*)(F_expected.data().data()), request.F);
85
86 // H(p|g1|g2|h1|h2|w|F|R|ni) ?= c, where R = h1^s * F^(-c)
87 FfElementObj nc(¶ms.fp, request.c);
88 THROW_ON_EPIDERR(FfNeg(params.fp, nc, nc));
89 EcPointObj a(¶ms.G1, grp_public_key.h1);
90 EcPointObj b(¶ms.G1, request.F);
91 THROW_ON_EPIDERR(EcExp(params.G1, a, (BigNumStr*)&request.s, a));
92 THROW_ON_EPIDERR(EcExp(params.G1, b, (BigNumStr*)nc.data().data(), b));
93 THROW_ON_EPIDERR(EcMul(params.G1, a, b, a));
94
95 #pragma pack(1)
96 struct {
97 BigNumStr p; // Intel(R) EPID 2.0 parameter p
98 G1ElemStr g1; // Intel(R) EPID 2.0 parameter g1
99 G2ElemStr g2; // Intel(R) EPID 2.0 parameter g2
100 G1ElemStr h1; // Group public key value h1
101 G1ElemStr h2; // Group public key value h2
102 G2ElemStr w; // Group public key value w
103 G1ElemStr F; // Variable F computed in algorithm
104 G1ElemStr R; // Variable R computed in algorithm
105 IssuerNonce NI; // Issuer Nonce
106 } commitment_values = {params_values.p,
107 params_values.g1,
108 params_values.g2,
109 grp_public_key.h1,
110 grp_public_key.h2,
111 grp_public_key.w,
112 request.F,
113 *(G1ElemStr*)(a.data().data()),
114 ni};
115 #pragma pack()
116
117 FfElementObj commitment(¶ms.fp);
118 THROW_ON_EPIDERR(FfHash(params.fp, &commitment_values,
119 sizeof commitment_values, hash_alg, commitment));
120 ASSERT_EQ(*(FpElemStr*)(commitment.data().data()), request.c);
121 }
122
TEST_F(EpidMemberTest,CreateJoinRequestFailsGivenNullParameters)123 TEST_F(EpidMemberTest, CreateJoinRequestFailsGivenNullParameters) {
124 GroupPubKey pub_key = kPubKey;
125 IssuerNonce ni;
126 MemberParams params;
127 Prng prng;
128 JoinRequest join_request;
129 SetMemberParams(Prng::Generate, &prng, nullptr, ¶ms);
130 MemberCtxObj ctx(¶ms);
131 THROW_ON_EPIDERR(EpidMemberSetHashAlg(ctx, kSha512));
132 EXPECT_EQ(kEpidBadArgErr,
133 EpidCreateJoinRequest(nullptr, &pub_key, &ni, &join_request));
134 EXPECT_EQ(kEpidBadArgErr,
135 EpidCreateJoinRequest(ctx, nullptr, &ni, &join_request));
136 EXPECT_EQ(kEpidBadArgErr,
137 EpidCreateJoinRequest(ctx, &pub_key, nullptr, &join_request));
138 EXPECT_EQ(kEpidBadArgErr, EpidCreateJoinRequest(ctx, &pub_key, &ni, nullptr));
139 }
140
TEST_F(EpidMemberTest,CreateJoinRequestFailsGivenNoF)141 TEST_F(EpidMemberTest, CreateJoinRequestFailsGivenNoF) {
142 GroupPubKey pub_key = kPubKey;
143 IssuerNonce ni;
144 MemberParams params;
145 Prng prng;
146 JoinRequest join_request;
147 SetMemberParams(Prng::Generate, &prng, nullptr, ¶ms);
148 MemberCtxObj ctx(¶ms);
149 THROW_ON_EPIDERR(EpidMemberSetHashAlg(ctx, kSha512));
150 EXPECT_EQ(kEpidBadArgErr,
151 EpidCreateJoinRequest(ctx, &pub_key, &ni, &join_request));
152 }
153
TEST_F(EpidMemberTest,CreateJoinRequestFailsGivenInvalidGroupKey)154 TEST_F(EpidMemberTest, CreateJoinRequestFailsGivenInvalidGroupKey) {
155 Prng prng;
156 MemberParams params = {0};
157 GroupPubKey pub_key = kPubKey;
158 FpElemStr f = {
159 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
160 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
161 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff,
162 };
163 IssuerNonce ni = {
164 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03,
165 0x04, 0x05, 0x06, 0x07, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
166 0x00, 0x00, 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01,
167 };
168 pub_key.h1.x.data.data[15] = 0xff;
169 Epid20Params epid_params;
170 EcPointObj pt(&epid_params.G1);
171 JoinRequest join_request;
172 SetMemberParams(Prng::Generate, &prng, &f, ¶ms);
173 MemberCtxObj member(¶ms);
174 THROW_ON_EPIDERR(EpidMemberSetHashAlg(member, kSha512));
175 ASSERT_NE(kEpidNoErr, ReadEcPoint(epid_params.G1, (uint8_t*)&pub_key.h1,
176 sizeof(pub_key.h1), pt));
177 EXPECT_EQ(kEpidBadArgErr,
178 EpidCreateJoinRequest(member, &pub_key, &ni, &join_request));
179 }
180
TEST_F(EpidMemberTest,CreateJoinRequestFailsGivenInvalidFValue)181 TEST_F(EpidMemberTest, CreateJoinRequestFailsGivenInvalidFValue) {
182 Prng prng;
183 MemberParams params = {0};
184 GroupPubKey pub_key = kPubKey;
185 FpElemStr f = {
186 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
187 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
188 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00,
189 };
190 IssuerNonce ni = {
191 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03,
192 0x04, 0x05, 0x06, 0x07, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
193 0x00, 0x00, 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01,
194 };
195 JoinRequest join_request;
196 EpidStatus sts;
197 SetMemberParams(Prng::Generate, &prng, &f, ¶ms);
198
199 std::unique_ptr<uint8_t[]> member;
200 size_t context_size = 0;
201 sts = EpidMemberGetSize(¶ms, &context_size);
202 EXPECT_TRUE(kEpidNoErr == sts || kEpidBadArgErr == sts)
203 << "Actual value " << sts;
204
205 if (kEpidNoErr == sts) {
206 member.reset(new uint8_t[context_size]());
207 sts = EpidMemberInit(¶ms, (MemberCtx*)member.get());
208 EXPECT_TRUE(kEpidNoErr == sts || kEpidBadArgErr == sts)
209 << "Actual value " << sts;
210 }
211
212 if (kEpidNoErr == sts) {
213 sts = EpidCreateJoinRequest((MemberCtx*)member.get(), &pub_key, &ni,
214 &join_request);
215 EXPECT_EQ(kEpidBadArgErr, sts);
216 }
217
218 EpidMemberDeinit((MemberCtx*)member.get());
219 }
220
TEST_F(EpidMemberTest,CreateJoinRequestWorksUsingSha512)221 TEST_F(EpidMemberTest, CreateJoinRequestWorksUsingSha512) {
222 Prng prng;
223 MemberParams params = {0};
224 GroupPubKey pub_key = kPubKey;
225 FpElemStr f = {
226 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
227 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
228 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff,
229 };
230 IssuerNonce ni = {
231 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03,
232 0x04, 0x05, 0x06, 0x07, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
233 0x00, 0x00, 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01,
234 };
235 JoinRequest join_request;
236 SetMemberParams(Prng::Generate, &prng, &f, ¶ms);
237 MemberCtxObj member(¶ms);
238 THROW_ON_EPIDERR(EpidMemberSetHashAlg(member, kSha512));
239 EXPECT_EQ(kEpidNoErr,
240 EpidCreateJoinRequest(member, &pub_key, &ni, &join_request));
241 EXPECT_NO_FATAL_FAILURE(
242 ValidateJoinRequest(join_request, kSha512, pub_key, f, ni));
243 }
244
TEST_F(EpidMemberTest,CreateJoinRequestWorksUsingSha256)245 TEST_F(EpidMemberTest, CreateJoinRequestWorksUsingSha256) {
246 Prng prng;
247 MemberParams params = {0};
248 GroupPubKey pub_key = kPubKey;
249 FpElemStr f = {
250 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
251 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
252 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff,
253 };
254 IssuerNonce ni = {
255 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03,
256 0x04, 0x05, 0x06, 0x07, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
257 0x00, 0x00, 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01,
258 };
259 JoinRequest join_request;
260 SetMemberParams(Prng::Generate, &prng, &f, ¶ms);
261 MemberCtxObj member(¶ms);
262 THROW_ON_EPIDERR(EpidMemberSetHashAlg(member, kSha256));
263 EXPECT_EQ(kEpidNoErr,
264 EpidCreateJoinRequest(member, &pub_key, &ni, &join_request));
265 EXPECT_NO_FATAL_FAILURE(
266 ValidateJoinRequest(join_request, kSha256, pub_key, f, ni));
267 }
268
TEST_F(EpidMemberTest,CreateJoinRequestGeneratesDiffJoinRequestsOnMultipleCalls)269 TEST_F(EpidMemberTest,
270 CreateJoinRequestGeneratesDiffJoinRequestsOnMultipleCalls) {
271 Prng prng;
272 MemberParams params = {0};
273 GroupPubKey pub_key = kPubKey;
274 FpElemStr f = {
275 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
276 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
277 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff,
278 };
279 IssuerNonce ni = {
280 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03,
281 0x04, 0x05, 0x06, 0x07, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
282 0x00, 0x00, 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01,
283 };
284 JoinRequest join_request1;
285 JoinRequest join_request2;
286 SetMemberParams(Prng::Generate, &prng, &f, ¶ms);
287 MemberCtxObj member(¶ms);
288 THROW_ON_EPIDERR(EpidMemberSetHashAlg(member, kSha512));
289 EXPECT_EQ(kEpidNoErr,
290 EpidCreateJoinRequest(member, &pub_key, &ni, &join_request1));
291 EXPECT_NO_FATAL_FAILURE(
292 ValidateJoinRequest(join_request1, kSha512, pub_key, f, ni));
293 EXPECT_EQ(kEpidNoErr,
294 EpidCreateJoinRequest(member, &pub_key, &ni, &join_request2));
295 EXPECT_NO_FATAL_FAILURE(
296 ValidateJoinRequest(join_request2, kSha512, pub_key, f, ni));
297 EXPECT_NE(join_request1, join_request2);
298 }
299
TEST_F(EpidMemberTest,CreateJoinRequestGeneratesDiffJoinRequestsGivenDiffHashAlgs)300 TEST_F(EpidMemberTest,
301 CreateJoinRequestGeneratesDiffJoinRequestsGivenDiffHashAlgs) {
302 MemberParams params = {0};
303 GroupPubKey pub_key = kPubKey;
304 FpElemStr f = {
305 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
306 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
307 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff,
308 };
309 IssuerNonce ni = {
310 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03,
311 0x04, 0x05, 0x06, 0x07, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
312 0x00, 0x00, 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01,
313 };
314 JoinRequest join_request1;
315 JoinRequest join_request2;
316 // Ensure that two members created with equal seed and do not
317 // interfere each other. Member1 is deleted by the time member2
318 // is created.
319 {
320 Prng prng;
321 SetMemberParams(Prng::Generate, &prng, &f, ¶ms);
322 MemberCtxObj member1(¶ms);
323 THROW_ON_EPIDERR(EpidMemberSetHashAlg(member1, kSha256));
324 prng.set_seed(0x1234);
325 EXPECT_EQ(kEpidNoErr,
326 EpidCreateJoinRequest(member1, &pub_key, &ni, &join_request1));
327 EXPECT_NO_FATAL_FAILURE(
328 ValidateJoinRequest(join_request1, kSha256, pub_key, f, ni));
329 }
330 {
331 Prng prng;
332 SetMemberParams(Prng::Generate, &prng, &f, ¶ms);
333 MemberCtxObj member2(¶ms);
334 THROW_ON_EPIDERR(EpidMemberSetHashAlg(member2, kSha512));
335 prng.set_seed(0x1234);
336 EXPECT_EQ(kEpidNoErr,
337 EpidCreateJoinRequest(member2, &pub_key, &ni, &join_request2));
338 EXPECT_NO_FATAL_FAILURE(
339 ValidateJoinRequest(join_request2, kSha512, pub_key, f, ni));
340 }
341 EXPECT_NE(join_request1, join_request2);
342 }
343
TEST_F(EpidMemberTest,CreateJoinRequestWorksGivenValidParametersUsingIKGFData)344 TEST_F(EpidMemberTest,
345 CreateJoinRequestWorksGivenValidParametersUsingIKGFData) {
346 Prng prng;
347 MemberParams params = {0};
348 const GroupPubKey* pub_key = reinterpret_cast<const GroupPubKey*>(
349 this->kGroupPublicKeyDataIkgf.data());
350 FpElemStr f = {
351 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
352 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
353 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff,
354 };
355 IssuerNonce ni = {
356 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03,
357 0x04, 0x05, 0x06, 0x07, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
358 0x00, 0x00, 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01,
359 };
360 JoinRequest join_request;
361 SetMemberParams(Prng::Generate, &prng, &f, ¶ms);
362 MemberCtxObj member(¶ms);
363 THROW_ON_EPIDERR(EpidMemberSetHashAlg(member, kSha512));
364 EXPECT_EQ(kEpidNoErr,
365 EpidCreateJoinRequest(member, pub_key, &ni, &join_request));
366 EXPECT_NO_FATAL_FAILURE(
367 ValidateJoinRequest(join_request, kSha512, *pub_key, f, ni));
368 }
369 } // namespace
370