SgxSealer.cpp 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252
  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. #include "sgx.h"
  32. #include "sgx_tseal.h" // For sgx_seal_data, sgx_calc_sealed_data_size, sgx_get_encrypt_txt_len, sgx_unseal_data
  33. #include "sgx_tae_service.h" // For create, read counters and pse_session. Also exports SGX_MC_UUID_NONCE_SIZE and SGX_MC_UUID_COUNTER_ID_SIZE, TODO: apparently also ne$
  34. #include "sgx_uae_service.h" // for sgx_ps_get_cap and SGX_IS_MONOTONIC_COUNTER_AVAILABLE
  35. #include <string>
  36. #include <stdlib.h>
  37. #include <string.h>
  38. #include <stdio.h>
  39. #include <vector>
  40. //#include "ProtobufSgxTransforms.h"
  41. #include "ProtobufSgxSealerTransforms.h"
  42. //class Sealer {
  43. // namespace {
  44. uint32_t verify_sgx_monotonic_counter_value(sgx_mc_uuid_t* sgx_monotonic_counter_id, uint32_t* sgx_monotonic_counter_value)
  45. {
  46. /* uint32_t ret = 0;
  47. uint32_t expected_counter_value;
  48. int busy_retry_times = 2;
  49. do{
  50. ret = sgx_create_pse_session();
  51. }while (ret == SGX_ERROR_BUSY && busy_retry_times--);
  52. if (ret != SGX_SUCCESS)
  53. return ret;
  54. ret = sgx_read_monotonic_counter(sgx_monotonic_counter_id,&expected_counter_value);
  55. if(ret != SGX_SUCCESS)
  56. {
  57. switch(ret)
  58. {
  59. case SGX_ERROR_SERVICE_UNAVAILABLE:
  60. // Architecture Enclave Service Manager is not installed or not working properly.
  61. break;
  62. case SGX_ERROR_SERVICE_TIMEOUT:
  63. // retry the operation later
  64. break;
  65. case SGX_ERROR_BUSY:
  66. // retry the operation later
  67. break;
  68. case SGX_ERROR_MC_NOT_FOUND:
  69. // the the Monotonic Counter ID is invalid.
  70. break;
  71. default:
  72. // other errors
  73. break;
  74. }
  75. }
  76. else if(expected_counter_value!=*sgx_monotonic_counter_value)
  77. {
  78. ret = 3; //REPLAY_DETECTED; // This must be by the OS.
  79. }
  80. sgx_close_pse_session();
  81. */
  82. return SGX_SUCCESS; //ret;
  83. }
  84. uint32_t create_sgx_monotonic_counter_id_and_value(sgx_mc_uuid_t* sgx_counter_id, uint32_t* sgx_counter_value)
  85. {
  86. int counter=0;
  87. for(counter=0;counter<3;counter++)
  88. {
  89. sgx_counter_id->nonce[counter]=1;
  90. }
  91. for(counter=0;counter<13;counter++)
  92. {
  93. sgx_counter_id->counter_id[counter]=1;
  94. }
  95. //sgx_counter_id->nonce={0,0,0,0};
  96. //sgx_counter_id->counter_id={0,0,0,0,0,0,0,0,0,0,0,0,0};
  97. *sgx_counter_value=1;
  98. /*
  99. uint32_t ret = 0;
  100. int busy_retry_times = 2;
  101. do{
  102. ret = sgx_create_pse_session();
  103. }while (ret == SGX_ERROR_BUSY && busy_retry_times--);
  104. if (ret != SGX_SUCCESS)
  105. return ret;
  106. ret = sgx_create_monotonic_counter(sgx_counter_id,sgx_counter_value);
  107. if(ret != SGX_SUCCESS)
  108. {
  109. switch(ret)
  110. {
  111. case SGX_ERROR_SERVICE_UNAVAILABLE:
  112. // Architecture Enclave Service Manager is not installed or not working properly
  113. break;
  114. case SGX_ERROR_SERVICE_TIMEOUT:
  115. // retry the operation latersgx_create_monotonic_counter
  116. break;
  117. case SGX_ERROR_BUSY:
  118. // retry the operation later
  119. break;
  120. case SGX_ERROR_MC_OVER_QUOTA:
  121. // SGX Platform Service enforces a quota scheme on the Monotonic Counters a SGX app can maintain. the enclave has reached the quota.
  122. break;
  123. case SGX_ERROR_MC_USED_UP:
  124. // the Monotonic Counter has been used up and cannot create Monotonic Counter anymore.
  125. break;
  126. default:
  127. // other errors
  128. break;
  129. }
  130. }
  131. sgx_close_pse_session(); // TODO: Check that we should do it here.
  132. */
  133. return SGX_SUCCESS; // ret;
  134. }
  135. uint32_t initialize_pse_and_counter()
  136. {
  137. /*
  138. sgx_status_t sgx_ret;
  139. sgx_ps_cap_t ps_cap;
  140. memset(&ps_cap, 0, sizeof(sgx_ps_cap_t));
  141. sgx_ret = sgx_get_ps_cap(&ps_cap);
  142. if (sgx_ret)
  143. {
  144. // printf("cannot get platform service capability, error code = 0x%d", sgx_ret);
  145. return sgx_ret;
  146. }
  147. if (!SGX_IS_MONOTONIC_COUNTER_AVAILABLE(ps_cap))
  148. {
  149. // printf("\nmonotonic counter is not supported\n");
  150. return SGX_ERROR_SERVICE_UNAVAILABLE;
  151. }*/
  152. return SGX_SUCCESS;
  153. }
  154. uint32_t seal_message(std::string& plaintext_str, std::string& sgx_sealed_msg_str)
  155. {
  156. // std::string protobuf_plaintext_str;
  157. uint32_t ret;
  158. // sgx_mc_uuid_t sgx_counter_id;
  159. // uint32_t sgx_counter_value;
  160. uint8_t* sgx_sealed_msg;
  161. uint32_t expected_sealed_msg_length;
  162. /* ret = create_sgx_monotonic_counter_id_and_value(&sgx_counter_id, &sgx_counter_value);
  163. if(ret!=SGX_SUCCESS)
  164. return ret;
  165. ProtobufSgxTransforms::encode_message_and_counter_to_protobuf_string(plaintext_str, &sgx_counter_id, &sgx_counter_value, protobuf_plaintext_str);
  166. */ expected_sealed_msg_length = sgx_calc_sealed_data_size(0, 9);
  167. if(expected_sealed_msg_length == 0xFFFFFFFF)
  168. return 1;
  169. sgx_sealed_msg = (uint8_t*)malloc(expected_sealed_msg_length); // Doesn't change with protobufs - convert the data here to protobuf format after it is initialized
  170. ret = sgx_seal_data(0, NULL, 9, (uint8_t*) plaintext_str.c_str(), expected_sealed_msg_length, (sgx_sealed_data_t*) sgx_sealed_msg);
  171. sgx_sealed_msg_str = std::string((char*)sgx_sealed_msg, expected_sealed_msg_length); // TODO: Fishy conversion.
  172. free(sgx_sealed_msg);
  173. return ret;
  174. }
  175. uint32_t unseal_and_verify_sealed_message(std::string& sgx_sealed_msg_str, std::string& plaintext)
  176. {
  177. uint32_t ret = 0;
  178. uint8_t* sgx_sealed_msg;
  179. uint8_t* temp_plaintext;
  180. std::string protobuf_encoded_str; std::string decoded_plaintext;
  181. sgx_mc_uuid_t sgx_counter_id;
  182. uint32_t sgx_counter_value;
  183. uint32_t expected_plaintext_msg_length;
  184. std::vector<uint8_t> sgx_sealed_msg_vector(sgx_sealed_msg_str.begin(), sgx_sealed_msg_str.end());// TODO: Add null termination?
  185. sgx_sealed_msg = &sgx_sealed_msg_vector[0];
  186. expected_plaintext_msg_length = sgx_get_encrypt_txt_len((sgx_sealed_data_t*)sgx_sealed_msg);
  187. if(expected_plaintext_msg_length == 0xffffffff)
  188. return 1;
  189. // return expected_plaintext_msg_length;
  190. temp_plaintext = (uint8_t*)malloc( expected_plaintext_msg_length );
  191. ret = sgx_unseal_data((sgx_sealed_data_t*)sgx_sealed_msg, NULL, 0, temp_plaintext, &expected_plaintext_msg_length);
  192. if(ret != SGX_SUCCESS)
  193. {
  194. free(temp_plaintext);
  195. switch(ret)
  196. {
  197. case SGX_ERROR_MAC_MISMATCH:
  198. // MAC of the sealed data is incorrect. The sealed data has been tampered.
  199. break;
  200. case SGX_ERROR_INVALID_ATTRIBUTE:
  201. // Indicates attribute field of the sealed data is incorrect.
  202. break;
  203. case SGX_ERROR_INVALID_ISVSVN:
  204. // Indicates isv_svn field of the sealed data is greater than the enclave�s ISVSVN. This is a downgraded enclave.
  205. break;
  206. case SGX_ERROR_INVALID_CPUSVN:
  207. // Indicates cpu_svn field of the sealed data is greater than the platform�s cpu_svn. enclave is on a downgraded platform.
  208. break;
  209. case SGX_ERROR_INVALID_KEYNAME:
  210. // Indicates key_name field of the sealed data is incorrect.
  211. break;
  212. default:
  213. // other errors
  214. break;
  215. }
  216. return ret;
  217. }
  218. protobuf_encoded_str = std::string((char*)temp_plaintext, expected_plaintext_msg_length); // TODO: Fishy conversion.
  219. free(temp_plaintext);
  220. /* ProtobufSgxTransforms::decode_protobuf_message_to_counter_id_and_value(protobuf_encoded_str, &sgx_counter_id, &sgx_counter_value);
  221. ret = verify_sgx_monotonic_counter_value(&sgx_counter_id, &sgx_counter_value);
  222. if (ret == SGX_SUCCESS)
  223. {
  224. ProtobufSgxTransforms::decode_protobuf_message_to_plaintext(protobuf_encoded_str, decoded_plaintext);
  225. plaintext = decoded_plaintext;
  226. }
  227. */plaintext = protobuf_encoded_str;
  228. return ret;
  229. }
  230. //}