1 /*############################################################################
2 # Copyright 2016-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
17 /*!
18 * \file
19 * \brief Verify implementation.
20 */
21 #include <string.h>
22 #include "epid/common/src/endian_convert.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
EpidGetSignatureRlCount(EpidSignature const * sig)32 static size_t EpidGetSignatureRlCount(EpidSignature const* sig) {
33 if (!sig)
34 return 0;
35 else
36 return ntohl(sig->n2);
37 }
38
EpidGetGroupRlCount(GroupRl const * rl)39 static size_t EpidGetGroupRlCount(GroupRl const* rl) {
40 if (!rl)
41 return 0;
42 else
43 return ntohl(rl->n3);
44 }
45
EpidGetPrivRlCount(PrivRl const * rl)46 static size_t EpidGetPrivRlCount(PrivRl const* rl) {
47 if (!rl)
48 return 0;
49 else
50 return ntohl(rl->n1);
51 }
52
EpidGetSigRlCount(SigRl const * rl)53 static size_t EpidGetSigRlCount(SigRl const* rl) {
54 if (!rl)
55 return 0;
56 else
57 return ntohl(rl->n2);
58 }
59
EpidGetVerifierRlCount(VerifierRl const * rl)60 static size_t EpidGetVerifierRlCount(VerifierRl const* rl) {
61 if (!rl)
62 return 0;
63 else
64 return ntohl(rl->n4);
65 }
66
67 // implements section 4.1.2 "Verify algorithm" from Intel(R) EPID 2.0 Spec
EpidVerify(VerifierCtx const * ctx,EpidSignature const * sig,size_t sig_len,void const * msg,size_t msg_len)68 EpidStatus EpidVerify(VerifierCtx const* ctx, EpidSignature const* sig,
69 size_t sig_len, void const* msg, size_t msg_len) {
70 // Step 1. Setup
71 size_t const sig_header_len = (sizeof(EpidSignature) - sizeof(NrProof));
72 EpidStatus sts = kEpidErr;
73 size_t rl_count = 0;
74 size_t i;
75 if (!ctx || !sig) {
76 return kEpidBadArgErr;
77 }
78 if (!msg && (0 != msg_len)) {
79 // if message is non-empty it must have both length and content
80 return kEpidBadArgErr;
81 }
82 if (!ctx->epid2_params || !ctx->pub_key) {
83 return kEpidBadArgErr;
84 }
85 if (sig_len < sig_header_len) {
86 return kEpidBadArgErr;
87 }
88 rl_count = EpidGetSignatureRlCount(sig);
89 if (rl_count > (SIZE_MAX - sig_header_len) / sizeof(sig->sigma[0]) ||
90 (rl_count * sizeof(sig->sigma[0])) + sig_header_len != sig_len) {
91 return kEpidBadArgErr;
92 }
93 // Step 2. The verifier verifies the basic signature Sigma0 as follows:
94 sts = EpidVerifyBasicSig(ctx, &sig->sigma0, msg, msg_len);
95 if (sts != kEpidNoErr) {
96 // p. If any of the above verifications fails, the verifier aborts and
97 // outputs 1
98 return kEpidSigInvalid;
99 }
100
101 // Step 3. If GroupRL is provided,
102 if (ctx->group_rl) {
103 // a. The verifier verifies that gid does not match any entry in GroupRL.
104 size_t grouprl_count = EpidGetGroupRlCount(ctx->group_rl);
105 for (i = 0; i < grouprl_count; ++i) {
106 if (0 == memcmp(&ctx->pub_key->gid, &ctx->group_rl->gid[i],
107 sizeof(ctx->pub_key->gid))) {
108 // b. If gid matches an entry in GroupRL, aborts and returns 2.
109 return kEpidSigRevokedInGroupRl;
110 }
111 }
112 }
113
114 // Step 4. If PrivRL is provided,
115 if (ctx->priv_rl) {
116 size_t privrl_count = EpidGetPrivRlCount(ctx->priv_rl);
117 // a. The verifier verifies that gid in the public key and in PrivRL match.
118 // If mismatch, abort and return "operation failed".
119 if (0 != memcmp(&ctx->pub_key->gid, &ctx->priv_rl->gid,
120 sizeof(ctx->pub_key->gid))) {
121 return kEpidBadArgErr;
122 }
123 // b. For i = 0, ..., n1-1, the verifier computes t4 =G1.exp(B, f[i]) and
124 // verifies that G1.isEqual(t4, K) = false. A faster private-key revocation
125 // check algorithm is provided in Section 4.5.
126 for (i = 0; i < privrl_count; ++i) {
127 sts = EpidCheckPrivRlEntry(ctx, &sig->sigma0, &ctx->priv_rl->f[i]);
128 if (sts != kEpidNoErr) {
129 // c. If the above step fails, the verifier aborts and output 3.
130 return kEpidSigRevokedInPrivRl;
131 }
132 }
133 }
134
135 // Step 5. If SigRL is provided,
136 if (ctx->sig_rl) {
137 size_t sigrl_count = EpidGetSigRlCount(ctx->sig_rl);
138 // a. The verifier verifies that gid in the public key and in SigRL match.
139 // If mismatch, abort and return "operation failed".
140 if (0 != memcmp(&ctx->pub_key->gid, &ctx->sig_rl->gid,
141 sizeof(ctx->pub_key->gid))) {
142 return kEpidBadArgErr;
143 }
144
145 // b. The verifier verifies that RLver in Sigma and in SigRL match. If
146 // mismatch, abort and output "operation failed".
147 if (0 != memcmp(&ctx->sig_rl->version, &sig->rl_ver,
148 sizeof(ctx->sig_rl->version))) {
149 return kEpidErr;
150 }
151
152 // c. The verifier verifies that n2 in Sigma and in SigRL match. If
153 // mismatch, abort and output "operation failed".
154 if (sigrl_count != rl_count) {
155 return kEpidBadArgErr;
156 }
157
158 // d. For i = 0, ..., n2-1, the verifier verifies nrVerify(B, K, B[i],
159 // K[i], Sigma[i]) = true. The details of nrVerify() will be given in the
160 // next subsection.
161 for (i = 0; i < sigrl_count; ++i) {
162 sts = EpidNrVerify(ctx, &sig->sigma0, msg, msg_len, &ctx->sig_rl->bk[i],
163 &sig->sigma[i]);
164 if (sts != kEpidNoErr) {
165 // e. If the above step fails, the verifier aborts and output 4.
166 return kEpidSigRevokedInSigRl;
167 }
168 }
169 }
170
171 // Step 6. If VerifierRL is provided,
172 if (ctx->verifier_rl) {
173 // a. The verifier verifies that gid in the public key and in VerifierRL
174 // match. If mismatch, abort and return "operation failed".
175 if (0 != memcmp(&ctx->pub_key->gid, &ctx->verifier_rl->gid,
176 sizeof(ctx->pub_key->gid))) {
177 return kEpidBadArgErr;
178 }
179
180 // b. The verifier verifies that B in the signature and in VerifierRL
181 // match. If mismatch, go to step 7.
182 if (0 ==
183 memcmp(&ctx->verifier_rl->B, &sig->sigma0.B, sizeof(sig->sigma0.B))) {
184 size_t verifierrl_count = EpidGetVerifierRlCount(ctx->verifier_rl);
185 // c. For i = 0, ..., n4-1, the verifier verifies that K != K[i].
186 for (i = 0; i < verifierrl_count; ++i) {
187 if (0 == memcmp(&ctx->verifier_rl->K[i], &sig->sigma0.K,
188 sizeof(sig->sigma0.K))) {
189 // d. If the above step fails, the verifier aborts and output 5.
190 return kEpidSigRevokedInVerifierRl;
191 }
192 }
193 }
194 }
195
196 // Step 7. If all the above verifications succeed, the verifier outputs 0.
197 return kEpidSigValid;
198 }
199