presig.c 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295
  1. /*############################################################################
  2. # Copyright 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. /// Sensitive pre-computed signature implementation
  17. /*! \file */
  18. #include <epid/member/api.h>
  19. #include <string.h>
  20. #include "epid/common/math/ecgroup.h"
  21. #include "epid/common/math/finitefield.h"
  22. #include "epid/common/src/endian_convert.h"
  23. #include "epid/common/src/epid2params.h"
  24. #include "epid/common/src/memory.h"
  25. #include "epid/common/src/stack.h"
  26. #include "epid/member/src/context.h"
  27. #include "epid/member/tpm2/commit.h"
  28. #include "epid/member/tpm2/context.h"
  29. #include "epid/member/tpm2/getrandom.h"
  30. #include "epid/member/tpm2/sign.h"
  31. /// Handle SDK Error with Break
  32. #define BREAK_ON_EPID_ERROR(ret) \
  33. if (kEpidNoErr != (ret)) { \
  34. break; \
  35. }
  36. /// Count of elements in array
  37. #define COUNT_OF(A) (sizeof(A) / sizeof((A)[0]))
  38. static EpidStatus MemberComputePreSig(MemberCtx const* ctx,
  39. PreComputedSignature* precompsig);
  40. EpidStatus EpidAddPreSigs(MemberCtx* ctx, size_t number_presigs) {
  41. PreComputedSignature* new_presigs = NULL;
  42. size_t i = 0;
  43. if (!ctx || !ctx->presigs) return kEpidBadArgErr;
  44. if (0 == number_presigs) return kEpidNoErr;
  45. new_presigs =
  46. (PreComputedSignature*)StackPushN(ctx->presigs, number_presigs, NULL);
  47. if (!new_presigs) return kEpidMemAllocErr;
  48. for (i = 0; i < number_presigs; i++) {
  49. EpidStatus sts = MemberComputePreSig(ctx, &new_presigs[i]);
  50. if (kEpidNoErr != sts) {
  51. // roll back pre-computed-signature pool
  52. StackPopN(ctx->presigs, number_presigs, 0);
  53. return sts;
  54. }
  55. }
  56. return kEpidNoErr;
  57. }
  58. size_t EpidGetNumPreSigs(MemberCtx const* ctx) {
  59. return (ctx && ctx->presigs) ? StackGetSize(ctx->presigs) : (size_t)0;
  60. }
  61. EpidStatus MemberGetPreSig(MemberCtx* ctx, PreComputedSignature* presig) {
  62. if (!ctx || !presig) {
  63. return kEpidBadArgErr;
  64. }
  65. if (StackGetSize(ctx->presigs)) {
  66. // Use existing pre-computed signature
  67. if (!StackPopN(ctx->presigs, 1, presig)) {
  68. return kEpidErr;
  69. }
  70. return kEpidNoErr;
  71. }
  72. // generate a new pre-computed signature
  73. return MemberComputePreSig(ctx, presig);
  74. }
  75. /// Performs Pre-computation that can be used to speed up signing
  76. EpidStatus MemberComputePreSig(MemberCtx const* ctx,
  77. PreComputedSignature* precompsig) {
  78. EpidStatus sts = kEpidErr;
  79. EcPoint* B = NULL;
  80. EcPoint* k = NULL;
  81. EcPoint* t = NULL; // temporary, used for K, T, R1
  82. EcPoint* e = NULL;
  83. FfElement* R2 = NULL;
  84. FfElement* a = NULL;
  85. FfElement* rx = NULL; // reused for rf
  86. FfElement* rb = NULL; // reused for ra
  87. FfElement* t1 = NULL;
  88. FfElement* t2 = NULL;
  89. BigNumStr t1_str = {0};
  90. BigNumStr t2_str = {0};
  91. struct {
  92. uint32_t i;
  93. BigNumStr bsn;
  94. } p2x = {0};
  95. FfElement* p2y = NULL;
  96. if (!ctx || !precompsig || !ctx->epid2_params) {
  97. return kEpidBadArgErr;
  98. }
  99. do {
  100. // handy shorthands:
  101. Tpm2Ctx* tpm = ctx->tpm2_ctx;
  102. EcGroup* G1 = ctx->epid2_params->G1;
  103. FiniteField* GT = ctx->epid2_params->GT;
  104. FiniteField* Fp = ctx->epid2_params->Fp;
  105. FiniteField* Fq = ctx->epid2_params->Fq;
  106. EcPoint const* h2 = ctx->h2;
  107. EcPoint const* A = ctx->A;
  108. FfElement const* x = ctx->x;
  109. PairingState* ps_ctx = ctx->epid2_params->pairing_state;
  110. const BigNumStr kOne = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  111. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1};
  112. // 1. The member expects the pre-computation is done (e12, e22, e2w,
  113. // ea2). Refer to Section 3.5 for the computation of these
  114. // values.
  115. sts = NewFfElement(Fq, &p2y);
  116. // The following variables B, K, T, R1 (elements of G1), R2
  117. // (elements of GT), a, b, rx, rf, ra, rb, t1, t2 (256-bit
  118. // integers) are used.
  119. BREAK_ON_EPID_ERROR(sts);
  120. sts = NewEcPoint(G1, &B);
  121. BREAK_ON_EPID_ERROR(sts);
  122. sts = NewEcPoint(G1, &k);
  123. BREAK_ON_EPID_ERROR(sts);
  124. sts = NewEcPoint(G1, &t);
  125. BREAK_ON_EPID_ERROR(sts);
  126. sts = NewEcPoint(G1, &e);
  127. BREAK_ON_EPID_ERROR(sts);
  128. sts = NewFfElement(GT, &R2);
  129. BREAK_ON_EPID_ERROR(sts);
  130. sts = NewFfElement(Fp, &a);
  131. BREAK_ON_EPID_ERROR(sts);
  132. sts = NewFfElement(Fp, &rx);
  133. BREAK_ON_EPID_ERROR(sts);
  134. sts = NewFfElement(Fp, &rb);
  135. BREAK_ON_EPID_ERROR(sts);
  136. sts = NewFfElement(Fp, &t1);
  137. BREAK_ON_EPID_ERROR(sts);
  138. sts = NewFfElement(Fp, &t2);
  139. BREAK_ON_EPID_ERROR(sts);
  140. // 3. The member computes B = G1.getRandom().
  141. // 4.a. If bsn is not provided, the member chooses randomly an integer bsn
  142. // from [1, p-1].
  143. sts = Tpm2GetRandom(tpm, sizeof(p2x.bsn) * 8, &p2x.bsn);
  144. BREAK_ON_EPID_ERROR(sts);
  145. precompsig->rnd_bsn = p2x.bsn;
  146. // 4.b. The member computes (B, i2, y2) = G1.tpmHash(bsn).
  147. sts = EcHash(G1, (const void*)&p2x.bsn, sizeof(p2x.bsn), ctx->hash_alg, B,
  148. &p2x.i);
  149. BREAK_ON_EPID_ERROR(sts);
  150. p2x.i = htonl(p2x.i);
  151. sts = WriteEcPoint(G1, B, &precompsig->B, sizeof(precompsig->B));
  152. BREAK_ON_EPID_ERROR(sts);
  153. sts = ReadFfElement(Fq, &precompsig->B.y, sizeof(precompsig->B.y), p2y);
  154. BREAK_ON_EPID_ERROR(sts);
  155. // 4.c. (KTPM, LTPM, ETPM, counterTPM) = TPM2_Commit(P1=h1, (s2, y2) = (i1
  156. // || bsn, y2)), K = KTPM
  157. sts = Tpm2Commit(tpm, ctx->h1, &p2x, sizeof(p2x), p2y, k, t, e,
  158. &precompsig->rf_ctr);
  159. BREAK_ON_EPID_ERROR(sts);
  160. sts = WriteEcPoint(G1, k, &precompsig->K, sizeof(precompsig->K));
  161. BREAK_ON_EPID_ERROR(sts);
  162. // 4.k. The member computes R1 = LTPM.
  163. sts = WriteEcPoint(G1, t, &precompsig->R1, sizeof(precompsig->R1));
  164. BREAK_ON_EPID_ERROR(sts);
  165. // 4.d. The member chooses randomly an integer a from [1, p-1].
  166. sts = FfGetRandom(Fp, &kOne, ctx->rnd_func, ctx->rnd_param, a);
  167. BREAK_ON_EPID_ERROR(sts);
  168. sts = WriteFfElement(Fp, a, &precompsig->a, sizeof(precompsig->a));
  169. BREAK_ON_EPID_ERROR(sts);
  170. // 4.e. The member computes T = G1.sscmExp(h2, a).
  171. sts = EcExp(G1, h2, (BigNumStr*)&precompsig->a, t);
  172. BREAK_ON_EPID_ERROR(sts);
  173. // 4.k. The member computes T = G1.mul(T, A).
  174. sts = EcMul(G1, t, A, t);
  175. BREAK_ON_EPID_ERROR(sts);
  176. sts = WriteEcPoint(G1, t, &precompsig->T, sizeof(precompsig->T));
  177. BREAK_ON_EPID_ERROR(sts);
  178. // 4.h. The member chooses rx, ra, rb randomly from [1, p-1].
  179. // note : rb are reused as ra
  180. sts = FfGetRandom(Fp, &kOne, ctx->rnd_func, ctx->rnd_param, rx);
  181. BREAK_ON_EPID_ERROR(sts);
  182. sts = FfGetRandom(Fp, &kOne, ctx->rnd_func, ctx->rnd_param, rb);
  183. BREAK_ON_EPID_ERROR(sts);
  184. sts = WriteFfElement(Fp, rx, &precompsig->rx, sizeof(precompsig->rx));
  185. BREAK_ON_EPID_ERROR(sts);
  186. sts = WriteFfElement(Fp, rb, &precompsig->rb, sizeof(precompsig->rb));
  187. BREAK_ON_EPID_ERROR(sts);
  188. // 4.i. The member computes t1 = (- rx) mod p.
  189. sts = FfNeg(Fp, rx, t1);
  190. BREAK_ON_EPID_ERROR(sts);
  191. // 4.j. The member computes t2 = (rb - a * rx) mod p.
  192. sts = FfMul(Fp, a, rx, t2);
  193. BREAK_ON_EPID_ERROR(sts);
  194. sts = FfNeg(Fp, t2, t2);
  195. BREAK_ON_EPID_ERROR(sts);
  196. sts = FfAdd(Fp, rb, t2, t2);
  197. BREAK_ON_EPID_ERROR(sts);
  198. // 4.g. The member computes b = (a * x) mod p.
  199. sts = FfMul(Fp, a, x, a);
  200. BREAK_ON_EPID_ERROR(sts);
  201. sts = WriteFfElement(Fp, a, &precompsig->b, sizeof(precompsig->b));
  202. BREAK_ON_EPID_ERROR(sts);
  203. // reusing rb as ra
  204. sts = FfGetRandom(Fp, &kOne, ctx->rnd_func, ctx->rnd_param, rb);
  205. BREAK_ON_EPID_ERROR(sts);
  206. sts = WriteFfElement(Fp, rb, &precompsig->ra, sizeof(precompsig->ra));
  207. BREAK_ON_EPID_ERROR(sts);
  208. // 4.l.i e12rf = pairing(ETPM, g2)
  209. sts = Pairing(ps_ctx, e, ctx->epid2_params->g2, R2);
  210. BREAK_ON_EPID_ERROR(sts);
  211. // 4.l.ii. The member computes R2 = GT.sscmMultiExp(ea2, t1, e12rf, 1,
  212. // e22, t2, e2w, ra).
  213. sts = WriteFfElement(Fp, t1, &t1_str, sizeof(t1_str));
  214. BREAK_ON_EPID_ERROR(sts);
  215. sts = WriteFfElement(Fp, t2, &t2_str, sizeof(t2_str));
  216. BREAK_ON_EPID_ERROR(sts);
  217. {
  218. FfElement const* points[4];
  219. BigNumStr const* exponents[4];
  220. points[0] = ctx->ea2;
  221. points[1] = R2;
  222. points[2] = ctx->e22;
  223. points[3] = ctx->e2w;
  224. exponents[0] = &t1_str;
  225. exponents[1] = &kOne;
  226. exponents[2] = &t2_str;
  227. exponents[3] = (BigNumStr*)&precompsig->ra;
  228. sts = FfMultiExp(GT, points, exponents, COUNT_OF(points), R2);
  229. BREAK_ON_EPID_ERROR(sts);
  230. }
  231. sts = WriteFfElement(GT, R2, &precompsig->R2, sizeof(precompsig->R2));
  232. BREAK_ON_EPID_ERROR(sts);
  233. sts = kEpidNoErr;
  234. } while (0);
  235. if (sts != kEpidNoErr) {
  236. (void)Tpm2ReleaseCounter(ctx->tpm2_ctx, precompsig->rf_ctr);
  237. }
  238. EpidZeroMemory(&t1_str, sizeof(t1_str));
  239. EpidZeroMemory(&t2_str, sizeof(t2_str));
  240. EpidZeroMemory(&p2x, sizeof(p2x));
  241. DeleteFfElement(&p2y);
  242. DeleteEcPoint(&B);
  243. DeleteEcPoint(&k);
  244. DeleteEcPoint(&t);
  245. DeleteEcPoint(&e);
  246. DeleteFfElement(&R2);
  247. DeleteFfElement(&a);
  248. DeleteFfElement(&rx);
  249. DeleteFfElement(&rb);
  250. DeleteFfElement(&t1);
  251. DeleteFfElement(&t2);
  252. return sts;
  253. }