1 /*############################################################################
2 # Copyright 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 Provision credential unit tests.
20 */
21 #include <cstring>
22 #include <vector>
23
24 #include "gtest/gtest.h"
25
26 extern "C" {
27 #include "epid/member/api.h"
28 #include "epid/member/src/context.h"
29 #include "epid/member/src/storage.h"
30 }
31
32 #include "epid/common-testhelper/epid_gtest-testhelper.h"
33 #include "epid/common-testhelper/errors-testhelper.h"
34 #include "epid/common-testhelper/mem_params-testhelper.h"
35 #include "epid/common-testhelper/prng-testhelper.h"
36 #include "epid/member/unittests/member-testhelper.h"
37
38 namespace {
39
ProvisionCredentialAndStart(MemberCtx * ctx,GroupPubKey const * pub_key,MembershipCredential const * credential,MemberPrecomp const * precomp_str)40 EpidStatus ProvisionCredentialAndStart(MemberCtx* ctx,
41 GroupPubKey const* pub_key,
42 MembershipCredential const* credential,
43 MemberPrecomp const* precomp_str) {
44 EpidStatus sts;
45 sts = EpidProvisionCredential(ctx, pub_key, credential, precomp_str);
46 if (sts != kEpidNoErr) {
47 return sts;
48 }
49 sts = EpidMemberStartup(ctx);
50 return sts;
51 }
52
TEST_F(EpidMemberTest,ProvisionCredentialFailsGivenNullParameters)53 TEST_F(EpidMemberTest, ProvisionCredentialFailsGivenNullParameters) {
54 Prng prng;
55 GroupPubKey pub_key = this->kGrpXKey;
56 FpElemStr f = this->kGrpXMember9PrivKey.f;
57 MembershipCredential credential;
58 credential.A = this->kGrpXMember9PrivKey.A;
59 credential.gid = this->kGrpXMember9PrivKey.gid;
60 credential.x = this->kGrpXMember9PrivKey.x;
61 // Note: this MemberPrecomp is for the wrong group, however it should not
62 // be checked in Provision because doing so would negate the performance
63 // boost of using the precomp.
64 MemberPrecomp precomp = this->kMemberPrecomp;
65 MemberParams params = {0};
66 SetMemberParams(&Prng::Generate, &prng, &f, ¶ms);
67 MemberCtxObj member(¶ms);
68 EXPECT_EQ(kEpidBadArgErr,
69 EpidProvisionCredential(nullptr, &pub_key, &credential, &precomp));
70 EXPECT_EQ(kEpidBadArgErr,
71 EpidProvisionCredential(member, nullptr, &credential, &precomp));
72 EXPECT_EQ(kEpidBadArgErr,
73 EpidProvisionCredential(member, &pub_key, nullptr, &precomp));
74 EXPECT_EQ(kEpidBadArgErr,
75 EpidProvisionCredential(nullptr, &pub_key, &credential, nullptr));
76 EXPECT_EQ(kEpidBadArgErr,
77 EpidProvisionCredential(member, nullptr, &credential, nullptr));
78 EXPECT_EQ(kEpidBadArgErr,
79 EpidProvisionCredential(member, &pub_key, nullptr, nullptr));
80 }
81
TEST_F(EpidMemberTest,ProvisionCredentialRejectsInvalidCredential)82 TEST_F(EpidMemberTest, ProvisionCredentialRejectsInvalidCredential) {
83 Prng prng;
84 GroupPubKey pub_key = this->kGrpXKey;
85 FpElemStr f = this->kGrpXMember9PrivKey.f;
86 MembershipCredential credential;
87 MembershipCredential base_credential;
88 base_credential.A = this->kGrpXMember9PrivKey.A;
89 base_credential.gid = this->kGrpXMember9PrivKey.gid;
90 base_credential.x = this->kGrpXMember9PrivKey.x;
91 // Note: this MemberPrecomp is for the wrong group, however it should not
92 // be checked in Provision because doing so would negate the performance
93 // boost of using the precomp.
94 MemberPrecomp precomp = this->kMemberPrecomp;
95 MemberParams params = {0};
96 SetMemberParams(&Prng::Generate, &prng, &f, ¶ms);
97 MemberCtxObj member(¶ms);
98
99 credential = base_credential;
100 credential.A.x.data.data[0]++;
101 EXPECT_EQ(kEpidBadArgErr, ProvisionCredentialAndStart(member, &pub_key,
102 &credential, &precomp));
103 EXPECT_EQ(kEpidBadArgErr, ProvisionCredentialAndStart(member, &pub_key,
104 &credential, nullptr));
105
106 credential = base_credential;
107 credential.A.y.data.data[0]++;
108 EXPECT_EQ(kEpidBadArgErr, ProvisionCredentialAndStart(member, &pub_key,
109 &credential, &precomp));
110 EXPECT_EQ(kEpidBadArgErr, ProvisionCredentialAndStart(member, &pub_key,
111 &credential, nullptr));
112
113 credential = base_credential;
114 credential.x.data.data[0]++;
115 EXPECT_EQ(kEpidBadArgErr, ProvisionCredentialAndStart(member, &pub_key,
116 &credential, &precomp));
117 EXPECT_EQ(kEpidBadArgErr, ProvisionCredentialAndStart(member, &pub_key,
118 &credential, nullptr));
119 }
120
TEST_F(EpidMemberTest,ProvisionCredentialRejectsInvalidGroupKey)121 TEST_F(EpidMemberTest, ProvisionCredentialRejectsInvalidGroupKey) {
122 Prng prng;
123 GroupPubKey pub_key = this->kGrpXKey;
124 FpElemStr f = this->kGrpXMember9PrivKey.f;
125 MembershipCredential credential;
126 credential.A = this->kGrpXMember9PrivKey.A;
127 credential.gid = this->kGrpXMember9PrivKey.gid;
128 credential.x = this->kGrpXMember9PrivKey.x;
129 // Note: this MemberPrecomp is for the wrong group, however it should not
130 // be checked in Provision because doing so would negate the performance
131 // boost of using the precomp.
132 MemberPrecomp precomp = this->kMemberPrecomp;
133 MemberParams params = {0};
134 SetMemberParams(&Prng::Generate, &prng, &f, ¶ms);
135 MemberCtxObj member(¶ms);
136
137 pub_key = this->kGroupPublicKey;
138 pub_key.h1.x.data.data[0]++;
139 EXPECT_EQ(kEpidBadArgErr, ProvisionCredentialAndStart(member, &pub_key,
140 &credential, &precomp));
141 EXPECT_EQ(kEpidBadArgErr, ProvisionCredentialAndStart(member, &pub_key,
142 &credential, nullptr));
143
144 pub_key = this->kGroupPublicKey;
145 pub_key.h1.y.data.data[0]++;
146 EXPECT_EQ(kEpidBadArgErr, ProvisionCredentialAndStart(member, &pub_key,
147 &credential, &precomp));
148 EXPECT_EQ(kEpidBadArgErr, ProvisionCredentialAndStart(member, &pub_key,
149 &credential, nullptr));
150
151 pub_key = this->kGroupPublicKey;
152 pub_key.h2.x.data.data[0]++;
153 EXPECT_EQ(kEpidBadArgErr, ProvisionCredentialAndStart(member, &pub_key,
154 &credential, &precomp));
155 EXPECT_EQ(kEpidBadArgErr, ProvisionCredentialAndStart(member, &pub_key,
156 &credential, nullptr));
157
158 pub_key = this->kGroupPublicKey;
159 pub_key.h2.y.data.data[0]++;
160 EXPECT_EQ(kEpidBadArgErr, ProvisionCredentialAndStart(member, &pub_key,
161 &credential, &precomp));
162 EXPECT_EQ(kEpidBadArgErr, ProvisionCredentialAndStart(member, &pub_key,
163 &credential, nullptr));
164
165 pub_key = this->kGroupPublicKey;
166 pub_key.w.x[0].data.data[0]++;
167 EXPECT_EQ(kEpidBadArgErr, ProvisionCredentialAndStart(member, &pub_key,
168 &credential, &precomp));
169 EXPECT_EQ(kEpidBadArgErr, ProvisionCredentialAndStart(member, &pub_key,
170 &credential, nullptr));
171
172 pub_key = this->kGroupPublicKey;
173 pub_key.w.x[1].data.data[0]++;
174 EXPECT_EQ(kEpidBadArgErr, ProvisionCredentialAndStart(member, &pub_key,
175 &credential, &precomp));
176 EXPECT_EQ(kEpidBadArgErr, ProvisionCredentialAndStart(member, &pub_key,
177 &credential, nullptr));
178
179 pub_key = this->kGroupPublicKey;
180 pub_key.w.y[0].data.data[0]++;
181 EXPECT_EQ(kEpidBadArgErr, ProvisionCredentialAndStart(member, &pub_key,
182 &credential, &precomp));
183 EXPECT_EQ(kEpidBadArgErr, ProvisionCredentialAndStart(member, &pub_key,
184 &credential, nullptr));
185
186 pub_key = this->kGroupPublicKey;
187 pub_key.w.y[1].data.data[0]++;
188 EXPECT_EQ(kEpidBadArgErr, ProvisionCredentialAndStart(member, &pub_key,
189 &credential, &precomp));
190 EXPECT_EQ(kEpidBadArgErr, ProvisionCredentialAndStart(member, &pub_key,
191 &credential, nullptr));
192 }
193
TEST_F(EpidMemberTest,ProvisionCredentialRejectsCredentialNotInGroup)194 TEST_F(EpidMemberTest, ProvisionCredentialRejectsCredentialNotInGroup) {
195 Prng prng;
196 GroupPubKey pub_key = this->kGrpXKey;
197 FpElemStr f = this->kGrpXMember9PrivKey.f;
198 MembershipCredential credential;
199 MembershipCredential base_credential;
200 base_credential.A = this->kGrpXMember9PrivKey.A;
201 base_credential.gid = this->kGrpXMember9PrivKey.gid;
202 base_credential.x = this->kGrpXMember9PrivKey.x;
203 // Note: this MemberPrecomp is for the wrong group, however it should not
204 // be checked in Provision because doing so would negate the performance
205 // boost of using the precomp.
206 MemberPrecomp precomp = this->kMemberPrecomp;
207 MemberParams params = {0};
208 SetMemberParams(&Prng::Generate, &prng, &f, ¶ms);
209 MemberCtxObj member(¶ms);
210
211 credential = base_credential;
212 credential.gid.data[0] = ~credential.gid.data[0];
213 EXPECT_EQ(kEpidBadArgErr, ProvisionCredentialAndStart(member, &pub_key,
214 &credential, &precomp));
215 EXPECT_EQ(kEpidBadArgErr, ProvisionCredentialAndStart(member, &pub_key,
216 &credential, nullptr));
217 }
218
TEST_F(EpidMemberTest,CanProvisionUsingMembershipCredentialPrecomp)219 TEST_F(EpidMemberTest, CanProvisionUsingMembershipCredentialPrecomp) {
220 Prng prng;
221 GroupPubKey pub_key = this->kGrpXKey;
222 FpElemStr f = this->kGrpXMember9PrivKey.f;
223 MembershipCredential credential;
224 credential.A = this->kGrpXMember9PrivKey.A;
225 credential.gid = this->kGrpXMember9PrivKey.gid;
226 credential.x = this->kGrpXMember9PrivKey.x;
227 // Note: this MemberPrecomp is for the wrong group, however it should not
228 // be checked in Provision because doing so would negate the performance
229 // boost of using the precomp.
230 MemberPrecomp precomp = this->kMemberPrecomp;
231 MemberParams params = {0};
232 SetMemberParams(&Prng::Generate, &prng, &f, ¶ms);
233 MemberCtxObj member(¶ms);
234 EXPECT_EQ(kEpidNoErr, ProvisionCredentialAndStart(member, &pub_key,
235 &credential, &precomp));
236 }
237
TEST_F(EpidMemberTest,CanProvisionUsingMembershipCredentialNoPrecomp)238 TEST_F(EpidMemberTest, CanProvisionUsingMembershipCredentialNoPrecomp) {
239 Prng prng;
240 GroupPubKey pub_key = this->kGrpXKey;
241 FpElemStr f = this->kGrpXMember9PrivKey.f;
242 MembershipCredential credential;
243 credential.A = this->kGrpXMember9PrivKey.A;
244 credential.gid = this->kGrpXMember9PrivKey.gid;
245 credential.x = this->kGrpXMember9PrivKey.x;
246 MemberParams params = {0};
247 SetMemberParams(&Prng::Generate, &prng, &f, ¶ms);
248 MemberCtxObj member(¶ms);
249 EXPECT_EQ(kEpidNoErr, ProvisionCredentialAndStart(member, &pub_key,
250 &credential, nullptr));
251 }
252
253 // test that create succeeds with valid IKGF given parameters
TEST_F(EpidMemberTest,CanProvisionUsingIKGFMembershipCredentialPrecomp)254 TEST_F(EpidMemberTest, CanProvisionUsingIKGFMembershipCredentialPrecomp) {
255 Prng prng;
256 const GroupPubKey* pub_key = reinterpret_cast<const GroupPubKey*>(
257 this->kGroupPublicKeyDataIkgf.data());
258 const PrivKey* priv_key =
259 reinterpret_cast<const PrivKey*>(this->kMemberPrivateKeyDataIkgf.data());
260 FpElemStr f = priv_key->f;
261 MembershipCredential credential;
262 credential.A = priv_key->A;
263 credential.gid = priv_key->gid;
264 credential.x = priv_key->x;
265 // Note: this MemberPrecomp is for the wrong group, however it should not
266 // be checked in Provision because doing so would negate the performance
267 // boost of using the precomp.
268 MemberPrecomp precomp = this->kMemberPrecomp;
269 MemberParams params = {0};
270 SetMemberParams(&Prng::Generate, &prng, &f, ¶ms);
271 MemberCtxObj member(¶ms);
272 EXPECT_EQ(kEpidNoErr, ProvisionCredentialAndStart(member, pub_key,
273 &credential, &precomp));
274 }
275
TEST_F(EpidMemberTest,CanProvisionUsingIKGFMembershipCredentialNoPrecomp)276 TEST_F(EpidMemberTest, CanProvisionUsingIKGFMembershipCredentialNoPrecomp) {
277 Prng prng;
278 const GroupPubKey* pub_key = reinterpret_cast<const GroupPubKey*>(
279 this->kGroupPublicKeyDataIkgf.data());
280 const PrivKey* priv_key =
281 reinterpret_cast<const PrivKey*>(this->kMemberPrivateKeyDataIkgf.data());
282 FpElemStr f = priv_key->f;
283 MembershipCredential credential;
284 credential.A = priv_key->A;
285 credential.gid = priv_key->gid;
286 credential.x = priv_key->x;
287 MemberParams params = {0};
288 SetMemberParams(&Prng::Generate, &prng, &f, ¶ms);
289 MemberCtxObj member(¶ms);
290 EXPECT_EQ(kEpidNoErr,
291 ProvisionCredentialAndStart(member, pub_key, &credential, nullptr));
292 }
293
TEST_F(EpidMemberTest,ProvisionCredentialCanStoreMembershipCredentialNoPrecomp)294 TEST_F(EpidMemberTest,
295 ProvisionCredentialCanStoreMembershipCredentialNoPrecomp) {
296 Prng prng;
297 uint32_t nv_index = 0x01c10100;
298
299 MembershipCredential const orig_credential =
300 *(MembershipCredential*)&this->kGrpXMember9PrivKey;
301 MembershipCredential credential;
302
303 GroupPubKey pub_key = this->kGrpXKey;
304 FpElemStr f = this->kGrpXMember9PrivKey.f;
305
306 MemberParams params = {0};
307 SetMemberParams(&Prng::Generate, &prng, &f, ¶ms);
308 MemberCtxObj member(¶ms);
309 EXPECT_EQ(kEpidNoErr, ProvisionCredentialAndStart(member, &pub_key,
310 &orig_credential, nullptr));
311
312 EXPECT_EQ(kEpidNoErr,
313 EpidNvReadMembershipCredential(((MemberCtx*)member)->tpm2_ctx,
314 nv_index, &pub_key, &credential));
315 EXPECT_EQ(orig_credential, credential);
316 }
317
318 } // namespace
319