decompress_privkey.c 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295
  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 EpidDecompressPrivKey implementation.
  19. */
  20. #include "epid/member/api.h"
  21. #include "epid/common/src/memory.h"
  22. #include "epid/common/src/epid2params.h"
  23. #include "epid/common/math/src/bignum-internal.h"
  24. #include "epid/common/math/hash.h"
  25. #include "epid/member/src/privkey.h"
  26. /// Handle Intel(R) EPID Error with Break
  27. #define BREAK_ON_EPID_ERROR(ret) \
  28. if (kEpidNoErr != (ret)) { \
  29. break; \
  30. }
  31. /// Implements the derivation method used by private key decompression
  32. /// Derives two integers x, f between [1, p-1] from the seed value
  33. static EpidStatus DeriveXF(FpElemStr* x, FpElemStr* f, Seed const* seed,
  34. FpElemStr const* p);
  35. EpidStatus EpidDecompressPrivKey(GroupPubKey const* pub_key,
  36. CompressedPrivKey const* compressed_privkey,
  37. PrivKey* priv_key) {
  38. EpidStatus result = kEpidErr;
  39. Epid2Params_* epid2_params = 0;
  40. PrivKey_ priv_key_ = {{{0}}, 0, 0, 0};
  41. FfElement* Ax = 0;
  42. EcPoint* t1 = 0;
  43. EcPoint* t2 = 0;
  44. FfElement* t3 = 0;
  45. FfElement* t4 = 0;
  46. BigNum* bn_pminus1 = 0;
  47. BigNum* bn_one = 0;
  48. EcPoint* h1 = 0;
  49. EcPoint* w = 0;
  50. // check parameters
  51. if (!pub_key || !compressed_privkey || !priv_key) {
  52. return kEpidBadArgErr;
  53. }
  54. // Internal representation of Epid2Params
  55. result = CreateEpid2Params(&epid2_params);
  56. if (kEpidNoErr != result) {
  57. return result;
  58. }
  59. do {
  60. uint8_t bn_one_str = 1;
  61. FpElemStr p_str = {0};
  62. bool is_valid = false;
  63. // shortcuts
  64. EcGroup* G1 = epid2_params->G1;
  65. EcGroup* G2 = epid2_params->G2;
  66. FiniteField* GT = epid2_params->GT;
  67. EcPoint* g1 = epid2_params->g1;
  68. EcPoint* g2 = epid2_params->g2;
  69. PairingState* ps_ctx = epid2_params->pairing_state;
  70. FiniteField* Fp = epid2_params->Fp;
  71. FiniteField* Fq = epid2_params->Fq;
  72. BigNum* p = epid2_params->p;
  73. // In the following process, temporary variables t1 (an element of
  74. // G2), t2 (an element of G1), t3, t4 (elements of GT) are used.
  75. // Let the compressed private key be (gid, A.x, seed). Let the
  76. // Intel(R) EPID public key be (gid, h1, h2, w).
  77. // Create a new Priv Key
  78. result = NewEcPoint(G1, &priv_key_.A);
  79. BREAK_ON_EPID_ERROR(result);
  80. result = NewFfElement(Fp, &priv_key_.x);
  81. BREAK_ON_EPID_ERROR(result);
  82. result = NewFfElement(Fp, &priv_key_.f);
  83. BREAK_ON_EPID_ERROR(result);
  84. result = NewFfElement(Fq, &Ax);
  85. BREAK_ON_EPID_ERROR(result);
  86. result = NewEcPoint(G2, &t1);
  87. BREAK_ON_EPID_ERROR(result);
  88. result = NewEcPoint(G1, &t2);
  89. BREAK_ON_EPID_ERROR(result);
  90. result = NewFfElement(GT, &t3);
  91. BREAK_ON_EPID_ERROR(result);
  92. result = NewFfElement(GT, &t4);
  93. BREAK_ON_EPID_ERROR(result);
  94. result = NewBigNum(sizeof(BigNumStr), &bn_pminus1);
  95. BREAK_ON_EPID_ERROR(result);
  96. result = NewBigNum(sizeof(bn_one_str), &bn_one);
  97. BREAK_ON_EPID_ERROR(result);
  98. result = NewEcPoint(G1, &h1);
  99. BREAK_ON_EPID_ERROR(result);
  100. result = ReadEcPoint(G1, &(pub_key->h1), sizeof(pub_key->h1), h1);
  101. BREAK_ON_EPID_ERROR(result);
  102. result = NewEcPoint(G2, &w);
  103. BREAK_ON_EPID_ERROR(result);
  104. result = ReadEcPoint(G2, &(pub_key->w), sizeof(pub_key->w), w);
  105. BREAK_ON_EPID_ERROR(result);
  106. result = WriteBigNum(p, sizeof(p_str), &p_str);
  107. BREAK_ON_EPID_ERROR(result);
  108. result = ReadBigNum(&bn_one_str, sizeof(bn_one_str), bn_one);
  109. BREAK_ON_EPID_ERROR(result);
  110. // 1. The member derives x and f from seed. The derivation
  111. // function must be the same as the one used in the key
  112. // generation above. This step is out of scope of this
  113. // specification.
  114. result =
  115. DeriveXF(&priv_key->x, &priv_key->f, &compressed_privkey->seed, &p_str);
  116. BREAK_ON_EPID_ERROR(result);
  117. // 2. The member computes A = G1.makePoint(A.x).
  118. result = ReadFfElement(Fq, &compressed_privkey->ax,
  119. sizeof(compressed_privkey->ax), Ax);
  120. BREAK_ON_EPID_ERROR(result);
  121. result = EcMakePoint(G1, Ax, priv_key_.A);
  122. BREAK_ON_EPID_ERROR(result);
  123. // 3. The member tests whether (A, x, f) is a valid Intel(R) EPID
  124. // private key as follows:
  125. // a. It computes t1 = G2.sscmExp(g2, x).
  126. result = EcSscmExp(G2, g2, (BigNumStr const*)&priv_key->x, t1);
  127. BREAK_ON_EPID_ERROR(result);
  128. // b. It computes t1 = G2.mul(t1, w).
  129. result = EcMul(G2, t1, w, t1);
  130. BREAK_ON_EPID_ERROR(result);
  131. // c. It computes t3 = pairing(A, t1).
  132. result = Pairing(ps_ctx, t3, priv_key_.A, t1);
  133. BREAK_ON_EPID_ERROR(result);
  134. // d. It computes t2 = G1.sscmExp(h1, f).
  135. result = EcSscmExp(G1, h1, (BigNumStr const*)&priv_key->f, t2);
  136. BREAK_ON_EPID_ERROR(result);
  137. // e. It computes t2 = G1.mul(t2, g1).
  138. result = EcMul(G1, t2, g1, t2);
  139. BREAK_ON_EPID_ERROR(result);
  140. // f. It computes t4 = pairing(t2, g2).
  141. result = Pairing(ps_ctx, t4, t2, g2);
  142. BREAK_ON_EPID_ERROR(result);
  143. // g. If GT.isEqual(t3, t4) = false
  144. result = FfIsEqual(GT, t3, t4, &is_valid);
  145. BREAK_ON_EPID_ERROR(result);
  146. if (!is_valid) {
  147. // i. It computes t3 = GT.exp(t3, p-1).
  148. result = BigNumSub(p, bn_one, bn_pminus1);
  149. BREAK_ON_EPID_ERROR(result);
  150. result = FfExp(GT, t3, bn_pminus1, t3);
  151. BREAK_ON_EPID_ERROR(result);
  152. // ii. If GT.isEqual(t3, t4) = false again, it reports bad
  153. // Intel(R) EPID private key and exits.
  154. result = FfIsEqual(GT, t3, t4, &is_valid);
  155. BREAK_ON_EPID_ERROR(result);
  156. if (!is_valid) {
  157. result = kEpidBadArgErr; // Invalid Member key
  158. break;
  159. }
  160. // iii. It sets A = G1.inverse(A).
  161. result = EcInverse(G1, priv_key_.A, priv_key_.A);
  162. BREAK_ON_EPID_ERROR(result);
  163. // NOTE A is modified here in this step.
  164. }
  165. // 4. The decompressed Intel(R) EPID private key is (gid, A, x, f).
  166. // x, f already filled in.
  167. priv_key->gid = pub_key->gid;
  168. result = WriteEcPoint(G1, priv_key_.A, &priv_key->A, sizeof(priv_key->A));
  169. BREAK_ON_EPID_ERROR(result);
  170. result = kEpidNoErr;
  171. } while (0);
  172. DeleteEcPoint(&priv_key_.A);
  173. DeleteFfElement(&priv_key_.x);
  174. DeleteFfElement(&priv_key_.f);
  175. DeleteFfElement(&Ax);
  176. DeleteEcPoint(&t1);
  177. DeleteEcPoint(&t2);
  178. DeleteFfElement(&t3);
  179. DeleteFfElement(&t4);
  180. DeleteBigNum(&bn_pminus1);
  181. DeleteBigNum(&bn_one);
  182. DeleteEcPoint(&h1);
  183. DeleteEcPoint(&w);
  184. DeleteEpid2Params(&epid2_params);
  185. return result;
  186. }
  187. /// Hash message buffer
  188. typedef struct HashMsg {
  189. /// Message to be hashed
  190. char data[11];
  191. } HashMsg;
  192. static EpidStatus DeriveXF(FpElemStr* x, FpElemStr* f, Seed const* seed,
  193. FpElemStr const* p) {
  194. EpidStatus result = kEpidErr;
  195. BigNum* bn_x = 0;
  196. BigNum* bn_f = 0;
  197. BigNum* bn_p = 0;
  198. do {
  199. HashMsg msgstr = {{
  200. 0x00, 0x45, 0x43, 0x43, 0x2d, 0x53, 0x61, 0x66, 0x65, 0x49, 0x44,
  201. }};
  202. #pragma pack(1)
  203. struct {
  204. Seed seed;
  205. HashMsg msg;
  206. } hashbuf;
  207. #pragma pack()
  208. Sha256Digest digest[2];
  209. Ipp8u str512[512 / 8];
  210. result = NewBigNum(sizeof(*p), &bn_p);
  211. BREAK_ON_EPID_ERROR(result);
  212. result = ReadBigNum(p, sizeof(*p), bn_p);
  213. BREAK_ON_EPID_ERROR(result);
  214. result = NewBigNum(sizeof(digest), &bn_x);
  215. BREAK_ON_EPID_ERROR(result);
  216. result = NewBigNum(sizeof(digest), &bn_f);
  217. BREAK_ON_EPID_ERROR(result);
  218. // compute x
  219. hashbuf.seed = *seed;
  220. hashbuf.msg = msgstr;
  221. hashbuf.msg.data[0] = 0x06;
  222. result = Sha256MessageDigest(&hashbuf, sizeof(hashbuf), &digest[0]);
  223. BREAK_ON_EPID_ERROR(result);
  224. hashbuf.msg.data[0] = 0x07;
  225. result = Sha256MessageDigest(&hashbuf, sizeof(hashbuf), &digest[1]);
  226. BREAK_ON_EPID_ERROR(result);
  227. result = ReadBigNum(&digest, sizeof(digest), bn_x);
  228. BREAK_ON_EPID_ERROR(result);
  229. result = BigNumMod(bn_x, bn_p, bn_x);
  230. BREAK_ON_EPID_ERROR(result);
  231. result = WriteBigNum(bn_x, sizeof(str512), str512);
  232. BREAK_ON_EPID_ERROR(result);
  233. *x = *(FpElemStr*)&str512[sizeof(str512) / 2];
  234. // compute f
  235. hashbuf.seed = *seed;
  236. hashbuf.msg = msgstr;
  237. hashbuf.msg.data[0] = 0x08;
  238. result = Sha256MessageDigest(&hashbuf, sizeof(hashbuf), &digest[0]);
  239. BREAK_ON_EPID_ERROR(result);
  240. hashbuf.msg.data[0] = 0x09;
  241. result = Sha256MessageDigest(&hashbuf, sizeof(hashbuf), &digest[1]);
  242. BREAK_ON_EPID_ERROR(result);
  243. result = ReadBigNum(&digest, sizeof(digest), bn_f);
  244. BREAK_ON_EPID_ERROR(result);
  245. result = BigNumMod(bn_f, bn_p, bn_f);
  246. BREAK_ON_EPID_ERROR(result);
  247. result = WriteBigNum(bn_f, sizeof(str512), str512);
  248. BREAK_ON_EPID_ERROR(result);
  249. *f = *(FpElemStr*)&str512[sizeof(str512) / 2];
  250. result = kEpidNoErr;
  251. } while (0);
  252. DeleteBigNum(&bn_x);
  253. DeleteBigNum(&bn_f);
  254. DeleteBigNum(&bn_p);
  255. return result;
  256. }