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