pse_provisioning_msg1.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295
  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 "CertificateProvisioningProtocol.h"
  32. #include "epid_utility.h"
  33. #include "tlv_common.h"
  34. #include "type_length_value.h"
  35. #include "se_wrapper.h"
  36. //*********************************************************************************************************
  37. //* PSE_ProvMsg1
  38. //* Seq # Data Item
  39. //* ===== ============================================================================================
  40. //* 1 Request Header (Protocol, Version, TransactionID, Type)
  41. //* 2 Cipher Text TLV (TLV Type, Type, Version, Size, [KeyID, EncryptedPayload is 2.1])
  42. //* 2.1 Block Cipher Info TLV (TLV Type, Type, Version, Size, [SK])
  43. //* 3 Block Cipher Text TLV (TLV Type, Type, Version, Size, [IV, EncryptedPayload is 3.1])
  44. //* 3.1 EPID GID TLV (TLV Type, Type, Version, Size, [GID])
  45. //* 4 Message Authentication Code TLV (TLV Type, Type, Version, Size, [MAC])
  46. //* MAC over 1 and 3:EncryptedPayload
  47. //*********************************************************************************************************
  48. ae_error_t CertificateProvisioningProtocol::msg1_generate(const GroupId gid, upse::Buffer& serializedMsg1)
  49. {
  50. ae_error_t status = AE_FAILURE;
  51. tlv_status_t tlv_status = TLV_UNKNOWN_ERROR;
  52. GroupId be_gid; //gid from init_quote is little endian, change to bigendian for backend server here
  53. be_gid.data[0]=gid.data[3];
  54. be_gid.data[1]=gid.data[2];
  55. be_gid.data[2]=gid.data[1];
  56. be_gid.data[3]=gid.data[0];
  57. provision_request_header_t header;
  58. memset(&header, 0, sizeof(header));
  59. TLVsMsg seq2_0_tlv_cipher_text;
  60. TLVsMsg seq2_1_tlv_block_cipher_info;
  61. TLVsMsg seq3_0_tlv_block_cipher_text;
  62. TLVsMsg seq3_1_tlv_epid_gid;
  63. TLVsMsg seq4_0_tlv_mac;
  64. do
  65. {
  66. status = get_random_value(XID_SIZE, TransactionID);
  67. if (AE_FAILED(status))
  68. break;
  69. // Prepare sequence 2.1 -- Block Cipher Text TLV with SK
  70. status = msg1_create_seq2_1(seq2_1_tlv_block_cipher_info);
  71. if (AE_FAILED(status))
  72. break;
  73. // Prepare sequence 2.0 -- Cipher Text TLV with KeyID and encrypted 2.1
  74. status = msg1_create_seq2_0(seq2_1_tlv_block_cipher_info, seq2_0_tlv_cipher_text);
  75. if (AE_FAILED(status))
  76. break;
  77. // Prepare sequence 3.1 -- EPID GID TLV
  78. tlv_status = seq3_1_tlv_epid_gid.add_epid_gid(be_gid);
  79. status = tlv_error_2_pve_error(tlv_status);
  80. if (AE_FAILED(status))
  81. break;
  82. // Derive EK1
  83. upse::Buffer EK1;
  84. status = aesCMAC(M1SK, TransactionID, EK1);
  85. if (AE_FAILED(status))
  86. break;
  87. // Create Request Header (we need to calculate size before AES-GCM CMAC)
  88. status = msg1_create_header(seq2_0_tlv_cipher_text.get_tlv_msg_size(), seq3_1_tlv_epid_gid.get_tlv_msg_size(), TransactionID, header);
  89. if (AE_FAILED(status))
  90. break;
  91. // Prepare sequence 3.0 -- Block Cipher Text TLV with IV and encrypted 3.1
  92. upse::Buffer mac;
  93. status = msg1_create_seq3_0(seq3_1_tlv_epid_gid, header, EK1, seq3_0_tlv_block_cipher_text, mac);
  94. if (AE_FAILED(status))
  95. break;
  96. // Prepare sequence 4.0 -- MAC TLV
  97. tlv_status = seq4_0_tlv_mac.add_mac(mac.getData());
  98. status = tlv_error_2_pve_error(tlv_status);
  99. if (AE_FAILED(status))
  100. break;
  101. //*********************************************************************
  102. // Prepare serialized message buffer
  103. //*********************************************************************
  104. uint32_t size_msg1 = static_cast<uint32_t>(PROVISION_REQUEST_HEADER_SIZE) + seq2_0_tlv_cipher_text.get_tlv_msg_size() +
  105. seq3_0_tlv_block_cipher_text.get_tlv_msg_size() + seq4_0_tlv_mac.get_tlv_msg_size();
  106. status = serializedMsg1.Alloc(size_msg1);
  107. if (AE_FAILED(status))
  108. break;
  109. serializedMsg1.zeroMemory();
  110. upse::BufferWriter bwMsg1(serializedMsg1);
  111. // Write serialized request header to serialized message
  112. status = bwMsg1.writeRaw((uint8_t*)&header, sizeof(header));
  113. if (AE_FAILED(status))
  114. break;
  115. // Write sequence 2.0 - Cipher Text TLV (contains 2.1 as encrypted payload)
  116. status = bwMsg1.writeRaw(const_cast<uint8_t*>(seq2_0_tlv_cipher_text.get_tlv_msg()), seq2_0_tlv_cipher_text.get_tlv_msg_size());
  117. if (AE_FAILED(status))
  118. break;
  119. // Write sequence 3.0 - Block Cipher Text TLV (contains 3.1 as encrypted payload)
  120. status = bwMsg1.writeRaw(const_cast<uint8_t*>(seq3_0_tlv_block_cipher_text.get_tlv_msg()), seq3_0_tlv_block_cipher_text.get_tlv_msg_size());
  121. if (AE_FAILED(status))
  122. break;
  123. // Write sequence 4.0 - MAC TLV
  124. status = bwMsg1.writeRaw(const_cast<uint8_t*>(seq4_0_tlv_mac.get_tlv_msg()), seq4_0_tlv_mac.get_tlv_msg_size());
  125. if (AE_FAILED(status))
  126. break;
  127. status = AE_SUCCESS;
  128. } while (0);
  129. return status;
  130. }
  131. ae_error_t CertificateProvisioningProtocol::msg1_create_header(uint32_t seq2_0_cipher_text_size, uint32_t seq3_1_epid_gid_size, const upse::Buffer& transactionID, provision_request_header_t& header)
  132. {
  133. ae_error_t status = AE_FAILURE;
  134. do
  135. {
  136. uint32_t seq3_0_block_cipher_text_size = BLOCK_CIPHER_TEXT_TLV_SIZE(seq3_1_epid_gid_size);
  137. uint32_t seq4_0_tlv_mac_size = MAC_TLV_SIZE(MAC_SIZE);
  138. header.protocol = PSE_PROVISIONING;
  139. header.version = TLV_VERSION_1;
  140. header.type = static_cast<uint8_t>(TYPE_PSE_MSG1);
  141. if (XID_SIZE != transactionID.getSize())
  142. break;
  143. if (memcpy_s(header.xid, sizeof(header.xid), transactionID.getData(), transactionID.getSize()) != 0)
  144. break;
  145. uint32_t totalSize = seq2_0_cipher_text_size + seq3_0_block_cipher_text_size + seq4_0_tlv_mac_size;
  146. uint32_t serializedSize = _htonl(totalSize);
  147. if (sizeof(serializedSize) != sizeof(header.size))
  148. break;
  149. if (memcpy_s(header.size, sizeof(header.size), &serializedSize, sizeof(serializedSize)) != 0)
  150. break;
  151. status = AE_SUCCESS;
  152. } while (0);
  153. return status;
  154. }
  155. ae_error_t CertificateProvisioningProtocol::msg1_create_seq2_0(const TLVsMsg& seq2_1_tlv_block_cipher_info, TLVsMsg& seq2_0_tlv_cipher_text)
  156. {
  157. //* 2.0 Cipher Text TLV (TLV Type, Type, Version, Size, [KeyID, EncryptedPayload is 2.1])
  158. ae_error_t status = AE_FAILURE;
  159. tlv_status_t tlv_status;
  160. do
  161. {
  162. upse::Buffer seq2_1_encrypted_tlv;
  163. upse::Buffer encryptedBlockCipherInfo;
  164. const public_key_t& public_key = get_intel_pek();
  165. // Encrypt TLV 2.1
  166. upse::Buffer blockCipherInfo;
  167. status = blockCipherInfo.Alloc(seq2_1_tlv_block_cipher_info.get_tlv_msg(), seq2_1_tlv_block_cipher_info.get_tlv_msg_size());
  168. if (AE_FAILED(status))
  169. break;
  170. upse::BufferReader blockCipherInfoReader(blockCipherInfo);
  171. status = encryptRSA_OAEP_SHA256(public_key, blockCipherInfoReader, encryptedBlockCipherInfo);
  172. if (AE_FAILED(status))
  173. break;
  174. tlv_status = seq2_0_tlv_cipher_text.add_cipher_text(encryptedBlockCipherInfo.getData(), encryptedBlockCipherInfo.getSize(), PEK_PUB);
  175. status = tlv_error_2_pve_error(tlv_status);
  176. if (AE_FAILED(status))
  177. break;
  178. status = AE_SUCCESS;
  179. } while (0);
  180. return status;
  181. }
  182. ae_error_t CertificateProvisioningProtocol::msg1_create_seq2_1(TLVsMsg& seq2_1_tlv_block_cipher_info)
  183. {
  184. //* 2.1 Block Cipher Info TLV (TLV Type, Type, Version, Size, [SK])
  185. ae_error_t status = AE_FAILURE;
  186. tlv_status_t tlv_status;
  187. do
  188. {
  189. status = get_random_value(SK_SIZE, M1SK);
  190. if (AE_FAILED(status))
  191. break;
  192. tlv_status = seq2_1_tlv_block_cipher_info.add_block_cipher_info(M1SK.getData());
  193. status = tlv_error_2_pve_error(tlv_status);
  194. if (AE_FAILED(status))
  195. break;
  196. status = AE_SUCCESS;
  197. } while (0);
  198. return status;
  199. }
  200. ae_error_t CertificateProvisioningProtocol::msg1_create_seq3_0(const TLVsMsg& seq3_1_tlv_epid_gid, const provision_request_header_t& serializedHeader,
  201. const upse::Buffer& ek1, TLVsMsg& seq3_0_tlv_block_cipher_text, upse::Buffer& mac)
  202. {
  203. //* 3.0 Block Cipher Text TLV (TLV Type, Type, Version, Size, [IV, EncryptedPayload is 3.1])
  204. ae_error_t status = AE_FAILURE;
  205. tlv_status_t tlv_status;
  206. do
  207. {
  208. status = get_random_value(IV_SIZE, M1IV);
  209. if (AE_FAILED(status))
  210. break;
  211. upse::Buffer aad;
  212. status = aad.Alloc(sizeof(serializedHeader));
  213. if (AE_FAILED(status))
  214. break;
  215. upse::BufferWriter aadWriter(aad);
  216. status = aadWriter.writeRaw((const uint8_t*)&serializedHeader, sizeof(serializedHeader));
  217. if (AE_FAILED(status))
  218. break;
  219. upse::Buffer epidGid;
  220. status = epidGid.Alloc(seq3_1_tlv_epid_gid.get_tlv_msg(), seq3_1_tlv_epid_gid.get_tlv_msg_size());
  221. if (AE_FAILED(status))
  222. break;
  223. upse::Buffer encryptedPayload;
  224. status = aesGCMEncrypt(M1IV, ek1, epidGid, aad, encryptedPayload, mac);
  225. if (AE_FAILED(status))
  226. break;
  227. tlv_status = seq3_0_tlv_block_cipher_text.add_block_cipher_text(M1IV.getData(), encryptedPayload.getData(), encryptedPayload.getSize());
  228. status = tlv_error_2_pve_error(tlv_status);
  229. if (AE_FAILED(status))
  230. break;
  231. status = AE_SUCCESS;
  232. } while (0);
  233. return status;
  234. }