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