pve_verify_signature.cpp 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183
  1. /*
  2. * Copyright (C) 2011-2017 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. /**
  32. * File: pve_verify_signature.cpp
  33. * Description: Define function to check ISK signed signature at the end of SigRL.
  34. * It will use qe/pve shared code in file se_ecdsa_verify_internal
  35. */
  36. #include "provision_msg.h"
  37. #include "epid/common/errors.h"
  38. #include "ae_ipp.h"
  39. #include "epid/member/api.h"
  40. #include <string.h>
  41. #include "helper.h"
  42. #include "cipher.h"
  43. #include "pve_qe_common.h"
  44. #include "se_ecdsa_verify_internal.h"
  45. #include "byte_order.h"
  46. #include "util.h"
  47. /*
  48. * An internal function used to verify the ECDSA signature inside PvE given hash of message
  49. *
  50. * @param p_signature[in] Pointer to signature part of the message, the data in bigendian.
  51. * @param p_input_hash[in] The pointer of the hash of the whole message.
  52. * @param public_key_x and public_key_y, the two components of ECDSA public key
  53. * @return ae_error_t PVEC_SUCCESS for success and verification passed,
  54. * @ return PVEC_MSG_ERROR for invalid and signature and other for errors.
  55. */
  56. static pve_status_t pve_verify_ecdsa_signature(
  57. const uint8_t *p_signature,
  58. const se_ae_ecdsa_hash_t *p_input_hash,
  59. const uint8_t public_key_x[SGX_ECP256_KEY_SIZE],
  60. const uint8_t public_key_y[SGX_ECP256_KEY_SIZE])
  61. {
  62. pve_status_t ret = PVEC_SUCCESS;
  63. IppStatus ipp_ret = ippStsNoErr;
  64. IppsECCPState* p_ecp = NULL;
  65. sgx_ec256_public_t ec_pub_key;
  66. IppECResult ecc_result = ippECValid;
  67. sgx_status_t se_ret = SGX_SUCCESS;
  68. sgx_ec256_signature_t little_endian_signature;
  69. memset(&ec_pub_key, 0, sizeof(ec_pub_key));
  70. ipp_ret = new_std_256_ecp(&p_ecp);
  71. if(ipp_ret != ippStsNoErr)
  72. {
  73. ret = ipp_error_to_pve_error(ipp_ret);
  74. goto CLEANUP;
  75. }
  76. memcpy(&little_endian_signature.x , p_signature, ECDSA_SIGN_SIZE);
  77. memcpy(&little_endian_signature.y , p_signature+ECDSA_SIGN_SIZE, ECDSA_SIGN_SIZE);
  78. SWAP_ENDIAN_32B(little_endian_signature.x);
  79. SWAP_ENDIAN_32B(little_endian_signature.y);
  80. memcpy(ec_pub_key.gx, public_key_x, sizeof(ec_pub_key.gx));
  81. memcpy(ec_pub_key.gy, public_key_y, sizeof(ec_pub_key.gy));
  82. se_ret = se_ecdsa_verify_internal(p_ecp,
  83. &ec_pub_key,
  84. &little_endian_signature,
  85. p_input_hash,
  86. &ecc_result);
  87. if(se_ret != SGX_SUCCESS){
  88. ret = sgx_error_to_pve_error(se_ret);
  89. goto CLEANUP;
  90. }
  91. if(ecc_result != ippECValid){
  92. ret = PVEC_MSG_ERROR;
  93. goto CLEANUP;
  94. }
  95. CLEANUP:
  96. secure_free_std_256_ecp(p_ecp);
  97. return ret;
  98. }
  99. pve_status_t verify_epid_ecdsa_signature(
  100. const uint8_t *p_sig_rl_sign, //The ecdsa signature of message to be verified, the size of it should be 2*ECDSA_SIGN_SIZE which contains two big integers in big endian
  101. const extended_epid_group_blob_t& xegb,
  102. const se_ae_ecdsa_hash_t *p_sig_rl_hash) //The sha256 hash value of message to be verified
  103. {
  104. uint8_t pub_x[ECDSA_SIGN_SIZE], pub_y[ECDSA_SIGN_SIZE];
  105. memcpy(pub_x, xegb.epid_sk, ECDSA_SIGN_SIZE);
  106. memcpy(pub_y, xegb.epid_sk+ECDSA_SIGN_SIZE, ECDSA_SIGN_SIZE);//epid sk has been of little endian format in xegb
  107. return pve_verify_ecdsa_signature(p_sig_rl_sign, p_sig_rl_hash, pub_x, pub_y);
  108. }
  109. static pve_status_t pve_check_ecdsa_signature(const uint8_t *data,
  110. uint32_t data_len,
  111. const uint8_t *signature,
  112. const uint8_t public_key_x[SGX_ECP256_KEY_SIZE],
  113. const uint8_t public_key_y[SGX_ECP256_KEY_SIZE])
  114. {
  115. sgx_sha_state_handle_t sha_state = NULL;
  116. pve_status_t ret = PVEC_SUCCESS;
  117. sgx_status_t sgx_status = SGX_SUCCESS;
  118. //First generate SHA256 hash value of the data
  119. sgx_status = sgx_sha256_init(&sha_state);
  120. if(sgx_status != SGX_SUCCESS){
  121. ret = sgx_error_to_pve_error(sgx_status);
  122. goto ret_point;
  123. }
  124. sgx_status = sgx_sha256_update(data, data_len, sha_state);
  125. if(sgx_status != SGX_SUCCESS){
  126. ret = sgx_error_to_pve_error(sgx_status);
  127. goto ret_point;
  128. }
  129. se_ae_ecdsa_hash_t out;
  130. //get the SHA256 hash value of input data in buffer 'out'
  131. se_static_assert(sizeof(out)==sizeof(sgx_sha256_hash_t)); /*sgx_sha256_hash_t must have same size as se_ae_ecdsa_hash_t*/
  132. sgx_status =sgx_sha256_get_hash(sha_state, reinterpret_cast<sgx_sha256_hash_t *>(out.hash));
  133. if(sgx_status != SGX_SUCCESS){
  134. ret = sgx_error_to_pve_error(sgx_status);
  135. goto ret_point;
  136. }
  137. //call the function to verify the ECDSA signature of hash value 'out' matches 'signature'
  138. ret = pve_verify_ecdsa_signature(signature, &out, public_key_x, public_key_y);
  139. ret_point:
  140. if(sha_state!=NULL){
  141. sgx_sha256_close(sha_state);
  142. }
  143. return ret;
  144. }
  145. //Function to verify the ECDSA signature is signed by EPID Signing Key
  146. //The function will also check that version and type of the cert
  147. //64 bytes signature is the last field of the input data structure
  148. pve_status_t check_signature_of_group_pub_cert(const signed_epid_group_cert_t *group_cert, const uint8_t* epid_sk)
  149. {
  150. uint8_t pub_x[ECDSA_SIGN_SIZE], pub_y[ECDSA_SIGN_SIZE];
  151. uint16_t version = lv_ntohs(group_cert->version);
  152. uint16_t type = lv_ntohs(group_cert->type);
  153. uint8_t version_minor = static_cast<uint8_t>(version>>8);//byte 0 of original data
  154. uint8_t version_major = static_cast<uint8_t>(version);//byte 1 of original data
  155. if(type != EPID_TYPE_GROUP_CERT){
  156. return PVEC_MSG_ERROR;
  157. }
  158. if(version_major != EPID_VERSION_MAJOR ||
  159. version_minor != EPID_VERSION_MINOR){
  160. return PVEC_UNSUPPORTED_VERSION_ERROR;
  161. }
  162. memcpy(pub_x, epid_sk, ECDSA_SIGN_SIZE);
  163. memcpy(pub_y, epid_sk + ECDSA_SIGN_SIZE, ECDSA_SIGN_SIZE);
  164. return pve_check_ecdsa_signature(reinterpret_cast<const uint8_t *>(group_cert),
  165. static_cast<uint32_t>(sizeof(signed_epid_group_cert_t)-sizeof(group_cert->ecdsa_signature)),
  166. group_cert->ecdsa_signature,
  167. pub_x, pub_y);
  168. }