sgx_ecc256_ecdsa.cpp 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299
  1. /*
  2. * Copyright (C) 2011-2018 Intel Corporation. All rights reserved.
  3. *
  4. * Redistribution and use in source and binary forms, with or without
  5. * modification, are permitted provided that the following conditions
  6. * are met:
  7. *
  8. * * Redistributions of source code must retain the above copyright
  9. * notice, this list of conditions and the following disclaimer.
  10. * * Redistributions in binary form must reproduce the above copyright
  11. * notice, this list of conditions and the following disclaimer in
  12. * the documentation and/or other materials provided with the
  13. * distribution.
  14. * * Neither the name of Intel Corporation nor the names of its
  15. * contributors may be used to endorse or promote products derived
  16. * from this software without specific prior written permission.
  17. *
  18. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  19. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  20. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  21. * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  22. * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  23. * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  24. * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  25. * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  26. * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  27. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  28. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  29. *
  30. */
  31. #include "sgx_ecc256_common.h"
  32. const uint32_t sgx_nistp256_r[] = {
  33. 0xFC632551, 0xF3B9CAC2, 0xA7179E84, 0xBCE6FAAD, 0xFFFFFFFF, 0xFFFFFFFF,
  34. 0x00000000, 0xFFFFFFFF };
  35. /* Computes signature for data based on private key
  36. * Parameters:
  37. * Return: sgx_status_t - SGX_SUCCESS or failure as defined sgx_error.h
  38. * Inputs: sgx_ecc_state_handle_t ecc_handle - Handle to ECC crypto system
  39. * sgx_ec256_private_t *p_private - Pointer to the private key - LITTLE ENDIAN
  40. * sgx_uint8_t *p_data - Pointer to the data to be signed
  41. * uint32_t data_size - Size of the data to be signed
  42. * Output: sgx_ec256_signature_t *p_signature - Pointer to the signature - LITTLE ENDIAN */
  43. sgx_status_t sgx_ecdsa_sign(const uint8_t *p_data,
  44. uint32_t data_size,
  45. sgx_ec256_private_t *p_private,
  46. sgx_ec256_signature_t *p_signature,
  47. sgx_ecc_state_handle_t ecc_handle)
  48. {
  49. if ((ecc_handle == NULL) || (p_private == NULL) || (p_signature == NULL) || (p_data == NULL) || (data_size < 1))
  50. {
  51. return SGX_ERROR_INVALID_PARAMETER;
  52. }
  53. IppStatus ipp_ret = ippStsNoErr;
  54. IppsECCPState* p_ecc_state = (IppsECCPState*)ecc_handle;
  55. IppsBigNumState* p_ecp_order = NULL;
  56. IppsBigNumState* p_hash_bn = NULL;
  57. IppsBigNumState* p_msg_bn = NULL;
  58. IppsBigNumState* p_eph_priv_bn = NULL;
  59. IppsECCPPointState* p_eph_pub = NULL;
  60. IppsBigNumState* p_reg_priv_bn = NULL;
  61. IppsBigNumState* p_signx_bn = NULL;
  62. IppsBigNumState* p_signy_bn = NULL;
  63. Ipp32u *p_sigx = NULL;
  64. Ipp32u *p_sigy = NULL;
  65. int ecp_size = 0;
  66. const int order_size = sizeof(sgx_nistp256_r);
  67. uint32_t hash[8] = { 0 };
  68. do
  69. {
  70. ipp_ret = sgx_ipp_newBN(sgx_nistp256_r, order_size, &p_ecp_order);
  71. ERROR_BREAK(ipp_ret);
  72. // Prepare the message used to sign.
  73. ipp_ret = ippsHashMessage(p_data, data_size, (Ipp8u*)hash, IPP_ALG_HASH_SHA256);
  74. ERROR_BREAK(ipp_ret);
  75. /* Byte swap in creation of Big Number from SHA256 hash output */
  76. ipp_ret = sgx_ipp_newBN(NULL, sizeof(hash), &p_hash_bn);
  77. ERROR_BREAK(ipp_ret);
  78. ipp_ret = ippsSetOctString_BN((Ipp8u*)hash, sizeof(hash), p_hash_bn);
  79. ERROR_BREAK(ipp_ret);
  80. ipp_ret = sgx_ipp_newBN(NULL, order_size, &p_msg_bn);
  81. ERROR_BREAK(ipp_ret);
  82. ipp_ret = ippsMod_BN(p_hash_bn, p_ecp_order, p_msg_bn);
  83. ERROR_BREAK(ipp_ret);
  84. // Get ephemeral key pair.
  85. ipp_ret = sgx_ipp_newBN(NULL, order_size, &p_eph_priv_bn);
  86. ERROR_BREAK(ipp_ret);
  87. //init eccp point
  88. ipp_ret = ippsECCPPointGetSize(256, &ecp_size);
  89. ERROR_BREAK(ipp_ret);
  90. p_eph_pub = (IppsECCPPointState*)(malloc(ecp_size));
  91. if (!p_eph_pub)
  92. {
  93. ipp_ret = ippStsNoMemErr;
  94. break;
  95. }
  96. ipp_ret = ippsECCPPointInit(256, p_eph_pub);
  97. ERROR_BREAK(ipp_ret);
  98. // Generate ephemeral key pair for signing operation
  99. // Notice that IPP ensures the private key generated is non-zero
  100. ipp_ret = ippsECCPGenKeyPair(p_eph_priv_bn, p_eph_pub, p_ecc_state,
  101. (IppBitSupplier)sgx_ipp_DRNGen, NULL);
  102. ERROR_BREAK(ipp_ret);
  103. ipp_ret = ippsECCPSetKeyPair(p_eph_priv_bn, p_eph_pub, ippFalse, p_ecc_state);
  104. ERROR_BREAK(ipp_ret);
  105. // Set the regular private key.
  106. ipp_ret = sgx_ipp_newBN((uint32_t *)p_private->r, sizeof(p_private->r),
  107. &p_reg_priv_bn);
  108. ERROR_BREAK(ipp_ret);
  109. ipp_ret = sgx_ipp_newBN(NULL, order_size, &p_signx_bn);
  110. ERROR_BREAK(ipp_ret);
  111. ipp_ret = sgx_ipp_newBN(NULL, order_size, &p_signy_bn);
  112. ERROR_BREAK(ipp_ret);
  113. // Sign the message.
  114. ipp_ret = ippsECCPSignDSA(p_msg_bn, p_reg_priv_bn, p_signx_bn, p_signy_bn,
  115. p_ecc_state);
  116. ERROR_BREAK(ipp_ret);
  117. IppsBigNumSGN sign;
  118. int length;
  119. ipp_ret = ippsRef_BN(&sign, &length,(Ipp32u**) &p_sigx, p_signx_bn);
  120. ERROR_BREAK(ipp_ret);
  121. memset(p_signature->x, 0, sizeof(p_signature->x));
  122. ipp_ret = check_copy_size(sizeof(p_signature->x), ROUND_TO(length, 8) / 8);
  123. ERROR_BREAK(ipp_ret);
  124. memcpy(p_signature->x, p_sigx, ROUND_TO(length, 8) / 8);
  125. memset_s(p_sigx, sizeof(p_signature->x), 0, ROUND_TO(length, 8) / 8);
  126. ipp_ret = ippsRef_BN(&sign, &length,(Ipp32u**) &p_sigy, p_signy_bn);
  127. ERROR_BREAK(ipp_ret);
  128. memset(p_signature->y, 0, sizeof(p_signature->y));
  129. ipp_ret = check_copy_size(sizeof(p_signature->y), ROUND_TO(length, 8) / 8);
  130. ERROR_BREAK(ipp_ret);
  131. memcpy(p_signature->y, p_sigy, ROUND_TO(length, 8) / 8);
  132. memset_s(p_sigy, sizeof(p_signature->y), 0, ROUND_TO(length, 8) / 8);
  133. } while (0);
  134. // Clear buffer before free.
  135. if (p_eph_pub)
  136. memset_s(p_eph_pub, ecp_size, 0, ecp_size);
  137. SAFE_FREE(p_eph_pub);
  138. sgx_ipp_secure_free_BN(p_ecp_order, order_size);
  139. sgx_ipp_secure_free_BN(p_hash_bn, sizeof(hash));
  140. sgx_ipp_secure_free_BN(p_msg_bn, order_size);
  141. sgx_ipp_secure_free_BN(p_eph_priv_bn, order_size);
  142. sgx_ipp_secure_free_BN(p_reg_priv_bn, sizeof(p_private->r));
  143. sgx_ipp_secure_free_BN(p_signx_bn, order_size);
  144. sgx_ipp_secure_free_BN(p_signy_bn, order_size);
  145. switch (ipp_ret)
  146. {
  147. case ippStsNoErr: return SGX_SUCCESS;
  148. case ippStsNoMemErr:
  149. case ippStsMemAllocErr: return SGX_ERROR_OUT_OF_MEMORY;
  150. case ippStsNullPtrErr:
  151. case ippStsLengthErr:
  152. case ippStsOutOfRangeErr:
  153. case ippStsSizeErr:
  154. case ippStsBadArgErr: return SGX_ERROR_INVALID_PARAMETER;
  155. default: return SGX_ERROR_UNEXPECTED;
  156. }
  157. }
  158. /* Verifies the signature for the given data based on the public key
  159. *
  160. * Parameters:
  161. * Return: sgx_status_t - SGX_SUCCESS or failure as defined sgx_error.h
  162. * Inputs: sgx_ecc_state_handle_t ecc_handle - Handle to ECC crypto system
  163. * sgx_ec256_public_t *p_public - Pointer to the public key - LITTLE ENDIAN
  164. * uint8_t *p_data - Pointer to the data to be signed
  165. * uint32_t data_size - Size of the data to be signed
  166. * sgx_ec256_signature_t *p_signature - Pointer to the signature - LITTLE ENDIAN
  167. * Output: uint8_t *p_result - Pointer to the result of verification check */
  168. sgx_status_t sgx_ecdsa_verify(const uint8_t *p_data,
  169. uint32_t data_size,
  170. const sgx_ec256_public_t *p_public,
  171. sgx_ec256_signature_t *p_signature,
  172. uint8_t *p_result,
  173. sgx_ecc_state_handle_t ecc_handle)
  174. {
  175. if ((ecc_handle == NULL) || (p_public == NULL) || (p_signature == NULL) ||
  176. (p_data == NULL) || (data_size < 1) || (p_result == NULL))
  177. {
  178. return SGX_ERROR_INVALID_PARAMETER;
  179. }
  180. IppStatus ipp_ret = ippStsNoErr;
  181. IppsECCPState* p_ecc_state = (IppsECCPState*)ecc_handle;
  182. IppECResult result = ippECInvalidSignature;
  183. *p_result = SGX_EC_INVALID_SIGNATURE;
  184. IppsBigNumState* p_ecp_order = NULL;
  185. IppsBigNumState* p_hash_bn = NULL;
  186. IppsBigNumState* p_msg_bn = NULL;
  187. IppsECCPPointState* p_reg_pub = NULL;
  188. IppsBigNumState* p_reg_pubx_bn = NULL;
  189. IppsBigNumState* p_reg_puby_bn = NULL;
  190. IppsBigNumState* p_signx_bn = NULL;
  191. IppsBigNumState* p_signy_bn = NULL;
  192. const int order_size = sizeof(sgx_nistp256_r);
  193. uint32_t hash[8] = { 0 };
  194. int ecp_size = 0;
  195. do
  196. {
  197. ipp_ret = sgx_ipp_newBN(sgx_nistp256_r, order_size, &p_ecp_order);
  198. ERROR_BREAK(ipp_ret);
  199. // Prepare the message used to sign.
  200. ipp_ret = ippsHashMessage(p_data, data_size, (Ipp8u*)hash, IPP_ALG_HASH_SHA256);
  201. ERROR_BREAK(ipp_ret);
  202. /* Byte swap in creation of Big Number from SHA256 hash output */
  203. ipp_ret = sgx_ipp_newBN(NULL, sizeof(hash), &p_hash_bn);
  204. ERROR_BREAK(ipp_ret);
  205. ipp_ret = ippsSetOctString_BN((Ipp8u*)hash, sizeof(hash), p_hash_bn);
  206. ERROR_BREAK(ipp_ret);
  207. ipp_ret = sgx_ipp_newBN(NULL, order_size, &p_msg_bn);
  208. ERROR_BREAK(ipp_ret);
  209. ipp_ret = ippsMod_BN(p_hash_bn, p_ecp_order, p_msg_bn);
  210. ERROR_BREAK(ipp_ret);
  211. //Init eccp point
  212. ipp_ret = ippsECCPPointGetSize(256, &ecp_size);
  213. ERROR_BREAK(ipp_ret);
  214. p_reg_pub = (IppsECCPPointState*)(malloc(ecp_size));
  215. if (!p_reg_pub)
  216. {
  217. ipp_ret = ippStsNoMemErr;
  218. break;
  219. }
  220. ipp_ret = ippsECCPPointInit(256, p_reg_pub);
  221. ERROR_BREAK(ipp_ret);
  222. ipp_ret = sgx_ipp_newBN((const uint32_t *)p_public->gx, sizeof(p_public->gx),
  223. &p_reg_pubx_bn);
  224. ERROR_BREAK(ipp_ret);
  225. ipp_ret = sgx_ipp_newBN((const uint32_t *)p_public->gy, sizeof(p_public->gy),
  226. &p_reg_puby_bn);
  227. ERROR_BREAK(ipp_ret);
  228. ipp_ret = ippsECCPSetPoint(p_reg_pubx_bn, p_reg_puby_bn, p_reg_pub,
  229. p_ecc_state);
  230. ERROR_BREAK(ipp_ret);
  231. ipp_ret = ippsECCPSetKeyPair(NULL, p_reg_pub, ippTrue, p_ecc_state);
  232. ERROR_BREAK(ipp_ret);
  233. ipp_ret = sgx_ipp_newBN(p_signature->x, order_size, &p_signx_bn);
  234. ERROR_BREAK(ipp_ret);
  235. ipp_ret = sgx_ipp_newBN(p_signature->y, order_size, &p_signy_bn);
  236. ERROR_BREAK(ipp_ret);
  237. // Verify the message.
  238. ipp_ret = ippsECCPVerifyDSA(p_msg_bn, p_signx_bn, p_signy_bn, &result,
  239. p_ecc_state);
  240. ERROR_BREAK(ipp_ret);
  241. } while (0);
  242. // Clear buffer before free.
  243. if (p_reg_pub)
  244. memset_s(p_reg_pub, ecp_size, 0, ecp_size);
  245. SAFE_FREE(p_reg_pub);
  246. sgx_ipp_secure_free_BN(p_ecp_order, order_size);
  247. sgx_ipp_secure_free_BN(p_hash_bn, sizeof(hash));
  248. sgx_ipp_secure_free_BN(p_msg_bn, order_size);
  249. sgx_ipp_secure_free_BN(p_reg_pubx_bn, sizeof(p_public->gx));
  250. sgx_ipp_secure_free_BN(p_reg_puby_bn, sizeof(p_public->gy));
  251. sgx_ipp_secure_free_BN(p_signx_bn, order_size);
  252. sgx_ipp_secure_free_BN(p_signy_bn, order_size);
  253. switch (result) {
  254. case ippECValid: *p_result = SGX_EC_VALID; break; /* validation pass successfully */
  255. case ippECInvalidSignature: *p_result = SGX_EC_INVALID_SIGNATURE; break; /* invalid signature */
  256. default: *p_result = SGX_EC_INVALID_SIGNATURE; break;
  257. }
  258. switch (ipp_ret)
  259. {
  260. case ippStsNoErr: return SGX_SUCCESS;
  261. case ippStsNoMemErr:
  262. case ippStsMemAllocErr: return SGX_ERROR_OUT_OF_MEMORY;
  263. case ippStsNullPtrErr:
  264. case ippStsLengthErr:
  265. case ippStsOutOfRangeErr:
  266. case ippStsSizeErr:
  267. case ippStsBadArgErr: return SGX_ERROR_INVALID_PARAMETER;
  268. default: return SGX_ERROR_UNEXPECTED;
  269. }
  270. }