epid_endpoint_selection.cpp 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212
  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. #include "provision_msg.h"
  32. #include "type_length_value.h"
  33. #include <sgx_trts.h>
  34. #include "PVEClass.h"
  35. #include "aesm_rand.h"
  36. #include "se_wrapper.h"
  37. #include "epid_utility.h"
  38. #include "prof_fun.h"
  39. #include "oal/internal_log.h"
  40. #include <assert.h>
  41. static ae_error_t prov_es_gen_header(provision_request_header_t *es_header,
  42. const uint8_t *xid,
  43. uint32_t msg_buffer_size)
  44. {
  45. uint32_t total_size = 0;
  46. total_size = ES_SELECTOR_TLV_SIZE();
  47. //initialize ES Msg1 Header
  48. es_header->protocol = ENDPOINT_SELECTION;
  49. es_header->type = TYPE_ES_MSG1;
  50. es_header->version = TLV_VERSION_1;
  51. if(0!=memcpy_s(es_header->xid, XID_SIZE, xid, XID_SIZE)){
  52. AESM_DBG_FATAL("memcpy error");
  53. return PVE_UNEXPECTED_ERROR;
  54. }
  55. uint32_t size_in;
  56. size_in = _htonl(total_size);//big endian size required in msg header
  57. if(0!=memcpy_s(&es_header->size,sizeof(es_header->size), &size_in, sizeof(size_in))){
  58. AESM_DBG_FATAL("memcpy error");
  59. return PVE_UNEXPECTED_ERROR;
  60. }
  61. if(total_size +sizeof(*es_header) >msg_buffer_size){//the input msg body buffer size is not large enough
  62. AESM_DBG_ERROR("input msg buffer is too small");
  63. return PVE_INSUFFICIENT_MEMORY_ERROR;
  64. }
  65. return AE_SUCCESS;
  66. }
  67. uint32_t CPVEClass::gen_es_msg1(
  68. uint8_t *msg,
  69. uint32_t msg_size,
  70. const gen_endpoint_selection_output_t& es_output)
  71. {
  72. ae_error_t ret;
  73. AESM_PROFILE_FUN;
  74. if(msg_size < PROVISION_REQUEST_HEADER_SIZE)
  75. return PVE_INSUFFICIENT_MEMORY_ERROR;
  76. provision_request_header_t *es_header = reinterpret_cast<provision_request_header_t *>(msg);
  77. ret = prov_es_gen_header(es_header, es_output.xid, msg_size);
  78. if(AE_SUCCESS != ret){
  79. AESM_DBG_ERROR("Fail to generate Endpoint Selection Msg1 Header:%d",ret);
  80. return ret;
  81. }
  82. {
  83. TLVsMsg tlvs_msg;
  84. tlv_status_t tlv_status = tlvs_msg.add_es_selector(SE_EPID_PROVISIONING, es_output.selector_id);
  85. ret = tlv_error_2_pve_error(tlv_status);
  86. if(AE_SUCCESS!=ret){
  87. AESM_DBG_ERROR("fail to create ES Selector TLV:%d",ret);
  88. return ret;
  89. }
  90. assert(tlvs_msg.get_tlv_msg_size()<=msg_size - PROVISION_REQUEST_HEADER_SIZE); //The checking should have been done in prov_es_gen_header
  91. if(0!=memcpy_s(msg+PROVISION_REQUEST_HEADER_SIZE, msg_size-PROVISION_REQUEST_HEADER_SIZE, tlvs_msg.get_tlv_msg(), tlvs_msg.get_tlv_msg_size())){
  92. AESM_DBG_FATAL("memcpy failed");
  93. return PVE_UNEXPECTED_ERROR;
  94. }
  95. return AE_SUCCESS;
  96. }
  97. }
  98. #define ES_MSG2_FIELD_COUNT 3
  99. #define ES_FIELD0_MIN_SIZE 3
  100. #define ES_FIELD0_MAX_SIZE (MAX_PATH-1)
  101. uint32_t CPVEClass::proc_es_msg2(
  102. const uint8_t *msg,
  103. uint32_t msg_size,
  104. char server_url[MAX_PATH],
  105. uint16_t& ttl,
  106. const uint8_t xid[XID_SIZE],
  107. uint8_t rsa_signature[PVE_RSA_KEY_BYTES],
  108. signed_pek_t& pek)
  109. {
  110. uint32_t ae_ret = PVE_MSG_ERROR;
  111. TLVsMsg tlvs_msg;
  112. AESM_PROFILE_FUN;
  113. tlv_status_t tlv_status;
  114. uint16_t time_in_net;
  115. const provision_response_header_t *resp_header = (const provision_response_header_t *)msg;
  116. const uint8_t *resp_body = msg + PROVISION_RESPONSE_HEADER_SIZE;
  117. if(msg_size<PROVISION_RESPONSE_HEADER_SIZE){//at least response header is available
  118. AESM_DBG_ERROR("Endpoint selection Msg2 buffer size too small");
  119. goto final_point;
  120. }
  121. //first checking resp header for protocol, version and type
  122. if(resp_header->protocol != ENDPOINT_SELECTION || resp_header->version!=TLV_VERSION_1 || resp_header->type != TYPE_ES_MSG2){
  123. AESM_DBG_ERROR("ES Msg2 header error");
  124. goto final_point;
  125. }
  126. ae_ret = check_endpoint_pg_stauts(resp_header);
  127. if(AE_SUCCESS != ae_ret){
  128. AESM_DBG_ERROR("Backend report error in ES Msg2 Header:%d",ae_ret);
  129. goto final_point;
  130. }
  131. if(0!=memcmp(xid, resp_header->xid, XID_SIZE)){
  132. AESM_DBG_ERROR("XID in ES Msg2 header doesn't match the one in ES Msg1");
  133. ae_ret = PVE_MSG_ERROR;
  134. goto final_point;
  135. }
  136. uint32_t size; size = GET_BODY_SIZE_FROM_PROVISION_RESPONSE(msg);
  137. if(size + PROVISION_RESPONSE_HEADER_SIZE != msg_size){ //size information inconsistent
  138. AESM_DBG_ERROR("message size inconsistent in ES Msg2");
  139. ae_ret = PVE_MSG_ERROR;
  140. goto final_point;
  141. }
  142. tlv_status = tlvs_msg.init_from_buffer(resp_body, msg_size - static_cast<uint32_t>(PROVISION_RESPONSE_HEADER_SIZE));
  143. ae_ret = tlv_error_2_pve_error(tlv_status);
  144. if(AE_SUCCESS!=ae_ret){
  145. AESM_DBG_ERROR("Fail to decode ES Msg2:%d",ae_ret);
  146. goto final_point;
  147. }
  148. if(tlvs_msg.get_tlv_count() != ES_MSG2_FIELD_COUNT){//three TLVs
  149. AESM_DBG_ERROR("Invaid number of TLV in ES Msg2");
  150. ae_ret = PVE_MSG_ERROR;
  151. goto final_point;
  152. }
  153. if(tlvs_msg[0].type != TLV_ES_INFORMATION || tlvs_msg[0].version != TLV_VERSION_1 || tlvs_msg[0].header_size != SMALL_TLV_HEADER_SIZE){//TLV header checking
  154. AESM_DBG_ERROR("Invalid TLV in ES Msg2");
  155. ae_ret = PVE_MSG_ERROR;
  156. goto final_point;
  157. }
  158. if(tlvs_msg[0].size<ES_FIELD0_MIN_SIZE||tlvs_msg[0].size>ES_FIELD0_MAX_SIZE){//size checking
  159. AESM_DBG_ERROR("Invalid TLV in ES Msg2");
  160. ae_ret = PVE_MSG_ERROR;
  161. goto final_point;
  162. }
  163. if(tlvs_msg[1].type != TLV_SIGNATURE || tlvs_msg[1].version != TLV_VERSION_1 ||
  164. tlvs_msg[1].header_size!=SMALL_TLV_HEADER_SIZE||tlvs_msg[1].size != PVE_RSA_KEY_BYTES+1 ||
  165. tlvs_msg[1].payload[0] != PEK_PRIV){
  166. ae_ret = PVE_MSG_ERROR;
  167. AESM_DBG_ERROR("Invalid Signature TLV: type %d, version %d, size %d while expected value is %d, %d, %d",
  168. tlvs_msg[1].type, tlvs_msg[1].version, tlvs_msg[1].size,
  169. TLV_SIGNATURE, TLV_VERSION_1, PVE_RSA_KEY_BYTES);
  170. goto final_point;
  171. }
  172. if(tlvs_msg[2].type != TLV_PEK || tlvs_msg[2].version != TLV_VERSION_1 ||
  173. tlvs_msg[2].header_size!=SMALL_TLV_HEADER_SIZE||tlvs_msg[2].size != sizeof(signed_pek_t)){
  174. ae_ret = PVE_MSG_ERROR;
  175. AESM_DBG_ERROR("Invalid PEK TLV: type %d, version %d, size %d while expected value is %d, %d, %d",
  176. tlvs_msg[2].type, tlvs_msg[2].version, tlvs_msg[2].size,
  177. TLV_PEK, TLV_VERSION_1, sizeof(signed_pek_t));
  178. goto final_point;
  179. }
  180. //skip the byte for KEY_ID
  181. if(memcpy_s(rsa_signature, PVE_RSA_KEY_BYTES, tlvs_msg[1].payload+1, tlvs_msg[1].size-1)!=0){
  182. ae_ret = AE_FAILURE;
  183. AESM_DBG_ERROR("memcpy failed");
  184. goto final_point;
  185. }
  186. if(memcpy_s(&pek, sizeof(pek), tlvs_msg[2].payload, tlvs_msg[2].size)!=0){
  187. ae_ret = AE_FAILURE;
  188. AESM_DBG_ERROR("memcpy failed");
  189. goto final_point;
  190. }
  191. time_in_net = *(uint16_t *)tlvs_msg[0].payload;//TTL in ES
  192. ttl = lv_ntohs(time_in_net);//First two bytes in payload for TTL (maximal seconds that the URL to be valid)
  193. if(memcpy_s(server_url, MAX_PATH, tlvs_msg[0].payload+2, tlvs_msg[0].size-2)!=0){//other bytes for URL
  194. ae_ret = AE_FAILURE;
  195. AESM_DBG_ERROR("memcpy failed");
  196. goto final_point;
  197. }
  198. server_url[tlvs_msg[0].size-2]='\0';
  199. ae_ret = AE_SUCCESS;
  200. final_point:
  201. return ae_ret;
  202. }