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 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