grpc 1.13.0 → 1.14.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of grpc might be problematic. Click here for more details.

Files changed (213) hide show
  1. checksums.yaml +4 -4
  2. data/Makefile +403 -153
  3. data/include/grpc/grpc.h +0 -8
  4. data/include/grpc/grpc_security.h +59 -2
  5. data/include/grpc/impl/codegen/grpc_types.h +8 -2
  6. data/include/grpc/impl/codegen/log.h +112 -0
  7. data/include/grpc/module.modulemap +2 -0
  8. data/include/grpc/support/log.h +2 -88
  9. data/include/grpc/support/string_util.h +2 -0
  10. data/src/boringssl/err_data.c +597 -593
  11. data/src/core/ext/filters/client_channel/client_channel.cc +715 -770
  12. data/src/core/ext/filters/client_channel/client_channel.h +5 -0
  13. data/src/core/ext/filters/client_channel/client_channel_channelz.cc +111 -0
  14. data/src/core/ext/filters/client_channel/client_channel_channelz.h +69 -0
  15. data/src/core/ext/filters/client_channel/client_channel_plugin.cc +9 -0
  16. data/src/core/ext/filters/client_channel/http_proxy.cc +22 -5
  17. data/src/core/ext/filters/client_channel/lb_policy.h +15 -0
  18. data/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc +3 -0
  19. data/src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.cc +3 -3
  20. data/src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.h +3 -1
  21. data/src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/duration.pb.c +19 -0
  22. data/src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/duration.pb.h +54 -0
  23. data/src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/timestamp.pb.c +19 -0
  24. data/src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/timestamp.pb.h +54 -0
  25. data/src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c +4 -17
  26. data/src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h +37 -63
  27. data/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc +79 -0
  28. data/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc +5 -2
  29. data/src/core/ext/filters/client_channel/lb_policy_factory.cc +8 -0
  30. data/src/core/ext/filters/client_channel/lb_policy_factory.h +4 -0
  31. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc +2 -2
  32. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.cc +317 -0
  33. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h +48 -9
  34. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.cc +40 -293
  35. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc +106 -84
  36. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h +6 -2
  37. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc +6 -5
  38. data/src/core/ext/filters/client_channel/subchannel.cc +36 -6
  39. data/src/core/ext/filters/client_channel/subchannel.h +4 -0
  40. data/src/core/ext/filters/deadline/deadline_filter.cc +18 -15
  41. data/src/core/ext/filters/deadline/deadline_filter.h +5 -5
  42. data/src/core/ext/filters/http/client/http_client_filter.cc +10 -9
  43. data/src/core/ext/filters/http/server/http_server_filter.h +1 -1
  44. data/src/core/ext/transport/chttp2/client/insecure/channel_create_posix.cc +1 -1
  45. data/src/core/ext/transport/chttp2/server/insecure/server_chttp2_posix.cc +3 -2
  46. data/src/core/ext/transport/chttp2/transport/chttp2_transport.cc +33 -22
  47. data/src/core/ext/transport/chttp2/transport/hpack_parser.cc +1 -1
  48. data/src/core/ext/transport/chttp2/transport/internal.h +10 -3
  49. data/src/core/ext/transport/chttp2/transport/stream_lists.cc +17 -0
  50. data/src/core/ext/transport/chttp2/transport/writing.cc +21 -16
  51. data/src/core/ext/transport/inproc/inproc_transport.cc +46 -6
  52. data/src/core/lib/channel/channel_stack.cc +22 -24
  53. data/src/core/lib/channel/channel_trace.cc +28 -63
  54. data/src/core/lib/channel/channel_trace.h +13 -17
  55. data/src/core/lib/channel/channelz.cc +143 -0
  56. data/src/core/lib/channel/channelz.h +124 -0
  57. data/src/core/lib/channel/channelz_registry.cc +7 -24
  58. data/src/core/lib/channel/channelz_registry.h +12 -8
  59. data/src/core/lib/channel/connected_channel.cc +8 -1
  60. data/src/core/{ext/filters/load_reporting/server_load_reporting_filter.h → lib/gpr/alloc.h} +7 -9
  61. data/src/core/lib/gpr/arena.cc +8 -8
  62. data/src/core/lib/gpr/string.cc +28 -0
  63. data/src/core/lib/gpr/string.h +10 -0
  64. data/src/core/lib/gprpp/abstract.h +5 -2
  65. data/src/core/lib/gprpp/inlined_vector.h +57 -3
  66. data/src/core/lib/gprpp/memory.h +2 -2
  67. data/src/core/lib/gprpp/ref_counted_ptr.h +5 -0
  68. data/src/core/lib/gprpp/thd_posix.cc +1 -1
  69. data/src/core/lib/iomgr/call_combiner.h +80 -0
  70. data/src/core/lib/iomgr/closure.h +3 -2
  71. data/src/core/lib/iomgr/endpoint_pair_posix.cc +2 -2
  72. data/src/core/lib/iomgr/error.cc +12 -0
  73. data/src/core/lib/iomgr/error.h +5 -0
  74. data/src/core/lib/iomgr/ev_epoll1_linux.cc +36 -9
  75. data/src/core/lib/iomgr/ev_epollex_linux.cc +172 -46
  76. data/src/core/lib/iomgr/ev_epollsig_linux.cc +47 -21
  77. data/src/core/lib/iomgr/ev_poll_posix.cc +10 -4
  78. data/src/core/lib/iomgr/ev_posix.cc +17 -9
  79. data/src/core/lib/iomgr/ev_posix.h +20 -4
  80. data/src/core/lib/iomgr/executor.cc +196 -140
  81. data/src/core/lib/iomgr/executor.h +47 -14
  82. data/src/core/lib/iomgr/iomgr.cc +2 -0
  83. data/src/core/lib/iomgr/iomgr.h +5 -0
  84. data/src/core/lib/iomgr/is_epollexclusive_available.cc +1 -0
  85. data/src/core/lib/iomgr/socket_utils.h +9 -0
  86. data/src/core/lib/iomgr/socket_utils_common_posix.cc +4 -0
  87. data/src/core/lib/iomgr/socket_utils_uv.cc +4 -0
  88. data/src/core/lib/iomgr/socket_utils_windows.cc +4 -0
  89. data/src/core/lib/iomgr/tcp_client_posix.cc +3 -5
  90. data/src/core/lib/iomgr/tcp_posix.cc +6 -1
  91. data/src/core/lib/iomgr/tcp_server_posix.cc +3 -3
  92. data/src/core/lib/iomgr/tcp_server_utils_posix_common.cc +1 -1
  93. data/src/core/lib/iomgr/timer_manager.cc +0 -1
  94. data/src/core/lib/iomgr/udp_server.cc +2 -3
  95. data/src/core/lib/json/json.cc +10 -0
  96. data/src/core/lib/json/json.h +5 -0
  97. data/src/core/lib/security/context/security_context.cc +8 -8
  98. data/src/core/lib/security/context/security_context.h +6 -2
  99. data/src/core/lib/security/credentials/google_default/google_default_credentials.cc +2 -1
  100. data/src/core/lib/security/credentials/local/local_credentials.cc +77 -0
  101. data/src/core/lib/security/credentials/local/local_credentials.h +40 -0
  102. data/src/core/lib/security/credentials/ssl/ssl_credentials.cc +17 -3
  103. data/src/core/lib/security/security_connector/local_security_connector.cc +245 -0
  104. data/src/core/lib/security/security_connector/local_security_connector.h +58 -0
  105. data/src/core/lib/security/security_connector/security_connector.cc +30 -5
  106. data/src/core/lib/security/security_connector/security_connector.h +1 -0
  107. data/src/core/lib/security/transport/client_auth_filter.cc +5 -1
  108. data/src/core/lib/security/transport/server_auth_filter.cc +4 -5
  109. data/src/core/lib/surface/call.cc +75 -32
  110. data/src/core/lib/surface/call.h +2 -0
  111. data/src/core/lib/surface/channel.cc +32 -13
  112. data/src/core/lib/surface/channel.h +4 -0
  113. data/src/core/lib/surface/version.cc +1 -1
  114. data/src/core/lib/transport/transport.cc +20 -9
  115. data/src/core/lib/transport/transport.h +12 -10
  116. data/src/core/lib/transport/transport_op_string.cc +0 -7
  117. data/src/core/plugin_registry/grpc_plugin_registry.cc +0 -4
  118. data/src/core/tsi/alts/handshaker/alts_handshaker_service_api_util.h +2 -2
  119. data/src/core/tsi/alts/handshaker/alts_tsi_handshaker.cc +2 -1
  120. data/src/core/tsi/alts/handshaker/altscontext.pb.c +0 -1
  121. data/src/core/tsi/alts/handshaker/altscontext.pb.h +1 -2
  122. data/src/core/tsi/alts/handshaker/handshaker.pb.c +0 -1
  123. data/src/core/tsi/alts/handshaker/handshaker.pb.h +1 -2
  124. data/src/core/tsi/alts/handshaker/transport_security_common.pb.c +0 -1
  125. data/src/core/tsi/alts/handshaker/transport_security_common.pb.h +1 -1
  126. data/src/core/tsi/alts/handshaker/transport_security_common_api.h +2 -2
  127. data/src/core/tsi/alts/zero_copy_frame_protector/alts_grpc_integrity_only_record_protocol.cc +47 -1
  128. data/src/core/tsi/alts/zero_copy_frame_protector/alts_grpc_integrity_only_record_protocol.h +3 -1
  129. data/src/core/tsi/alts/zero_copy_frame_protector/alts_zero_copy_grpc_protector.cc +12 -11
  130. data/src/core/tsi/alts/zero_copy_frame_protector/alts_zero_copy_grpc_protector.h +7 -2
  131. data/src/core/tsi/local_transport_security.cc +209 -0
  132. data/src/core/tsi/local_transport_security.h +51 -0
  133. data/src/core/tsi/ssl_transport_security.cc +2 -3
  134. data/src/{core/ext → cpp/ext/filters}/census/grpc_context.cc +0 -0
  135. data/src/ruby/ext/grpc/rb_channel_credentials.c +3 -3
  136. data/src/ruby/ext/grpc/rb_grpc_imports.generated.c +18 -18
  137. data/src/ruby/ext/grpc/rb_grpc_imports.generated.h +29 -29
  138. data/src/ruby/lib/grpc/generic/active_call.rb +19 -23
  139. data/src/ruby/lib/grpc/version.rb +1 -1
  140. data/src/ruby/spec/call_credentials_spec.rb +1 -1
  141. data/src/ruby/spec/call_spec.rb +1 -1
  142. data/src/ruby/spec/channel_credentials_spec.rb +1 -1
  143. data/src/ruby/spec/channel_spec.rb +1 -1
  144. data/src/ruby/spec/client_auth_spec.rb +1 -12
  145. data/src/ruby/spec/client_server_spec.rb +1 -1
  146. data/src/ruby/spec/compression_options_spec.rb +1 -1
  147. data/src/ruby/spec/error_sanity_spec.rb +1 -1
  148. data/src/ruby/spec/generic/client_stub_spec.rb +13 -1
  149. data/src/ruby/spec/generic/rpc_desc_spec.rb +1 -1
  150. data/src/ruby/spec/generic/rpc_server_pool_spec.rb +1 -1
  151. data/src/ruby/spec/generic/service_spec.rb +1 -1
  152. data/src/ruby/spec/google_rpc_status_utils_spec.rb +1 -12
  153. data/src/ruby/spec/pb/duplicate/codegen_spec.rb +1 -0
  154. data/src/ruby/spec/pb/health/checker_spec.rb +1 -1
  155. data/src/ruby/spec/server_credentials_spec.rb +1 -1
  156. data/src/ruby/spec/server_spec.rb +1 -1
  157. data/src/ruby/spec/spec_helper.rb +1 -0
  158. data/src/ruby/spec/support/services.rb +1 -1
  159. data/src/ruby/spec/time_consts_spec.rb +1 -1
  160. data/third_party/boringssl/crypto/asn1/tasn_dec.c +40 -19
  161. data/third_party/boringssl/crypto/bytestring/cbs.c +1 -0
  162. data/third_party/boringssl/crypto/cipher_extra/e_aesccm.c +47 -15
  163. data/third_party/boringssl/crypto/ec_extra/ec_asn1.c +9 -10
  164. data/third_party/boringssl/crypto/ecdh/ecdh.c +4 -3
  165. data/third_party/boringssl/crypto/fipsmodule/bn/add.c +30 -54
  166. data/third_party/boringssl/crypto/fipsmodule/bn/bn.c +7 -1
  167. data/third_party/boringssl/crypto/fipsmodule/bn/cmp.c +8 -8
  168. data/third_party/boringssl/crypto/fipsmodule/bn/div.c +97 -11
  169. data/third_party/boringssl/crypto/fipsmodule/bn/gcd.c +274 -218
  170. data/third_party/boringssl/crypto/fipsmodule/bn/internal.h +111 -34
  171. data/third_party/boringssl/crypto/fipsmodule/bn/montgomery.c +2 -2
  172. data/third_party/boringssl/crypto/fipsmodule/bn/montgomery_inv.c +1 -1
  173. data/third_party/boringssl/crypto/fipsmodule/bn/mul.c +24 -6
  174. data/third_party/boringssl/crypto/fipsmodule/bn/prime.c +324 -63
  175. data/third_party/boringssl/crypto/fipsmodule/bn/random.c +74 -21
  176. data/third_party/boringssl/crypto/fipsmodule/bn/shift.c +128 -86
  177. data/third_party/boringssl/crypto/fipsmodule/bn/sqrt.c +1 -1
  178. data/third_party/boringssl/crypto/fipsmodule/ec/ec_key.c +67 -112
  179. data/third_party/boringssl/crypto/fipsmodule/ec/internal.h +8 -1
  180. data/third_party/boringssl/crypto/fipsmodule/ec/oct.c +5 -5
  181. data/third_party/boringssl/crypto/fipsmodule/ec/p224-64.c +9 -17
  182. data/third_party/boringssl/crypto/fipsmodule/ec/p256-x86_64-table.h +5378 -5418
  183. data/third_party/boringssl/crypto/fipsmodule/ec/simple.c +32 -32
  184. data/third_party/boringssl/crypto/fipsmodule/ecdsa/ecdsa.c +5 -11
  185. data/third_party/boringssl/crypto/fipsmodule/rsa/blinding.c +16 -40
  186. data/third_party/boringssl/crypto/fipsmodule/rsa/internal.h +1 -6
  187. data/third_party/boringssl/crypto/fipsmodule/rsa/rsa.c +41 -29
  188. data/third_party/boringssl/crypto/fipsmodule/rsa/rsa_impl.c +63 -49
  189. data/third_party/boringssl/crypto/x509/vpm_int.h +1 -0
  190. data/third_party/boringssl/crypto/x509/x509_vfy.c +4 -0
  191. data/third_party/boringssl/crypto/x509/x509_vpm.c +44 -22
  192. data/third_party/boringssl/include/openssl/aead.h +8 -2
  193. data/third_party/boringssl/include/openssl/asn1.h +1 -0
  194. data/third_party/boringssl/include/openssl/base.h +4 -0
  195. data/third_party/boringssl/include/openssl/bn.h +13 -3
  196. data/third_party/boringssl/include/openssl/bytestring.h +4 -4
  197. data/third_party/boringssl/include/openssl/ec.h +10 -4
  198. data/third_party/boringssl/include/openssl/ec_key.h +0 -3
  199. data/third_party/boringssl/include/openssl/rsa.h +1 -0
  200. data/third_party/boringssl/include/openssl/ssl.h +8 -3
  201. data/third_party/boringssl/include/openssl/ssl3.h +0 -1
  202. data/third_party/boringssl/include/openssl/x509.h +1 -0
  203. data/third_party/boringssl/include/openssl/x509v3.h +1 -0
  204. data/third_party/boringssl/ssl/handshake_client.cc +36 -64
  205. data/third_party/boringssl/ssl/ssl_cipher.cc +4 -0
  206. data/third_party/boringssl/ssl/ssl_lib.cc +1 -1
  207. metadata +45 -38
  208. data/src/core/ext/filters/load_reporting/server_load_reporting_filter.cc +0 -222
  209. data/src/core/ext/filters/load_reporting/server_load_reporting_plugin.cc +0 -71
  210. data/src/core/ext/filters/load_reporting/server_load_reporting_plugin.h +0 -61
  211. data/src/ruby/spec/pb/package_with_underscore/checker_spec.rb +0 -51
  212. data/src/ruby/spec/pb/package_with_underscore/data.proto +0 -23
  213. data/src/ruby/spec/pb/package_with_underscore/service.proto +0 -23
@@ -74,6 +74,7 @@
74
74
  #include <openssl/err.h>
75
75
  #include <openssl/mem.h>
76
76
 
77
+ #include "../fipsmodule/ec/internal.h"
77
78
  #include "../internal.h"
78
79
 
79
80
 
@@ -81,11 +82,11 @@ int ECDH_compute_key(void *out, size_t outlen, const EC_POINT *pub_key,
81
82
  const EC_KEY *priv_key,
82
83
  void *(*kdf)(const void *in, size_t inlen, void *out,
83
84
  size_t *outlen)) {
84
- const BIGNUM *const priv = EC_KEY_get0_private_key(priv_key);
85
- if (priv == NULL) {
85
+ if (priv_key->priv_key == NULL) {
86
86
  OPENSSL_PUT_ERROR(ECDH, ECDH_R_NO_PRIVATE_VALUE);
87
87
  return -1;
88
88
  }
89
+ const EC_SCALAR *const priv = &priv_key->priv_key->scalar;
89
90
 
90
91
  BN_CTX *ctx = BN_CTX_new();
91
92
  if (ctx == NULL) {
@@ -104,7 +105,7 @@ int ECDH_compute_key(void *out, size_t outlen, const EC_POINT *pub_key,
104
105
  goto err;
105
106
  }
106
107
 
107
- if (!EC_POINT_mul(group, tmp, NULL, pub_key, priv, ctx)) {
108
+ if (!ec_point_mul_scalar(group, tmp, NULL, pub_key, priv, ctx)) {
108
109
  OPENSSL_PUT_ERROR(ECDH, ECDH_R_POINT_ARITHMETIC_FAILURE);
109
110
  goto err;
110
111
  }
@@ -100,7 +100,7 @@ int BN_add(BIGNUM *r, const BIGNUM *a, const BIGNUM *b) {
100
100
  return ret;
101
101
  }
102
102
 
103
- int bn_uadd_fixed(BIGNUM *r, const BIGNUM *a, const BIGNUM *b) {
103
+ int bn_uadd_consttime(BIGNUM *r, const BIGNUM *a, const BIGNUM *b) {
104
104
  // Widths are public, so we normalize to make |a| the larger one.
105
105
  if (a->width < b->width) {
106
106
  const BIGNUM *tmp = a;
@@ -128,7 +128,7 @@ int bn_uadd_fixed(BIGNUM *r, const BIGNUM *a, const BIGNUM *b) {
128
128
  }
129
129
 
130
130
  int BN_uadd(BIGNUM *r, const BIGNUM *a, const BIGNUM *b) {
131
- if (!bn_uadd_fixed(r, a, b)) {
131
+ if (!bn_uadd_consttime(r, a, b)) {
132
132
  return 0;
133
133
  }
134
134
  bn_set_minimal_width(r);
@@ -223,69 +223,45 @@ int BN_sub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b) {
223
223
  return 1;
224
224
  }
225
225
 
226
- int BN_usub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b) {
227
- int max, min, dif;
228
- register BN_ULONG t1, t2, *ap, *bp, *rp;
229
- int i, carry;
230
-
231
- max = bn_minimal_width(a);
232
- min = bn_minimal_width(b);
233
- dif = max - min;
234
-
235
- if (dif < 0) // hmm... should not be happening
236
- {
237
- OPENSSL_PUT_ERROR(BN, BN_R_ARG2_LT_ARG3);
238
- return 0;
226
+ int bn_usub_consttime(BIGNUM *r, const BIGNUM *a, const BIGNUM *b) {
227
+ // |b| may have more words than |a| given non-minimal inputs, but all words
228
+ // beyond |a->width| must then be zero.
229
+ int b_width = b->width;
230
+ if (b_width > a->width) {
231
+ if (!bn_fits_in_words(b, a->width)) {
232
+ OPENSSL_PUT_ERROR(BN, BN_R_ARG2_LT_ARG3);
233
+ return 0;
234
+ }
235
+ b_width = a->width;
239
236
  }
240
237
 
241
- if (!bn_wexpand(r, max)) {
238
+ if (!bn_wexpand(r, a->width)) {
242
239
  return 0;
243
240
  }
244
241
 
245
- ap = a->d;
246
- bp = b->d;
247
- rp = r->d;
248
-
249
- carry = 0;
250
- for (i = min; i != 0; i--) {
251
- t1 = *(ap++);
252
- t2 = *(bp++);
253
- if (carry) {
254
- carry = (t1 <= t2);
255
- t1 -= t2 + 1;
256
- } else {
257
- carry = (t1 < t2);
258
- t1 -= t2;
259
- }
260
- *(rp++) = t1;
261
- }
262
-
263
- if (carry) // subtracted
264
- {
265
- if (!dif) {
266
- // error: a < b
267
- return 0;
268
- }
269
-
270
- while (dif) {
271
- dif--;
272
- t1 = *(ap++);
273
- t2 = t1 - 1;
274
- *(rp++) = t2;
275
- if (t1) {
276
- break;
277
- }
278
- }
242
+ BN_ULONG borrow = bn_sub_words(r->d, a->d, b->d, b_width);
243
+ for (int i = b_width; i < a->width; i++) {
244
+ // |r| and |a| may alias, so use a temporary.
245
+ BN_ULONG tmp = a->d[i];
246
+ r->d[i] = a->d[i] - borrow;
247
+ borrow = tmp < r->d[i];
279
248
  }
280
249
 
281
- if (dif > 0 && rp != ap) {
282
- OPENSSL_memcpy(rp, ap, sizeof(*rp) * dif);
250
+ if (borrow) {
251
+ OPENSSL_PUT_ERROR(BN, BN_R_ARG2_LT_ARG3);
252
+ return 0;
283
253
  }
284
254
 
285
- r->width = max;
255
+ r->width = a->width;
286
256
  r->neg = 0;
287
- bn_set_minimal_width(r);
257
+ return 1;
258
+ }
288
259
 
260
+ int BN_usub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b) {
261
+ if (!bn_usub_consttime(r, a, b)) {
262
+ return 0;
263
+ }
264
+ bn_set_minimal_width(r);
289
265
  return 1;
290
266
  }
291
267
 
@@ -187,13 +187,19 @@ unsigned BN_num_bits_word(BN_ULONG l) {
187
187
  int bits = (l != 0);
188
188
 
189
189
  #if BN_BITS2 > 32
190
+ // Look at the upper half of |x|. |x| is at most 64 bits long.
190
191
  x = l >> 32;
192
+ // Set |mask| to all ones if |x| (the top 32 bits of |l|) is non-zero and all
193
+ // all zeros otherwise.
191
194
  mask = 0u - x;
192
195
  mask = (0u - (mask >> (BN_BITS2 - 1)));
196
+ // If |x| is non-zero, the lower half is included in the bit count in full,
197
+ // and we count the upper half. Otherwise, we count the lower half.
193
198
  bits += 32 & mask;
194
- l ^= (x ^ l) & mask;
199
+ l ^= (x ^ l) & mask; // |l| is |x| if |mask| and remains |l| otherwise.
195
200
  #endif
196
201
 
202
+ // The remaining blocks are analogous iterations at lower powers of two.
197
203
  x = l >> 16;
198
204
  mask = 0u - x;
199
205
  mask = (0u - (mask >> (BN_BITS2 - 1)));
@@ -128,14 +128,14 @@ int bn_less_than_words(const BN_ULONG *a, const BN_ULONG *b, size_t len) {
128
128
  }
129
129
 
130
130
  int BN_abs_is_word(const BIGNUM *bn, BN_ULONG w) {
131
- switch (bn_minimal_width(bn)) {
132
- case 1:
133
- return bn->d[0] == w;
134
- case 0:
135
- return w == 0;
136
- default:
137
- return 0;
131
+ if (bn->width == 0) {
132
+ return w == 0;
133
+ }
134
+ BN_ULONG mask = bn->d[0] ^ w;
135
+ for (int i = 1; i < bn->width; i++) {
136
+ mask |= bn->d[i];
138
137
  }
138
+ return mask == 0;
139
139
  }
140
140
 
141
141
  int BN_cmp_word(const BIGNUM *a, BN_ULONG b) {
@@ -150,7 +150,7 @@ int BN_cmp_word(const BIGNUM *a, BN_ULONG b) {
150
150
  }
151
151
 
152
152
  int BN_is_zero(const BIGNUM *bn) {
153
- return bn_minimal_width(bn) == 0;
153
+ return bn_fits_in_words(bn, 0);
154
154
  }
155
155
 
156
156
  int BN_is_one(const BIGNUM *bn) {
@@ -454,6 +454,92 @@ static void bn_mod_add_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b,
454
454
  bn_select_words(r, carry, tmp /* r < 0 */, r /* r >= 0 */, num);
455
455
  }
456
456
 
457
+ int bn_div_consttime(BIGNUM *quotient, BIGNUM *remainder,
458
+ const BIGNUM *numerator, const BIGNUM *divisor,
459
+ BN_CTX *ctx) {
460
+ if (BN_is_negative(numerator) || BN_is_negative(divisor)) {
461
+ OPENSSL_PUT_ERROR(BN, BN_R_NEGATIVE_NUMBER);
462
+ return 0;
463
+ }
464
+ if (BN_is_zero(divisor)) {
465
+ OPENSSL_PUT_ERROR(BN, BN_R_DIV_BY_ZERO);
466
+ return 0;
467
+ }
468
+
469
+ // This function implements long division in binary. It is not very efficient,
470
+ // but it is simple, easy to make constant-time, and performant enough for RSA
471
+ // key generation.
472
+
473
+ int ret = 0;
474
+ BN_CTX_start(ctx);
475
+ BIGNUM *q = quotient, *r = remainder;
476
+ if (quotient == NULL || quotient == numerator || quotient == divisor) {
477
+ q = BN_CTX_get(ctx);
478
+ }
479
+ if (remainder == NULL || remainder == numerator || remainder == divisor) {
480
+ r = BN_CTX_get(ctx);
481
+ }
482
+ BIGNUM *tmp = BN_CTX_get(ctx);
483
+ if (q == NULL || r == NULL || tmp == NULL ||
484
+ !bn_wexpand(q, numerator->width) ||
485
+ !bn_wexpand(r, divisor->width) ||
486
+ !bn_wexpand(tmp, divisor->width)) {
487
+ goto err;
488
+ }
489
+
490
+ OPENSSL_memset(q->d, 0, numerator->width * sizeof(BN_ULONG));
491
+ q->width = numerator->width;
492
+ q->neg = 0;
493
+
494
+ OPENSSL_memset(r->d, 0, divisor->width * sizeof(BN_ULONG));
495
+ r->width = divisor->width;
496
+ r->neg = 0;
497
+
498
+ // Incorporate |numerator| into |r|, one bit at a time, reducing after each
499
+ // step. At the start of each loop iteration, |r| < |divisor|
500
+ for (int i = numerator->width - 1; i >= 0; i--) {
501
+ for (int bit = BN_BITS2 - 1; bit >= 0; bit--) {
502
+ // Incorporate the next bit of the numerator, by computing
503
+ // r = 2*r or 2*r + 1. Note the result fits in one more word. We store the
504
+ // extra word in |carry|.
505
+ BN_ULONG carry = bn_add_words(r->d, r->d, r->d, divisor->width);
506
+ r->d[0] |= (numerator->d[i] >> bit) & 1;
507
+ // tmp = r - divisor. We use |bn_sub_words| to perform the bulk of the
508
+ // subtraction, and then apply the borrow to |carry|.
509
+ carry -= bn_sub_words(tmp->d, r->d, divisor->d, divisor->width);
510
+ // |r| was previously fully-reduced, so we know:
511
+ //
512
+ // 2*0 - divisor <= tmp <= 2*(divisor-1) + 1 - divisor
513
+ // -divisor <= tmp < divisor
514
+ //
515
+ // If 0 <= |tmp| < |divisor|, |tmp| fits in |divisor->width| and |carry|
516
+ // is zero. We then wish to select |tmp|. Otherwise,
517
+ // -|divisor| <= |tmp| < 0 and we wish to select |tmp| + |divisor|, which
518
+ // is |r|. |carry| must then be -1 (all ones). In both cases, |carry| is a
519
+ // suitable input to |bn_select_words|.
520
+ //
521
+ // Although |carry| may be one if |bn_add_words| returns one and
522
+ // |bn_sub_words| returns zero, this would give |r| > |d|, which violates
523
+ // the loop invariant.
524
+ bn_select_words(r->d, carry, r->d /* tmp < 0 */, tmp->d /* tmp >= 0 */,
525
+ divisor->width);
526
+ // The corresponding bit of the quotient is set iff we needed to subtract.
527
+ q->d[i] |= (~carry & 1) << bit;
528
+ }
529
+ }
530
+
531
+ if ((quotient != NULL && !BN_copy(quotient, q)) ||
532
+ (remainder != NULL && !BN_copy(remainder, r))) {
533
+ goto err;
534
+ }
535
+
536
+ ret = 1;
537
+
538
+ err:
539
+ BN_CTX_end(ctx);
540
+ return ret;
541
+ }
542
+
457
543
  static BIGNUM *bn_scratch_space_from_ctx(size_t width, BN_CTX *ctx) {
458
544
  BIGNUM *ret = BN_CTX_get(ctx);
459
545
  if (ret == NULL ||
@@ -498,12 +584,12 @@ int BN_mod_add_quick(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
498
584
  const BIGNUM *m) {
499
585
  BN_CTX *ctx = BN_CTX_new();
500
586
  int ok = ctx != NULL &&
501
- bn_mod_add_quick_ctx(r, a, b, m, ctx);
587
+ bn_mod_add_consttime(r, a, b, m, ctx);
502
588
  BN_CTX_free(ctx);
503
589
  return ok;
504
590
  }
505
591
 
506
- int bn_mod_add_quick_ctx(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
592
+ int bn_mod_add_consttime(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
507
593
  const BIGNUM *m, BN_CTX *ctx) {
508
594
  BN_CTX_start(ctx);
509
595
  a = bn_resized_from_ctx(a, m->width, ctx);
@@ -527,7 +613,7 @@ int BN_mod_sub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m,
527
613
  return BN_nnmod(r, r, m, ctx);
528
614
  }
529
615
 
530
- int bn_mod_sub_quick_ctx(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
616
+ int bn_mod_sub_consttime(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
531
617
  const BIGNUM *m, BN_CTX *ctx) {
532
618
  BN_CTX_start(ctx);
533
619
  a = bn_resized_from_ctx(a, m->width, ctx);
@@ -547,7 +633,7 @@ int BN_mod_sub_quick(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
547
633
  const BIGNUM *m) {
548
634
  BN_CTX *ctx = BN_CTX_new();
549
635
  int ok = ctx != NULL &&
550
- bn_mod_sub_quick_ctx(r, a, b, m, ctx);
636
+ bn_mod_sub_consttime(r, a, b, m, ctx);
551
637
  BN_CTX_free(ctx);
552
638
  return ok;
553
639
  }
@@ -610,19 +696,19 @@ int BN_mod_lshift(BIGNUM *r, const BIGNUM *a, int n, const BIGNUM *m,
610
696
  abs_m->neg = 0;
611
697
  }
612
698
 
613
- ret = bn_mod_lshift_quick_ctx(r, r, n, (abs_m ? abs_m : m), ctx);
699
+ ret = bn_mod_lshift_consttime(r, r, n, (abs_m ? abs_m : m), ctx);
614
700
 
615
701
  BN_free(abs_m);
616
702
  return ret;
617
703
  }
618
704
 
619
- int bn_mod_lshift_quick_ctx(BIGNUM *r, const BIGNUM *a, int n, const BIGNUM *m,
705
+ int bn_mod_lshift_consttime(BIGNUM *r, const BIGNUM *a, int n, const BIGNUM *m,
620
706
  BN_CTX *ctx) {
621
707
  if (!BN_copy(r, a)) {
622
708
  return 0;
623
709
  }
624
710
  for (int i = 0; i < n; i++) {
625
- if (!bn_mod_lshift1_quick_ctx(r, r, m, ctx)) {
711
+ if (!bn_mod_lshift1_consttime(r, r, m, ctx)) {
626
712
  return 0;
627
713
  }
628
714
  }
@@ -632,7 +718,7 @@ int bn_mod_lshift_quick_ctx(BIGNUM *r, const BIGNUM *a, int n, const BIGNUM *m,
632
718
  int BN_mod_lshift_quick(BIGNUM *r, const BIGNUM *a, int n, const BIGNUM *m) {
633
719
  BN_CTX *ctx = BN_CTX_new();
634
720
  int ok = ctx != NULL &&
635
- bn_mod_lshift_quick_ctx(r, a, n, m, ctx);
721
+ bn_mod_lshift_consttime(r, a, n, m, ctx);
636
722
  BN_CTX_free(ctx);
637
723
  return ok;
638
724
  }
@@ -645,15 +731,15 @@ int BN_mod_lshift1(BIGNUM *r, const BIGNUM *a, const BIGNUM *m, BN_CTX *ctx) {
645
731
  return BN_nnmod(r, r, m, ctx);
646
732
  }
647
733
 
648
- int bn_mod_lshift1_quick_ctx(BIGNUM *r, const BIGNUM *a, const BIGNUM *m,
734
+ int bn_mod_lshift1_consttime(BIGNUM *r, const BIGNUM *a, const BIGNUM *m,
649
735
  BN_CTX *ctx) {
650
- return bn_mod_add_quick_ctx(r, a, a, m, ctx);
736
+ return bn_mod_add_consttime(r, a, a, m, ctx);
651
737
  }
652
738
 
653
739
  int BN_mod_lshift1_quick(BIGNUM *r, const BIGNUM *a, const BIGNUM *m) {
654
740
  BN_CTX *ctx = BN_CTX_new();
655
741
  int ok = ctx != NULL &&
656
- bn_mod_lshift1_quick_ctx(r, a, m, ctx);
742
+ bn_mod_lshift1_consttime(r, a, m, ctx);
657
743
  BN_CTX_free(ctx);
658
744
  return ok;
659
745
  }
@@ -114,121 +114,310 @@
114
114
 
115
115
  #include "internal.h"
116
116
 
117
- static BIGNUM *euclid(BIGNUM *a, BIGNUM *b) {
118
- BIGNUM *t;
119
- int shifts = 0;
120
117
 
121
- // 0 <= b <= a
122
- while (!BN_is_zero(b)) {
123
- // 0 < b <= a
118
+ static BN_ULONG word_is_odd_mask(BN_ULONG a) { return (BN_ULONG)0 - (a & 1); }
124
119
 
125
- if (BN_is_odd(a)) {
126
- if (BN_is_odd(b)) {
127
- if (!BN_sub(a, a, b)) {
128
- goto err;
129
- }
130
- if (!BN_rshift1(a, a)) {
131
- goto err;
132
- }
133
- if (BN_cmp(a, b) < 0) {
134
- t = a;
135
- a = b;
136
- b = t;
137
- }
138
- } else {
139
- // a odd - b even
140
- if (!BN_rshift1(b, b)) {
141
- goto err;
142
- }
143
- if (BN_cmp(a, b) < 0) {
144
- t = a;
145
- a = b;
146
- b = t;
147
- }
148
- }
149
- } else {
150
- // a is even
151
- if (BN_is_odd(b)) {
152
- if (!BN_rshift1(a, a)) {
153
- goto err;
154
- }
155
- if (BN_cmp(a, b) < 0) {
156
- t = a;
157
- a = b;
158
- b = t;
159
- }
160
- } else {
161
- // a even - b even
162
- if (!BN_rshift1(a, a)) {
163
- goto err;
164
- }
165
- if (!BN_rshift1(b, b)) {
166
- goto err;
167
- }
168
- shifts++;
169
- }
170
- }
171
- // 0 <= b <= a
120
+ static void maybe_rshift1_words(BN_ULONG *a, BN_ULONG mask, BN_ULONG *tmp,
121
+ size_t num) {
122
+ bn_rshift1_words(tmp, a, num);
123
+ bn_select_words(a, mask, tmp, a, num);
124
+ }
125
+
126
+ static void maybe_rshift1_words_carry(BN_ULONG *a, BN_ULONG carry,
127
+ BN_ULONG mask, BN_ULONG *tmp,
128
+ size_t num) {
129
+ maybe_rshift1_words(a, mask, tmp, num);
130
+ if (num != 0) {
131
+ carry &= mask;
132
+ a[num - 1] |= carry << (BN_BITS2-1);
133
+ }
134
+ }
135
+
136
+ static BN_ULONG maybe_add_words(BN_ULONG *a, BN_ULONG mask, const BN_ULONG *b,
137
+ BN_ULONG *tmp, size_t num) {
138
+ BN_ULONG carry = bn_add_words(tmp, a, b, num);
139
+ bn_select_words(a, mask, tmp, a, num);
140
+ return carry & mask;
141
+ }
142
+
143
+ static int bn_gcd_consttime(BIGNUM *r, unsigned *out_shift, const BIGNUM *x,
144
+ const BIGNUM *y, BN_CTX *ctx) {
145
+ size_t width = x->width > y->width ? x->width : y->width;
146
+ if (width == 0) {
147
+ *out_shift = 0;
148
+ BN_zero(r);
149
+ return 1;
172
150
  }
173
151
 
174
- if (shifts) {
175
- if (!BN_lshift(a, a, shifts)) {
176
- goto err;
177
- }
152
+ // This is a constant-time implementation of Stein's algorithm (binary GCD).
153
+ int ret = 0;
154
+ BN_CTX_start(ctx);
155
+ BIGNUM *u = BN_CTX_get(ctx);
156
+ BIGNUM *v = BN_CTX_get(ctx);
157
+ BIGNUM *tmp = BN_CTX_get(ctx);
158
+ if (u == NULL || v == NULL || tmp == NULL ||
159
+ !BN_copy(u, x) ||
160
+ !BN_copy(v, y) ||
161
+ !bn_resize_words(u, width) ||
162
+ !bn_resize_words(v, width) ||
163
+ !bn_resize_words(tmp, width)) {
164
+ goto err;
165
+ }
166
+
167
+ // Each loop iteration halves at least one of |u| and |v|. Thus we need at
168
+ // most the combined bit width of inputs for at least one value to be zero.
169
+ unsigned x_bits = x->width * BN_BITS2, y_bits = y->width * BN_BITS2;
170
+ unsigned num_iters = x_bits + y_bits;
171
+ if (num_iters < x_bits) {
172
+ OPENSSL_PUT_ERROR(BN, BN_R_BIGNUM_TOO_LONG);
173
+ goto err;
178
174
  }
179
175
 
180
- return a;
176
+ unsigned shift = 0;
177
+ for (unsigned i = 0; i < num_iters; i++) {
178
+ BN_ULONG both_odd = word_is_odd_mask(u->d[0]) & word_is_odd_mask(v->d[0]);
179
+
180
+ // If both |u| and |v| are odd, subtract the smaller from the larger.
181
+ BN_ULONG u_less_than_v =
182
+ (BN_ULONG)0 - bn_sub_words(tmp->d, u->d, v->d, width);
183
+ bn_select_words(u->d, both_odd & ~u_less_than_v, tmp->d, u->d, width);
184
+ bn_sub_words(tmp->d, v->d, u->d, width);
185
+ bn_select_words(v->d, both_odd & u_less_than_v, tmp->d, v->d, width);
186
+
187
+ // At least one of |u| and |v| is now even.
188
+ BN_ULONG u_is_odd = word_is_odd_mask(u->d[0]);
189
+ BN_ULONG v_is_odd = word_is_odd_mask(v->d[0]);
190
+ assert(!(u_is_odd & v_is_odd));
191
+
192
+ // If both are even, the final GCD gains a factor of two.
193
+ shift += 1 & (~u_is_odd & ~v_is_odd);
194
+
195
+ // Halve any which are even.
196
+ maybe_rshift1_words(u->d, ~u_is_odd, tmp->d, width);
197
+ maybe_rshift1_words(v->d, ~v_is_odd, tmp->d, width);
198
+ }
199
+
200
+ // One of |u| or |v| is zero at this point. The algorithm usually makes |u|
201
+ // zero, unless |y| was already zero on input. Fix this by combining the
202
+ // values.
203
+ assert(BN_is_zero(u) || BN_is_zero(v));
204
+ for (size_t i = 0; i < width; i++) {
205
+ v->d[i] |= u->d[i];
206
+ }
207
+
208
+ *out_shift = shift;
209
+ ret = bn_set_words(r, v->d, width);
181
210
 
182
211
  err:
183
- return NULL;
212
+ BN_CTX_end(ctx);
213
+ return ret;
184
214
  }
185
215
 
186
- int BN_gcd(BIGNUM *r, const BIGNUM *in_a, const BIGNUM *in_b, BN_CTX *ctx) {
187
- BIGNUM *a, *b, *t;
216
+ int BN_gcd(BIGNUM *r, const BIGNUM *x, const BIGNUM *y, BN_CTX *ctx) {
217
+ unsigned shift;
218
+ return bn_gcd_consttime(r, &shift, x, y, ctx) &&
219
+ BN_lshift(r, r, shift);
220
+ }
221
+
222
+ int bn_is_relatively_prime(int *out_relatively_prime, const BIGNUM *x,
223
+ const BIGNUM *y, BN_CTX *ctx) {
188
224
  int ret = 0;
225
+ BN_CTX_start(ctx);
226
+ unsigned shift;
227
+ BIGNUM *gcd = BN_CTX_get(ctx);
228
+ if (gcd == NULL ||
229
+ !bn_gcd_consttime(gcd, &shift, x, y, ctx)) {
230
+ goto err;
231
+ }
232
+
233
+ // Check that 2^|shift| * |gcd| is one.
234
+ if (gcd->width == 0) {
235
+ *out_relatively_prime = 0;
236
+ } else {
237
+ BN_ULONG mask = shift | (gcd->d[0] ^ 1);
238
+ for (int i = 1; i < gcd->width; i++) {
239
+ mask |= gcd->d[i];
240
+ }
241
+ *out_relatively_prime = mask == 0;
242
+ }
243
+ ret = 1;
244
+
245
+ err:
246
+ BN_CTX_end(ctx);
247
+ return ret;
248
+ }
189
249
 
250
+ int bn_lcm_consttime(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx) {
190
251
  BN_CTX_start(ctx);
191
- a = BN_CTX_get(ctx);
192
- b = BN_CTX_get(ctx);
252
+ unsigned shift;
253
+ BIGNUM *gcd = BN_CTX_get(ctx);
254
+ int ret = gcd != NULL &&
255
+ bn_mul_consttime(r, a, b, ctx) &&
256
+ bn_gcd_consttime(gcd, &shift, a, b, ctx) &&
257
+ bn_div_consttime(r, NULL, r, gcd, ctx) &&
258
+ bn_rshift_secret_shift(r, r, shift, ctx);
259
+ BN_CTX_end(ctx);
260
+ return ret;
261
+ }
193
262
 
194
- if (a == NULL || b == NULL) {
195
- goto err;
263
+ int bn_mod_inverse_consttime(BIGNUM *r, int *out_no_inverse, const BIGNUM *a,
264
+ const BIGNUM *n, BN_CTX *ctx) {
265
+ *out_no_inverse = 0;
266
+ if (BN_is_negative(a) || BN_ucmp(a, n) >= 0) {
267
+ OPENSSL_PUT_ERROR(BN, BN_R_INPUT_NOT_REDUCED);
268
+ return 0;
196
269
  }
197
- if (BN_copy(a, in_a) == NULL) {
198
- goto err;
270
+ if (BN_is_zero(a)) {
271
+ if (BN_is_one(n)) {
272
+ BN_zero(r);
273
+ return 1;
274
+ }
275
+ *out_no_inverse = 1;
276
+ OPENSSL_PUT_ERROR(BN, BN_R_NO_INVERSE);
277
+ return 0;
199
278
  }
200
- if (BN_copy(b, in_b) == NULL) {
201
- goto err;
279
+
280
+ // This is a constant-time implementation of the extended binary GCD
281
+ // algorithm. It is adapted from the Handbook of Applied Cryptography, section
282
+ // 14.4.3, algorithm 14.51, and modified to bound coefficients and avoid
283
+ // negative numbers.
284
+ //
285
+ // For more details and proof of correctness, see
286
+ // https://github.com/mit-plv/fiat-crypto/pull/333. In particular, see |step|
287
+ // and |mod_inverse_consttime| for the algorithm in Gallina and see
288
+ // |mod_inverse_consttime_spec| for the correctness result.
289
+
290
+ if (!BN_is_odd(a) && !BN_is_odd(n)) {
291
+ *out_no_inverse = 1;
292
+ OPENSSL_PUT_ERROR(BN, BN_R_NO_INVERSE);
293
+ return 0;
202
294
  }
203
295
 
204
- a->neg = 0;
205
- b->neg = 0;
296
+ // This function exists to compute the RSA private exponent, where |a| is one
297
+ // word. We'll thus use |a_width| when available.
298
+ size_t n_width = n->width, a_width = a->width;
299
+ if (a_width > n_width) {
300
+ a_width = n_width;
301
+ }
206
302
 
207
- if (BN_cmp(a, b) < 0) {
208
- t = a;
209
- a = b;
210
- b = t;
303
+ int ret = 0;
304
+ BN_CTX_start(ctx);
305
+ BIGNUM *u = BN_CTX_get(ctx);
306
+ BIGNUM *v = BN_CTX_get(ctx);
307
+ BIGNUM *A = BN_CTX_get(ctx);
308
+ BIGNUM *B = BN_CTX_get(ctx);
309
+ BIGNUM *C = BN_CTX_get(ctx);
310
+ BIGNUM *D = BN_CTX_get(ctx);
311
+ BIGNUM *tmp = BN_CTX_get(ctx);
312
+ BIGNUM *tmp2 = BN_CTX_get(ctx);
313
+ if (u == NULL || v == NULL || A == NULL || B == NULL || C == NULL ||
314
+ D == NULL || tmp == NULL || tmp2 == NULL ||
315
+ !BN_copy(u, a) ||
316
+ !BN_copy(v, n) ||
317
+ !BN_one(A) ||
318
+ !BN_one(D) ||
319
+ // For convenience, size |u| and |v| equivalently.
320
+ !bn_resize_words(u, n_width) ||
321
+ !bn_resize_words(v, n_width) ||
322
+ // |A| and |C| are bounded by |m|.
323
+ !bn_resize_words(A, n_width) ||
324
+ !bn_resize_words(C, n_width) ||
325
+ // |B| and |D| are bounded by |a|.
326
+ !bn_resize_words(B, a_width) ||
327
+ !bn_resize_words(D, a_width) ||
328
+ // |tmp| and |tmp2| may be used at either size.
329
+ !bn_resize_words(tmp, n_width) ||
330
+ !bn_resize_words(tmp2, n_width)) {
331
+ goto err;
211
332
  }
212
- t = euclid(a, b);
213
- if (t == NULL) {
333
+
334
+ // Each loop iteration halves at least one of |u| and |v|. Thus we need at
335
+ // most the combined bit width of inputs for at least one value to be zero.
336
+ unsigned a_bits = a_width * BN_BITS2, n_bits = n_width * BN_BITS2;
337
+ unsigned num_iters = a_bits + n_bits;
338
+ if (num_iters < a_bits) {
339
+ OPENSSL_PUT_ERROR(BN, BN_R_BIGNUM_TOO_LONG);
214
340
  goto err;
215
341
  }
216
342
 
217
- if (BN_copy(r, t) == NULL) {
343
+ // Before and after each loop iteration, the following hold:
344
+ //
345
+ // u = A*a - B*n
346
+ // v = D*n - C*a
347
+ // 0 < u <= a
348
+ // 0 <= v <= n
349
+ // 0 <= A < n
350
+ // 0 <= B <= a
351
+ // 0 <= C < n
352
+ // 0 <= D <= a
353
+ //
354
+ // After each loop iteration, u and v only get smaller, and at least one of
355
+ // them shrinks by at least a factor of two.
356
+ for (unsigned i = 0; i < num_iters; i++) {
357
+ BN_ULONG both_odd = word_is_odd_mask(u->d[0]) & word_is_odd_mask(v->d[0]);
358
+
359
+ // If both |u| and |v| are odd, subtract the smaller from the larger.
360
+ BN_ULONG v_less_than_u =
361
+ (BN_ULONG)0 - bn_sub_words(tmp->d, v->d, u->d, n_width);
362
+ bn_select_words(v->d, both_odd & ~v_less_than_u, tmp->d, v->d, n_width);
363
+ bn_sub_words(tmp->d, u->d, v->d, n_width);
364
+ bn_select_words(u->d, both_odd & v_less_than_u, tmp->d, u->d, n_width);
365
+
366
+ // If we updated one of the values, update the corresponding coefficient.
367
+ BN_ULONG carry = bn_add_words(tmp->d, A->d, C->d, n_width);
368
+ carry -= bn_sub_words(tmp2->d, tmp->d, n->d, n_width);
369
+ bn_select_words(tmp->d, carry, tmp->d, tmp2->d, n_width);
370
+ bn_select_words(A->d, both_odd & v_less_than_u, tmp->d, A->d, n_width);
371
+ bn_select_words(C->d, both_odd & ~v_less_than_u, tmp->d, C->d, n_width);
372
+
373
+ bn_add_words(tmp->d, B->d, D->d, a_width);
374
+ bn_sub_words(tmp2->d, tmp->d, a->d, a_width);
375
+ bn_select_words(tmp->d, carry, tmp->d, tmp2->d, a_width);
376
+ bn_select_words(B->d, both_odd & v_less_than_u, tmp->d, B->d, a_width);
377
+ bn_select_words(D->d, both_odd & ~v_less_than_u, tmp->d, D->d, a_width);
378
+
379
+ // Our loop invariants hold at this point. Additionally, exactly one of |u|
380
+ // and |v| is now even.
381
+ BN_ULONG u_is_even = ~word_is_odd_mask(u->d[0]);
382
+ BN_ULONG v_is_even = ~word_is_odd_mask(v->d[0]);
383
+ assert(u_is_even != v_is_even);
384
+
385
+ // Halve the even one and adjust the corresponding coefficient.
386
+ maybe_rshift1_words(u->d, u_is_even, tmp->d, n_width);
387
+ BN_ULONG A_or_B_is_odd =
388
+ word_is_odd_mask(A->d[0]) | word_is_odd_mask(B->d[0]);
389
+ BN_ULONG A_carry =
390
+ maybe_add_words(A->d, A_or_B_is_odd & u_is_even, n->d, tmp->d, n_width);
391
+ BN_ULONG B_carry =
392
+ maybe_add_words(B->d, A_or_B_is_odd & u_is_even, a->d, tmp->d, a_width);
393
+ maybe_rshift1_words_carry(A->d, A_carry, u_is_even, tmp->d, n_width);
394
+ maybe_rshift1_words_carry(B->d, B_carry, u_is_even, tmp->d, a_width);
395
+
396
+ maybe_rshift1_words(v->d, v_is_even, tmp->d, n_width);
397
+ BN_ULONG C_or_D_is_odd =
398
+ word_is_odd_mask(C->d[0]) | word_is_odd_mask(D->d[0]);
399
+ BN_ULONG C_carry =
400
+ maybe_add_words(C->d, C_or_D_is_odd & v_is_even, n->d, tmp->d, n_width);
401
+ BN_ULONG D_carry =
402
+ maybe_add_words(D->d, C_or_D_is_odd & v_is_even, a->d, tmp->d, a_width);
403
+ maybe_rshift1_words_carry(C->d, C_carry, v_is_even, tmp->d, n_width);
404
+ maybe_rshift1_words_carry(D->d, D_carry, v_is_even, tmp->d, a_width);
405
+ }
406
+
407
+ assert(BN_is_zero(v));
408
+ if (!BN_is_one(u)) {
409
+ *out_no_inverse = 1;
410
+ OPENSSL_PUT_ERROR(BN, BN_R_NO_INVERSE);
218
411
  goto err;
219
412
  }
220
- ret = 1;
413
+
414
+ ret = BN_copy(r, A) != NULL;
221
415
 
222
416
  err:
223
417
  BN_CTX_end(ctx);
224
418
  return ret;
225
419
  }
226
420
 
227
- // solves ax == 1 (mod n)
228
- static int bn_mod_inverse_general(BIGNUM *out, int *out_no_inverse,
229
- const BIGNUM *a, const BIGNUM *n,
230
- BN_CTX *ctx);
231
-
232
421
  int BN_mod_inverse_odd(BIGNUM *out, int *out_no_inverse, const BIGNUM *a,
233
422
  const BIGNUM *n, BN_CTX *ctx) {
234
423
  *out_no_inverse = 0;
@@ -423,7 +612,7 @@ BIGNUM *BN_mod_inverse(BIGNUM *out, const BIGNUM *a, const BIGNUM *n,
423
612
 
424
613
  int no_inverse;
425
614
  if (!BN_is_odd(n)) {
426
- if (!bn_mod_inverse_general(out, &no_inverse, a, n, ctx)) {
615
+ if (!bn_mod_inverse_consttime(out, &no_inverse, a, n, ctx)) {
427
616
  goto err;
428
617
  }
429
618
  } else if (!BN_mod_inverse_odd(out, &no_inverse, a, n, ctx)) {
@@ -469,139 +658,6 @@ err:
469
658
  return ret;
470
659
  }
471
660
 
472
- // bn_mod_inverse_general is the general inversion algorithm that works for
473
- // both even and odd |n|. It was specifically designed to contain fewer
474
- // branches that may leak sensitive information; see "New Branch Prediction
475
- // Vulnerabilities in OpenSSL and Necessary Software Countermeasures" by
476
- // Onur Acıçmez, Shay Gueron, and Jean-Pierre Seifert.
477
- static int bn_mod_inverse_general(BIGNUM *out, int *out_no_inverse,
478
- const BIGNUM *a, const BIGNUM *n,
479
- BN_CTX *ctx) {
480
- BIGNUM *A, *B, *X, *Y, *M, *D, *T;
481
- int ret = 0;
482
- int sign;
483
-
484
- *out_no_inverse = 0;
485
-
486
- BN_CTX_start(ctx);
487
- A = BN_CTX_get(ctx);
488
- B = BN_CTX_get(ctx);
489
- X = BN_CTX_get(ctx);
490
- D = BN_CTX_get(ctx);
491
- M = BN_CTX_get(ctx);
492
- Y = BN_CTX_get(ctx);
493
- T = BN_CTX_get(ctx);
494
- if (T == NULL) {
495
- goto err;
496
- }
497
-
498
- BIGNUM *R = out;
499
-
500
- BN_zero(Y);
501
- if (!BN_one(X) || BN_copy(B, a) == NULL || BN_copy(A, n) == NULL) {
502
- goto err;
503
- }
504
- A->neg = 0;
505
-
506
- sign = -1;
507
- // From B = a mod |n|, A = |n| it follows that
508
- //
509
- // 0 <= B < A,
510
- // -sign*X*a == B (mod |n|),
511
- // sign*Y*a == A (mod |n|).
512
-
513
- while (!BN_is_zero(B)) {
514
- BIGNUM *tmp;
515
-
516
- // 0 < B < A,
517
- // (*) -sign*X*a == B (mod |n|),
518
- // sign*Y*a == A (mod |n|)
519
-
520
- // (D, M) := (A/B, A%B) ...
521
- if (!BN_div(D, M, A, B, ctx)) {
522
- goto err;
523
- }
524
-
525
- // Now
526
- // A = D*B + M;
527
- // thus we have
528
- // (**) sign*Y*a == D*B + M (mod |n|).
529
-
530
- tmp = A; // keep the BIGNUM object, the value does not matter
531
-
532
- // (A, B) := (B, A mod B) ...
533
- A = B;
534
- B = M;
535
- // ... so we have 0 <= B < A again
536
-
537
- // Since the former M is now B and the former B is now A,
538
- // (**) translates into
539
- // sign*Y*a == D*A + B (mod |n|),
540
- // i.e.
541
- // sign*Y*a - D*A == B (mod |n|).
542
- // Similarly, (*) translates into
543
- // -sign*X*a == A (mod |n|).
544
- //
545
- // Thus,
546
- // sign*Y*a + D*sign*X*a == B (mod |n|),
547
- // i.e.
548
- // sign*(Y + D*X)*a == B (mod |n|).
549
- //
550
- // So if we set (X, Y, sign) := (Y + D*X, X, -sign), we arrive back at
551
- // -sign*X*a == B (mod |n|),
552
- // sign*Y*a == A (mod |n|).
553
- // Note that X and Y stay non-negative all the time.
554
-
555
- if (!BN_mul(tmp, D, X, ctx)) {
556
- goto err;
557
- }
558
- if (!BN_add(tmp, tmp, Y)) {
559
- goto err;
560
- }
561
-
562
- M = Y; // keep the BIGNUM object, the value does not matter
563
- Y = X;
564
- X = tmp;
565
- sign = -sign;
566
- }
567
-
568
- if (!BN_is_one(A)) {
569
- *out_no_inverse = 1;
570
- OPENSSL_PUT_ERROR(BN, BN_R_NO_INVERSE);
571
- goto err;
572
- }
573
-
574
- // The while loop (Euclid's algorithm) ends when
575
- // A == gcd(a,n);
576
- // we have
577
- // sign*Y*a == A (mod |n|),
578
- // where Y is non-negative.
579
-
580
- if (sign < 0) {
581
- if (!BN_sub(Y, n, Y)) {
582
- goto err;
583
- }
584
- }
585
- // Now Y*a == A (mod |n|).
586
-
587
- // Y*a == 1 (mod |n|)
588
- if (!Y->neg && BN_ucmp(Y, n) < 0) {
589
- if (!BN_copy(R, Y)) {
590
- goto err;
591
- }
592
- } else {
593
- if (!BN_nnmod(R, Y, n, ctx)) {
594
- goto err;
595
- }
596
- }
597
-
598
- ret = 1;
599
-
600
- err:
601
- BN_CTX_end(ctx);
602
- return ret;
603
- }
604
-
605
661
  int bn_mod_inverse_prime(BIGNUM *out, const BIGNUM *a, const BIGNUM *p,
606
662
  BN_CTX *ctx, const BN_MONT_CTX *mont_p) {
607
663
  BN_CTX_start(ctx);