enclave_entry.S 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358
  1. #include "sgx_arch.h"
  2. #include "sgx_tls.h"
  3. .extern ecall_table
  4. .extern enclave_ecall_pal_main
  5. .global enclave_entry
  6. .type enclave_entry, @function
  7. enclave_entry:
  8. # current SSA is in RAX
  9. cmp $0, %rax
  10. jne .Lhandle_resume
  11. # AEP address in RCX
  12. mov %rcx, %gs:SGX_AEP
  13. cmp $RETURN_FROM_OCALL, %rdi
  14. je .Lreturn_from_ocall
  15. # move stack address to both urts_orig_stack and urts_stack
  16. mov %rsp, %gs:SGX_URTS_INITIAL_STACK
  17. mov %rsp, %gs:SGX_URTS_STACK
  18. # switch the stack specified in TLS
  19. mov %gs:SGX_INITIAL_STACK, %rsp
  20. # exit target in RDX
  21. mov %rdx, %gs:SGX_EXIT_TARGET
  22. # debug counter register in R8
  23. mov %r8, %gs:SGX_DEBUG_REGISTER
  24. cmp $0, %rdi
  25. jne .Lhandle_ecall
  26. lea enclave_ecall_pal_main(%rip), %rbx
  27. jmp .Lcall_ecall
  28. .Lhandle_ecall:
  29. lea ecall_table(%rip), %rbx
  30. mov (%rbx,%rdi,8), %rbx
  31. .Lcall_ecall:
  32. mov %rsi, %rdi
  33. call *%rbx
  34. # never return to this point (should die)
  35. xor %rdi, %rdi
  36. xor %rsi, %rsi
  37. jmp .Leexit
  38. .Lhandle_resume:
  39. # get some information from GPR
  40. mov %gs:SGX_GPR, %rbx
  41. # check if there is external event in R9
  42. cmp $0, %r9
  43. je .Lno_external_event_in_resume
  44. mov %r9, %rdi
  45. jmp .Lhandle_exception
  46. .Lno_external_event_in_resume:
  47. xor %rdi, %rdi
  48. mov SGX_GPR_EXITINFO(%rbx), %edi
  49. test $0x80000000, %edi
  50. jnz .Lhandle_exception
  51. #if SGX_HAS_FSGSBASE == 0
  52. mov %gs:SGX_FSBASE, %rdi
  53. cmp $0, %rdi
  54. je .Ljust_resume
  55. mov SGX_GPR_RSP(%rbx), %rsi
  56. sub $16, %rsi
  57. mov %rsi, SGX_GPR_RSP(%rbx)
  58. # try to push rip and fsbase onto the stack
  59. mov %rdi, (%rsi)
  60. mov SGX_GPR_RIP(%rbx), %rdi
  61. mov %rdi, 8(%rsi)
  62. # new RIP is the resume point
  63. lea .Lafter_resume(%rip), %rdi
  64. mov %rdi, SGX_GPR_RIP(%rbx)
  65. .Ljust_resume:
  66. #endif
  67. # clear the registers
  68. xor %rdi, %rdi
  69. xor %rsi, %rsi
  70. # exit address in RDX, mov it to RBX
  71. mov %rdx, %rbx
  72. mov $EEXIT, %rax
  73. ENCLU
  74. #if SGX_HAS_FSGSBASE == 0
  75. .Lafter_resume:
  76. mov %rax, -8(%rsp)
  77. pop %rax
  78. .byte 0xf3, 0x48, 0x0f, 0xae, 0xd0 /* WRFSBASE %RAX */
  79. mov -16(%rsp), %rax
  80. ret
  81. #endif
  82. .Lhandle_exception:
  83. mov SGX_GPR_RSP(%rbx), %rsi
  84. sub $0x90, %rsi
  85. # we have exitinfo in RDI, swap with the one on GPR
  86. # and dump into the context
  87. xchg %rdi, SGX_GPR_RDI(%rbx)
  88. mov %rdi, 0x38(%rsi)
  89. # dump the rest of context
  90. mov SGX_GPR_RAX(%rbx), %rdi
  91. mov %rdi, 0x00(%rsi)
  92. mov SGX_GPR_RCX(%rbx), %rdi
  93. mov %rdi, 0x08(%rsi)
  94. mov SGX_GPR_RDX(%rbx), %rdi
  95. mov %rdi, 0x10(%rsi)
  96. mov SGX_GPR_RBX(%rbx), %rdi
  97. mov %rdi, 0x18(%rsi)
  98. mov SGX_GPR_RSP(%rbx), %rdi
  99. mov %rdi, 0x20(%rsi)
  100. mov SGX_GPR_RBP(%rbx), %rdi
  101. mov %rdi, 0x28(%rsi)
  102. mov SGX_GPR_RSI(%rbx), %rdi
  103. mov %rdi, 0x30(%rsi)
  104. mov SGX_GPR_R8(%rbx), %rdi
  105. mov %rdi, 0x40(%rsi)
  106. mov SGX_GPR_R9(%rbx), %rdi
  107. mov %rdi, 0x48(%rsi)
  108. mov SGX_GPR_R10(%rbx), %rdi
  109. mov %rdi, 0x50(%rsi)
  110. mov SGX_GPR_R11(%rbx), %rdi
  111. mov %rdi, 0x58(%rsi)
  112. mov SGX_GPR_R12(%rbx), %rdi
  113. mov %rdi, 0x60(%rsi)
  114. mov SGX_GPR_R13(%rbx), %rdi
  115. mov %rdi, 0x68(%rsi)
  116. mov SGX_GPR_R14(%rbx), %rdi
  117. mov %rdi, 0x70(%rsi)
  118. mov SGX_GPR_R15(%rbx), %rdi
  119. mov %rdi, 0x78(%rsi)
  120. mov SGX_GPR_RFLAGS(%rbx), %rdi
  121. mov %rdi, 0x80(%rsi)
  122. mov SGX_GPR_RIP(%rbx), %rdi
  123. mov %rdi, 0x88(%rsi)
  124. mov %rsi, SGX_GPR_RSP(%rbx)
  125. mov %rsi, SGX_GPR_RSI(%rbx)
  126. # new RIP is the exception handler
  127. lea _DkExceptionHandler(%rip), %rdi
  128. mov %rdi, SGX_GPR_RIP(%rbx)
  129. # clear the registers
  130. xor %rdi, %rdi
  131. xor %rsi, %rsi
  132. # exit address in RDX, mov it to RBX
  133. mov %rdx, %rbx
  134. mov $EEXIT, %rax
  135. ENCLU
  136. .global sgx_ocall
  137. .type sgx_ocall, @function
  138. sgx_ocall:
  139. push %rbp
  140. mov %rsp, %rbp
  141. sub $XSAVE_SIZE, %rsp
  142. and $XSAVE_ALIGN, %rsp
  143. fxsave (%rsp)
  144. push %rbx
  145. push %rdx
  146. push %rcx
  147. push %rsi
  148. push %rdi
  149. push %r8
  150. push %r9
  151. push %r10
  152. push %r11
  153. push %r12
  154. push %r13
  155. push %r14
  156. push %r15
  157. push %rbp
  158. pushfq
  159. mov %rsp, %gs:SGX_LAST_STACK
  160. jmp .Leexit
  161. .Lexception_handler:
  162. .Leexit:
  163. xor %rdx, %rdx
  164. xor %r8, %r8
  165. xor %r9, %r9
  166. xor %r10, %r10
  167. xor %r11, %r11
  168. xor %r12, %r12
  169. xor %r13, %r13
  170. xor %r14, %r14
  171. xor %r15, %r15
  172. xor %rbp, %rbp
  173. mov %gs:SGX_URTS_STACK, %rsp
  174. and $STACK_ALIGN, %rsp
  175. mov %gs:SGX_EXIT_TARGET, %rbx
  176. mov %gs:SGX_AEP, %rcx
  177. mov $EEXIT, %rax
  178. ENCLU
  179. .Lreturn_from_ocall:
  180. # save ocall return value
  181. mov %rsi, %gs:SGX_LAST_OCALL_RESULT
  182. # check if there is external event in R9
  183. cmp $0, %r9
  184. je .Lno_external_event
  185. mov %r9, %gs:SGX_EXTERNAL_EVENT
  186. .Lno_external_event:
  187. # restore the stack
  188. mov %gs:SGX_LAST_STACK, %rsp
  189. popfq
  190. pop %rbp
  191. pop %r15
  192. pop %r14
  193. pop %r13
  194. pop %r12
  195. pop %r11
  196. pop %r10
  197. pop %r9
  198. pop %r8
  199. pop %rdi
  200. pop %rsi
  201. pop %rcx
  202. pop %rdx
  203. pop %rbx
  204. fxrstor (%rsp)
  205. mov %gs:SGX_FSBASE, %rax
  206. cmp $0, %rax
  207. je .Lno_fsbase
  208. .byte 0xf3, 0x48, 0x0f, 0xae, 0xd0 /* WRFSBASE %RAX */
  209. .Lno_fsbase:
  210. mov %gs:SGX_LAST_OCALL_RESULT, %rax
  211. leave
  212. ret
  213. /*
  214. * sgx_report:
  215. * Generate SGX hardware signed report.
  216. */
  217. .global sgx_report
  218. .type sgx_report, @function
  219. sgx_report:
  220. .cfi_startproc
  221. push %rbx
  222. push %rcx
  223. mov %rdi, %rbx
  224. mov %rsi, %rcx
  225. mov $EREPORT, %rax
  226. ENCLU
  227. pop %rcx
  228. pop %rbx
  229. ret
  230. .cfi_endproc
  231. .size sgx_report, .-sgx_report
  232. /*
  233. * sgx_getkey:
  234. * Retreive SGX hardware enclave cryptography key.
  235. */
  236. .global sgx_getkey
  237. .type sgx_getkey, @function
  238. sgx_getkey:
  239. .cfi_startproc
  240. push %rbx
  241. push %rcx
  242. mov %rdi, %rbx
  243. mov %rsi, %rcx
  244. mov $EGETKEY, %rax
  245. ENCLU
  246. pop %rcx
  247. pop %rbx
  248. ret
  249. .cfi_endproc
  250. .size sgx_getkey, .-sgx_getkey
  251. /*
  252. * rdrand:
  253. * Get hardware generated random value.
  254. */
  255. .global rdrand
  256. .type rdrand, @function
  257. rdrand:
  258. .cfi_startproc
  259. .Lretry_rdrand:
  260. .byte 0x0f, 0xc7, 0xf0 /* RDRAND %EAX */
  261. jnc .Lretry_rdrand
  262. ret
  263. .cfi_endproc
  264. .size rdrand, .-rdrand
  265. /*
  266. * rdfsbase:
  267. * read FS register (allowed in enclaves).
  268. */
  269. .global rdfsbase
  270. .type rdfsbase, @function
  271. rdfsbase:
  272. .cfi_startproc
  273. .byte 0xf3, 0x48, 0x0f, 0xae, 0xc0 /* RDFSBASE %RAX */
  274. ret
  275. .cfi_endproc
  276. .size rdfsbase, .-rdfsbase
  277. /*
  278. * wrfsbase:
  279. * modify FS register (allowed in enclaves).
  280. */
  281. .global wrfsbase
  282. .type wrfsbase, @function
  283. wrfsbase:
  284. .cfi_startproc
  285. .byte 0xf3, 0x48, 0x0f, 0xae, 0xd7 /* WRFSBASE %RDI */
  286. ret
  287. .cfi_endproc
  288. .size wrfsbase, .-wrfsbase