mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-09-21 13:34:59 +02:00
Merge branch 'bug17686_v2_027'
This commit is contained in:
commit
e5754c42d1
4
changes/bug17686
Normal file
4
changes/bug17686
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
o Minor features:
|
||||||
|
- Adjust Tor's use of OpenSSL's RNG APIs so that they absolutely,
|
||||||
|
positively are not allowed to fail. Previously we depended on
|
||||||
|
internals about OpenSSL behavior. Closes ticket 17686.
|
@ -118,6 +118,7 @@
|
|||||||
#define ATTR_CONST __attribute__((const))
|
#define ATTR_CONST __attribute__((const))
|
||||||
#define ATTR_MALLOC __attribute__((malloc))
|
#define ATTR_MALLOC __attribute__((malloc))
|
||||||
#define ATTR_NORETURN __attribute__((noreturn))
|
#define ATTR_NORETURN __attribute__((noreturn))
|
||||||
|
#define ATTR_WUR __attribute__((warn_unused_result))
|
||||||
/* Alas, nonnull is not at present a good idea for us. We'd like to get
|
/* Alas, nonnull is not at present a good idea for us. We'd like to get
|
||||||
* warnings when we pass NULL where we shouldn't (which nonnull does, albeit
|
* warnings when we pass NULL where we shouldn't (which nonnull does, albeit
|
||||||
* spottily), but we don't want to tell the compiler to make optimizations
|
* spottily), but we don't want to tell the compiler to make optimizations
|
||||||
@ -153,6 +154,7 @@
|
|||||||
#define ATTR_NORETURN
|
#define ATTR_NORETURN
|
||||||
#define ATTR_NONNULL(x)
|
#define ATTR_NONNULL(x)
|
||||||
#define ATTR_UNUSED
|
#define ATTR_UNUSED
|
||||||
|
#define ATTR_WUR
|
||||||
#define PREDICT_LIKELY(exp) (exp)
|
#define PREDICT_LIKELY(exp) (exp)
|
||||||
#define PREDICT_UNLIKELY(exp) (exp)
|
#define PREDICT_UNLIKELY(exp) (exp)
|
||||||
#endif
|
#endif
|
||||||
|
@ -267,8 +267,7 @@ crypto_init_siphash_key(void)
|
|||||||
if (have_seeded_siphash)
|
if (have_seeded_siphash)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (crypto_rand((char*) &key, sizeof(key)) < 0)
|
crypto_rand((char*) &key, sizeof(key));
|
||||||
return -1;
|
|
||||||
siphash_set_global_key(&key);
|
siphash_set_global_key(&key);
|
||||||
have_seeded_siphash = 1;
|
have_seeded_siphash = 1;
|
||||||
return 0;
|
return 0;
|
||||||
@ -321,7 +320,8 @@ int
|
|||||||
crypto_global_init(int useAccel, const char *accelName, const char *accelDir)
|
crypto_global_init(int useAccel, const char *accelName, const char *accelDir)
|
||||||
{
|
{
|
||||||
if (!crypto_global_initialized_) {
|
if (!crypto_global_initialized_) {
|
||||||
crypto_early_init();
|
if (crypto_early_init() < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
crypto_global_initialized_ = 1;
|
crypto_global_initialized_ = 1;
|
||||||
|
|
||||||
@ -2421,34 +2421,41 @@ crypto_seed_rng(void)
|
|||||||
|
|
||||||
memwipe(buf, 0, sizeof(buf));
|
memwipe(buf, 0, sizeof(buf));
|
||||||
|
|
||||||
if (rand_poll_ok || load_entropy_ok)
|
if ((rand_poll_ok || load_entropy_ok) && RAND_status() == 1)
|
||||||
return 0;
|
return 0;
|
||||||
else
|
else
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Write <b>n</b> bytes of strong random data to <b>to</b>. Return 0 on
|
/** Write <b>n</b> bytes of strong random data to <b>to</b>. Supports mocking
|
||||||
* success, -1 on failure, with support for mocking for unit tests.
|
* for unit tests.
|
||||||
|
*
|
||||||
|
* This function is not allowed to fail; if it would fail to generate strong
|
||||||
|
* entropy, it must terminate the process instead.
|
||||||
*/
|
*/
|
||||||
MOCK_IMPL(int,
|
MOCK_IMPL(void,
|
||||||
crypto_rand, (char *to, size_t n))
|
crypto_rand, (char *to, size_t n))
|
||||||
{
|
{
|
||||||
return crypto_rand_unmocked(to, n);
|
crypto_rand_unmocked(to, n);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Write <b>n</b> bytes of strong random data to <b>to</b>. Return 0 on
|
/** Write <b>n</b> bytes of strong random data to <b>to</b>. Most callers
|
||||||
* success, assert on failure. Most callers will want crypto_rand instead.
|
* will want crypto_rand instead.
|
||||||
|
*
|
||||||
|
* This function is not allowed to fail; if it would fail to generate strong
|
||||||
|
* entropy, it must terminate the process instead.
|
||||||
*/
|
*/
|
||||||
int
|
void
|
||||||
crypto_rand_unmocked(char *to, size_t n)
|
crypto_rand_unmocked(char *to, size_t n)
|
||||||
{
|
{
|
||||||
int r;
|
int r;
|
||||||
|
if (n == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
tor_assert(n < INT_MAX);
|
tor_assert(n < INT_MAX);
|
||||||
tor_assert(to);
|
tor_assert(to);
|
||||||
r = RAND_bytes((unsigned char*)to, (int)n);
|
r = RAND_bytes((unsigned char*)to, (int)n);
|
||||||
if (r == 0)
|
tor_assert(r >= 0);
|
||||||
crypto_log_errors(LOG_WARN, "generating random data");
|
|
||||||
return (r == 1) ? 0 : -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Return a pseudorandom integer, chosen uniformly from the values
|
/** Return a pseudorandom integer, chosen uniformly from the values
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include "torint.h"
|
#include "torint.h"
|
||||||
#include "testsupport.h"
|
#include "testsupport.h"
|
||||||
|
#include "compat.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Macro to create an arbitrary OpenSSL version number as used by
|
Macro to create an arbitrary OpenSSL version number as used by
|
||||||
@ -119,10 +120,10 @@ typedef struct crypto_dh_t crypto_dh_t;
|
|||||||
/* global state */
|
/* global state */
|
||||||
const char * crypto_openssl_get_version_str(void);
|
const char * crypto_openssl_get_version_str(void);
|
||||||
const char * crypto_openssl_get_header_version_str(void);
|
const char * crypto_openssl_get_header_version_str(void);
|
||||||
int crypto_early_init(void);
|
int crypto_early_init(void) ATTR_WUR;
|
||||||
int crypto_global_init(int hardwareAccel,
|
int crypto_global_init(int hardwareAccel,
|
||||||
const char *accelName,
|
const char *accelName,
|
||||||
const char *accelPath);
|
const char *accelPath) ATTR_WUR;
|
||||||
void crypto_thread_cleanup(void);
|
void crypto_thread_cleanup(void);
|
||||||
int crypto_global_cleanup(void);
|
int crypto_global_cleanup(void);
|
||||||
|
|
||||||
@ -269,9 +270,9 @@ int crypto_expand_key_material_rfc5869_sha256(
|
|||||||
uint8_t *key_out, size_t key_out_len);
|
uint8_t *key_out, size_t key_out_len);
|
||||||
|
|
||||||
/* random numbers */
|
/* random numbers */
|
||||||
int crypto_seed_rng(void);
|
int crypto_seed_rng(void) ATTR_WUR;
|
||||||
MOCK_DECL(int,crypto_rand,(char *to, size_t n));
|
MOCK_DECL(void,crypto_rand,(char *to, size_t n));
|
||||||
int crypto_rand_unmocked(char *to, size_t n);
|
void crypto_rand_unmocked(char *to, size_t n);
|
||||||
int crypto_strongest_rand(uint8_t *out, size_t out_len);
|
int crypto_strongest_rand(uint8_t *out, size_t out_len);
|
||||||
int crypto_rand_int(unsigned int max);
|
int crypto_rand_int(unsigned int max);
|
||||||
int crypto_rand_int_range(unsigned int min, unsigned int max);
|
int crypto_rand_int_range(unsigned int min, unsigned int max);
|
||||||
|
@ -113,8 +113,7 @@ curve25519_rand_seckey_bytes(uint8_t *out, int extra_strong)
|
|||||||
{
|
{
|
||||||
uint8_t k_tmp[CURVE25519_SECKEY_LEN];
|
uint8_t k_tmp[CURVE25519_SECKEY_LEN];
|
||||||
|
|
||||||
if (crypto_rand((char*)out, CURVE25519_SECKEY_LEN) < 0)
|
crypto_rand((char*)out, CURVE25519_SECKEY_LEN);
|
||||||
return -1;
|
|
||||||
if (extra_strong && !crypto_strongest_rand(k_tmp, CURVE25519_SECKEY_LEN)) {
|
if (extra_strong && !crypto_strongest_rand(k_tmp, CURVE25519_SECKEY_LEN)) {
|
||||||
/* If they asked for extra-strong entropy and we have some, use it as an
|
/* If they asked for extra-strong entropy and we have some, use it as an
|
||||||
* HMAC key to improve not-so-good entropy rather than using it directly,
|
* HMAC key to improve not-so-good entropy rather than using it directly,
|
||||||
|
@ -517,8 +517,7 @@ MOCK_IMPL(STATIC X509 *,
|
|||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
{ /* our serial number is 8 random bytes. */
|
{ /* our serial number is 8 random bytes. */
|
||||||
if (crypto_rand((char *)serial_tmp, sizeof(serial_tmp)) < 0)
|
crypto_rand((char *)serial_tmp, sizeof(serial_tmp));
|
||||||
goto error;
|
|
||||||
if (!(serial_number = BN_bin2bn(serial_tmp, sizeof(serial_tmp), NULL)))
|
if (!(serial_number = BN_bin2bn(serial_tmp, sizeof(serial_tmp), NULL)))
|
||||||
goto error;
|
goto error;
|
||||||
if (!(BN_to_ASN1_INTEGER(serial_number, X509_get_serialNumber(x509))))
|
if (!(BN_to_ASN1_INTEGER(serial_number, X509_get_serialNumber(x509))))
|
||||||
|
@ -7335,8 +7335,7 @@ init_cookie_authentication(const char *fname, const char *header,
|
|||||||
|
|
||||||
/* Generate the cookie */
|
/* Generate the cookie */
|
||||||
*cookie_out = tor_malloc(cookie_len);
|
*cookie_out = tor_malloc(cookie_len);
|
||||||
if (crypto_rand((char *)*cookie_out, cookie_len) < 0)
|
crypto_rand((char *)*cookie_out, cookie_len);
|
||||||
goto done;
|
|
||||||
|
|
||||||
/* Create the string that should be written on the file. */
|
/* Create the string that should be written on the file. */
|
||||||
memcpy(cookie_file_str, header, strlen(header));
|
memcpy(cookie_file_str, header, strlen(header));
|
||||||
|
@ -2256,8 +2256,7 @@ connection_or_send_auth_challenge_cell(or_connection_t *conn)
|
|||||||
|
|
||||||
auth_challenge_cell_t *ac = auth_challenge_cell_new();
|
auth_challenge_cell_t *ac = auth_challenge_cell_new();
|
||||||
|
|
||||||
if (crypto_rand((char*)ac->challenge, sizeof(ac->challenge)) < 0)
|
crypto_rand((char*)ac->challenge, sizeof(ac->challenge));
|
||||||
goto done;
|
|
||||||
|
|
||||||
auth_challenge_cell_add_methods(ac, AUTHTYPE_RSA_SHA256_TLSSECRET);
|
auth_challenge_cell_add_methods(ac, AUTHTYPE_RSA_SHA256_TLSSECRET);
|
||||||
auth_challenge_cell_set_n_methods(ac,
|
auth_challenge_cell_set_n_methods(ac,
|
||||||
|
@ -3442,8 +3442,7 @@ handle_control_authchallenge(control_connection_t *conn, uint32_t len,
|
|||||||
tor_free(client_nonce);
|
tor_free(client_nonce);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
const int fail = crypto_rand(server_nonce, SAFECOOKIE_SERVER_NONCE_LEN);
|
crypto_rand(server_nonce, SAFECOOKIE_SERVER_NONCE_LEN);
|
||||||
tor_assert(!fail);
|
|
||||||
|
|
||||||
/* Now compute and send the server-to-controller response, and the
|
/* Now compute and send the server-to-controller response, and the
|
||||||
* server's nonce. */
|
* server's nonce. */
|
||||||
|
@ -193,8 +193,7 @@ handle_client_auth_nonce(const char *client_nonce, size_t client_nonce_len,
|
|||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
/* Get our nonce */
|
/* Get our nonce */
|
||||||
if (crypto_rand(server_nonce, EXT_OR_PORT_AUTH_NONCE_LEN) < 0)
|
crypto_rand(server_nonce, EXT_OR_PORT_AUTH_NONCE_LEN);
|
||||||
return -1;
|
|
||||||
|
|
||||||
{ /* set up macs */
|
{ /* set up macs */
|
||||||
size_t hmac_s_msg_len = strlen(EXT_OR_PORT_AUTH_SERVER_TO_CLIENT_CONST) +
|
size_t hmac_s_msg_len = strlen(EXT_OR_PORT_AUTH_SERVER_TO_CLIENT_CONST) +
|
||||||
|
@ -1616,7 +1616,6 @@ rotate_x509_certificate_callback(time_t now, const or_options_t *options)
|
|||||||
/* We also make sure to rotate the TLS connections themselves if they've
|
/* We also make sure to rotate the TLS connections themselves if they've
|
||||||
* been up for too long -- but that's done via is_bad_for_new_circs in
|
* been up for too long -- but that's done via is_bad_for_new_circs in
|
||||||
* run_connection_housekeeping() above. */
|
* run_connection_housekeeping() above. */
|
||||||
|
|
||||||
return MAX_SSL_KEY_LIFETIME_INTERNAL;
|
return MAX_SSL_KEY_LIFETIME_INTERNAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1626,7 +1625,10 @@ add_entropy_callback(time_t now, const or_options_t *options)
|
|||||||
(void)now;
|
(void)now;
|
||||||
(void)options;
|
(void)options;
|
||||||
/* We already seeded once, so don't die on failure. */
|
/* We already seeded once, so don't die on failure. */
|
||||||
crypto_seed_rng();
|
if (crypto_seed_rng() < 0) {
|
||||||
|
log_warn(LD_GENERAL, "Tried to re-seed RNG, but failed. We already "
|
||||||
|
"seeded once, though, so we won't exit here.");
|
||||||
|
}
|
||||||
|
|
||||||
/** How often do we add more entropy to OpenSSL's RNG pool? */
|
/** How often do we add more entropy to OpenSSL's RNG pool? */
|
||||||
#define ENTROPY_INTERVAL (60*60)
|
#define ENTROPY_INTERVAL (60*60)
|
||||||
|
@ -30,10 +30,7 @@ fast_onionskin_create(fast_handshake_state_t **handshake_state_out,
|
|||||||
{
|
{
|
||||||
fast_handshake_state_t *s;
|
fast_handshake_state_t *s;
|
||||||
*handshake_state_out = s = tor_malloc(sizeof(fast_handshake_state_t));
|
*handshake_state_out = s = tor_malloc(sizeof(fast_handshake_state_t));
|
||||||
if (crypto_rand((char*)s->state, sizeof(s->state)) < 0) {
|
crypto_rand((char*)s->state, sizeof(s->state));
|
||||||
tor_free(s);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
memcpy(handshake_out, s->state, DIGEST_LEN);
|
memcpy(handshake_out, s->state, DIGEST_LEN);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -56,8 +53,7 @@ fast_server_handshake(const uint8_t *key_in, /* DIGEST_LEN bytes */
|
|||||||
size_t out_len;
|
size_t out_len;
|
||||||
int r = -1;
|
int r = -1;
|
||||||
|
|
||||||
if (crypto_rand((char*)handshake_reply_out, DIGEST_LEN)<0)
|
crypto_rand((char*)handshake_reply_out, DIGEST_LEN);
|
||||||
return -1;
|
|
||||||
|
|
||||||
memcpy(tmp, key_in, DIGEST_LEN);
|
memcpy(tmp, key_in, DIGEST_LEN);
|
||||||
memcpy(tmp+DIGEST_LEN, handshake_reply_out, DIGEST_LEN);
|
memcpy(tmp+DIGEST_LEN, handshake_reply_out, DIGEST_LEN);
|
||||||
|
@ -65,11 +65,7 @@ rend_client_send_establish_rendezvous(origin_circuit_t *circ)
|
|||||||
tor_assert(circ->rend_data);
|
tor_assert(circ->rend_data);
|
||||||
log_info(LD_REND, "Sending an ESTABLISH_RENDEZVOUS cell");
|
log_info(LD_REND, "Sending an ESTABLISH_RENDEZVOUS cell");
|
||||||
|
|
||||||
if (crypto_rand(circ->rend_data->rend_cookie, REND_COOKIE_LEN) < 0) {
|
crypto_rand(circ->rend_data->rend_cookie, REND_COOKIE_LEN);
|
||||||
log_warn(LD_BUG, "Internal error: Couldn't produce random cookie.");
|
|
||||||
circuit_mark_for_close(TO_CIRCUIT(circ), END_CIRC_REASON_INTERNAL);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Set timestamp_dirty, because circuit_expire_building expects it,
|
/* Set timestamp_dirty, because circuit_expire_building expects it,
|
||||||
* and the rend cookie also means we've used the circ. */
|
* and the rend cookie also means we've used the circ. */
|
||||||
|
@ -269,11 +269,7 @@ rend_encrypt_v2_intro_points_basic(char **encrypted_out,
|
|||||||
tor_assert(client_cookies && smartlist_len(client_cookies) > 0);
|
tor_assert(client_cookies && smartlist_len(client_cookies) > 0);
|
||||||
|
|
||||||
/* Generate session key. */
|
/* Generate session key. */
|
||||||
if (crypto_rand(session_key, CIPHER_KEY_LEN) < 0) {
|
crypto_rand(session_key, CIPHER_KEY_LEN);
|
||||||
log_warn(LD_REND, "Unable to generate random session key to encrypt "
|
|
||||||
"introduction point string.");
|
|
||||||
goto done;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Determine length of encrypted introduction points including session
|
/* Determine length of encrypted introduction points including session
|
||||||
* keys. */
|
* keys. */
|
||||||
@ -335,11 +331,7 @@ rend_encrypt_v2_intro_points_basic(char **encrypted_out,
|
|||||||
REND_BASIC_AUTH_CLIENT_MULTIPLE;
|
REND_BASIC_AUTH_CLIENT_MULTIPLE;
|
||||||
i < REND_BASIC_AUTH_CLIENT_MULTIPLE - 1; i++) {
|
i < REND_BASIC_AUTH_CLIENT_MULTIPLE - 1; i++) {
|
||||||
client_part = tor_malloc_zero(REND_BASIC_AUTH_CLIENT_ENTRY_LEN);
|
client_part = tor_malloc_zero(REND_BASIC_AUTH_CLIENT_ENTRY_LEN);
|
||||||
if (crypto_rand(client_part, REND_BASIC_AUTH_CLIENT_ENTRY_LEN) < 0) {
|
crypto_rand(client_part, REND_BASIC_AUTH_CLIENT_ENTRY_LEN);
|
||||||
log_warn(LD_REND, "Unable to generate fake client entry.");
|
|
||||||
tor_free(client_part);
|
|
||||||
goto done;
|
|
||||||
}
|
|
||||||
smartlist_add(encrypted_session_keys, client_part);
|
smartlist_add(encrypted_session_keys, client_part);
|
||||||
}
|
}
|
||||||
/* Sort smartlist and put elements in result in order. */
|
/* Sort smartlist and put elements in result in order. */
|
||||||
|
@ -643,7 +643,10 @@ main(int argc, const char **argv)
|
|||||||
|
|
||||||
reset_perftime();
|
reset_perftime();
|
||||||
|
|
||||||
crypto_seed_rng();
|
if (crypto_seed_rng() < 0) {
|
||||||
|
printf("Couldn't seed RNG; exiting.\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
crypto_init_siphash_key();
|
crypto_init_siphash_key();
|
||||||
options = options_new();
|
options = options_new();
|
||||||
init_logging(1);
|
init_logging(1);
|
||||||
|
@ -309,15 +309,14 @@ test_ext_or_cookie_auth(void *arg)
|
|||||||
tor_free(client_hash2);
|
tor_free(client_hash2);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static void
|
||||||
crypto_rand_return_tse_str(char *to, size_t n)
|
crypto_rand_return_tse_str(char *to, size_t n)
|
||||||
{
|
{
|
||||||
if (n != 32) {
|
if (n != 32) {
|
||||||
TT_FAIL(("Asked for %d bytes, not 32", (int)n));
|
TT_FAIL(("Asked for %d bytes, not 32", (int)n));
|
||||||
return -1;
|
return;
|
||||||
}
|
}
|
||||||
memcpy(to, "te road There is always another ", 32);
|
memcpy(to, "te road There is always another ", 32);
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -390,8 +390,14 @@ main(int argc, char **argv)
|
|||||||
|
|
||||||
init_logging(1);
|
init_logging(1);
|
||||||
network_init();
|
network_init();
|
||||||
crypto_global_init(1, NULL, NULL);
|
if (crypto_global_init(1, NULL, NULL) < 0) {
|
||||||
crypto_seed_rng();
|
printf("Couldn't initialize crypto subsystem; exiting.\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if (crypto_seed_rng() < 0) {
|
||||||
|
printf("Couldn't seed RNG; exiting.\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
rq = replyqueue_new(as_flags);
|
rq = replyqueue_new(as_flags);
|
||||||
tor_assert(rq);
|
tor_assert(rq);
|
||||||
|
@ -272,7 +272,10 @@ main(int c, const char **v)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
crypto_set_tls_dh_prime();
|
crypto_set_tls_dh_prime();
|
||||||
crypto_seed_rng();
|
if (crypto_seed_rng() < 0) {
|
||||||
|
printf("Couldn't seed RNG; exiting.\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
rep_hist_init();
|
rep_hist_init();
|
||||||
network_init();
|
network_init();
|
||||||
setup_directory();
|
setup_directory();
|
||||||
|
Loading…
Reference in New Issue
Block a user