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.
- checksums.yaml +4 -4
- data/Makefile +403 -153
- data/include/grpc/grpc.h +0 -8
- data/include/grpc/grpc_security.h +59 -2
- data/include/grpc/impl/codegen/grpc_types.h +8 -2
- data/include/grpc/impl/codegen/log.h +112 -0
- data/include/grpc/module.modulemap +2 -0
- data/include/grpc/support/log.h +2 -88
- data/include/grpc/support/string_util.h +2 -0
- data/src/boringssl/err_data.c +597 -593
- data/src/core/ext/filters/client_channel/client_channel.cc +715 -770
- data/src/core/ext/filters/client_channel/client_channel.h +5 -0
- data/src/core/ext/filters/client_channel/client_channel_channelz.cc +111 -0
- data/src/core/ext/filters/client_channel/client_channel_channelz.h +69 -0
- data/src/core/ext/filters/client_channel/client_channel_plugin.cc +9 -0
- data/src/core/ext/filters/client_channel/http_proxy.cc +22 -5
- data/src/core/ext/filters/client_channel/lb_policy.h +15 -0
- data/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc +3 -0
- data/src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.cc +3 -3
- data/src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.h +3 -1
- data/src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/duration.pb.c +19 -0
- data/src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/duration.pb.h +54 -0
- data/src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/timestamp.pb.c +19 -0
- data/src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/timestamp.pb.h +54 -0
- data/src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c +4 -17
- data/src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h +37 -63
- data/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc +79 -0
- data/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc +5 -2
- data/src/core/ext/filters/client_channel/lb_policy_factory.cc +8 -0
- data/src/core/ext/filters/client_channel/lb_policy_factory.h +4 -0
- data/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc +2 -2
- data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.cc +317 -0
- data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h +48 -9
- data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.cc +40 -293
- data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc +106 -84
- data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h +6 -2
- data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc +6 -5
- data/src/core/ext/filters/client_channel/subchannel.cc +36 -6
- data/src/core/ext/filters/client_channel/subchannel.h +4 -0
- data/src/core/ext/filters/deadline/deadline_filter.cc +18 -15
- data/src/core/ext/filters/deadline/deadline_filter.h +5 -5
- data/src/core/ext/filters/http/client/http_client_filter.cc +10 -9
- data/src/core/ext/filters/http/server/http_server_filter.h +1 -1
- data/src/core/ext/transport/chttp2/client/insecure/channel_create_posix.cc +1 -1
- data/src/core/ext/transport/chttp2/server/insecure/server_chttp2_posix.cc +3 -2
- data/src/core/ext/transport/chttp2/transport/chttp2_transport.cc +33 -22
- data/src/core/ext/transport/chttp2/transport/hpack_parser.cc +1 -1
- data/src/core/ext/transport/chttp2/transport/internal.h +10 -3
- data/src/core/ext/transport/chttp2/transport/stream_lists.cc +17 -0
- data/src/core/ext/transport/chttp2/transport/writing.cc +21 -16
- data/src/core/ext/transport/inproc/inproc_transport.cc +46 -6
- data/src/core/lib/channel/channel_stack.cc +22 -24
- data/src/core/lib/channel/channel_trace.cc +28 -63
- data/src/core/lib/channel/channel_trace.h +13 -17
- data/src/core/lib/channel/channelz.cc +143 -0
- data/src/core/lib/channel/channelz.h +124 -0
- data/src/core/lib/channel/channelz_registry.cc +7 -24
- data/src/core/lib/channel/channelz_registry.h +12 -8
- data/src/core/lib/channel/connected_channel.cc +8 -1
- data/src/core/{ext/filters/load_reporting/server_load_reporting_filter.h → lib/gpr/alloc.h} +7 -9
- data/src/core/lib/gpr/arena.cc +8 -8
- data/src/core/lib/gpr/string.cc +28 -0
- data/src/core/lib/gpr/string.h +10 -0
- data/src/core/lib/gprpp/abstract.h +5 -2
- data/src/core/lib/gprpp/inlined_vector.h +57 -3
- data/src/core/lib/gprpp/memory.h +2 -2
- data/src/core/lib/gprpp/ref_counted_ptr.h +5 -0
- data/src/core/lib/gprpp/thd_posix.cc +1 -1
- data/src/core/lib/iomgr/call_combiner.h +80 -0
- data/src/core/lib/iomgr/closure.h +3 -2
- data/src/core/lib/iomgr/endpoint_pair_posix.cc +2 -2
- data/src/core/lib/iomgr/error.cc +12 -0
- data/src/core/lib/iomgr/error.h +5 -0
- data/src/core/lib/iomgr/ev_epoll1_linux.cc +36 -9
- data/src/core/lib/iomgr/ev_epollex_linux.cc +172 -46
- data/src/core/lib/iomgr/ev_epollsig_linux.cc +47 -21
- data/src/core/lib/iomgr/ev_poll_posix.cc +10 -4
- data/src/core/lib/iomgr/ev_posix.cc +17 -9
- data/src/core/lib/iomgr/ev_posix.h +20 -4
- data/src/core/lib/iomgr/executor.cc +196 -140
- data/src/core/lib/iomgr/executor.h +47 -14
- data/src/core/lib/iomgr/iomgr.cc +2 -0
- data/src/core/lib/iomgr/iomgr.h +5 -0
- data/src/core/lib/iomgr/is_epollexclusive_available.cc +1 -0
- data/src/core/lib/iomgr/socket_utils.h +9 -0
- data/src/core/lib/iomgr/socket_utils_common_posix.cc +4 -0
- data/src/core/lib/iomgr/socket_utils_uv.cc +4 -0
- data/src/core/lib/iomgr/socket_utils_windows.cc +4 -0
- data/src/core/lib/iomgr/tcp_client_posix.cc +3 -5
- data/src/core/lib/iomgr/tcp_posix.cc +6 -1
- data/src/core/lib/iomgr/tcp_server_posix.cc +3 -3
- data/src/core/lib/iomgr/tcp_server_utils_posix_common.cc +1 -1
- data/src/core/lib/iomgr/timer_manager.cc +0 -1
- data/src/core/lib/iomgr/udp_server.cc +2 -3
- data/src/core/lib/json/json.cc +10 -0
- data/src/core/lib/json/json.h +5 -0
- data/src/core/lib/security/context/security_context.cc +8 -8
- data/src/core/lib/security/context/security_context.h +6 -2
- data/src/core/lib/security/credentials/google_default/google_default_credentials.cc +2 -1
- data/src/core/lib/security/credentials/local/local_credentials.cc +77 -0
- data/src/core/lib/security/credentials/local/local_credentials.h +40 -0
- data/src/core/lib/security/credentials/ssl/ssl_credentials.cc +17 -3
- data/src/core/lib/security/security_connector/local_security_connector.cc +245 -0
- data/src/core/lib/security/security_connector/local_security_connector.h +58 -0
- data/src/core/lib/security/security_connector/security_connector.cc +30 -5
- data/src/core/lib/security/security_connector/security_connector.h +1 -0
- data/src/core/lib/security/transport/client_auth_filter.cc +5 -1
- data/src/core/lib/security/transport/server_auth_filter.cc +4 -5
- data/src/core/lib/surface/call.cc +75 -32
- data/src/core/lib/surface/call.h +2 -0
- data/src/core/lib/surface/channel.cc +32 -13
- data/src/core/lib/surface/channel.h +4 -0
- data/src/core/lib/surface/version.cc +1 -1
- data/src/core/lib/transport/transport.cc +20 -9
- data/src/core/lib/transport/transport.h +12 -10
- data/src/core/lib/transport/transport_op_string.cc +0 -7
- data/src/core/plugin_registry/grpc_plugin_registry.cc +0 -4
- data/src/core/tsi/alts/handshaker/alts_handshaker_service_api_util.h +2 -2
- data/src/core/tsi/alts/handshaker/alts_tsi_handshaker.cc +2 -1
- data/src/core/tsi/alts/handshaker/altscontext.pb.c +0 -1
- data/src/core/tsi/alts/handshaker/altscontext.pb.h +1 -2
- data/src/core/tsi/alts/handshaker/handshaker.pb.c +0 -1
- data/src/core/tsi/alts/handshaker/handshaker.pb.h +1 -2
- data/src/core/tsi/alts/handshaker/transport_security_common.pb.c +0 -1
- data/src/core/tsi/alts/handshaker/transport_security_common.pb.h +1 -1
- data/src/core/tsi/alts/handshaker/transport_security_common_api.h +2 -2
- data/src/core/tsi/alts/zero_copy_frame_protector/alts_grpc_integrity_only_record_protocol.cc +47 -1
- data/src/core/tsi/alts/zero_copy_frame_protector/alts_grpc_integrity_only_record_protocol.h +3 -1
- data/src/core/tsi/alts/zero_copy_frame_protector/alts_zero_copy_grpc_protector.cc +12 -11
- data/src/core/tsi/alts/zero_copy_frame_protector/alts_zero_copy_grpc_protector.h +7 -2
- data/src/core/tsi/local_transport_security.cc +209 -0
- data/src/core/tsi/local_transport_security.h +51 -0
- data/src/core/tsi/ssl_transport_security.cc +2 -3
- data/src/{core/ext → cpp/ext/filters}/census/grpc_context.cc +0 -0
- data/src/ruby/ext/grpc/rb_channel_credentials.c +3 -3
- data/src/ruby/ext/grpc/rb_grpc_imports.generated.c +18 -18
- data/src/ruby/ext/grpc/rb_grpc_imports.generated.h +29 -29
- data/src/ruby/lib/grpc/generic/active_call.rb +19 -23
- data/src/ruby/lib/grpc/version.rb +1 -1
- data/src/ruby/spec/call_credentials_spec.rb +1 -1
- data/src/ruby/spec/call_spec.rb +1 -1
- data/src/ruby/spec/channel_credentials_spec.rb +1 -1
- data/src/ruby/spec/channel_spec.rb +1 -1
- data/src/ruby/spec/client_auth_spec.rb +1 -12
- data/src/ruby/spec/client_server_spec.rb +1 -1
- data/src/ruby/spec/compression_options_spec.rb +1 -1
- data/src/ruby/spec/error_sanity_spec.rb +1 -1
- data/src/ruby/spec/generic/client_stub_spec.rb +13 -1
- data/src/ruby/spec/generic/rpc_desc_spec.rb +1 -1
- data/src/ruby/spec/generic/rpc_server_pool_spec.rb +1 -1
- data/src/ruby/spec/generic/service_spec.rb +1 -1
- data/src/ruby/spec/google_rpc_status_utils_spec.rb +1 -12
- data/src/ruby/spec/pb/duplicate/codegen_spec.rb +1 -0
- data/src/ruby/spec/pb/health/checker_spec.rb +1 -1
- data/src/ruby/spec/server_credentials_spec.rb +1 -1
- data/src/ruby/spec/server_spec.rb +1 -1
- data/src/ruby/spec/spec_helper.rb +1 -0
- data/src/ruby/spec/support/services.rb +1 -1
- data/src/ruby/spec/time_consts_spec.rb +1 -1
- data/third_party/boringssl/crypto/asn1/tasn_dec.c +40 -19
- data/third_party/boringssl/crypto/bytestring/cbs.c +1 -0
- data/third_party/boringssl/crypto/cipher_extra/e_aesccm.c +47 -15
- data/third_party/boringssl/crypto/ec_extra/ec_asn1.c +9 -10
- data/third_party/boringssl/crypto/ecdh/ecdh.c +4 -3
- data/third_party/boringssl/crypto/fipsmodule/bn/add.c +30 -54
- data/third_party/boringssl/crypto/fipsmodule/bn/bn.c +7 -1
- data/third_party/boringssl/crypto/fipsmodule/bn/cmp.c +8 -8
- data/third_party/boringssl/crypto/fipsmodule/bn/div.c +97 -11
- data/third_party/boringssl/crypto/fipsmodule/bn/gcd.c +274 -218
- data/third_party/boringssl/crypto/fipsmodule/bn/internal.h +111 -34
- data/third_party/boringssl/crypto/fipsmodule/bn/montgomery.c +2 -2
- data/third_party/boringssl/crypto/fipsmodule/bn/montgomery_inv.c +1 -1
- data/third_party/boringssl/crypto/fipsmodule/bn/mul.c +24 -6
- data/third_party/boringssl/crypto/fipsmodule/bn/prime.c +324 -63
- data/third_party/boringssl/crypto/fipsmodule/bn/random.c +74 -21
- data/third_party/boringssl/crypto/fipsmodule/bn/shift.c +128 -86
- data/third_party/boringssl/crypto/fipsmodule/bn/sqrt.c +1 -1
- data/third_party/boringssl/crypto/fipsmodule/ec/ec_key.c +67 -112
- data/third_party/boringssl/crypto/fipsmodule/ec/internal.h +8 -1
- data/third_party/boringssl/crypto/fipsmodule/ec/oct.c +5 -5
- data/third_party/boringssl/crypto/fipsmodule/ec/p224-64.c +9 -17
- data/third_party/boringssl/crypto/fipsmodule/ec/p256-x86_64-table.h +5378 -5418
- data/third_party/boringssl/crypto/fipsmodule/ec/simple.c +32 -32
- data/third_party/boringssl/crypto/fipsmodule/ecdsa/ecdsa.c +5 -11
- data/third_party/boringssl/crypto/fipsmodule/rsa/blinding.c +16 -40
- data/third_party/boringssl/crypto/fipsmodule/rsa/internal.h +1 -6
- data/third_party/boringssl/crypto/fipsmodule/rsa/rsa.c +41 -29
- data/third_party/boringssl/crypto/fipsmodule/rsa/rsa_impl.c +63 -49
- data/third_party/boringssl/crypto/x509/vpm_int.h +1 -0
- data/third_party/boringssl/crypto/x509/x509_vfy.c +4 -0
- data/third_party/boringssl/crypto/x509/x509_vpm.c +44 -22
- data/third_party/boringssl/include/openssl/aead.h +8 -2
- data/third_party/boringssl/include/openssl/asn1.h +1 -0
- data/third_party/boringssl/include/openssl/base.h +4 -0
- data/third_party/boringssl/include/openssl/bn.h +13 -3
- data/third_party/boringssl/include/openssl/bytestring.h +4 -4
- data/third_party/boringssl/include/openssl/ec.h +10 -4
- data/third_party/boringssl/include/openssl/ec_key.h +0 -3
- data/third_party/boringssl/include/openssl/rsa.h +1 -0
- data/third_party/boringssl/include/openssl/ssl.h +8 -3
- data/third_party/boringssl/include/openssl/ssl3.h +0 -1
- data/third_party/boringssl/include/openssl/x509.h +1 -0
- data/third_party/boringssl/include/openssl/x509v3.h +1 -0
- data/third_party/boringssl/ssl/handshake_client.cc +36 -64
- data/third_party/boringssl/ssl/ssl_cipher.cc +4 -0
- data/third_party/boringssl/ssl/ssl_lib.cc +1 -1
- metadata +45 -38
- data/src/core/ext/filters/load_reporting/server_load_reporting_filter.cc +0 -222
- data/src/core/ext/filters/load_reporting/server_load_reporting_plugin.cc +0 -71
- data/src/core/ext/filters/load_reporting/server_load_reporting_plugin.h +0 -61
- data/src/ruby/spec/pb/package_with_underscore/checker_spec.rb +0 -51
- data/src/ruby/spec/pb/package_with_underscore/data.proto +0 -23
- 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
|
-
|
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 (!
|
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
|
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 (!
|
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
|
227
|
-
|
228
|
-
|
229
|
-
int
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
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,
|
238
|
+
if (!bn_wexpand(r, a->width)) {
|
242
239
|
return 0;
|
243
240
|
}
|
244
241
|
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
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 (
|
282
|
-
|
250
|
+
if (borrow) {
|
251
|
+
OPENSSL_PUT_ERROR(BN, BN_R_ARG2_LT_ARG3);
|
252
|
+
return 0;
|
283
253
|
}
|
284
254
|
|
285
|
-
r->width =
|
255
|
+
r->width = a->width;
|
286
256
|
r->neg = 0;
|
287
|
-
|
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
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
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
|
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
|
-
|
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
|
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
|
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
|
-
|
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 =
|
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
|
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 (!
|
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
|
-
|
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
|
734
|
+
int bn_mod_lshift1_consttime(BIGNUM *r, const BIGNUM *a, const BIGNUM *m,
|
649
735
|
BN_CTX *ctx) {
|
650
|
-
return
|
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
|
-
|
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
|
-
|
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
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
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
|
-
|
175
|
-
|
176
|
-
|
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
|
-
|
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
|
-
|
212
|
+
BN_CTX_end(ctx);
|
213
|
+
return ret;
|
184
214
|
}
|
185
215
|
|
186
|
-
int BN_gcd(BIGNUM *r, const BIGNUM *
|
187
|
-
|
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
|
-
|
192
|
-
|
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
|
-
|
195
|
-
|
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 (
|
198
|
-
|
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
|
-
|
201
|
-
|
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
|
205
|
-
|
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
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
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
|
-
|
213
|
-
|
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
|
-
|
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
|
-
|
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 (!
|
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);
|