se_ecdsa_verify_internal.cpp 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281
  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 "stdlib.h"
  32. #include "string.h"
  33. #include "ipp_wrapper.h"
  34. #include "se_ecdsa_verify_internal.h"
  35. #if !defined(SWAP_ENDIAN_DW)
  36. #define SWAP_ENDIAN_DW(dw) ((((dw) & 0x000000ff) << 24) \
  37. | (((dw) & 0x0000ff00) << 8) \
  38. | (((dw) & 0x00ff0000) >> 8) \
  39. | (((dw) & 0xff000000) >> 24))
  40. #endif
  41. // LE<->BE translation of 32 byte big number
  42. #if !defined(SWAP_ENDIAN_32B)
  43. #define SWAP_ENDIAN_32B(ptr) \
  44. { \
  45. unsigned int temp = 0; \
  46. temp = SWAP_ENDIAN_DW(((unsigned int*)(ptr))[0]); \
  47. ((unsigned int*)(ptr))[0] = SWAP_ENDIAN_DW(((unsigned int*)(ptr))[7]); \
  48. ((unsigned int*)(ptr))[7] = temp; \
  49. temp = SWAP_ENDIAN_DW(((unsigned int*)(ptr))[1]); \
  50. ((unsigned int*)(ptr))[1] = SWAP_ENDIAN_DW(((unsigned int*)(ptr))[6]); \
  51. ((unsigned int*)(ptr))[6] = temp; \
  52. temp = SWAP_ENDIAN_DW(((unsigned int*)(ptr))[2]); \
  53. ((unsigned int*)(ptr))[2] = SWAP_ENDIAN_DW(((unsigned int*)(ptr))[5]); \
  54. ((unsigned int*)(ptr))[5] = temp; \
  55. temp = SWAP_ENDIAN_DW(((unsigned int*)(ptr))[3]); \
  56. ((unsigned int*)(ptr))[3] = SWAP_ENDIAN_DW(((unsigned int*)(ptr))[4]); \
  57. ((unsigned int*)(ptr))[4] = temp; \
  58. }
  59. #endif
  60. #if !defined(ntohs)
  61. #define ntohs(u16) \
  62. ((uint16_t)(((((unsigned char*)&(u16))[0]) << 8) \
  63. + (((unsigned char*)&(u16))[1])))
  64. #endif
  65. static const uint32_t g_nistp256_r[] = {
  66. 0xFC632551, 0xF3B9CAC2, 0xA7179E84, 0xBCE6FAAD, 0xFFFFFFFF, 0xFFFFFFFF,
  67. 0x00000000, 0xFFFFFFFF};
  68. /*
  69. * An utility function used to verify ecc signature.
  70. *
  71. * @param p_ecp Pointer to ecc context.
  72. * @param p_pubkey The ecc public key.
  73. * @param p_signature The signature, in little endian
  74. * @param p_sig_rl_hash Output from sgx_sha256_get_hash
  75. * @param p_result Verify result
  76. * @return sgx_status_t Return SGX_SUCCESS if p_result is valid. Need to check
  77. * the p_result for detailed result. ippECValid means signature match.
  78. * ippECInvalidSignature means the input signature is invalid.
  79. */
  80. sgx_status_t se_ecdsa_verify_internal(
  81. IppsECCPState *p_ecp,
  82. sgx_ec256_public_t *p_pubkey,
  83. sgx_ec256_signature_t *p_signature,
  84. const se_ae_ecdsa_hash_t *p_sig_rl_hash,
  85. IppECResult *p_result)
  86. {
  87. sgx_status_t ret = SGX_SUCCESS;
  88. IppStatus ipp_ret = ippStsNoErr;
  89. Ipp32u cmpZeroResult = 0;
  90. IppsBigNumState* p_bn_ecp_order = NULL;
  91. IppsBigNumState* p_bn_sig_rl_hash = NULL;
  92. IppsBigNumState* p_bn_sig_rl_msg = NULL;
  93. IppsBigNumState* p_bn_sign_x = NULL;
  94. IppsBigNumState* p_bn_sign_y = NULL;
  95. IppsBigNumState* p_bn_p_x = NULL;
  96. IppsBigNumState* p_bn_p_y = NULL;
  97. IppsECCPPointState *p_reg_pub_key = NULL;
  98. int ctxSize = 0;
  99. IppECResult ecc_result = ippECValid;
  100. uint32_t sig_rl_hash_le[8] = {0};
  101. const uint32_t zero = 0;
  102. IppsBigNumState* p_bn_zero = NULL;
  103. if(NULL == p_ecp || NULL == p_pubkey || NULL == p_signature
  104. || NULL == p_sig_rl_hash || NULL == p_result)
  105. return SGX_ERROR_INVALID_PARAMETER;
  106. const int order_size = sizeof(g_nistp256_r);
  107. ipp_ret = newBN(g_nistp256_r, order_size, &p_bn_ecp_order);
  108. if(ipp_ret != ippStsNoErr)
  109. {
  110. ret = SGX_ERROR_UNEXPECTED;
  111. goto CLEANUP;
  112. }
  113. memcpy(sig_rl_hash_le, p_sig_rl_hash->hash, sizeof(sig_rl_hash_le));
  114. SWAP_ENDIAN_32B(sig_rl_hash_le);
  115. ipp_ret = newBN(sig_rl_hash_le, sizeof(sig_rl_hash_le),
  116. &p_bn_sig_rl_hash);
  117. if(ipp_ret != ippStsNoErr)
  118. {
  119. ret = SGX_ERROR_UNEXPECTED;
  120. goto CLEANUP;
  121. }
  122. ipp_ret = newBN(0, order_size, &p_bn_sig_rl_msg);
  123. if(ipp_ret != ippStsNoErr)
  124. {
  125. ret = SGX_ERROR_UNEXPECTED;
  126. goto CLEANUP;
  127. }
  128. ipp_ret = ippsMod_BN(p_bn_sig_rl_hash, p_bn_ecp_order, p_bn_sig_rl_msg);
  129. if(ipp_ret != ippStsNoErr)
  130. {
  131. ret = SGX_ERROR_UNEXPECTED;
  132. goto CLEANUP;
  133. }
  134. ipp_ret = newBN(p_signature->x, order_size, &p_bn_sign_x);
  135. if(ipp_ret != ippStsNoErr)
  136. {
  137. ret = SGX_ERROR_UNEXPECTED;
  138. goto CLEANUP;
  139. }
  140. // Create a Big Number whose value is zero
  141. ipp_ret = newBN(&zero, sizeof(zero), &p_bn_zero);
  142. if(ipp_ret != ippStsNoErr)
  143. {
  144. ret = SGX_ERROR_UNEXPECTED;
  145. goto CLEANUP;
  146. }
  147. // Make sure none of the 2 signature big numbers is 0.
  148. ipp_ret = ippsCmp_BN(p_bn_sign_x, p_bn_zero, &cmpZeroResult);
  149. if(ipp_ret != ippStsNoErr)
  150. {
  151. ret = SGX_ERROR_UNEXPECTED;
  152. goto CLEANUP;
  153. }
  154. if(IS_ZERO == cmpZeroResult)
  155. {
  156. // Return SGX_SUCCESS and *p_result to be ippECInvalidSignature to report invalid signature.
  157. ret = SGX_SUCCESS;
  158. *p_result = ippECInvalidSignature;
  159. goto CLEANUP;
  160. }
  161. ipp_ret = newBN(p_signature->y, order_size, &p_bn_sign_y);
  162. if(ipp_ret != ippStsNoErr)
  163. {
  164. ret = SGX_ERROR_UNEXPECTED;
  165. goto CLEANUP;
  166. }
  167. ipp_ret = ippsCmp_BN(p_bn_sign_y, p_bn_zero, &cmpZeroResult);
  168. if(ipp_ret != ippStsNoErr)
  169. {
  170. ret = SGX_ERROR_UNEXPECTED;
  171. goto CLEANUP;
  172. }
  173. if(IS_ZERO == cmpZeroResult)
  174. {
  175. // Return SGX_SUCCESS and *p_result to be ippECInvalidSignature to report invalid signature
  176. ret = SGX_SUCCESS;
  177. *p_result = ippECInvalidSignature;
  178. goto CLEANUP;
  179. }
  180. ipp_ret = newBN((Ipp32u *)p_pubkey->gx, order_size, &p_bn_p_x);
  181. if(ipp_ret != ippStsNoErr)
  182. {
  183. ret = SGX_ERROR_UNEXPECTED;
  184. goto CLEANUP;
  185. }
  186. ipp_ret = newBN((Ipp32u *)p_pubkey->gy, order_size, &p_bn_p_y);
  187. if(ipp_ret != ippStsNoErr)
  188. {
  189. ret = SGX_ERROR_UNEXPECTED;
  190. goto CLEANUP;
  191. }
  192. ipp_ret = ippsECCPPointGetSize(256, &ctxSize);
  193. if(ipp_ret != ippStsNoErr)
  194. {
  195. ret = SGX_ERROR_UNEXPECTED;
  196. goto CLEANUP;
  197. }
  198. p_reg_pub_key = (IppsECCPPointState *)malloc(ctxSize);
  199. if(NULL == p_reg_pub_key)
  200. {
  201. ret = SGX_ERROR_UNEXPECTED;
  202. goto CLEANUP;
  203. }
  204. ipp_ret = ippsECCPPointInit(256, p_reg_pub_key);
  205. if(ipp_ret != ippStsNoErr)
  206. {
  207. ret = SGX_ERROR_UNEXPECTED;
  208. goto CLEANUP;
  209. }
  210. ipp_ret = ippsECCPSetPoint(p_bn_p_x, p_bn_p_y, p_reg_pub_key, p_ecp);
  211. if(ipp_ret != ippStsNoErr)
  212. {
  213. ret = SGX_ERROR_UNEXPECTED;
  214. goto CLEANUP;
  215. }
  216. /* Set the regular pub key. */
  217. ipp_ret = ippsECCPSetKeyPair(NULL, p_reg_pub_key, ippTrue, p_ecp);
  218. if(ipp_ret != ippStsNoErr)
  219. {
  220. ret = SGX_ERROR_UNEXPECTED;
  221. goto CLEANUP;
  222. }
  223. ipp_ret = ippsECCPVerifyDSA(p_bn_sig_rl_msg, p_bn_sign_x, p_bn_sign_y,
  224. &ecc_result, p_ecp);
  225. if(ipp_ret != ippStsNoErr)
  226. {
  227. ret = SGX_ERROR_UNEXPECTED;
  228. goto CLEANUP;
  229. }
  230. *p_result = ecc_result;
  231. CLEANUP:
  232. if(p_bn_ecp_order)
  233. free(p_bn_ecp_order);
  234. if(p_bn_sig_rl_hash)
  235. free(p_bn_sig_rl_hash);
  236. if(p_bn_sig_rl_msg)
  237. free(p_bn_sig_rl_msg);
  238. if(p_bn_sign_x)
  239. free(p_bn_sign_x);
  240. if(p_bn_sign_y)
  241. free(p_bn_sign_y);
  242. if(p_bn_p_x)
  243. free(p_bn_p_x);
  244. if(p_bn_p_y)
  245. free(p_bn_p_y);
  246. if(p_reg_pub_key)
  247. free(p_reg_pub_key);
  248. if(p_bn_zero)
  249. free(p_bn_zero);
  250. return ret;
  251. }