request_join.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418
  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. * \file
  18. * \brief EpidRequestJoin implementation.
  19. */
  20. #include <epid/member/api.h>
  21. #include <string.h>
  22. #include "epid/common/src/epid2params.h"
  23. #include "epid/common/math/finitefield.h"
  24. #include "epid/common/math/ecgroup.h"
  25. #pragma pack(1)
  26. /// Storage for values to create commitment in Sign and Verify algorithms
  27. typedef struct JoinPCommitValues {
  28. BigNumStr p; ///< Intel(R) EPID 2.0 parameter p
  29. G1ElemStr g1; ///< Intel(R) EPID 2.0 parameter g1
  30. G2ElemStr g2; ///< Intel(R) EPID 2.0 parameter g2
  31. G1ElemStr h1; ///< Group public key value h1
  32. G1ElemStr h2; ///< Group public key value h2
  33. G2ElemStr w; ///< Group public key value w
  34. G1ElemStr F; ///< Variable F computed in algorithm
  35. G1ElemStr R; ///< Variable R computed in algorithm
  36. IssuerNonce NI; ///< Nonce
  37. } JoinPCommitValues;
  38. #pragma pack()
  39. /// Handle SDK Error with Break
  40. #define BREAK_ON_EPID_ERROR(ret) \
  41. if (kEpidNoErr != (ret)) { \
  42. break; \
  43. }
  44. EpidStatus EpidRequestJoin(GroupPubKey const* pub_key, IssuerNonce const* ni,
  45. FpElemStr const* f, BitSupplier rnd_func,
  46. void* rnd_param, HashAlg hash_alg,
  47. JoinRequest* join_request) {
  48. EpidStatus sts;
  49. static const BigNumStr one = {
  50. {{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}}};
  51. BigNumStr r_str;
  52. JoinPCommitValues commit_values;
  53. Epid2Params_* params = NULL;
  54. FfElement* r_el = NULL;
  55. FfElement* f_el = NULL;
  56. FfElement* c_el = NULL;
  57. FfElement* cf_el = NULL;
  58. FfElement* s_el = NULL;
  59. EcPoint* f_pt = NULL;
  60. EcPoint* r_pt = NULL;
  61. EcPoint* h1_pt = NULL;
  62. if (!pub_key || !ni || !f || !rnd_func || !join_request) {
  63. return kEpidBadArgErr;
  64. }
  65. if (kSha256 != hash_alg && kSha384 != hash_alg && kSha512 != hash_alg) {
  66. return kEpidBadArgErr;
  67. }
  68. do {
  69. sts = CreateEpid2Params(&params);
  70. BREAK_ON_EPID_ERROR(sts);
  71. if (!params->Fp || !params->G1) {
  72. sts = kEpidBadArgErr;
  73. break;
  74. }
  75. sts = NewFfElement(params->Fp, &r_el);
  76. BREAK_ON_EPID_ERROR(sts);
  77. sts = NewFfElement(params->Fp, &f_el);
  78. BREAK_ON_EPID_ERROR(sts);
  79. sts = NewFfElement(params->Fp, &c_el);
  80. BREAK_ON_EPID_ERROR(sts);
  81. sts = NewFfElement(params->Fp, &cf_el);
  82. BREAK_ON_EPID_ERROR(sts);
  83. sts = NewFfElement(params->Fp, &s_el);
  84. BREAK_ON_EPID_ERROR(sts);
  85. sts = NewEcPoint(params->G1, &f_pt);
  86. BREAK_ON_EPID_ERROR(sts);
  87. sts = NewEcPoint(params->G1, &h1_pt);
  88. BREAK_ON_EPID_ERROR(sts);
  89. sts = NewEcPoint(params->G1, &r_pt);
  90. BREAK_ON_EPID_ERROR(sts);
  91. sts = ReadFfElement(params->Fp, (uint8_t const*)f, sizeof(*f), f_el);
  92. BREAK_ON_EPID_ERROR(sts);
  93. sts = ReadEcPoint(params->G1, (uint8_t*)&pub_key->h1, sizeof(pub_key->h1),
  94. h1_pt);
  95. BREAK_ON_EPID_ERROR(sts);
  96. // Step 1. The member chooses a random integer r from [1, p-1].
  97. sts = FfGetRandom(params->Fp, &one, rnd_func, rnd_param, r_el);
  98. BREAK_ON_EPID_ERROR(sts);
  99. sts = WriteFfElement(params->Fp, r_el, (uint8_t*)&r_str, sizeof(r_str));
  100. // Step 2. The member computes F = G1.sscmExp(h1, f).
  101. sts = EcExp(params->G1, h1_pt, (BigNumStr const*)f, f_pt);
  102. BREAK_ON_EPID_ERROR(sts);
  103. // Step 3. The member computes R = G1.sscmExp(h1, r).
  104. sts = EcExp(params->G1, h1_pt, (BigNumStr const*)&r_str, r_pt);
  105. BREAK_ON_EPID_ERROR(sts);
  106. // Step 4. The member computes c = Fp.hash(p || g1 || g2 || h1 || h2 || w ||
  107. // F || R || NI). Refer to Section 7.1 for hash operation over a prime
  108. // field.
  109. sts = WriteBigNum(params->p, sizeof(commit_values.p),
  110. (uint8_t*)&commit_values.p);
  111. BREAK_ON_EPID_ERROR(sts);
  112. sts = WriteEcPoint(params->G1, params->g1, (uint8_t*)&commit_values.g1,
  113. sizeof(commit_values.g1));
  114. BREAK_ON_EPID_ERROR(sts);
  115. sts = WriteEcPoint(params->G2, params->g2, (uint8_t*)&commit_values.g2,
  116. sizeof(commit_values.g2));
  117. BREAK_ON_EPID_ERROR(sts);
  118. commit_values.h1 = pub_key->h1;
  119. commit_values.h2 = pub_key->h2;
  120. commit_values.w = pub_key->w;
  121. sts = WriteEcPoint(params->G1, f_pt, (uint8_t*)&commit_values.F,
  122. sizeof(commit_values.F));
  123. BREAK_ON_EPID_ERROR(sts);
  124. sts = WriteEcPoint(params->G1, r_pt, (uint8_t*)&commit_values.R,
  125. sizeof(commit_values.R));
  126. BREAK_ON_EPID_ERROR(sts);
  127. commit_values.NI = *ni;
  128. sts = FfHash(params->Fp, (uint8_t*)&commit_values, sizeof(commit_values),
  129. hash_alg, c_el);
  130. BREAK_ON_EPID_ERROR(sts);
  131. // Step 5. The member computes s = (r + c * f) mod p.
  132. sts = FfMul(params->Fp, c_el, f_el, cf_el);
  133. BREAK_ON_EPID_ERROR(sts);
  134. sts = FfAdd(params->Fp, r_el, cf_el, s_el);
  135. BREAK_ON_EPID_ERROR(sts);
  136. // Step 6. The output join request is (F, c, s).
  137. sts = WriteFfElement(params->Fp, c_el, (uint8_t*)&join_request->c,
  138. sizeof(join_request->c));
  139. BREAK_ON_EPID_ERROR(sts);
  140. sts = WriteFfElement(params->Fp, s_el, (uint8_t*)&join_request->s,
  141. sizeof(join_request->s));
  142. BREAK_ON_EPID_ERROR(sts);
  143. sts = WriteEcPoint(params->G1, f_pt, (uint8_t*)&join_request->F,
  144. sizeof(join_request->F));
  145. BREAK_ON_EPID_ERROR(sts);
  146. sts = kEpidNoErr;
  147. } while (0);
  148. DeleteEcPoint(&h1_pt);
  149. DeleteEcPoint(&r_pt);
  150. DeleteEcPoint(&f_pt);
  151. DeleteFfElement(&s_el);
  152. DeleteFfElement(&cf_el);
  153. DeleteFfElement(&c_el);
  154. DeleteFfElement(&f_el);
  155. DeleteFfElement(&r_el);
  156. DeleteEpid2Params(&params);
  157. return sts;
  158. }
  159. // implements section 3.2.2 "Validation of Private Key" from
  160. // Intel(R) EPID 2.0 Spec
  161. bool EpidIsPrivKeyInGroup(GroupPubKey const* pub_key, PrivKey const* priv_key) {
  162. bool result;
  163. // Intel(R) EPID Parameters
  164. Epid2Params_* params = NULL;
  165. PairingState* ps = NULL;
  166. // private key
  167. EcPoint* a_pt = NULL; // an element in G1
  168. FfElement* x_el = NULL; // an integer between [1, p-1]
  169. FfElement* f_el = NULL; // an integer between [1, p-1]
  170. // public key
  171. EcPoint* h1_pt = NULL; // an element in G1
  172. EcPoint* h2_pt = NULL; // an element in G1
  173. EcPoint* w_pt = NULL; // an element in G2
  174. // local variables
  175. EcPoint* t1_pt = NULL; // an element in G2
  176. EcPoint* t2_pt = NULL; // an element in G1
  177. FfElement* t3_el = NULL; // an element in GT
  178. FfElement* t4_el = NULL; // an element in GT
  179. if (!pub_key || !priv_key) {
  180. return false;
  181. }
  182. do {
  183. EpidStatus sts;
  184. EcGroup* G1 = NULL;
  185. EcGroup* G2 = NULL;
  186. FiniteField* GT = NULL;
  187. FiniteField* Fp = NULL;
  188. BigNumStr t_str = {0};
  189. sts = CreateEpid2Params(&params);
  190. if (kEpidNoErr != sts) {
  191. result = false;
  192. break;
  193. }
  194. G1 = params->G1;
  195. G2 = params->G2;
  196. GT = params->GT;
  197. Fp = params->Fp;
  198. sts = WriteBigNum(params->t, sizeof(t_str), &t_str);
  199. if (kEpidNoErr != sts) {
  200. result = false;
  201. break;
  202. }
  203. sts = NewPairingState(G1, G2, GT, &t_str, params->neg, &ps);
  204. if (kEpidNoErr != sts) {
  205. result = false;
  206. break;
  207. }
  208. // Load private key
  209. sts = NewEcPoint(G1, &a_pt);
  210. if (kEpidNoErr != sts) {
  211. result = false;
  212. break;
  213. }
  214. sts = ReadEcPoint(G1, &priv_key->A, sizeof(priv_key->A), a_pt);
  215. if (kEpidNoErr != sts) {
  216. result = false;
  217. break;
  218. }
  219. sts = NewFfElement(Fp, &x_el);
  220. if (kEpidNoErr != sts) {
  221. result = false;
  222. break;
  223. }
  224. sts = ReadFfElement(Fp, &priv_key->x, sizeof(priv_key->x), x_el);
  225. if (kEpidNoErr != sts) {
  226. result = false;
  227. break;
  228. }
  229. sts = NewFfElement(Fp, &f_el);
  230. if (kEpidNoErr != sts) {
  231. result = false;
  232. break;
  233. }
  234. sts = ReadFfElement(Fp, &priv_key->f, sizeof(priv_key->f), f_el);
  235. if (kEpidNoErr != sts) {
  236. result = false;
  237. break;
  238. }
  239. // Load public key
  240. sts = NewEcPoint(G1, &h1_pt);
  241. if (kEpidNoErr != sts) {
  242. result = false;
  243. break;
  244. }
  245. sts = ReadEcPoint(G1, &pub_key->h1, sizeof(pub_key->h1), h1_pt);
  246. if (kEpidNoErr != sts) {
  247. result = false;
  248. break;
  249. }
  250. sts = NewEcPoint(G1, &h2_pt);
  251. if (kEpidNoErr != sts) {
  252. result = false;
  253. break;
  254. }
  255. sts = ReadEcPoint(G1, &pub_key->h2, sizeof(pub_key->h2), h2_pt);
  256. if (kEpidNoErr != sts) {
  257. result = false;
  258. break;
  259. }
  260. sts = NewEcPoint(G2, &w_pt);
  261. if (kEpidNoErr != sts) {
  262. result = false;
  263. break;
  264. }
  265. sts = ReadEcPoint(G2, &pub_key->w, sizeof(pub_key->w), w_pt);
  266. if (kEpidNoErr != sts) {
  267. result = false;
  268. break;
  269. }
  270. // local variables
  271. sts = NewEcPoint(G2, &t1_pt);
  272. if (kEpidNoErr != sts) {
  273. result = false;
  274. break;
  275. }
  276. sts = NewEcPoint(G1, &t2_pt);
  277. if (kEpidNoErr != sts) {
  278. result = false;
  279. break;
  280. }
  281. sts = NewFfElement(GT, &t3_el);
  282. if (kEpidNoErr != sts) {
  283. result = false;
  284. break;
  285. }
  286. sts = NewFfElement(GT, &t4_el);
  287. if (kEpidNoErr != sts) {
  288. result = false;
  289. break;
  290. }
  291. // Step 1. The member verifies that the gid in the public key matches the
  292. // gid in the private key.
  293. if (0 != memcmp(&pub_key->gid, &priv_key->gid, sizeof(priv_key->gid))) {
  294. result = false;
  295. break;
  296. }
  297. // Step 2. The member computes t1 = G2.sscmExp(g2, x).
  298. sts = EcSscmExp(G2, params->g2, (BigNumStr const*)&priv_key->x, t1_pt);
  299. if (kEpidNoErr != sts) {
  300. result = false;
  301. break;
  302. }
  303. // Step 3. The member computes t1 = G2.mul(t1, w).
  304. sts = EcMul(G2, t1_pt, w_pt, t1_pt);
  305. if (kEpidNoErr != sts) {
  306. result = false;
  307. break;
  308. }
  309. // Step 4. The member computes t3 = pairing(A, t1).
  310. sts = Pairing(ps, t3_el, a_pt, t1_pt);
  311. if (kEpidNoErr != sts) {
  312. result = false;
  313. break;
  314. }
  315. // Step 5. The member computes t2 = G1.sscmExp(h1, f).
  316. sts = EcSscmExp(G1, h1_pt, (BigNumStr const*)&priv_key->f, t2_pt);
  317. if (kEpidNoErr != sts) {
  318. result = false;
  319. break;
  320. }
  321. // Step 6. The member computes t2 = G1.mul(t2, g1).
  322. sts = EcMul(G1, t2_pt, params->g1, t2_pt);
  323. if (kEpidNoErr != sts) {
  324. result = false;
  325. break;
  326. }
  327. // Step 7. The member computes t4 = pairing(t2, g2).
  328. sts = WriteBigNum(params->t, sizeof(t_str), &t_str);
  329. if (kEpidNoErr != sts) {
  330. result = false;
  331. break;
  332. }
  333. sts = Pairing(ps, t4_el, t2_pt, params->g2);
  334. if (kEpidNoErr != sts) {
  335. result = false;
  336. break;
  337. }
  338. // Step 8. If GT.isEqual(t3, t4) = false, reports bad private key.
  339. sts = FfIsEqual(GT, t3_el, t4_el, &result);
  340. if (kEpidNoErr != sts) {
  341. result = false;
  342. break;
  343. }
  344. } while (0);
  345. // local variables
  346. DeleteFfElement(&t4_el);
  347. DeleteFfElement(&t3_el);
  348. DeleteEcPoint(&t2_pt);
  349. DeleteEcPoint(&t1_pt);
  350. // public key
  351. DeleteEcPoint(&w_pt);
  352. DeleteEcPoint(&h2_pt);
  353. DeleteEcPoint(&h1_pt);
  354. // private key
  355. DeleteFfElement(&f_el);
  356. DeleteFfElement(&x_el);
  357. DeleteEcPoint(&a_pt);
  358. // Intel(R) EPID Parameters
  359. DeletePairingState(&ps);
  360. DeleteEpid2Params(&params);
  361. return result;
  362. }