1 /*############################################################################ 2 # Copyright 2016 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 NrVerfy implementation. 20 */ 21 22 #include "epid/common/src/memory.h" 23 #include "epid/verifier/api.h" 24 #include "epid/verifier/src/context.h" 25 26 /// Handle SDK Error with Break 27 #define BREAK_ON_EPID_ERROR(ret) \ 28 if (kEpidNoErr != (ret)) { \ 29 break; \ 30 } 31 32 #pragma pack(1) 33 /// Storage for values to create commitment in NrVerify algorithm 34 typedef struct NrVerifyCommitValues { 35 BigNumStr p; //!< A large prime (256-bit) 36 G1ElemStr g1; //!< Generator of G1 (512-bit) 37 G1ElemStr b; //!< (element of G1): part of basic signature Sigma0 38 G1ElemStr k; //!< (element of G1): part of basic signature Sigma0 39 G1ElemStr bp; //!< (element of G1): one entry in SigRL 40 G1ElemStr kp; //!< (element of G1): one entry in SigRL 41 G1ElemStr t; //!< element of G1 42 G1ElemStr r1; //!< element of G1 43 G1ElemStr r2; //!< element of G1 44 uint8_t msg[1]; //!< message 45 } NrVerifyCommitValues; 46 #pragma pack() 47 48 EpidStatus EpidNrVerify(VerifierCtx const* ctx, BasicSignature const* sig, 49 void const* msg, size_t msg_len, 50 SigRlEntry const* sigrl_entry, NrProof const* proof) { 51 size_t const cv_header_len = sizeof(NrVerifyCommitValues) - sizeof(uint8_t); 52 EpidStatus sts = kEpidErr; 53 NrVerifyCommitValues* commit_values = NULL; 54 size_t const commit_len = sizeof(*commit_values) + msg_len - 1; 55 EcPoint* t_pt = NULL; 56 EcPoint* k_pt = NULL; 57 EcPoint* b_pt = NULL; 58 EcPoint* kp_pt = NULL; 59 EcPoint* bp_pt = NULL; 60 EcPoint* r1_pt = NULL; 61 EcPoint* r2_pt = NULL; 62 FfElement* c_el = NULL; 63 FfElement* nc_el = NULL; 64 FfElement* smu_el = NULL; 65 FfElement* snu_el = NULL; 66 FfElement* commit_hash = NULL; 67 if (!ctx || !sig || !proof || !sigrl_entry) { 68 return kEpidBadArgErr; 69 } 70 if (!msg && (0 != msg_len)) { 71 return kEpidBadArgErr; 72 } 73 if (msg_len > (SIZE_MAX - cv_header_len)) { 74 return kEpidBadArgErr; 75 } 76 if (!ctx->epid2_params || !ctx->epid2_params->G1 || !ctx->epid2_params->Fp) { 77 return kEpidBadArgErr; 78 } 79 do { 80 EcGroup* G1 = ctx->epid2_params->G1; 81 FiniteField* Fp = ctx->epid2_params->Fp; 82 G1ElemStr const* b = &sig->B; 83 G1ElemStr const* k = &sig->K; 84 G1ElemStr const* bp = &sigrl_entry->b; 85 G1ElemStr const* kp = &sigrl_entry->k; 86 EcPoint const* r1p[2]; 87 FpElemStr const* r1b[2]; 88 EcPoint const* r2p[3]; 89 FpElemStr const* r2b[3]; 90 FpElemStr nc_str; 91 bool t_is_identity; 92 bool c_is_equal; 93 94 commit_values = SAFE_ALLOC(commit_len); 95 if (commit_values == NULL) { 96 sts = kEpidMemAllocErr; 97 break; 98 } 99 100 // allocate local memory 101 sts = NewEcPoint(G1, &t_pt); 102 BREAK_ON_EPID_ERROR(sts); 103 sts = NewEcPoint(G1, &k_pt); 104 BREAK_ON_EPID_ERROR(sts); 105 sts = NewEcPoint(G1, &b_pt); 106 BREAK_ON_EPID_ERROR(sts); 107 sts = NewEcPoint(G1, &kp_pt); 108 BREAK_ON_EPID_ERROR(sts); 109 sts = NewEcPoint(G1, &bp_pt); 110 BREAK_ON_EPID_ERROR(sts); 111 sts = NewEcPoint(G1, &r1_pt); 112 BREAK_ON_EPID_ERROR(sts); 113 sts = NewEcPoint(G1, &r2_pt); 114 BREAK_ON_EPID_ERROR(sts); 115 sts = NewFfElement(Fp, &c_el); 116 BREAK_ON_EPID_ERROR(sts); 117 sts = NewFfElement(Fp, &nc_el); 118 BREAK_ON_EPID_ERROR(sts); 119 sts = NewFfElement(Fp, &smu_el); 120 BREAK_ON_EPID_ERROR(sts); 121 sts = NewFfElement(Fp, &snu_el); 122 BREAK_ON_EPID_ERROR(sts); 123 sts = NewFfElement(Fp, &commit_hash); 124 BREAK_ON_EPID_ERROR(sts); 125 126 // 1. The verifier verifies that G1.inGroup(T) = true. 127 sts = ReadEcPoint(G1, &proof->T, sizeof(proof->T), t_pt); 128 if (kEpidNoErr != sts) { 129 sts = kEpidBadArgErr; 130 break; 131 } 132 133 // 2. The verifier verifies that G1.isIdentity(T) = false. 134 sts = EcIsIdentity(G1, t_pt, &t_is_identity); 135 BREAK_ON_EPID_ERROR(sts); 136 if (t_is_identity) { 137 sts = kEpidBadArgErr; 138 break; 139 } 140 141 // 3. The verifier verifies that c, smu, snu in [0, p-1]. 142 sts = ReadFfElement(Fp, &proof->c, sizeof(proof->c), c_el); 143 BREAK_ON_EPID_ERROR(sts); 144 sts = ReadFfElement(Fp, &proof->smu, sizeof(proof->smu), smu_el); 145 BREAK_ON_EPID_ERROR(sts); 146 sts = ReadFfElement(Fp, &proof->snu, sizeof(proof->snu), snu_el); 147 BREAK_ON_EPID_ERROR(sts); 148 149 // 4. The verifier computes nc = (- c) mod p. 150 sts = FfNeg(Fp, c_el, nc_el); 151 BREAK_ON_EPID_ERROR(sts); 152 153 sts = WriteFfElement(Fp, nc_el, &nc_str, sizeof(nc_str)); 154 BREAK_ON_EPID_ERROR(sts); 155 156 // 5. The verifier computes R1 = G1.multiExp(K, smu, B, snu). 157 sts = ReadEcPoint(G1, k, sizeof(*k), k_pt); 158 if (kEpidNoErr != sts) { 159 sts = kEpidBadArgErr; 160 break; 161 } 162 sts = ReadEcPoint(G1, b, sizeof(*b), b_pt); 163 if (kEpidNoErr != sts) { 164 sts = kEpidBadArgErr; 165 break; 166 } 167 r1p[0] = k_pt; 168 r1p[1] = b_pt; 169 r1b[0] = &proof->smu; 170 r1b[1] = &proof->snu; 171 sts = EcMultiExp(G1, r1p, (const BigNumStr**)r1b, 2, r1_pt); 172 BREAK_ON_EPID_ERROR(sts); 173 174 // 6. The verifier computes R2 = G1.multiExp(K', smu, B', snu, T, nc). 175 sts = ReadEcPoint(G1, kp, sizeof(*kp), kp_pt); 176 if (kEpidNoErr != sts) { 177 sts = kEpidBadArgErr; 178 break; 179 } 180 sts = ReadEcPoint(G1, bp, sizeof(*bp), bp_pt); 181 if (kEpidNoErr != sts) { 182 sts = kEpidBadArgErr; 183 break; 184 } 185 r2p[0] = kp_pt; 186 r2p[1] = bp_pt; 187 r2p[2] = t_pt; 188 r2b[0] = &proof->smu; 189 r2b[1] = &proof->snu; 190 r2b[2] = &nc_str; 191 sts = EcMultiExp(G1, r2p, (const BigNumStr**)r2b, 3, r2_pt); 192 BREAK_ON_EPID_ERROR(sts); 193 194 // 7. The verifier verifies c = Fp.hash(p || g1 || B || K || 195 // B' || K' || T || R1 || R2 || m). 196 // Refer to Section 7.1 for hash operation over a prime field. 197 198 // commit_values is allocated such that there are msg_len bytes available 199 // starting at commit_values->msg 200 if (msg) { 201 // Memory copy is used to copy a message of variable length 202 if (0 != memcpy_S(&commit_values->msg[0], msg_len, msg, msg_len)) { 203 sts = kEpidBadArgErr; 204 break; 205 } 206 } 207 commit_values->p = ctx->commit_values.p; 208 commit_values->g1 = ctx->commit_values.g1; 209 commit_values->b = sig->B; 210 commit_values->k = sig->K; 211 commit_values->bp = sigrl_entry->b; 212 commit_values->kp = sigrl_entry->k; 213 commit_values->t = proof->T; 214 sts = 215 WriteEcPoint(G1, r1_pt, &commit_values->r1, sizeof(commit_values->r1)); 216 BREAK_ON_EPID_ERROR(sts); 217 sts = 218 WriteEcPoint(G1, r2_pt, &commit_values->r2, sizeof(commit_values->r2)); 219 BREAK_ON_EPID_ERROR(sts); 220 sts = FfHash(Fp, commit_values, commit_len, ctx->hash_alg, commit_hash); 221 BREAK_ON_EPID_ERROR(sts); 222 sts = FfIsEqual(Fp, c_el, commit_hash, &c_is_equal); 223 BREAK_ON_EPID_ERROR(sts); 224 if (!c_is_equal) { 225 sts = kEpidBadArgErr; 226 break; 227 } 228 sts = kEpidNoErr; 229 } while (0); 230 SAFE_FREE(commit_values); 231 DeleteFfElement(&commit_hash); 232 DeleteFfElement(&snu_el); 233 DeleteFfElement(&smu_el); 234 DeleteFfElement(&nc_el); 235 DeleteFfElement(&c_el); 236 DeleteEcPoint(&r2_pt); 237 DeleteEcPoint(&r1_pt); 238 DeleteEcPoint(&bp_pt); 239 DeleteEcPoint(&kp_pt); 240 DeleteEcPoint(&b_pt); 241 DeleteEcPoint(&k_pt); 242 DeleteEcPoint(&t_pt); 243 return sts; 244 } 245