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 Verifier context implementation.
20  */
21 #include "epid/verifier/src/context.h"
22 #include <string.h>
23 #include "epid/common/math/pairing.h"
24 #include "epid/common/src/endian_convert.h"
25 #include "epid/common/src/epid2params.h"
26 #include "epid/common/src/memory.h"
27 #include "epid/common/src/sigrlvalid.h"
28 #include "epid/verifier/api.h"
29 
30 /// Handle SDK Error with Break
31 #define BREAK_ON_EPID_ERROR(ret) \
32   if (kEpidNoErr != (ret)) {     \
33     break;                       \
34   }
35 /// create Verifier precomp of the VerifierCtx
36 static EpidStatus DoPrecomputation(VerifierCtx* ctx);
37 
38 /// Read Verifier precomp
39 static EpidStatus ReadPrecomputation(VerifierPrecomp const* precomp_str,
40                                      VerifierCtx* ctx);
41 
42 /// Internal function to prove if group based revocation list is valid
IsGroupRlValid(GroupRl const * group_rl,size_t grp_rl_size)43 static bool IsGroupRlValid(GroupRl const* group_rl, size_t grp_rl_size) {
44   const size_t kMinGroupRlSize = sizeof(GroupRl) - sizeof(GroupId);
45   size_t input_grp_rl_size = 0;
46 
47   if (!group_rl || grp_rl_size < kMinGroupRlSize) {
48     return false;
49   }
50   if (ntohl(group_rl->n3) > (SIZE_MAX - kMinGroupRlSize) / sizeof(GroupId)) {
51     return false;
52   }
53   input_grp_rl_size = kMinGroupRlSize + (ntohl(group_rl->n3) * sizeof(GroupId));
54   if (input_grp_rl_size != grp_rl_size) {
55     return false;
56   }
57   return true;
58 }
59 
60 /// Internal function to verify if private key based revocation list is valid
IsPrivRlValid(GroupId const * gid,PrivRl const * priv_rl,size_t priv_rl_size)61 static bool IsPrivRlValid(GroupId const* gid, PrivRl const* priv_rl,
62                           size_t priv_rl_size) {
63   const size_t kMinPrivRlSize = sizeof(PrivRl) - sizeof(FpElemStr);
64   size_t input_priv_rl_size = 0;
65 
66   if (!gid || !priv_rl || kMinPrivRlSize > priv_rl_size) {
67     return false;
68   }
69   if (ntohl(priv_rl->n1) >
70       (SIZE_MAX - kMinPrivRlSize) / sizeof(priv_rl->f[0])) {
71     return false;
72   }
73   // sanity check of input PrivRl size
74   input_priv_rl_size =
75       kMinPrivRlSize + ntohl(priv_rl->n1) * sizeof(priv_rl->f[0]);
76   if (input_priv_rl_size != priv_rl_size) {
77     return false;
78   }
79   // verify that gid given and gid in PrivRl match
80   if (0 != memcmp(gid, &priv_rl->gid, sizeof(*gid))) {
81     return false;
82   }
83   return true;
84 }
85 
86 /// Internal function to verify if verifier revocation list is valid
IsVerifierRlValid(GroupId const * gid,VerifierRl const * ver_rl,size_t ver_rl_size)87 static bool IsVerifierRlValid(GroupId const* gid, VerifierRl const* ver_rl,
88                               size_t ver_rl_size) {
89   const size_t kMinVerifierRlSize = sizeof(VerifierRl) - sizeof(G1ElemStr);
90   size_t expected_verifier_rl_size = 0;
91 
92   if (!gid || !ver_rl || kMinVerifierRlSize > ver_rl_size) {
93     return false;
94   }
95   if (ntohl(ver_rl->n4) >
96       (SIZE_MAX - kMinVerifierRlSize) / sizeof(ver_rl->K[0])) {
97     return false;
98   }
99   // sanity check of input VerifierRl size
100   expected_verifier_rl_size =
101       kMinVerifierRlSize + ntohl(ver_rl->n4) * sizeof(ver_rl->K[0]);
102   if (expected_verifier_rl_size != ver_rl_size) {
103     return false;
104   }
105 
106   // verify that gid in public key and gid in SigRl match
107   if (0 != memcmp(gid, &ver_rl->gid, sizeof(*gid))) {
108     return false;
109   }
110 
111   return true;
112 }
113 
EpidVerifierCreate(GroupPubKey const * pubkey,VerifierPrecomp const * precomp,VerifierCtx ** ctx)114 EpidStatus EpidVerifierCreate(GroupPubKey const* pubkey,
115                               VerifierPrecomp const* precomp,
116                               VerifierCtx** ctx) {
117   EpidStatus result = kEpidErr;
118   VerifierCtx* verifier_ctx = NULL;
119   if (!pubkey || !ctx) {
120     return kEpidBadArgErr;
121   }
122   do {
123     // Allocate memory for VerifierCtx
124     verifier_ctx = SAFE_ALLOC(sizeof(VerifierCtx));
125     if (!verifier_ctx) {
126       result = kEpidMemAllocErr;
127       break;
128     }
129 
130     // set the default hash algorithm
131     verifier_ctx->hash_alg = kSha512;
132 #ifdef TPM_TSS  // if build for TSS, make Sha256 default
133     verifier_ctx->hash_alg = kSha256;
134 #endif
135 
136     // Internal representation of Epid2Params
137     result = CreateEpid2Params(&verifier_ctx->epid2_params);
138     if (kEpidNoErr != result) {
139       break;
140     }
141     // Internal representation of Group Pub Key
142     result = CreateGroupPubKey(pubkey, verifier_ctx->epid2_params->G1,
143                                verifier_ctx->epid2_params->G2,
144                                &verifier_ctx->pub_key);
145     if (kEpidNoErr != result) {
146       break;
147     }
148     // Store group public key strings for later use
149     result = SetKeySpecificCommitValues(pubkey, &verifier_ctx->commit_values);
150     if (kEpidNoErr != result) {
151       break;
152     }
153     // Allocate verifier_ctx->e12
154     result = NewFfElement(verifier_ctx->epid2_params->GT, &verifier_ctx->e12);
155     if (kEpidNoErr != result) {
156       break;
157     }
158     // Allocate verifier_ctx->e22
159     result = NewFfElement(verifier_ctx->epid2_params->GT, &verifier_ctx->e22);
160     if (kEpidNoErr != result) {
161       break;
162     }
163     // Allocate verifier_ctx->e2w
164     result = NewFfElement(verifier_ctx->epid2_params->GT, &verifier_ctx->e2w);
165     if (kEpidNoErr != result) {
166       break;
167     }
168     // Allocate verifier_ctx->eg12
169     result = NewFfElement(verifier_ctx->epid2_params->GT, &verifier_ctx->eg12);
170     if (kEpidNoErr != result) {
171       break;
172     }
173     // precomputation
174     if (precomp != NULL) {
175       result = ReadPrecomputation(precomp, verifier_ctx);
176     } else {
177       result = DoPrecomputation(verifier_ctx);
178     }
179     if (kEpidNoErr != result) {
180       break;
181     }
182     verifier_ctx->sig_rl = NULL;
183     verifier_ctx->group_rl = NULL;
184     verifier_ctx->priv_rl = NULL;
185     verifier_ctx->verifier_rl = NULL;
186     verifier_ctx->was_verifier_rl_updated = false;
187     verifier_ctx->basename_hash = NULL;
188     verifier_ctx->basename = NULL;
189     verifier_ctx->basename_len = 0;
190     *ctx = verifier_ctx;
191     result = kEpidNoErr;
192   } while (0);
193 
194   if (kEpidNoErr != result && verifier_ctx) {
195     DeleteFfElement(&verifier_ctx->eg12);
196     DeleteFfElement(&verifier_ctx->e2w);
197     DeleteFfElement(&verifier_ctx->e22);
198     DeleteFfElement(&verifier_ctx->e12);
199     DeleteEpid2Params(&verifier_ctx->epid2_params);
200     DeleteGroupPubKey(&verifier_ctx->pub_key);
201     SAFE_FREE(verifier_ctx);
202   }
203   return result;
204 }
205 
EpidVerifierDelete(VerifierCtx ** ctx)206 void EpidVerifierDelete(VerifierCtx** ctx) {
207   if (ctx && *ctx) {
208     DeleteFfElement(&(*ctx)->eg12);
209     DeleteFfElement(&(*ctx)->e2w);
210     DeleteFfElement(&(*ctx)->e22);
211     DeleteFfElement(&(*ctx)->e12);
212     DeleteGroupPubKey(&(*ctx)->pub_key);
213     DeleteEpid2Params(&(*ctx)->epid2_params);
214     (*ctx)->priv_rl = NULL;
215     (*ctx)->sig_rl = NULL;
216     (*ctx)->group_rl = NULL;
217     SAFE_FREE((*ctx)->verifier_rl);
218     DeleteEcPoint(&(*ctx)->basename_hash);
219     SAFE_FREE((*ctx)->basename);
220     (*ctx)->basename_len = 0;
221     SAFE_FREE(*ctx);
222   }
223 }
224 
EpidVerifierWritePrecomp(VerifierCtx const * ctx,VerifierPrecomp * precomp)225 EpidStatus EpidVerifierWritePrecomp(VerifierCtx const* ctx,
226                                     VerifierPrecomp* precomp) {
227   EpidStatus result = kEpidErr;
228   FfElement* e12 = NULL;   // an element in GT
229   FfElement* e22 = NULL;   // an element in GT
230   FfElement* e2w = NULL;   // an element in GT
231   FfElement* eg12 = NULL;  // an element in GT
232   FiniteField* GT = NULL;  // Finite field GT(Fq12 )
233   if (!ctx) {
234     return kEpidBadArgErr;
235   }
236   if (!precomp) {
237     return kEpidBadArgErr;
238   }
239   if (!ctx->e12 || !ctx->e22 || !ctx->e2w || !ctx->eg12 || !ctx->epid2_params ||
240       !ctx->epid2_params->GT || !ctx->pub_key) {
241     return kEpidBadArgErr;
242   }
243   e12 = ctx->e12;
244   e22 = ctx->e22;
245   e2w = ctx->e2w;
246   eg12 = ctx->eg12;
247   GT = ctx->epid2_params->GT;
248   precomp->gid = ctx->pub_key->gid;
249   result = WriteFfElement(GT, e12, &(precomp->e12), sizeof(precomp->e12));
250   if (kEpidNoErr != result) {
251     return result;
252   }
253   result = WriteFfElement(GT, e22, &(precomp->e22), sizeof(precomp->e22));
254   if (kEpidNoErr != result) {
255     return result;
256   }
257   result = WriteFfElement(GT, e2w, &(precomp->e2w), sizeof(precomp->e2w));
258   if (kEpidNoErr != result) {
259     return result;
260   }
261   result = WriteFfElement(GT, eg12, &(precomp->eg12), sizeof(precomp->eg12));
262   if (kEpidNoErr != result) {
263     return result;
264   }
265   return result;
266 }
267 
EpidVerifierSetPrivRl(VerifierCtx * ctx,PrivRl const * priv_rl,size_t priv_rl_size)268 EpidStatus EpidVerifierSetPrivRl(VerifierCtx* ctx, PrivRl const* priv_rl,
269                                  size_t priv_rl_size) {
270   if (!ctx || !priv_rl || !ctx->pub_key) {
271     return kEpidBadArgErr;
272   }
273   if (!IsPrivRlValid(&ctx->pub_key->gid, priv_rl, priv_rl_size)) {
274     return kEpidBadArgErr;
275   }
276   // Do not set an older version of priv rl
277   if (ctx->priv_rl) {
278     unsigned int current_ver = 0;
279     unsigned int incoming_ver = 0;
280     current_ver = ntohl(ctx->priv_rl->version);
281     incoming_ver = ntohl(priv_rl->version);
282     if (current_ver >= incoming_ver) {
283       return kEpidBadArgErr;
284     }
285   }
286   ctx->priv_rl = priv_rl;
287   return kEpidNoErr;
288 }
289 
EpidVerifierSetSigRl(VerifierCtx * ctx,SigRl const * sig_rl,size_t sig_rl_size)290 EpidStatus EpidVerifierSetSigRl(VerifierCtx* ctx, SigRl const* sig_rl,
291                                 size_t sig_rl_size) {
292   if (!ctx || !sig_rl || !ctx->pub_key) {
293     return kEpidBadArgErr;
294   }
295   if (!IsSigRlValid(&ctx->pub_key->gid, sig_rl, sig_rl_size)) {
296     return kEpidBadArgErr;
297   }
298   // Do not set an older version of sig rl
299   if (ctx->sig_rl) {
300     unsigned int current_ver = 0;
301     unsigned int incoming_ver = 0;
302     current_ver = ntohl(ctx->sig_rl->version);
303     incoming_ver = ntohl(sig_rl->version);
304     if (current_ver >= incoming_ver) {
305       return kEpidBadArgErr;
306     }
307   }
308   ctx->sig_rl = sig_rl;
309 
310   return kEpidNoErr;
311 }
312 
EpidVerifierSetGroupRl(VerifierCtx * ctx,GroupRl const * grp_rl,size_t grp_rl_size)313 EpidStatus EpidVerifierSetGroupRl(VerifierCtx* ctx, GroupRl const* grp_rl,
314                                   size_t grp_rl_size) {
315   if (!ctx || !grp_rl || !ctx->pub_key) {
316     return kEpidBadArgErr;
317   }
318   if (!IsGroupRlValid(grp_rl, grp_rl_size)) {
319     return kEpidBadArgErr;
320   }
321   // Do not set an older version of group rl
322   if (ctx->group_rl) {
323     unsigned int current_ver = 0;
324     unsigned int incoming_ver = 0;
325     current_ver = ntohl(ctx->group_rl->version);
326     incoming_ver = ntohl(grp_rl->version);
327     if (current_ver >= incoming_ver) {
328       return kEpidBadArgErr;
329     }
330   }
331   ctx->group_rl = grp_rl;
332 
333   return kEpidNoErr;
334 }
335 
EpidVerifierSetVerifierRl(VerifierCtx * ctx,VerifierRl const * ver_rl,size_t ver_rl_size)336 EpidStatus EpidVerifierSetVerifierRl(VerifierCtx* ctx, VerifierRl const* ver_rl,
337                                      size_t ver_rl_size) {
338   VerifierRl* verifier_rl = NULL;
339   EpidStatus res = kEpidErr;
340   EcPoint* B = NULL;
341   bool cmp_result = false;
342   EcGroup* G1 = NULL;
343   if (!ctx || !ver_rl || !ctx->pub_key || !ctx->epid2_params ||
344       !ctx->epid2_params->G1) {
345     return kEpidBadArgErr;
346   }
347   if (!IsVerifierRlValid(&ctx->pub_key->gid, ver_rl, ver_rl_size)) {
348     return kEpidBadArgErr;
349   }
350   // if random basename
351   if (!ctx->basename_hash) {
352     return kEpidInconsistentBasenameSetErr;
353   }
354   // Do not set an older version of verifier rl
355   if (ctx->verifier_rl) {
356     unsigned int current_ver = 0;
357     unsigned int incoming_ver = 0;
358     current_ver = ntohl(ctx->verifier_rl->version);
359     incoming_ver = ntohl(ver_rl->version);
360     if (current_ver >= incoming_ver) {
361       return kEpidBadArgErr;
362     }
363   }
364   do {
365     G1 = ctx->epid2_params->G1;
366     res = NewEcPoint(G1, &B);
367     BREAK_ON_EPID_ERROR(res);
368     res = ReadEcPoint(G1, &(ver_rl->B), sizeof(ver_rl->B), B);
369     BREAK_ON_EPID_ERROR(res);
370     // verify B = G1.hash(bsn)
371     res = EcIsEqual(G1, ctx->basename_hash, B, &cmp_result);
372     BREAK_ON_EPID_ERROR(res);
373     if (true != cmp_result) {
374       res = kEpidBadArgErr;
375       break;
376     }
377     verifier_rl = SAFE_ALLOC(ver_rl_size);
378     if (!verifier_rl) {
379       res = kEpidMemAllocErr;
380       break;
381     }
382     if (0 != memcpy_S(verifier_rl, ver_rl_size, ver_rl, ver_rl_size)) {
383       res = kEpidBadArgErr;
384       break;
385     }
386     res = kEpidNoErr;
387   } while (0);
388   DeleteEcPoint(&B);
389   SAFE_FREE(ctx->verifier_rl);
390   if (kEpidNoErr == res) {
391     ctx->verifier_rl = verifier_rl;
392     ctx->was_verifier_rl_updated = false;
393   }
394   return res;
395 }
396 
EpidGetVerifierRlSize(VerifierCtx const * ctx)397 size_t EpidGetVerifierRlSize(VerifierCtx const* ctx) {
398   size_t empty_size = 0;
399   if (!ctx || !ctx->basename_hash) return 0;
400   empty_size = sizeof(VerifierRl) - sizeof(((VerifierRl*)0)->K[0]);
401   if (!ctx->verifier_rl) return empty_size;
402   return empty_size +
403          ntohl(ctx->verifier_rl->n4) * sizeof(ctx->verifier_rl->K[0]);
404 }
405 
EpidWriteVerifierRl(VerifierCtx const * ctx,VerifierRl * ver_rl,size_t ver_rl_size)406 EpidStatus EpidWriteVerifierRl(VerifierCtx const* ctx, VerifierRl* ver_rl,
407                                size_t ver_rl_size) {
408   EpidStatus res = kEpidErr;
409   size_t real_ver_rl_size = 0;
410   if (!ctx || !ver_rl || !ctx->pub_key || !ctx->epid2_params ||
411       !ctx->epid2_params->G1) {
412     return kEpidBadArgErr;
413   }
414   real_ver_rl_size = EpidGetVerifierRlSize(ctx);
415   if (real_ver_rl_size == 0) {
416     return kEpidErr;
417   }
418   if (real_ver_rl_size != ver_rl_size) {
419     return kEpidBadArgErr;
420   }
421   if (ctx->verifier_rl) {
422     // serialize
423     if (0 !=
424         memcpy_S(ver_rl, ver_rl_size, ctx->verifier_rl, real_ver_rl_size)) {
425       return kEpidBadArgErr;
426     }
427     // update rl version if it has changed
428     if (ctx->was_verifier_rl_updated) {
429       uint32_t prior_rl_version = ntohl(ver_rl->version);
430       *((uint32_t*)(&ver_rl->version)) = htonl(prior_rl_version + 1);
431       ((VerifierCtx*)ctx)->was_verifier_rl_updated = false;
432     }
433   } else {
434     // write empty rl
435     res = WriteEcPoint(ctx->epid2_params->G1, ctx->basename_hash, &(ver_rl->B),
436                        sizeof(ver_rl->B));
437     if (kEpidNoErr != res) {
438       return res;
439     }
440     ver_rl->gid = ctx->pub_key->gid;
441     memset(&ver_rl->version, 0, sizeof(ver_rl->version));
442     memset(&ver_rl->n4, 0, sizeof(ver_rl->n4));
443   }
444   return kEpidNoErr;
445 }
446 
EpidBlacklistSig(VerifierCtx * ctx,EpidSignature const * sig,size_t sig_len,void const * msg,size_t msg_len)447 EpidStatus EpidBlacklistSig(VerifierCtx* ctx, EpidSignature const* sig,
448                             size_t sig_len, void const* msg, size_t msg_len) {
449   EpidStatus result = kEpidErr;
450   VerifierRl* ver_rl = NULL;
451   if (!ctx || !sig || (!msg && msg_len > 0) || !ctx->epid2_params ||
452       !ctx->epid2_params->G1) {
453     return kEpidBadArgErr;
454   }
455   if (sig_len < sizeof(EpidSignature) - sizeof(((EpidSignature*)0)->sigma[0])) {
456     return kEpidBadArgErr;
457   }
458   if (!ctx->basename_hash) {
459     return kEpidInconsistentBasenameSetErr;
460   }
461 
462   do {
463     EcGroup* G1 = ctx->epid2_params->G1;
464     uint32_t n4 = 0;
465     result = EpidVerify(ctx, sig, sig_len, msg, msg_len);
466     BREAK_ON_EPID_ERROR(result);
467 
468     if (!ctx->verifier_rl) {
469       ver_rl = SAFE_ALLOC(sizeof(VerifierRl));
470       if (!ver_rl) {
471         result = kEpidMemAllocErr;
472         break;
473       }
474       // write empty rl
475       ver_rl->gid = ctx->pub_key->gid;
476       result =
477           WriteEcPoint(G1, ctx->basename_hash, &(ver_rl->B), sizeof(ver_rl->B));
478       BREAK_ON_EPID_ERROR(result);
479     } else {
480       uint32_t prior_rl_version = ntohl(ctx->verifier_rl->version);
481       n4 = ntohl(ctx->verifier_rl->n4);
482 
483       if (prior_rl_version == UINT32_MAX || n4 == UINT32_MAX) {
484         result = kEpidBadArgErr;
485         break;
486       }
487       ver_rl = SAFE_REALLOC(
488           ctx->verifier_rl,
489           EpidGetVerifierRlSize(ctx) + sizeof(((VerifierRl*)0)->K[0]));
490       if (!ver_rl) {
491         result = kEpidMemAllocErr;
492         break;
493       }
494     }
495 
496     ctx->was_verifier_rl_updated = true;
497     ++n4;
498     ver_rl->K[n4 - 1] = sig->sigma0.K;
499 
500     *((uint32_t*)(&ver_rl->n4)) = htonl(n4);
501     ctx->verifier_rl = ver_rl;
502     result = kEpidNoErr;
503   } while (0);
504   if (kEpidNoErr != result) SAFE_FREE(ver_rl);
505   return result;
506 }
507 
EpidVerifierSetHashAlg(VerifierCtx * ctx,HashAlg hash_alg)508 EpidStatus EpidVerifierSetHashAlg(VerifierCtx* ctx, HashAlg hash_alg) {
509   EpidStatus result = kEpidErr;
510   if (!ctx) {
511     return kEpidBadArgErr;
512   }
513   if (kSha256 != hash_alg && kSha384 != hash_alg && kSha512 != hash_alg &&
514       kSha512_256 != hash_alg)
515     return kEpidBadArgErr;
516 
517   if (ctx->hash_alg != hash_alg) {
518     HashAlg previous_hash_alg = ctx->hash_alg;
519     ctx->hash_alg = hash_alg;
520 
521     result = EpidVerifierSetBasename(ctx, ctx->basename, ctx->basename_len);
522     if (kEpidNoErr != result) {
523       ctx->hash_alg = previous_hash_alg;
524       return result;
525     }
526   }
527   result = kEpidNoErr;
528   return result;
529 }
530 
EpidVerifierSetBasename(VerifierCtx * ctx,void const * basename,size_t basename_len)531 EpidStatus EpidVerifierSetBasename(VerifierCtx* ctx, void const* basename,
532                                    size_t basename_len) {
533   EpidStatus result = kEpidErr;
534   EcPoint* basename_hash = NULL;
535   uint8_t* basename_buffer = NULL;
536 
537   if (!ctx || !ctx->epid2_params || !ctx->epid2_params->G1) {
538     return kEpidBadArgErr;
539   }
540   if (!basename && basename_len > 0) {
541     return kEpidBadArgErr;
542   }
543 
544   if (!basename) {
545     DeleteEcPoint(&ctx->basename_hash);
546     ctx->basename_hash = NULL;
547     ctx->was_verifier_rl_updated = false;
548     SAFE_FREE(ctx->basename);
549     ctx->basename_len = 0;
550     return kEpidNoErr;
551   }
552 
553   do {
554     size_t i = 0;
555     EcGroup* G1 = ctx->epid2_params->G1;
556     result = NewEcPoint(G1, &basename_hash);
557     if (kEpidNoErr != result) {
558       break;
559     }
560 
561     result =
562         EcHash(G1, basename, basename_len, ctx->hash_alg, basename_hash, NULL);
563     if (kEpidNoErr != result) {
564       break;
565     }
566 
567     if (basename_len > 0) {
568       basename_buffer = SAFE_ALLOC(basename_len);
569       if (!basename_buffer) {
570         result = kEpidMemAllocErr;
571         break;
572       }
573     }
574 
575     SAFE_FREE(ctx->verifier_rl);
576 
577     DeleteEcPoint(&ctx->basename_hash);
578     ctx->basename_hash = basename_hash;
579     SAFE_FREE(ctx->basename);
580     ctx->basename = basename_buffer;
581     ctx->basename_len = basename_len;
582     for (i = 0; i < basename_len; i++) {
583       ctx->basename[i] = ((uint8_t*)basename)[i];
584     }
585     result = kEpidNoErr;
586   } while (0);
587 
588   if (kEpidNoErr != result) {
589     DeleteEcPoint(&basename_hash);
590     SAFE_FREE(basename_buffer);
591   }
592   return result;
593 }
594 
DoPrecomputation(VerifierCtx * ctx)595 static EpidStatus DoPrecomputation(VerifierCtx* ctx) {
596   EpidStatus result = kEpidErr;
597   FfElement* e12 = NULL;
598   FfElement* e22 = NULL;
599   FfElement* e2w = NULL;
600   FfElement* eg12 = NULL;
601   Epid2Params_* params = NULL;
602   GroupPubKey_* pub_key = NULL;
603   PairingState* ps_ctx = NULL;
604   if (!ctx) {
605     return kEpidBadArgErr;
606   }
607   if (!ctx->epid2_params || !ctx->epid2_params->GT ||
608       !ctx->epid2_params->pairing_state || !ctx->pub_key || !ctx->e12 ||
609       !ctx->e22 || !ctx->e2w || !ctx->eg12) {
610     return kEpidBadArgErr;
611   }
612   pub_key = ctx->pub_key;
613   params = ctx->epid2_params;
614   e12 = ctx->e12;
615   e22 = ctx->e22;
616   e2w = ctx->e2w;
617   eg12 = ctx->eg12;
618   ps_ctx = params->pairing_state;
619   // do precomputation
620   // 1. The verifier computes e12 = pairing(h1, g2).
621   result = Pairing(ps_ctx, pub_key->h1, params->g2, e12);
622   if (kEpidNoErr != result) {
623     return result;
624   }
625   // 2. The verifier computes e22 = pairing(h2, g2).
626   result = Pairing(ps_ctx, pub_key->h2, params->g2, e22);
627   if (kEpidNoErr != result) {
628     return result;
629   }
630   // 3. The verifier computes e2w = pairing(h2, w).
631   result = Pairing(ps_ctx, pub_key->h2, pub_key->w, e2w);
632   if (kEpidNoErr != result) {
633     return result;
634   }
635   // 4. The verifier computes eg12 = pairing(g1, g2).
636   result = Pairing(ps_ctx, params->g1, params->g2, eg12);
637   if (kEpidNoErr != result) {
638     return result;
639   }
640   return kEpidNoErr;
641 }
ReadPrecomputation(VerifierPrecomp const * precomp_str,VerifierCtx * ctx)642 static EpidStatus ReadPrecomputation(VerifierPrecomp const* precomp_str,
643                                      VerifierCtx* ctx) {
644   EpidStatus result = kEpidErr;
645   FfElement* e12 = NULL;
646   FfElement* e22 = NULL;
647   FfElement* e2w = NULL;
648   FfElement* eg12 = NULL;
649   FiniteField* GT = NULL;
650   Epid2Params_* params = NULL;
651   if (!ctx) {
652     return kEpidBadArgErr;
653   }
654   if (!ctx->epid2_params || !ctx->epid2_params->GT || !ctx->e12 || !ctx->e22 ||
655       !ctx->e2w || !ctx->eg12 || !ctx->pub_key) {
656     return kEpidBadArgErr;
657   }
658   if (0 !=
659       memcmp(&precomp_str->gid, &ctx->pub_key->gid, sizeof(precomp_str->gid))) {
660     return kEpidBadArgErr;
661   }
662   params = ctx->epid2_params;
663   GT = params->GT;
664   e12 = ctx->e12;
665   e22 = ctx->e22;
666   e2w = ctx->e2w;
667   eg12 = ctx->eg12;
668 
669   result = ReadFfElement(GT, &precomp_str->e12, sizeof(precomp_str->e12), e12);
670   if (kEpidNoErr != result) {
671     return result;
672   }
673   result = ReadFfElement(GT, &precomp_str->e22, sizeof(precomp_str->e22), e22);
674   if (kEpidNoErr != result) {
675     return result;
676   }
677   result = ReadFfElement(GT, &precomp_str->e2w, sizeof(precomp_str->e2w), e2w);
678   if (kEpidNoErr != result) {
679     return result;
680   }
681   result =
682       ReadFfElement(GT, &precomp_str->eg12, sizeof(precomp_str->eg12), eg12);
683   if (kEpidNoErr != result) {
684     return result;
685   }
686   return kEpidNoErr;
687 }
688