nrprove.c 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293
  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. /// EpidNrProve implementation.
  17. /*! \file */
  18. #include "epid/member/src/nrprove.h"
  19. #include <stddef.h>
  20. #include <stdint.h>
  21. #include "epid/common/src/endian_convert.h"
  22. #include "epid/common/src/epid2params.h"
  23. #include "epid/common/src/hashsize.h"
  24. #include "epid/common/src/memory.h"
  25. #include "epid/common/stdtypes.h"
  26. #include "epid/common/types.h"
  27. #include "epid/member/src/context.h"
  28. #include "epid/member/src/nrprove_commitment.h"
  29. #include "epid/member/src/privateexp.h"
  30. #include "epid/member/tpm2/commit.h"
  31. #include "epid/member/tpm2/sign.h"
  32. /// Handle SDK Error with Break
  33. #define BREAK_ON_EPID_ERROR(ret) \
  34. if (kEpidNoErr != (ret)) { \
  35. break; \
  36. }
  37. /// Count of elements in array
  38. #define COUNT_OF(A) (sizeof(A) / sizeof((A)[0]))
  39. static bool IsIdentity(G1ElemStr const* elem_str) {
  40. unsigned char* bytes = (unsigned char*)elem_str;
  41. if (!bytes) {
  42. return false;
  43. } else {
  44. size_t i = 0;
  45. for (i = 0; i < sizeof(*elem_str); i++) {
  46. if (0 != bytes[i]) return false;
  47. }
  48. }
  49. return true;
  50. }
  51. EpidStatus EpidNrProve(MemberCtx const* ctx, void const* msg, size_t msg_len,
  52. void const* basename, size_t basename_len,
  53. BasicSignature const* sig, SigRlEntry const* sigrl_entry,
  54. NrProof* proof) {
  55. EpidStatus sts = kEpidErr;
  56. EcPoint* B = NULL;
  57. EcPoint* K = NULL;
  58. EcPoint* rlB = NULL;
  59. EcPoint* rlK = NULL;
  60. EcPoint* t = NULL; // temp value in G1 either T, R1, R2
  61. EcPoint* k_tpm = NULL;
  62. EcPoint* l_tpm = NULL;
  63. EcPoint* e_tpm = NULL;
  64. EcPoint* D = NULL;
  65. FfElement* y2 = NULL;
  66. uint8_t* s2 = NULL;
  67. FfElement* mu = NULL;
  68. FfElement* nu = NULL;
  69. FfElement* rmu = NULL;
  70. FfElement* t2 = NULL; // temporary for multiplication
  71. FfElement* c = NULL;
  72. uint8_t* digest = NULL;
  73. BigNumStr mu_str = {0};
  74. BigNumStr nu_str = {0};
  75. BigNumStr rmu_str = {0};
  76. if (!ctx || (0 != msg_len && !msg) || !sig || !sigrl_entry || !proof)
  77. return kEpidBadArgErr;
  78. if (!basename || 0 == basename_len) {
  79. // basename should not be empty
  80. return kEpidBadArgErr;
  81. }
  82. if (!ctx->epid2_params) return kEpidBadArgErr;
  83. do {
  84. NrProveCommitOutput commit_out = {0};
  85. FiniteField* Fp = ctx->epid2_params->Fp;
  86. FiniteField* Fq = ctx->epid2_params->Fq;
  87. EcGroup* G1 = ctx->epid2_params->G1;
  88. BitSupplier rnd_func = ctx->rnd_func;
  89. void* rnd_param = ctx->rnd_param;
  90. uint32_t i = 0;
  91. G1ElemStr B_str = {0};
  92. const BigNumStr kOne = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  93. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1};
  94. FpElemStr c_str = {0};
  95. uint16_t rnu_ctr =
  96. 0; ///< TPM counter pointing to Nr Proof related random value
  97. size_t digest_len = EpidGetHashSize(ctx->hash_alg);
  98. sts = NewEcPoint(G1, &B);
  99. BREAK_ON_EPID_ERROR(sts);
  100. sts = NewEcPoint(G1, &K);
  101. BREAK_ON_EPID_ERROR(sts);
  102. sts = NewEcPoint(G1, &rlB);
  103. BREAK_ON_EPID_ERROR(sts);
  104. sts = NewEcPoint(G1, &rlK);
  105. BREAK_ON_EPID_ERROR(sts);
  106. sts = NewEcPoint(G1, &D);
  107. BREAK_ON_EPID_ERROR(sts);
  108. sts = NewEcPoint(G1, &t);
  109. BREAK_ON_EPID_ERROR(sts);
  110. sts = NewFfElement(Fp, &y2);
  111. BREAK_ON_EPID_ERROR(sts);
  112. sts = NewEcPoint(G1, &k_tpm);
  113. BREAK_ON_EPID_ERROR(sts);
  114. sts = NewEcPoint(G1, &l_tpm);
  115. BREAK_ON_EPID_ERROR(sts);
  116. sts = NewEcPoint(G1, &e_tpm);
  117. BREAK_ON_EPID_ERROR(sts);
  118. sts = NewFfElement(Fp, &mu);
  119. BREAK_ON_EPID_ERROR(sts);
  120. sts = NewFfElement(Fp, &nu);
  121. BREAK_ON_EPID_ERROR(sts);
  122. sts = NewFfElement(Fp, &rmu);
  123. BREAK_ON_EPID_ERROR(sts);
  124. s2 = SAFE_ALLOC(basename_len + sizeof(i));
  125. if (!s2) {
  126. sts = kEpidMemAllocErr;
  127. break;
  128. }
  129. sts = ReadEcPoint(G1, &sig->K, sizeof(sig->K), K);
  130. BREAK_ON_EPID_ERROR(sts);
  131. sts = ReadEcPoint(G1, &(sigrl_entry->b), sizeof(sigrl_entry->b), rlB);
  132. BREAK_ON_EPID_ERROR(sts);
  133. sts = ReadEcPoint(G1, &(sigrl_entry->k), sizeof(sigrl_entry->k), rlK);
  134. BREAK_ON_EPID_ERROR(sts);
  135. // 1. The member chooses random mu from [1, p-1].
  136. sts = FfGetRandom(Fp, &kOne, rnd_func, rnd_param, mu);
  137. BREAK_ON_EPID_ERROR(sts);
  138. // 2. The member computes nu = -mu mod p.
  139. sts = FfNeg(Fp, mu, nu);
  140. BREAK_ON_EPID_ERROR(sts);
  141. // 3.1. The member computes D = G1.privateExp(B', f)
  142. sts = EpidPrivateExp((MemberCtx*)ctx, rlB, D);
  143. BREAK_ON_EPID_ERROR(sts);
  144. // 3.2.The member computes T = G1.sscmMultiExp(K', mu, D, nu).
  145. sts = WriteFfElement(Fp, mu, &mu_str, sizeof(mu_str));
  146. BREAK_ON_EPID_ERROR(sts);
  147. sts = WriteFfElement(Fp, nu, &nu_str, sizeof(nu_str));
  148. BREAK_ON_EPID_ERROR(sts);
  149. {
  150. EcPoint const* points[2];
  151. BigNumStr const* exponents[2];
  152. points[0] = rlK;
  153. points[1] = D;
  154. exponents[0] = &mu_str;
  155. exponents[1] = &nu_str;
  156. sts = EcSscmMultiExp(G1, points, exponents, COUNT_OF(points), t);
  157. BREAK_ON_EPID_ERROR(sts);
  158. sts = WriteEcPoint(G1, t, &commit_out.T, sizeof(commit_out.T));
  159. BREAK_ON_EPID_ERROR(sts);
  160. }
  161. // 4.1. The member chooses rmu randomly from[1, p - 1].
  162. sts = FfGetRandom(Fp, &kOne, rnd_func, rnd_param, rmu);
  163. BREAK_ON_EPID_ERROR(sts);
  164. // 4.2. (KTPM, LTPM, ETPM, counterTPM) = TPM2_Commit(P1 = B', P2 = B)
  165. sts = EcHash(G1, basename, basename_len, ctx->hash_alg, B, &i);
  166. BREAK_ON_EPID_ERROR(sts);
  167. *(uint32_t*)s2 = ntohl(i);
  168. sts = WriteEcPoint(G1, B, &B_str, sizeof(B_str));
  169. BREAK_ON_EPID_ERROR(sts);
  170. sts = ReadFfElement(Fq, &B_str.y, sizeof(B_str.y), y2);
  171. BREAK_ON_EPID_ERROR(sts);
  172. if (0 != memcpy_S(s2 + sizeof(i), basename_len, basename, basename_len)) {
  173. sts = kEpidErr;
  174. break;
  175. }
  176. sts = Tpm2Commit(ctx->tpm2_ctx, rlB, s2, basename_len + sizeof(i), y2,
  177. k_tpm, l_tpm, e_tpm, &rnu_ctr);
  178. BREAK_ON_EPID_ERROR(sts);
  179. // 5.1. The member computes R1 = G1.sscmExp(K, rmu).
  180. sts = WriteFfElement(Fp, rmu, &rmu_str, sizeof(rmu_str));
  181. BREAK_ON_EPID_ERROR(sts);
  182. sts = EcSscmExp(G1, K, &rmu_str, t);
  183. BREAK_ON_EPID_ERROR(sts);
  184. // 5.2. The member computes R1 = G1.mul(R1, LTPM).
  185. sts = EcMul(G1, t, l_tpm, t);
  186. BREAK_ON_EPID_ERROR(sts);
  187. sts = WriteEcPoint(G1, t, &commit_out.R1, sizeof(commit_out.R1));
  188. BREAK_ON_EPID_ERROR(sts);
  189. // 6.1. The member computes R2 = G1.sscmExp(K', rmu).
  190. sts = EcSscmExp(G1, rlK, &rmu_str, t);
  191. BREAK_ON_EPID_ERROR(sts);
  192. // 6.2. The member computes R2 = G1.mul(R2, ETPM).
  193. sts = EcMul(G1, t, e_tpm, t);
  194. BREAK_ON_EPID_ERROR(sts);
  195. sts = WriteEcPoint(G1, t, &commit_out.R2, sizeof(commit_out.R2));
  196. BREAK_ON_EPID_ERROR(sts);
  197. sts = HashNrProveCommitment(Fp, ctx->hash_alg, &sig->B, &sig->K,
  198. sigrl_entry, &commit_out, msg, msg_len, &c_str);
  199. BREAK_ON_EPID_ERROR(sts);
  200. digest = SAFE_ALLOC(digest_len);
  201. if (!digest) {
  202. sts = kEpidMemAllocErr;
  203. break;
  204. }
  205. sts = NewFfElement(Fp, &t2);
  206. BREAK_ON_EPID_ERROR(sts);
  207. sts = NewFfElement(Fp, &c);
  208. BREAK_ON_EPID_ERROR(sts);
  209. sts = ReadFfElement(Fp, &c_str, sizeof(c_str), c);
  210. BREAK_ON_EPID_ERROR(sts);
  211. // 8. The member computes smu = (rmu + c * mu) mod p.
  212. sts = FfMul(Fp, c, mu, t2);
  213. BREAK_ON_EPID_ERROR(sts);
  214. sts = FfAdd(Fp, rmu, t2, t2);
  215. BREAK_ON_EPID_ERROR(sts);
  216. sts = WriteFfElement(Fp, t2, &proof->smu, sizeof(proof->smu));
  217. BREAK_ON_EPID_ERROR(sts);
  218. // 9.1. The member computes c' = (c * nu) mod p
  219. sts = FfMul(Fp, c, nu, t2);
  220. BREAK_ON_EPID_ERROR(sts);
  221. // 9.2. snu = TPM2_Sign(c = c', counterTPM)
  222. sts = WriteFfElement(Fp, t2, digest, digest_len);
  223. BREAK_ON_EPID_ERROR(sts);
  224. sts = Tpm2Sign(ctx->tpm2_ctx, digest, digest_len, rnu_ctr, NULL, t2);
  225. BREAK_ON_EPID_ERROR(sts);
  226. sts = WriteFfElement(Fp, t2, &proof->snu, sizeof(proof->snu));
  227. BREAK_ON_EPID_ERROR(sts);
  228. // 10. The member outputs sigma = (T, c, smu, snu), a non-revoked
  229. // proof. If G1.is_identity(T) = true, the member also outputs
  230. // "failed".
  231. proof->T = commit_out.T;
  232. proof->c = c_str;
  233. if (IsIdentity(&proof->T)) {
  234. sts = kEpidSigRevokedInSigRl;
  235. BREAK_ON_EPID_ERROR(sts);
  236. }
  237. sts = kEpidNoErr;
  238. } while (0);
  239. SAFE_FREE(s2);
  240. EpidZeroMemory(&mu_str, sizeof(mu_str));
  241. EpidZeroMemory(&nu_str, sizeof(nu_str));
  242. EpidZeroMemory(&rmu_str, sizeof(rmu_str));
  243. DeleteFfElement(&y2);
  244. DeleteEcPoint(&B);
  245. DeleteEcPoint(&K);
  246. DeleteEcPoint(&rlB);
  247. DeleteEcPoint(&rlK);
  248. DeleteEcPoint(&D);
  249. DeleteEcPoint(&t);
  250. DeleteEcPoint(&e_tpm);
  251. DeleteEcPoint(&l_tpm);
  252. DeleteEcPoint(&k_tpm);
  253. DeleteFfElement(&mu);
  254. DeleteFfElement(&nu);
  255. DeleteFfElement(&rmu);
  256. DeleteFfElement(&t2);
  257. DeleteFfElement(&c);
  258. SAFE_FREE(digest);
  259. return sts;
  260. }