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, &params);
67   MemberCtxObj member(&params);
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, &params);
97   MemberCtxObj member(&params);
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, &params);
135   MemberCtxObj member(&params);
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, &params);
209   MemberCtxObj member(&params);
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, &params);
233   MemberCtxObj member(&params);
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, &params);
248   MemberCtxObj member(&params);
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, &params);
271   MemberCtxObj member(&params);
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, &params);
289   MemberCtxObj member(&params);
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, &params);
308   MemberCtxObj member(&params);
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