test_encl.c 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. // SPDX-License-Identifier: GPL-2.0
  2. /* Copyright(c) 2016-20 Intel Corporation. */
  3. #include <stddef.h>
  4. #include "defines.h"
  5. /*
  6. * Data buffer spanning two pages that will be placed first in .data
  7. * segment. Even if not used internally the second page is needed by
  8. * external test manipulating page permissions.
  9. */
  10. static uint8_t encl_buffer[8192] = { 1 };
  11. enum sgx_enclu_function {
  12. EACCEPT = 0x5,
  13. EMODPE = 0x6,
  14. };
  15. static void do_encl_emodpe(void *_op)
  16. {
  17. struct sgx_secinfo secinfo __aligned(sizeof(struct sgx_secinfo)) = {0};
  18. struct encl_op_emodpe *op = _op;
  19. secinfo.flags = op->flags;
  20. asm volatile(".byte 0x0f, 0x01, 0xd7"
  21. :
  22. : "a" (EMODPE),
  23. "b" (&secinfo),
  24. "c" (op->epc_addr));
  25. }
  26. static void do_encl_eaccept(void *_op)
  27. {
  28. struct sgx_secinfo secinfo __aligned(sizeof(struct sgx_secinfo)) = {0};
  29. struct encl_op_eaccept *op = _op;
  30. int rax;
  31. secinfo.flags = op->flags;
  32. asm volatile(".byte 0x0f, 0x01, 0xd7"
  33. : "=a" (rax)
  34. : "a" (EACCEPT),
  35. "b" (&secinfo),
  36. "c" (op->epc_addr));
  37. op->ret = rax;
  38. }
  39. static void *memcpy(void *dest, const void *src, size_t n)
  40. {
  41. size_t i;
  42. for (i = 0; i < n; i++)
  43. ((char *)dest)[i] = ((char *)src)[i];
  44. return dest;
  45. }
  46. static void *memset(void *dest, int c, size_t n)
  47. {
  48. size_t i;
  49. for (i = 0; i < n; i++)
  50. ((char *)dest)[i] = c;
  51. return dest;
  52. }
  53. static void do_encl_init_tcs_page(void *_op)
  54. {
  55. struct encl_op_init_tcs_page *op = _op;
  56. void *tcs = (void *)op->tcs_page;
  57. uint32_t val_32;
  58. memset(tcs, 0, 16); /* STATE and FLAGS */
  59. memcpy(tcs + 16, &op->ssa, 8); /* OSSA */
  60. memset(tcs + 24, 0, 4); /* CSSA */
  61. val_32 = 1;
  62. memcpy(tcs + 28, &val_32, 4); /* NSSA */
  63. memcpy(tcs + 32, &op->entry, 8); /* OENTRY */
  64. memset(tcs + 40, 0, 24); /* AEP, OFSBASE, OGSBASE */
  65. val_32 = 0xFFFFFFFF;
  66. memcpy(tcs + 64, &val_32, 4); /* FSLIMIT */
  67. memcpy(tcs + 68, &val_32, 4); /* GSLIMIT */
  68. memset(tcs + 72, 0, 4024); /* Reserved */
  69. }
  70. static void do_encl_op_put_to_buf(void *op)
  71. {
  72. struct encl_op_put_to_buf *op2 = op;
  73. memcpy(&encl_buffer[0], &op2->value, 8);
  74. }
  75. static void do_encl_op_get_from_buf(void *op)
  76. {
  77. struct encl_op_get_from_buf *op2 = op;
  78. memcpy(&op2->value, &encl_buffer[0], 8);
  79. }
  80. static void do_encl_op_put_to_addr(void *_op)
  81. {
  82. struct encl_op_put_to_addr *op = _op;
  83. memcpy((void *)op->addr, &op->value, 8);
  84. }
  85. static void do_encl_op_get_from_addr(void *_op)
  86. {
  87. struct encl_op_get_from_addr *op = _op;
  88. memcpy(&op->value, (void *)op->addr, 8);
  89. }
  90. static void do_encl_op_nop(void *_op)
  91. {
  92. }
  93. void encl_body(void *rdi, void *rsi)
  94. {
  95. const void (*encl_op_array[ENCL_OP_MAX])(void *) = {
  96. do_encl_op_put_to_buf,
  97. do_encl_op_get_from_buf,
  98. do_encl_op_put_to_addr,
  99. do_encl_op_get_from_addr,
  100. do_encl_op_nop,
  101. do_encl_eaccept,
  102. do_encl_emodpe,
  103. do_encl_init_tcs_page,
  104. };
  105. struct encl_op_header *op = (struct encl_op_header *)rdi;
  106. if (op->type < ENCL_OP_MAX)
  107. (*encl_op_array[op->type])(op);
  108. }