• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 /// Join Request related implementation.
17 /*! \file */
18 
19 #include <epid/member/api.h>
20 
21 #include "epid/common/src/epid2params.h"
22 #include "epid/common/src/grouppubkey.h"
23 #include "epid/common/src/hashsize.h"
24 #include "epid/common/src/memory.h"
25 #include "epid/common/types.h"
26 #include "epid/member/src/context.h"
27 #include "epid/member/src/join_commitment.h"
28 #include "epid/member/src/privateexp.h"
29 #include "epid/member/src/resize.h"
30 #include "epid/member/tpm2/commit.h"
31 #include "epid/member/tpm2/sign.h"
32 
33 /// Handle SDK Error with Break
34 #define BREAK_ON_EPID_ERROR(ret) \
35   if (kEpidNoErr != (ret)) {     \
36     break;                       \
37   }
38 
EpidCreateJoinRequest(MemberCtx * ctx,GroupPubKey const * pub_key,IssuerNonce const * ni,JoinRequest * join_request)39 EpidStatus EpidCreateJoinRequest(MemberCtx* ctx, GroupPubKey const* pub_key,
40                                  IssuerNonce const* ni,
41                                  JoinRequest* join_request) {
42   EpidStatus sts = kEpidErr;
43   GroupPubKey_* pub_key_ = NULL;
44   EcPoint* t = NULL;  // temporary used for F and R
45   EcPoint* h1 = NULL;
46   EcPoint* K = NULL;
47   EcPoint* l = NULL;
48   EcPoint* e = NULL;
49 
50   FfElement* k = NULL;
51   FfElement* s = NULL;
52   uint8_t* digest = NULL;
53 
54   if (!ctx || !pub_key || !ni || !join_request || !ctx->epid2_params) {
55     return kEpidBadArgErr;
56   }
57 
58   if (kSha256 != ctx->hash_alg && kSha384 != ctx->hash_alg &&
59       kSha512 != ctx->hash_alg && kSha512_256 != ctx->hash_alg) {
60     return kEpidBadArgErr;
61   }
62 
63   do {
64     JoinRequest request = {0};
65     G1ElemStr R = {0};
66     EcGroup* G1 = ctx->epid2_params->G1;
67     FiniteField* Fp = ctx->epid2_params->Fp;
68     size_t digest_size = 0;
69 
70     if (!ctx->is_provisioned && !ctx->is_initially_provisioned) {
71       sts = EpidMemberInitialProvision(ctx);
72       BREAK_ON_EPID_ERROR(sts);
73     }
74 
75     // validate public key by creating
76     sts = CreateGroupPubKey(pub_key, ctx->epid2_params->G1,
77                             ctx->epid2_params->G2, &pub_key_);
78     BREAK_ON_EPID_ERROR(sts);
79 
80     sts = NewEcPoint(G1, &t);
81     BREAK_ON_EPID_ERROR(sts);
82     sts = NewEcPoint(G1, &h1);
83     BREAK_ON_EPID_ERROR(sts);
84     sts = ReadEcPoint(G1, &pub_key->h1, sizeof(pub_key->h1), h1);
85     BREAK_ON_EPID_ERROR(sts);
86 
87     // 2. The member computes F = G1.sscmExp(h1, f).
88     sts = EpidPrivateExp(ctx, h1, t);
89     BREAK_ON_EPID_ERROR(sts);
90     sts = WriteEcPoint(G1, t, &request.F, sizeof(request.F));
91     BREAK_ON_EPID_ERROR(sts);
92 
93     // 1. The member chooses a random integer r from [1, p-1].
94     // 3. The member computes R = G1.sscmExp(h1, r).
95     sts = NewEcPoint(G1, &K);
96     BREAK_ON_EPID_ERROR(sts);
97     sts = NewEcPoint(G1, &l);
98     BREAK_ON_EPID_ERROR(sts);
99     sts = NewEcPoint(G1, &e);
100     BREAK_ON_EPID_ERROR(sts);
101     sts =
102         Tpm2Commit(ctx->tpm2_ctx, h1, NULL, 0, NULL, K, l, e, &(ctx->join_ctr));
103     BREAK_ON_EPID_ERROR(sts);
104     sts = WriteEcPoint(G1, e, &R, sizeof(R));
105     BREAK_ON_EPID_ERROR(sts);
106 
107     sts = HashJoinCommitment(ctx->epid2_params->Fp, ctx->hash_alg, pub_key,
108                              &request.F, &R, ni, &request.c);
109     BREAK_ON_EPID_ERROR(sts);
110 
111     // Extend value c to be of a digest size.
112     digest_size = EpidGetHashSize(ctx->hash_alg);
113     digest = (uint8_t*)SAFE_ALLOC(digest_size);
114     if (!digest) {
115       sts = kEpidMemAllocErr;
116       break;
117     }
118     sts = ResizeOctStr(&request.c, sizeof(request.c), digest, digest_size);
119     BREAK_ON_EPID_ERROR(sts);
120 
121     // Step 5. The member computes s = (r + c * f) mod p.
122     sts = NewFfElement(Fp, &k);
123     BREAK_ON_EPID_ERROR(sts);
124     sts = NewFfElement(Fp, &s);
125     BREAK_ON_EPID_ERROR(sts);
126     sts = Tpm2Sign(ctx->tpm2_ctx, digest, digest_size, ctx->join_ctr, k, s);
127     BREAK_ON_EPID_ERROR(sts);
128     sts = WriteFfElement(Fp, s, &request.s, sizeof(request.s));
129     BREAK_ON_EPID_ERROR(sts);
130 
131     // Step 6. The output join request is (F, c, s).
132     *join_request = request;
133 
134     sts = kEpidNoErr;
135   } while (0);
136 
137   if (sts != kEpidNoErr) {
138     (void)Tpm2ReleaseCounter(ctx->tpm2_ctx, ctx->join_ctr);
139   }
140 
141   DeleteEcPoint(&t);
142   DeleteEcPoint(&h1);
143   DeleteEcPoint(&K);
144   DeleteEcPoint(&l);
145   DeleteEcPoint(&e);
146   DeleteFfElement(&k);
147   DeleteFfElement(&s);
148   SAFE_FREE(digest);
149   DeleteGroupPubKey(&pub_key_);
150 
151   return sts;
152 }
153