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 32 static size_t EpidGetSignatureRlCount(EpidSignature const* sig) { 33 if (!sig) 34 return 0; 35 else 36 return ntohl(sig->n2); 37 } 38 39 static size_t EpidGetGroupRlCount(GroupRl const* rl) { 40 if (!rl) 41 return 0; 42 else 43 return ntohl(rl->n3); 44 } 45 46 static size_t EpidGetPrivRlCount(PrivRl const* rl) { 47 if (!rl) 48 return 0; 49 else 50 return ntohl(rl->n1); 51 } 52 53 static size_t EpidGetSigRlCount(SigRl const* rl) { 54 if (!rl) 55 return 0; 56 else 57 return ntohl(rl->n2); 58 } 59 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 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