pve_verify_signature.cpp 7.6 KB

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