asm-inline-s390x.h 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206
  1. /* asm-inline-s390x.h - Common macros for zSeries inline assembly
  2. *
  3. * Copyright (C) 2020 Jussi Kivilinna <jussi.kivilinna@iki.fi>
  4. *
  5. * This file is part of Libgcrypt.
  6. *
  7. * Libgcrypt is free software; you can redistribute it and/or modify
  8. * it under the terms of the GNU Lesser General Public License as
  9. * published by the Free Software Foundation; either version 2.1 of
  10. * the License, or (at your option) any later version.
  11. *
  12. * Libgcrypt is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU Lesser General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU Lesser General Public
  18. * License along with this program; if not, see <http://www.gnu.org/licenses/>.
  19. */
  20. #ifndef GCRY_ASM_INLINE_S390X_H
  21. #define GCRY_ASM_INLINE_S390X_H
  22. #include <config.h>
  23. #define ALWAYS_INLINE inline __attribute__((always_inline))
  24. typedef unsigned int u128_t __attribute__ ((mode (TI)));
  25. enum kmxx_functions_e
  26. {
  27. KM_FUNCTION_AES_128 = 18,
  28. KM_FUNCTION_AES_192 = 19,
  29. KM_FUNCTION_AES_256 = 20,
  30. KM_FUNCTION_XTS_AES_128 = 50,
  31. KM_FUNCTION_XTS_AES_256 = 52,
  32. KMID_FUNCTION_SHA1 = 1,
  33. KMID_FUNCTION_SHA256 = 2,
  34. KMID_FUNCTION_SHA512 = 3,
  35. KMID_FUNCTION_SHA3_224 = 32,
  36. KMID_FUNCTION_SHA3_256 = 33,
  37. KMID_FUNCTION_SHA3_384 = 34,
  38. KMID_FUNCTION_SHA3_512 = 35,
  39. KMID_FUNCTION_SHAKE128 = 36,
  40. KMID_FUNCTION_SHAKE256 = 37,
  41. KMID_FUNCTION_GHASH = 65,
  42. PCC_FUNCTION_NIST_P256 = 64,
  43. PCC_FUNCTION_NIST_P384 = 65,
  44. PCC_FUNCTION_NIST_P521 = 66,
  45. PCC_FUNCTION_ED25519 = 72,
  46. PCC_FUNCTION_ED448 = 73,
  47. PCC_FUNCTION_X25519 = 80,
  48. PCC_FUNCTION_X448 = 81
  49. };
  50. enum kmxx_function_flags_e
  51. {
  52. KM_ENCRYPT = 0 << 7,
  53. KM_DECRYPT = 1 << 7,
  54. KMF_LCFB_16 = 16 << 24,
  55. KMA_LPC = 1 << 8,
  56. KMA_LAAD = 1 << 9,
  57. KMA_HS = 1 << 10,
  58. KLMD_PADDING_STATE = 1 << 8,
  59. };
  60. static ALWAYS_INLINE u128_t km_function_to_mask(enum kmxx_functions_e func)
  61. {
  62. return (u128_t)1 << (127 - func);
  63. }
  64. static inline u128_t kimd_query(void)
  65. {
  66. static u128_t function_codes = 0;
  67. static int initialized = 0;
  68. register unsigned long reg0 asm("0") = 0;
  69. register void *reg1 asm("1") = &function_codes;
  70. u128_t r1;
  71. if (initialized)
  72. return function_codes;
  73. asm volatile ("0: .insn rre,0xb93e << 16, 0, %[r1]\n\t"
  74. " brc 1,0b\n\t"
  75. : [r1] "=a" (r1)
  76. : [reg0] "r" (reg0), [reg1] "r" (reg1)
  77. : "cc", "memory");
  78. initialized = 1;
  79. return function_codes;
  80. }
  81. static inline u128_t klmd_query(void)
  82. {
  83. static u128_t function_codes = 0;
  84. static int initialized = 0;
  85. register unsigned long reg0 asm("0") = 0;
  86. register void *reg1 asm("1") = &function_codes;
  87. u128_t r1;
  88. if (initialized)
  89. return function_codes;
  90. asm volatile ("0: .insn rre,0xb93f << 16, 0, %[r1]\n\t"
  91. " brc 1,0b\n\t"
  92. : [r1] "=a" (r1)
  93. : [reg0] "r" (reg0), [reg1] "r" (reg1)
  94. : "cc", "memory");
  95. initialized = 1;
  96. return function_codes;
  97. }
  98. static inline u128_t pcc_query(void)
  99. {
  100. static u128_t function_codes = 0;
  101. static int initialized = 0;
  102. register unsigned long reg0 asm("0") = 0;
  103. register void *reg1 asm("1") = &function_codes;
  104. if (initialized)
  105. return function_codes;
  106. asm volatile ("0: .insn rre,0xb92c << 16, 0, 0\n\t"
  107. " brc 1,0b\n\t"
  108. :
  109. : [reg0] "r" (reg0), [reg1] "r" (reg1)
  110. : "cc", "memory");
  111. initialized = 1;
  112. return function_codes;
  113. }
  114. static ALWAYS_INLINE void
  115. kimd_execute(unsigned int func, void *param_block, const void *src,
  116. size_t src_len)
  117. {
  118. register unsigned long reg0 asm("0") = func;
  119. register byte *reg1 asm("1") = param_block;
  120. u128_t r1 = ((u128_t)(uintptr_t)src << 64) | (u64)src_len;
  121. asm volatile ("0: .insn rre,0xb93e << 16, 0, %[r1]\n\t"
  122. " brc 1,0b\n\t"
  123. : [r1] "+a" (r1)
  124. : [func] "r" (reg0), [param_ptr] "r" (reg1)
  125. : "cc", "memory");
  126. }
  127. static ALWAYS_INLINE void
  128. klmd_execute(unsigned int func, void *param_block, const void *src,
  129. size_t src_len)
  130. {
  131. register unsigned long reg0 asm("0") = func;
  132. register byte *reg1 asm("1") = param_block;
  133. u128_t r1 = ((u128_t)(uintptr_t)src << 64) | (u64)src_len;
  134. asm volatile ("0: .insn rre,0xb93f << 16, 0, %[r1]\n\t"
  135. " brc 1,0b\n\t"
  136. : [func] "+r" (reg0), [r1] "+a" (r1)
  137. : [param_ptr] "r" (reg1)
  138. : "cc", "memory");
  139. }
  140. static ALWAYS_INLINE void
  141. klmd_shake_execute(unsigned int func, void *param_block, void *dst,
  142. size_t dst_len, const void *src, size_t src_len)
  143. {
  144. register unsigned long reg0 asm("0") = func;
  145. register byte *reg1 asm("1") = param_block;
  146. u128_t r1 = ((u128_t)(uintptr_t)dst << 64) | (u64)dst_len;
  147. u128_t r2 = ((u128_t)(uintptr_t)src << 64) | (u64)src_len;
  148. asm volatile ("0: .insn rre,0xb93f << 16, %[r1], %[r2]\n\t"
  149. " brc 1,0b\n\t"
  150. : [func] "+r" (reg0), [r1] "+a" (r1), [r2] "+a" (r2)
  151. : [param_ptr] "r" (reg1)
  152. : "cc", "memory");
  153. }
  154. static ALWAYS_INLINE unsigned int
  155. pcc_scalar_multiply(unsigned int func, void *param_block)
  156. {
  157. register unsigned long reg0 asm("0") = func;
  158. register byte *reg1 asm("1") = param_block;
  159. register unsigned long error = 0;
  160. asm volatile ("0: .insn rre,0xb92c << 16, 0, 0\n\t"
  161. " brc 1,0b\n\t"
  162. " brc 7,1f\n\t"
  163. " j 2f\n\t"
  164. "1: lhi %[error], 1\n\t"
  165. "2:\n\t"
  166. : [func] "+r" (reg0), [error] "+r" (error)
  167. : [param_ptr] "r" (reg1)
  168. : "cc", "memory");
  169. return error;
  170. }
  171. #endif /* GCRY_ASM_INLINE_S390X_H */