comms.cpp 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. #include <vector>
  2. #include <cstring>
  3. #include "sgx_tcrypto.h"
  4. #include "sgx_tseal.h"
  5. #include "Enclave_t.h"
  6. #include "utils.hpp"
  7. #include "config.hpp"
  8. // Our public and private identity keys
  9. static sgx_ec256_private_t g_privkey;
  10. static sgx_ec256_public_t g_pubkey;
  11. // Communication state for a node
  12. struct NodeCommState {
  13. sgx_ec256_public_t pubkey;
  14. };
  15. // The communication states for all the nodes. There's an entry for
  16. // ourselves in here, but it is unused.
  17. static std::vector<NodeCommState> commstates;
  18. // Generate a new identity signature key. Output the public key and the
  19. // sealed private key. outsealedpriv must point to SEALEDPRIVKEY_SIZE =
  20. // sizeof(sgx_sealed_data_t) + sizeof(sgx_ec256_private_t) + 18 bytes of
  21. // memory.
  22. void ecall_identity_key_new(sgx_ec256_public_t *outpub,
  23. sgx_sealed_data_t *outsealedpriv)
  24. {
  25. sgx_ecc_state_handle_t ecc_handle;
  26. sgx_ecc256_open_context(&ecc_handle);
  27. sgx_ecc256_create_key_pair(&g_privkey, &g_pubkey, ecc_handle);
  28. memmove(outpub, &g_pubkey, sizeof(g_pubkey));
  29. sgx_ecc256_close_context(ecc_handle);
  30. sgx_seal_data(18, (const uint8_t*)"TEEMS Identity key",
  31. sizeof(g_privkey), (const uint8_t*)&g_privkey,
  32. SEALED_PRIVKEY_SIZE, outsealedpriv);
  33. }
  34. // Load an identity key from a sealed privkey. Output the resulting
  35. // public key. insealedpriv must point to sizeof(sgx_sealed_data_t) +
  36. // sizeof(sgx_ec256_private_t) bytes of memory. Returns true for
  37. // success, false for failure.
  38. bool ecall_identity_key_load(sgx_ec256_public_t *outpub,
  39. const sgx_sealed_data_t *insealedpriv)
  40. {
  41. sgx_ecc_state_handle_t ecc_handle;
  42. char aad[18];
  43. uint32_t aadsize = sizeof(aad);
  44. sgx_ec256_private_t privkey;
  45. uint32_t privkeysize = sizeof(privkey);
  46. sgx_status_t res = sgx_unseal_data(
  47. insealedpriv, (uint8_t*)aad, &aadsize,
  48. (uint8_t*)&privkey, &privkeysize);
  49. if (res || aadsize != sizeof(aad) || privkeysize != sizeof(privkey)
  50. || memcmp(aad, "TEEMS Identity key", sizeof(aad))) {
  51. return false;
  52. }
  53. sgx_ecc256_open_context(&ecc_handle);
  54. sgx_ec256_public_t pubkey;
  55. int valid;
  56. if (sgx_ecc256_calculate_pub_from_priv(&privkey, &pubkey) ||
  57. sgx_ecc256_check_point(&pubkey, ecc_handle, &valid) ||
  58. !valid) {
  59. sgx_ecc256_close_context(ecc_handle);
  60. return false;
  61. }
  62. sgx_ecc256_close_context(ecc_handle);
  63. memmove(&g_pubkey, &pubkey, sizeof(pubkey));
  64. memmove(&g_privkey, &privkey, sizeof(privkey));
  65. memmove(outpub, &pubkey, sizeof(pubkey));
  66. return true;
  67. }
  68. bool comms_init_nodestate(const EnclaveAPINodeConfig *apinodeconfigs,
  69. nodenum_t num_nodes, nodenum_t my_node_num)
  70. {
  71. sgx_ecc_state_handle_t ecc_handle;
  72. sgx_ecc256_open_context(&ecc_handle);
  73. commstates.clear();
  74. commstates.resize(num_nodes);
  75. for (nodenum_t i=0; i<num_nodes; ++i) {
  76. // Check that the pubkey is valid
  77. int valid;
  78. if (sgx_ecc256_check_point(&apinodeconfigs[i].pubkey,
  79. ecc_handle, &valid) ||
  80. !valid) {
  81. printf("Pubkey for node %hu invalid\n", i);
  82. commstates.clear();
  83. sgx_ecc256_close_context(ecc_handle);
  84. return false;
  85. }
  86. memmove(&commstates[i].pubkey, &apinodeconfigs[i].pubkey,
  87. sizeof(commstates[i].pubkey));
  88. }
  89. sgx_ecc256_close_context(ecc_handle);
  90. // Check that no one other than us has our pubkey (deals with
  91. // reflection attacks)
  92. for (nodenum_t i=0; i<num_nodes; ++i) {
  93. if (i == my_node_num) continue;
  94. if (!memcmp(&commstates[i].pubkey,
  95. &commstates[my_node_num].pubkey,
  96. sizeof(commstates[i].pubkey))) {
  97. printf("Pubkey %hu matches our own; possible reflection attack?\n",
  98. i);
  99. commstates.clear();
  100. return false;
  101. }
  102. }
  103. return true;
  104. }