oasm_lib.h 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183
  1. /*
  2. * ZeroTrace: Oblivious Memory Primitives from Intel SGX
  3. * Copyright (C) 2018 Sajin (sshsshy)
  4. *
  5. * This program is free software: you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License as published by
  7. * the Free Software Foundation, version 3 of the License.
  8. *
  9. * This program is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. * GNU General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU General Public License
  15. * along with this program. If not, see <https://www.gnu.org/licenses/>.
  16. */
  17. #ifndef __OASM_LIB__
  18. #define __OASM_LIB__
  19. #include <cstdint>
  20. #ifndef BEFTS_MODE
  21. #include "CONFIG.h"
  22. #endif
  23. #ifdef COUNT_OSWAPS
  24. extern thread_local uint64_t OSWAP_COUNTER;
  25. #endif
  26. // Oblivious Buffer move/swap functions:
  27. #if 0
  28. extern "C" void oswap_buffer_16x(unsigned char *dest, unsigned char *source, uint32_t buffersize, uint8_t flag);
  29. extern "C" void oswap_buffer_byte(unsigned char *dest, unsigned char *source, uint32_t buffersize, uint8_t flag);
  30. extern "C" void oswap_buffer_byte_16x(unsigned char *dest, unsigned char *source, uint32_t buffersize, uint8_t flag);
  31. extern "C" void oswap_buffer_byte_v2(unsigned char *dest, unsigned char *source, uint8_t flag);
  32. extern "C" void ogt_comp_swap(uint64_t *key1, uint64_t *key2, unsigned char *buff1, unsigned char *buff2, uint32_t buffersize);
  33. #endif
  34. enum OSwap_Style { OSWAP_4, OSWAP_8, OSWAP_12, OSWAP_16X, OSWAP_8_16X };
  35. template<OSwap_Style oswap_style> inline void oswap_buffer(unsigned char *dest, unsigned char *source, uint32_t buffersize, uint8_t flag);
  36. template<typename KeyType> inline void oswap_key(unsigned char *dest, unsigned char *source, uint8_t flag);
  37. template<OSwap_Style oswap_style> inline void omove_buffer(unsigned char *dest, unsigned char *source, uint32_t buffersize, uint8_t flag);
  38. inline uint8_t ogt_set_flag(uint64_t key1, uint64_t key2)
  39. {
  40. uint8_t flag;
  41. __asm__ (
  42. "# inline ogt_set_flag\n"
  43. "cmp %[key2], %[key1]\n"
  44. //"# FOAV ogt_set_flag key1 (%[key1]):\n"
  45. "seta %[flag]\n"
  46. : [flag] "=r" (flag)
  47. : [key1] "r" (key1), [key2] "r" (key2)
  48. : "cc"
  49. );
  50. return flag;
  51. }
  52. // A size-templated version of oblivious greater than for wide-key Bitonic Sort
  53. // Returns 1 if (*key1p) > (*key2p), and 0 otherwise, in a fully oblivious manner.
  54. template<typename keytype>
  55. inline uint8_t ogt(const keytype *key1p, const keytype *key2p);
  56. template<>
  57. inline uint8_t ogt<uint32_t>(const uint32_t *key1p, const uint32_t *key2p)
  58. {
  59. uint8_t flag;
  60. __asm__ (
  61. "# inline ogt_uint32\n"
  62. "movl (%[key1p]), %%eax\n"
  63. "cmpl (%[key2p]), %%eax\n"
  64. "seta %[flag]\n"
  65. : [flag] "=r" (flag)
  66. : [key1p] "r" (key1p), [key2p] "r" (key2p)
  67. : "eax", "cc"
  68. );
  69. return flag;
  70. }
  71. template<>
  72. inline uint8_t ogt<uint64_t>(const uint64_t *key1p, const uint64_t *key2p) {
  73. __asm__ ("# inline ogt_uint64\n");
  74. return ogt_set_flag(*key1p, *key2p);
  75. }
  76. template<>
  77. inline uint8_t ogt<__uint128_t>(const __uint128_t *key1p, const __uint128_t *key2p) {
  78. uint8_t flag;
  79. __asm__ (
  80. "# inline ogt_uint128\n"
  81. "movq 8(%[key2p]), %%rcx\n"
  82. "movq (%[key1p]), %%rax\n"
  83. "cmpq %%rax, (%[key2p])\n"
  84. "sbbq 8(%[key1p]), %%rcx\n"
  85. "setc %[flag]\n"
  86. : [flag] "=r" (flag)
  87. : [key1p] "r" (key1p), [key2p] "r" (key2p)
  88. : "rax", "rcx", "cc"
  89. );
  90. return flag;
  91. }
  92. inline uint8_t oge_set_flag(uint64_t key1, uint64_t key2)
  93. {
  94. uint8_t flag;
  95. __asm__ (
  96. "# inline oge_set_flag\n"
  97. "cmp %[key2], %[key1]\n"
  98. //"# FOAV oge_set_flag key1 (%[key1]):\n"
  99. "setae %[flag]\n"
  100. : [flag] "=r" (flag)
  101. : [key1] "r" (key1), [key2] "r" (key2)
  102. : "cc"
  103. );
  104. return flag;
  105. }
  106. inline uint8_t oe_set_flag(uint32_t key1, uint32_t key2)
  107. {
  108. uint8_t flag;
  109. __asm__ (
  110. "# inline oe_set_flag\n"
  111. "cmp %[key2], %[key1]\n"
  112. //"# FOAV oe_set_flag key1 (%[key1]):\n"
  113. "sete %[flag]\n"
  114. : [flag] "=r" (flag)
  115. : [key1] "r" (key1), [key2] "r" (key2)
  116. : "cc"
  117. );
  118. return flag;
  119. }
  120. inline void oset_value(uint64_t *dest, uint64_t value, uint32_t flag)
  121. {
  122. __asm__ (
  123. "# inline oset_value\n"
  124. "mov (%[dest]), %%r10\n"
  125. "test %[flag], %[flag]\n"
  126. "cmovnz %[value], %%r10\n"
  127. "mov %%r10, (%[dest])\n"
  128. :
  129. : [dest] "r" (dest), [value] "r" (value), [flag] "r" (flag)
  130. : "cc", "memory", "r10"
  131. );
  132. }
  133. inline void oset_value_uint32_t(uint32_t *dest, uint32_t value, uint8_t flag)
  134. {
  135. __asm__ (
  136. "# inline oset_value_uint32_t\n"
  137. "mov (%[dest]), %%r10d\n"
  138. "test %[flag], %[flag]\n"
  139. "cmovnz %[value], %%r10d\n"
  140. "mov %%r10d, (%[dest])\n"
  141. :
  142. : [dest] "r" (dest), [value] "r" (value), [flag] "r" (flag)
  143. : "cc", "memory", "r10"
  144. );
  145. }
  146. inline uint32_t oselect_uint32_t(uint32_t value_0, uint32_t value_1, uint8_t flag)
  147. {
  148. uint32_t out;
  149. __asm__ (
  150. "# inline oselect_uint32_t\n"
  151. "mov %[value0], %[out]\n"
  152. "test %[flag], %[flag]\n"
  153. "cmovnz %[value1], %[out]\n"
  154. : [out] "=&r" (out)
  155. : [value0] "r" (value_0), [value1] "r" (value_1), [flag] "r" (flag)
  156. : "cc"
  157. );
  158. return out;
  159. }
  160. #include "oasm_lib.tcc"
  161. #endif