ecx_s390x.c 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217
  1. /*
  2. * Copyright 2006-2020 The OpenSSL Project Authors. All Rights Reserved.
  3. *
  4. * Licensed under the Apache License 2.0 (the "License"). You may not use
  5. * this file except in compliance with the License. You can obtain a copy
  6. * in the file LICENSE in the source distribution or at
  7. * https://www.openssl.org/source/license.html
  8. */
  9. #include <stdio.h>
  10. #include "internal/cryptlib.h"
  11. #include <openssl/ec.h>
  12. #include <openssl/rand.h>
  13. #include "crypto/ecx.h"
  14. #include "ec_local.h"
  15. #include "curve448/curve448_local.h"
  16. #include "ecx_backend.h"
  17. #include "s390x_arch.h"
  18. #include "internal/constant_time.h"
  19. static void s390x_x25519_mod_p(unsigned char u[32])
  20. {
  21. unsigned char u_red[32];
  22. unsigned int c = 0;
  23. int i;
  24. memcpy(u_red, u, sizeof(u_red));
  25. c += (unsigned int)u_red[31] + 19;
  26. u_red[31] = (unsigned char)c;
  27. c >>= 8;
  28. for (i = 30; i >= 0; i--) {
  29. c += (unsigned int)u_red[i];
  30. u_red[i] = (unsigned char)c;
  31. c >>= 8;
  32. }
  33. c = (u_red[0] & 0x80) >> 7;
  34. u_red[0] &= 0x7f;
  35. constant_time_cond_swap_buff(0 - (unsigned char)c,
  36. u, u_red, sizeof(u_red));
  37. }
  38. static void s390x_x448_mod_p(unsigned char u[56])
  39. {
  40. unsigned char u_red[56];
  41. unsigned int c = 0;
  42. int i;
  43. memcpy(u_red, u, sizeof(u_red));
  44. c += (unsigned int)u_red[55] + 1;
  45. u_red[55] = (unsigned char)c;
  46. c >>= 8;
  47. for (i = 54; i >= 28; i--) {
  48. c += (unsigned int)u_red[i];
  49. u_red[i] = (unsigned char)c;
  50. c >>= 8;
  51. }
  52. c += (unsigned int)u_red[27] + 1;
  53. u_red[27] = (unsigned char)c;
  54. c >>= 8;
  55. for (i = 26; i >= 0; i--) {
  56. c += (unsigned int)u_red[i];
  57. u_red[i] = (unsigned char)c;
  58. c >>= 8;
  59. }
  60. constant_time_cond_swap_buff(0 - (unsigned char)c,
  61. u, u_red, sizeof(u_red));
  62. }
  63. int s390x_x25519_mul(unsigned char u_dst[32],
  64. const unsigned char u_src[32],
  65. const unsigned char d_src[32])
  66. {
  67. union {
  68. struct {
  69. unsigned char u_dst[32];
  70. unsigned char u_src[32];
  71. unsigned char d_src[32];
  72. } x25519;
  73. unsigned long long buff[512];
  74. } param;
  75. int rc;
  76. memset(&param, 0, sizeof(param));
  77. s390x_flip_endian32(param.x25519.u_src, u_src);
  78. param.x25519.u_src[0] &= 0x7f;
  79. s390x_x25519_mod_p(param.x25519.u_src);
  80. s390x_flip_endian32(param.x25519.d_src, d_src);
  81. param.x25519.d_src[31] &= 248;
  82. param.x25519.d_src[0] &= 127;
  83. param.x25519.d_src[0] |= 64;
  84. rc = s390x_pcc(S390X_SCALAR_MULTIPLY_X25519, &param.x25519) ? 0 : 1;
  85. if (rc == 1)
  86. s390x_flip_endian32(u_dst, param.x25519.u_dst);
  87. OPENSSL_cleanse(param.x25519.d_src, sizeof(param.x25519.d_src));
  88. return rc;
  89. }
  90. int s390x_x448_mul(unsigned char u_dst[56],
  91. const unsigned char u_src[56],
  92. const unsigned char d_src[56])
  93. {
  94. union {
  95. struct {
  96. unsigned char u_dst[64];
  97. unsigned char u_src[64];
  98. unsigned char d_src[64];
  99. } x448;
  100. unsigned long long buff[512];
  101. } param;
  102. int rc;
  103. memset(&param, 0, sizeof(param));
  104. memcpy(param.x448.u_src, u_src, 56);
  105. memcpy(param.x448.d_src, d_src, 56);
  106. s390x_flip_endian64(param.x448.u_src, param.x448.u_src);
  107. s390x_x448_mod_p(param.x448.u_src + 8);
  108. s390x_flip_endian64(param.x448.d_src, param.x448.d_src);
  109. param.x448.d_src[63] &= 252;
  110. param.x448.d_src[8] |= 128;
  111. rc = s390x_pcc(S390X_SCALAR_MULTIPLY_X448, &param.x448) ? 0 : 1;
  112. if (rc == 1) {
  113. s390x_flip_endian64(param.x448.u_dst, param.x448.u_dst);
  114. memcpy(u_dst, param.x448.u_dst, 56);
  115. }
  116. OPENSSL_cleanse(param.x448.d_src, sizeof(param.x448.d_src));
  117. return rc;
  118. }
  119. int s390x_ed25519_mul(unsigned char x_dst[32],
  120. unsigned char y_dst[32],
  121. const unsigned char x_src[32],
  122. const unsigned char y_src[32],
  123. const unsigned char d_src[32])
  124. {
  125. union {
  126. struct {
  127. unsigned char x_dst[32];
  128. unsigned char y_dst[32];
  129. unsigned char x_src[32];
  130. unsigned char y_src[32];
  131. unsigned char d_src[32];
  132. } ed25519;
  133. unsigned long long buff[512];
  134. } param;
  135. int rc;
  136. memset(&param, 0, sizeof(param));
  137. s390x_flip_endian32(param.ed25519.x_src, x_src);
  138. s390x_flip_endian32(param.ed25519.y_src, y_src);
  139. s390x_flip_endian32(param.ed25519.d_src, d_src);
  140. rc = s390x_pcc(S390X_SCALAR_MULTIPLY_ED25519, &param.ed25519) ? 0 : 1;
  141. if (rc == 1) {
  142. s390x_flip_endian32(x_dst, param.ed25519.x_dst);
  143. s390x_flip_endian32(y_dst, param.ed25519.y_dst);
  144. }
  145. OPENSSL_cleanse(param.ed25519.d_src, sizeof(param.ed25519.d_src));
  146. return rc;
  147. }
  148. int s390x_ed448_mul(unsigned char x_dst[57],
  149. unsigned char y_dst[57],
  150. const unsigned char x_src[57],
  151. const unsigned char y_src[57],
  152. const unsigned char d_src[57])
  153. {
  154. union {
  155. struct {
  156. unsigned char x_dst[64];
  157. unsigned char y_dst[64];
  158. unsigned char x_src[64];
  159. unsigned char y_src[64];
  160. unsigned char d_src[64];
  161. } ed448;
  162. unsigned long long buff[512];
  163. } param;
  164. int rc;
  165. memset(&param, 0, sizeof(param));
  166. memcpy(param.ed448.x_src, x_src, 57);
  167. memcpy(param.ed448.y_src, y_src, 57);
  168. memcpy(param.ed448.d_src, d_src, 57);
  169. s390x_flip_endian64(param.ed448.x_src, param.ed448.x_src);
  170. s390x_flip_endian64(param.ed448.y_src, param.ed448.y_src);
  171. s390x_flip_endian64(param.ed448.d_src, param.ed448.d_src);
  172. rc = s390x_pcc(S390X_SCALAR_MULTIPLY_ED448, &param.ed448) ? 0 : 1;
  173. if (rc == 1) {
  174. s390x_flip_endian64(param.ed448.x_dst, param.ed448.x_dst);
  175. s390x_flip_endian64(param.ed448.y_dst, param.ed448.y_dst);
  176. memcpy(x_dst, param.ed448.x_dst, 57);
  177. memcpy(y_dst, param.ed448.y_dst, 57);
  178. }
  179. OPENSSL_cleanse(param.ed448.d_src, sizeof(param.ed448.d_src));
  180. return rc;
  181. }