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
EpidNrVerify(VerifierCtx const * ctx,BasicSignature const * sig,void const * msg,size_t msg_len,SigRlEntry const * sigrl_entry,NrProof const * proof)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